[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 09/11] tools/xc: pass errno to callers of xc_domain_save
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. Note: some of the functions used in xc_domain_save do not use errno to indicate a reason. In these cases the errno remains undefined as it used to be without this change. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> --- tools/libxc/xc_domain_save.c | 88 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index 42c4752..f32ac81 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -806,6 +806,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 errnoval = 0; int rc = 1, frc, i, j, last_iter = 0, iter = 0; int live = (flags & XCFLAGS_LIVE); int debug = (flags & XCFLAGS_DEBUG); @@ -898,8 +899,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( hvm && !callbacks->switch_qemu_logdirty ) { ERROR("No switch_qemu_logdirty callback provided."); - errno = EINVAL; - return 1; + errnoval = EINVAL; + goto exit; } outbuf_init(xch, &ob_pagebuf, OUTBUF_SIZE); @@ -913,14 +914,16 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( !get_platform_info(xch, dom, &ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) ) { + errnoval = errno; ERROR("Unable to get platform info."); - return 1; + goto exit; } if ( xc_domain_getinfo(xch, dom, 1, &info) != 1 ) { + errnoval = errno; PERROR("Could not get domain info"); - return 1; + goto exit; } shared_info_frame = info.shared_info_frame; @@ -932,6 +935,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 ) { + errnoval = errno; PERROR("Couldn't map live_shinfo"); goto out; } @@ -942,6 +946,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 ) { + errnoval = E2BIG; ERROR("Cannot save this big a guest"); goto out; } @@ -967,6 +972,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( frc < 0 ) { + errnoval = errno; PERROR("Couldn't enable shadow mode (rc %d) (errno %d)", frc, errno ); goto out; } @@ -975,6 +981,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter /* Enable qemu-dm logging dirty pages to xen */ if ( hvm && callbacks->switch_qemu_logdirty(dom, 1, callbacks->data) ) { + errnoval = errno; PERROR("Couldn't enable qemu log-dirty mode (errno %d)", errno); goto out; } @@ -985,6 +992,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( suspend_and_state(callbacks->suspend, callbacks->data, xch, io_fd, dom, &info) ) { + errnoval = errno; ERROR("Domain appears not to have suspended"); goto out; } @@ -994,6 +1002,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter { if (!(compress_ctx = xc_compression_create_context(xch, dinfo->p2m_size))) { + errnoval = errno; ERROR("Failed to create compression context"); goto out; } @@ -1012,6 +1021,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 ) { + errnoval = ENOMEM; ERROR("Couldn't allocate to_send array"); goto out; } @@ -1024,12 +1034,14 @@ 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 ) { + errnoval = errno; PERROR("Couldn't get HVM context size from Xen"); goto out; } hvm_buf = malloc(hvm_buf_size); if ( !hvm_buf ) { + errnoval = ENOMEM; ERROR("Couldn't allocate memory"); goto out; } @@ -1043,7 +1055,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (pfn_type == NULL) || (pfn_batch == NULL) || (pfn_err == NULL) ) { ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays"); - errno = ENOMEM; + errnoval = ENOMEM; goto out; } memset(pfn_type, 0, @@ -1052,6 +1064,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter /* Setup the mfn_to_pfn table mapping */ if ( !(ctx->live_m2p = xc_map_m2p(xch, ctx->max_mfn, PROT_READ, &ctx->m2p_mfn0)) ) { + errnoval = errno; PERROR("Failed to map live M2P table"); goto out; } @@ -1059,6 +1072,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter /* Start writing out the saved-domain record. */ if ( write_exact(io_fd, &dinfo->p2m_size, sizeof(unsigned long)) ) { + errnoval = errno; PERROR("write: p2m_size"); goto out; } @@ -1071,6 +1085,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 ) { + errnoval = errno; PERROR("Failed to map/save the p2m frame list"); goto out; } @@ -1097,12 +1112,14 @@ 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, XC_SAVE_ID_TMEM); if ( tmem_saved == -1 ) { + errnoval = errno; PERROR("Error when writing to state file (tmem)"); goto out; } if ( !live && save_tsc_info(xch, dom, io_fd) < 0 ) { + errnoval = errno; PERROR("Error when writing to state file (tsc)"); goto out; } @@ -1143,6 +1160,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter dinfo->p2m_size, NULL, 0, NULL); if ( frc != dinfo->p2m_size ) { + errnoval = errno; ERROR("Error peeking shadow bitmap"); goto out; } @@ -1257,6 +1275,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 ) { + errnoval = errno; PERROR("map batch failed"); goto out; } @@ -1264,6 +1283,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) ) { + errnoval = errno; PERROR("get_pfn_type_batch failed"); goto out; } @@ -1332,6 +1352,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( wrexact(io_fd, &batch, sizeof(unsigned int)) ) { + errnoval = errno; PERROR("Error when writing to state file (2)"); goto out; } @@ -1341,6 +1362,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter ((unsigned long *)pfn_type)[j] = pfn_type[j]; if ( wrexact(io_fd, pfn_type, sizeof(unsigned long)*batch) ) { + errnoval = errno; PERROR("Error when writing to state file (3)"); goto out; } @@ -1368,6 +1390,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 ) { + errnoval = errno; PERROR("Error when writing to state file (4a)" " (errno %d)", errno); goto out; @@ -1396,6 +1419,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( race && !live ) { + errnoval = errno; ERROR("Fatal PT race (pfn %lx, type %08lx)", pfn, pagetype); goto out; @@ -1409,6 +1433,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter pfn, 1 /* raw page */); if (c_err == -2) /* OOB PFN */ { + errnoval = errno; ERROR("Could not add pagetable page " "(pfn:%" PRIpfn "to page buffer\n", pfn); goto out; @@ -1428,6 +1453,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter */ if (wrcompressed(io_fd) < 0) { + errnoval = errno; ERROR("Error when writing compressed" " data (4b)\n"); goto out; @@ -1437,6 +1463,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter else if ( wruncached(io_fd, live, page, PAGE_SIZE) != PAGE_SIZE ) { + errnoval = errno; PERROR("Error when writing to state file (4b)" " (errno %d)", errno); goto out; @@ -1456,6 +1483,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if (c_err == -2) /* OOB PFN */ { + errnoval = errno; ERROR("Could not add page " "(pfn:%" PRIpfn "to page buffer\n", pfn); goto out; @@ -1465,6 +1493,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter { if (wrcompressed(io_fd) < 0) { + errnoval = errno; ERROR("Error when writing compressed" " data (4c)\n"); goto out; @@ -1483,6 +1512,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 ) { + errnoval = errno; PERROR("Error when writing to state file (4c)" " (errno %d)", errno); goto out; @@ -1520,6 +1550,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter /* send "-1" to put receiver into debug mode */ if ( wrexact(io_fd, &id, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing to state file (6)"); goto out; } @@ -1542,6 +1573,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( suspend_and_state(callbacks->suspend, callbacks->data, xch, io_fd, dom, &info) ) { + errnoval = errno; ERROR("Domain appears not to have suspended"); goto out; } @@ -1550,12 +1582,14 @@ 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,XC_SAVE_ID_TMEM_EXTRA) == -1) ) { + errnoval = errno; PERROR("Error when writing to state file (tmem)"); goto out; } if ( save_tsc_info(xch, dom, io_fd) < 0 ) { + errnoval = errno; PERROR("Error when writing to state file (tsc)"); goto out; } @@ -1567,6 +1601,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter XEN_DOMCTL_SHADOW_OP_CLEAN, HYPERCALL_BUFFER(to_send), dinfo->p2m_size, NULL, 0, &shadow_stats) != dinfo->p2m_size ) { + errnoval = errno; PERROR("Error flushing shadow PT"); goto out; } @@ -1598,6 +1633,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 ) { + errnoval = E2BIG; ERROR("Too many VCPUS in guest!"); goto out; } @@ -1614,6 +1650,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( wrexact(io_fd, &chunk, offsetof(struct chunk, vcpumap) + vcpumap_sz(info.max_vcpu_id)) ) { + errnoval = errno; PERROR("Error when writing to state file"); goto out; } @@ -1633,6 +1670,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the generation id buffer location for guest"); goto out; } @@ -1645,6 +1683,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the ident_pt for EPT guest"); goto out; } @@ -1657,6 +1696,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the paging ring pfn for guest"); goto out; } @@ -1669,6 +1709,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the access ring pfn for guest"); goto out; } @@ -1681,6 +1722,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the sharing ring pfn for guest"); goto out; } @@ -1693,6 +1735,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the vm86 TSS for guest"); goto out; } @@ -1705,6 +1748,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the console pfn for guest"); goto out; } @@ -1716,6 +1760,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ((chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk))) { + errnoval = errno; PERROR("Error when writing the firmware ioport version"); goto out; } @@ -1728,6 +1773,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the viridian flag"); goto out; } @@ -1741,6 +1787,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( callbacks->toolstack_save(dom, &buf, &len, callbacks->data) < 0 ) { + errnoval = errno; PERROR("Error calling toolstack_save"); goto out; } @@ -1759,6 +1806,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter i = XC_SAVE_ID_LAST_CHECKPOINT; if ( wrexact(io_fd, &i, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing last checkpoint chunk"); goto out; } @@ -1778,6 +1826,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter i = XC_SAVE_ID_ENABLE_COMPRESSION; if ( wrexact(io_fd, &i, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing enable_compression marker"); goto out; } @@ -1787,6 +1836,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter i = 0; if ( wrexact(io_fd, &i, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing to state file (6')"); goto out; } @@ -1805,6 +1855,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter (unsigned long *)&magic_pfns[2]); if ( wrexact(io_fd, magic_pfns, sizeof(magic_pfns)) ) { + errnoval = errno; PERROR("Error when writing to state file (7)"); goto out; } @@ -1813,18 +1864,21 @@ 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 ) { + errnoval = errno; PERROR("HVM:Could not get hvm buffer"); goto out; } if ( wrexact(io_fd, &rec_size, sizeof(uint32_t)) ) { + errnoval = errno; PERROR("error write hvm buffer size"); goto out; } if ( wrexact(io_fd, hvm_buf, rec_size) ) { + errnoval = errno; PERROR("write HVM info failed!"); goto out; } @@ -1849,6 +1903,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( wrexact(io_fd, &j, sizeof(unsigned int)) ) { + errnoval = errno; PERROR("Error when writing to state file (6a)"); goto out; } @@ -1863,6 +1918,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter { if ( wrexact(io_fd, &pfntab, sizeof(unsigned long)*j) ) { + errnoval = errno; PERROR("Error when writing to state file (6b)"); goto out; } @@ -1873,6 +1929,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) ) { + errnoval = errno; PERROR("Could not get vcpu context"); goto out; } @@ -1888,6 +1945,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) ) { + errnoval = ERANGE; ERROR("Suspend record is not in range of pseudophys map"); goto out; } @@ -1900,6 +1958,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) ) { + errnoval = errno; PERROR("No context for VCPU%d", i); goto out; } @@ -1910,6 +1969,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) ) { + errnoval = ERANGE; ERROR("GDT frame is not in range of pseudophys map"); goto out; } @@ -1920,6 +1980,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]))) ) { + errnoval = ERANGE; ERROR("PT base is not in range of pseudophys map"); goto out; } @@ -1931,6 +1992,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])) ) { + errnoval = ERANGE; ERROR("PT base is not in range of pseudophys map"); goto out; } @@ -1943,6 +2005,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter ? sizeof(ctxt.x64) : sizeof(ctxt.x32))) ) { + errnoval = errno; PERROR("Error when writing to state file (1)"); goto out; } @@ -1953,11 +2016,13 @@ 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 ) { + errnoval = errno; PERROR("No extended context for VCPU%d", i); goto out; } if ( wrexact(io_fd, &domctl.u.ext_vcpucontext, 128) ) { + errnoval = errno; PERROR("Error when writing to state file (2)"); goto out; } @@ -1971,6 +2036,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter domctl.u.vcpuextstate.size = 0; if ( xc_domctl(xch, &domctl) < 0 ) { + errnoval = errno; PERROR("No eXtended states (XSAVE) for VCPU%d", i); goto out; } @@ -1982,6 +2048,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter buffer = xc_hypercall_buffer_alloc(xch, buffer, domctl.u.vcpuextstate.size); if ( !buffer ) { + errnoval = errno; PERROR("Insufficient memory for getting eXtended states for" "VCPU%d", i); goto out; @@ -1989,6 +2056,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter set_xen_guest_handle(domctl.u.vcpuextstate.buffer, buffer); if ( xc_domctl(xch, &domctl) < 0 ) { + errnoval = errno; PERROR("No eXtended states (XSAVE) for VCPU%d", i); xc_hypercall_buffer_free(xch, buffer); goto out; @@ -2000,6 +2068,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter sizeof(domctl.u.vcpuextstate.size)) || wrexact(io_fd, buffer, domctl.u.vcpuextstate.size) ) { + errnoval = errno; PERROR("Error when writing to state file VCPU extended state"); xc_hypercall_buffer_free(xch, buffer); goto out; @@ -2015,6 +2084,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter arch.pfn_to_mfn_frame_list_list, 0); if ( wrexact(io_fd, page, PAGE_SIZE) ) { + errnoval = errno; PERROR("Error when writing to state file (1)"); goto out; } @@ -2022,6 +2092,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter /* Flush last write and check for errors. */ if ( fsync(io_fd) && errno != EINVAL ) { + errnoval = errno; PERROR("Error when flushing state file"); goto out; } @@ -2043,6 +2114,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter ob = &ob_pagebuf; if (wrcompressed(io_fd) < 0) { + errnoval = errno; ERROR("Error when writing compressed data, after postcopy\n"); rc = 1; goto out; @@ -2051,6 +2123,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( wrexact(io_fd, ob_tailbuf.buf, ob_tailbuf.pos) ) { rc = 1; + errnoval = errno; PERROR("Error when copying tailbuf into outbuf"); goto out; } @@ -2079,6 +2152,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter if ( suspend_and_state(callbacks->suspend, callbacks->data, xch, io_fd, dom, &info) ) { + errnoval = errno; ERROR("Domain appears not to have suspended"); goto out; } @@ -2130,7 +2204,9 @@ 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); +exit: + DPRINTF("Save exit of domid %u with rc=%d, errno=%d\n", dom, rc, errnoval); + errno = errnoval; return !!rc; } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |