1

My understanding is that, at least in early user space, init is a shell script that cannot be exited from. Is this correct?

So what happens when it comes to an end?

I am aware that in a typical bootup sequence, the init shell script in early user space would mount the root file system then transition control to the init from the new root. BUT assuming that did not happen - that root was not mounted and control not transitioned to the new root init - what would happen when the init script comes to an end?

Duke Dougal
  • 1,025
  • 4
  • 18
  • 28

2 Answers2

1

My understanding is that, at least in early user space, init is a shell script that cannot be exited from. Is this correct?

It doesn't have to be a shell script. You can certainly exit from the init process. It will cause a kernel panic, but it can be done.

So what happens when it comes to an end?

The script usually has a line like exec switch_root /root "$@". Because it uses exec, the same process ID is overlaid with a new binary to run.

Thus the program that is init changes and the kernel never sees an exit from the init process.

In turn, switch_root execs the root filesystem's /sbin/init after cleaning up the initramfs and bind-mounting /root to /. So init always remains PID 1.

You can see the source code of BusyBox's switch_root here, it's quite simple really: https://git.busybox.net/busybox/plain/util-linux/switch_root.c There is also a long comment at the end explaining a bit of what goes on under the hood.

  • say I wanted to never switch to the hard disk root, and wanted to stay in the early user space initramfs forever, how should I end my init shell script? – Duke Dougal Dec 02 '16 at 06:55
0

The init process, /sbin/init is not a shell script and it doesn't exit (under normal conditions).
From https://en.wikipedia.org/wiki/Init

In Unix-based computer operating systems, init (short for initialization) is the first process started during booting of the computer system. Init is a daemon process that continues running until the system is shut down.
It is the direct or indirect ancestor of all other processes and automatically adopts all orphaned processes.

It is the first user space process the kernel fork and exec's after the kernel has initialised itself. Thats why its called PID1 (process id 1).

There are different implementations nowadays of the init process, e.g. upstart or systemd, with the original implementations being based on systemV init.

What they all basically do is - on boot - read configuration files for each process that is a candidate to be launched. Traditionally these config files are located in /etc/init/. If the process is flagged for launch then the process is started or - if its config says "don't start me on boot" then its not started, but may still be started manually later.
If the process is flagged for launch the way - traditionally - that they would have been started is that the init system would execute a shell script corresponding to the daemon in /etc/init.d/.

Some of the differences between newer init systems and the original system V init is that system V uses numeric run levels, 0,1,2, etc to determine system state and systemd or upstart use named identifiers like mulit-user.target.

Also - I believe - newer init systems launch daemons themselves and use their own so called "unit" files to define config directives rather than invoke a shell script.

e.g for nginx there is a config file /lib/systemd/system/nginx.service which defines startup directives like:

[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

[Install]
WantedBy=multi-user.target

You would enable it with a command like sudo systemctl enable nginx.service this will create a symlink in

/etc/systemd/system/multi-user.target.wants/nginx.service

pointing to the unit file in:

/lib/systemd/system/nginx.service

sudo systemctl disable nginx.service would remove the symlink and the service won't be launched on startup.

Newer init systems are backward compatible with systemV init scripts and will read configs in /etc/init and launch shell scripts in /etc/init.d

  • Well, OP was asking about the init in an initramfs, which commonly is a shell script and is used to load necessary firmware and drivers before the root partition with the final init can even be mounted. – DepressedDaniel Dec 02 '16 at 06:37
  • @DepressedDaniel oh ok. I havent come across initramfs before . can you tell me what it is? – the_velour_fog Dec 02 '16 at 06:40
  • @the_velour_fog: The initial RAM-based file system, the file system available before mounting the root file system. – AlexP Dec 02 '16 at 09:17
  • @AlexP ah cool, thanks. Yes thats the thing about linux is there are alot of things you need to learn - even though you don't necessarily need to use that knowledge that often! – the_velour_fog Dec 02 '16 at 09:30