Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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:

  1. 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.)

  2. 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.

share|improve this question
add comment

3 Answers

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.

share|improve this answer
    
Hmm 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 –  Posco Grubb Dec 16 '09 at 20:34
add comment
up vote 1 down vote accepted

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"?

share|improve this answer
    
Go for it! It's your question, after all, and none of us got you all the way there. –  phresus Dec 18 '09 at 13:01
add comment

Init itself generally creates initctl. However, you need the following:

/etc/inittab must contain an entry for initdefault. Secondly, send SIGUSR1 to init after /dev is remounted on the proper root, which will force init to reread the configuration.

share|improve this answer
    
there 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 as telinit, since its PID is not 1? Frustrating. –  Posco Grubb Dec 16 '09 at 23:29
    
You can either pass init=/linuxrc or rename /linuxrc to /sbin/init (which is just a shell script in the initrd). –  phresus Dec 17 '09 at 12:40
    
I tried adding init=/linuxrc and it still didn't run with PID 1. Apparently I also needed root=/dev/ram0 rw. I have no idea why this would make a difference. Any enlightenment would be appreciated! –  Posco Grubb Dec 17 '09 at 23:06
    
The initrd is pulled out to a ramdisk, and that's treated as your root until switchroot or pivot_root. Why it's necessary for linuxrc to get PID 1, I'm not sure about –  phresus Dec 18 '09 at 13:00
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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