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

[Xen-devel] [PATCH,RFC] 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.

Patch is RFC since not all call-paths modified have been tested and I
may have missed some. Such a sweeping change has a possibility to break
something.

Signed-off-by: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>

 libxl.c          |  106 +++++++++++++++++++++++++++++++++----------------------
 libxl_dom.c      |   21 ++++++----
 libxl_internal.h |    3 +
 3 files changed, 80 insertions(+), 50 deletions(-)

diff -r 238587759d20 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Mon Jul 19 15:47:58 2010 +0100
+++ b/tools/libxl/libxl.c       Mon Jul 19 16:37:12 2010 +0100
@@ -38,6 +38,28 @@
 
 #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)
 {
     if (version != LIBXL_VERSION)
@@ -519,21 +541,23 @@
 
 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 @@
             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 @@
 {
     char *shutdown_path;
     char *dom_path;
+    int rc = 0;
 
     if (req > ARRAY_SIZE(req_table))
         return ERROR_INVAL;
@@ -577,9 +601,9 @@
         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);
+            rc = xc_domain_shutdown(ctx->xch, domid, req);
     }
-    return 0;
+    return libxl_xc_error(rc);
 }
 
 int libxl_get_wait_fd(struct libxl_ctx *ctx, int *fd)
@@ -624,7 +648,7 @@
     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 *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 @@
         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 @@
 
     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 @@
     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 @@
     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;
 }
@@ -1143,11 +1167,11 @@
     }
     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);
@@ -1351,7 +1375,7 @@
                 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");
@@ -2051,7 +2075,7 @@
     }
     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);
@@ -2301,7 +2325,7 @@
 
     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);
@@ -2350,13 +2374,13 @@
     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;
         }
     }
 
@@ -2370,7 +2394,7 @@
     }
     if (i == num) {
         XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find the device on xenstore");
-        return -1;
+        return ERROR_INVAL;
     }
 
 retry_transaction:
@@ -2384,7 +2408,7 @@
     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;
         }
     }
 
@@ -2464,7 +2488,7 @@
     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);
@@ -2494,7 +2518,7 @@
 
         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)
@@ -2557,7 +2581,7 @@
     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);
@@ -2568,7 +2592,7 @@
         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));
@@ -2692,7 +2716,7 @@
     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;
@@ -2978,14 +3002,14 @@
     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;
@@ -2993,7 +3017,7 @@
 
     rc = xc_sched_credit_domain_set(ctx->xch, domid, &sdom);
     if (rc != 0)
-        return rc;
+        return libxl_xc_error(rc);
 
     return 0;
 }
@@ -3022,7 +3046,7 @@
     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);
@@ -3030,7 +3054,7 @@
         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)
@@ -3156,7 +3180,7 @@
     if (rc < 0) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc,
             "Can not freeze tmem pools");
-        return -1;
+        return ERROR_FAIL;
     }
 
     return rc;
@@ -3171,7 +3195,7 @@
     if (rc < 0) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc,
             "Can not destroy tmem pools");
-        return -1;
+        return ERROR_FAIL;
     }
 
     return rc;
@@ -3186,7 +3210,7 @@
     if (rc < 0) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc,
             "Can not thaw tmem pools");
-        return -1;
+        return ERROR_FAIL;
     }
 
     return rc;
@@ -3212,13 +3236,13 @@
     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;
@@ -3233,7 +3257,7 @@
     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 238587759d20 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Mon Jul 19 15:47:58 2010 +0100
+++ b/tools/libxl/libxl_dom.c   Mon Jul 19 16:37:12 2010 +0100
@@ -212,7 +212,7 @@
     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 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 @@
 
     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 @@
     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 @@
     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 @@
     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 @@
     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 238587759d20 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Mon Jul 19 15:47:58 2010 +0100
+++ b/tools/libxl/libxl_internal.h      Mon Jul 19 16:37:12 2010 +0100
@@ -222,5 +222,8 @@
 #define XL_LOG_WARNING XTL_WARN
 #define XL_LOG_ERROR   XTL_ERROR
 
+/* Error handling */
+int libxl_xc_error(int xc_err);
+
 #endif
 



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


 


Rackspace

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