[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.