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-devel

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

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 12/14] libxc: save/restore error handling fixes
From: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date: Thu, 27 May 2010 17:01:12 +0100
Cc: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Delivery-date: Thu, 27 May 2010 09:37:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1274976074-3965-12-git-send-email-ian.jackson@xxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1274976074-3965-1-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-2-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-3-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-4-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-5-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-6-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-7-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-8-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-9-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-10-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-11-git-send-email-ian.jackson@xxxxxxxxxxxxx> <1274976074-3965-12-git-send-email-ian.jackson@xxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
* 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