[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] libxc: save/restore error handling fixes



* Make "read_exact" in libxc always set errno.
* Rename "read_exact" macro in xc_domain_restore.c (which shadows
  real function) to RDEXACT and change all callers.
* Make RDEXACT anamorphically use xch for error reporting rather than stderr.
* Call PERROR rather than ERROR when appropriate, so that log messages
  include errno.
* Save errno in noncached_write so that its errno value is always right.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>

xc fix a newline in PERROR
---
 tools/libxc/xc_domain_restore.c |  171 ++++++++++++++++++++-------------------
 tools/libxc/xc_domain_save.c    |   64 ++++++++-------
 tools/libxc/xc_private.c        |    2 +
 tools/libxc/xc_private.h        |    4 +-
 4 files changed, 125 insertions(+), 116 deletions(-)

diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 508cebd..fd34636 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -124,7 +124,7 @@ static int break_super_page(xc_interface *xch,
 
     if ( ram_base == NULL )
     {
-        ERROR("map batch failed\n");
+        PERROR("map batch failed\n");
         rc = 1;
         goto out;
     }
@@ -136,7 +136,7 @@ static int break_super_page(xc_interface *xch,
     if ( xc_domain_memory_decrease_reservation(xch, dom, 1,
                                    SUPERPAGE_PFN_SHIFT, &start_pfn) != 0 )
     {
-        ERROR("free 2M page failure @ 0x%ld.\n", next_pfn);
+        PERROR("free 2M page failure @ 0x%ld.\n", next_pfn);
         rc = 1;
         goto out;
     }
@@ -153,7 +153,7 @@ static int break_super_page(xc_interface *xch,
         if (xc_domain_memory_populate_physmap(xch, dom, 1, 0,
                                               0, &mfn) != 0)
         {
-            ERROR("Failed to allocate physical memory.!\n");
+            PERROR("Failed to allocate physical memory.!\n");
             errno = ENOMEM;
             rc = 1;
             goto out;
@@ -171,7 +171,7 @@ static int break_super_page(xc_interface *xch,
                                     page_array, tot_pfns);
     if ( ram_base == NULL )
     {
-        ERROR("map batch failed\n");
+        PERROR("map batch failed\n");
         rc = 1;
         goto out;
     }
@@ -283,7 +283,7 @@ normal_page:
             if (xc_domain_memory_populate_physmap(xch, dom, 1, 0,
                         0, &mfn) != 0)
             {
-                ERROR("Failed to allocate physical memory.! pfn=0x%lx, 
mfn=0x%lx.\n",
+                PERROR("Failed to allocate physical memory.! pfn=0x%lx, 
mfn=0x%lx.\n",
                         pfn, mfn);
                 errno = ENOMEM;
                 return 1;
@@ -448,7 +448,7 @@ static int completed = 0;
 #define HEARTBEAT_MS 1000
 
 #ifndef __MINIOS__
-static ssize_t read_exact_timed(int fd, void* buf, size_t size)
+static ssize_t rdexact(struct xc_interface *xch, int fd, void* buf, size_t 
size)
 {
     size_t offset = 0;
     ssize_t len;
@@ -465,8 +465,11 @@ static ssize_t read_exact_timed(int fd, void* buf, size_t 
size)
             FD_ZERO(&rfds);
             FD_SET(fd, &rfds);
             len = select(fd + 1, &rfds, NULL, NULL, &tv);
+            if ( len == -1 && errno == EINTR )
+                continue;
             if ( !FD_ISSET(fd, &rfds) ) {
-                fprintf(stderr, "read_exact_timed failed (select returned 
%zd)\n", len);
+                ERROR("read_exact_timed failed (select returned %zd)", len);
+                errno = ETIMEDOUT;
                 return -1;
             }
         }
@@ -474,6 +477,8 @@ static ssize_t read_exact_timed(int fd, void* buf, size_t 
size)
         len = read(fd, buf + offset, size - offset);
         if ( (len == -1) && ((errno == EINTR) || (errno == EAGAIN)) )
             continue;
+        if ( len == 0 )
+            errno = 0;
         if ( len <= 0 )
             return -1;
         offset += len;
@@ -482,10 +487,9 @@ static ssize_t read_exact_timed(int fd, void* buf, size_t 
size)
     return 0;
 }
 
-#define read_exact read_exact_timed
-
+#define RDEXACT(fd,buf,size) rdexact(xch, fd, buf, size)
 #else
-#define read_exact_timed read_exact
+#define RDEXACT read_exact
 #endif
 /*
 ** In the state file (or during transfer), all page-table pages are
@@ -549,9 +553,9 @@ static xen_pfn_t *load_p2m_frame_list(
     struct domain_info_context *dinfo = &ctx->dinfo;
 
     /* Read first entry of P2M list, or extended-info signature (~0UL). */
-    if ( read_exact(io_fd, &p2m_fl_zero, sizeof(long)) )
+    if ( RDEXACT(io_fd, &p2m_fl_zero, sizeof(long)) )
     {
-        ERROR("read extended-info signature failed");
+        PERROR("read extended-info signature failed");
         return NULL;
     }
     
@@ -560,9 +564,9 @@ static xen_pfn_t *load_p2m_frame_list(
         uint32_t tot_bytes;
         
         /* Next 4 bytes: total size of following extended info. */
-        if ( read_exact(io_fd, &tot_bytes, sizeof(tot_bytes)) )
+        if ( RDEXACT(io_fd, &tot_bytes, sizeof(tot_bytes)) )
         {
-            ERROR("read extended-info size failed");
+            PERROR("read extended-info size failed");
             return NULL;
         }
         
@@ -572,11 +576,11 @@ static xen_pfn_t *load_p2m_frame_list(
             char     chunk_sig[4];
             
             /* 4-character chunk signature + 4-byte remaining chunk size. */
-            if ( read_exact(io_fd, chunk_sig, sizeof(chunk_sig)) ||
-                 read_exact(io_fd, &chunk_bytes, sizeof(chunk_bytes)) ||
+            if ( RDEXACT(io_fd, chunk_sig, sizeof(chunk_sig)) ||
+                 RDEXACT(io_fd, &chunk_bytes, sizeof(chunk_bytes)) ||
                  (tot_bytes < (chunk_bytes + 8)) )
             {
-                ERROR("read extended-info chunk signature failed");
+                PERROR("read extended-info chunk signature failed");
                 return NULL;
             }
             tot_bytes -= 8;
@@ -602,9 +606,9 @@ static xen_pfn_t *load_p2m_frame_list(
                     return NULL;
                 }
 
-                if ( read_exact(io_fd, &ctxt, chunk_bytes) )
+                if ( RDEXACT(io_fd, &ctxt, chunk_bytes) )
                 {
-                    ERROR("read extended-info vcpu context failed");
+                    PERROR("read extended-info vcpu context failed");
                     return NULL;
                 }
                 tot_bytes -= chunk_bytes;
@@ -623,9 +627,9 @@ static xen_pfn_t *load_p2m_frame_list(
             while ( chunk_bytes )
             {
                 unsigned long sz = MIN(chunk_bytes, sizeof(xen_pfn_t));
-                if ( read_exact(io_fd, &p2m_fl_zero, sz) )
+                if ( RDEXACT(io_fd, &p2m_fl_zero, sz) )
                 {
-                    ERROR("read-and-discard extended-info chunk bytes failed");
+                    PERROR("read-and-discard extended-info chunk bytes 
failed");
                     return NULL;
                 }
                 chunk_bytes -= sz;
@@ -634,9 +638,9 @@ static xen_pfn_t *load_p2m_frame_list(
         }
 
         /* Now read the real first entry of P2M list. */
-        if ( read_exact(io_fd, &p2m_fl_zero, sizeof(xen_pfn_t)) )
+        if ( RDEXACT(io_fd, &p2m_fl_zero, sizeof(xen_pfn_t)) )
         {
-            ERROR("read first entry of p2m_frame_list failed");
+            PERROR("read first entry of p2m_frame_list failed");
             return NULL;
         }
     }
@@ -651,10 +655,10 @@ static xen_pfn_t *load_p2m_frame_list(
 
     /* First entry has already been read. */
     p2m_frame_list[0] = p2m_fl_zero;
-    if ( read_exact(io_fd, &p2m_frame_list[1], 
+    if ( RDEXACT(io_fd, &p2m_frame_list[1], 
                     (P2M_FL_ENTRIES - 1) * sizeof(xen_pfn_t)) )
     {
-        ERROR("read p2m_frame_list failed");
+        PERROR("read p2m_frame_list failed");
         return NULL;
     }
     
@@ -742,8 +746,8 @@ static int buffer_qemu(xc_interface *xch,
     uint32_t qlen;
     uint8_t *tmp;
 
-    if ( read_exact(fd, &qlen, sizeof(qlen)) ) {
-        ERROR("Error reading QEMU header length");
+    if ( RDEXACT(fd, &qlen, sizeof(qlen)) ) {
+        PERROR("Error reading QEMU header length");
         return -1;
     }
 
@@ -766,8 +770,8 @@ static int buffer_qemu(xc_interface *xch,
     }
     buf->qemubufsize = qlen;
 
-    if ( read_exact(fd, buf->qemubuf, buf->qemubufsize) ) {
-        ERROR("Error reading QEMU state");
+    if ( RDEXACT(fd, buf->qemubuf, buf->qemubufsize) ) {
+        PERROR("Error reading QEMU state");
         return -1;
     }
 
@@ -806,13 +810,13 @@ static int buffer_tail_hvm(xc_interface *xch, struct 
restore_ctx *ctx,
     uint8_t *tmp;
     unsigned char qemusig[21];
 
-    if ( read_exact(fd, buf->magicpfns, sizeof(buf->magicpfns)) ) {
-        ERROR("Error reading magic PFNs");
+    if ( RDEXACT(fd, buf->magicpfns, sizeof(buf->magicpfns)) ) {
+        PERROR("Error reading magic PFNs");
         return -1;
     }
 
-    if ( read_exact(fd, &buf->reclen, sizeof(buf->reclen)) ) {
-        ERROR("Error reading HVM params size");
+    if ( RDEXACT(fd, &buf->reclen, sizeof(buf->reclen)) ) {
+        PERROR("Error reading HVM params size");
         return -1;
     }
 
@@ -836,13 +840,13 @@ static int buffer_tail_hvm(xc_interface *xch, struct 
restore_ctx *ctx,
         }
     }
 
-    if ( read_exact(fd, buf->hvmbuf, buf->reclen) ) {
-        ERROR("Error reading HVM params");
+    if ( RDEXACT(fd, buf->hvmbuf, buf->reclen) ) {
+        PERROR("Error reading HVM params");
         return -1;
     }
 
-    if ( read_exact(fd, qemusig, sizeof(qemusig)) ) {
-        ERROR("Error reading QEMU signature");
+    if ( RDEXACT(fd, qemusig, sizeof(qemusig)) ) {
+        PERROR("Error reading QEMU signature");
         return -1;
     }
 
@@ -871,10 +875,10 @@ static int buffer_tail_pv(xc_interface *xch, struct 
restore_ctx *ctx,
 
     /* TODO: handle changing pfntab and vcpu counts */
     /* PFN tab */
-    if ( read_exact(fd, &buf->pfncount, sizeof(buf->pfncount)) ||
+    if ( RDEXACT(fd, &buf->pfncount, sizeof(buf->pfncount)) ||
          (buf->pfncount > (1U << 28)) ) /* up to 1TB of address space */
     {
-        ERROR("Error when reading pfn count");
+        PERROR("Error when reading pfn count");
         return -1;
     }
     pfnlen = sizeof(unsigned long) * buf->pfncount;
@@ -885,8 +889,8 @@ static int buffer_tail_pv(xc_interface *xch, struct 
restore_ctx *ctx,
         }
     }
     // DPRINTF("Reading PFN tab: %d bytes\n", pfnlen);
-    if ( read_exact(fd, buf->pfntab, pfnlen) ) {
-        ERROR("Error when reading pfntab");
+    if ( RDEXACT(fd, buf->pfntab, pfnlen) ) {
+        PERROR("Error when reading pfntab");
         goto free_pfntab;
     }
 
@@ -911,15 +915,15 @@ static int buffer_tail_pv(xc_interface *xch, struct 
restore_ctx *ctx,
         }
     }
     // DPRINTF("Reading VCPUS: %d bytes\n", vcpulen);
-    if ( read_exact(fd, buf->vcpubuf, vcpulen) ) {
-        ERROR("Error when reading ctxt");
+    if ( RDEXACT(fd, buf->vcpubuf, vcpulen) ) {
+        PERROR("Error when reading ctxt");
         goto free_vcpus;
     }
 
     /* load shared_info_page */
     // DPRINTF("Reading shared info: %lu bytes\n", PAGE_SIZE);
-    if ( read_exact(fd, buf->shared_info_page, PAGE_SIZE) ) {
-        ERROR("Error when reading shared info page");
+    if ( RDEXACT(fd, buf->shared_info_page, PAGE_SIZE) ) {
+        PERROR("Error when reading shared info page");
         goto free_vcpus;
     }
 
@@ -1024,9 +1028,9 @@ static int pagebuf_get_one(xc_interface *xch,
     int count, countpages, oldcount, i;
     void* ptmp;
 
-    if ( read_exact(fd, &count, sizeof(count)) )
+    if ( RDEXACT(fd, &count, sizeof(count)) )
     {
-        ERROR("Error when reading batch size");
+        PERROR("Error when reading batch size");
         return -1;
     }
 
@@ -1041,10 +1045,10 @@ static int pagebuf_get_one(xc_interface *xch,
         return pagebuf_get_one(xch, buf, fd, dom);
     } else if (count == -2) {
         buf->new_ctxt_format = 1;
-        if ( read_exact(fd, &buf->max_vcpu_id, sizeof(buf->max_vcpu_id)) ||
-             buf->max_vcpu_id >= 64 || read_exact(fd, &buf->vcpumap,
-                                                  sizeof(uint64_t)) ) {
-            ERROR("Error when reading max_vcpu_id");
+        if ( RDEXACT(fd, &buf->max_vcpu_id, sizeof(buf->max_vcpu_id)) ||
+             buf->max_vcpu_id >= 64 || RDEXACT(fd, &buf->vcpumap,
+                                               sizeof(uint64_t)) ) {
+            PERROR("Error when reading max_vcpu_id");
             return -1;
         }
         // DPRINTF("Max VCPU ID: %d, vcpumap: %llx\n", buf->max_vcpu_id, 
buf->vcpumap);
@@ -1054,7 +1058,7 @@ static int pagebuf_get_one(xc_interface *xch,
         if ( read_exact(fd, &buf->identpt, sizeof(uint32_t)) ||
              read_exact(fd, &buf->identpt, sizeof(uint64_t)) )
         {
-            ERROR("error read the address of the EPT identity map");
+            PERROR("error read the address of the EPT identity map");
             return -1;
         }
         // DPRINTF("EPT identity map address: %llx\n", buf->identpt);
@@ -1064,7 +1068,7 @@ static int pagebuf_get_one(xc_interface *xch,
         if ( read_exact(fd, &buf->vm86_tss, sizeof(uint32_t)) ||
              read_exact(fd, &buf->vm86_tss, sizeof(uint64_t)) )
         {
-            ERROR("error read the address of the vm86 TSS");
+            PERROR("error read the address of the vm86 TSS");
             return -1;
         }
         // DPRINTF("VM86 TSS location: %llx\n", buf->vm86_tss);
@@ -1072,14 +1076,14 @@ static int pagebuf_get_one(xc_interface *xch,
     } else if ( count == -5 ) {
         DPRINTF("xc_domain_restore start tmem\n");
         if ( xc_tmem_restore(xch, dom, fd) ) {
-            ERROR("error reading/restoring tmem");
+            PERROR("error reading/restoring tmem");
             return -1;
         }
         return pagebuf_get_one(xch, buf, fd, dom);
     }
     else if ( count == -6 ) {
         if ( xc_tmem_restore_extra(xch, dom, fd) ) {
-            ERROR("error reading/restoring tmem extra");
+            PERROR("error reading/restoring tmem extra");
             return -1;
         }
         return pagebuf_get_one(xch, buf, fd, dom);
@@ -1091,12 +1095,13 @@ static int pagebuf_get_one(xc_interface *xch,
              read_exact(fd, &khz, sizeof(uint32_t)) ||
              read_exact(fd, &incarn, sizeof(uint32_t)) ||
              xc_domain_set_tsc_info(xch, dom, tsc_mode, nsec, khz, incarn) ) {
-            ERROR("error reading/restoring tsc info");
+            PERROR("error reading/restoring tsc info");
             return -1;
         }
         return pagebuf_get_one(xch, buf, fd, dom);
     } else if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
         ERROR("Max batch size exceeded (%d). Giving up.", count);
+        errno = EMSGSIZE;
         return -1;
     }
 
@@ -1115,7 +1120,7 @@ static int pagebuf_get_one(xc_interface *xch,
         buf->pfn_types = ptmp;
     }
     if ( read_exact(fd, buf->pfn_types + oldcount, count * 
sizeof(*(buf->pfn_types)))) {
-        ERROR("Error when reading region pfn types");
+        PERROR("Error when reading region pfn types");
         return -1;
     }
 
@@ -1142,7 +1147,7 @@ static int pagebuf_get_one(xc_interface *xch,
         buf->pages = ptmp;
     }
     if ( read_exact(fd, buf->pages + oldcount * PAGE_SIZE, countpages * 
PAGE_SIZE) ) {
-        ERROR("Error when reading pages");
+        PERROR("Error when reading pages");
         return -1;
     }
 
@@ -1202,7 +1207,7 @@ static int apply_batch(xc_interface *xch, uint32_t dom, 
struct restore_ctx *ctx,
 
     if ( region_base == NULL )
     {
-        ERROR("map batch failed");
+        PERROR("map batch failed");
         free(pfn_err);
         return -1;
     }
@@ -1305,7 +1310,7 @@ static int apply_batch(xc_interface *xch, uint32_t dom, 
struct restore_ctx *ctx,
                                (((unsigned long long)mfn) << PAGE_SHIFT)
                                | MMU_MACHPHYS_UPDATE, pfn) )
         {
-            ERROR("failed machpys update mfn=%lx pfn=%lx", mfn, pfn);
+            PERROR("failed machpys update mfn=%lx pfn=%lx", mfn, pfn);
             goto err_mapped;
         }
     } /* end of 'batch' for loop */
@@ -1389,7 +1394,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 
     if ( read_exact(io_fd, &dinfo->p2m_size, sizeof(unsigned long)) )
     {
-        ERROR("read: p2m_size");
+        PERROR("read: p2m_size");
         goto out;
     }
     DPRINTF("xc_domain_restore start: p2m_size = %lx\n", dinfo->p2m_size);
@@ -1423,7 +1428,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         frc = do_domctl(xch, &domctl);
         if ( frc != 0 )
         {
-            ERROR("Unable to set guest address size.");
+            PERROR("Unable to set guest address size.");
             goto out;
         }
     }
@@ -1448,7 +1453,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 
     if ( lock_pages(region_mfn, sizeof(xen_pfn_t) * MAX_BATCH_SIZE) )
     {
-        ERROR("Could not lock region_mfn");
+        PERROR("Could not lock region_mfn");
         goto out;
     }
 
@@ -1457,7 +1462,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     domctl.domain = (domid_t)dom;
     if ( xc_domctl(xch, &domctl) < 0 )
     {
-        ERROR("Could not get information on new domain");
+        PERROR("Could not get information on new domain");
         goto out;
     }
     shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
@@ -1469,7 +1474,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     mmu = xc_alloc_mmu_updates(xch, dom);
     if ( mmu == NULL )
     {
-        ERROR("Could not initialise for MMU updates");
+        PERROR("Could not initialise for MMU updates");
         goto out;
     }
 
@@ -1492,7 +1497,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         if ( !completed ) {
             pagebuf.nr_physpages = pagebuf.nr_pages = 0;
             if ( pagebuf_get_one(xch, &pagebuf, io_fd, dom) < 0 ) {
-                ERROR("Error when reading batch\n");
+                PERROR("Error when reading batch\n");
                 goto out;
             }
         }
@@ -1551,7 +1556,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
      */
     if ( !hvm && xc_flush_mmu_updates(xch, mmu) )
     {
-        ERROR("Error doing flush_mmu_updates()");
+        PERROR("Error doing flush_mmu_updates()");
         goto out;
     }
 
@@ -1575,7 +1580,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     // DPRINTF("Buffered checkpoint\n");
 
     if ( pagebuf_get(xch, &pagebuf, io_fd, dom) ) {
-        ERROR("error when buffering batch, finishing\n");
+        PERROR("error when buffering batch, finishing");
         goto finish;
     }
     memset(&tmptail, 0, sizeof(tmptail));
@@ -1633,7 +1638,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
                 new_mfn = xc_make_page_below_4G(xch, dom, ctx->p2m[i]);
                 if ( !new_mfn )
                 {
-                    ERROR("Couldn't get a page below 4GB :-(");
+                    PERROR("Couldn't get a page below 4GB :-(");
                     goto out;
                 }
 
@@ -1643,7 +1648,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
                                         << PAGE_SHIFT) |
                                        MMU_MACHPHYS_UPDATE, i) )
                 {
-                    ERROR("Couldn't m2p on PAE root pgdir");
+                    PERROR("Couldn't m2p on PAE root pgdir");
                     goto out;
                 }
 
@@ -1676,7 +1681,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
                     xch, dom, PROT_READ | PROT_WRITE, region_mfn, j);
                 if ( region_base == NULL )
                 {
-                    ERROR("map batch failed");
+                    PERROR("map batch failed");
                     goto out;
                 }
 
@@ -1698,7 +1703,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 
         if ( xc_flush_mmu_updates(xch, mmu) )
         {
-            ERROR("Error doing xc_flush_mmu_updates()");
+            PERROR("Error doing xc_flush_mmu_updates()");
             goto out;
         }
     }
@@ -1743,7 +1748,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         {
             if ( xc_mmuext_op(xch, pin, nr_pins, dom) < 0 )
             {
-                ERROR("Failed to pin batch of %d page tables", nr_pins);
+                PERROR("Failed to pin batch of %d page tables", nr_pins);
                 goto out;
             }
             nr_pins = 0;
@@ -1753,7 +1758,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     /* Flush final partial batch. */
     if ( (nr_pins != 0) && (xc_mmuext_op(xch, pin, nr_pins, dom) < 0) )
     {
-        ERROR("Failed to pin batch of %d page tables", nr_pins);
+        PERROR("Failed to pin batch of %d page tables", nr_pins);
         goto out;
     }
 
@@ -1788,7 +1793,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
             if ( (frc = xc_memory_op(xch, XENMEM_decrease_reservation,
                                      &reservation)) != nr_frees )
             {
-                ERROR("Could not decrease reservation : %d", frc);
+                PERROR("Could not decrease reservation : %d", frc);
                 goto out;
             }
             else
@@ -1798,7 +1803,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 
     if ( lock_pages(&ctxt, sizeof(ctxt)) )
     {
-        ERROR("Unable to lock ctxt");
+        PERROR("Unable to lock ctxt");
         return 1;
     }
 
@@ -1911,7 +1916,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         frc = xc_domctl(xch, &domctl);
         if ( frc != 0 )
         {
-            ERROR("Couldn't build vcpu%d", i);
+            PERROR("Couldn't build vcpu%d", i);
             goto out;
         }
 
@@ -1924,7 +1929,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         frc = xc_domctl(xch, &domctl);
         if ( frc != 0 )
         {
-            ERROR("Couldn't set extended vcpu%d info\n", i);
+            PERROR("Couldn't set extended vcpu%d info\n", i);
             goto out;
         }
     }
@@ -1968,7 +1973,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
     if ( !(ctx->live_p2m = xc_map_foreign_pages(xch, dom, PROT_WRITE,
                                            p2m_frame_list, P2M_FL_ENTRIES)) )
     {
-        ERROR("Couldn't map p2m table");
+        PERROR("Couldn't map p2m table");
         goto out;
     }
 
@@ -1991,7 +1996,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   finish_hvm:
     /* Dump the QEMU state to a state file for QEMU to load */
     if ( dump_qemu(xch, dom, &tailbuf.u.hvm) ) {
-        ERROR("Error dumping QEMU state to file");
+        PERROR("Error dumping QEMU state to file");
         goto out;
     }
 
@@ -2000,7 +2005,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
          xc_clear_domain_page(xch, dom, tailbuf.u.hvm.magicpfns[1]) ||
          xc_clear_domain_page(xch, dom, tailbuf.u.hvm.magicpfns[2]) )
     {
-        ERROR("error zeroing magic pages");
+        PERROR("error zeroing magic pages");
         goto out;
     }
 
@@ -2016,7 +2021,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
                                     HVM_PARAM_STORE_EVTCHN,
                                     store_evtchn)) )
     {
-        ERROR("error setting HVM params: %i", frc);
+        PERROR("error setting HVM params: %i", frc);
         goto out;
     }
     *store_mfn = tailbuf.u.hvm.magicpfns[2];
@@ -2025,7 +2030,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
                                    tailbuf.u.hvm.reclen);
     if ( frc )
     {
-        ERROR("error setting the HVM context");
+        PERROR("error setting the HVM context");
         goto out;
     }
 
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 398dac4..624b17c 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -147,7 +147,9 @@ static int noncached_write(xc_interface *xch,
     if ( write_count >= (MAX_PAGECACHE_USAGE * PAGE_SIZE) )
     {
         /* Time to discard cache - dont care if this fails */
+        int saved_errno = errno;
         discard_file_cache(xch, fd, 0 /* no flush */);
+        errno = saved_errno;
         write_count = 0;
     }
 
@@ -474,7 +476,7 @@ static void *map_frame_list_list(xc_interface *xch, 
uint32_t dom,
 
     p = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ, fll);
     if ( p == NULL )
-        ERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
+        PERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
 
     return p;
 }
@@ -631,7 +633,7 @@ xen_pfn_t *xc_map_m2p(xc_interface *xch,
     if ( xc_memory_op(xch, XENMEM_machphys_mfn_list, &xmml) ||
          (xmml.nr_extents != m2p_chunks) )
     {
-        ERROR("xc_get_m2p_mfns");
+        PERROR("xc_get_m2p_mfns");
         goto err1;
     }
 
@@ -650,7 +652,7 @@ xen_pfn_t *xc_map_m2p(xc_interface *xch,
                        entries, m2p_chunks);
     if (m2p == NULL)
     {
-        ERROR("xc_mmap_foreign_ranges failed");
+        PERROR("xc_mmap_foreign_ranges failed");
         goto err2;
     }
 
@@ -719,7 +721,7 @@ static xen_pfn_t *map_and_save_p2m_table(xc_interface *xch,
                              P2M_FLL_ENTRIES);
     if ( !live_p2m_frame_list )
     {
-        ERROR("Couldn't map p2m_frame_list");
+        PERROR("Couldn't map p2m_frame_list");
         goto out;
     }
 
@@ -754,7 +756,7 @@ static xen_pfn_t *map_and_save_p2m_table(xc_interface *xch,
                                P2M_FL_ENTRIES);
     if ( !p2m )
     {
-        ERROR("Couldn't map p2m table");
+        PERROR("Couldn't map p2m table");
         goto out;
     }
     ctx->live_p2m = p2m; /* So that translation macros will work */
@@ -784,7 +786,7 @@ static xen_pfn_t *map_and_save_p2m_table(xc_interface *xch,
 
     if ( xc_vcpu_getcontext(xch, dom, 0, &ctxt) )
     {
-        ERROR("Could not get vcpu context");
+        PERROR("Could not get vcpu context");
         goto out;
     }
 
@@ -944,7 +946,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
 
     if ( xc_domain_getinfo(xch, dom, 1, &info) != 1 )
     {
-        ERROR("Could not get domain info");
+        PERROR("Could not get domain info");
         return 1;
     }
 
@@ -957,7 +959,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                                            PROT_READ, shared_info_frame);
         if ( !live_shinfo )
         {
-            ERROR("Couldn't map live_shinfo");
+            PERROR("Couldn't map live_shinfo");
             goto out;
         }
     }
@@ -992,7 +994,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
             
             if ( frc < 0 )
             {
-                ERROR("Couldn't enable shadow mode (rc %d) (errno %d)", frc, 
errno );
+                PERROR("Couldn't enable shadow mode (rc %d) (errno %d)", frc, 
errno );
                 goto out;
             }
         }
@@ -1032,14 +1034,14 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
uint32_t dom, uint32_t max_iter
 
     if ( lock_pages(to_send, BITMAP_SIZE) )
     {
-        ERROR("Unable to lock to_send");
+        PERROR("Unable to lock to_send");
         return 1;
     }
 
     /* (to fix is local only) */
     if ( lock_pages(to_skip, BITMAP_SIZE) )
     {
-        ERROR("Unable to lock to_skip");
+        PERROR("Unable to lock to_skip");
         return 1;
     }
 
@@ -1049,7 +1051,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
         hvm_buf_size = xc_domain_hvm_getcontext(xch, dom, 0, 0);
         if ( hvm_buf_size == -1 )
         {
-            ERROR("Couldn't get HVM context size from Xen");
+            PERROR("Couldn't get HVM context size from Xen");
             goto out;
         }
         hvm_buf = malloc(hvm_buf_size);
@@ -1077,14 +1079,14 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
uint32_t dom, uint32_t max_iter
 
     if ( lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type)) )
     {
-        ERROR("Unable to lock pfn_type array");
+        PERROR("Unable to lock pfn_type array");
         goto out;
     }
 
     /* Setup the mfn_to_pfn table mapping */
     if ( !(ctx->live_m2p = xc_map_m2p(xch, ctx->max_mfn, PROT_READ, 
&ctx->m2p_mfn0)) )
     {
-        ERROR("Failed to map live M2P table");
+        PERROR("Failed to map live M2P table");
         goto out;
     }
 
@@ -1103,7 +1105,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
         ctx->live_p2m = map_and_save_p2m_table(xch, io_fd, dom, ctx, 
live_shinfo);
         if ( ctx->live_p2m == NULL )
         {
-            ERROR("Failed to map/save the p2m frame list");
+            PERROR("Failed to map/save the p2m frame list");
             goto out;
         }
 
@@ -1129,13 +1131,13 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
uint32_t dom, uint32_t max_iter
     tmem_saved = xc_tmem_save(xch, dom, io_fd, live, -5);
     if ( tmem_saved == -1 )
     {
-        ERROR("Error when writing to state file (tmem)");
+        PERROR("Error when writing to state file (tmem)");
         goto out;
     }
 
     if ( !live && save_tsc_info(xch, dom, io_fd) < 0 )
     {
-        ERROR("Error when writing to state file (tsc)");
+        PERROR("Error when writing to state file (tsc)");
         goto out;
     }
 
@@ -1282,7 +1284,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                 xch, dom, PROT_READ, pfn_type, pfn_err, batch);
             if ( region_base == NULL )
             {
-                ERROR("map batch failed");
+                PERROR("map batch failed");
                 goto out;
             }
 
@@ -1309,7 +1311,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                 /* Get page types */
                 if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
                 {
-                    ERROR("get_pfn_type_batch failed");
+                    PERROR("get_pfn_type_batch failed");
                     goto out;
                 }
 
@@ -1376,7 +1378,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                                        (char*)region_base+(PAGE_SIZE*(j-run)), 
                                        PAGE_SIZE*run) != PAGE_SIZE*run )
                         {
-                            ERROR("Error when writing to state file (4a)"
+                            PERROR("Error when writing to state file (4a)"
                                   " (errno %d)", errno);
                             goto out;
                         }                        
@@ -1406,7 +1408,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
 
                     if ( ratewrite(io_fd, live, page, PAGE_SIZE) != PAGE_SIZE )
                     {
-                        ERROR("Error when writing to state file (4b)"
+                        PERROR("Error when writing to state file (4b)"
                               " (errno %d)", errno);
                         goto out;
                     }
@@ -1425,7 +1427,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                                (char*)region_base+(PAGE_SIZE*(j-run)), 
                                PAGE_SIZE*run) != PAGE_SIZE*run )
                 {
-                    ERROR("Error when writing to state file (4c)"
+                    PERROR("Error when writing to state file (4c)"
                           " (errno %d)", errno);
                     goto out;
                 }                        
@@ -1491,13 +1493,13 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
uint32_t dom, uint32_t max_iter
                 if ( (tmem_saved > 0) &&
                      (xc_tmem_save_extra(xch,dom,io_fd,-6) == -1) )
                 {
-                        ERROR("Error when writing to state file (tmem)");
+                        PERROR("Error when writing to state file (tmem)");
                         goto out;
                 }
 
                 if ( save_tsc_info(xch, dom, io_fd) < 0 )
                 {
-                    ERROR("Error when writing to state file (tsc)");
+                    PERROR("Error when writing to state file (tsc)");
                     goto out;
                 }
 
@@ -1508,7 +1510,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                                    XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, 
                                    dinfo->p2m_size, NULL, 0, &stats) != 
dinfo->p2m_size )
             {
-                ERROR("Error flushing shadow PT");
+                PERROR("Error flushing shadow PT");
                 goto out;
             }
 
@@ -1611,7 +1613,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
         if ( (rec_size = xc_domain_hvm_getcontext(xch, dom, hvm_buf, 
                                                   hvm_buf_size)) == -1 )
         {
-            ERROR("HVM:Could not get hvm buffer");
+            PERROR("HVM:Could not get hvm buffer");
             goto out;
         }
         
@@ -1671,7 +1673,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
 
     if ( xc_vcpu_getcontext(xch, dom, 0, &ctxt) )
     {
-        ERROR("Could not get vcpu context");
+        PERROR("Could not get vcpu context");
         goto out;
     }
 
@@ -1691,7 +1693,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
 
         if ( (i != 0) && xc_vcpu_getcontext(xch, dom, i, &ctxt) )
         {
-            ERROR("No context for VCPU%d", i);
+            PERROR("No context for VCPU%d", i);
             goto out;
         }
 
@@ -1743,7 +1745,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
         domctl.u.ext_vcpucontext.vcpu = i;
         if ( xc_domctl(xch, &domctl) < 0 )
         {
-            ERROR("No extended context for VCPU%d", i);
+            PERROR("No extended context for VCPU%d", i);
             goto out;
         }
         if ( wrexact(io_fd, &domctl.u.ext_vcpucontext, 128) )
@@ -1783,7 +1785,7 @@ 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 ( outbuf_flush(xch, &ob, io_fd) < 0 ) {
-        ERROR("Error when flushing output buffer\n");
+        PERROR("Error when flushing output buffer\n");
         rc = 1;
     }
 
@@ -1811,7 +1813,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
                                XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
                                dinfo->p2m_size, NULL, 0, &stats) != 
dinfo->p2m_size )
         {
-            ERROR("Error flushing shadow PT");
+            PERROR("Error flushing shadow PT");
         }
 
         goto copypages;
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index 9bcf175..9761b98 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -741,6 +741,8 @@ int read_exact(int fd, void *data, size_t size)
         len = read(fd, (char *)data + offset, size - offset);
         if ( (len == -1) && (errno == EINTR) )
             continue;
+        if ( len == 0 )
+            errno = 0;
         if ( len <= 0 )
             return -1;
         offset += len;
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 95c0f7d..a919508 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -226,8 +226,8 @@ int xc_add_mmu_update(xc_interface *xch, struct xc_mmu *mmu,
                    unsigned long long ptr, unsigned long long val);
 int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu);
 
-/* Return 0 on success; -1 on error. */
-int read_exact(int fd, void *data, size_t size);
+/* Return 0 on success; -1 on error setting errno. */
+int read_exact(int fd, void *data, size_t size); /* EOF => -1, errno=0 */
 int write_exact(int fd, const void *data, size_t size);
 
 int xc_ffs8(uint8_t x);
-- 
1.5.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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