[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] More consistent error handling in libxl
# HG changeset patch # User Stefano Stabellini <sstabellini@xxxxxxxxxxxxx> # Date 1279561209 -3600 # Node ID 91c486918e020b3d7c15ac880734701bf0277dd2 # Parent e81454d7c8a1ffb0090641d39f33d55788567df8 More consistent error handling in libxl Lots of places in libxl return -1 as an error which is inconsistent with libxl error codes since that is ERROR_VERSION. Also in other places the xc_* function to implement a command is called but the return value is either never checked or not passed on. This patch introduces a new internal function libxl_xc_error() which maps xc error codes to xl error codes. Callers of libxc functions are converted to use this when returning error codes back to libxl callers. Also a bug is fixed where a caller depends on errno being set but is cleared by cleanup code which calls in to library functions which modify errno as a side-effect. Signed-off-by: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx> --- tools/libxl/libxl.c | 108 ++++++++++++++++++++++++++----------------- tools/libxl/libxl_dom.c | 21 ++++---- tools/libxl/libxl_internal.h | 3 + 3 files changed, 81 insertions(+), 51 deletions(-) diff -r e81454d7c8a1 -r 91c486918e02 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Jul 19 15:33:38 2010 +0100 +++ b/tools/libxl/libxl.c Mon Jul 19 18:40:09 2010 +0100 @@ -37,6 +37,28 @@ #include "tap-ctl.h" #define PAGE_TO_MEMKB(pages) ((pages) * 4) + +int libxl_xc_error(int xc_err) +{ + int ret = ERROR_FAIL; + + switch(xc_err) { + case XC_ERROR_NONE: + return 0; + case XC_INVALID_PARAM: + ret = ERROR_INVAL; + break; + case XC_OUT_OF_MEMORY: + ret = ERROR_NOMEM; + break; + case XC_INTERNAL_ERROR: + case XC_INVALID_KERNEL: + default: + break; + } + + return ret; +} int libxl_ctx_init(struct libxl_ctx *ctx, int version, xentoollog_logger *lg) { @@ -519,21 +541,23 @@ int libxl_domain_suspend(struct libxl_ct int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid) { - xc_domain_pause(ctx->xch, domid); - return 0; + int rc; + rc = xc_domain_pause(ctx->xch, domid); + return libxl_xc_error(rc); } int libxl_domain_core_dump(struct libxl_ctx *ctx, uint32_t domid, const char *filename) { - if ( xc_domain_dumpcore(ctx->xch, domid, filename) ) - return ERROR_FAIL; - return 0; + int rc; + rc = xc_domain_dumpcore(ctx->xch, domid, filename); + return libxl_xc_error(rc); } int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid) { char *path; char *state; + int rc; if (is_hvm(ctx, domid)) { path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); @@ -543,9 +567,8 @@ int libxl_domain_unpause(struct libxl_ct libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL); } } - xc_domain_unpause(ctx->xch, domid); - - return 0; + rc = xc_domain_unpause(ctx->xch, domid); + return libxl_xc_error(rc); } static char *req_table[] = { @@ -560,6 +583,7 @@ int libxl_domain_shutdown(struct libxl_c { char *shutdown_path; char *dom_path; + int rc = 0; if (req > ARRAY_SIZE(req_table)) return ERROR_INVAL; @@ -577,9 +601,9 @@ int libxl_domain_shutdown(struct libxl_c xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state); xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver); if (!pvdriver || acpi_s_state != 0) - xc_domain_shutdown(ctx->xch, domid, req); - } - return 0; + rc = xc_domain_shutdown(ctx->xch, domid, req); + } + return libxl_xc_error(rc); } int libxl_get_wait_fd(struct libxl_ctx *ctx, int *fd) @@ -624,7 +648,7 @@ int libxl_get_event(struct libxl_ctx *ct char **events = xs_read_watch(ctx->xsh, &num); if (num != 2) { free(events); - return -1; + return ERROR_FAIL; } event->path = strdup(events[XS_WATCH_PATH]); event->token = strdup(events[XS_WATCH_TOKEN]); @@ -636,7 +660,7 @@ int libxl_stop_waiting(struct libxl_ctx int libxl_stop_waiting(struct libxl_ctx *ctx, libxl_waiter *waiter) { if (!xs_unwatch(ctx->xsh, waiter->path, waiter->token)) - return -1; + return ERROR_FAIL; else return 0; } @@ -716,7 +740,7 @@ static int libxl_destroy_device_model(st int stubdomid = libxl_get_stubdom_id(ctx, domid); if (!stubdomid) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't find device model's pid"); - return -1; + return ERROR_INVAL; } XL_LOG(ctx, XL_LOG_ERROR, "Device model is a stubdom, domid=%d\n", stubdomid); return libxl_domain_destroy(ctx, stubdomid, 0); @@ -754,7 +778,7 @@ int libxl_domain_destroy(struct libxl_ct dom_path = libxl_xs_get_dompath(ctx, domid); if (!dom_path) - return -1; + return ERROR_FAIL; if (libxl_device_pci_shutdown(ctx, domid) < 0) XL_LOG(ctx, XL_LOG_ERROR, "pci shutdown failed for domid %d", domid); @@ -766,7 +790,7 @@ int libxl_domain_destroy(struct libxl_ct rc = xc_domain_pause(ctx->xch, domid); if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_pause failed for %d", domid); - return -1; + return libxl_xc_error(rc); } if (dm_present) { if (libxl_destroy_device_model(ctx, domid) < 0) @@ -797,7 +821,7 @@ int libxl_domain_destroy(struct libxl_ct rc = xc_domain_destroy(ctx->xch, domid); if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); - return -1; + return libxl_xc_error(rc); } return 0; } @@ -1152,11 +1176,11 @@ retry_transaction: } if (libxl_create_xenpv_qemu(ctx, vfb, num_console, console, &dm_starting) < 0) { free(args); - return -1; + return ERROR_FAIL; } if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { free(args); - return -1; + return ERROR_FAIL; } libxl_domain_unpause(ctx, domid); @@ -1360,7 +1384,7 @@ int libxl_device_disk_add(struct libxl_c if (!dev) dev = make_blktap2_device(ctx, disk->physpath, type); if (!dev) - return -1; + return ERROR_FAIL; flexarray_set(back, boffset++, "tapdisk-params"); flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); flexarray_set(back, boffset++, "params"); @@ -2060,7 +2084,7 @@ int libxl_cdrom_insert(struct libxl_ctx } if (i == num) { XL_LOG(ctx, XL_LOG_ERROR, "Virtual device not found"); - return -1; + return ERROR_FAIL; } libxl_device_disk_del(ctx, disks + i, 1); libxl_device_disk_add(ctx, domid, disk); @@ -2310,7 +2334,7 @@ static int libxl_device_pci_add_xenstore if (!is_hvm(ctx, domid)) { if (libxl_wait_for_backend(ctx, be_path, "4") < 0) - return -1; + return ERROR_FAIL; } back = flexarray_make(16, 1); @@ -2359,13 +2383,13 @@ static int libxl_device_pci_remove_xenst num_devs_path = libxl_sprintf(ctx, "%s/num_devs", be_path); num_devs = libxl_xs_read(ctx, XBT_NULL, num_devs_path); if (!num_devs) - return -1; + return ERROR_INVAL; num = atoi(num_devs); if (!is_hvm(ctx, domid)) { if (libxl_wait_for_backend(ctx, be_path, "4") < 0) { XL_LOG(ctx, XL_LOG_DEBUG, "pci backend at %s is not ready", be_path); - return -1; + return ERROR_FAIL; } } @@ -2379,7 +2403,7 @@ static int libxl_device_pci_remove_xenst } if (i == num) { XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find the device on xenstore"); - return -1; + return ERROR_INVAL; } retry_transaction: @@ -2393,7 +2417,7 @@ retry_transaction: if (!is_hvm(ctx, domid)) { if (libxl_wait_for_backend(ctx, be_path, "4") < 0) { XL_LOG(ctx, XL_LOG_DEBUG, "pci backend at %s is not ready", be_path); - return -1; + return ERROR_FAIL; } } @@ -2473,7 +2497,7 @@ int libxl_device_pci_add(struct libxl_ct hvm = is_hvm(ctx, domid); if (hvm) { if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 0) { - return -1; + return ERROR_FAIL; } path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); state = libxl_xs_read(ctx, XBT_NULL, path); @@ -2503,7 +2527,7 @@ int libxl_device_pci_add(struct libxl_ct if (f == NULL) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", sysfs_path); - return -1; + return ERROR_FAIL; } for (i = 0; i < PROC_PCI_NUM_RESOURCES; i++) { if (fscanf(f, "0x%llx 0x%llx 0x%llx\n", &start, &end, &flags) != 3) @@ -2566,7 +2590,7 @@ int libxl_device_pci_remove(struct libxl hvm = is_hvm(ctx, domid); if (hvm) { if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 0) { - return -1; + return ERROR_FAIL; } path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); state = libxl_xs_read(ctx, XBT_NULL, path); @@ -2577,7 +2601,7 @@ int libxl_device_pci_remove(struct libxl xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem")); if (libxl_wait_for_device_model(ctx, domid, "pci-removed", NULL, NULL) < 0) { XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); - return -1; + return ERROR_FAIL; } path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); @@ -2701,7 +2725,7 @@ int libxl_device_pci_shutdown(struct lib pcidevs = libxl_device_pci_list(ctx, domid, &num); for (i = 0; i < num; i++) { if (libxl_device_pci_remove(ctx, domid, pcidevs + i) < 0) - return -1; + return ERROR_FAIL; } free(pcidevs); return 0; @@ -2987,14 +3011,14 @@ int libxl_sched_credit_domain_set(struct if (scinfo->weight < 1 || scinfo->weight > 65535) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Cpu weight out of range, valid values are within range from 1 to 65535"); - return -1; + return ERROR_INVAL; } if (scinfo->cap < 0 || scinfo->cap > (domaininfo.max_vcpu_id + 1) * 100) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Cpu cap out of range, valid range is from 0 to %d for specified number of vcpus", ((domaininfo.max_vcpu_id + 1) * 100)); - return -1; + return ERROR_INVAL; } sdom.weight = scinfo->weight; @@ -3002,7 +3026,7 @@ int libxl_sched_credit_domain_set(struct rc = xc_sched_credit_domain_set(ctx->xch, domid, &sdom); if (rc != 0) - return rc; + return libxl_xc_error(rc); return 0; } @@ -3031,7 +3055,7 @@ int libxl_send_trigger(struct libxl_ctx if (trigger_type == -1) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, "Invalid trigger, valid triggers are <nmi|reset|init|power|sleep>"); - return -1; + return ERROR_INVAL; } rc = xc_domain_send_trigger(ctx->xch, domid, trigger_type, vcpuid); @@ -3039,7 +3063,7 @@ int libxl_send_trigger(struct libxl_ctx XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Send trigger '%s' failed", trigger_name); - return rc; + return libxl_xc_error(rc); } int libxl_send_sysrq(struct libxl_ctx *ctx, uint32_t domid, char sysrq) @@ -3165,7 +3189,7 @@ int libxl_tmem_freeze(struct libxl_ctx * if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Can not freeze tmem pools"); - return -1; + return ERROR_FAIL; } return rc; @@ -3180,7 +3204,7 @@ int libxl_tmem_destroy(struct libxl_ctx if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Can not destroy tmem pools"); - return -1; + return ERROR_FAIL; } return rc; @@ -3195,7 +3219,7 @@ int libxl_tmem_thaw(struct libxl_ctx *ct if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Can not thaw tmem pools"); - return -1; + return ERROR_FAIL; } return rc; @@ -3221,13 +3245,13 @@ int libxl_tmem_set(struct libxl_ctx *ctx if (subop == -1) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, "Invalid set, valid sets are <weight|cap|compress>"); - return -1; + return ERROR_INVAL; } rc = xc_tmem_control(ctx->xch, -1, subop, domid, set, 0, 0, NULL); if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Can not set tmem %s", name); - return -1; + return libxl_xc_error(rc); } return rc; @@ -3242,7 +3266,7 @@ int libxl_tmem_shared_auth(struct libxl_ if (rc < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "Can not set tmem shared auth"); - return -1; + return libxl_xc_error(rc); } return rc; diff -r e81454d7c8a1 -r 91c486918e02 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Mon Jul 19 15:33:38 2010 +0100 +++ b/tools/libxl/libxl_dom.c Mon Jul 19 18:40:09 2010 +0100 @@ -212,7 +212,7 @@ int build_pv(struct libxl_ctx *ctx, uint ret = 0; out: xc_dom_release(dom); - return ret == 0 ? 0 : ERROR_FAIL; + return libxl_xc_error(ret); } int build_hvm(struct libxl_ctx *ctx, uint32_t domid, @@ -250,10 +250,12 @@ int restore_common(struct libxl_ctx *ctx int fd) { /* read signature */ - return xc_domain_restore(ctx->xch, fd, domid, + int rc; + rc = xc_domain_restore(ctx->xch, fd, domid, state->store_port, &state->store_mfn, state->console_port, &state->console_mfn, info->hvm, info->u.hvm.pae, 0); + return libxl_xc_error(rc); } struct suspendinfo { @@ -359,7 +361,7 @@ int core_suspend(struct libxl_ctx *ctx, si.xce = xc_evtchn_open(); if (si.xce < 0) - return -1; + return ERROR_FAIL; if (si.xce > 0) { port = xs_suspend_evtchn_port(si.domid); @@ -438,7 +440,7 @@ static const char *userdata_path(struct if (rc) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unable to find domain info" " for domain %"PRIu32, domid); - return 0; + return NULL; } uuid_string = string_of_uuid(ctx, info.uuid); @@ -493,13 +495,13 @@ int libxl_userdata_store(struct libxl_ct size_t rs; filename = userdata_path(ctx, domid, userdata_userid, "d"); - if (!filename) return ENOMEM; + if (!filename) return ERROR_NOMEM; if (!datalen) return userdata_delete(ctx, filename); newfilename = userdata_path(ctx, domid, userdata_userid, "n"); - if (!newfilename) return ENOMEM; + if (!newfilename) return ERROR_NOMEM; fd= open(newfilename, O_RDWR|O_CREAT|O_TRUNC, 0600); if (fd<0) goto xe; @@ -523,9 +525,10 @@ int libxl_userdata_store(struct libxl_ct if (f) fclose(f); if (fd>=0) close(fd); + errno = e; XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot write %s for %s", newfilename, filename); - return e; + return ERROR_FAIL; } int libxl_userdata_retrieve(struct libxl_ctx *ctx, uint32_t domid, @@ -537,14 +540,14 @@ int libxl_userdata_retrieve(struct libxl void *data = 0; filename = userdata_path(ctx, domid, userdata_userid, "d"); - if (!filename) return ENOMEM; + if (!filename) return ERROR_NOMEM; e = libxl_read_file_contents(ctx, filename, data_r ? &data : 0, &datalen); if (!e && !datalen) { XL_LOG(ctx, XL_LOG_ERROR, "userdata file %s is empty", filename); if (data_r) assert(!*data_r); - return EPROTO; + return ERROR_FAIL; } if (data_r) *data_r = data; diff -r e81454d7c8a1 -r 91c486918e02 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Mon Jul 19 15:33:38 2010 +0100 +++ b/tools/libxl/libxl_internal.h Mon Jul 19 18:40:09 2010 +0100 @@ -222,5 +222,8 @@ char *libxl_abs_path(struct libxl_ctx *c #define XL_LOG_WARNING XTL_WARN #define XL_LOG_ERROR XTL_ERROR +/* Error handling */ +int libxl_xc_error(int xc_err); + #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |