C Init: mounted root by kernel guaranteed? and other questions.

I'm developing an init system for many POSIX/POSIX-like systems and after reviewing part of the FreeBSD Architecture Handbook as well as part of the kernel source it appears that upon calling the init binary that it's guaranteed that root will already be mounted. I just want to verify if this is correct or if there are situations where this could turn out to be false.

I hope it's not improper to ask but is this true of all BSD and/or XNU/Darwin? Finally, is there any mandate to ensure that /etc/fstab exists on root? If there is an entry for root in /etc/fstab and it doesn't match the mounted root (upon init) then should any action be taken?
 
I think in traditional Unixes (both the AT&T and the Berkeley ones) the kernel mounts the root file system before starting init. Now, that doesn't mean that it is "guaranteed", in the sense that there is a standards body that says "if you want to be XX-compliant (for example XX=Posix), you have to do it that way". After all, init is co-developed with the kernel, and there are no standards for the interface between the kernel and init. There may be exceptions in unusual systems.

Consider the alternatives: Imagine you are trying to develop a new init. Imagine what you would do if you are started, and there is no root file system mounted yet. If you knew which device it is on, and had all the required knowledge (like mount options, what type of file systems), you could call the mount(2) system call. First problem: That call is not standardized (it's not part of Posix). Second serious problem: How are you going to find this information? You can't look in /etc/fstab, because it it not mounted yet. So if it were possible that init would have to do the mount of the root file system, it would have to get that information from elsewhere. For example as "command line parameters" in argc/argv from its "caller" (usually that would be a shell, in the case of init it's the kernel). For this to work, you'd have to co-develop init with the kernel to pass these parameters. If you do all that work, you might as well have the kernel do the mount - thereby reducing it to a problem already solved.

By the way, where does the kernel get that information from? Special parameters passed in by the boot loader (or a kernel command line if an interactive boot is used). It does not use anything stored solely on the root file system to find the root file system.

Then you ask whether /etc/fstab has to exist, and whether it has to be on the root file system (which is the same question as whether the /etc can be a separate file system). First: if it were on a file system other than root, that would be useless, since the kernel only mounts the root file system, and then the whole init process (the init executable and all the rc scripts) would never find it. Second: I think it is legal to not have an /etc/fstab file; in that case, only the root file system is mounted.

And last you ask: What if the root entry in /etc/fstab doesn't match what is actually mounted, what should your init do? Well, let's consider what it could do. It could for example crash the system deliberately (sort of like an assert), and tell the user in an error message that they misconfigured the system by editing /etc/fstab without updating the kernel parameters. That would be worse than useless, it would turn a small human error into a permanent outage. It could print an error message in syslog or dmesg. That would be somewhat useful, since it at least tells the admin that they did something silly. It could actually remount the root file system the correct way; this is obviously dangerous, since at this point files are already open (and remounting an already mounted file system is rather difficult, look at all the complexity of pivoting root in Linux). For example: what if the new root file system has a different init binary than the one that was used previously, then init knows that it shouldn't be running - but blowing up was already decided to be a bad idea. Exec'ing the new init is at least dangerous (since this init can't be sure how to pass parameters to the new init), and it would turn a minor misconfiguration (wrong entry in /etc/fstab) into a hard crash if the new init doesn't actually work (for example because the other file system is a typo, and not intended to be a root file system, and has something completely different in its directory .../sbin/init which was never intended to be the init program). I think in summary, there is nothing sensible to do if the entry in /etc/fstab is wrong. One of my former colleagues had a good way to describe this situation: "Don't ask a question, if you aren't prepared to handle the answer."
 
I think in traditional Unixes (both the AT&T and the Berkeley ones) the kernel mounts the root file system before starting init. Now, that doesn't mean that it is "guaranteed", in the sense that there is a standards body that says "if you want to be XX-compliant (for example XX=Posix), you have to do it that way".
I was speaking specifically about FreeBSD. To date, do all free distributed FreeBSD systems have root mounted upon calling init?

After all, init is co-developed with the kernel, and there are no standards for the interface between the kernel and init. There may be exceptions in unusual systems.
I don't care about customized kernels, I'm really just referring to stock FreeBSD kernels. Are there any exceptions in stock FreeBSD kernels?

What if the root entry in /etc/fstab doesn't match what is actually mounted, what should your init do? Well, let's consider what it could do.
I don't care about what it could do, I care about what it's expected to do. In this context, what is the behavior of current init systems for FreeBSD?


You are really overthinking my questions. All I want to know is the behavior of stock distributed FreeBSD systems and others BSDs if you by chance knew. I'm trying to target the maximum number of computers, not every computer. Perfect is the enemy of good.
 
My experience with installing and administering *BSD only goes back about 10 or 15 years. And I have not done a detailed analysis of the source code. With those disclaimers: Yes, the kernel mounts the root file system. Actually, init(8) itself does not normally mount anything; the mounting of other file systems happens in various /etc/rc.d/* scripts (which are started by init).

And what happens if the root entry in /etc/fstab disagrees with what is actually mounted? Good question. I just looked at the various /etc/rc.d scripts, and the only thing I found that touches the root file system is optionally remounting it read-wrote (if it was mounted read-only), but that's done without an explicit reference to /etc/fstab by calling mount -uw / (which just changes the read-write/read-only flag). My educated guess is: nobody ever checks, so nothing happens.

I think you can do a few things to find out: (a) Try it, by editing /etc/fstab and rebooting (and be ready to go into single-user mode to fix anything that goes wrong). (b) Read the source code to init and read the rc.d scripts. (c) Find a copy of the daemon book and hope that it explains how root is mounted (my copy is about 20 years old and in some cardboard box in the basement, it would take an hour to even find the book).
 
On FreeBSD, if the root entry in /etc/fstab points to for example /dev/da0p1 and you are booting from da1, the boot fails, and you are left at the mountroot prompt. Happens a lot when device order changes between machines. I don't have a t-shirt for this one :-D
 
Back
Top