[Libguestfs] [PATCH 3/4] Shut down the appliance cleanly

Matthew Booth mbooth at redhat.com
Thu Aug 26 11:12:00 UTC 2010


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




More information about the Libguestfs mailing list