Custom initrd init script: how to create /dev/initctl
Solution 1
As phresus answered, init
creates /dev/initctl
.
The problem I was having was that my /linuxrc
script was not running with PID 1. Thus, when it executed init
, it also was not running with PID 1. init
not running as PID 1 behaves as telinit
.
To get /linuxrc
to run with PID 1, I needed the following on the kernel boot line: root=/dev/ram0 rw init=/linuxrc
, as described in this forum.
Now it's all working. With the VM booted, the output of mount
is
aufs on / type aufs (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
Yay! BTW, is it kosher to mark my own answer as "the answer"?
Solution 2
If you're already using a virtualization solution, why are you going through all this trouble? The simplest solution would be to use something like LVM on your host, which already has snapshot support, and present a snapshot to your VM. That is:
- Create a logical volume (LV) that will hold your root filesystem.
- Create a snapshot of this LV
- Configure your VM to boot from the snapshot.
If you want to revert back to the clean filesystem, delete the snapshot and recreate it. Easy, and no fiddling about with initrd or aufs -- in fact, it doesn't require any modifications to the guest OS.
Related videos on Youtube
dilip
Updated on September 17, 2022Comments
-
dilip over 1 year
I have a virtual machine (VMM is Xen 3.3) equipped with two IDE HDD's (/dev/hda and /dev/hdb). The root file system is in /dev/hda1, where Scientific Linux 5.4 is installed. /dev/hdb contains an empty ext2 file system.
I want to protect the root file system from writes by the VM by using aufs (AnotherUnionFS) to layer a writable file system on top of the root file system. The changes to / will be written to the file system located on /dev/hdb. (Furthermore, outside the VM, the file backing the /dev/hda will also be set to read-only permissions, so the VMM should also prevent the VM from modifying at that level.) (The purpose of this setup: be able to corrupt a virtual machine using software-implemented fault injection but preserve the file system image in order to quickly reboot the VM to a fault-free state.)
How do I get an initrd init script to do the necessary mounts to create the union file system?
I've tried 2 approaches:
I've tried modifying the nash script that mkinitrd creates, but I don't know what setuproot and switchroot do and how to make them use my aufs as the new root.
Apparently, nobody else here knows either.(EDIT: I take that back.)I've tried building a LiveCD (using linux-live-6.3.0) and then modifying the Bash /linuxrc script from the generated initrd, and I got the mounts correct, but the final /sbin/init complains about /dev/initctl.
Specifically, my /linuxrc mounts the aufs at /union. The last few lines of /linuxrc effectively do the following:
cd /union mkdir -p mnt/live pivot_root . mnt/live exec sbin/chroot . sbin/init </dev/console >/dev/console 2>&1
When init starts, it outputs something like
init: /dev/initctl: No such file or directory
. What is supposed to create this FIFO? I found no such filename in the original linuxrc and liblinuxlive scripts.I tried creating it via "mkfifo /dev/initctl", but then init complained about a timeout opening or writing to the FIFO.
Would appreciate any help or pointers. Thanks.
-
dilip over 14 yearsHmm wow. I had no idea LVM could manage <b>writable</b> snapshots. I will consider implementing this option. The LVM HOWTO explicitly mentions this as [a solution for VMs][1]. [1]:tldp.org/HOWTO/LVM-HOWTO/snapshotintro.html
-
dilip over 14 yearsthere is an
initdefault
entry in my /etc/inittab. I just discovered by running ash within /linuxrc just before the pivot_root that /linuxrc is not running as PID 1 (its PID was 300). That's odd. Doesn't this mean that when it exec's init, init will behave astelinit
, since its PID is not 1? Frustrating. -
user1283002 over 14 yearsYou can either pass
init=/linuxrc
or rename /linuxrc to /sbin/init (which is just a shell script in the initrd). -
dilip over 14 yearsI tried adding
init=/linuxrc
and it still didn't run with PID 1. Apparently I also neededroot=/dev/ram0 rw
. I have no idea why this would make a difference. Any enlightenment would be appreciated! -
user1283002 over 14 yearsThe initrd is pulled out to a ramdisk, and that's treated as your root until
switchroot
orpivot_root
. Why it's necessary for linuxrc to get PID 1, I'm not sure about -
user1283002 over 14 yearsGo for it! It's your question, after all, and none of us got you all the way there.