From 4d86ee0a1d37d75765e566326d780e407b8a6e70 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 24 Oct 2011 22:02:16 -0400 Subject: [PATCH] Pile of work on parallel-debian --- .../0001-Add-support-for-subroot-option.patch | 148 ----------------- parallel-debian/0001-Support-OSTree.patch | 149 ++++++++++++++++++ .../0001-switch_root-Add-subroot-option.patch | 102 ------------ parallel-debian/debian-setup.sh | 20 +++ parallel-debian/gnomeos-make-image.sh | 93 +++++++---- parallel-debian/ostree_switch_root.c | 67 +++++--- src/libostree/ostree-checkout.c | 28 +++- src/ot-builtin-run-triggers.c | 2 + triggers.d/desktop-database.trigger | 1 + triggers.d/gdk-pixbuf.trigger | 1 + triggers.d/glib.trigger | 1 + triggers.d/gtk+.trigger | 1 + triggers.d/immodules.trigger | 1 + triggers.d/ldconfig.trigger | 1 + triggers.d/mime-database.trigger | 1 + triggers.d/pango.trigger | 1 + 16 files changed, 306 insertions(+), 311 deletions(-) delete mode 100644 parallel-debian/0001-Add-support-for-subroot-option.patch create mode 100644 parallel-debian/0001-Support-OSTree.patch delete mode 100644 parallel-debian/0001-switch_root-Add-subroot-option.patch create mode 100755 parallel-debian/debian-setup.sh diff --git a/parallel-debian/0001-Add-support-for-subroot-option.patch b/parallel-debian/0001-Add-support-for-subroot-option.patch deleted file mode 100644 index 5abf7c79..00000000 --- a/parallel-debian/0001-Add-support-for-subroot-option.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0e22e86348bb356e69ed28a58e959b7fab7c43cc Mon Sep 17 00:00:00 2001 -From: Colin Walters -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 - diff --git a/parallel-debian/0001-Support-OSTree.patch b/parallel-debian/0001-Support-OSTree.patch new file mode 100644 index 00000000..81fa4d4a --- /dev/null +++ b/parallel-debian/0001-Support-OSTree.patch @@ -0,0 +1,149 @@ +From e9cb0f0c6ef13773c823610f27a562bd54b2acd3 Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Mon, 24 Oct 2011 22:01:17 -0400 +Subject: [PATCH] Support OSTree + +See http://git.gnome.org/browse/ostree +--- + modules.d/95rootfs-block/mount-root.sh | 12 ++++++------ + modules.d/99base/init | 32 ++++++++++++++++++++++---------- + 2 files changed, 28 insertions(+), 16 deletions(-) + +diff --git a/modules.d/95rootfs-block/mount-root.sh b/modules.d/95rootfs-block/mount-root.sh +index 2c89431..4f411da 100755 +--- a/modules.d/95rootfs-block/mount-root.sh ++++ b/modules.d/95rootfs-block/mount-root.sh +@@ -34,8 +34,8 @@ mount_root() { + + READONLY= + fsckoptions= +- if [ -f "$NEWROOT"/etc/sysconfig/readonly-root ]; then +- . "$NEWROOT"/etc/sysconfig/readonly-root ++ if [ -f "$NEWROOT_PREFIX"/etc/sysconfig/readonly-root ]; then ++ . "$NEWROOT_PREFIX"/etc/sysconfig/readonly-root + fi + + if getargbool 0 "readonlyroot=" -y readonlyroot; then +@@ -57,7 +57,7 @@ mount_root() { + if [ -f "$NEWROOT"/forcefsck ] || getargbool 0 forcefsck ; then + fsckoptions="-f $fsckoptions" + elif [ -f "$NEWROOT"/.autofsck ]; then +- [ -f "$NEWROOT"/etc/sysconfig/autofsck ] && . "$NEWROOT"/etc/sysconfig/autofsck ++ [ -f "$NEWROOT_PREFIX"/etc/sysconfig/autofsck ] && . "$NEWROOT_PREFIX"/etc/sysconfig/autofsck + if [ "$AUTOFSCK_DEF_CHECK" = "yes" ]; then + AUTOFSCK_OPT="$AUTOFSCK_OPT -f" + fi +@@ -73,8 +73,8 @@ mount_root() { + rootopts= + if getargbool 1 rd.fstab -n rd_NO_FSTAB \ + && ! getarg rootflags \ +- && [ -f "$NEWROOT/etc/fstab" ] \ +- && ! [ -L "$NEWROOT/etc/fstab" ]; then ++ && [ -f "$NEWROOT_PREFIX/etc/fstab" ] \ ++ && ! [ -L "$NEWROOT_PREFIX/etc/fstab" ]; then + # if $NEWROOT/etc/fstab contains special mount options for + # the root filesystem, + # remount it with the proper options +@@ -89,7 +89,7 @@ mount_root() { + rootopts=$opts + break + fi +- done < "$NEWROOT/etc/fstab" ++ done < "$NEWROOT_PREFIX/etc/fstab" + + rootopts=$(filter_rootopts $rootopts) + fi +diff --git a/modules.d/99base/init b/modules.d/99base/init +index 36b2152..9636990 100755 +--- a/modules.d/99base/init ++++ b/modules.d/99base/init +@@ -275,6 +275,13 @@ unset queuetriggered + unset main_loop + unset RDRETRY + ++ostree=$(getarg ostree=) ++if test -n $ostree; then ++ NEWROOT_PREFIX=${NEWROOT}/ostree/$ostree ++else ++ NEWROOT_PREFIX=$NEWROOT ++fi ++ + # pre-mount happens before we try to mount the root filesystem, + # and happens once. + getarg 'rd.break=pre-mount' 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount" +@@ -287,14 +294,15 @@ getarg 'rd.break=mount' 'rdbreak=mount' && emergency_shell -n mount "Break mount + i=0 + while :; do + if ismounted "$NEWROOT"; then +- usable_root "$NEWROOT" && break; ++ echo "Checking usable $NEWROOT_PREFIX" ++ usable_root "$NEWROOT_PREFIX" && break; + umount "$NEWROOT" + fi + for f in $hookdir/mount/*.sh; do + [ -f "$f" ] && . "$f" + if ismounted "$NEWROOT"; then +- usable_root "$NEWROOT" && break; +- warn "$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook" ++ usable_root "$NEWROOT_PREFIX" && break; ++ warn "$NEWROOT_PREFIX has no proper rootfs layout, ignoring and removing offending mount hook" + umount "$NEWROOT" + rm -f "$f" + fi +@@ -320,11 +328,11 @@ unset __usr_found + for i in "$(getarg real_init=)" "$(getarg init=)" /sbin/init /etc/init /init /bin/sh; do + [ -n "$i" ] || continue + +- __p=$(readlink -m "$NEWROOT$i") ++ __p=$(readlink -m "$NEWROOT_PREFIX$i") + if [ -n "$__p" ] \ + && [ "x$__usr_found" = "x" ] \ + && [ ! -x "$__p" ] \ +- && strstr "$__p" "$NEWROOT/usr" \ ++ && strstr "$__p" "$NEWROOT_PREFIX/usr" \ + ; then + # we have to mount /usr + while read dev mp fs opts rest; do +@@ -333,14 +341,14 @@ for i in "$(getarg real_init=)" "$(getarg init=)" /sbin/init /etc/init /init /bi + __usr_found="1" + break + fi +- done < "$NEWROOT/etc/fstab" >> /etc/fstab ++ done < "$NEWROOT_PREFIX/etc/fstab" >> /etc/fstab + if [ "x$__usr_found" != "x" ]; then + info "Mounting /usr" +- mount "$NEWROOT/usr" 2>&1 | vinfo ++ mount "$NEWROOT_PREFIX/usr" 2>&1 | vinfo + fi + fi + +- __p=$(readlink -f "$NEWROOT$i") ++ __p=$(readlink -f "$NEWROOT_PREFIX$i") + if [ -x "$__p" ]; then + INIT="$i" + break +@@ -445,7 +453,11 @@ info "Switching root" + unset PS4 + + CAPSH=$(command -v capsh) +-SWITCH_ROOT=$(command -v switch_root) ++if test -n "${ostree}"; then ++ SWITCH_ROOT=$(command -v ostree_switch_root) ++else ++ SWITCH_ROOT=$(command -v switch_root) ++fi + PATH=$OLDPATH + export PATH + +@@ -463,7 +475,7 @@ if [ -f /etc/capsdrop ]; then + } + else + unset RD_DEBUG +- exec $SWITCH_ROOT "$NEWROOT" "$INIT" $initargs || { ++ exec $SWITCH_ROOT "$NEWROOT" $ostree "$INIT" $initargs || { + warn "Something went very badly wrong in the initramfs. Please " + warn "file a bug against dracut." + emergency_shell +-- +1.7.6.4 + diff --git a/parallel-debian/0001-switch_root-Add-subroot-option.patch b/parallel-debian/0001-switch_root-Add-subroot-option.patch deleted file mode 100644 index 145ee70b..00000000 --- a/parallel-debian/0001-switch_root-Add-subroot-option.patch +++ /dev/null @@ -1,102 +0,0 @@ -From fa0e7df4e3d6550f0391bb3b81b2b6ac5165439d Mon Sep 17 00:00:00 2001 -From: Colin Walters -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 \n", -+ fprintf(output, "usage: %s [--subroot DIR] \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 - diff --git a/parallel-debian/debian-setup.sh b/parallel-debian/debian-setup.sh new file mode 100755 index 00000000..c1d34b8a --- /dev/null +++ b/parallel-debian/debian-setup.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +cat > etc/inittab < # @@ -22,6 +22,9 @@ set -e set -x +SRCDIR=`dirname $0` +WORKDIR=`pwd` + case `uname -p` in x86_64) ARCH=amd64 @@ -33,69 +36,101 @@ esac; DEBTARGET=wheezy -NOTSHARED_DIRS="dev bin etc lib lib32 lib64 proc media mnt run sbin selinux sys srv usr" -SHARED_DIRS="home root tmp var" +INITRD_MOVE_MOUNTS="dev proc sys" +TOPROOT_BIND_MOUNTS="boot home root tmp" +OSTREE_BIND_MOUNTS="var" +MOVE_MOUNTS="selinux mnt media" +READONLY_BIND_MOUNTS="bin etc lib lib32 lib64 sbin usr" -if ! test -d debootstrap-$DEBTARGET; then +OBJ=debootstrap-$DEBTARGET +if ! test -d ${OBJ} ; then echo "Creating $DEBTARGET.img" - mkdir -p debootstrap-$DEBTARGET.tmp - debootstrap --download-only --arch $ARCH $DEBTARGET debootstrap-$DEBTARGET.tmp - mv debootstrap-$DEBTARGET.tmp debootstrap-$DEBTARGET + mkdir -p ${OBJ}.tmp + debootstrap --download-only --arch $ARCH $DEBTARGET ${OBJ}.tmp + mv ${OBJ}.tmp ${OBJ} fi -if ! test -f $DEBTARGET.img; then - echo "Creating $DEBTARGET.img" +OBJ=$DEBTARGET.img +if ! test -f ${OBJ}; then umount fs || true mkdir -p fs - qemu-img create $DEBTARGET.img.tmp 2G - mkfs.ext4 -q -F $DEBTARGET.img.tmp - mount -o loop $DEBTARGET.img.tmp fs + qemu-img create ${OBJ}.tmp 2G + mkfs.ext4 -q -F ${OBJ}.tmp + mount -o loop ${OBJ}.tmp fs for d in debootstrap-$DEBTARGET/var/cache/apt/archives/*.deb; do - tmpdir=`mktemp --tmpdir=. -d` - (cd ${tmpdir}; - ar x ../$d; - tar -x -z -C ../fs -f data.tar.gz) - rm -rf ${tmpdir} + rm -rf work; mkdir work + (cd work && ar x ../$d && tar -x -z -C ../fs -f data.tar.gz) done umount fs - mv $DEBTARGET.img.tmp $DEBTARGET.img + mv ${OBJ}.tmp ${OBJ} fi # TODO download source for above # TODO download build dependencies for above -if ! test -f gnomeos.img; then - echo "Cloning gnomeos.img from $DEBTARGET.img" - cp -a --sparse=always $DEBTARGET.img gnomeos.img.tmp +OBJ=gnomeos-filesystem.img +if ! test -f ${OBJ}; then + cp -a --sparse=always $DEBTARGET.img ${OBJ}.tmp mkdir -p fs umount fs || true - mount -o loop gnomeos.img.tmp fs + mount -o loop ${OBJ}.tmp fs (cd fs; mkdir ostree mkdir ostree/repo mkdir ostree/gnomeos-origin - for d in $NOTSHARED_DIRS; do + for d in $INITRD_MOVE_MOUNTS $TOPROOT_BIND_MOUNTS; do + mkdir -p ostree/gnomeos-origin/$d + chmod --reference $d ostree/gnomeos-origin/$d + done + for d in $OSTREE_BIND_MOUNTS; do + mkdir -p ostree/gnomeos-origin/$d + chmod --reference $d ostree/gnomeos-origin/$d + mv $d ostree + done + for d in $READONLY_BIND_MOUNTS $MOVE_MOUNTS; do if test -d $d; then mv $d ostree/gnomeos-origin fi done - for d in $SHARED_DIRS; do - mv $d ostree - mkdir ostree/gnomeos-origin/$d - touch ostree/gnomeos-origin/$d/EMPTY - done + + cp ${SRCDIR}/debian-setup.sh ostree/gnomeos-origin/ + chroot ostree/gnomeos-origin ./debian-setup.sh + rm ostree/gnomeos-origin/debian-setup.sh + ostree init --repo=ostree/repo (cd ostree/gnomeos-origin; find . '!' -type p | grep -v '^.$' | ostree commit -s 'Initial import' --repo=../repo --from-stdin) rm -rf ostree/gnomeos-origin (cd ostree; rev=`cat repo/HEAD` ostree checkout --repo=repo HEAD gnomeos-${rev} + ostree run-triggers --repo=repo current ln -s gnomeos-${rev} current) ) umount fs - mv gnomeos.img.tmp gnomeos.img + mv ${OBJ}.tmp ${OBJ} fi +OBJ=gnomeos-kernel +if ! test -f ${OBJ}; then + if test -x /sbin/grubby; then + kernel=`grubby --default-kernel` + cp $kernel ${OBJ}.tmp + else + echo "ERROR: couldn't find /sbin/grubby (which we use to find the running kernel)" + echo " You can copy any kernel image you want in here as gnomeos-kernel" + echo " For example: cp /boot/vmlinuz-2.6.40.6-0.fc15.x86_64 gnomeos-kernel" + exit 1 + fi + mv ${OBJ}.tmp ${OBJ} +fi +cp ${SRCDIR}/ostree_switch_root ${WORKDIR} + +OBJ=gnomeos-initrd.img +if ! test -f ${OBJ}; then + rm -f ${OBJ}.tmp + dracutbasedir=/src/build/jhbuild/share/dracut /src/build/jhbuild/sbin/dracut -v --include `pwd`/ostree_switch_root /sbin/ostree_switch_root ${OBJ}.tmp + mv ${OBJ}.tmp ${OBJ} +fi diff --git a/parallel-debian/ostree_switch_root.c b/parallel-debian/ostree_switch_root.c index 67a1cc68..fb750f2d 100644 --- a/parallel-debian/ostree_switch_root.c +++ b/parallel-debian/ostree_switch_root.c @@ -38,6 +38,9 @@ #include #include +static int +perrorv (const char *format, ...) __attribute__ ((format (printf, 1, 2))); + static int perrorv (const char *format, ...) { @@ -51,8 +54,11 @@ perrorv (const char *format, ...) vfprintf (stderr, format, args); fprintf (stderr, ": %s\n", p); + fflush (stderr); va_end (args); + + sleep (3); return 0; } @@ -129,6 +135,12 @@ done: static int make_readonly(const char *tree) { + struct stat stbuf; + /* Ignore nonexistent directories for now; + * some installs won't have e.g. lib64 + */ + if (stat (tree, &stbuf) < 0) + return 0; if (mount(tree, tree, NULL, MS_BIND, NULL) < 0) { perrorv("Failed to do initial RO bind mount %s", tree); return -1; @@ -143,8 +155,8 @@ static int make_readonly(const char *tree) static int switchroot(const char *newroot, const char *subroot) { - const char *toproot_bind_mounts[] = { "/boot", NULL }; - const char *ostree_inherit_mounts[] = { "/home", "/root", NULL }; + const char *initrd_move_mounts[] = { "/dev", "/proc", "/sys", NULL }; + const char *toproot_bind_mounts[] = { "/boot", "/home", "/root", "/tmp", NULL }; const char *ostree_bind_mounts[] = { "/var", NULL }; const char *readonly_bind_mounts[] = { "/bin", "/etc", "/lib", "/lib32", "/lib64", "/sbin", @@ -158,11 +170,20 @@ static int switchroot(const char *newroot, const char *subroot) char subroot_path[PATH_MAX]; char srcpath[PATH_MAX]; char destpath[PATH_MAX]; - struct stat stbuf; + + fprintf (stderr, "switching to root %s subroot: %s\n", newroot, subroot); orig_cfd = open("/", O_RDONLY); new_cfd = open(newroot, O_RDONLY); + /* For now just remount the rootfs r/w. Should definitely + * handle this better later... (famous last words) + */ + if (mount(newroot, newroot, NULL, MS_REMOUNT, NULL) < 0) { + perrorv("failed to remount %s read/write", newroot); + return -1; + } + snprintf(subroot_path, sizeof(subroot_path), "%s/ostree/%s", newroot, subroot); subroot_cfd = open(subroot_path, O_RDONLY); if (subroot_cfd < 0) { @@ -170,12 +191,14 @@ static int switchroot(const char *newroot, const char *subroot) return -1; } - /* For now just remount the rootfs r/w. Should definitely - * handle this better later... (famous last words) - */ - if (mount(newroot, newroot, NULL, MS_REMOUNT & ~MS_RDONLY, NULL) < 0) { - perrorv("failed to remount / read/write", newroot); - return -1; + for (i = 0; initrd_move_mounts[i] != NULL; i++) { + snprintf(destpath, sizeof(destpath), "%s%s", subroot_path, initrd_move_mounts[i]); + + if (mount(initrd_move_mounts[i], destpath, NULL, MS_MOVE, NULL) < 0) { + perrorv("failed to move initramfs mount %s to %s", + initrd_move_mounts[i], destpath); + umount2(initrd_move_mounts[i], MNT_FORCE); + } } for (i = 0; toproot_bind_mounts[i] != NULL; i++) { @@ -187,17 +210,6 @@ static int switchroot(const char *newroot, const char *subroot) } } - for (i = 0; ostree_inherit_mounts[i] != NULL; i++) { - snprintf(srcpath, sizeof(srcpath), "%s%s", newroot, ostree_inherit_mounts[i]); - if (stat (srcpath, &stbuf) < 0) - snprintf(srcpath, sizeof(srcpath), "%s/ostree%s", newroot, ostree_inherit_mounts[i]); - snprintf(destpath, sizeof(destpath), "%s%s", subroot_path, ostree_inherit_mounts[i]); - if (mount(srcpath, destpath, NULL, MS_BIND & ~MS_RDONLY, NULL) < 0) { - perrorv("failed to bind mount (class:inherit) %s to %s", srcpath, destpath); - return -1; - } - } - for (i = 0; ostree_bind_mounts[i] != NULL; i++) { snprintf(srcpath, sizeof(srcpath), "%s/ostree%s", newroot, ostree_bind_mounts[i]); snprintf(destpath, sizeof(destpath), "%s%s", subroot_path, ostree_bind_mounts[i]); @@ -222,8 +234,9 @@ static int switchroot(const char *newroot, const char *subroot) return -1; } - if (chroot(subroot) < 0) { - perrorv("failed to change root to %s", subroot); + snprintf(destpath, sizeof(destpath), "ostree/%s", subroot); + if (chroot(destpath) < 0) { + perrorv("failed to change root to %s", destpath); return -1; } @@ -237,7 +250,7 @@ static int switchroot(const char *newroot, const char *subroot) return -1; } } - + if (orig_cfd >= 0) { pid = fork(); if (pid <= 0) { @@ -253,7 +266,7 @@ static int switchroot(const char *newroot, const char *subroot) static void usage(FILE *output) { - fprintf(output, "usage: %s \n", + fprintf(output, "usage: %s \n", program_invocation_short_name); exit(output == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } @@ -262,7 +275,8 @@ int main(int argc, char *argv[]) { char *newroot, *subroot, *init, **initargs; - if (argc < 3) + fflush (stderr); + if (argc < 4) usage(stderr); if ((!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) @@ -273,7 +287,7 @@ int main(int argc, char *argv[]) init = argv[3]; initargs = &argv[3]; - if (!*newroot || !*init) + if (!*newroot || !*subroot || !*init) usage(stderr); if (switchroot(newroot, subroot)) @@ -283,6 +297,7 @@ int main(int argc, char *argv[]) perrorv("cannot access %s", init); execv(init, initargs); + perrorv("Failed to exec init '%s'", init); exit(1); } diff --git a/src/libostree/ostree-checkout.c b/src/libostree/ostree-checkout.c index 1da500f9..7fb7bd34 100644 --- a/src/libostree/ostree-checkout.c +++ b/src/libostree/ostree-checkout.c @@ -188,6 +188,9 @@ run_trigger (OstreeCheckout *self, OstreeCheckoutPrivate *priv = GET_PRIVATE (self); gboolean ret = FALSE; char *path = NULL; + char *temp_path = NULL; + char *rel_temp_path = NULL; + GFile *temp_copy = NULL; char *basename = NULL; GPtrArray *args = NULL; int estatus; @@ -199,9 +202,16 @@ run_trigger (OstreeCheckout *self, if (requires_chroot) { + temp_path = g_build_filename (priv->path, basename, NULL); + rel_temp_path = g_strconcat ("./", basename, NULL); + temp_copy = g_file_new_for_path (temp_path); + + if (!g_file_copy (trigger, temp_copy, 0, NULL, NULL, NULL, error)) + goto out; + g_ptr_array_add (args, "chroot"); - g_ptr_array_add (args, priv->path); - g_ptr_array_add (args, path); + g_ptr_array_add (args, "."); + g_ptr_array_add (args, rel_temp_path); g_ptr_array_add (args, NULL); } else @@ -210,10 +220,12 @@ run_trigger (OstreeCheckout *self, g_ptr_array_add (args, NULL); } + g_print ("Running trigger: %s\n", path); if (!g_spawn_sync (priv->path, (char**)args->pdata, NULL, - 0, NULL, NULL, NULL, NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, &estatus, error)) { @@ -223,8 +235,14 @@ run_trigger (OstreeCheckout *self, ret = TRUE; out: + if (requires_chroot && temp_path) + (void)unlink (temp_path); + g_free (path); g_free (basename); + g_free (temp_path); + g_free (rel_temp_path); + g_clear_object (&temp_copy); if (args) g_ptr_array_free (args, TRUE); return ret; @@ -242,7 +260,7 @@ check_trigger (OstreeCheckout *self, GError *temp_error = NULL; char *line; gsize len; - gboolean requires_chroot = FALSE; + gboolean requires_chroot = TRUE; gboolean matches = FALSE; instream = (GInputStream*)g_file_read (trigger, NULL, error); @@ -259,8 +277,6 @@ check_trigger (OstreeCheckout *self, matches = executable_exists_in_checkout (priv->path, executable); g_free (executable); } - if (g_str_has_prefix (line, "# RequiresChroot: ")) - requires_chroot = TRUE; g_free (line); } diff --git a/src/ot-builtin-run-triggers.c b/src/ot-builtin-run-triggers.c index 55274187..49591564 100644 --- a/src/ot-builtin-run-triggers.c +++ b/src/ot-builtin-run-triggers.c @@ -27,9 +27,11 @@ #include static char *repo_path; +static gboolean quiet; static GOptionEntry options[] = { { "repo", 0, 0, G_OPTION_ARG_FILENAME, &repo_path, "Repository path", "repo" }, + { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Don't display informational messages", NULL }, { NULL } }; diff --git a/triggers.d/desktop-database.trigger b/triggers.d/desktop-database.trigger index 55fce20a..7ab2ea49 100755 --- a/triggers.d/desktop-database.trigger +++ b/triggers.d/desktop-database.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for desktop files. -*- mode: sh -*- # # Written by Matthias Clasen diff --git a/triggers.d/gdk-pixbuf.trigger b/triggers.d/gdk-pixbuf.trigger index 44f5a226..bd210444 100755 --- a/triggers.d/gdk-pixbuf.trigger +++ b/triggers.d/gdk-pixbuf.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for gdk-pixbuf. -*- mode: sh -*- # Corresponds to gdk-pixbuf/gdk-pixbuf/Makefile.am:install-data-hook # diff --git a/triggers.d/glib.trigger b/triggers.d/glib.trigger index 01e4aa58..b7af8f51 100755 --- a/triggers.d/glib.trigger +++ b/triggers.d/glib.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for glib/gschema. -*- mode: sh -*- # # Written by Colin Walters diff --git a/triggers.d/gtk+.trigger b/triggers.d/gtk+.trigger index 7cc16948..8d516d2e 100755 --- a/triggers.d/gtk+.trigger +++ b/triggers.d/gtk+.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for gtk icon cache. -*- mode: sh -*- # # Written by Colin Walters diff --git a/triggers.d/immodules.trigger b/triggers.d/immodules.trigger index 1248c1e0..924c8b9a 100755 --- a/triggers.d/immodules.trigger +++ b/triggers.d/immodules.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for GTK+ input method modules. -*- mode: sh -*- # # Written by Matthias Clasen diff --git a/triggers.d/ldconfig.trigger b/triggers.d/ldconfig.trigger index a1994b1b..997c16c4 100755 --- a/triggers.d/ldconfig.trigger +++ b/triggers.d/ldconfig.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for shared libraries. -*- mode: sh -*- # # Written by Colin Walters diff --git a/triggers.d/mime-database.trigger b/triggers.d/mime-database.trigger index 298d5373..ab7fc644 100755 --- a/triggers.d/mime-database.trigger +++ b/triggers.d/mime-database.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for shared-mime-info. -*- mode: sh -*- # # Written by Matthias Clasen diff --git a/triggers.d/pango.trigger b/triggers.d/pango.trigger index c6802451..2331cb38 100755 --- a/triggers.d/pango.trigger +++ b/triggers.d/pango.trigger @@ -1,3 +1,4 @@ +#!/bin/sh # Post-installation hook for pango. -*- mode: sh -*- # Corresponds to gdk-pixbuf/gdk-pixbuf/Makefile.am:install-data-hook #