Add documentation for parallel-debian
This commit is contained in:
parent
d32dd476f7
commit
8020f444cf
|
|
@ -1,38 +0,0 @@
|
||||||
Experimenting with multiple roots
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
$ qemu-img create debian.img 600M
|
|
||||||
$ mkfs.ext2 debian.img
|
|
||||||
$ mkdir debian-mnt
|
|
||||||
$ mount -o loop debian.img debian-mnt
|
|
||||||
$ debootstrap wheezy debian-mnt
|
|
||||||
$ chroot debian-mnt
|
|
||||||
$ apt-get install linux-image-3.0.0
|
|
||||||
Control-d
|
|
||||||
$ cp debian-mnt/boot/vmlinuz* .
|
|
||||||
$ cp debian-mnt/boot/initrd* .
|
|
||||||
$ umount debian-mnt
|
|
||||||
|
|
||||||
You now have a Debian disk image in debian.img and a kernel+initrd that are bootable with qemu.
|
|
||||||
|
|
||||||
Modifying the image
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The first thing I did was re-mount the image, and move almost everythig
|
|
||||||
(/boot, /var, /etc), except lost+found to a new directory "r0".
|
|
||||||
|
|
||||||
Then I started hacking on the initrd, making understand how to chroot
|
|
||||||
to "r0".
|
|
||||||
|
|
||||||
This means that after booting, every process would be in /r0 -
|
|
||||||
including any hacktree process. Assuming objects live in say
|
|
||||||
/objects, we need some way for hacktree to switch things. I think
|
|
||||||
just chroot breakout would work. This has the advantage the daemon
|
|
||||||
can continue to use libraries from the active host.
|
|
||||||
|
|
||||||
Note there is a self-reference here (as is present in Debian/Fedora
|
|
||||||
etc.) - the update system would at present be shipped with the system
|
|
||||||
itself. Should they be independent? That has advantages and
|
|
||||||
disadvantages. I think we should just try really really hard to avoid
|
|
||||||
breaking hacktree in updates.
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
From 0e22e86348bb356e69ed28a58e959b7fab7c43cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Colin Walters <walters@verbum.org>
|
||||||
|
Date: Sun, 16 Oct 2011 14:26:40 -0400
|
||||||
|
Subject: [PATCH] Add support for subroot= option
|
||||||
|
|
||||||
|
Passing this option causes the initrd to chroot() into a subdirectory of /.
|
||||||
|
This is useful for parallel installing multiple systems in one filesystem.
|
||||||
|
|
||||||
|
This relies on a patched switch_root from util-linux.
|
||||||
|
---
|
||||||
|
init | 32 +++++++++++++++++++++-----------
|
||||||
|
scripts/init-bottom/udev | 5 ++---
|
||||||
|
scripts/local | 6 ++++--
|
||||||
|
3 files changed, 27 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/init b/init
|
||||||
|
index 445c354..3ff2750 100755
|
||||||
|
--- a/init
|
||||||
|
+++ b/init
|
||||||
|
@@ -49,6 +49,8 @@ export init=/sbin/init
|
||||||
|
export quiet=n
|
||||||
|
export readonly=y
|
||||||
|
export rootmnt=/root
|
||||||
|
+export subroot=
|
||||||
|
+export rootsubmnt=
|
||||||
|
export debug=
|
||||||
|
export panic=
|
||||||
|
export blacklist=
|
||||||
|
@@ -68,6 +70,10 @@ for x in $(cat /proc/cmdline); do
|
||||||
|
init=*)
|
||||||
|
init=${x#init=}
|
||||||
|
;;
|
||||||
|
+ subroot=*)
|
||||||
|
+ subroot=${x#subroot=}
|
||||||
|
+ rootsubmnt=${x#subroot=}
|
||||||
|
+ ;;
|
||||||
|
root=*)
|
||||||
|
ROOT=${x#root=}
|
||||||
|
case $ROOT in
|
||||||
|
@@ -218,14 +224,18 @@ maybe_break mountroot
|
||||||
|
mountroot
|
||||||
|
log_end_msg
|
||||||
|
|
||||||
|
+if test -n "${rootsubmnt}"; then
|
||||||
|
+ rootsubmnt=${rootmnt}/${rootsubmnt}
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
maybe_break bottom
|
||||||
|
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom"
|
||||||
|
run_scripts /scripts/init-bottom
|
||||||
|
[ "$quiet" != "y" ] && log_end_msg
|
||||||
|
|
||||||
|
# Preserve information on old systems without /run on the rootfs
|
||||||
|
-if [ -d ${rootmnt}/run ]; then
|
||||||
|
- mount -n -o move /run ${rootmnt}/run
|
||||||
|
+if [ -d ${rootsubmnt}/run ]; then
|
||||||
|
+ mount -n -o move /run ${rootsubmnt}/run
|
||||||
|
else
|
||||||
|
# The initramfs udev database must be migrated:
|
||||||
|
if [ -d /run/udev ] && [ ! -d /dev/.udev ]; then
|
||||||
|
@@ -239,27 +249,27 @@ else
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move virtual filesystems over to the real filesystem
|
||||||
|
-mount -n -o move /sys ${rootmnt}/sys
|
||||||
|
-mount -n -o move /proc ${rootmnt}/proc
|
||||||
|
+mount -n -o move /sys ${rootsubmnt}/sys
|
||||||
|
+mount -n -o move /proc ${rootsubmnt}/proc
|
||||||
|
|
||||||
|
validate_init() {
|
||||||
|
checktarget="${1}"
|
||||||
|
|
||||||
|
# Work around absolute symlinks
|
||||||
|
- if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${checktarget}" ]; then
|
||||||
|
- case $(readlink "${rootmnt}${checktarget}") in /*)
|
||||||
|
- checktarget="$(chroot ${rootmnt} readlink ${checktarget})"
|
||||||
|
+ if [ -d "${rootsubmnt}" ] && [ -h "${rootsubmnt}${checktarget}" ]; then
|
||||||
|
+ case $(readlink "${rootsubmnt}${checktarget}") in /*)
|
||||||
|
+ checktarget="$(chroot ${rootsubmnt} readlink ${checktarget})"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure the specified init can be executed
|
||||||
|
- if [ ! -x "${rootmnt}${checktarget}" ]; then
|
||||||
|
+ if [ ! -x "${rootsubmnt}${checktarget}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Upstart uses /etc/init as configuration directory :-/
|
||||||
|
- if [ -d "${rootmnt}${checktarget}" ]; then
|
||||||
|
+ if [ -d "${rootsubmnt}${checktarget}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
@@ -273,7 +283,7 @@ if [ -n "${init}" ]; then
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Common case: /sbin/init is present
|
||||||
|
-if [ ! -x "${rootmnt}/sbin/init" ]; then
|
||||||
|
+if [ ! -x "${rootsubmnt}/sbin/init" ]; then
|
||||||
|
# ... if it's not available search for valid init
|
||||||
|
if [ -z "${init}" ] ; then
|
||||||
|
for inittest in /sbin/init /etc/init /bin/init /bin/sh; do
|
||||||
|
@@ -315,5 +325,5 @@ unset resume
|
||||||
|
unset resume_offset
|
||||||
|
|
||||||
|
# Chain to real filesystem
|
||||||
|
-exec run-init ${rootmnt} ${init} "$@" <${rootmnt}/dev/console >${rootmnt}/dev/console
|
||||||
|
+exec switch_root --subroot ${subroot} ${rootmnt} ${init} "$@" <${rootsubmnt}/dev/console >${rootsubmnt}/dev/console
|
||||||
|
panic "Could not execute run-init."
|
||||||
|
diff --git a/scripts/init-bottom/udev b/scripts/init-bottom/udev
|
||||||
|
index 375dfab..7922d0f 100755
|
||||||
|
--- a/scripts/init-bottom/udev
|
||||||
|
+++ b/scripts/init-bottom/udev
|
||||||
|
@@ -20,9 +20,8 @@ if [ -e /etc/udev/udev.conf ]; then
|
||||||
|
fi
|
||||||
|
|
||||||
|
# move the /dev tmpfs to the rootfs
|
||||||
|
-mount -n -o move /dev ${rootmnt}${udev_root}
|
||||||
|
+mount -n -o move /dev ${rootsubmnt}${udev_root}
|
||||||
|
|
||||||
|
# create a temporary symlink to the final /dev for other initramfs scripts
|
||||||
|
nuke /dev
|
||||||
|
-ln -s ${rootmnt}${udev_root} /dev
|
||||||
|
-
|
||||||
|
+ln -s ${rootsubmnt}${udev_root} /dev
|
||||||
|
diff --git a/scripts/local b/scripts/local
|
||||||
|
index 521e69a..25b518f 100644
|
||||||
|
--- a/scripts/local
|
||||||
|
+++ b/scripts/local
|
||||||
|
@@ -101,9 +101,11 @@ mountroot()
|
||||||
|
# FIXME This has no error checking
|
||||||
|
# Mount root
|
||||||
|
if [ "${FSTYPE}" != "unknown" ]; then
|
||||||
|
- mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
|
||||||
|
+ echo mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
|
||||||
|
+ mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt} || echo "FAILED TO MOUNT ROOT"
|
||||||
|
else
|
||||||
|
- mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
|
||||||
|
+ echo mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
|
||||||
|
+ mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt} || echo "FAILED TO MOUNT ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
|
||||||
|
--
|
||||||
|
1.7.6.4
|
||||||
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
From fa0e7df4e3d6550f0391bb3b81b2b6ac5165439d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Colin Walters <walters@verbum.org>
|
||||||
|
Date: Sun, 16 Oct 2011 21:01:46 -0400
|
||||||
|
Subject: [PATCH] switch_root: Add --subroot option
|
||||||
|
|
||||||
|
This is useful for parallel installing multiple operating system
|
||||||
|
roots. See: http://git.gnome.org/browse/hacktree
|
||||||
|
---
|
||||||
|
sys-utils/switch_root.8 | 4 ++++
|
||||||
|
sys-utils/switch_root.c | 31 +++++++++++++++++++++----------
|
||||||
|
2 files changed, 25 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sys-utils/switch_root.8 b/sys-utils/switch_root.8
|
||||||
|
index 34ab0d0..6981852 100644
|
||||||
|
--- a/sys-utils/switch_root.8
|
||||||
|
+++ b/sys-utils/switch_root.8
|
||||||
|
@@ -27,6 +27,10 @@ process.
|
||||||
|
show help and exit
|
||||||
|
.IP "\fB\-V, \-\-version\fP"
|
||||||
|
show version number and exit
|
||||||
|
+.IP "\-\-subroot\fP"
|
||||||
|
+Instead of calling chroot into the / of the new root, instead use the
|
||||||
|
+given argument. This helps parallel install multiple operating systems in one
|
||||||
|
+root filesystem.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
.B switch_root
|
||||||
|
diff --git a/sys-utils/switch_root.c b/sys-utils/switch_root.c
|
||||||
|
index 2dfed71..20ae5d6 100644
|
||||||
|
--- a/sys-utils/switch_root.c
|
||||||
|
+++ b/sys-utils/switch_root.c
|
||||||
|
@@ -108,7 +108,7 @@ done:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int switchroot(const char *newroot)
|
||||||
|
+static int switchroot(const char *newroot, const char *subroot)
|
||||||
|
{
|
||||||
|
/* Don't try to unmount the old "/", there's no way to do it. */
|
||||||
|
const char *umounts[] = { "/dev", "/proc", "/sys", NULL };
|
||||||
|
@@ -141,7 +141,7 @@ static int switchroot(const char *newroot)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (chroot(".")) {
|
||||||
|
+ if (chroot(subroot ? subroot : ".")) {
|
||||||
|
warn("failed to change root");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@@ -160,7 +160,7 @@ static int switchroot(const char *newroot)
|
||||||
|
|
||||||
|
static void usage(FILE *output)
|
||||||
|
{
|
||||||
|
- fprintf(output, "usage: %s <newrootdir> <init> <args to init>\n",
|
||||||
|
+ fprintf(output, "usage: %s [--subroot DIR] <newrootdir> <init> <args to init>\n",
|
||||||
|
program_invocation_short_name);
|
||||||
|
exit(output == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
@@ -175,22 +175,33 @@ static void version(void)
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *newroot, *init, **initargs;
|
||||||
|
+ char *subroot = NULL;
|
||||||
|
+ int argi;
|
||||||
|
|
||||||
|
- if (argv[1] && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
|
||||||
|
+ if (argc < 2)
|
||||||
|
+ usage(stderr);
|
||||||
|
+
|
||||||
|
+ argi = 1;
|
||||||
|
+ if ((!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
|
||||||
|
usage(stdout);
|
||||||
|
- if (argv[1] && (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-V")))
|
||||||
|
+ if ((!strcmp(argv[1], "--version") || !strcmp(argv[1], "-V")))
|
||||||
|
version();
|
||||||
|
- if (argc < 3)
|
||||||
|
+ if (argc > 3 && argv[1] && (!strcmp(argv[1], "--subroot"))) {
|
||||||
|
+ subroot = argv[2];
|
||||||
|
+ argi = 3;
|
||||||
|
+ }
|
||||||
|
+ if (argc <= argi+1) {
|
||||||
|
usage(stderr);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- newroot = argv[1];
|
||||||
|
- init = argv[2];
|
||||||
|
- initargs = &argv[2];
|
||||||
|
+ newroot = argv[argi];
|
||||||
|
+ init = argv[argi+1];
|
||||||
|
+ initargs = &argv[argi+1];
|
||||||
|
|
||||||
|
if (!*newroot || !*init)
|
||||||
|
usage(stderr);
|
||||||
|
|
||||||
|
- if (switchroot(newroot))
|
||||||
|
+ if (switchroot(newroot, subroot))
|
||||||
|
errx(EXIT_FAILURE, "failed. Sorry.");
|
||||||
|
|
||||||
|
if (access(init, X_OK))
|
||||||
|
--
|
||||||
|
1.7.6.4
|
||||||
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
|
||||||
|
Experimenting with multiple roots
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
<http://wiki.debian.org/QEMU#Setting_up_a_testing.2BAC8-unstable_system>
|
||||||
|
|
||||||
|
Follow the steps for making a disk image, downloading the business
|
||||||
|
card CD, booting it in QEMU and running through the installer.
|
||||||
|
|
||||||
|
Test that the image works after installation too, before you start
|
||||||
|
modifying things below! Remember to remove the -cdrom and -boot
|
||||||
|
options from the installation QEMU command.
|
||||||
|
|
||||||
|
Modifying the image
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
You now have a disk image in debian.img, and the first partition
|
||||||
|
should be ext4.
|
||||||
|
|
||||||
|
The first thing I did was mount the image, and move almost everythig
|
||||||
|
(/boot, /var, /etc), except lost+found to a new directory "r0".
|
||||||
|
|
||||||
|
$ mkdir /mnt/debian
|
||||||
|
$ modprobe nbd max_part=8
|
||||||
|
$ qemu-nbd --connect=/dev/nbd0 debian.qcow
|
||||||
|
$ mount /dev/nbd0p1 /mnt/debian/
|
||||||
|
$ cd /mnt/debian
|
||||||
|
$ mkdir r0
|
||||||
|
$ DIRS="bin boot dev etc lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var"
|
||||||
|
$ mv $DIRS r0
|
||||||
|
|
||||||
|
Now with it still mounted, we need to move on to the next part -
|
||||||
|
modifying the initrd.
|
||||||
|
|
||||||
|
Then I started hacking on the initrd, making understand how to chroot
|
||||||
|
to "r0". I ended up with two patches - one to util-linux, and one to
|
||||||
|
the "init" script in Debian's initrd.
|
||||||
|
|
||||||
|
See:
|
||||||
|
0001-switch_root-Add-subroot-option.patch
|
||||||
|
0001-Add-support-for-subroot-option.patch
|
||||||
|
|
||||||
|
$ git clone --depth=1 git://github.com/karelzak/util-linux.git
|
||||||
|
$ cd util-linux
|
||||||
|
$ patch -p1 -i ../0001-switch_root-Add-subroot-option.patch
|
||||||
|
$ ./autogen.sh; ./configure ; make
|
||||||
|
|
||||||
|
Now you have a modified "sys-utils/switch_root" binary. Let's next
|
||||||
|
patch the initrd and rebuild it:
|
||||||
|
|
||||||
|
Make a backup:
|
||||||
|
|
||||||
|
$ mkdir initrd
|
||||||
|
$ cp /mnt/debian/boot/initrd.img-3.0.0-1-amd64{,.orig}
|
||||||
|
|
||||||
|
Unpack, and patch:
|
||||||
|
|
||||||
|
$ zcat /mnt/debian/boot/initrd.img-3.0.0-1-amd64 | (cd initrd; cpio -d -i -v)
|
||||||
|
$ (cd initrd && patch -p1 -i ../0001-Add-support-for-subroot-option.patch)
|
||||||
|
|
||||||
|
Repack:
|
||||||
|
|
||||||
|
$ (cd initrd; find | cpio -o -H newc) | gzip > /mnt/debian/boot/initrd.img-3.0.0-1-amd64.new
|
||||||
|
$ mv /mnt/debian/boot/initrd.img-3.0.0-1-amd64{.new,}
|
||||||
|
|
||||||
|
Running hacktree inside the system
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
This means that after booting, every process would be in /r0 -
|
||||||
|
including any hacktree process. Assuming objects live in say
|
||||||
|
/objects, we need some way for hacktree to switch things. I think
|
||||||
|
just chroot breakout would work. This has the advantage the daemon
|
||||||
|
can continue to use libraries from the active host.
|
||||||
|
|
||||||
|
Note there is a self-reference here (as is present in Debian/Fedora
|
||||||
|
etc.) - the update system would at present be shipped with the system
|
||||||
|
itself. Should they be independent? That has advantages and
|
||||||
|
disadvantages. I think we should just try really really hard to avoid
|
||||||
|
breaking hacktree in updates.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if test -f debian.img; then
|
||||||
|
echo debian.img already exists
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
qemu-img create debian.img 600M
|
||||||
|
mkfs.ext2 -q -F debian.img
|
||||||
|
mkdir -p debian-mnt
|
||||||
|
mount -o loop debian.img debian-mnt
|
||||||
|
debootstrap --arch amd64 wheezy debian-mnt
|
||||||
|
umount debian-mnt
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
DIRS="bin boot dev etc lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var"
|
||||||
|
|
||||||
|
if ! test -f debian.img; then
|
||||||
|
echo need debian.img
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mount -o loop debian.img debian-mnt
|
||||||
|
cd debian-mnt
|
||||||
|
if ! test -d r0; then
|
||||||
|
mkdir r0
|
||||||
|
mv $DIRS r0
|
||||||
|
fi
|
||||||
|
cd ..
|
||||||
|
umount debian-mnt
|
||||||
Loading…
Reference in New Issue