10

Why does Linux allow ‘init=/bin/bash’?

I read this, answers are saying it's KERNEL running this init program.

Then I started to wonder, Linux usually comes with a initramfs, which will eventually mount and pivot_root to real root filesystem. So what does this init argument mean? The path in the initramfs? Or like I guessed, it's not read by the kernel but by init of initramfs to exec the real init.

Also, the root=UUID=xxxx argument, is that really read by kernel or just by init of initramfs to find the real root filesystem?

It seems like I can pass any argument I want as kernel arguments, so are they all read by the kernel or at least some of them are only meaningful to userspace programs?

16

Parameters passed on the kernel command line don’t have to be meaningful for the kernel: the kernel parameters documentation says

The kernel parses parameters from the kernel command line up to “–”; if it doesn’t recognize a parameter and it doesn’t contain a ‘.’, the parameter gets passed to init: parameters with ‘=’ go into init’s environment, others are passed as command line arguments to init. Everything after “–” is passed as an argument to init.

This doesn’t apply to init and root which really are kernel parameters, and are handled by the kernel. They can also be acted upon by user-space, since they appear in /proc/cmdline. (Thus for example systemd takes the quiet kernel parameter into account to reduce its output.)

When the kernel is booted with an initramfs, the init and root parameters aren’t used by the kernel directly; as far as the kernel is concerned, they are fall-backs in case the initramfs doesn’t work (but they are still kernel parameters). The initramfs itself is the root file system (at least for booting), and the kernel looks for an init executable in the root directory of the initramfs and runs that. If anything fails (the initramfs isn’t usable, or doesn’t contain /init, or the latter isn’t executable), the kernel will try to mount the device specified by its root parameter, and run /sbin/init or the executable specified by the init parameter.

  • Also a little curious, what if init-in-the-initramfs is a set-uid-non-root file? A file without executable bit? Will it be run as root anyway? What if it's broken ELF or can't find ld-linux.so ELF or recursion-too-deep script or anything just can't be execve? – 炸鱼薯条德里克 Oct 4 '18 at 14:58
  • 3
    I'm pretty sure the kernel doesn't load the program specified in "init=" from the initramfs. It an initramfs is in use then it seems to run as normal before the user-specified init program is run (not sure if it's the kernel that does this or code in the initramfs). – plugwash Oct 4 '18 at 15:31
  • 2
    @plugwash you’re right, the kernel runs /init from the initramfs, and if that doesn’t exist, tries to run the program specified in init=, or /sbin/init, from the root file system. – Stephen Kitt Oct 4 '18 at 15:40
3

Passing custom kernel arguments is one way to customize a system during a KickStart install, for example a PXE server could set:

linuxefi /c7/vmlinuz ks=http://.../ks/c7 lab ksdevice=eth0 net.ifnames=0 biosdevname=0

where lab is then used in the KickStart configuration to do different things than for other system builds:

%pre
...
case " $(cat /proc/cmdline)" in
   ...
   *\ lab*)
      filesystems_lab
      ;;
   *)
      filesystems_common
      ;;
...

Here to setup a different filesystem layout than used on other system types. Hopefully different labels are used for local customizations than are used by the kernel, given the single namespace involved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.