Nixers Book Club - Book #6: Introduction to Operating Systems Abstractions - Community & Forums Related Discussions

Users browsing this thread: 1 Guest(s)
Long time nixers
As proposed in the last thread, the next book of the Nixer's Book Club is gonna be Introduction to Operating Systems Abstractions using Plan 9 from Bell Labs

[Image: plan9bunnywhite.jpg]

We can do 2 chapters per week.
Our first session will be Nov 13, when we will discuss the first two chapters.
See you then!
Long time nixers
Mainly because of our conf, I am postponing our first session to Nov 13.
If you are interested or curious on Operating Systems and Plan 9 in particular, join us in this sixth reading of the book club!
Long time nixers
Interested in joining in with this. Have no experience with plan 9 but it looks interesting!
If I want to test it out what would you recommend? I know there's a couple of forks and different projects/continuations. And can I just spin up a virtual machine?
Long time nixers
(30-10-2021, 09:14 AM)RoastPotatoes Wrote: Interested in joining in with this. Have no experience with plan 9 but it looks interesting!
If I want to test it out what would you recommend? I know there's a couple of forks and different projects/continuations. And can I just spin up a virtual machine?

I also have no experience with plan 9, but I am having fun playing with it.
I'm using 9front (for no reason in special). Its manual, although full of unrelated pictures, explains the installation process in details.

I first tried to install it in Qemu. But I did not like how qemu grabs the cursor... I want to freely navigate between my windows.
Then I installed drawterm, which connects to a 9front system and runs rio inside a X11 window. You can connect drawterm with the plan9 system running in your qemu virtual machine.
Then I moved from qemu to OpenBSD vmm.

The nice thing about drawterm is that it mounts your host system's root file system in your 9front system. So I can use vim in my host system to edit my files in a xterm window and then open the files in the 9front guest system from a rio window open via drawterm.
It's time for the book club.
Here's my summary/notes for the first two chapters.

## Chapter 1

I installed Plan 9 latest image in a VM and started learning it
properly. All the times I tried it in the past, I stopped short and didn't
go so deep.

Rio is definitely a weird experience. It isn't very intuitive that ACME
is missing line numbers, and that using the cursor scrolls down instead
of going to the next line. These probably can be configured somewhere,
or so I think.
At least for now, it feels like I'm fighting against the UI and clumsily
editing files. I'm making a lot of mistakes with the mouse, deleting
text I didn't intend to, mixing middle mouse (emulated shift+right click).
I love plumber, but my hands just keep mixing the buttons.

Similarly, in the shell, arrow up doesn't show the previous command but
scrolls up. Obviously, there's no tab completion either.
Overall, I'll still need a while to get used to the UI.

I'm quite fund of the compiled that allows targeting multiple
architecture (cross-compilation) that easily.
It's also my first go at the Plan 9 C dialect and it looks good so fr.

Definitely liking the thin-client architecture, the decoupling of
terminal/data/cpu servers.

## Chapter 2

This chapter has an initial overview of what's the meaning of program
and processes, what it means to have an OS, letting multiple things run
at once (multitasking OS).

However, it quickly follows with analysis of processes exec layout and
virtual memory. I'm not so sure it's a good logical order, it felt
parachuted for me. At least, if I was writing for beginner students,
I would be surprised if they didn't nag when studying with such book.
Furthermore, it's a bit annoying that multiple sentences are sprinkled
with the words "it's important to know this". I guess if I didn't have
the background knowledge I have right now, I'd be freaked out reading
that book.
The writing is also a bit more botched and clumsy than the first chapter,
heavy explanations in some places where there shouldn't really be and
shallow ones where there should be.

Apart from this, I'm still liking the Plan 9 C dialect.
ARGBEGIN/ARGEND, E/ARGF are quite nice macros, a good simple replacement
for getopt.
It's great that the return status can be a string, it allows for more
explicit errors.
And actually, system calls can return both string and integers in general.

However, even when the program returns a string, some of the info,
when the program crashes needs extra step to make sense of it.
src and acid command for debugging are super interesting, but I feel
like a lot of what is done could be much simpler. I'm also wondering if
all broken processes stay in the process tree hanging there (like zombie
processes on Unix).

Other cool info:
- Environment variables are similar to Unix.
- seninha mentioned it once but here I got reminded again: If you type
ip/ping, the shell tries with ./ip/ping, and then with /bin/ip/ping.
- PID are similar to Unix too
- Everything is a file, obviously. This particular example caught my
attention: echo kill >/proc/$pid/ctl

In sum, I'm hopeful for the next chapters.
Long time nixers
## Chapter 1

The group-based permission system is interesting, and solves the "shared directory" problem, which is a very common one: have one directory in read-write access by anyone in the group.

It looks simple, but with UNIX-style permissions, by default umask 022, not only files will be created with the wrong group (it would have to be setup by hand) but also they would be not modifiable by the group (due to the umask).

Plan 9 behaves the same way as UNIX after
chmod -R g+s /
umask 002
for all users : the +s mode provokes inheritance of groups on newly created files, and 002 make the new files read/write by the groups.

In fact there is not even chown(1) in plan 9, just chgrp(1).

## Chapter 2

The plan 9 cross-compilers are really nice. And look at what we find in Go source code history...

Russ Cox worked long on getting Plan 9 commands everywhere, starting with the compilers to build everything else, so it was a good base for Go.

From the book, "demand paging" is quite enlightening, and constitute a good counterpart to dynamic libraries : since everything is made by composable programs that are reused by different purposes, there is only one instance of the program's code (.text section) in total.

In the end, filesystems seems offer the same feature-set that shared libraries are offering on non-plan9 world, except communicating through 9p instead of the ABI : more expensive (requires carefully placing the features across FS so there is not too much 9p protocol overhead, which is extremely low locally!), but more generic and isolated.
Long time nixers
(13-11-2021, 04:56 AM)venam Wrote: It's great that the return status can be a string, it allows for more
explicit errors.
IIRC there is a "error message" field in 9P, so that errors strings can come from remote or local.

(13-11-2021, 04:56 AM)venam Wrote: it's important to know this
from the book: "always check out for error conditions".
In practice I have seen a few code not doing so, but people doing it might know that the driver/fs does not have any room for error (no code that returns -1 for instance)... So maybe the idea under all the "important to know" was to focus the reader attention on core principles rather than the implementation details that are accidentally needed for the sake of example.

(30-10-2021, 11:29 PM)seninha Wrote: So I can use vim in my host system to edit my files in a xterm window and then open the files in the 9front guest system from a rio window open via drawterm.
For whoever interested in using Linux/UNIX-like tools but still discover plan-9:
Long time nixers
(13-11-2021, 04:56 AM)venam Wrote: ARGBEGIN/ARGEND, E/ARGF
Available on an UNIX machine near you TODAY

(13-11-2021, 04:56 AM)venam Wrote: However, even when the program returns a string, some of the info,
when the program crashes needs extra step to make sense of it.

refused(char *e)
    return e && strstr(e, "mail refused") != nil;

(13-11-2021, 04:56 AM)venam Wrote: src and acid command for debugging
I really like the source code dumps. Stepping through C source code as it gets executed!
I never played with it though.
Long time nixers
Getting Started

The first section is a brief introduction to a operating system as a collection of system programs that interface with the hardware and how it lies to the programmer by common abstractions.

`/sys/lib/newuser` is a rc(1) script that creates and set up the home directory for the user and create the necessary profile scripts. I cat this file to see its contents, and it is pretty straight forward at 9front.
I'm just curious about why it is at `/sys/lib/` and not at `/bin/whatever/`.

Our first interaction with rio! Damn this menu thing is awkward. I'm used to click to open the menu and then click on the selected entry (that's how I programmed πmenu to behave). But rio's menu is click-and-hold then release on the selected entry.

Now it's acme time.
Button3 click opens a file/directory or looks for a word in the current window. I found this behaviour really awkward... What if I wanted to look for a occurrence of a filename of a file that exists? Right click will open that file...

The window/widget that receives keyboard input is the one where the pointer is over, just like on Xaw/athena X applications. It's called point-to-type. I hated it.

One thing I find weird on rio and acme is how the height of the scroll bar handle changes while scrolling. After checking on the manual I found out that the height of the handle corresponds to the density of characters on the screen, not the number of lines on the window. So if you have a sequence of blank lines on the screen, the scroll bar handle will be very thin (as there are no characters on this section of the scroll), but when viewing the dump of xd that is full of characters, you will have a higher handle.

Enough acme. The next pages are on the manual. Simple file management commands (mv, cd, rm, etc) and concepts (directory, dot-dot, relative path, etc), and file content reading (plan9 uses xd(1), which is way more friendly than od(1)).

One thing I do not like in the plan 9 manuals is how everything is written in prose, rather than lists. Options are scattered through a paragraph that you have to read as a whole to understand the stuff. On some UNIX systems (OpenBSD at least), options are presented in a list using a `.TP` man macro. It is easy to spot an option for reference when they are on a list.

Then we write our first plan 9 program, using a variant of the C programming language with a plan9-specific standard library. The next pages talk about library and system calls, and how system calls work.

Programs and processes

Second chapter is about programs and the processes they generate. We begin with an overview of what a process is and how it is executed; and of the structure of a program (both in file and in memory) and how it is loaded into memory by the kernel.

The concept of program initialization is explained by the classic echo.c program. The example introduces the plan9 ARGBEGIN and ARGEND macros, which replace UNIX getopt(3).

Then comes the error handling. Plan9 has a "%r" directive for print(2) that is replaced by the error string, this directive does not require an additional argument. There is no errno(2). The system provides an err(3)-like function that both prints a message and exits: sysfatal(2). The {w,r}errstr functions write/read the error string.

Next section is about environment variables. Everything pretty simple and similar to how stuff is done on UNIX. One thing I discovered is that children processes can change the environment of their parents! (At least depending on how the processes are forked). The section about processes introduces the concepts of process id, process state, and process scheduling.

Next section explains how to debug a broken process that is still hanging around in the ps(1) table. The section introduces acid(1) and some of its commands (stk() and lstk()). To kill a broken process, run
% echo kill > /proc/$PID/ctl

And finally! Everything is a file! (Or that's the lie the computer tells to you). Time is a file (see /dev/time); processes are files (/proc/); environment variables are files (/env/).
Long time nixers
(13-11-2021, 04:56 AM)venam Wrote: Similarly, in the shell, arrow up doesn't show the previous command but
scrolls up. Obviously, there's no tab completion either.
Overall, I'll still need a while to get used to the UI.
9front has a " command that prints the previous command, and a "" that runs it. File completion is done with Ctrl+F.

(13-11-2021, 04:56 AM)venam Wrote: However, it quickly follows with analysis of processes exec layout and
virtual memory. I'm not so sure it's a good logical order, it felt
parachuted for me. At least, if I was writing for beginner students,
I would be surprised if they didn't nag when studying with such
The book was written for the students of the Operating System courses the author is professor of. Since the course is given after the Computer Architecture course, the students should knew about virtual memory beforehand.

(13-11-2021, 06:22 AM)josuah Wrote: The group-based permission system is interesting, and solves the "shared directory" problem, which is a very common one: have one directory in read-write access by anyone in the group.
UNIX has that. Quoting from the APUE book, third edition, section 4.6:

Quote:The user ID of a new file is set to the effective user ID of the process. POSIX.1 allows an implementation to choose one of the following options to determine the group ID of a new file:
1. The group ID of a new file can be the effective group ID of the process.
2. The group ID of a new file can be the group ID of the directory in which the file is being created.

FreeBSD 8.0 and Mac OS X 10.6.8 always copy the new file's group ID from the directory. Several Linux file systems allow the choice between the two options to be selected using a mount(1) command option. The default behavior for Linux 3.2.0 and Solaris 10 is to determine the group ID of a new file depending on whether the set-group-ID bit is set for the directory which the file is created. If this bit is set, the new file's group ID is copied from the directory; otherwise, the new file's group ID is set to the effective group ID of the process.

Using the second option (inheriting the directory's group ID) assures us that all files and directories created in that directory will have the same group ID as the directory. This group ownership of files and directories will then propagate down the hierarchy from that point. This is used in the Linux directory /var/mail, for example.
Edit: More information on that in this Wikipedia article
Chapter 3 and 4 were pretty simple, especially with a Unix background
the content can be compared.

Here are a couple of notes I took during my reading.

## Chapter 3

They fixed the create syscall 😂

fd = create("afile", OWRITE, 0664);

Quote:> Plan 9 does not have a wastebasket
First time I hear it called that way.

In Plan9, like old Unix, you can still see the directory file structure
and manipulate it directly with the help of some specific syscalls:

xd -c .
struct Dir {
    /* system-modified data */
    ushort type; /* server type */
    uint dev; /* server subtype */
    /* file data */
    Qid qid; /* unique id from server */
    ulong mode; /* permissions */
    ulong atime; /* last read time */
    ulong mtime; /* last write time */
    vlong length; /* file length */
    char *name; /* last element of path */
    char *uid; /* owner name */
    char *gid; /* group name */
    char *muid; /* last modifier name */
} Dir;

Globbing in the shell is the same as Unix.

One thing that is different though are the arguments for the dd command,
they got dashes now.

I was particularly impressed by the buffer section of chapter 3. It's
a pretty good way to learn the importance of buffering. We also get a
practical example. Biobuf is really useful instead of reinventing the
wheel each time.

## Chapter 4

Similar vibe as chapter 3, I keep comparing in my mind.

Fork is the same as Unix fork.

NB: The author never stops the "important" talk.

One thing I found weird is that execl needs argv[0] explicitly, that's

Wait syscall also returns a full message, I like how errors are much
more verbose in Plan9, that makes it simpler to debug.
Long time nixers
(20-11-2021, 04:40 AM)venam Wrote: One thing that is different though are the arguments for the dd command,
they got dashes now.
In rc(1) the = character is special not only at the beginning of the command line, but in the middle too. So you can set an environment variable in the middle of the line. The UNIX dd syntax
dd if=/dev/random of=/dev/mordor
was problematic in rc(1) because of the special meaning of the equal sign.


Third chapter is about files, I/O and buffered I/O using the <bio.h> header. Plan 9 also uses the concepts of file descriptors to identify the files open by a process.

The first section of this chapter introduces the basic unbuffered I/O functions (write(2) and read(2)), the functions to open/close files (open(2) and close(2)), and the function to set the file offset (seek(2)). /proc/$pid/fd lists the file descriptors that are open for process $pid (it also contains the process' cwd).

In the second section, we know that open(2) does not truncate the file by default, we should use `OTRUNC` to truncate. The file descriptor in the process' file descriptor table points to a `Chan` (channel), a structure that “contains information needed to let the kernel reach the file server and perform operations on the file”. This section also tells you that a file can have holes; it also tells about the append only permission bit.

Next sections is about the read(2) function and how to handle errors; and about the creat(2), access(2) and remove(2) functions. The next section covers directory entries, the Dir structure and functions to handle this structure.

We are introduced to globbing and, finally, at the end of the chapter, to buffered I/O.

Parent and Child

Fourth chapter deals with process creation. It introduces the functions fork(2), exec(2) and wait(2), and introduces the pitfalls of process creation (shared files, race conditions, waiting for children, etc).

Since we have bind(2) now, we do not need execp or execlp functions, the meaning of $path was diminished to a rc(1) feature. Just look at /bin.

At the end of the chapter, shell scripts and the shebang are introduced.
Time for the book club discussion.

Chapter 5 and 6 were interesting because they started to give an overview
of the decoupled, decentralized, architecture of Plan 9. They also
emphasize the strong enforcement of "everything is a file".

## Chapter 5

This one was about the shell and redirection in general.

The virtual descriptor, /fd/0 and /fd/1 were new to me, interface to
file descriptors.

The redirection to different file description is done using square brackets.
That's cleaner than Unix usual shells.

; lc *.c >[2] /dev/null

One interesting point, that is well covered in the book, is that pipes
preserve write boundaries, unlike Unix.
Another unusual feature that enforce cleanliness, is that Plan 9 kills
processes that only use the write end of the pipe.

rc, shell execute command like this:


<{...} # or when redirecting as input

The concept of notes to process wasn't obvious at first because of
the name, but making the comparison with Unix signals, it started to
make sense.
Similarly, like signals, they can be caught with a notification handler

Plumbing is pretty cool, it has ports to dispatch messages to
applications. It's kind of like mime-open and xdg-open in a way.

## Chapter 6

This chapter was about networking.

The network is a file on the disk, as with everything else. Somewhat
like linux proc/net/tcp which was inspired by Plan 9. Namely on Plan 9
we can have files such as /net/ether0.

One thing that feels a bit awkward is to send text as commands to files.
echo hangup >/net/tcp/14

I kind of think that it can be flimsy, unless there is a way to list
all the possible commands/notifications that a process can handle and
to limit processing unknown commands.

We also see the concept of translation of human readable names to
It reminds me of this but I hadn't covered Plan9 in it.

The network database, ndb in /lib/ndb/local is like NSS.
The equivalent of getent on Plan 9 is csquery. CS stands for "connection

The socket programming style is novel, different than BSD sockets,
and much simpler.

We get to also talk about registering services and running them.
We see /rc/bin/service which is kind of like an inetd if I understood

Lastly, we get reminded that the architecture is decoupled and that
commands are actually executed on a CPU server. We can explicitly do
that using rc command.
Long time nixers
Chapter 5 covers the basic IPC mechanisms for Plan 9. It begins with
IO redirection on rc (with the < and > operators) and on C (with dp(2)).
Redirection of one file descriptor to other other is much more different
on Plan 9. ">[1=2]" vs "1>&2".

Pipe is also explained both in rc(1) (which works like in UNIX sh(1)) and in
C (with pipe(2)).

rc(1) has <{}, a very useful construct that runs the command between
braces and expands to a pipe file with the output of that command.
Bash already does that with <(), but that's not in POSIX sh(1).

Plan 9 replaces UNIX signals with notes, which are strings "posted" into
a process' `/proc/$pid/note` file. The chapter illustrates this
mechanism with a program that prints the note that are posted into it.
It also introduces alarm(2), that posts a note containing `alarm` to the
process after some time has been passed.

The `ORCLOSE` flag for open(2) is then introduced. I wish UNIX had
that! With this flag, you do not need a signal handler to cleanup files
after the program is terminated.

The next session is about the /srv file descriptor bulletin board.
Apparently, that's plan 9 weird but interesting way to implement named

Chapter 6 is about networking and how it is represented in the file system.
I read this chapter some weeks ago but I have not wrote any notes about
it... So here's what I remember.

Through the chapter we design a simple echo server that we can use from
our Plan 9 machine. I used it to communicate between my Plan 9 guest
system to my host system.

At the end of the chapter we see how Plan 9 offers a simpler echo
service using only cat(1) (in a secript at /rc/bin/service/tcp7).

The way connections are controlled using writing into control files
was new to me.
Time for the book club review and discussion.

## Chapter 7

This chapter was captivating because it tackled aspects that I'm not
used to.
Here are some notes:

- The environment variables are cached in rc and for that reason you
need to start a new one so that they take effect. I'm not sure that's
very practical.

- The concept of namespace, using a name service, along with a translation
mechanism that resolves files/Chan that are stored on the file server
is pretty cool.
ns prints the current available namespaces, per process.
This is applied/passed when forking (flag RFNAMEG), and can be overriden
with Local to transfer the namespace to child processes.

- It's the 9p protocol that is used to talk with file servers

- The srv program is used to connect to a server and then creates a
file descriptor that will speak the appropriate protocol. It can then
be mounted.

- Bind is kind of like a more generic hardlink

- The /dev/drivers and device mounting conundrum, which is explained
with device names that start with #/ and that are omnipresent.

- Union mount, merging 2 directories in a bind and resolving conflict,
is something I've read about before.

## Chapter 8

This chapter was pretty uneventful, mostly because a lot of the shell examples
are familiar with Unix.

One thing to note, lists are like perl lists, flattened.

Another one is that single character concatenation is explained as
a subset/special case of the cross operator caret/^. I found that
Long time nixers
I had almost no time this week with my computer with the 9front virtual machine to run the code in the chapters and read them. I'm gonna review this week's chapters next saturday. Sorry about that.
Let's resume the book club.

# Chapter 9

Chapter 9 wasn't very exxeptional, most of it was about learning regex
related stuff.

there's a typo that hits hard in 9.4:
Quote:There is another tool is use extremely useful, which remains to be seen.

The end of chapter 9 is seninha's favorite, diving into AWK examples.

Apart from these, ramfs seems like a pretty nice idea as a command. I
know it's a replicated in Linux and other systems too. But I'm not sure
it's as easy as on Plan9.

# Chapter 10

This chapter was about the basic of concurrent programming, discussions
about race conditions, mutex (lock/unlock) and the specific application
to Plan9.

The naming is interesting: rendezvous to synchronize processes at a
certain position.

Quote:When a process calls rendezvous with a given tag, the process blocks until
another process calls rendezvous with the same tag, then exchange value.

Lastly, the concept of semaphore is actually really well explained,
I never knew it was a train metaphor.
Long time nixers
Chapter 9 is a continuation of chapter 8: shell scripting tools.
It also talks about regular expressions, grep, sed and awk.
Nothing that different from Unix.

The chapter ends with examples of file servers.
File server for archives (tarfs) is very interesting. And plan9's regular interface for archiving commands (compared to the multitude of interfaces of zip(1), tar(1), gzip(1), etc of UNIX) is something I miss on Unix.
I actually use plan9port's zip(1) and tar(1) on my OpenBSD rather than the default ones.

The tenth chapter begins by introducing the concepts of locks, critical region, mutual exclusion, etc.
Most of the chapter is about the theory of synchronization and locking (which is expected for a book for a uni course on operating systems).

The chapter ends by introducing how to implement semaphores in Plan 9.
Long time nixers
Because of festive reasons, next book club session will be delayed from 2021-12-25 to 2022-01-01.
Happy Holidays, everyone!
Long time nixers
Happy new year everyone!
That's the second to last session of the book club.
Just more two chapters to end this book.

Chapter 11

What we know as threads in the UNIX world, in Plan 9 is just a process that shares the memory with another and that is called with the RFMEM flag to rfork(2). What Plan 9 calls thread is a user-space flow of control created and controlled by the process itself. Therefore, the OS does not do any context switch between threads; the program itself must do that.

The chapter begins introducing threads and the difference between threads and light-weight processes (those processes that share memory).

Thread-related routines are provided by the thread library, which also contains the main() routine. We should write threadmain() instead for our main thread.

Then we are introduced to channels, a communication and context-switching mechanism between Plan 9 threads.

One problem with Plan 9 threads is that a blocking operation, such as I/O, blocks the entire process, rather than blocking a single thread. The thread library provides a proccreate(2) routine we can use to create a new thread wrapped in a new process.

To “poll” multiple channels, there's the alts(2) routine, which receives an array of Alt structures containing the channel operations.

The chapter ends with a notice on how to use other routines with the thread library. There are alternatives to exec(2), exits(2), wait(2), and atnotify(2) that are “multi-thread safe” in Plan 9, especially when using threads wrapped inside processes: procexec(2), threadexits(2), threadwaitchan(2), and threadnotify(2).

Chapter 12

The chapter talks about some I/O drivers, such as #c driver (console), #m driver (mouse), and the #v driver (vga). The files provided by those drivers are multiplexed by rio for each window.

It begins by explaining how the #c driver “cooks” the text typed at the keyboard. Things are a bit different in 9front than what is described in the book. In special, reading from '#c/cons' yields:

cat: error reading #c/cons: the front fell off

Asking on #cat-v, I got the following answer:

Quote:basically, devcons no longer does keyboard translation, that's userspace

Runes (unicode characters) can be typed using the compose key, which is related to X11's compose key. There is a handy Compose+X+NNNN key chord for inserting a rune by its unicode codepoint. My X11 also does that (because I listed, by hand, all the possible 2-byte codepoints in my XCompose file. It also talks about the rune(2) routines for handling runes.

One interesting feature of the print(2) function is that we can install verbs (that's how Plan 9 (and golang) calls the printf-like percent formatting directives). See fmtinstall(2).

Now I'm having some xlib vibes by using the draw(2) library: We establish a connection to the draw device, which sets a Display structure that represents such connection. Screen is the “drawable” (or in Plan 9, a pointer to an Image) where we draw on.

The chapter introduces the threaded routines for handling graphical/mouse/keyboard events. There is also an event library for non-threaded programs.
Book club time, happy new year.

# Chapter 11

A chapter about threads and channels.

Threads are independent of processes and so they have their own threadID.
I think we call that user-level threads in comparison with the different
types of mapping of kernel-level threads out there, user-level threads
are many-to-one.
I was once wondering about benchmarks, but it seems it's not very

Quote:One problem with Plan 9 threads is that a blocking operation, such as I/O, blocks the entire process, rather than blocking a single thread. The thread library provides a proccreate(2) routine we can use to create a new thread wrapped in a new process.
I hadn't thought of that but yes.

There is no main when including thread.h, the entry point is threadmain instead.
Interestingly to create thread we pass a stack size.

Channel concept is very interesting, clean. It
reminds me of the same concept I've seen in Rust

# Chapter 12

Chapter 12 is about user input/output.
It's pretty linear, going from driver to driver and checking what they do.
They're all files starting with #.

Console is `#c/cons` file.
You can use `#c/kprint` to read what's written to that console.

Then we learn that there are cooked mode terminal and raw ones. Similar to the line on Unix (line at a time).
`/dev/consctl` can be used to switch between raw and cooked mode.
One nice thing is that in cooked mode there's a "hold mode", enabled
with escape, to send multiple lines at once instead of directly.

Plan9 uses unicode, it was the first system to use it. It calls characters
"runes", 16-bit UTF-8.
The alt gr system is similar to the one with libinput/X11.

Mouse input driver is in #m and shows in a virtual file the mouse events /dev/mouse.

Video driver is in #v, aux/vga and /dev/vgactl can be used to control
the vga driver.
On that the display and screen globals in the code makes the programming
a bit weird.

Finally, controlling windows with files is pretty fun.
Alright, last two chapters of the book!

# Chapter 13

This chapter is about building a file server using P9 proto.

It starts by describing disk devices, devices defined as `/dev/sd*`.
The driver can be controled with /dev/sd<..>/ctl
For example: /dev/sdD0/data will be an abstraction of data on disk. (raw)
The disk is partitioned under a plan9 partition, with sub-ones.

The utilities used to do that are fdisk for the whole disk partitions
and disk/prep for plan9 ones.
We can also create partition by sending commands (echo) to the ctl of
the disk but it's wiser to use fdisk to avoid mistakes.

This kind of reminds me of this research I had done on disks storage:

The kfs or fossil command are used to manipulate/create/format the filesystem.

The next part of the chapter is about learning about 9p protocol, which
is akin to CIFS and NFS.
We dive a bit into traces of requests and responses of the protocol.

The goal, as mentioned at the start of the chapter is to build a file
server that will handle these 9P requests.

To do this, we have to initialize an Srv struct, which is a struct with
pointers to definitions of method. It's kind of like the virtual file
system in a way, similar calls too.
It's "plugged" into the system through postmountsrv function, basically
running the 9p server implementation.

An NB here is that instead of using malloc, we must use emalloc9p. "The
9P library provides implementations for emalloc9p, erealloc9p, and
estrdup9p that mimic the ones with a similar name in the C library".

The example of a semaphore as a server is such a bad example. They
could've chosen something else that is much more obvious.

The chapter ends with the Plan9 build system, an equivalent of Makefiles
with a similar syntax that is called mkfile and built with the mk command.

# Chapter 14

The final chapter is on security.

Quote:Plan 9 are not supposed to have local storage nor any other local resource
to protect!
A Plan 9 terminal is just a machine to connect to the rest of services
in the network
That's a nice take on security. Terminals are single user machines,
expected to have nothing on them, and nothing to hide.

Quote:; cat /dev/hostowner
; cat /dev/sysname
It may be a surprise, but the machine name is irrelevant for security
purposes. Only the host owner is relevant.
So these are irrelevant too.

To make sense of Plan9 security we have to think in a distributed way.
Each server is responsible for the protection of its content. Doing
user authorization and authentication.
Authentication is then delegated to a separate node, an authentication
server. But this server itself doesn't store the keys, they are stored
in a keyfs (sort of like an HSM, but in software like a java keystore).

This sort of reminds me of OAuth2, with identity servers, or maybe even Vault.
They are grouped into authentication domains, user@domain.

All auth is implemented in a program called factotum, an authentication
agent. Like an ssh-agent, sort of.

I wasn't so satisfied with the last chapters, I felt they missed the
point of explaining by getting lost in the details, it was burdening
the reading processing.
Frankly, even though it covers generic OS topics, I'm not sure it would
be the book I'd recommend to students studying operating systems.
The first few chapters were interesting to discover Plan9 but afterwards
it went downhill for me.
Long time nixers

The chapter begins with an introduction to the sd(3) device (#S) and the files it serves; this device is usually bound to /dev. There's a global control file (/dev/sdctl) and one directory for each disk. On each disk directory, there is another control file, one file for each partition (such as data, which represents the entire disk), and a raw file for low-level commands.

Reading the disk's control file lists some disk information, such as the start and end sectors of each partition. Writing to the disk's control file modifies its partition table (by creating or deleting a partition, for example).

There is also the fdisk(8) and prep(8) commands to modify a disk's partition table. It seems that Plan 9 uses a two-level partition scheme: the fdisk(8) partitions and the prep(8) partitions. Just like OpenBSD has the fdisk(8) partitions and the disklabel(8) partitions.

The chapter then instructs how to format a partition with the old kfs file system. I don't think that format is known by 9front, which knows the cwfs and hjfs file systems.

The next section details a conversation between Plan9 and a file server using the 9P protocol. They begin by agreeing with a protocol version and the maximum size for a message.

Our first file server is one that serves semaphores as files. It's a really straight forward file server and very easy to understand. The chapter also mentions /sys/src/cmd/ramfs.c as another example of simple file server.

The chapter ends with a introduction on how to write an idiomatic mkfile, and how to test our programs using the shell and leak(1).


The last chapter is about security.
It begins by explaining who is the host owner and what powers he has.

Each server is responsible for its own security. File servers act as a
relay for factotum, which is the authentication agent.

The book is interesting and got me into plan 9 programming, but it
diverges into tangents a lot of times.