WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-api

[Xen-API] [PATCH 4 of 4] CA-38567: Catch I/O errors during Debian postin

To: Xen API <xen-api@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-API] [PATCH 4 of 4] CA-38567: Catch I/O errors during Debian postinstall
From: Daniel Stodden <daniel.stodden@xxxxxxxxxx>
Date: Fri, 05 Mar 2010 23:20:59 -0000
Delivery-date: Fri, 05 Mar 2010 15:21:17 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1267831255@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1267831255@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.3.1
# 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