In the realm of software quality assurance, a thorough understanding of operating systems plays a pivotal role in ensuring the successful delivery of high-quality software products. It’s a basic part of a laptop or a server, that’s why it’s important to have a general understanding of how it works — this knowledge enables understanding of how applications use system resources, interact with peripherals and handle system-level events.
Operating systems
An operating system (OS) is the foundational software that controls the hardware and software resources of a computer system. It acts as an intermediary between the user and the computer hardware, handling essential tasks such as file management, memory allocation, process scheduling, and input/output operations.
An operating system consists of several key components that work together to ensure the smooth operation of a computer system. These components include:
Kernel. The core of the operating system, which manages hardware resources and provides low-level services to other system components.
Device drivers. Software programs that allow the operating system to communicate with specific hardware devices, such as printers, scanners, and storage drives.
File system. A collection of programs that manage the storage and organization of files on the computer's hard drive or other storage devices.
Scheduler. Allocates processing time among multiple applications, ensuring efficient use of the CPU.
Memory manager. Handles the allocation and deallocation of memory for applications and system processes, ensuring optimal memory usage.
User interface (UI). Offers a way for users to interact with the computer, either through a graphical user interface (GUI) or a command-line interface (CLI).
Operating systems can be categorized based on their architecture and purpose. Here are some of the most common types:
Multitasking. Allows multiple applications to run simultaneously, sharing the computer's resources.
Multiuser. Supports multiple users accessing the system at the same time, maintaining separate environments for each user.
Real-time. Tailored for time-sensitive applications, ensuring prompt responses to events.
Embedded. Used in specialized devices, such as smartphones, routers, and smart TVs.
Several operating systems are widely used in the personal computer and mobile device markets. Some you have likely encountered include Microsoft Windows, macOS, Android, iOS, and others. But in this part of the course, we will focus on the Linux family of operating systems, since they are often used as server operating systems. These are the operating systems a tester may encounter at work. Linux is a family of free, open-source Unix-like operating systems known for their stability, customization options, and various distributions.
Kernel
The operating system kernel is the core software that manages the hardware and software resources of a computer. It acts as an intermediary between the user and the hardware, providing a seamless and consistent interface for applications to run. The kernel handles tasks such as process management, memory management, device drivers, and file systems.
Operating systems can employ different types of kernels, each with its strengths and weaknesses. Here's an overview of five common kernel types:
Monolithic kernel. This is the most common kernel type, characterized by a single, self-contained codebase that encapsulates all essential operating system functionalities. A basic interview question is "What type of kernel do the Linux family OS have?". Know the answer — mono-kernel.
Microkernel. In contrast, a microkernel consists of a minimal core, with most services and drivers provided by dynamically loaded modules. This design emphasizes flexibility and security but can lead to performance overhead.
Hybrid kernel. Hybrid kernels combine elements of monolithic and microkernel architectures, aiming to strike a balance between performance and modularity. Some core functions reside in the kernel, while others are implemented as modules.
Nanokernel. This highly minimalist approach reduces the kernel to a minimum, focusing on essential services like process management and scheduling. Additional functionality is delegated to user-space processes, enhancing flexibility and security but potentially impacting performance.
Exokernel. An exokernel provides the most abstract interface between applications and hardware, with minimal kernel code and maximum control over resource allocation and management. It offers remarkable flexibility and security but requires more sophisticated programming techniques.
The Linux kernel is a monolithic kernel, meaning it's a single, self-contained piece of software that encompasses all the essential functionality of the operating system. This contrasts with microkernels, which have a smaller core and rely on modules for additional features. A kernel acts as an intermediary between the software and the underlying hardware, providing a consistent interface for applications to interact with devices. It manages the execution of multiple processes, ensuring they share resources efficiently without interfering with each other. A kernel allocates and manages memory for both processes and devices, ensuring resources are used effectively. It handles communication between the system and its peripherals, including input devices, storage devices, and network interfaces. It enforces security policies to protect the system from unauthorized access and malicious attacks.
Despite its monolithic nature, the Linux kernel incorporates a modular design, allowing for flexibility and customization. Kernel modules are similar to libraries that can be dynamically loaded and unloaded into the kernel as needed. This modularity enables developers to add new features without modifying the kernel's core, making it easier to maintain and update the kernel.
Processes
In the realm of Linux, processes are the fundamental units of execution, representing programs that are actively running. Each process has a unique identifier, known as a process ID (PID), to distinguish it from other processes on the system.
Linux processes are essential entities that execute programs and use system resources. They transition through distinct states throughout their lifecycle, each indicating a specific stage of execution.
Running or Runnable (R). In this state, a process is actively executing instructions on the CPU. It is considered "running" even if temporarily paused for I/O operations.
Uninterruptible Sleep (D). This state indicates that a process is waiting for an event that will never occur, such as a hardware interrupt that the kernel isn't configured to handle. Processes in this state are "blocked" and cannot be scheduled for execution. The only way out of uninterruptible sleep D is through an explicit wake-up call.
Interruptable Sleep (S). This state indicates that a process is waiting for an event that might occur, like user input or data from a network connection. These processes can be interrupted by others and will be scheduled for execution if the awaited event occurs.
Stopped (T). This state shows that the process has been halted by the user or a signal from another process. Stopped processes are not running or waiting for events and cannot be scheduled for execution.
Zombie (Z). This state indicates a process that has finished but whose parent process hasn't yet claimed its exit status. Zombie processes are not running or waiting for events, but they remain in the kernel's process table.
File systems
A file system is a software layer that governs the storage and retrieval of data on a system. It defines how files and directories are organized, how data is physically stored on the hard drive, and how access to files is controlled. Each file system has unique structures, features, and strengths.
A file system consists of several essential components:
Directory structure: The hierarchical organization of files and directories that resembles a tree-like structure.
Files metadata: Data describing the characteristics of files, such as size, creation date, access permissions, and ownership.
Data blocks: The actual storage locations on the hard drive where file contents are written.
File Allocation Table (FAT): A table storing pointers to the physical locations of file data blocks.
Journal: A log recording changes to the file system, facilitating data recovery in case of system crashes.
Journaling mechanisms: Techniques enhancing data integrity and consistency by ensuring file system modifications are written in sequential order.
In Linux, everything is a file (if it's not a process). That's why the file system is an essential part of this OS family. Linux supports a wide range of file systems, each with its own strengths and limitations. The ext4 is the most widely used file system for Linux, known for its stability, performance, and compatibility.
The Linux filesystem layout is described by the Filesystem Hierarchy Standard (FHS). According to it, all files and directories appear under the root directory /, all device files are in the /dev directory, all log files are in the /var/log directory, etc.
On the picture — Linux filesystem layout.
At the heart of every Linux file system lies the inode, a fundamental data structure storing metadata for files and directories. Inodes are unique identifiers holding essential information about each file, such as size, creation date, access permissions, and ownership. They also maintain pointers to the actual data blocks where the file's contents are stored.
Each file and directory within a Linux file system is assigned an inode number. The inode number serves as a reference to the corresponding inode structure, allowing the operating system to locate and access the file's metadata and data blocks efficiently.
User space
User space, also known as userland, refers to the portion of an OS where user-level applications run. It is a protected environment separate from the kernel, ensuring that applications cannot directly access or modify critical system components. This separation safeguards the system from unauthorized or malicious actions by user-level programs.
Linux user space includes a collection of essential components that facilitate application execution and user interaction:
Libraries: Pre-written code modules that provide core functionalities for user-level applications. They encapsulate common tasks, such as file I/O, networking, and user interface handling, simplifying application development.
System calls: Interfaces that connect user-level applications to the kernel. They enable applications to request services from the kernel, such as accessing files, managing memory, and communicating with hardware devices. System calls serve as a secure and controlled gateway between user-level programs and the underlying system resources.
User-level applications: The programs that users directly interact with. They range from web browsers and word processors to graphics editors and scientific computing tools. User-level applications rely on libraries and system calls to access system resources and perform their intended functions.
Conclusion
Designing operating systems is complex and warrants its own course. However, even basic knowledge of its principles is incredibly valuable for QA engineers. Understanding how operating systems function can drastically improve a QA's ability to do their job well. It enables them to pinpoint, examine, and fix software issues with more accuracy and efficiency.
This knowledge can aid in the identification and investigation of OS-related bugs. For instance, if a software crashes because it tries to open a file that the operating system has secured, a QA engineer aware of file locking mechanisms can identify the issue more swiftly.
It can also lead to creating more effective tests. For example, a QA engineer who understands memory management can develop tests to ensure that the software isn't leaking memory or accessing areas it shouldn't.
In conclusion, even a modest amount of operating system knowledge is a significant benefit for a QA engineer.