§2.4–2.7Persistence … Summary

Intro OSTEP pp. 11–18 · ~12 min read

  • persistence
  • i/o device
  • file system
  • device driver
  • abstraction
  • protection
  • isolation
  • batch processing
  • user mode
  • kernel mode
  • trap
  • return-from-trap
  • multiprogramming

One piece left. CPUs compute and memory remembers — but only while the power is on. The third piece is about what survives.

2.4 Persistence

System memory is volatile: DRAM loses its contents when the power goes away or the system crashes. So we need hardware and software to store data persistently — users care rather a lot about their data.

The hardware is some form of I/O device : in modern systems, a hard drive is the common home for long-lived information, with solid-state drives (SSDs) making headway. The software is the file system — the part of the OS responsible for storing user files reliably and efficiently on disk.

One big difference from the first two pieces: the OS does not create a private, virtualized disk for each application. Files are meant to be shared. Think about how a program gets born:

editoremacs -nw main.ccompilergcc -o main main.cnew process./maindiskmain.cmain (executable)createsreadscreatesis run as

Why disks aren’t virtualized per-process: three different processes cooperate through shared files. The editor’s output is the compiler’s input; the compiler’s output becomes a running process.

Here is a program that creates a file containing “hello world” — the io.c of Figure 2.6:

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    int fd = open("/tmp/file", O_WRONLY|O_CREAT|O_TRUNC,
                     S_IRWXU);
    assert(fd > -1);
    int rc = write(fd, "hello world\n", 13);
    assert(rc == 13);
    close(fd);
    return 0;
}

Figure 2.6: A Program That Does I/O (io.c)

The program makes three calls into the operating system: open() opens and creates the file, write() writes data into it, and close() says no more writing is coming. These system calls are routed to the file system, which handles the request and returns an error code. Step through what one of those calls actually involves:

Anatomy of one system call: write() from io.c, from user mode to the disk and back
t =
Program (user)
OS (kernel)
Disk
tick 1 / 8 · one step per tick (not to scale — the disk step dwarfs the rest)activeidle / waiting

The program runs in user mode, preparing its data ("hello world").

What the OS does to actually write to disk is (the book warns: close your eyes, it’s unpleasant) a fair bit of work: figure out where on disk the new data will live, track it in the file system’s own structures, and issue I/O requests to the storage device through a device driver — OS code that knows the low-level device interface and its exact semantics. That the OS wraps all this behind a standard, simple interface is one more reason it gets called a standard library.

Two performance-and-reliability details, both foreshadowing Part III:

  • For performance, most file systems delay writes, hoping to batch several into fewer, larger disk operations.
  • For crash safety, most file systems use an intricate write protocol — journaling or copy-on-write — carefully ordering the writes so that if a crash lands mid-sequence, the system can recover afterward.

The Crux: How To Store Data Persistently

The file system is the part of the OS in charge of persistent data. What techniques are needed to do so correctly? What mechanisms and policies give high performance? How is reliability achieved in the face of hardware and software failures? Part III (chapters 35–51: devices, disks, RAIDs, file systems) is the answer.

2.5 Design Goals

So an OS virtualizes physical resources, wrangles concurrency, and stores data safely. What should guide how it’s built? Building systems means making trade-offs, and these are the recurring goals:

Abstraction

Build good abstractions to make the system convenient to use. Abstraction is how CS works at all: C without assembly, assembly without gates, gates without transistors. Each part of the book introduces the OS’s major abstractions.

Performance

Minimize the overheads of the OS — extra time (more instructions) and extra space (memory, disk). Virtualization is worth a lot, but not any cost. Perfection isn’t always attainable; noticing and tolerating that is a skill.

Protection & isolation

Protection between applications, and between applications and the OS: one program’s malicious or accidental bad behavior must not harm the others — or the OS itself. The key principle is isolation of processes from one another.

Reliability

The OS must run non-stop: when it fails, everything fails. With OSes at millions of lines of code, this is hard — and an active research area.

…and, depending on the system:

Energy-efficiency (green computing, battery-powered devices), security (protection extended to a hostile, networked world), mobility (OSes on ever-smaller devices). The goals shift with the setting, but the principles in this book apply across the range.

2.6 Some History

Operating systems accumulated their good ideas over decades. The book’s short tour, era by era:

Just librariesmainframes, one jobat a time, batch runsby a human operator1950sProtectionAtlas invents thesystem call: trap,user/kernel modeearly 1960sMultiprogrammingminicomputers (PDP):overlap I/O, memoryprotection — UNIX born1960s–70sThe PC regressionDOS, early Mac OS:no memory protection,lessons forgotten1980sConvergenceWindows NT, macOS(UNIX core), Linux —the old ideas return1990s→now

Five eras of OS history. Note the shape: ideas are invented, forgotten in the rush to cheap hardware, then rediscovered.

Early operating systems: just libraries. At first the “OS” was a set of commonly-used routines (low-level I/O handling, say) so that not every programmer wrote them from scratch. One program ran at a time, chosen and loaded by a human operator — this was batch processing : jobs queued up and run in batches, never interactively. Computer time was simply too expensive to let a person sit at the console.

Beyond libraries: protection. The realization that OS code was special — it controls the devices — led to the invention of the system call, pioneered by the Atlas computing system. Rather than calling OS routines like any library function, a special pair of hardware instructions and hardware state make entering the OS a formal, controlled act. Programs run in user mode , where the hardware restricts what they can do — no raw I/O requests, no touching arbitrary physical memory. A system call starts with a trap instruction: the hardware jumps to a pre-registered trap handler and simultaneously raises the privilege level to kernel mode , where the OS may do anything it likes. When done, the OS uses return-from-trap to drop back to user mode and hand control back exactly where the program left off. (You watched this cycle in the widget above.)

The era of multiprogramming. Minicomputers (like DEC’s PDP family) made computers affordable enough that every workgroup — not every corporation — could have one, and developer activity exploded. Multiprogramming became standard: load several jobs in memory and switch among them, especially when one waits on slow I/O. Why let the CPU idle? This forced the big conceptual advances — memory protection, and correctness in the face of interrupt-driven concurrency (a problem you met in the previous section). The practical milestone of the era: UNIX, from Ken Thompson and Dennis Ritchie at Bell Labs.

Aside: The importance of UNIX

UNIX distilled the good ideas of its predecessors (notably MIT’s ambitious Multics) into something simple and powerful. Its unifying principle: small powerful programs, composed — the shell’s pipes let grep foo file.txt | wc -l string two tools into a bigger one. It shipped with a C compiler, was friendly to programmers, and — crucially — the authors mailed the source to anyone who asked: an early form of open source. A beautiful, small, readable kernel in C invited others in; Bill Joy’s group at Berkeley produced the BSD distribution (better virtual memory, file system, networking). Then companies and lawyers arrived (SunOS, AIX, HPUX, IRIX, and years of legal wrangling), and for a while UNIX’s survival looked doubtful…

The modern era. Then came the PC — cheaper, faster, for everyone, and at first a great leap backwards for operating systems. DOS didn’t think memory protection mattered; a bad program could scribble over everything. Mac OS 9 and earlier scheduled cooperatively, so one program stuck in a loop took the whole machine down. It took years for the minicomputer lessons to reach the desktop: macOS put UNIX at its core, Windows NT was Microsoft’s own great leap forward, and today’s phones run OSes closer to 1970s minicomputer systems than to 1980s PCs — thank goodness.

Aside: And then came Linux

A young Finnish hacker, Linus Torvalds, wrote his own UNIX from the principles up — borrowing none of the code, dodging the lawyers — with the GNU tools alongside. Linux (and the modern open-source movement) was born. The internet giants built on it, Android put it in phones, and Steve Jobs brought his UNIX-based NeXTStep to Apple. UNIX, more important today than ever.

2.7 Summary

You now know what an OS does: it virtualizes physical resources, handles the hard problems of concurrency, and stores data persistently. What this book deliberately leaves out: networking (take the networks course), graphics devices (graphics course), and deep security (security course — though protection between programs runs all through Part I). What’s ahead: virtualization of the CPU and memory, concurrency, and persistence — most of it, the book promises, quite cool.

Homework: how this book teaches (from p. 19)

Nearly every chapter ends with homework. Two kinds: simulators (small programs that mimic a system’s interesting behavior — you can even simulate machines that can’t exist) and real-world code (measurement and small C programs on a UNIX-like system). Simulations are approximations — treat their results with healthy suspicion — but they let you explore freely. This site summarizes each chapter’s simulator and links to ostep-homework; for bigger projects, see ostep-projects.

Check yourself

1.The OS gives each process a virtual CPU and a virtual memory — but NOT a private virtual disk. Why the exception?

2.io.c calls write(fd, "hello world\n", 13). Why can't the program just send those bytes to the disk itself?

3.What pair of steps happens, in hardware, when a system call begins and ends?

4.Why do most file systems use a write protocol like journaling or copy-on-write?

5.In the multiprogramming era, why did the OS switch to another job when the current one started an I/O operation?

5 questions