[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-API] [PATCH 4 of 4] CA-38567: Catch I/O errors during Debian postinstall
# HG changeset patch # User Daniel Stodden <daniel.stodden@xxxxxxxxxx> # Date 1267831160 28800 # Node ID 48bf0d8da534e1110ca73db10aa2d9fd74c939f2 # Parent 9b5b9b509bcb55f6cd2b485191fa6af88862845c CA-38567: Catch I/O errors during Debian postinstall. This somewhat redefines scripted postinstall code to exit with kernel error numbers when failing VDI provisioning. Partially works for ENOSPC (swap/dd only). Works for tar (rootfs) or dd (swap) failing with I/O errors. Was surprised to learn gnu tar apparently never fsyncs, it took an -osync mount to let it learn that not all is great in storage land. Unexpected return codes now raise an internal_error, not a wild bet on provision_failed_out_of_space, as it used to. Signed-off-by: Daniel Stodden <daniel.stodden@xxxxxxxxxx> diff -r 9b5b9b509bcb -r 48bf0d8da534 ocaml/xapi/xapi_templates_install.ml --- a/ocaml/xapi/xapi_templates_install.ml Fri Mar 05 15:19:19 2010 -0800 +++ b/ocaml/xapi/xapi_templates_install.ml Fri Mar 05 15:19:20 2010 -0800 @@ -98,9 +98,13 @@ in update_progress () ) with | Success _ -> debug "Install script exitted successfully." + | Failure(log, Subprocess_failed 5) -> + raise (Api_errors.Server_error (Api_errors.vdi_io_error, ["Device I/O error"])) + | Failure(log, Subprocess_failed 28) -> + raise (Api_errors.Server_error (Api_errors.provision_failed_out_of_space, [])) | Failure(log, Subprocess_failed n) -> - error "post_install_script failed: message='%s' (assuming this was because the disk was too small)" log; - raise (Api_errors.Server_error (Api_errors.provision_failed_out_of_space, [])) + let msg = Printf.sprintf "Template post installation script failed: status %d" n in + raise (Api_errors.Server_error (Api_errors.internal_error, [msg])) | Failure(log, exn) -> raise exn ) diff -r 9b5b9b509bcb -r 48bf0d8da534 scripts/templates/debian --- a/scripts/templates/debian Fri Mar 05 15:19:19 2010 -0800 +++ b/scripts/templates/debian Fri Mar 05 15:19:20 2010 -0800 @@ -3,6 +3,7 @@ # Code ripped out of 'xgt' script for now import commands, xmlrpclib, os, sys, httplib, socket, urllib2, signal +import errno verbose = True @@ -28,7 +29,9 @@ class CommandException(Exception): - pass + def __init__(self, ret, out): + Exception.__init__(self, out) + self.ret = ret def run(cmd, *args): @@ -42,7 +45,7 @@ pass if ret != 0: debug ("run - command %s failed with %d" , cmd, ret) - raise CommandException(out) + raise CommandException(ret, out) return out def log(fmt, *args): @@ -97,7 +100,7 @@ def sighandler(signum, frame): umount(mountpoint) os.killpg(0,signal.SIGKILL) - exit(1) + sys.exit(errno.EINTR) signal.signal(signal.SIGTERM,sighandler) @@ -110,12 +113,26 @@ run("/bin/mkdir -p %s", mountpoint) try: - run("/bin/mount %s1 %s", xvda, mountpoint) - run("/usr/bin/unzip -p %s root.tar.bz2 | tar -C %s -jx", xgt, mountpoint) - finally: - run("/bin/umount %s", mountpoint) - run("/bin/rmdir %s", mountpoint) - run("/usr/bin/unzip -p %s swap.img | dd of=%s oflag=direct bs=1M", xgt, xvdb) + try: + run("/bin/mount -osync %s1 %s", xvda, mountpoint) + run("/usr/bin/unzip -p %s root.tar.bz2 | tar -C %s -jx", xgt, mountpoint) + finally: + run("/bin/umount %s", mountpoint) + run("/bin/rmdir %s", mountpoint) + except CommandException, e: + if e.ret == 512: + sys.exit(errno.EIO) + else: + raise + try: + run("/usr/bin/unzip -p %s swap.img | dd of=%s oflag=direct bs=1M", xgt, xvdb) + except CommandException, e: + if e.ret == 256: + sys.exit(errno.EIO) + elif e.ret == 1: + sys.exit(errno.ENOSPC) + else: + raise try: session_id = server.session.login_with_password('','')['Value'] # HG changeset patch # User Daniel Stodden <daniel.stodden@xxxxxxxxxx> # Date 1267831160 28800 # Node ID 48bf0d8da534e1110ca73db10aa2d9fd74c939f2 # Parent 9b5b9b509bcb55f6cd2b485191fa6af88862845c CA-38567: Catch I/O errors during Debian postinstall. This somewhat redefines scripted postinstall code to exit with kernel error numbers when failing VDI provisioning. Partially works for ENOSPC (swap/dd only). Works for tar (rootfs) or dd (swap) failing with I/O errors. Was surprised to learn gnu tar apparently never fsyncs, it took an -osync mount to let it learn that not all is great in storage land. Unexpected return codes now raise an internal_error, not a wild bet on provision_failed_out_of_space, as it used to. Signed-off-by: Daniel Stodden <daniel.stodden@xxxxxxxxxx> diff -r 9b5b9b509bcb -r 48bf0d8da534 ocaml/xapi/xapi_templates_install.ml --- a/ocaml/xapi/xapi_templates_install.ml Fri Mar 05 15:19:19 2010 -0800 +++ b/ocaml/xapi/xapi_templates_install.ml Fri Mar 05 15:19:20 2010 -0800 @@ -98,9 +98,13 @@ in update_progress () ) with | Success _ -> debug "Install script exitted successfully." + | Failure(log, Subprocess_failed 5) -> + raise (Api_errors.Server_error (Api_errors.vdi_io_error, ["Device I/O error"])) + | Failure(log, Subprocess_failed 28) -> + raise (Api_errors.Server_error (Api_errors.provision_failed_out_of_space, [])) | Failure(log, Subprocess_failed n) -> - error "post_install_script failed: message='%s' (assuming this was because the disk was too small)" log; - raise (Api_errors.Server_error (Api_errors.provision_failed_out_of_space, [])) + let msg = Printf.sprintf "Template post installation script failed: status %d" n in + raise (Api_errors.Server_error (Api_errors.internal_error, [msg])) | Failure(log, exn) -> raise exn ) diff -r 9b5b9b509bcb -r 48bf0d8da534 scripts/templates/debian --- a/scripts/templates/debian Fri Mar 05 15:19:19 2010 -0800 +++ b/scripts/templates/debian Fri Mar 05 15:19:20 2010 -0800 @@ -3,6 +3,7 @@ # Code ripped out of 'xgt' script for now import commands, xmlrpclib, os, sys, httplib, socket, urllib2, signal +import errno verbose = True @@ -28,7 +29,9 @@ class CommandException(Exception): - pass + def __init__(self, ret, out): + Exception.__init__(self, out) + self.ret = ret def run(cmd, *args): @@ -42,7 +45,7 @@ pass if ret != 0: debug ("run - command %s failed with %d" , cmd, ret) - raise CommandException(out) + raise CommandException(ret, out) return out def log(fmt, *args): @@ -97,7 +100,7 @@ def sighandler(signum, frame): umount(mountpoint) os.killpg(0,signal.SIGKILL) - exit(1) + sys.exit(errno.EINTR) signal.signal(signal.SIGTERM,sighandler) @@ -110,12 +113,26 @@ run("/bin/mkdir -p %s", mountpoint) try: - run("/bin/mount %s1 %s", xvda, mountpoint) - run("/usr/bin/unzip -p %s root.tar.bz2 | tar -C %s -jx", xgt, mountpoint) - finally: - run("/bin/umount %s", mountpoint) - run("/bin/rmdir %s", mountpoint) - run("/usr/bin/unzip -p %s swap.img | dd of=%s oflag=direct bs=1M", xgt, xvdb) + try: + run("/bin/mount -osync %s1 %s", xvda, mountpoint) + run("/usr/bin/unzip -p %s root.tar.bz2 | tar -C %s -jx", xgt, mountpoint) + finally: + run("/bin/umount %s", mountpoint) + run("/bin/rmdir %s", mountpoint) + except CommandException, e: + if e.ret == 512: + sys.exit(errno.EIO) + else: + raise + try: + run("/usr/bin/unzip -p %s swap.img | dd of=%s oflag=direct bs=1M", xgt, xvdb) + except CommandException, e: + if e.ret == 256: + sys.exit(errno.EIO) + elif e.ret == 1: + sys.exit(errno.ENOSPC) + else: + raise try: session_id = server.session.login_with_password('','')['Value'] _______________________________________________ xen-api mailing list xen-api@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/mailman/listinfo/xen-api
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |