Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.8005
libxc-pass-errno-to-callers-of-xc_domain_save.p...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libxc-pass-errno-to-callers-of-xc_domain_save.patch of Package xen.8005
From b7fc90f3d4f0d61281312c5d05859ee2de8fc8be Mon Sep 17 00:00:00 2001 From: Olaf Hering <olaf@aepfle.de> Date: Mon, 10 Feb 2014 12:47:26 +0100 Subject: libxc: 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@aepfle.de> --- tools/libxc/xc_domain_save.c | 88 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 6 deletions(-) --- 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, in 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, in 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, in 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, in 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, in 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, in 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, in /* 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, in 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, in { 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, in 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, in 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, in 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, in /* 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, in /* 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, in 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, in 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, in 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, in 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, in /* 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, in 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, in ((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, in (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, in 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, in 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, in */ 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, in 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, in 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, in { 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, in (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, in /* 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in 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, in if ( (chunk.data != 0) && wrexact(io_fd, &chunk, sizeof(chunk)) ) { + errnoval = errno; PERROR("Error when writing the viridian flag"); goto out; } @@ -1753,6 +1799,7 @@ int xc_domain_save(xc_interface *xch, in if ( callbacks->toolstack_save(dom, &buf, &len, callbacks->data) < 0 ) { + errnoval = errno; PERROR("Error calling toolstack_save"); goto out; } @@ -1771,6 +1818,7 @@ int xc_domain_save(xc_interface *xch, in i = XC_SAVE_ID_LAST_CHECKPOINT; if ( wrexact(io_fd, &i, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing last checkpoint chunk"); goto out; } @@ -1790,6 +1838,7 @@ int xc_domain_save(xc_interface *xch, in i = XC_SAVE_ID_ENABLE_COMPRESSION; if ( wrexact(io_fd, &i, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing enable_compression marker"); goto out; } @@ -1799,6 +1848,7 @@ int xc_domain_save(xc_interface *xch, in i = 0; if ( wrexact(io_fd, &i, sizeof(int)) ) { + errnoval = errno; PERROR("Error when writing to state file (6')"); goto out; } @@ -1817,6 +1867,7 @@ int xc_domain_save(xc_interface *xch, in (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; } @@ -1825,18 +1876,21 @@ int xc_domain_save(xc_interface *xch, in 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; } @@ -1861,6 +1915,7 @@ int xc_domain_save(xc_interface *xch, in if ( wrexact(io_fd, &j, sizeof(unsigned int)) ) { + errnoval = errno; PERROR("Error when writing to state file (6a)"); goto out; } @@ -1875,6 +1930,7 @@ int xc_domain_save(xc_interface *xch, in { if ( wrexact(io_fd, &pfntab, sizeof(unsigned long)*j) ) { + errnoval = errno; PERROR("Error when writing to state file (6b)"); goto out; } @@ -1885,6 +1941,7 @@ int xc_domain_save(xc_interface *xch, in if ( xc_vcpu_getcontext(xch, dom, 0, &ctxt) ) { + errnoval = errno; PERROR("Could not get vcpu context"); goto out; } @@ -1900,6 +1957,7 @@ int xc_domain_save(xc_interface *xch, in 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; } @@ -1912,6 +1970,7 @@ int xc_domain_save(xc_interface *xch, in if ( (i != 0) && xc_vcpu_getcontext(xch, dom, i, &ctxt) ) { + errnoval = errno; PERROR("No context for VCPU%d", i); goto out; } @@ -1922,6 +1981,7 @@ int xc_domain_save(xc_interface *xch, in 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; } @@ -1932,6 +1992,7 @@ int xc_domain_save(xc_interface *xch, in 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; } @@ -1943,6 +2004,7 @@ int xc_domain_save(xc_interface *xch, in { 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; } @@ -1955,6 +2017,7 @@ int xc_domain_save(xc_interface *xch, in ? sizeof(ctxt.x64) : sizeof(ctxt.x32))) ) { + errnoval = errno; PERROR("Error when writing to state file (1)"); goto out; } @@ -1965,11 +2028,13 @@ int xc_domain_save(xc_interface *xch, in 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; } @@ -2003,6 +2068,7 @@ int xc_domain_save(xc_interface *xch, in domctl.u.vcpuextstate.size = 0; if ( xc_domctl(xch, &domctl) < 0 ) { + errnoval = errno; PERROR("No eXtended states (XSAVE) for VCPU%d", i); goto out; } @@ -2014,6 +2080,7 @@ int xc_domain_save(xc_interface *xch, in 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; @@ -2021,6 +2088,7 @@ int xc_domain_save(xc_interface *xch, in 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; @@ -2032,6 +2100,7 @@ int xc_domain_save(xc_interface *xch, in 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; @@ -2047,6 +2116,7 @@ int xc_domain_save(xc_interface *xch, in 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; } @@ -2054,6 +2124,7 @@ int xc_domain_save(xc_interface *xch, in /* Flush last write and check for errors. */ if ( fsync(io_fd) && errno != EINVAL ) { + errnoval = errno; PERROR("Error when flushing state file"); goto out; } @@ -2075,6 +2146,7 @@ int xc_domain_save(xc_interface *xch, in ob = &ob_pagebuf; if (wrcompressed(io_fd) < 0) { + errnoval = errno; ERROR("Error when writing compressed data, after postcopy\n"); rc = 1; goto out; @@ -2083,6 +2155,7 @@ int xc_domain_save(xc_interface *xch, in if ( wrexact(io_fd, ob_tailbuf.buf, ob_tailbuf.pos) ) { rc = 1; + errnoval = errno; PERROR("Error when copying tailbuf into outbuf"); goto out; } @@ -2111,6 +2184,7 @@ int xc_domain_save(xc_interface *xch, in if ( suspend_and_state(callbacks->suspend, callbacks->data, xch, io_fd, dom, &info) ) { + errnoval = errno; ERROR("Domain appears not to have suspended"); goto out; } @@ -2162,7 +2236,9 @@ int xc_domain_save(xc_interface *xch, in 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; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor