xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Olaf Hering <olaf@aepfle.de>
To: xen-devel@lists.xen.org
Cc: Olaf Hering <olaf@aepfle.de>,
	Ian.Jackson@eu.citrix.com, Ian.Campbell@citrix.com
Subject: [PATCH 4/4 v2] tools/xc: pass errno to callers of xc_domain_save
Date: Fri,  7 Mar 2014 10:15:09 +0100	[thread overview]
Message-ID: <1394183709-9956-5-git-send-email-olaf@aepfle.de> (raw)
In-Reply-To: <1394183709-9956-1-git-send-email-olaf@aepfle.de>

Callers of xc_domain_save use errno to print diagnostics if the call
fails. But xc_domain_save does not preserve the actual errno in case of
a failure.

This change preserves errno in all cases where code jumps to the label
"out". In addition a new label "exit" is added to catch also code which
used to do just "return 1".

Now libxl_save_helper:complete can print the actual error string.

v2:
- preserve errno during inital jump to label "out"
- use errno as success indicator

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 tools/libxc/xc_domain_save.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 42c4752..3aef0d2 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -150,6 +150,7 @@ static inline int outbuf_write(xc_interface *xch,
                                struct outbuf* ob, void* buf, size_t len)
 {
     if ( len > ob->size - ob->pos ) {
+        errno = ERANGE;
         DBGPRINTF("outbuf_write: %zu > %zu@%zu\n", len, ob->size - ob->pos, ob->pos);
         return -1;
     }
@@ -806,7 +807,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     xc_dominfo_t info;
     DECLARE_DOMCTL;
 
-    int rc = 1, frc, i, j, last_iter = 0, iter = 0;
+    int rc, frc, i, j, last_iter = 0, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
     int superpages = !!hvm;
@@ -899,7 +900,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     {
         ERROR("No switch_qemu_logdirty callback provided.");
         errno = EINVAL;
-        return 1;
+        goto exit;
     }
 
     outbuf_init(xch, &ob_pagebuf, OUTBUF_SIZE);
@@ -914,13 +915,13 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
                             &ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
     {
         ERROR("Unable to get platform info.");
-        return 1;
+        goto exit;
     }
 
     if ( xc_domain_getinfo(xch, dom, 1, &info) != 1 )
     {
         PERROR("Could not get domain info");
-        return 1;
+        goto exit;
     }
 
     shared_info_frame = info.shared_info_frame;
@@ -942,6 +943,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
     if ( dinfo->p2m_size > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
     {
+        errno = E2BIG;
         ERROR("Cannot save this big a guest");
         goto out;
     }
@@ -1012,6 +1014,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
     if ( !to_send || !to_fix || !to_skip )
     {
+        errno = ENOMEM;
         ERROR("Couldn't allocate to_send array");
         goto out;
     }
@@ -1030,6 +1033,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
         hvm_buf = malloc(hvm_buf_size);
         if ( !hvm_buf )
         {
+            errno = ENOMEM;
             ERROR("Couldn't allocate memory");
             goto out;
         }
@@ -1598,6 +1602,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
 
         if ( info.max_vcpu_id >= XC_SR_MAX_VCPUS )
         {
+            errno = E2BIG;
             ERROR("Too many VCPUS in guest!");
             goto out;
         }
@@ -1830,7 +1835,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
         }
         
         /* HVM guests are done now */
-        rc = 0;
+        errno = 0;
         goto out;
     }
 
@@ -1888,6 +1893,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     mfn = GET_FIELD(&ctxt, user_regs.edx);
     if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
     {
+        errno = ERANGE;
         ERROR("Suspend record is not in range of pseudophys map");
         goto out;
     }
@@ -1910,6 +1916,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
             mfn = GET_FIELD(&ctxt, gdt_frames[j]);
             if ( !MFN_IS_IN_PSEUDOPHYS_MAP(mfn) )
             {
+                errno = ERANGE;
                 ERROR("GDT frame is not in range of pseudophys map");
                 goto out;
             }
@@ -1920,6 +1927,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
         if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3(
                                            GET_FIELD(&ctxt, ctrlreg[3]))) )
         {
+            errno = ERANGE;
             ERROR("PT base is not in range of pseudophys map");
             goto out;
         }
@@ -1931,6 +1939,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
         {
             if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3(ctxt.x64.ctrlreg[1])) )
             {
+                errno = ERANGE;
                 ERROR("PT base is not in range of pseudophys map");
                 goto out;
             }
@@ -2027,9 +2036,10 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     }
 
     /* Success! */
-    rc = 0;
+    errno = 0;
 
  out:
+    rc = errno;
     completed = 1;
 
     if ( !rc && callbacks->postcopy )
@@ -2044,13 +2054,11 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
         if (wrcompressed(io_fd) < 0)
         {
             ERROR("Error when writing compressed data, after postcopy\n");
-            rc = 1;
             goto out;
         }
         /* Append the tailbuf data to the main outbuf */
         if ( wrexact(io_fd, ob_tailbuf.buf, ob_tailbuf.pos) )
         {
-            rc = 1;
             PERROR("Error when copying tailbuf into outbuf");
             goto out;
         }
@@ -2059,7 +2067,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     /* Flush last write and discard cache for file. */
     if ( ob && outbuf_flush(xch, ob, io_fd) < 0 ) {
         PERROR("Error when flushing output buffer");
-        rc = 1;
+        if (!rc)
+            rc = errno;
     }
 
     discard_file_cache(xch, io_fd, 1 /* flush */);
@@ -2130,9 +2139,11 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
     free(hvm_buf);
     outbuf_free(&ob_pagebuf);
 
-    DPRINTF("Save exit of domid %u with rc=%d\n", dom, rc);
+    errno = rc;
+exit:
+    DPRINTF("Save exit of domid %u with errno=%d\n", dom, errno);
 
-    return !!rc;
+    return !!errno;
 }
 
 /*

  parent reply	other threads:[~2014-03-07  9:15 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-07  9:15 [PATCH 0/4] tools/libxc: various errno changes Olaf Hering
2014-03-07  9:15 ` [PATCH 1/4] tools/libxc: remove double inclusion of errno.h Olaf Hering
2014-03-10 16:50   ` Ian Jackson
2014-03-07  9:15 ` [PATCH 2/4] tools/libxc: assign positive values to errno Olaf Hering
2014-03-10 16:51   ` Ian Jackson
2014-03-11 13:17     ` Ian Campbell
2014-03-11 14:35       ` Olaf Hering
2014-03-11 14:39         ` Ian Campbell
2014-03-11 15:24       ` Ian Jackson
2014-03-07  9:15 ` [PATCH 3/4] tools/xc: preserve errno in ERROR and DRINTF macros Olaf Hering
2014-03-10 16:51   ` Ian Jackson
2014-03-07  9:15 ` Olaf Hering [this message]
2014-03-10 16:59   ` [PATCH 4/4 v2] tools/xc: pass errno to callers of xc_domain_save Ian Jackson
2014-03-10 18:24     ` Olaf Hering
2014-03-11  7:49       ` Olaf Hering

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1394183709-9956-5-git-send-email-olaf@aepfle.de \
    --to=olaf@aepfle.de \
    --cc=Ian.Campbell@citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).