When guestfsd exits, or the user exits the virt-rescue shell, the init script exits which causes the kernel to panic. This isn't really a functional issue, as all useful work is done by this point. However, it does cause virt-rescue to display an unsightly error message. This patch adds a new utility, guestfs_poweroff, to the appliance. This powers off (reboots really: read the comment) the appliance, preventing init from exiting, and therefore the kernel panic. --- .gitignore | 1 + appliance/Makefile.am | 6 ++++-- appliance/debian/modules/y0_install-guestfsd | 2 ++ appliance/guestfs_poweroff.c | 14 ++++++++++++++ appliance/init | 2 +- appliance/update.sh.in | 4 ++++ po/POTFILES.in | 1 + 7 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 appliance/guestfs_poweroff.c diff --git a/.gitignore b/.gitignore index 094acb3..abd88bc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ appliance/debian/debirf-libguestfs*.cgz appliance/debian/root/ appliance/debian/vmlinuz-* appliance/debian/debirf.conf +appliance/guestfs_poweroff appliance/initramfs.*.img appliance/kmod.whitelist appliance/make.sh diff --git a/appliance/Makefile.am b/appliance/Makefile.am index bbf3c24..ccf7907 100644 --- a/appliance/Makefile.am +++ b/appliance/Makefile.am @@ -46,6 +46,8 @@ superminfs_DATA = \ supermin.d/hostfiles endif +noinst_PROGRAMS = guestfs_poweroff + # Don't change these names - they must be the same as in '*.sh' scripts. INITRAMFSIMG = initramfs.$(REPO).$(host_cpu).img VMLINUZ = vmlinuz.$(REPO).$(host_cpu) @@ -67,7 +69,7 @@ make.sh: make.sh.in chmod +x $@-t mv $@-t $@ -$(INITRAMFSIMG): $(top_builddir)/initramfs/fakeroot.log $(top_builddir)/daemon/guestfsd init update.sh +$(INITRAMFSIMG): $(top_builddir)/initramfs/fakeroot.log $(top_builddir)/daemon/guestfsd init guestfs_poweroff update.sh rm -f $@ bash update.sh touch $@ @@ -99,7 +101,7 @@ supermin.d/daemon.img: $(INITRAMFSIMG) mkdir -p supermin.d rm -f $@ $@-t (cd $(top_builddir)/initramfs && \ - echo -e "sbin\nsbin/guestfsd" | cpio --quiet -o -H newc ) > $@-t + echo -e "sbin\nsbin/guestfsd\nsbin/guestfs_poweroff" | cpio --quiet -o -H newc ) > $@-t mv $@-t $@ endif diff --git a/appliance/debian/modules/y0_install-guestfsd b/appliance/debian/modules/y0_install-guestfsd index 2d895a0..c2b812a 100755 --- a/appliance/debian/modules/y0_install-guestfsd +++ b/appliance/debian/modules/y0_install-guestfsd @@ -37,4 +37,6 @@ rm -rf "$DEBIRF_ROOT"/usr/share/man/ # Install the actual appliance: echo $PWD install -o root -g root -m 0755 ../daemon/guestfsd "$DEBIRF_ROOT"/sbin/guestfsd +install -o root -g root -m 0755 ../appliance/guestfs_poweroff \ + "$DEBIRF_ROOT"/sbin/guestfs_poweroff install -o root -g root -m 0755 init "$DEBIRF_ROOT"/sbin/init diff --git a/appliance/guestfs_poweroff.c b/appliance/guestfs_poweroff.c new file mode 100644 index 0000000..7e18839 --- /dev/null +++ b/appliance/guestfs_poweroff.c @@ -0,0 +1,14 @@ +#include <stdio.h> +#include <sys/reboot.h> + +int main(int argc, char **argv) +{ + /* We actually hard reboot here rather than power off. For some reason + * reboot causes the qemu process to die, whereas poweroff doesn't. + * + * This should not return */ + reboot(RB_AUTOBOOT); + + perror("Power off failed"); + return 1; +} diff --git a/appliance/init b/appliance/init index 90da1cb..4ed93b8 100755 --- a/appliance/init +++ b/appliance/init @@ -110,8 +110,8 @@ else bash -i echo echo "virt-rescue: Syncing the disk now before exiting ..." - echo "(Don't worry if you see a 'Kernel panic' message below)" echo fi sync +exec /sbin/guestfs_poweroff diff --git a/appliance/update.sh.in b/appliance/update.sh.in index 0222a75..9cb3450 100755 --- a/appliance/update.sh.in +++ b/appliance/update.sh.in @@ -33,6 +33,10 @@ if [ "@DIST@" = "REDHAT" ]; then # Copy the daemon into the filesystem. @FEBOOTSTRAP_INSTALL@ initramfs daemon/guestfsd /sbin/guestfsd 0755 root.root + # Copy guestfs_poweroff into the filesystem + febootstrap-install initramfs appliance/guestfs_poweroff \ + /sbin/guestfs_poweroff 0755 root.root + # Generate final image. @FEBOOTSTRAP_TO_INITRAMFS@ initramfs > $output-t mv $output-t $output diff --git a/po/POTFILES.in b/po/POTFILES.in index e5fb857..b2f7f26 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,3 +1,4 @@ +appliance/guestfs_poweroff.c daemon/augeas.c daemon/available.c daemon/base64.c -- 1.7.2.2