Gianni Tedesco
2010-Aug-12 16:30 UTC
[Xen-devel] [PATCH, v2]: xl: Implement per-API-call garbage-collection lifetime
Changes since v1: - Fix a double-free bug introduced by v1, pointed out by Stefano where internal pointer was being passed back to caller from libxl_create_stubdom() 8<---------------------------------------------------------------------- Currently scratch variables allocated by libxl have the same lifetime as the context. While this is suitable for one off invocations of xl. It is not so great for a daemon process linking to libxl. In that case there will be prolific leakage of heap memory. My proposed solution involves create a new libxl_gc structure, which contains a pointer to an owning context as well as the garbage collection data. Top-level library functions which expect to do a lot of scratch allocations put gc struct on the stack and initialize it with a macro. Before returning they then call libxl_free_all on this struct. This means that static helper functions called by such functions will usually take a gc instead of a ctx as a first parameter. The patch touches almost every code-path so a close review and testing would be much appreciated. I have tested with valgrind all of the parts I could which looked non-straightforward. Suffice to say that it seems crash-free even if we have exposed a few real memory leaks. These are for cases where we return eg. block list to an xl caller but there is no appropriate block_list_free() function to call. Ian Campbells work in this area should sew up all these loose ends. Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com> diff -r 7b144fe8c528 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl.c Thu Aug 12 15:22:56 2010 +0100 @@ -45,17 +45,12 @@ int libxl_ctx_init(libxl_ctx *ctx, int v return ERROR_VERSION; memset(ctx, 0, sizeof(libxl_ctx)); ctx->lg = lg; - ctx->alloc_maxsize = 256; - ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); - if (!ctx->alloc_ptrs) - return ERROR_NOMEM; memset(&ctx->version_info, 0, sizeof(libxl_version_info)); ctx->xch = xc_interface_open(lg,lg,0); if (!ctx->xch) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "cannot open libxc handle"); - free(ctx->alloc_ptrs); return ERROR_FAIL; } @@ -64,7 +59,6 @@ int libxl_ctx_init(libxl_ctx *ctx, int v XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, "cannot connect to xenstore"); xc_interface_close(ctx->xch); - free(ctx->alloc_ptrs); return ERROR_FAIL; } return 0; @@ -73,8 +67,6 @@ int libxl_ctx_init(libxl_ctx *ctx, int v static void do_free_version_info(libxl_version_info *info); int libxl_ctx_free(libxl_ctx *ctx) { - libxl_free_all(ctx); - free(ctx->alloc_ptrs); xc_interface_close(ctx->xch); do_free_version_info(&ctx->version_info); if (ctx->xsh) xs_daemon_close(ctx->xsh); @@ -86,6 +78,7 @@ int libxl_ctx_free(libxl_ctx *ctx) int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int flags, ret, i, rc; char *uuid_string; char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; @@ -98,7 +91,10 @@ int libxl_domain_make(libxl_ctx *ctx, li xen_domain_handle_t handle; uuid_string = libxl_uuid2string(ctx, info->uuid); - if (!uuid_string) return ERROR_NOMEM; + if (!uuid_string) { + libxl_free_all(&gc); + return ERROR_NOMEM; + } flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; @@ -111,22 +107,27 @@ int libxl_domain_make(libxl_ctx *ctx, li ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); if (ret < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain creation fail"); + libxl_free_all(&gc); return ERROR_FAIL; } ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); if (ret < 0) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain move fail"); + libxl_free_all(&gc); return ERROR_FAIL; } - dom_path = libxl_xs_get_dompath(ctx, *domid); - if (!dom_path) + dom_path = libxl_xs_get_dompath(&gc, *domid); + if (!dom_path) { + libxl_free_all(&gc); return ERROR_FAIL; - - vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); + } + + vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string); if (!vm_path) { XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths"); + libxl_free_all(&gc); return ERROR_FAIL; } @@ -147,42 +148,47 @@ retry_transaction: xs_mkdir(ctx->xsh, t, vm_path); xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); - if (rc) return rc; + if (rc) { + libxl_free_all(&gc); + return rc; + } for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { - char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]); + char *path = libxl_sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); xs_mkdir(ctx->xsh, t, path); xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); - libxl_free(ctx, path); } for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { - char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]); + char *path = libxl_sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); xs_mkdir(ctx->xsh, t, path); xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - libxl_free(ctx, path); } - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); if (info->poolname) - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); - - libxl_xs_writev(ctx, t, dom_path, info->xsdata); - libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata); - - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); + + libxl_xs_writev(&gc, t, dom_path, info->xsdata); + libxl_xs_writev(&gc, t, libxl_sprintf(&gc, "%s/platform", dom_path), info->platformdata); + + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; + + libxl_free_all(&gc); return 0; } int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, const char *old_name, const char *new_name, - xs_transaction_t trans) { + xs_transaction_t trans) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path = 0; const char *name_path; char *got_old_name; @@ -190,10 +196,10 @@ int libxl_domain_rename(libxl_ctx *ctx, xs_transaction_t our_trans = 0; int rc; - dom_path = libxl_xs_get_dompath(ctx, domid); + dom_path = libxl_xs_get_dompath(&gc, domid); if (!dom_path) goto x_nomem; - name_path= libxl_sprintf(ctx, "%s/name", dom_path); + name_path= libxl_sprintf(&gc, "%s/name", dom_path); if (!name_path) goto x_nomem; retry_transaction: @@ -250,8 +256,8 @@ int libxl_domain_rename(libxl_ctx *ctx, rc = 0; x_rc: - if (dom_path) libxl_free(ctx, dom_path); if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1); + libxl_free_all(&gc); return rc; x_fail: rc = ERROR_FAIL; goto x_rc; @@ -260,38 +266,42 @@ int libxl_domain_rename(libxl_ctx *ctx, int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char **vments = NULL, **localents = NULL; struct timeval start_time; int i, ret; ret = build_pre(ctx, domid, info, state); - if (ret) goto out; + if (ret) + goto out; gettimeofday(&start_time, NULL); if (info->hvm) { ret = build_hvm(ctx, domid, info, state); - if (ret) goto out; - - vments = libxl_calloc(ctx, 7, sizeof(char *)); + if (ret) + goto out; + + vments = libxl_calloc(&gc, 7, sizeof(char *)); vments[0] = "rtc/timeoffset"; vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; vments[2] = "image/ostype"; vments[3] = "hvm"; vments[4] = "start_time"; - vments[5] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[5] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); } else { ret = build_pv(ctx, domid, info, state); - if (ret) goto out; - - vments = libxl_calloc(ctx, 11, sizeof(char *)); + if (ret) + goto out; + + vments = libxl_calloc(&gc, 11, sizeof(char *)); i = 0; vments[i++] = "image/ostype"; vments[i++] = "linux"; vments[i++] = "image/kernel"; vments[i++] = (char*) info->kernel.path; vments[i++] = "start_time"; - vments[i++] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[i++] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); if (info->u.pv.ramdisk.path) { vments[i++] = "image/ramdisk"; vments[i++] = (char*) info->u.pv.ramdisk.path; @@ -307,6 +317,7 @@ out: if (!info->hvm) libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk); + libxl_free_all(&gc); return ret; } @@ -314,35 +325,38 @@ int libxl_domain_restore(libxl_ctx *ctx, uint32_t domid, int fd, libxl_domain_build_state *state, libxl_device_model_info *dm_info) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char **vments = NULL, **localents = NULL; struct timeval start_time; int i, ret, esave, flags; ret = build_pre(ctx, domid, info, state); - if (ret) goto out; + if (ret) + goto out; ret = restore_common(ctx, domid, info, state, fd); - if (ret) goto out; + if (ret) + goto out; gettimeofday(&start_time, NULL); if (info->hvm) { - vments = libxl_calloc(ctx, 7, sizeof(char *)); + vments = libxl_calloc(&gc, 7, sizeof(char *)); vments[0] = "rtc/timeoffset"; vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; vments[2] = "image/ostype"; vments[3] = "hvm"; vments[4] = "start_time"; - vments[5] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[5] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); } else { - vments = libxl_calloc(ctx, 11, sizeof(char *)); + vments = libxl_calloc(&gc, 11, sizeof(char *)); i = 0; vments[i++] = "image/ostype"; vments[i++] = "linux"; vments[i++] = "image/kernel"; vments[i++] = (char*) info->kernel.path; vments[i++] = "start_time"; - vments[i++] = libxl_sprintf(ctx, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + vments[i++] = libxl_sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); if (info->u.pv.ramdisk.path) { vments[i++] = "image/ramdisk"; vments[i++] = (char*) info->u.pv.ramdisk.path; @@ -353,7 +367,8 @@ int libxl_domain_restore(libxl_ctx *ctx, } } ret = build_post(ctx, domid, info, state, vments, localents); - if (ret) goto out; + if (ret) + goto out; dm_info->saved_state = NULL; if (info->hvm) { @@ -380,28 +395,36 @@ out: } errno = esave; + libxl_free_all(&gc); return ret; } int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); + int rc = 0; + if (is_hvm(ctx, domid)) { XL_LOG(ctx, XL_LOG_DEBUG, "Called domain_resume on " "non-cooperative hvm domain %u", domid); - return ERROR_NI; + rc = ERROR_NI; + goto out; } if (xc_domain_resume(ctx->xch, domid, 1)) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_domain_resume failed for domain %u", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } if (!xs_resume_domain(ctx->xsh, domid)) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_resume_domain failed for domain %u", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; } +out: + libxl_free_all(&gc); return 0; } @@ -414,6 +437,7 @@ int libxl_domain_resume(libxl_ctx *ctx, int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); struct xs_permissions roperm[2]; xs_transaction_t t; char *preserved_name; @@ -423,17 +447,29 @@ int libxl_domain_preserve(libxl_ctx *ctx int rc; - preserved_name = libxl_sprintf(ctx, "%s%s", info->name, name_suffix); - if (!preserved_name) return ERROR_NOMEM; + preserved_name = libxl_sprintf(&gc, "%s%s", info->name, name_suffix); + if (!preserved_name) { + libxl_free_all(&gc); + return ERROR_NOMEM; + } uuid_string = libxl_uuid2string(ctx, new_uuid); - if (!uuid_string) return ERROR_NOMEM; - - dom_path = libxl_xs_get_dompath(ctx, domid); - if (!dom_path) return ERROR_FAIL; - - vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string); - if (!vm_path) return ERROR_FAIL; + if (!uuid_string) { + libxl_free_all(&gc); + return ERROR_NOMEM; + } + + dom_path = libxl_xs_get_dompath(&gc, domid); + if (!dom_path) { + libxl_free_all(&gc); + return ERROR_FAIL; + } + + vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string); + if (!vm_path) { + libxl_free_all(&gc); + return ERROR_FAIL; + } roperm[0].id = 0; roperm[0].perms = XS_PERM_NONE; @@ -447,16 +483,17 @@ int libxl_domain_preserve(libxl_ctx *ctx xs_mkdir(ctx->xsh, t, vm_path); xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl_domain_rename(ctx, domid, info->name, preserved_name, t); if (rc) return rc; - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; + libxl_free_all(&gc); return 0; } @@ -586,11 +623,12 @@ int libxl_domain_suspend(libxl_ctx *ctx, int hvm = is_hvm(ctx, domid); int live = info != NULL && info->flags & XL_SUSPEND_LIVE; int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG; + int rc = 0; core_suspend(ctx, domid, fd, hvm, live, debug); if (hvm) - return save_device_model(ctx, domid, fd); - return 0; + rc = save_device_model(ctx, domid, fd); + return rc; } int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid) @@ -619,24 +657,26 @@ int libxl_domain_core_dump(libxl_ctx *ct int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path; char *state; - int ret; + int ret, rc = 0; if (is_hvm(ctx, domid)) { - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); - state = libxl_xs_read(ctx, XBT_NULL, path); + path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d/state", domid); + state = libxl_xs_read(&gc, XBT_NULL, path); if (state != NULL && !strcmp(state, "paused")) { - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "continue"); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "continue"); libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL); } } ret = xc_domain_unpause(ctx->xch, domid); if (ret<0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unpausing domain %d", domid); - return ERROR_FAIL; + rc = ERROR_FAIL; } - return 0; + libxl_free_all(&gc); + return rc; } static char *req_table[] = { @@ -649,17 +689,22 @@ static char *req_table[] = { int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *shutdown_path; char *dom_path; - if (req > ARRAY_SIZE(req_table)) + if (req > ARRAY_SIZE(req_table)) { + libxl_free_all(&gc); return ERROR_INVAL; - - dom_path = libxl_xs_get_dompath(ctx, domid); - if (!dom_path) + } + + dom_path = libxl_xs_get_dompath(&gc, domid); + if (!dom_path) { + libxl_free_all(&gc); return ERROR_FAIL; - - shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path); + } + + shutdown_path = libxl_sprintf(&gc, "%s/control/shutdown", dom_path); xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req])); if (is_hvm(ctx,domid)) { @@ -684,6 +729,7 @@ int libxl_domain_shutdown(libxl_ctx *ctx } } } + libxl_free_all(&gc); return 0; } @@ -705,7 +751,8 @@ int libxl_wait_for_domain_death(libxl_ct int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t guest_domid, libxl_device_disk *disks, int num_disks, libxl_waiter *waiter) { - int i; + libxl_gc gc = LIBXL_INIT_GC(ctx); + int i, rc = -1; uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid); if (!domid) @@ -713,14 +760,17 @@ int libxl_wait_for_disk_ejects(libxl_ctx for (i = 0; i < num_disks; i++) { if (asprintf(&(waiter[i].path), "%s/device/vbd/%d/eject", - libxl_xs_get_dompath(ctx, domid), + libxl_xs_get_dompath(&gc, domid), device_disk_dev_number(disks[i].virtpath)) < 0) - return -1; + goto out; if (asprintf(&(waiter[i].token), "%d", LIBXL_EVENT_DISK_EJECT) < 0) - return -1; + goto out; xs_watch(ctx->xsh, waiter->path, waiter->token); } - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_get_event(libxl_ctx *ctx, libxl_event *event) @@ -773,49 +823,56 @@ int libxl_event_get_domain_death_info(li int libxl_event_get_disk_eject_info(libxl_ctx *ctx, uint32_t domid, libxl_event *event, libxl_device_disk *disk) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path; char *backend; char *value; - value = libxl_xs_read(ctx, XBT_NULL, event->path); - - if (!value || strcmp(value, "eject")) + value = libxl_xs_read(&gc, XBT_NULL, event->path); + + if (!value || strcmp(value, "eject")) { + libxl_free_all(&gc); return 0; + } path = strdup(event->path); path[strlen(path) - 6] = ''\0''; - backend = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", path)); + backend = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", path)); disk->backend_domid = 0; disk->domid = domid; disk->physpath = NULL; disk->phystype = 0; /* this value is returned to the user: do not free right away */ - disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", backend)); + disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", backend)); disk->unpluggable = 1; disk->readwrite = 0; disk->is_cdrom = 1; free(path); + libxl_free_all(&gc); return 1; } static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *pid; int ret; - pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); + pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid)); if (!pid) { 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 ERROR_INVAL; + ret = ERROR_INVAL; + goto out; } XL_LOG(ctx, XL_LOG_ERROR, "Device model is a stubdom, domid=%d\n", stubdomid); - return libxl_domain_destroy(ctx, stubdomid, 0); + ret = libxl_domain_destroy(ctx, stubdomid, 0); + goto out; } - xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid)); + xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", domid)); ret = kill(atoi(pid), SIGHUP); if (ret < 0 && errno == ESRCH) { @@ -828,11 +885,14 @@ static int libxl_destroy_device_model(li XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to kill Device Model [%d]", atoi(pid)); } +out: + libxl_free_all(&gc); return ret; } int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path; char *vm_path; int rc, dm_present; @@ -841,20 +901,21 @@ int libxl_domain_destroy(libxl_ctx *ctx, dm_present = 1; } else { char *pid; - pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid)); + pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid)); dm_present = (pid != NULL); - libxl_free(ctx, pid); } - dom_path = libxl_xs_get_dompath(ctx, domid); - if (!dom_path) - return ERROR_FAIL; + dom_path = libxl_xs_get_dompath(&gc, domid); + if (!dom_path) { + rc = ERROR_FAIL; + goto out; + } if (libxl_device_pci_shutdown(ctx, domid) < 0) XL_LOG(ctx, XL_LOG_ERROR, "pci shutdown failed for domid %d", domid); if (dm_present) { xs_write(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), + libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "shutdown", strlen("shutdown")); } rc = xc_domain_pause(ctx->xch, domid); @@ -868,7 +929,7 @@ int libxl_domain_destroy(libxl_ctx *ctx, if (libxl_devices_destroy(ctx, domid, force) < 0) XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", domid); - vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dom_path)); + vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dom_path)); if (vm_path) if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path); @@ -881,17 +942,24 @@ int libxl_domain_destroy(libxl_ctx *ctx, 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 ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } + rc = 0; +out: + libxl_free_all(&gc); return 0; } int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num) { - char *p = libxl_sprintf(ctx, "%s/xenconsole", libxl_private_bindir_path()); - char *domid_s = libxl_sprintf(ctx, "%d", domid); - char *cons_num_s = libxl_sprintf(ctx, "%d", cons_num); - return execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL) == 0 ? 0 : ERROR_FAIL; + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *p = libxl_sprintf(&gc, "%s/xenconsole", libxl_private_bindir_path()); + char *domid_s = libxl_sprintf(&gc, "%d", domid); + char *cons_num_s = libxl_sprintf(&gc, "%d", cons_num); + execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL); + libxl_free_all(&gc); + return ERROR_FAIL; } int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) @@ -905,6 +973,7 @@ int libxl_primary_console_exec(libxl_ctx int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) { + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *vnc_port, *vfb_back; const char *vnc_listen = NULL, *vnc_pass = NULL; int port = 0, autopass_fd = -1; @@ -915,22 +984,22 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, NULL, }; - vnc_port = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vnc_port = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/console/vnc-port", domid)); if ( vnc_port ) port = atoi(vnc_port) - 5900; - vfb_back = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vfb_back = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/device/vfb/0/backend", domid)); if ( vfb_back ) { - vnc_listen = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vnc_listen = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/console/vnc-listen", domid)); if ( autopass ) - vnc_pass = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, + vnc_pass = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "/local/domain/%d/console/vnc-pass", domid)); } @@ -940,7 +1009,7 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, if ( (vnc_bin = getenv("VNCVIEWER")) ) args[0] = vnc_bin; - args[1] = libxl_sprintf(ctx, "%s:%d", vnc_listen, port); + args[1] = libxl_sprintf(&gc, "%s:%d", vnc_listen, port); if ( vnc_pass ) { char tmpname[] = "/tmp/vncautopass.XXXXXX"; @@ -962,11 +1031,12 @@ int libxl_vncviewer_exec(libxl_ctx *ctx, } skip_autopass: + libxl_free_all(&gc); libxl_exec(autopass_fd, -1, -1, args[0], args); return 0; } -static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, +static char ** libxl_build_device_model_args_old(libxl_gc *gc, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) @@ -974,13 +1044,14 @@ static char ** libxl_build_device_model_ int num = 0, i; flexarray_t *dm_args; dm_args = flexarray_make(16, 1); + if (!dm_args) return NULL; flexarray_set(dm_args, num++, "qemu-dm"); flexarray_set(dm_args, num++, "-d"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid)); if (info->dom_name) { flexarray_set(dm_args, num++, "-domain-name"); @@ -992,18 +1063,18 @@ static char ** libxl_build_device_model_ if (info->vnclisten && strchr(info->vnclisten, '':'') == NULL) { flexarray_set( dm_args, num++, - libxl_sprintf(ctx, "%s:%d%s", + libxl_sprintf(gc, "%s:%d%s", info->vnclisten, info->vncdisplay, info->vncpasswd ? ",password" : "")); } else { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "127.0.0.1:%d", info->vncdisplay)); } } else if (info->vnclisten) { if (strchr(info->vnclisten, '':'') != NULL) { flexarray_set(dm_args, num++, info->vnclisten); } else { - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%s:0", info->vnclisten)); } } else { flexarray_set(dm_args, num++, "127.0.0.1:0"); @@ -1034,7 +1105,7 @@ static char ** libxl_build_device_model_ if (info->videoram) { flexarray_set(dm_args, num++, "-videoram"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->videoram)); } if (info->stdvga) { flexarray_set(dm_args, num++, "-std-vga"); @@ -1060,24 +1131,24 @@ static char ** libxl_build_device_model_ } if (info->vcpus > 1) { flexarray_set(dm_args, num++, "-vcpus"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->vcpus)); } if (info->vcpu_avail) { flexarray_set(dm_args, num++, "-vcpu_avail"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "0x%x", info->vcpu_avail)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "0x%x", info->vcpu_avail)); } for (i = 0; i < num_vifs; i++) { if (vifs[i].nictype == NICTYPE_IOEMU) { - char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); if (!vifs[i].ifname) - vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid); + vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s", vifs[i].devid, smac, vifs[i].model)); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s,script=no", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no", vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); ioemu_vifs++; } @@ -1103,7 +1174,7 @@ static char ** libxl_build_device_model_ return (char **) flexarray_contents(dm_args); } -static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, +static char ** libxl_build_device_model_args_new(libxl_gc *gc, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) @@ -1120,7 +1191,7 @@ static char ** libxl_build_device_model_ flexarray_set(dm_args, num++, "qemu-system-xen"); flexarray_set(dm_args, num++, "-xen-domid"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid)); if (info->dom_name) { flexarray_set(dm_args, num++, "-name"); @@ -1143,11 +1214,11 @@ static char ** libxl_build_device_model_ if (strchr(listen, '':'') != NULL) flexarray_set(dm_args, num++, - libxl_sprintf(ctx, "%s%s", listen, + libxl_sprintf(gc, "%s%s", listen, info->vncunused ? ",to=99" : "")); else flexarray_set(dm_args, num++, - libxl_sprintf(ctx, "%s:%d%s", listen, display, + libxl_sprintf(gc, "%s:%d%s", listen, display, info->vncunused ? ",to=99" : "")); } if (info->sdl) { @@ -1174,7 +1245,7 @@ static char ** libxl_build_device_model_ if (info->boot) { flexarray_set(dm_args, num++, "-boot"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "order=%s", info->boot)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "order=%s", info->boot)); } if (info->usb || info->usbdevice) { flexarray_set(dm_args, num++, "-usb"); @@ -1193,22 +1264,22 @@ static char ** libxl_build_device_model_ if (info->vcpus > 1) { flexarray_set(dm_args, num++, "-smp"); if (info->vcpu_avail) - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail)); else - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->vcpus)); } for (i = 0; i < num_vifs; i++) { if (vifs[i].nictype == NICTYPE_IOEMU) { - char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); if (!vifs[i].ifname) - vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid); + vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s", vifs[i].devid, smac, vifs[i].model)); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,script=no", + flexarray_set(dm_args, num++, libxl_sprintf(gc, "tap,vlan=%d,ifname=%s,script=no", vifs[i].devid, vifs[i].ifname)); ioemu_vifs++; } @@ -1231,34 +1302,36 @@ static char ** libxl_build_device_model_ else flexarray_set(dm_args, num++, "xenfv"); - disks = libxl_device_disk_list(ctx, info->domid, &nb); + disks = libxl_device_disk_list(libxl_gc_owner(gc), info->domid, &nb); for (; nb > 0; --nb, ++disks) { if ( disks->is_cdrom ) { flexarray_set(dm_args, num++, "-cdrom"); flexarray_set(dm_args, num++, disks->physpath); }else{ - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-%s", disks->virtpath)); + flexarray_set(dm_args, num++, libxl_sprintf(gc, "-%s", disks->virtpath)); flexarray_set(dm_args, num++, disks->physpath); } } + free(disks); flexarray_set(dm_args, num++, NULL); return (char **) flexarray_contents(dm_args); } -static char ** libxl_build_device_model_args(libxl_ctx *ctx, +static char ** libxl_build_device_model_args(libxl_gc *gc, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) { + libxl_ctx *ctx = libxl_gc_owner(gc); int new_qemu; new_qemu = libxl_check_device_model_version(ctx, info->device_model); if (new_qemu == 1) { - return libxl_build_device_model_args_new(ctx, info, vifs, num_vifs); + return libxl_build_device_model_args_new(gc, info, vifs, num_vifs); } else { - return libxl_build_device_model_args_old(ctx, info, vifs, num_vifs); + return libxl_build_device_model_args_old(gc, info, vifs, num_vifs); } } @@ -1309,6 +1382,7 @@ static int libxl_vfb_and_vkb_from_device static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int i; char *vm_path; char *dmargs, *path; @@ -1321,7 +1395,7 @@ static int libxl_write_dmargs(libxl_ctx roperm[1].id = domid; roperm[1].perms = XS_PERM_READ; - vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/vm", guest_domid)); + vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/%d/vm", guest_domid)); i = 0; dmargs_size = 0; @@ -1340,17 +1414,18 @@ static int libxl_write_dmargs(libxl_ctx } i++; } - path = libxl_sprintf(ctx, "%s/image/dmargs", vm_path); + path = libxl_sprintf(&gc, "%s/image/dmargs", vm_path); retry_transaction: t = xs_transaction_start(ctx->xsh); xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs)); xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm)); + xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; free(dmargs); + libxl_free_all(&gc); return 0; } @@ -1362,6 +1437,7 @@ static int libxl_create_stubdom(libxl_ct libxl_device_vkb *vkb, libxl_device_model_starting **starting_r) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int i, num_console = 1, ret; libxl_device_console *console; libxl_domain_create_info c_info; @@ -1373,13 +1449,15 @@ static int libxl_create_stubdom(libxl_ct xs_transaction_t t; libxl_device_model_starting *dm_starting = 0; - args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); - if (!args) - return ERROR_FAIL; + args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); + if (!args) { + ret = ERROR_FAIL; + goto out; + } memset(&c_info, 0x00, sizeof(libxl_domain_create_info)); c_info.hvm = 0; - c_info.name = libxl_sprintf(ctx, "%s-dm", _libxl_domid_to_name(ctx, info->domid)); + c_info.name = libxl_sprintf(&gc, "%s-dm", _libxl_domid_to_name(&gc, info->domid)); for (i = 0; i < 16; i++) c_info.uuid[i] = info->uuid[i]; @@ -1387,28 +1465,31 @@ static int libxl_create_stubdom(libxl_ct b_info.max_vcpus = 1; b_info.max_memkb = 32 * 1024; b_info.target_memkb = b_info.max_memkb; - b_info.kernel.path = libxl_abs_path(ctx, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path()); - b_info.u.pv.cmdline = libxl_sprintf(ctx, " -d %d", info->domid); + b_info.kernel.path = libxl_abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path()); + b_info.u.pv.cmdline = libxl_sprintf(&gc, " -d %d", info->domid); b_info.u.pv.ramdisk.path = ""; b_info.u.pv.features = ""; b_info.hvm = 0; ret = libxl_domain_make(ctx, &c_info, &domid); - if (ret) return ret; + if (ret) + goto out_free; ret = libxl_domain_build(ctx, &b_info, domid, &state); - if (ret) return ret; + if (ret) + goto out_free; libxl_write_dmargs(ctx, domid, info->domid, args); - libxl_xs_write(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, info->domid)), + libxl_xs_write(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/image/device-model-domid", libxl_xs_get_dompath(&gc, info->domid)), "%d", domid); - libxl_xs_write(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid)), + libxl_xs_write(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/target", libxl_xs_get_dompath(&gc, domid)), "%d", info->domid); ret = xc_domain_set_target(ctx->xch, domid, info->domid); if (ret<0) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "setting target domain %d -> %d", domid, info->domid); - return ERROR_FAIL; + ret = ERROR_FAIL; + goto out_free; } xs_set_target(ctx->xsh, domid, info->domid); @@ -1418,10 +1499,10 @@ static int libxl_create_stubdom(libxl_ct perm[1].perms = XS_PERM_READ; retry_transaction: t = xs_transaction_start(ctx->xsh); - xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid)); - xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm)); - xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/%d/device/vfs", domid)); - xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm)); + xs_mkdir(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid)); + xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm)); + xs_mkdir(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/%d/device/vfs", domid)); + xs_set_permissions(ctx->xsh, t, libxl_sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -1429,26 +1510,32 @@ retry_transaction: for (i = 0; i < num_disks; i++) { disks[i].domid = domid; ret = libxl_device_disk_add(ctx, domid, &disks[i]); - if (ret) return ret; + if (ret) + goto out_free; } for (i = 0; i < num_vifs; i++) { vifs[i].domid = domid; ret = libxl_device_nic_add(ctx, domid, &vifs[i]); - if (ret) return ret; + if (ret) + goto out_free; } vfb->domid = domid; ret = libxl_device_vfb_add(ctx, domid, vfb); - if (ret) return ret; + if (ret) + goto out_free; vkb->domid = domid; ret = libxl_device_vkb_add(ctx, domid, vkb); - if (ret) return ret; + if (ret) + goto out_free; if (info->serial) num_console++; - console = libxl_calloc(ctx, num_console, sizeof(libxl_device_console)); - if (!console) - return ERROR_NOMEM; + console = libxl_calloc(&gc, num_console, sizeof(libxl_device_console)); + if (!console) { + ret = ERROR_NOMEM; + goto out_free; + } for (i = 0; i < num_console; i++) { console[i].devid = i; @@ -1457,28 +1544,34 @@ retry_transaction: if (!i) console[i].build_state = &state; ret = libxl_device_console_add(ctx, domid, &console[i]); - if (ret) return ret; + if (ret) + goto out_free; } if (libxl_create_xenpv_qemu(ctx, vfb, num_console, console, &dm_starting) < 0) { - free(args); - return ERROR_FAIL; + ret = ERROR_FAIL; + goto out_free; } if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { - free(args); - return ERROR_FAIL; + ret = ERROR_FAIL; + goto out_free; } libxl_domain_unpause(ctx, domid); if (starting_r) { - *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 1); + *starting_r = calloc(gc, sizeof(libxl_device_model_starting), 1); (*starting_r)->domid = info->domid; - (*starting_r)->dom_path = libxl_xs_get_dompath(ctx, info->domid); + (*starting_r)->dom_path = libxl_xs_get_dompath(&gc, info->domid); (*starting_r)->for_spawn = NULL; } + ret = 0; + +out_free: free(args); - return 0; +out: + libxl_free_all(&gc); + return ret; } int libxl_create_device_model(libxl_ctx *ctx, @@ -1487,6 +1580,7 @@ int libxl_create_device_model(libxl_ctx libxl_device_nic *vifs, int num_vifs, libxl_device_model_starting **starting_r) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path, *logfile; int logfile_w, null; int rc; @@ -1501,48 +1595,55 @@ int libxl_create_device_model(libxl_ctx libxl_device_vkb vkb; libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb); - return libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r); + rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r); + goto out; } - args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); - if (!args) - return ERROR_FAIL; - - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid); + args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); + if (!args) { + rc = ERROR_FAIL; + goto out; + } + + path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid); xs_mkdir(ctx->xsh, XBT_NULL, path); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/disable_pf", path), "%d", !info->xen_platform_pci); - - libxl_create_logfile(ctx, libxl_sprintf(ctx, "qemu-dm-%s", info->dom_name), &logfile); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci); + + libxl_create_logfile(ctx, libxl_sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile); logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); free(logfile); null = open("/dev/null", O_RDONLY); if (starting_r) { rc = ERROR_NOMEM; - *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 1); - if (!*starting_r) goto xit; + *starting_r = calloc(sizeof(libxl_device_model_starting), 1); + if (!*starting_r) + goto out_close; p = *starting_r; - p->for_spawn = libxl_calloc(ctx, sizeof(libxl_spawn_starting), 1); + p->for_spawn = calloc(sizeof(libxl_spawn_starting), 1); } else { p = &buf_starting; p->for_spawn = NULL; } p->domid = info->domid; - p->dom_path = libxl_xs_get_dompath(ctx, info->domid); - if (!p->dom_path) { libxl_free(ctx, p); return ERROR_FAIL; } + p->dom_path = libxl_xs_get_dompath(&gc, info->domid); + if (!p->dom_path) { + rc = ERROR_FAIL; + goto out_close; + } if (info->vncpasswd) { - retry_transaction: +retry_transaction: /* Find uuid and the write the vnc password to xenstore for qemu. */ t = xs_transaction_start(ctx->xsh); - vm_path = libxl_xs_read(ctx,t,libxl_sprintf(ctx, "%s/vm", p->dom_path)); + vm_path = libxl_xs_read(&gc,t,libxl_sprintf(&gc, "%s/vm", p->dom_path)); if (vm_path) { /* Now write the vncpassword into it. */ - pass_stuff = libxl_calloc(ctx, 2, sizeof(char *)); + pass_stuff = libxl_calloc(&gc, 2, sizeof(char *)); pass_stuff[0] = "vncpasswd"; pass_stuff[1] = info->vncpasswd; - libxl_xs_writev(ctx,t,vm_path,pass_stuff); + libxl_xs_writev(&gc,t,vm_path,pass_stuff); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -1550,19 +1651,22 @@ int libxl_create_device_model(libxl_ctx } rc = libxl_spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid); - if (rc < 0) goto xit; + if (rc < 0) + goto out_close; if (!rc) { /* inner child */ libxl_exec(null, logfile_w, logfile_w, - libxl_abs_path(ctx, info->device_model, libxl_private_bindir_path()), + libxl_abs_path(&gc, info->device_model, libxl_private_bindir_path()), args); } rc = 0; - xit: - free(args); + +out_close: close(null); close(logfile_w); - + free(args); +out: + libxl_free_all(&gc); return rc; } @@ -1571,8 +1675,9 @@ int libxl_detach_device_model(libxl_ctx { int rc; rc = libxl_spawn_detach(ctx, starting->for_spawn); - if (starting->for_spawn) libxl_free(ctx, starting->for_spawn); - libxl_free(ctx, starting); + if (starting->for_spawn) + free(starting->for_spawn); + free(starting); return rc; } @@ -1591,29 +1696,30 @@ int libxl_confirm_device_model_startup(l /******************************************************************************/ -static char *get_blktap2_device(libxl_ctx *ctx, +static char *get_blktap2_device(libxl_gc *gc, const char *name, const char *type) { int minor = tap_ctl_find_minor(type, name); if (minor < 0) return NULL; - return libxl_sprintf(ctx, "/dev/xen/blktap-2/tapdev%d", minor); + return libxl_sprintf(gc, "/dev/xen/blktap-2/tapdev%d", minor); } -static char *make_blktap2_device(libxl_ctx *ctx, +static char *make_blktap2_device(libxl_gc *gc, const char *name, const char *type) { char *params, *devname = NULL; int err; - params = libxl_sprintf(ctx, "%s:%s", type, name); + params = libxl_sprintf(gc, "%s:%s", type, name); err = tap_ctl_create(params, &devname); if (!err) - libxl_ptr_add(ctx, devname); + libxl_ptr_add(gc, devname); return err ? NULL : devname; } int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; char *backend_type; @@ -1621,21 +1727,26 @@ int libxl_device_disk_add(libxl_ctx *ctx unsigned int foffset = 0; int devid; libxl_device device; - int major, minor; + int major, minor, rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) /* leaks front if error */ - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } backend_type = device_disk_backend_type_of_phystype(disk->phystype); devid = device_disk_dev_number(disk->virtpath); if (devid==-1) { XL_LOG(ctx, XL_LOG_ERROR, "Invalid or unsupported" " virtual disk identifier %s", disk->virtpath); - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out_free; } device.backend_devid = devid; @@ -1649,7 +1760,7 @@ int libxl_device_disk_add(libxl_ctx *ctx device_physdisk_major_minor(disk->physpath, &major, &minor); flexarray_set(back, boffset++, "physical-device"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, minor)); flexarray_set(back, boffset++, "params"); flexarray_set(back, boffset++, disk->physpath); @@ -1665,25 +1776,27 @@ int libxl_device_disk_add(libxl_ctx *ctx if (!tap_ctl_check(&msg)) { const char *type = device_disk_string_of_phystype(disk->phystype); char *dev; - dev = get_blktap2_device(ctx, disk->physpath, type); + dev = get_blktap2_device(&gc, disk->physpath, type); if (!dev) - dev = make_blktap2_device(ctx, disk->physpath, type); - if (!dev) - return ERROR_FAIL; + dev = make_blktap2_device(&gc, disk->physpath, type); + if (!dev) { + rc = ERROR_FAIL; + goto out_free; + } 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++, libxl_sprintf(&gc, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); flexarray_set(back, boffset++, "params"); - flexarray_set(back, boffset++, libxl_strdup(ctx, dev)); + flexarray_set(back, boffset++, libxl_strdup(&gc, dev)); backend_type = "phy"; device_physdisk_major_minor(dev, &major, &minor); flexarray_set(back, boffset++, "physical-device"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, minor)); device.backend_kind = DEVICE_VBD; break; } flexarray_set(back, boffset++, "params"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s", device_disk_string_of_phystype(disk->phystype), disk->physpath)); device.backend_kind = DEVICE_TAP; @@ -1691,19 +1804,20 @@ int libxl_device_disk_add(libxl_ctx *ctx } default: XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", disk->phystype); - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out_free; } flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", disk->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "removable"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", (disk->unpluggable) ? 1 : 0)); flexarray_set(back, boffset++, "bootable"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "dev"); flexarray_set(back, boffset++, disk->virtpath); flexarray_set(back, boffset++, "type"); @@ -1712,11 +1826,11 @@ int libxl_device_disk_add(libxl_ctx *ctx flexarray_set(back, boffset++, disk->readwrite ? "w" : "r"); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", disk->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(front, foffset++, "virtual-device"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", devid)); flexarray_set(front, foffset++, "device-type"); flexarray_set(front, foffset++, disk->is_cdrom ? "cdrom" : "disk"); @@ -1726,11 +1840,17 @@ int libxl_device_disk_add(libxl_ctx *ctx } libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + + rc = 0; + +out_free: flexarray_free(back); flexarray_free(front); - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_disk_del(libxl_ctx *ctx, @@ -1750,9 +1870,10 @@ int libxl_device_disk_del(libxl_ctx *ctx return libxl_device_del(ctx, &device, wait); } -const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) +char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) { - char *dev = NULL; + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *dev = NULL, *ret; int phystype = disk->phystype; switch (phystype) { case PHYSTYPE_PHY: { @@ -1767,9 +1888,9 @@ const char * libxl_device_disk_local_att const char *msg; if (!tap_ctl_check(&msg)) { const char *type = device_disk_string_of_phystype(phystype); - dev = get_blktap2_device(ctx, disk->physpath, type); + dev = get_blktap2_device(&gc, disk->physpath, type); if (!dev) - dev = make_blktap2_device(ctx, disk->physpath, type); + dev = make_blktap2_device(&gc, disk->physpath, type); } break; } @@ -1777,7 +1898,9 @@ const char * libxl_device_disk_local_att XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", phystype); break; } - return dev; + ret = strdup(dev); + libxl_free_all(&gc); + return ret; } int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk) @@ -1795,31 +1918,36 @@ int libxl_device_disk_local_detach(libxl /******************************************************************************/ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; char *dompath, **l; - unsigned int nb; + unsigned int nb, rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } if (nic->devid == -1) { - if (!(dompath = libxl_xs_get_dompath(ctx, domid))) { - return ERROR_FAIL; + if (!(dompath = libxl_xs_get_dompath(&gc, domid))) { + rc = ERROR_FAIL; + goto out_free; } - if (!(l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif", dompath), &nb))) { + if (!(l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif", dompath), &nb))) { nic->devid = 0; } else { nic->devid = strtoul(l[nb - 1], NULL, 10) + 1; - libxl_free(ctx, l); } } @@ -1831,30 +1959,30 @@ int libxl_device_nic_add(libxl_ctx *ctx, device.kind = DEVICE_VIF; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "script"); flexarray_set(back, boffset++, nic->script); flexarray_set(back, boffset++, "mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", nic->mac[0], nic->mac[1], nic->mac[2], nic->mac[3], nic->mac[4], nic->mac[5])); flexarray_set(back, boffset++, "bridge"); - flexarray_set(back, boffset++, libxl_strdup(ctx, nic->bridge)); + flexarray_set(back, boffset++, libxl_strdup(&gc, nic->bridge)); flexarray_set(back, boffset++, "handle"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->devid)); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(front, foffset++, "handle"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->devid)); flexarray_set(front, foffset++, "mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", nic->mac[0], nic->mac[1], nic->mac[2], nic->mac[3], nic->mac[4], nic->mac[5])); if (0 /* protocol != native*/) { @@ -1863,13 +1991,17 @@ int libxl_device_nic_add(libxl_ctx *ctx, } libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); /* FIXME: wait for plug */ + rc = 0; +out_free: flexarray_free(back); flexarray_free(front); - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_nic_del(libxl_ctx *ctx, @@ -1900,87 +2032,94 @@ void libxl_free_nics_list(libxl_nicinfo libxl_nicinfo *libxl_list_nics(libxl_ctx *ctx, uint32_t domid, unsigned int *nb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dompath, *nic_path_fe; char **l, **list; char *val, *tok; unsigned int nb_nics, i; libxl_nicinfo *res, *nics; - dompath = libxl_xs_get_dompath(ctx, domid); - if (!dompath) { - return NULL; - } - list = l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif", dompath), &nb_nics); - if (!l) { - return NULL; - } + dompath = libxl_xs_get_dompath(&gc, domid); + if (!dompath) + goto err; + list = l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif", dompath), &nb_nics); + if (!l) + goto err; nics = res = calloc(nb_nics, sizeof (libxl_device_nic)); - if (!res) { - libxl_free(ctx, l); - return NULL; - } + if (!res) + goto err; for (*nb = nb_nics; nb_nics > 0; --nb_nics, ++l, ++nics) { - nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, *l); + nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, *l); nics->backend = xs_read(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", nic_path_fe), NULL); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", nic_path_fe)); + libxl_sprintf(&gc, "%s/backend", nic_path_fe), NULL); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", nic_path_fe)); nics->backend_id = val ? strtoul(val, NULL, 10) : -1; nics->devid = strtoul(*l, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", nic_path_fe)); nics->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", nic_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { nics->mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/event-channel", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", nic_path_fe)); nics->evtch = val ? strtol(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/tx-ring-ref", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/tx-ring-ref", nic_path_fe)); nics->rref_tx = val ? strtol(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/rx-ring-ref", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/rx-ring-ref", nic_path_fe)); nics->rref_rx = val ? strtol(val, NULL, 10) : -1; nics->frontend = xs_read(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "%s/frontend", nics->backend), NULL); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", nics->backend)); + libxl_sprintf(&gc, "%s/frontend", nics->backend), NULL); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", nics->backend)); nics->frontend_id = val ? strtoul(val, NULL, 10) : -1; nics->script = xs_read(ctx->xsh, XBT_NULL, - libxl_sprintf(ctx, "%s/script", nics->backend), NULL); + libxl_sprintf(&gc, "%s/script", nics->backend), NULL); } + libxl_free_all(&gc); return res; +err: + libxl_free_all(&gc); + return NULL; } /******************************************************************************/ int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 *net2) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front, *back; unsigned int boffset = 0, foffset = 0; libxl_device device; char *dompath, *dom, **l; unsigned int nb; + int rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto err; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; - - if (!(dompath = libxl_xs_get_dompath(ctx, domid))) { - return ERROR_FAIL; + if (!back) { + rc = ERROR_NOMEM; + goto err_free; } - dom = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/name", dompath)); + + if (!(dompath = libxl_xs_get_dompath(&gc, domid))) { + rc = ERROR_FAIL; + goto err_free; + } + dom = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/name", dompath)); if (net2->devid == -1) { - if (!(l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif2", dompath), &nb))) { + if (!(l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif2", dompath), &nb))) { net2->devid = 0; } else { net2->devid = strtoul(l[nb - 1], NULL, 10) + 1; - libxl_free(ctx, l); } } @@ -1994,129 +2133,132 @@ int libxl_device_net2_add(libxl_ctx *ctx flexarray_set(back, boffset++, "domain"); flexarray_set(back, boffset++, dom); flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->domid)); flexarray_set(back, boffset++, "local-trusted"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->back_trusted)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->back_trusted)); flexarray_set(back, boffset++, "mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->back_mac[0], net2->back_mac[1], net2->back_mac[2], net2->back_mac[3], net2->back_mac[4], net2->back_mac[5])); flexarray_set(back, boffset++, "remote-trusted"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->trusted)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->trusted)); flexarray_set(back, boffset++, "remote-mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->front_mac[0], net2->front_mac[1], net2->front_mac[2], net2->front_mac[3], net2->front_mac[4], net2->front_mac[5])); flexarray_set(back, boffset++, "max-bypasses"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->max_bypasses)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->max_bypasses)); flexarray_set(back, boffset++, "filter-mac"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", !!(net2->filter_mac))); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", !!(net2->filter_mac))); flexarray_set(back, boffset++, "handle"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->devid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->devid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); flexarray_set(back, boffset++, "1"); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->backend_domid)); flexarray_set(front, foffset++, "local-trusted"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->trusted)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->trusted)); flexarray_set(front, foffset++, "mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->front_mac[0], net2->front_mac[1], net2->front_mac[2], net2->front_mac[3], net2->front_mac[4], net2->front_mac[5])); flexarray_set(front, foffset++, "remote-trusted"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->back_trusted)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->back_trusted)); flexarray_set(front, foffset++, "remote-mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x", net2->back_mac[0], net2->back_mac[1], net2->back_mac[2], net2->back_mac[3], net2->back_mac[4], net2->back_mac[5])); flexarray_set(front, foffset++, "filter-mac"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", !!(net2->filter_mac))); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", !!(net2->filter_mac))); flexarray_set(front, foffset++, "state"); flexarray_set(front, foffset++, "1"); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); /* FIXME: wait for plug */ + rc = 0; +err_free: flexarray_free(back); flexarray_free(front); - return 0; +err: + libxl_free_all(&gc); + return rc; } libxl_net2info *libxl_device_net2_list(libxl_ctx *ctx, uint32_t domid, unsigned int *nb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dompath, *net2_path_fe; char **l; char *val, *tok; unsigned int nb_net2s, i; libxl_net2info *res, *net2s; - dompath = libxl_xs_get_dompath(ctx, domid); - if (!dompath) { - return NULL; - } - l = libxl_xs_directory(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/device/vif2", dompath), &nb_net2s); - if (!l) { - return NULL; - } - res = libxl_calloc(ctx, nb_net2s, sizeof (libxl_net2info)); - if (!res) { - libxl_free(ctx, l); - return NULL; - } + dompath = libxl_xs_get_dompath(&gc, domid); + if (!dompath) + goto err; + l = libxl_xs_directory(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/device/vif2", dompath), &nb_net2s); + if (!l) + goto err; + res = calloc(nb_net2s, sizeof (libxl_net2info)); + if (!res) + goto err; net2s = res; for (*nb = nb_net2s; nb_net2s > 0; --nb_net2s, ++l, ++net2s) { - net2_path_fe = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, *l); - - net2s->backend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", net2_path_fe)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", net2_path_fe)); + net2_path_fe = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, *l); + + net2s->backend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/backend", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", net2_path_fe)); net2s->backend_id = val ? strtoul(val, NULL, 10) : -1; net2s->devid = strtoul(*l, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", net2_path_fe)); net2s->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", net2_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2s->mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-trusted", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-trusted", net2_path_fe)); net2s->trusted = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", net2_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2s->back_mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", net2_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", net2_path_fe)); net2s->filter_mac = val ? strtoul(val, NULL, 10) : -1; - net2s->frontend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/frontend", net2s->backend)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", net2s->backend)); + net2s->frontend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/frontend", net2s->backend)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", net2s->backend)); net2s->frontend_id = val ? strtoul(val, NULL, 10) : -1; - libxl_free(ctx, net2_path_fe); } - libxl_free(ctx, l); + libxl_free_all(&gc); return res; +err: + libxl_free_all(&gc); + return NULL; } int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait) @@ -2137,21 +2279,23 @@ int libxl_device_net2_del(libxl_ctx *ctx /******************************************************************************/ int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, libxl_device_console *console) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; + int rc; if (console->build_state) { xs_transaction_t t; - char **ents = (char **) libxl_calloc(ctx, 9, sizeof(char *)); + char **ents = (char **) libxl_calloc(&gc, 9, sizeof(char *)); ents[0] = "console/port"; - ents[1] = libxl_sprintf(ctx, "%"PRIu32, console->build_state->console_port); + ents[1] = libxl_sprintf(&gc, "%"PRIu32, console->build_state->console_port); ents[2] = "console/ring-ref"; - ents[3] = libxl_sprintf(ctx, "%lu", console->build_state->console_mfn); + ents[3] = libxl_sprintf(&gc, "%lu", console->build_state->console_mfn); ents[4] = "console/limit"; - ents[5] = libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT); + ents[5] = libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT); ents[6] = "console/type"; if (console->constype == CONSTYPE_XENCONSOLED) ents[7] = "xenconsoled"; @@ -2159,18 +2303,22 @@ int libxl_device_console_add(libxl_ctx * ents[7] = "ioemu"; retry_transaction: t = xs_transaction_start(ctx->xsh); - libxl_xs_writev(ctx, t, libxl_xs_get_dompath(ctx, console->domid), ents); + libxl_xs_writev(&gc, t, libxl_xs_get_dompath(&gc, console->domid), ents); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; } front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } device.backend_devid = console->devid; device.backend_domid = console->backend_domid; @@ -2180,22 +2328,22 @@ retry_transaction: device.kind = DEVICE_CONSOLE; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", console->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", console->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); flexarray_set(back, boffset++, "protocol"); flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", console->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", console->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(front, foffset++, "limit"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT)); flexarray_set(front, foffset++, "protocol"); flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL); flexarray_set(front, foffset++, "type"); @@ -2205,29 +2353,38 @@ retry_transaction: flexarray_set(front, foffset++, "ioemu"); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + rc = 0; +out_free: flexarray_free(back); flexarray_free(front); - - return 0; +out: + libxl_free_all(&gc); + return rc; } /******************************************************************************/ int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; + int rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } device.backend_devid = vkb->devid; device.backend_domid = vkb->backend_domid; @@ -2237,26 +2394,29 @@ int libxl_device_vkb_add(libxl_ctx *ctx, device.kind = DEVICE_VKBD; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vkb->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vkb->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vkb->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", vkb->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + rc = 0; +out_free: flexarray_free(back); flexarray_free(front); - - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_vkb_clean_shutdown(libxl_ctx *ctx, uint32_t domid) @@ -2271,16 +2431,17 @@ int libxl_device_vkb_hard_shutdown(libxl libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *be_path_tap, *be_path_vbd; libxl_device_disk *dend, *disks, *ret = NULL; char **b, **l = NULL; unsigned int numl; char *type; - be_path_vbd = libxl_sprintf(ctx, "%s/backend/vbd/%d", libxl_xs_get_dompath(ctx, 0), domid); - be_path_tap = libxl_sprintf(ctx, "%s/backend/tap/%d", libxl_xs_get_dompath(ctx, 0), domid); - - b = l = libxl_xs_directory(ctx, XBT_NULL, be_path_vbd, &numl); + be_path_vbd = libxl_sprintf(&gc, "%s/backend/vbd/%d", libxl_xs_get_dompath(&gc, 0), domid); + be_path_tap = libxl_sprintf(&gc, "%s/backend/tap/%d", libxl_xs_get_dompath(&gc, 0), domid); + + b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_vbd, &numl); if (l) { ret = realloc(ret, sizeof(libxl_device_disk) * numl); disks = ret; @@ -2289,20 +2450,19 @@ libxl_device_disk *libxl_device_disk_lis for (; disks < dend; ++disks, ++l) { disks->backend_domid = 0; disks->domid = domid; - disks->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/params", be_path_vbd, *l)); - libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype)); - disks->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/dev", be_path_vbd, *l)); - disks->unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/removable", be_path_vbd, *l))); - if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/mode", be_path_vbd, *l)), "w")) + disks->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/params", be_path_vbd, *l)); + libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype)); + disks->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/dev", be_path_vbd, *l)); + disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/removable", be_path_vbd, *l))); + if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/mode", be_path_vbd, *l)), "w")) disks->readwrite = 1; else disks->readwrite = 0; - type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/frontend", be_path_vbd, *l)))); + type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/frontend", be_path_vbd, *l)))); disks->is_cdrom = !strcmp(type, "cdrom"); } - libxl_free(ctx, b); } - b = l = libxl_xs_directory(ctx, XBT_NULL, be_path_tap, &numl); + b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_tap, &numl); if (l) { ret = realloc(ret, sizeof(libxl_device_disk) * (*num + numl)); disks = ret + *num; @@ -2310,51 +2470,54 @@ libxl_device_disk *libxl_device_disk_lis for (dend = ret + *num; disks < dend; ++disks, ++l) { disks->backend_domid = 0; disks->domid = domid; - disks->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/params", be_path_tap, *l)); - libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/type", be_path_tap, *l)), &(disks->phystype)); - disks->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/dev", be_path_tap, *l)); - disks->unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/removable", be_path_tap, *l))); - if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/mode", be_path_tap, *l)), "w")) + disks->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/params", be_path_tap, *l)); + libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/type", be_path_tap, *l)), &(disks->phystype)); + disks->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/dev", be_path_tap, *l)); + disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/removable", be_path_tap, *l))); + if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/mode", be_path_tap, *l)), "w")) disks->readwrite = 1; else disks->readwrite = 0; - type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/%s/frontend", be_path_tap, *l)))); + type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/%s/frontend", be_path_tap, *l)))); disks->is_cdrom = !strcmp(type, "cdrom"); } - libxl_free(ctx, b); } + libxl_free_all(&gc); return ret; } int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, libxl_diskinfo *diskinfo) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dompath, *diskpath; char *val; - dompath = libxl_xs_get_dompath(ctx, domid); + dompath = libxl_xs_get_dompath(&gc, domid); diskinfo->devid = device_disk_dev_number(disk->virtpath); /* tap devices entries in xenstore are written as vbd devices. */ - diskpath = libxl_sprintf(ctx, "%s/device/vbd/%d", dompath, diskinfo->devid); - diskinfo->backend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", diskpath)); + diskpath = libxl_sprintf(&gc, "%s/device/vbd/%d", dompath, diskinfo->devid); + diskinfo->backend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/backend", diskpath)); if (!diskinfo->backend) { + libxl_free_all(&gc); return ERROR_FAIL; } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", diskpath)); diskinfo->backend_id = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", diskpath)); diskinfo->state = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/event-channel", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", diskpath)); diskinfo->evtch = val ? strtoul(val, NULL, 10) : -1; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/ring-ref", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/ring-ref", diskpath)); diskinfo->rref = val ? strtoul(val, NULL, 10) : -1; - diskinfo->frontend = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/frontend", diskinfo->backend)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", diskinfo->backend)); + diskinfo->frontend = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/frontend", diskinfo->backend)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", diskinfo->backend)); diskinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + libxl_free_all(&gc); return 0; } @@ -2376,6 +2539,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u } if (i == num) { XL_LOG(ctx, XL_LOG_ERROR, "Virtual device not found"); + free(disks); return ERROR_FAIL; } libxl_device_disk_del(ctx, disks + i, 1); @@ -2388,28 +2552,30 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u libxl_device_disk_add(ctx, stubdomid, disk); disk->domid = domid; } + free(disks); return 0; } /******************************************************************************/ -static int libxl_build_xenpv_qemu_args(libxl_ctx *ctx, +static int libxl_build_xenpv_qemu_args(libxl_gc *gc, libxl_device_vfb *vfb, int num_console, libxl_device_console *console, libxl_device_model_info *info) { + libxl_ctx *ctx = libxl_gc_owner(gc); int i = 0, j = 0, num = 0; memset(info, 0x00, sizeof(libxl_device_model_info)); info->vnc = vfb->vnc; if (vfb->vnclisten) - info->vnclisten = libxl_strdup(ctx, vfb->vnclisten); + info->vnclisten = libxl_strdup(gc, vfb->vnclisten); info->vncdisplay = vfb->vncdisplay; info->vncunused = vfb->vncunused; if (vfb->vncpasswd) info->vncpasswd = vfb->vncpasswd; if (vfb->keymap) - info->keymap = libxl_strdup(ctx, vfb->keymap); + info->keymap = libxl_strdup(gc, vfb->keymap); info->sdl = vfb->sdl; info->opengl = vfb->opengl; for (i = 0; i < num_console; i++) { @@ -2420,9 +2586,9 @@ static int libxl_build_xenpv_qemu_args(l uint32_t guest_domid; if (libxl_is_stubdom(ctx, vfb->domid, &guest_domid)) { char *filename; - char *name = libxl_sprintf(ctx, "qemu-dm-%s", _libxl_domid_to_name(ctx, guest_domid)); + char *name = libxl_sprintf(gc, "qemu-dm-%s", _libxl_domid_to_name(gc, guest_domid)); libxl_create_logfile(ctx, name, &filename); - info->serial = libxl_sprintf(ctx, "file:%s", filename); + info->serial = libxl_sprintf(gc, "file:%s", filename); free(filename); } else { info->serial = "pty"; @@ -2430,7 +2596,7 @@ static int libxl_build_xenpv_qemu_args(l num--; } if (num > 0) { - info->extra = (char **) libxl_calloc(ctx, num * 2 + 1, sizeof(char *)); + info->extra = (char **) libxl_calloc(gc, num * 2 + 1, sizeof(char *)); for (j = 0; j < num * 2; j = j + 2) { info->extra[j] = "-serial"; info->extra[j + 1] = "pty"; @@ -2438,8 +2604,8 @@ static int libxl_build_xenpv_qemu_args(l info->extra[j] = NULL; } info->domid = vfb->domid; - info->dom_name = _libxl_domid_to_name(ctx, vfb->domid); - info->device_model = libxl_abs_path(ctx, "qemu-dm", libxl_libexec_path()); + info->dom_name = _libxl_domid_to_name(gc, vfb->domid); + info->device_model = libxl_abs_path(gc, "qemu-dm", libxl_libexec_path()); info->type = XENPV; return 0; } @@ -2448,27 +2614,35 @@ int libxl_create_xenpv_qemu(libxl_ctx *c int num_console, libxl_device_console *console, libxl_device_model_starting **starting_r) { + libxl_gc gc = LIBXL_INIT_GC(ctx); libxl_device_model_info info; - libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info); + libxl_build_xenpv_qemu_args(&gc, vfb, num_console, console, &info); libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); + libxl_free_all(&gc); return 0; } int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; unsigned int foffset = 0; libxl_device device; + int rc; front = flexarray_make(16, 1); - if (!front) - return ERROR_NOMEM; + if (!front) { + rc = ERROR_NOMEM; + goto out; + } back = flexarray_make(16, 1); - if (!back) - return ERROR_NOMEM; + if (!back) { + rc = ERROR_NOMEM; + goto out_free; + } device.backend_devid = vfb->devid; device.backend_domid = vfb->backend_domid; @@ -2478,27 +2652,27 @@ int libxl_device_vfb_add(libxl_ctx *ctx, device.kind = DEVICE_VFB; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->domid)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid)); flexarray_set(back, boffset++, "vnc"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vnc)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vnc)); flexarray_set(back, boffset++, "vnclisten"); flexarray_set(back, boffset++, vfb->vnclisten); flexarray_set(back, boffset++, "vncpasswd"); flexarray_set(back, boffset++, vfb->vncpasswd); flexarray_set(back, boffset++, "vncdisplay"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncdisplay)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncdisplay)); flexarray_set(back, boffset++, "vncunused"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncunused)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncunused)); flexarray_set(back, boffset++, "sdl"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->sdl)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->sdl)); flexarray_set(back, boffset++, "opengl"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->opengl)); + flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->opengl)); if (vfb->xauthority) { flexarray_set(back, boffset++, "xauthority"); flexarray_set(back, boffset++, vfb->xauthority); @@ -2509,17 +2683,20 @@ int libxl_device_vfb_add(libxl_ctx *ctx, } flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", vfb->backend_domid)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", vfb->backend_domid)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1)); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(&gc, back, boffset), + libxl_xs_kvs_of_flexarray(&gc, front, foffset)); + rc = 0; +out_free: flexarray_free(front); flexarray_free(back); - - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_device_vfb_clean_shutdown(libxl_ctx *ctx, uint32_t domid) @@ -2536,81 +2713,90 @@ int libxl_device_vfb_hard_shutdown(libxl int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *mem, *endptr; uint32_t memorykb; - char *dompath = libxl_xs_get_dompath(ctx, domid); - - mem = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", dompath)); + char *dompath = libxl_xs_get_dompath(&gc, domid); + int rc = 1; + + mem = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath)); if (!mem) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from %s/memory/target\n", dompath); - return 1; + goto out; } memorykb = strtoul(mem, &endptr, 10); if (*endptr != ''\0'') { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid memory %s from %s/memory/target\n", mem, dompath); - return 1; + goto out; } if (max_memkb < memorykb) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "memory_static_max must be greater than or or equal to memory_dynamic_max\n"); - return 1; + goto out; } if (domid != 0) - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb); - - return 0; + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath), "%"PRIu32, max_memkb); + + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb, int enforce) { - int rc = 0; + libxl_gc gc = LIBXL_INIT_GC(ctx); + int rc = 1; uint32_t memorykb = 0, videoram = 0; char *memmax, *endptr, *videoram_s = NULL; - char *dompath = libxl_xs_get_dompath(ctx, domid); + char *dompath = libxl_xs_get_dompath(&gc, domid); xc_domaininfo_t info; libxl_dominfo ptr; char *uuid; if (domid) { - memmax = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/static-max", dompath)); + memmax = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/static-max", dompath)); if (!memmax) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from %s/memory/static-max\n", dompath); - return 1; + goto out; } memorykb = strtoul(memmax, &endptr, 10); if (*endptr != ''\0'') { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid max memory %s from %s/memory/static-max\n", memmax, dompath); - return 1; + goto out; } if (target_memkb > memorykb) { XL_LOG(ctx, XL_LOG_ERROR, "memory_dynamic_max must be less than or equal to memory_static_max\n"); - return 1; + goto out; } } - videoram_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/videoram", dompath)); + videoram_s = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/videoram", dompath)); videoram = videoram_s ? atoi(videoram_s) : 0; - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", dompath), "%"PRIu32, target_memkb); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", dompath), "%"PRIu32, target_memkb); rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info); if (rc != 1 || info.domain != domid) - return rc; + goto out; xcinfo2xlinfo(&info, &ptr); uuid = libxl_uuid2string(ctx, ptr.uuid); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/vm/%s/memory", uuid), "%"PRIu32, target_memkb / 1024); if (enforce || !domid) memorykb = target_memkb; rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + LIBXL_MAXMEM_CONSTANT); if (rc != 0) - return rc; + goto out; rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - videoram) / 4, NULL, NULL, NULL); + +out: + libxl_free_all(&gc); return rc; } @@ -2784,26 +2970,31 @@ int libxl_set_vcpuaffinity(libxl_ctx *ct int libxl_set_vcpucount(libxl_ctx *ctx, uint32_t domid, uint32_t count) { + libxl_gc gc = LIBXL_INIT_GC(ctx); xc_domaininfo_t domaininfo; char *dompath; - int i; + int i, rc = ERROR_FAIL; if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting domain info list"); - return ERROR_FAIL; + goto out; } if (!count || ((domaininfo.max_vcpu_id + 1) < count)) { - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out; } - if (!(dompath = libxl_xs_get_dompath(ctx, domid))) - return ERROR_FAIL; + if (!(dompath = libxl_xs_get_dompath(&gc, domid))) + goto out; for (i = 0; i <= domaininfo.max_vcpu_id; ++i) { - libxl_xs_write(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/cpu/%u/availability", dompath, i), + libxl_xs_write(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/cpu/%u/availability", dompath, i), "%s", ((1 << i) & ((1 << count) - 1)) ? "online" : "offline"); } - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } /* @@ -2916,10 +3107,12 @@ int libxl_send_trigger(libxl_ctx *ctx, u int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq) { - char *dompath = libxl_xs_get_dompath(ctx, domid); - - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/control/sysrq", dompath), "%c", sysrq); - + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *dompath = libxl_xs_get_dompath(&gc, domid); + + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/control/sysrq", dompath), "%c", sysrq); + + libxl_free_all(&gc); return 0; } @@ -3006,20 +3199,24 @@ void libxl_xen_console_read_finish(libxl uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid) { - char *dompath = libxl_xs_get_dompath(ctx, domid); + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *dompath = libxl_xs_get_dompath(&gc, domid); char *vm_path, *start_time; + uint32_t ret; vm_path = libxl_xs_read( - ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dompath)); + &gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dompath)); start_time = libxl_xs_read( - ctx, XBT_NULL, libxl_sprintf(ctx, "%s/start_time", vm_path)); + &gc, XBT_NULL, libxl_sprintf(&gc, "%s/start_time", vm_path)); if (start_time == NULL) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1, "Can''t get start time of domain ''%d''", domid); - return -1; + ret = -1; + }else{ + ret = strtoul(start_time, NULL, 10); } - - return strtoul(start_time, NULL, 10); + libxl_free_all(&gc); + return ret; } char *libxl_tmem_list(libxl_ctx *ctx, uint32_t domid, int use_long) diff -r 7b144fe8c528 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl.h Thu Aug 12 15:22:56 2010 +0100 @@ -78,10 +78,6 @@ typedef struct { xc_interface *xch; struct xs_handle *xsh; - /* mini-GC */ - int alloc_maxsize; - void **alloc_ptrs; - /* for callers who reap children willy-nilly; caller must only * set this after libxl_init and before any other call - or * may leave them untouched */ @@ -491,7 +487,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u /* * Make a disk available in this domain. Returns path to a device. */ -const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); +char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk); typedef struct { diff -r 7b144fe8c528 tools/libxl/libxl_bootloader.c --- a/tools/libxl/libxl_bootloader.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_bootloader.c Thu Aug 12 15:22:56 2010 +0100 @@ -30,7 +30,7 @@ #define XENCONSOLED_BUF_SIZE 16 #define BOOTLOADER_BUF_SIZE 1024 -static char **make_bootloader_args(libxl_ctx *ctx, +static char **make_bootloader_args(libxl_gc *gc, libxl_domain_build_info *info, uint32_t domid, const char *fifo, const char *disk) @@ -45,20 +45,20 @@ static char **make_bootloader_args(libxl flexarray_set(args, nr++, (char *)info->u.pv.bootloader); if (info->kernel.path) - flexarray_set(args, nr++, libxl_sprintf(ctx, "--kernel=%s", info->kernel.path)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--kernel=%s", info->kernel.path)); if (info->u.pv.ramdisk.path) - flexarray_set(args, nr++, libxl_sprintf(ctx, "--ramdisk=%s", info->u.pv.ramdisk.path)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--ramdisk=%s", info->u.pv.ramdisk.path)); if (info->u.pv.cmdline && *info->u.pv.cmdline != ''\0'') - flexarray_set(args, nr++, libxl_sprintf(ctx, "--args=%s", info->u.pv.cmdline)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--args=%s", info->u.pv.cmdline)); - flexarray_set(args, nr++, libxl_sprintf(ctx, "--output=%s", fifo)); + flexarray_set(args, nr++, libxl_sprintf(gc, "--output=%s", fifo)); flexarray_set(args, nr++, "--output-format=simple0"); - flexarray_set(args, nr++, libxl_sprintf(ctx, "--output-directory=%s", "/var/run/libxl/")); + flexarray_set(args, nr++, libxl_sprintf(gc, "--output-directory=%s", "/var/run/libxl/")); if (info->u.pv.bootloader_args) { char *saveptr; /* Operate on a duplicate since strtok modifes the argument */ - char *dup = libxl_strdup(ctx, info->u.pv.bootloader_args); + char *dup = libxl_strdup(gc, info->u.pv.bootloader_args); char *t = strtok_r(dup, " \t\n", &saveptr); do { flexarray_set(args, nr++, t); @@ -161,7 +161,7 @@ static pid_t fork_exec_bootloader(int *m * if there is actual data to write, otherwise this would loop too fast, * eating up CPU time. */ -static char * bootloader_interact(libxl_ctx *ctx, int xenconsoled_fd, int bootloader_fd, int fifo_fd) +static char * bootloader_interact(libxl_gc *gc, int xenconsoled_fd, int bootloader_fd, int fifo_fd) { int ret; @@ -263,7 +263,7 @@ static char * bootloader_interact(libxl_ } } - libxl_ptr_add(ctx, output); + libxl_ptr_add(gc, output); return output; out_err: @@ -300,8 +300,8 @@ int libxl_run_bootloader(libxl_ctx *ctx, libxl_device_disk *disk, uint32_t domid) { - int ret; - + libxl_gc gc = LIBXL_INIT_GC(ctx); + int ret, rc = 0; char *fifo = NULL; const char *diskpath = NULL; char **args = NULL; @@ -322,49 +322,48 @@ int libxl_run_bootloader(libxl_ctx *ctx, struct stat st_buf; if (info->hvm || !info->u.pv.bootloader) - return 0; + goto out; + rc = ERROR_INVAL; if (!disk) - return ERROR_INVAL; + goto out; + rc = ERROR_FAIL; ret = mkdir("/var/run/libxl/", S_IRWXU); if (ret < 0 && errno != EEXIST) - return ERROR_FAIL; + goto out; ret = stat("/var/run/libxl/", &st_buf); if (ret < 0) - return ERROR_FAIL; + goto out; if (!S_ISDIR(st_buf.st_mode)) - return ERROR_FAIL; + goto out; tempdir = mkdtemp(tempdir_template); if (tempdir == NULL) - return ERROR_FAIL; + goto out; ret = asprintf(&fifo, "%s/fifo", tempdir); if (ret < 0) { - ret = ERROR_FAIL; fifo = NULL; - goto out; + goto out_close; } ret = mkfifo(fifo, 0600); if (ret < 0) { - ret = ERROR_FAIL; - goto out; + goto out_close; } diskpath = libxl_device_disk_local_attach(ctx, disk); if (!diskpath) { - ret = ERROR_FAIL; - goto out; + goto out_close; } - args = make_bootloader_args(ctx, info, domid, fifo, diskpath); + args = make_bootloader_args(&gc, info, domid, fifo, diskpath); if (args == NULL) { - ret = ERROR_NOMEM; - goto out; + rc = ERROR_NOMEM; + goto out_close; } /* @@ -381,17 +380,15 @@ int libxl_run_bootloader(libxl_ctx *ctx, &dom_console_slave_tty_path[0], sizeof(dom_console_slave_tty_path)); if (ret < 0) { - ret = ERROR_FAIL; - goto out; + goto out_close; } - dom_console_xs_path = libxl_sprintf(ctx, "%s/serial/0/tty", libxl_xs_get_dompath(ctx, domid)); - libxl_xs_write(ctx, XBT_NULL, dom_console_xs_path, "%s", dom_console_slave_tty_path); + dom_console_xs_path = libxl_sprintf(&gc, "%s/serial/0/tty", libxl_xs_get_dompath(&gc, domid)); + libxl_xs_write(&gc, XBT_NULL, dom_console_xs_path, "%s", dom_console_slave_tty_path); pid = fork_exec_bootloader(&bootloader_fd, (char *)info->u.pv.bootloader, args); if (pid < 0) { - ret = ERROR_FAIL; - goto out; + goto out_close; } while (1) { @@ -402,30 +399,27 @@ int libxl_run_bootloader(libxl_ctx *ctx, if (errno == EINTR) continue; - ret = ERROR_FAIL; - goto out; + goto out_close; } fcntl(fifo_fd, F_SETFL, O_NDELAY); - blout = bootloader_interact(ctx, xenconsoled_fd, bootloader_fd, fifo_fd); + blout = bootloader_interact(&gc, xenconsoled_fd, bootloader_fd, fifo_fd); if (blout == NULL) { - ret = ERROR_FAIL; - goto out; + goto out_close; } pid = waitpid(pid, &blrc, 0); if (pid == -1 || (pid > 0 && WIFEXITED(blrc) && WEXITSTATUS(blrc) != 0)) { - ret = ERROR_FAIL; - goto out; + goto out_close; } libxl_device_disk_local_detach(ctx, disk); parse_bootloader_result(ctx, info, blout); - ret = 0; -out: + rc = 0; +out_close: if (fifo_fd > -1) close(fifo_fd); if (bootloader_fd > -1) @@ -444,6 +438,8 @@ out: free(args); - return ret; +out: + libxl_free_all(&gc); + return rc; } diff -r 7b144fe8c528 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_device.c Thu Aug 12 15:22:56 2010 +0100 @@ -42,20 +42,24 @@ static const char *string_of_kinds[] = { int libxl_device_generic_add(libxl_ctx *ctx, libxl_device *device, char **bents, char **fents) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path_backend, *dom_path, *frontend_path, *backend_path; xs_transaction_t t; struct xs_permissions frontend_perms[2]; struct xs_permissions backend_perms[2]; + int rc; - if (!is_valid_device_kind(device->backend_kind) || !is_valid_device_kind(device->kind)) - return ERROR_INVAL; + if (!is_valid_device_kind(device->backend_kind) || !is_valid_device_kind(device->kind)) { + rc = ERROR_INVAL; + goto out; + } - dom_path_backend = libxl_xs_get_dompath(ctx, device->backend_domid); - dom_path = libxl_xs_get_dompath(ctx, device->domid); + dom_path_backend = libxl_xs_get_dompath(&gc, device->backend_domid); + dom_path = libxl_xs_get_dompath(&gc, device->domid); - frontend_path = libxl_sprintf(ctx, "%s/device/%s/%d", + frontend_path = libxl_sprintf(&gc, "%s/device/%s/%d", dom_path, string_of_kinds[device->kind], device->devid); - backend_path = libxl_sprintf(ctx, "%s/backend/%s/%u/%d", + backend_path = libxl_sprintf(&gc, "%s/backend/%s/%u/%d", dom_path_backend, string_of_kinds[device->backend_kind], device->domid, device->devid); frontend_perms[0].id = device->domid; @@ -81,12 +85,12 @@ retry_transaction: xs_mkdir(ctx->xsh, t, backend_path); xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, ARRAY_SIZE(backend_perms)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/backend", frontend_path), backend_path, strlen(backend_path)); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/frontend", backend_path), frontend_path, strlen(frontend_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/backend", frontend_path), backend_path, strlen(backend_path)); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/frontend", backend_path), frontend_path, strlen(frontend_path)); /* and write frontend kvs and backend kvs */ - libxl_xs_writev(ctx, t, backend_path, bents); - libxl_xs_writev(ctx, t, frontend_path, fents); + libxl_xs_writev(&gc, t, backend_path, bents); + libxl_xs_writev(&gc, t, frontend_path, fents); if (!xs_transaction_end(ctx->xsh, t, 0)) { if (errno == EAGAIN) @@ -94,7 +98,10 @@ retry_transaction: else XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs transaction failed"); } - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } char *device_disk_string_of_phystype(libxl_disk_phystype phystype) @@ -221,35 +228,43 @@ int device_disk_dev_number(char *virtpat int libxl_device_destroy(libxl_ctx *ctx, char *be_path, int force) { + libxl_gc gc = LIBXL_INIT_GC(ctx); xs_transaction_t t; - char *state_path = libxl_sprintf(ctx, "%s/state", be_path); - char *state = libxl_xs_read(ctx, XBT_NULL, state_path); + char *state_path = libxl_sprintf(&gc, "%s/state", be_path); + char *state = libxl_xs_read(&gc, XBT_NULL, state_path); + int rc = 0; + if (!state) - return 0; + goto out; if (atoi(state) != 4) { xs_rm(ctx->xsh, XBT_NULL, be_path); - return 0; + goto out; } retry_transaction: t = xs_transaction_start(ctx->xsh); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/online", be_path), "0", strlen("0")); + xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/online", be_path), "0", strlen("0")); xs_write(ctx->xsh, t, state_path, "5", strlen("5")); if (!xs_transaction_end(ctx->xsh, t, 0)) { if (errno == EAGAIN) goto retry_transaction; - else - return -1; + else { + rc = -1; + goto out; + } } if (!force) { xs_watch(ctx->xsh, state_path, be_path); - return 1; - } else - return 0; + rc = 1; + } +out: + libxl_free_all(&gc); + return rc; } int wait_for_dev_destroy(libxl_ctx *ctx, struct timeval *tv) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int nfds, rc; unsigned int n; fd_set rfds; @@ -262,57 +277,52 @@ int wait_for_dev_destroy(libxl_ctx *ctx, if (select(nfds, &rfds, NULL, NULL, tv) > 0) { l1 = xs_read_watch(ctx->xsh, &n); if (l1 != NULL) { - char *state = libxl_xs_read(ctx, XBT_NULL, l1[XS_WATCH_PATH]); + char *state = libxl_xs_read(&gc, XBT_NULL, l1[XS_WATCH_PATH]); if (!state || atoi(state) == 6) { xs_unwatch(ctx->xsh, l1[0], l1[1]); xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]); XL_LOG(ctx, XL_LOG_DEBUG, "Destroyed device backend at %s", l1[XS_WATCH_TOKEN]); rc = 0; } - libxl_free(ctx, state); free(l1); } } + libxl_free_all(&gc); return rc; } int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path, *be_path, *fe_path; unsigned int num1, num2; char **l1 = NULL, **l2 = NULL; int i, j, n = 0, n_watches = 0; flexarray_t *toremove; - libxl_ctx clone; - - if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) { - return -1; - } toremove = flexarray_make(16, 1); - path = libxl_sprintf(&clone, "/local/domain/%d/device", domid); - l1 = libxl_xs_directory(&clone, XBT_NULL, path, &num1); + path = libxl_sprintf(&gc, "/local/domain/%d/device", domid); + l1 = libxl_xs_directory(&gc, XBT_NULL, path, &num1); if (!l1) { - XL_LOG(&clone, XL_LOG_ERROR, "%s is empty", path); - libxl_ctx_free(&clone); - return 0; + XL_LOG(ctx, XL_LOG_ERROR, "%s is empty", path); + goto out; } for (i = 0; i < num1; i++) { if (!strcmp("vfs", l1[i])) continue; - path = libxl_sprintf(&clone, "/local/domain/%d/device/%s", domid, l1[i]); - l2 = libxl_xs_directory(&clone, XBT_NULL, path, &num2); + path = libxl_sprintf(&gc, "/local/domain/%d/device/%s", domid, l1[i]); + l2 = libxl_xs_directory(&gc, XBT_NULL, path, &num2); if (!l2) continue; for (j = 0; j < num2; j++) { - fe_path = libxl_sprintf(&clone, "/local/domain/%d/device/%s/%s", domid, l1[i], l2[j]); - be_path = libxl_xs_read(&clone, XBT_NULL, libxl_sprintf(&clone, "%s/backend", fe_path)); + fe_path = libxl_sprintf(&gc, "/local/domain/%d/device/%s/%s", domid, l1[i], l2[j]); + be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", fe_path)); if (be_path != NULL) { - if (libxl_device_destroy(&clone, be_path, force) > 0) + if (libxl_device_destroy(ctx, be_path, force) > 0) n_watches++; - flexarray_set(toremove, n++, libxl_dirname(&clone, be_path)); + flexarray_set(toremove, n++, libxl_dirname(&gc, be_path)); } else { - xs_rm(clone.xsh, XBT_NULL, path); + xs_rm(ctx->xsh, XBT_NULL, path); } } } @@ -326,7 +336,7 @@ int libxl_devices_destroy(libxl_ctx *ctx tv.tv_sec = LIBXL_DESTROY_TIMEOUT; tv.tv_usec = 0; while (n_watches > 0) { - if (wait_for_dev_destroy(&clone, &tv)) { + if (wait_for_dev_destroy(ctx, &tv)) { break; } else { n_watches--; @@ -335,46 +345,44 @@ int libxl_devices_destroy(libxl_ctx *ctx } for (i = 0; i < n; i++) { flexarray_get(toremove, i, (void**) &path); - xs_rm(clone.xsh, XBT_NULL, path); + xs_rm(ctx->xsh, XBT_NULL, path); } +out: flexarray_free(toremove); - libxl_ctx_free(&clone); + libxl_free_all(&gc); return 0; } int libxl_device_del(libxl_ctx *ctx, libxl_device *dev, int wait) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path_backend, *backend_path; int rc; - libxl_ctx clone; - - if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) { - return -1; - } /* Create strings */ - dom_path_backend = libxl_xs_get_dompath(&clone, dev->backend_domid); - backend_path = libxl_sprintf(&clone, "%s/backend/%s/%u/%d", + dom_path_backend = libxl_xs_get_dompath(&gc, dev->backend_domid); + backend_path = libxl_sprintf(&gc, "%s/backend/%s/%u/%d", dom_path_backend, string_of_kinds[dev->backend_kind], dev->domid, dev->devid); - libxl_free(&clone, dom_path_backend); - - rc = libxl_device_destroy(&clone, backend_path, !wait); + rc = libxl_device_destroy(ctx, backend_path, !wait); if (rc == -1) { - libxl_ctx_free(&clone); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } if (wait) { struct timeval tv; tv.tv_sec = LIBXL_DESTROY_TIMEOUT; tv.tv_usec = 0; - (void)wait_for_dev_destroy(&clone, &tv); + (void)wait_for_dev_destroy(ctx, &tv); } - libxl_ctx_free(&clone); - return 0; + rc = 0; + +out: + libxl_free_all(&gc); + return rc; } int libxl_wait_for_device_model(libxl_ctx *ctx, @@ -385,6 +393,7 @@ int libxl_wait_for_device_model(libxl_ct void *userdata), void *check_callback_userdata) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *path; char *p; unsigned int len; @@ -397,7 +406,7 @@ int libxl_wait_for_device_model(libxl_ct char **l = NULL; xsh = xs_daemon_open(); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d/state", domid); xs_watch(xsh, path, path); tv.tv_sec = LIBXL_DEVICE_MODEL_START_TIMEOUT; tv.tv_usec = 0; @@ -419,6 +428,7 @@ int libxl_wait_for_device_model(libxl_ct free(p); xs_unwatch(xsh, path, path); xs_daemon_close(xsh); + libxl_free_all(&gc); return rc; again: free(p); @@ -436,15 +446,17 @@ again: xs_unwatch(xsh, path, path); xs_daemon_close(xsh); XL_LOG(ctx, XL_LOG_ERROR, "Device Model not ready"); + libxl_free_all(&gc); return -1; } int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int watchdog = 100; unsigned int len; char *p; - char *path = libxl_sprintf(ctx, "%s/state", be_path); + char *path = libxl_sprintf(&gc, "%s/state", be_path); while (watchdog > 0) { p = xs_read(ctx->xsh, XBT_NULL, path, &len); @@ -467,6 +479,7 @@ int libxl_wait_for_backend(libxl_ctx *ct } } XL_LOG(ctx, XL_LOG_ERROR, "Backend %s not ready", be_path); + libxl_free_all(&gc); return -1; } diff -r 7b144fe8c528 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_dom.c Thu Aug 12 15:22:56 2010 +0100 @@ -86,6 +86,7 @@ int build_post(libxl_ctx *ctx, uint32_t libxl_domain_build_info *info, libxl_domain_build_state *state, char **vms_ents, char **local_ents) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *dom_path, *vm_path; xs_transaction_t t; char **ents; @@ -95,44 +96,43 @@ int build_post(libxl_ctx *ctx, uint32_t xc_cpuid_apply_policy(ctx->xch, domid); #endif - ents = libxl_calloc(ctx, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); + ents = libxl_calloc(&gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; - ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb); + ents[1] = libxl_sprintf(&gc, "%d", info->max_memkb); ents[2] = "memory/target"; - ents[3] = libxl_sprintf(ctx, "%d", info->target_memkb); + ents[3] = libxl_sprintf(&gc, "%d", info->target_memkb); ents[4] = "memory/videoram"; - ents[5] = libxl_sprintf(ctx, "%d", info->video_memkb); + ents[5] = libxl_sprintf(&gc, "%d", info->video_memkb); ents[6] = "domid"; - ents[7] = libxl_sprintf(ctx, "%d", domid); + ents[7] = libxl_sprintf(&gc, "%d", domid); ents[8] = "store/port"; - ents[9] = libxl_sprintf(ctx, "%"PRIu32, state->store_port); + ents[9] = libxl_sprintf(&gc, "%"PRIu32, state->store_port); ents[10] = "store/ring-ref"; - ents[11] = libxl_sprintf(ctx, "%lu", state->store_mfn); + ents[11] = libxl_sprintf(&gc, "%lu", state->store_mfn); for (i = 0; i < info->max_vcpus; i++) { - ents[12+(i*2)] = libxl_sprintf(ctx, "cpu/%d/availability", i); + ents[12+(i*2)] = libxl_sprintf(&gc, "cpu/%d/availability", i); ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) ? "offline" : "online"; } - dom_path = libxl_xs_get_dompath(ctx, domid); + dom_path = libxl_xs_get_dompath(&gc, domid); if (!dom_path) return ERROR_FAIL; - vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dom_path), NULL); + vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dom_path), NULL); retry_transaction: t = xs_transaction_start(ctx->xsh); - libxl_xs_writev(ctx, t, dom_path, ents); - libxl_xs_writev(ctx, t, dom_path, local_ents); - libxl_xs_writev(ctx, t, vm_path, vms_ents); + libxl_xs_writev(&gc, t, dom_path, ents); + libxl_xs_writev(&gc, t, dom_path, local_ents); + libxl_xs_writev(&gc, t, vm_path, vms_ents); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port); free(vm_path); - libxl_free(ctx, ents); - libxl_free(ctx, dom_path); + libxl_free_all(&gc); return 0; } @@ -218,30 +218,35 @@ out: int build_hvm(libxl_ctx *ctx, uint32_t domid, libxl_domain_build_info *info, libxl_domain_build_state *state) { - int ret; + libxl_gc gc = LIBXL_INIT_GC(ctx); + int ret, rc = ERROR_INVAL; if (info->kernel.mapped) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "build_hvm kernel cannot be mmapped"); - return ERROR_INVAL; + goto out; } + rc = ERROR_FAIL; ret = xc_hvm_build_target_mem( ctx->xch, domid, (info->max_memkb - info->video_memkb) / 1024, (info->target_memkb - info->video_memkb) / 1024, - libxl_abs_path(ctx, (char *)info->kernel.path, + libxl_abs_path(&gc, (char *)info->kernel.path, libxl_xenfirmwaredir_path())); if (ret) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm building failed"); - return ERROR_FAIL; + goto out; } ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port, &state->store_mfn, state->console_port, &state->console_mfn); if (ret) { XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm build set params failed"); - return ERROR_FAIL; + goto out; } + rc = 0; +out: + libxl_free_all(&gc); return 0; } @@ -263,7 +268,7 @@ int restore_common(libxl_ctx *ctx, uint3 } struct suspendinfo { - libxl_ctx *ctx; + libxl_gc *gc; int xce; /* event channel handle */ int suspend_eventchn; int domid; @@ -295,39 +300,40 @@ static int core_suspend_callback(void *d int ret; char *path, *state = "suspend"; int watchdog = 60; + libxl_ctx *ctx = libxl_gc_owner(si->gc); if (si->hvm) - xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &s_state); + xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &s_state); if ((s_state == 0) && (si->suspend_eventchn >= 0)) { ret = xc_evtchn_notify(si->xce, si->suspend_eventchn); if (ret < 0) { - XL_LOG(si->ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", ret); + XL_LOG(ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", ret); return 0; } - ret = xc_await_suspend(si->ctx->xch, si->xce, si->suspend_eventchn); + ret = xc_await_suspend(ctx->xch, si->xce, si->suspend_eventchn); if (ret < 0) { - XL_LOG(si->ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", ret); + XL_LOG(ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", ret); return 0; } return 1; } - path = libxl_sprintf(si->ctx, "%s/control/shutdown", libxl_xs_get_dompath(si->ctx, si->domid)); - libxl_xs_write(si->ctx, XBT_NULL, path, "suspend"); + path = libxl_sprintf(si->gc, "%s/control/shutdown", libxl_xs_get_dompath(si->gc, si->domid)); + libxl_xs_write(si->gc, XBT_NULL, path, "suspend"); if (si->hvm) { unsigned long hvm_pvdrv, hvm_s_state; - xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, &hvm_pvdrv); - xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &hvm_s_state); + xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, &hvm_pvdrv); + xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, &hvm_s_state); if (!hvm_pvdrv || hvm_s_state) { - XL_LOG(si->ctx, XL_LOG_DEBUG, "Calling xc_domain_shutdown on the domain"); - xc_domain_shutdown(si->ctx->xch, si->domid, SHUTDOWN_suspend); + XL_LOG(ctx, XL_LOG_DEBUG, "Calling xc_domain_shutdown on the domain"); + xc_domain_shutdown(ctx->xch, si->domid, SHUTDOWN_suspend); } } - XL_LOG(si->ctx, XL_LOG_DEBUG, "wait for the guest to suspend"); + XL_LOG(ctx, XL_LOG_DEBUG, "wait for the guest to suspend"); while (!strcmp(state, "suspend") && watchdog > 0) { xc_domaininfo_t info; usleep(100000); - ret = xc_domain_getinfolist(si->ctx->xch, si->domid, 1, &info); + ret = xc_domain_getinfolist(ctx->xch, si->domid, 1, &info); if (ret == 1 && info.domain == si->domid && info.flags & XEN_DOMINF_shutdown) { int shutdown_reason; @@ -335,12 +341,12 @@ static int core_suspend_callback(void *d if (shutdown_reason == SHUTDOWN_suspend) return 1; } - state = libxl_xs_read(si->ctx, XBT_NULL, path); + state = libxl_xs_read(si->gc, XBT_NULL, path); watchdog--; } if (!strcmp(state, "suspend")) { - XL_LOG(si->ctx, XL_LOG_ERROR, "guest didn''t suspend in time"); - libxl_xs_write(si->ctx, XBT_NULL, path, ""); + XL_LOG(ctx, XL_LOG_ERROR, "guest didn''t suspend in time"); + libxl_xs_write(si->gc, XBT_NULL, path, ""); } return 1; } @@ -348,10 +354,12 @@ static int core_suspend_callback(void *d int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, int debug) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int flags; int port; struct save_callbacks callbacks; struct suspendinfo si; + int rc = ERROR_FAIL; flags = (live) ? XCFLAGS_LIVE : 0 | (debug) ? XCFLAGS_DEBUG : 0 @@ -360,12 +368,12 @@ int core_suspend(libxl_ctx *ctx, uint32_ si.domid = domid; si.flags = flags; si.hvm = hvm; - si.ctx = ctx; + si.gc = &gc; si.suspend_eventchn = -1; si.xce = xc_evtchn_open(); if (si.xce < 0) - return ERROR_FAIL; + goto out; if (si.xce > 0) { port = xs_suspend_evtchn_port(si.domid); @@ -373,7 +381,7 @@ int core_suspend(libxl_ctx *ctx, uint32_ if (port < 0) { XL_LOG(ctx, XL_LOG_WARNING, "Failed to get the suspend evtchn port"); } else { - si.suspend_eventchn = xc_suspend_evtchn_init(si.ctx->xch, si.xce, si.domid, port); + si.suspend_eventchn = xc_suspend_evtchn_init(ctx->xch, si.xce, si.domid, port); if (si.suspend_eventchn < 0) XL_LOG(ctx, XL_LOG_WARNING, "Suspend event channel initialization failed"); @@ -389,21 +397,24 @@ int core_suspend(libxl_ctx *ctx, uint32_ &core_suspend_switch_qemu_logdirty); if (si.suspend_eventchn > 0) - xc_suspend_evtchn_release(si.ctx->xch, si.xce, domid, si.suspend_eventchn); + xc_suspend_evtchn_release(ctx->xch, si.xce, domid, si.suspend_eventchn); if (si.xce > 0) xc_evtchn_close(si.xce); - return 0; + rc = 0; +out: + return rc; } int save_device_model(libxl_ctx *ctx, uint32_t domid, int fd) { + libxl_gc gc = LIBXL_INIT_GC(ctx); int fd2, c; char buf[1024]; - char *filename = libxl_sprintf(ctx, "/var/lib/xen/qemu-save.%d", domid); + char *filename = libxl_sprintf(&gc, "/var/lib/xen/qemu-save.%d", domid); XL_LOG(ctx, XL_LOG_DEBUG, "Saving device model state to %s", filename); - libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid), "save"); + libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "save"); libxl_wait_for_device_model(ctx, domid, "paused", NULL, NULL); c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE), @@ -415,27 +426,42 @@ int save_device_model(libxl_ctx *ctx, ui if (c < 0) { if (errno == EINTR) continue; + libxl_free_all(&gc); return errno; } c = libxl_write_exactly( ctx, fd, buf, c, "saved-state file", "qemu state"); - if (c) + if (c) { + libxl_free_all(&gc); return c; + } } close(fd2); unlink(filename); + libxl_free_all(&gc); return 0; } -char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) { - char *s = string_of_uuid(ctx, uuid); - if (!s) XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid"); - return s; +char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); + char *s = string_of_uuid(&gc, uuid); + char *ret; + if (!s) { + XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid"); + ret = NULL; + }else{ + ret = strdup(s); + } + libxl_free_all(&gc); + return ret; } -static const char *userdata_path(libxl_ctx *ctx, uint32_t domid, +static const char *userdata_path(libxl_gc *gc, uint32_t domid, const char *userdata_userid, - const char *wh) { + const char *wh) +{ + libxl_ctx *ctx = libxl_gc_owner(gc); char *path, *uuid_string; libxl_dominfo info; int rc; @@ -446,9 +472,9 @@ static const char *userdata_path(libxl_c " for domain %"PRIu32, domid); return NULL; } - uuid_string = string_of_uuid(ctx, info.uuid); + uuid_string = string_of_uuid(gc, info.uuid); - path = libxl_sprintf(ctx, "/var/lib/xen/" + path = libxl_sprintf(gc, "/var/lib/xen/" "userdata-%s.%s.%s", wh, uuid_string, userdata_userid); if (!path) @@ -467,94 +493,132 @@ static int userdata_delete(libxl_ctx *ct return 0; } -void libxl__userdata_destroyall(libxl_ctx *ctx, uint32_t domid) { +void libxl__userdata_destroyall(libxl_ctx *ctx, uint32_t domid) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *pattern; glob_t gl; int r, i; - pattern = userdata_path(ctx, domid, "*", "?"); - if (!pattern) return; + pattern = userdata_path(&gc, domid, "*", "?"); + if (!pattern) + goto out; gl.gl_pathc = 0; gl.gl_pathv = 0; gl.gl_offs = 0; r = glob(pattern, GLOB_ERR|GLOB_NOSORT|GLOB_MARK, 0, &gl); - if (r == GLOB_NOMATCH) return; - if (r) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "glob failed for %s", pattern); + if (r == GLOB_NOMATCH) + goto out; + if (r) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "glob failed for %s", pattern); for (i=0; i<gl.gl_pathc; i++) { userdata_delete(ctx, gl.gl_pathv[i]); } globfree(&gl); +out: + libxl_free_all(&gc); } int libxl_userdata_store(libxl_ctx *ctx, uint32_t domid, const char *userdata_userid, - const uint8_t *data, int datalen) { + const uint8_t *data, int datalen) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *filename; const char *newfilename; - int e; + int e, rc; int fd = -1; - FILE *f = 0; + FILE *f = NULL; size_t rs; - filename = userdata_path(ctx, domid, userdata_userid, "d"); - if (!filename) return ERROR_NOMEM; + filename = userdata_path(&gc, domid, userdata_userid, "d"); + if (!filename) { + rc = ERROR_NOMEM; + goto out; + } - if (!datalen) - return userdata_delete(ctx, filename); + if (!datalen) { + rc = userdata_delete(ctx, filename); + goto out; + } - newfilename = userdata_path(ctx, domid, userdata_userid, "n"); - if (!newfilename) return ERROR_NOMEM; + newfilename = userdata_path(&gc, domid, userdata_userid, "n"); + if (!newfilename) { + rc = ERROR_NOMEM; + goto out; + } + + rc = ERROR_FAIL; fd= open(newfilename, O_RDWR|O_CREAT|O_TRUNC, 0600); - if (fd<0) goto xe; + if (fd<0) + goto err; f= fdopen(fd, "wb"); - if (!f) goto xe; + if (!f) + goto err; fd = -1; rs = fwrite(data, 1, datalen, f); - if (rs != datalen) { assert(ferror(f)); goto xe; } + if (rs != datalen) { + assert(ferror(f)); + goto err; + } - if (fclose(f)) goto xe; + if (fclose(f)) + goto err; f = 0; - if (rename(newfilename,filename)) goto xe; + if (rename(newfilename,filename)) + goto err; - return 0; + rc = 0; - xe: +err: e = errno; if (f) fclose(f); if (fd>=0) close(fd); errno = e; - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot write %s for %s", + if ( rc ) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot write %s for %s", newfilename, filename); - return ERROR_FAIL; +out: + libxl_free_all(&gc); + return rc; } int libxl_userdata_retrieve(libxl_ctx *ctx, uint32_t domid, const char *userdata_userid, - uint8_t **data_r, int *datalen_r) { + uint8_t **data_r, int *datalen_r) +{ + libxl_gc gc = LIBXL_INIT_GC(ctx); const char *filename; - int e; + int e, rc; int datalen = 0; void *data = 0; - filename = userdata_path(ctx, domid, userdata_userid, "d"); - if (!filename) return ERROR_NOMEM; + filename = userdata_path(&gc, domid, userdata_userid, "d"); + if (!filename) { + rc = ERROR_NOMEM; + goto out; + } 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 ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } if (data_r) *data_r = data; if (datalen_r) *datalen_r = datalen; - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } diff -r 7b144fe8c528 tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_exec.c Thu Aug 12 15:22:56 2010 +0100 @@ -100,7 +100,7 @@ int libxl_spawn_spawn(libxl_ctx *ctx, libxl_spawn_starting *for_spawn = starting->for_spawn; if (for_spawn) { - for_spawn->what = libxl_strdup(ctx, what); + for_spawn->what = strdup(what); if (!for_spawn->what) return ERROR_NOMEM; } @@ -140,10 +140,12 @@ static void report_spawn_intermediate_st int status) { if (!WIFEXITED(status)) { + char *intermediate_what; /* intermediate process did the logging itself if it exited */ - char *intermediate_what = libxl_sprintf(ctx, - "%s intermediate process (startup monitor)", - for_spawn->what); + if ( asprintf(&intermediate_what, + "%s intermediate process (startup monitor)", + for_spawn->what) < 0 ) + intermediate_what = "intermediate process (startup monitor)"; libxl_report_child_exitstatus(ctx, XL_LOG_ERROR, intermediate_what, for_spawn->intermediate, status); } diff -r 7b144fe8c528 tools/libxl/libxl_internal.c --- a/tools/libxl/libxl_internal.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_internal.c Thu Aug 12 15:22:56 2010 +0100 @@ -28,7 +28,7 @@ int libxl_error_set(libxl_ctx *ctx, int return 0; } -int libxl_ptr_add(libxl_ctx *ctx, void *ptr) +int libxl_ptr_add(libxl_gc *gc, void *ptr) { int i; void **re; @@ -37,29 +37,29 @@ int libxl_ptr_add(libxl_ctx *ctx, void * return 0; /* fast case: we have space in the array for storing the pointer */ - for (i = 0; i < ctx->alloc_maxsize; i++) { - if (!ctx->alloc_ptrs[i]) { - ctx->alloc_ptrs[i] = ptr; + for (i = 0; i < gc->alloc_maxsize; i++) { + if (!gc->alloc_ptrs[i]) { + gc->alloc_ptrs[i] = ptr; return 0; } } /* realloc alloc_ptrs manually with calloc/free/replace */ - re = calloc(ctx->alloc_maxsize + 25, sizeof(void *)); + re = calloc(gc->alloc_maxsize + 25, sizeof(void *)); if (!re) return -1; - for (i = 0; i < ctx->alloc_maxsize; i++) - re[i] = ctx->alloc_ptrs[i]; + for (i = 0; i < gc->alloc_maxsize; i++) + re[i] = gc->alloc_ptrs[i]; /* assign the next pointer */ re[i] = ptr; /* replace the old alloc_ptr */ - free(ctx->alloc_ptrs); - ctx->alloc_ptrs = re; - ctx->alloc_maxsize += 25; + free(gc->alloc_ptrs); + gc->alloc_ptrs = re; + gc->alloc_maxsize += 25; return 0; } -void libxl_free(libxl_ctx *ctx, void *ptr) +void libxl_free(libxl_gc *gc, void *ptr) { int i; @@ -67,9 +67,9 @@ void libxl_free(libxl_ctx *ctx, void *pt return; /* remove the pointer from the tracked ptrs */ - for (i = 0; i < ctx->alloc_maxsize; i++) { - if (ctx->alloc_ptrs[i] == ptr) { - ctx->alloc_ptrs[i] = NULL; + for (i = 0; i < gc->alloc_maxsize; i++) { + if (gc->alloc_ptrs[i] == ptr) { + gc->alloc_ptrs[i] = NULL; free(ptr); return; } @@ -78,43 +78,44 @@ void libxl_free(libxl_ctx *ctx, void *pt abort(); } -void libxl_free_all(libxl_ctx *ctx) +void libxl_free_all(libxl_gc *gc) { void *ptr; int i; - for (i = 0; i < ctx->alloc_maxsize; i++) { - ptr = ctx->alloc_ptrs[i]; - ctx->alloc_ptrs[i] = NULL; + for (i = 0; i < gc->alloc_maxsize; i++) { + ptr = gc->alloc_ptrs[i]; + gc->alloc_ptrs[i] = NULL; free(ptr); } + free(gc->alloc_ptrs); } -void *libxl_zalloc(libxl_ctx *ctx, int bytes) +void *libxl_zalloc(libxl_gc *gc, int bytes) { void *ptr = calloc(bytes, 1); if (!ptr) { - libxl_error_set(ctx, ENOMEM); + libxl_error_set(libxl_gc_owner(gc), ENOMEM); return NULL; } - libxl_ptr_add(ctx, ptr); + libxl_ptr_add(gc, ptr); return ptr; } -void *libxl_calloc(libxl_ctx *ctx, size_t nmemb, size_t size) +void *libxl_calloc(libxl_gc *gc, size_t nmemb, size_t size) { void *ptr = calloc(nmemb, size); if (!ptr) { - libxl_error_set(ctx, ENOMEM); + libxl_error_set(libxl_gc_owner(gc), ENOMEM); return NULL; } - libxl_ptr_add(ctx, ptr); + libxl_ptr_add(gc, ptr); return ptr; } -char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) +char *libxl_sprintf(libxl_gc *gc, const char *fmt, ...) { char *s; va_list ap; @@ -128,7 +129,7 @@ char *libxl_sprintf(libxl_ctx *ctx, cons return NULL; } - s = libxl_zalloc(ctx, ret + 1); + s = libxl_zalloc(gc, ret + 1); if (s) { va_start(ap, fmt); ret = vsnprintf(s, ret + 1, fmt, ap); @@ -137,20 +138,20 @@ char *libxl_sprintf(libxl_ctx *ctx, cons return s; } -char *libxl_strdup(libxl_ctx *ctx, const char *c) +char *libxl_strdup(libxl_gc *gc, const char *c) { char *s = strdup(c); if (s) - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } -char *libxl_dirname(libxl_ctx *ctx, const char *s) +char *libxl_dirname(libxl_gc *gc, const char *s) { char *c; - char *ptr = libxl_strdup(ctx, s); + char *ptr = libxl_strdup(gc, s); c = strrchr(ptr, ''/''); if (!c) @@ -196,10 +197,10 @@ void xl_log(libxl_ctx *ctx, xentoollog_l va_end(ap); } -char *libxl_abs_path(libxl_ctx *ctx, char *s, const char *path) +char *libxl_abs_path(libxl_gc *gc, char *s, const char *path) { if (!s || s[0] == ''/'') return s; - return libxl_sprintf(ctx, "%s/%s", path, s); + return libxl_sprintf(gc, "%s/%s", path, s); } diff -r 7b144fe8c528 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_internal.h Thu Aug 12 15:22:56 2010 +0100 @@ -114,24 +114,37 @@ typedef struct { _hidden int xs_writev(struct xs_handle *xsh, xs_transaction_t t, char *dir, char *kvs[]); +typedef struct { + /* mini-GC */ + int alloc_maxsize; + void **alloc_ptrs; + libxl_ctx *owner; +} libxl_gc; + +#define LIBXL_INIT_GC(ctx) (libxl_gc){ .alloc_maxsize = 0, .alloc_ptrs = 0, .owner = ctx } +static inline libxl_ctx *libxl_gc_owner(libxl_gc *gc) +{ + return gc->owner; +} + /* memory allocation tracking/helpers */ -_hidden int libxl_ptr_add(libxl_ctx *ctx, void *ptr); -_hidden void libxl_free(libxl_ctx *ctx, void *ptr); -_hidden void libxl_free_all(libxl_ctx *ctx); -_hidden void *libxl_zalloc(libxl_ctx *ctx, int bytes); -_hidden void *libxl_calloc(libxl_ctx *ctx, size_t nmemb, size_t size); -_hidden char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); -_hidden char *libxl_strdup(libxl_ctx *ctx, const char *c); -_hidden char *libxl_dirname(libxl_ctx *ctx, const char *s); +_hidden int libxl_ptr_add(libxl_gc *gc, void *ptr); +_hidden void libxl_free(libxl_gc *gc, void *ptr); +_hidden void libxl_free_all(libxl_gc *gc); +_hidden void *libxl_zalloc(libxl_gc *gc, int bytes); +_hidden void *libxl_calloc(libxl_gc *gc, size_t nmemb, size_t size); +_hidden char *libxl_sprintf(libxl_gc *gc, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); +_hidden char *libxl_strdup(libxl_gc *gc, const char *c); +_hidden char *libxl_dirname(libxl_gc *gc, const char *s); -_hidden char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int length); -_hidden int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t, +_hidden char **libxl_xs_kvs_of_flexarray(libxl_gc *gc, flexarray_t *array, int length); +_hidden int libxl_xs_writev(libxl_gc *gc, xs_transaction_t t, char *dir, char **kvs); -_hidden int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t, +_hidden int libxl_xs_write(libxl_gc *gc, xs_transaction_t t, char *path, char *fmt, ...) PRINTF_ATTRIBUTE(4, 5); -_hidden char *libxl_xs_get_dompath(libxl_ctx *ctx, uint32_t domid); // logs errs -_hidden char *libxl_xs_read(libxl_ctx *ctx, xs_transaction_t t, char *path); -_hidden char **libxl_xs_directory(libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb); +_hidden char *libxl_xs_get_dompath(libxl_gc *gc, uint32_t domid); // logs errs +_hidden char *libxl_xs_read(libxl_gc *gc, xs_transaction_t t, char *path); +_hidden char **libxl_xs_directory(libxl_gc *gc, xs_transaction_t t, char *path, unsigned int *nb); /* from xl_dom */ _hidden int is_hvm(libxl_ctx *ctx, uint32_t domid); @@ -175,8 +188,6 @@ _hidden int libxl_wait_for_device_model( void *userdata), void *check_callback_userdata); _hidden int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state); -_hidden int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus, - unsigned int dev, unsigned int func); /* from xenguest (helper */ _hidden int hvm_build_set_params(xc_interface *handle, uint32_t domid, @@ -225,18 +236,17 @@ _hidden int libxl_spawn_check(libxl_ctx /* low-level stuff, for synchronous subprocesses etc. */ _hidden void libxl_exec(int stdinfd, int stdoutfd, int stderrfd, char *arg0, char **args); // logs errors, never returns -_hidden void libxl_log_child_exitstatus(libxl_ctx *ctx, +_hidden void libxl_log_child_exitstatus(libxl_gc *gc, const char *what, pid_t pid, int status); -_hidden char *libxl_abs_path(libxl_ctx *ctx, char *s, const char *path); +_hidden char *libxl_abs_path(libxl_gc *gc, char *s, const char *path); #define XL_LOG_DEBUG XTL_DEBUG #define XL_LOG_INFO XTL_INFO #define XL_LOG_WARNING XTL_WARN #define XL_LOG_ERROR XTL_ERROR -_hidden char *_libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid); -_hidden char *_libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid); +_hidden char *_libxl_domid_to_name(libxl_gc *gc, uint32_t domid); +_hidden char *_libxl_poolid_to_name(libxl_gc *gc, uint32_t poolid); #endif - diff -r 7b144fe8c528 tools/libxl/libxl_pci.c --- a/tools/libxl/libxl_pci.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_pci.c Thu Aug 12 15:22:56 2010 +0100 @@ -195,8 +195,9 @@ parse_error: return ERROR_INVAL; } -static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev, int num) +static int libxl_create_pci_backend(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev, int num) { + libxl_ctx *ctx = libxl_gc_owner(gc); flexarray_t *front; flexarray_t *back; unsigned int boffset = 0; @@ -222,56 +223,57 @@ static int libxl_create_pci_backend(libx device.kind = DEVICE_PCI; flexarray_set(back, boffset++, "frontend-id"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", domid)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", domid)); flexarray_set(back, boffset++, "online"); flexarray_set(back, boffset++, "1"); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1)); flexarray_set(back, boffset++, "domain"); - flexarray_set(back, boffset++, _libxl_domid_to_name(ctx, domid)); + flexarray_set(back, boffset++, _libxl_domid_to_name(gc, domid)); for (i = 0; i < num; i++) { - flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "key-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "dev-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); if (pcidev->vdevfn) { - flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", pcidev->vdevfn)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "vdevfn-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%x", pcidev->vdevfn)); } - flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", i)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "opts-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "state-%d", i)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1)); } flexarray_set(back, boffset++, "num_devs"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", num)); flexarray_set(front, foffset++, "backend-id"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 0)); + flexarray_set(front, foffset++, libxl_sprintf(gc, "%d", 0)); flexarray_set(front, foffset++, "state"); - flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(front, foffset++, libxl_sprintf(gc, "%d", 1)); libxl_device_generic_add(ctx, &device, - libxl_xs_kvs_of_flexarray(ctx, back, boffset), - libxl_xs_kvs_of_flexarray(ctx, front, foffset)); + libxl_xs_kvs_of_flexarray(gc, back, boffset), + libxl_xs_kvs_of_flexarray(gc, front, foffset)); flexarray_free(back); flexarray_free(front); return 0; } -static int libxl_device_pci_add_xenstore(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int libxl_device_pci_add_xenstore(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); flexarray_t *back; char *num_devs, *be_path; int num = 0; unsigned int boffset = 0; xs_transaction_t t; - be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); - num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", be_path)); + be_path = libxl_sprintf(gc, "%s/backend/pci/%d/0", libxl_xs_get_dompath(gc, 0), domid); + num_devs = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/num_devs", be_path)); if (!num_devs) - return libxl_create_pci_backend(ctx, domid, pcidev, 1); + return libxl_create_pci_backend(gc, domid, pcidev, 1); if (!is_hvm(ctx, domid)) { if (libxl_wait_for_backend(ctx, be_path, "4") < 0) @@ -284,27 +286,27 @@ static int libxl_device_pci_add_xenstore XL_LOG(ctx, XL_LOG_DEBUG, "Adding new pci device to xenstore"); num = atoi(num_devs); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "key-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "dev-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func)); if (pcidev->vdevfn) { - flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", pcidev->vdevfn)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "vdevfn-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%x", pcidev->vdevfn)); } - flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", num)); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "opts-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "state-%d", num)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1)); flexarray_set(back, boffset++, "num_devs"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num + 1)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", num + 1)); flexarray_set(back, boffset++, "state"); - flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 7)); + flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 7)); retry_transaction: t = xs_transaction_start(ctx->xsh); - libxl_xs_writev(ctx, t, be_path, - libxl_xs_kvs_of_flexarray(ctx, back, boffset)); + libxl_xs_writev(gc, t, be_path, + libxl_xs_kvs_of_flexarray(gc, back, boffset)); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -313,16 +315,17 @@ retry_transaction: return 0; } -static int libxl_device_pci_remove_xenstore(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int libxl_device_pci_remove_xenstore(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *be_path, *num_devs_path, *num_devs, *xsdev, *tmp, *tmppath; int num, i, j; xs_transaction_t t; unsigned int domain = 0, bus = 0, dev = 0, func = 0; - be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); - num_devs_path = libxl_sprintf(ctx, "%s/num_devs", be_path); - num_devs = libxl_xs_read(ctx, XBT_NULL, num_devs_path); + be_path = libxl_sprintf(gc, "%s/backend/pci/%d/0", libxl_xs_get_dompath(gc, 0), domid); + num_devs_path = libxl_sprintf(gc, "%s/num_devs", be_path); + num_devs = libxl_xs_read(gc, XBT_NULL, num_devs_path); if (!num_devs) return ERROR_INVAL; num = atoi(num_devs); @@ -335,7 +338,7 @@ static int libxl_device_pci_remove_xenst } for (i = 0; i < num; i++) { - xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); + xsdev = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/dev-%d", be_path, i)); sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); if (domain == pcidev->domain && bus == pcidev->bus && pcidev->dev == dev && pcidev->func == func) { @@ -349,8 +352,8 @@ static int libxl_device_pci_remove_xenst retry_transaction: t = xs_transaction_start(ctx->xsh); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i), "5", strlen("5")); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state", be_path), "7", strlen("7")); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, i), "5", strlen("5")); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state", be_path), "7", strlen("7")); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; @@ -364,42 +367,42 @@ retry_transaction: retry_transaction2: t = xs_transaction_start(ctx->xsh); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, i)); - xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i)); - libxl_xs_write(ctx, t, num_devs_path, "%d", num - 1); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/key-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/dev-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/vdev-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/opts-%d", be_path, i)); + xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/vdevfn-%d", be_path, i)); + libxl_xs_write(gc, t, num_devs_path, "%d", num - 1); for (j = i + 1; j < num; j++) { - tmppath = libxl_sprintf(ctx, "%s/state-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, j - 1), tmp, strlen(tmp)); + tmppath = libxl_sprintf(gc, "%s/state-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); - tmppath = libxl_sprintf(ctx, "%s/dev-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, j - 1), tmp, strlen(tmp)); + tmppath = libxl_sprintf(gc, "%s/dev-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/dev-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); - tmppath = libxl_sprintf(ctx, "%s/key-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, j - 1), tmp, strlen(tmp)); + tmppath = libxl_sprintf(gc, "%s/key-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/key-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); - tmppath = libxl_sprintf(ctx, "%s/vdev-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); + tmppath = libxl_sprintf(gc, "%s/vdev-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); if (tmp) { - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, j - 1), tmp, strlen(tmp)); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/vdev-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } - tmppath = libxl_sprintf(ctx, "%s/opts-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); + tmppath = libxl_sprintf(gc, "%s/opts-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); if (tmp) { - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, j - 1), tmp, strlen(tmp)); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/opts-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } - tmppath = libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j); - tmp = libxl_xs_read(ctx, t, tmppath); + tmppath = libxl_sprintf(gc, "%s/vdevfn-%d", be_path, j); + tmp = libxl_xs_read(gc, t, tmppath); if (tmp) { - xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp)); + xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp)); xs_rm(ctx->xsh, t, tmppath); } } @@ -408,7 +411,7 @@ retry_transaction2: goto retry_transaction2; if (num == 1) { - char *fe_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend", be_path)); + char *fe_path = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/frontend", be_path)); libxl_device_destroy(ctx, be_path, 1); xs_rm(ctx->xsh, XBT_NULL, be_path); xs_rm(ctx->xsh, XBT_NULL, fe_path); @@ -418,7 +421,7 @@ retry_transaction2: return 0; } -static int get_all_assigned_devices(libxl_ctx *ctx, libxl_device_pci **list, int *num) +static int get_all_assigned_devices(libxl_gc *gc, libxl_device_pci **list, int *num) { libxl_device_pci *pcidevs = NULL; char **domlist; @@ -427,21 +430,21 @@ static int get_all_assigned_devices(libx *list = NULL; *num = 0; - domlist = libxl_xs_directory(ctx, XBT_NULL, "/local/domain", &nd); + domlist = libxl_xs_directory(gc, XBT_NULL, "/local/domain", &nd); for(i = 0; i < nd; i++) { char *path, *num_devs; - path = libxl_sprintf(ctx, "/local/domain/0/backend/pci/%s/0/num_devs", domlist[i]); - num_devs = libxl_xs_read(ctx, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/backend/pci/%s/0/num_devs", domlist[i]); + num_devs = libxl_xs_read(gc, XBT_NULL, path); if ( num_devs ) { int ndev = atoi(num_devs), j; char *devpath, *bdf; - pcidevs = calloc(sizeof(*pcidevs), ndev); + pcidevs = libxl_calloc(gc, sizeof(*pcidevs), ndev); for(j = (pcidevs) ? 0 : ndev; j < ndev; j++) { - devpath = libxl_sprintf(ctx, "/local/domain/0/backend/pci/%s/0/dev-%u", + devpath = libxl_sprintf(gc, "/local/domain/0/backend/pci/%s/0/dev-%u", domlist[i], j); - bdf = libxl_xs_read(ctx, XBT_NULL, devpath); + bdf = libxl_xs_read(gc, XBT_NULL, devpath); if ( bdf ) { unsigned dom, bus, dev, func; if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 ) @@ -486,6 +489,7 @@ static int is_assigned(libxl_device_pci int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, int *num) { + libxl_gc gc = LIBXL_INIT_GC(ctx); libxl_device_pci *pcidevs = NULL, *new, *assigned; struct dirent *de; DIR *dir; @@ -494,7 +498,7 @@ int libxl_device_pci_list_assignable(lib *num = 0; *list = NULL; - rc = get_all_assigned_devices(ctx, &assigned, &num_assigned); + rc = get_all_assigned_devices(&gc, &assigned, &num_assigned); if ( rc ) return rc; @@ -505,7 +509,7 @@ int libxl_device_pci_list_assignable(lib }else{ XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn''t open %s", SYSFS_PCIBACK_DRIVER); } - free(assigned); + libxl_free_all(&gc); return ERROR_FAIL; } @@ -530,8 +534,8 @@ int libxl_device_pci_list_assignable(lib } closedir(dir); - free(assigned); *list = pcidevs; + libxl_free_all(&gc); return 0; } @@ -540,8 +544,9 @@ int libxl_device_pci_list_assignable(lib * driver. It also initialises a bit-mask of which function numbers are present * on that device. */ -static int pci_multifunction_check(libxl_ctx *ctx, libxl_device_pci *pcidev, unsigned int *func_mask) +static int pci_multifunction_check(libxl_gc *gc, libxl_device_pci *pcidev, unsigned int *func_mask) { + libxl_ctx *ctx = libxl_gc_owner(gc); struct dirent *de; DIR *dir; @@ -567,7 +572,7 @@ static int pci_multifunction_check(libxl if ( pcidev->dev != dev ) continue; - path = libxl_sprintf(ctx, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func); + path = libxl_sprintf(gc, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func); if ( lstat(path, &st) ) { if ( errno == ENOENT ) XL_LOG(ctx, XL_LOG_ERROR, PCI_BDF " is not assigned to pciback driver", @@ -598,8 +603,9 @@ static int pci_ins_check(libxl_ctx *ctx, return 1; } -static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int do_pci_add(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *path; char *state, *vdevfn; int rc, hvm; @@ -609,21 +615,21 @@ static int do_pci_add(libxl_ctx *ctx, ui if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 0) { return ERROR_FAIL; } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); - state = libxl_xs_read(ctx, XBT_NULL, path); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + state = libxl_xs_read(gc, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); if (pcidev->vdevfn) - libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain, + libxl_xs_write(gc, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func, pcidev->vdevfn); else - libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, + libxl_xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/command", domid); xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins")); rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); - vdevfn = libxl_xs_read(ctx, XBT_NULL, path); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); + vdevfn = libxl_xs_read(gc, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); if ( rc < 0 ) XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn); else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 ) @@ -632,7 +638,7 @@ static int do_pci_add(libxl_ctx *ctx, ui if ( rc ) return ERROR_FAIL; } else { - char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, + char *sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); FILE *f = fopen(sysfs_path, "r"); unsigned long long start = 0, end = 0, flags = 0, size = 0; @@ -667,7 +673,7 @@ static int do_pci_add(libxl_ctx *ctx, ui } } fclose(f); - sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, + sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); f = fopen(sysfs_path, "r"); if (f == NULL) { @@ -699,38 +705,74 @@ out: } } - libxl_device_pci_add_xenstore(ctx, domid, pcidev); + libxl_device_pci_add_xenstore(gc, domid, pcidev); return 0; } +static int libxl_device_pci_reset(libxl_gc *gc, unsigned int domain, unsigned int bus, + unsigned int dev, unsigned int func) +{ + libxl_ctx *ctx = libxl_gc_owner(gc); + char *reset; + int fd, rc; + + reset = libxl_sprintf(gc, "%s/pciback/do_flr", SYSFS_PCI_DEV); + fd = open(reset, O_WRONLY); + if (fd > 0) { + char *buf = libxl_sprintf(gc, PCI_BDF, domain, bus, dev, func); + rc = write(fd, buf, strlen(buf)); + if (rc < 0) + XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno != ENOENT) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset); + reset = libxl_sprintf(gc, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func); + fd = open(reset, O_WRONLY); + if (fd > 0) { + rc = write(fd, "1", 1); + if (rc < 0) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno == ENOENT) { + XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn''t support PCI device reset from sysfs"); + } else { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", reset); + } + return -1; +} + int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { + libxl_gc gc = LIBXL_INIT_GC(ctx); unsigned int orig_vdev, pfunc_mask; libxl_device_pci *assigned; - int num_assigned, rc, i; + int num_assigned, i, rc; int stubdomid = 0; - rc = get_all_assigned_devices(ctx, &assigned, &num_assigned); + rc = get_all_assigned_devices(&gc, &assigned, &num_assigned); if ( rc ) { XL_LOG(ctx, XL_LOG_ERROR, "cannot determine if device is assigned, refusing to continue"); - return ERROR_FAIL; + goto out; } if ( is_assigned(assigned, num_assigned, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func) ) { XL_LOG(ctx, XL_LOG_ERROR, "PCI device already attached to a domain"); - free(assigned); - return ERROR_FAIL; + rc = ERROR_FAIL; + goto out; } - free(assigned); - libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + libxl_device_pci_reset(&gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); stubdomid = libxl_get_stubdom_id(ctx, domid); if (stubdomid != 0) { libxl_device_pci pcidev_s = *pcidev; - rc = do_pci_add(ctx, stubdomid, &pcidev_s); + rc = do_pci_add(&gc, stubdomid, &pcidev_s); if ( rc ) - return rc; + goto out; } orig_vdev = pcidev->vdevfn & ~7U; @@ -738,10 +780,12 @@ int libxl_device_pci_add(libxl_ctx *ctx, if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { if ( !(pcidev->vdevfn >> 3) ) { XL_LOG(ctx, XL_LOG_ERROR, "Must specify a v-slot for multi-function devices"); - return ERROR_INVAL; + rc = ERROR_INVAL; + goto out; } - if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) { - return ERROR_FAIL; + if ( pci_multifunction_check(&gc, pcidev, &pfunc_mask) ) { + rc = ERROR_FAIL; + goto out; } pcidev->vfunc_mask &= pfunc_mask; /* so now vfunc_mask == pfunc_mask */ @@ -749,7 +793,7 @@ int libxl_device_pci_add(libxl_ctx *ctx, pfunc_mask = (1 << pcidev->func); } - for(i = 7; i >= 0; --i) { + for(rc = 0, i = 7; i >= 0; --i) { if ( (1 << i) & pfunc_mask ) { if ( pcidev->vfunc_mask == pfunc_mask ) { pcidev->func = i; @@ -761,16 +805,19 @@ int libxl_device_pci_add(libxl_ctx *ctx, */ pcidev->vdevfn = orig_vdev; } - if ( do_pci_add(ctx, domid, pcidev) ) + if ( do_pci_add(&gc, domid, pcidev) ) rc = ERROR_FAIL; } } +out: + libxl_free_all(&gc); return rc; } -static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +static int do_pci_remove(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev) { + libxl_ctx *ctx = libxl_gc_owner(gc); libxl_device_pci *assigned; char *path; char *state; @@ -785,19 +832,19 @@ static int do_pci_remove(libxl_ctx *ctx, } } - libxl_device_pci_remove_xenstore(ctx, domid, pcidev); + libxl_device_pci_remove_xenstore(gc, domid, pcidev); hvm = is_hvm(ctx, domid); if (hvm) { if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 0) { return ERROR_FAIL; } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); - state = libxl_xs_read(ctx, XBT_NULL, path); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid); - libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + state = libxl_xs_read(gc, XBT_NULL, path); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", domid); + libxl_xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/command", domid); /* Remove all functions at once atomically by only signalling * device-model for function 0 */ @@ -808,10 +855,10 @@ static int do_pci_remove(libxl_ctx *ctx, return ERROR_FAIL; } } - path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); + path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid); xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); } else { - char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, + char *sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); FILE *f = fopen(sysfs_path, "r"); unsigned int start = 0, end = 0, flags = 0, size = 0; @@ -841,7 +888,7 @@ static int do_pci_remove(libxl_ctx *ctx, } fclose(f); skip1: - sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, + sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); f = fopen(sysfs_path, "r"); if (f == NULL) { @@ -863,7 +910,7 @@ skip1: out: /* don''t do multiple resets while some functions are still passed through */ if ( (pcidev->vdevfn & 0x7) == 0 ) { - libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + libxl_device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); } if (!libxl_is_stubdom(ctx, domid, NULL)) { @@ -883,21 +930,23 @@ out: int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { + libxl_gc gc = LIBXL_INIT_GC(ctx); unsigned int orig_vdev, pfunc_mask; int i, rc; orig_vdev = pcidev->vdevfn & ~7U; if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { - if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) { - return ERROR_FAIL; + if ( pci_multifunction_check(&gc, pcidev, &pfunc_mask) ) { + rc = ERROR_FAIL; + goto out; } pcidev->vfunc_mask &= pfunc_mask; }else{ pfunc_mask = (1 << pcidev->func); } - for(i = 7; i >= 0; --i) { + for(rc = 0, i = 7; i >= 0; --i) { if ( (1 << i) & pfunc_mask ) { if ( pcidev->vfunc_mask == pfunc_mask ) { pcidev->func = i; @@ -905,26 +954,30 @@ int libxl_device_pci_remove(libxl_ctx *c }else{ pcidev->vdevfn = orig_vdev; } - if ( do_pci_remove(ctx, domid, pcidev) ) + if ( do_pci_remove(&gc, domid, pcidev) ) rc = ERROR_FAIL; } } +out: + libxl_free_all(&gc); return rc; } int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts; int n, i; unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0; libxl_device_pci *pcidevs; - be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", libxl_xs_get_dompath(ctx, 0), domid); - num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", be_path)); + be_path = libxl_sprintf(&gc, "%s/backend/pci/%d/0", libxl_xs_get_dompath(&gc, 0), domid); + num_devs = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/num_devs", be_path)); if (!num_devs) { *num = 0; *list = NULL; + libxl_free_all(&gc); return 0; } n = atoi(num_devs); @@ -932,13 +985,13 @@ int libxl_device_pci_list_assigned(libxl *num = n; for (i = 0; i < n; i++) { - xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", be_path, i)); + xsdev = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev-%d", be_path, i)); sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func); - xsvdevfn = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i)); + xsvdevfn = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/vdevfn-%d", be_path, i)); if (xsvdevfn) vdevfn = strtol(xsvdevfn, (char **) NULL, 16); pcidev_init(pcidevs + i, domain, bus, dev, func, vdevfn); - xsopts = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/opts-%d", be_path, i)); + xsopts = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/opts-%d", be_path, i)); if (xsopts) { char *saveptr; char *p = strtok_r(xsopts, ",=", &saveptr); @@ -957,6 +1010,7 @@ int libxl_device_pci_list_assigned(libxl } if ( *num ) *list = pcidevs; + libxl_free_all(&gc); return 0; } @@ -975,38 +1029,3 @@ int libxl_device_pci_shutdown(libxl_ctx free(pcidevs); return 0; } - -int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int bus, - unsigned int dev, unsigned int func) -{ - char *reset; - int fd, rc; - - reset = libxl_sprintf(ctx, "%s/pciback/do_flr", SYSFS_PCI_DEV); - fd = open(reset, O_WRONLY); - if (fd > 0) { - char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func); - rc = write(fd, buf, strlen(buf)); - if (rc < 0) - XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno != ENOENT) - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset); - reset = libxl_sprintf(ctx, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func); - fd = open(reset, O_WRONLY); - if (fd > 0) { - rc = write(fd, "1", 1); - if (rc < 0) - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno == ENOENT) { - XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn''t support PCI device reset from sysfs"); - } else { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", reset); - } - return -1; -} diff -r 7b144fe8c528 tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_utils.c Thu Aug 12 15:22:56 2010 +0100 @@ -54,11 +54,11 @@ char *libxl_domid_to_name(libxl_ctx *ctx return s; } -char *_libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid) +char *_libxl_domid_to_name(libxl_gc *gc, uint32_t domid) { - char *s = libxl_domid_to_name(ctx, domid); + char *s = libxl_domid_to_name(libxl_gc_owner(gc), domid); if ( s ) - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } @@ -75,14 +75,16 @@ int libxl_name_to_domid(libxl_ctx *ctx, return ERROR_NOMEM; for (i = 0; i < nb_domains; i++) { - domname = _libxl_domid_to_name(ctx, dominfo[i].domid); + domname = libxl_domid_to_name(ctx, dominfo[i].domid); if (!domname) continue; if (strcmp(domname, name) == 0) { *domid = dominfo[i].domid; ret = 0; + free(domname); break; } + free(domname); } free(dominfo); return ret; @@ -101,11 +103,11 @@ char *libxl_poolid_to_name(libxl_ctx *ct return s; } -char *_libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid) +char *_libxl_poolid_to_name(libxl_gc *gc, uint32_t poolid) { - char *s = libxl_poolid_to_name(ctx, poolid); + char *s = libxl_poolid_to_name(libxl_gc_owner(gc), poolid); if ( s ) - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } @@ -122,14 +124,16 @@ int libxl_name_to_poolid(libxl_ctx *ctx, return ERROR_NOMEM; for (i = 0; i < nb_pools; i++) { - poolname = _libxl_poolid_to_name(ctx, poolinfo[i].poolid); + poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid); if (!poolname) continue; if (strcmp(poolname, name) == 0) { *poolid = poolinfo[i].poolid; ret = 0; + free(poolname); break; } + free(poolname); } free(poolinfo); return ret; @@ -137,27 +141,40 @@ int libxl_name_to_poolid(libxl_ctx *ctx, int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid) { - char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid))); + libxl_gc gc = LIBXL_INIT_GC(ctx); + char * stubdom_id_s; + int ret; + + stubdom_id_s = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/image/device-model-domid", + libxl_xs_get_dompath(&gc, guest_domid))); if (stubdom_id_s) - return atoi(stubdom_id_s); + ret = atoi(stubdom_id_s); else - return 0; + ret = 0; + libxl_free_all(&gc); + return ret; } int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *target, *endptr; uint32_t value; + int ret = 0; - target = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid))); + target = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/target", libxl_xs_get_dompath(&gc, domid))); if (!target) - return 0; + goto out; value = strtol(target, &endptr, 10); if (*endptr != ''\0'') - return 0; + goto out; if (target_domid) *target_domid = value; - return 1; + ret = 1; +out: + libxl_free_all(&gc); + return ret; } static int logrename(libxl_ctx *ctx, const char *old, const char *new) { @@ -176,26 +193,29 @@ static int logrename(libxl_ctx *ctx, con int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name) { + libxl_gc gc = LIBXL_INIT_GC(ctx); struct stat stat_buf; char *logfile, *logfile_new; int i, rc; - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log", name); if (stat(logfile, &stat_buf) == 0) { /* file exists, rotate */ - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.10", name); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log.10", name); unlink(logfile); for (i = 9; i > 0; i--) { - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i); - logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i + 1); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log.%d", name, i); + logfile_new = libxl_sprintf(&gc, "/var/log/xen/%s.log.%d", name, i + 1); rc = logrename(ctx, logfile, logfile_new); - if (rc) return rc; + if (rc) + goto out; } - logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name); - logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.1", name); + logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log", name); + logfile_new = libxl_sprintf(&gc, "/var/log/xen/%s.log.1", name); rc = logrename(ctx, logfile, logfile_new); - if (rc) return rc; + if (rc) + goto out; } else { if (errno != ENOENT) XL_LOG_ERRNO(ctx, XL_LOG_WARNING, "problem checking existence of" @@ -203,7 +223,10 @@ int libxl_create_logfile(libxl_ctx *ctx, name); } *full_name = strdup(logfile); - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_string_to_phystype(libxl_ctx *ctx, char *s, libxl_disk_phystype *phystype) @@ -423,122 +446,135 @@ int libxl_mac_to_device_nic(libxl_ctx *c int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_nic *nic) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *tok, *val; char *dompath, *nic_path_fe, *nic_path_be; unsigned int i; + int rc = ERROR_FAIL; memset(nic, 0, sizeof (libxl_device_nic)); - dompath = libxl_xs_get_dompath(ctx, domid); + dompath = libxl_xs_get_dompath(&gc, domid); if (!dompath) { - return ERROR_FAIL; + goto out; } - nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, devid); - nic_path_be = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/backend", nic_path_fe)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", nic_path_fe)); + nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, devid); + nic_path_be = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/backend", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", nic_path_fe)); if ( NULL == val ) { - return ERROR_FAIL; + goto out; } nic->backend_domid = strtoul(val, NULL, 10); nic->devid = strtoul(devid, NULL, 10); - libxl_free(ctx, val); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", nic_path_fe)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", nic_path_fe)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { nic->mac[i] = strtoul(tok, NULL, 16); } - libxl_free(ctx, val); - nic->script = libxl_xs_read(ctx, XBT_NULL, - libxl_sprintf(ctx, "%s/script", nic_path_be)); - libxl_free(ctx, nic_path_fe); - libxl_free(ctx, nic_path_be); - return 0; + nic->script = libxl_xs_read(&gc, XBT_NULL, + libxl_sprintf(&gc, "%s/script", nic_path_be)); + rc = 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_devid_to_device_disk(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_disk *disk) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *endptr, *val; char *dompath, *diskpath, *be_path; unsigned int devid_n; + int rc = ERROR_INVAL; devid_n = strtoul(devid, &endptr, 10); if (devid == endptr) { - return ERROR_INVAL; + goto out; } - dompath = libxl_xs_get_dompath(ctx, domid); - diskpath = libxl_sprintf(ctx, "%s/device/vbd/%s", dompath, devid); + rc = ERROR_FAIL; + dompath = libxl_xs_get_dompath(&gc, domid); + diskpath = libxl_sprintf(&gc, "%s/device/vbd/%s", dompath, devid); if (!diskpath) { - return ERROR_FAIL; + goto out; } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", diskpath)); if (!val) - return ERROR_FAIL; + goto out; disk->backend_domid = strtoul(val, NULL, 10); disk->domid = domid; - be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", diskpath)); - disk->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/params", be_path)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/type", be_path)); + be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", diskpath)); + disk->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/params", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/type", be_path)); libxl_string_to_phystype(ctx, val, &(disk->phystype)); - disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", be_path)); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/removable", be_path)); + disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/removable", be_path)); disk->unpluggable = !strcmp(val, "1"); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mode", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mode", be_path)); disk->readwrite = !!strcmp(val, "w"); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", diskpath)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", diskpath)); disk->is_cdrom = !strcmp(val, "cdrom"); + rc = 0; - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_net2 *net2) { + libxl_gc gc = LIBXL_INIT_GC(ctx); char *tok, *endptr, *val; char *dompath, *net2path, *be_path; unsigned int devid_n, i; + int rc = ERROR_INVAL; devid_n = strtoul(devid, &endptr, 10); if (devid == endptr) { - return ERROR_INVAL; + goto out; } - dompath = libxl_xs_get_dompath(ctx, domid); - net2path = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, devid); + rc = ERROR_FAIL; + dompath = libxl_xs_get_dompath(&gc, domid); + net2path = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, devid); if (!net2path) { - return ERROR_FAIL; + goto out; } memset(net2, 0, sizeof (libxl_device_net2)); - be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", net2path)); + be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", net2path)); net2->devid = devid_n; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", net2path)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2->front_mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", net2path)); for (i = 0, tok = strtok(val, ":"); tok && (i < 6); ++i, tok = strtok(NULL, ":")) { net2->back_mac[i] = strtoul(tok, NULL, 16); } - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", net2path)); net2->backend_domid = strtoul(val, NULL, 10); net2->domid = domid; - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-trusted", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-trusted", be_path)); net2->trusted = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/local-trusted", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/local-trusted", be_path)); net2->back_trusted = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", be_path)); net2->filter_mac = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", net2path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", net2path)); net2->front_filter_mac = strtoul(val, NULL, 10); - val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/max-bypasses", be_path)); + val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/max-bypasses", be_path)); net2->max_bypasses = strtoul(val, NULL, 10); + rc = 0; - return 0; +out: + libxl_free_all(&gc); + return rc; } int libxl_strtomac(const char *mac_s, uint8_t *mac) @@ -561,21 +597,23 @@ int libxl_strtomac(const char *mac_s, ui int libxl_check_device_model_version(libxl_ctx *ctx, char *path) { + libxl_gc gc = LIBXL_INIT_GC(ctx); pid_t pid = -1; int pipefd[2]; char buf[100]; ssize_t i, count = 0; int status; char *abs_path = NULL; + int rc = -1; - abs_path = libxl_abs_path(ctx, path, libxl_private_bindir_path()); + abs_path = libxl_abs_path(&gc, path, libxl_private_bindir_path()); if (pipe(pipefd)) - return -1; + goto out; pid = fork(); if (pid == -1) { - return -1; + goto out; } if (!pid) { @@ -589,8 +627,6 @@ int libxl_check_device_model_version(lib } close(pipefd[1]); - if (abs_path != path) - libxl_free(ctx, abs_path); /* attempt to get the first line of `qemu -h` */ while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) { @@ -606,13 +642,14 @@ int libxl_check_device_model_version(lib close(pipefd[0]); waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - return -1; + goto out; } /* Check if we have the forked qemu-xen. */ /* QEMU-DM emulator version 0.10.2, ... */ if (strncmp("QEMU-DM ", buf, 7) == 0) { - return 0; + rc = 0; + goto out; } /* Check if the version is above 12.0 */ @@ -626,10 +663,14 @@ int libxl_check_device_model_version(lib if (major == 0 && endptr && *endptr == ''.'') { v = endptr + 1; minor = strtol(v, &endptr, 10); - if (minor >= 12) - return 1; + if (minor >= 12) { + rc = 1; + goto out; + } } } - - return 0; + rc = 0; +out: + libxl_free_all(&gc); + return rc; } diff -r 7b144fe8c528 tools/libxl/libxl_xshelp.c --- a/tools/libxl/libxl_xshelp.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/libxl_xshelp.c Thu Aug 12 15:22:56 2010 +0100 @@ -44,12 +44,12 @@ int xs_writev(struct xs_handle *xsh, xs_ return 0; } -char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int length) +char **libxl_xs_kvs_of_flexarray(libxl_gc *gc, flexarray_t *array, int length) { char **kvs; int i; - kvs = libxl_calloc(ctx, length + 2, sizeof(char *)); + kvs = libxl_calloc(gc, length + 2, sizeof(char *)); if (kvs) { for (i = 0; i < length; i += 2) { void *ptr; @@ -65,9 +65,10 @@ char **libxl_xs_kvs_of_flexarray(libxl_c return kvs; } -int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t, +int libxl_xs_writev(libxl_gc *gc, xs_transaction_t t, char *dir, char *kvs[]) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *path; int i; @@ -75,19 +76,19 @@ int libxl_xs_writev(libxl_ctx *ctx, xs_t return 0; for (i = 0; kvs[i] != NULL; i += 2) { - path = libxl_sprintf(ctx, "%s/%s", dir, kvs[i]); + path = libxl_sprintf(gc, "%s/%s", dir, kvs[i]); if (path && kvs[i + 1]) { int length = strlen(kvs[i + 1]); xs_write(ctx->xsh, t, path, kvs[i + 1], length); } - libxl_free(ctx, path); } return 0; } -int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t, +int libxl_xs_write(libxl_gc *gc, xs_transaction_t t, char *path, char *fmt, ...) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *s; va_list ap; int ret; @@ -103,35 +104,38 @@ int libxl_xs_write(libxl_ctx *ctx, xs_tr return 0; } -char * libxl_xs_read(libxl_ctx *ctx, xs_transaction_t t, char *path) +char * libxl_xs_read(libxl_gc *gc, xs_transaction_t t, char *path) { + libxl_ctx *ctx = libxl_gc_owner(gc); unsigned int len; char *ptr; ptr = xs_read(ctx->xsh, t, path, &len); if (ptr != NULL) { - libxl_ptr_add(ctx, ptr); + libxl_ptr_add(gc, ptr); return ptr; } return 0; } -char *libxl_xs_get_dompath(libxl_ctx *ctx, uint32_t domid) +char *libxl_xs_get_dompath(libxl_gc *gc, uint32_t domid) { + libxl_ctx *ctx = libxl_gc_owner(gc); char *s = xs_get_domain_path(ctx->xsh, domid); if (!s) { XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to get dompath for %" PRIu32, domid); return NULL; } - libxl_ptr_add(ctx, s); + libxl_ptr_add(gc, s); return s; } -char **libxl_xs_directory(libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb) +char **libxl_xs_directory(libxl_gc *gc, xs_transaction_t t, char *path, unsigned int *nb) { + libxl_ctx *ctx = libxl_gc_owner(gc); char **ret = NULL; ret = xs_directory(ctx->xsh, XBT_NULL, path, nb); - libxl_ptr_add(ctx, ret); + libxl_ptr_add(gc, ret); return ret; } diff -r 7b144fe8c528 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Wed Aug 11 14:39:44 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Thu Aug 12 15:22:56 2010 +0100 @@ -3267,7 +3267,7 @@ static void print_vcpuinfo(uint32_t tdom void vcpulist(int argc, char **argv) { - libxl_dominfo *dominfo; + libxl_dominfo *dominfo, *domlist; libxl_vcpuinfo *vcpuinfo, *list = NULL; libxl_physinfo physinfo; int nb_vcpu, nb_domain, nrcpus; @@ -3279,7 +3279,7 @@ void vcpulist(int argc, char **argv) printf("%-32s %5s %5s %5s %5s %9s %s\n", "Name", "ID", "VCPU", "CPU", "State", "Time(s)", "CPU Affinity"); if (!argc) { - if (!(dominfo = libxl_list_domain(&ctx, &nb_domain))) { + if (!(domlist = dominfo = libxl_list_domain(&ctx, &nb_domain))) { fprintf(stderr, "libxl_list_domain failed.\n"); goto vcpulist_out; } @@ -3294,6 +3294,7 @@ void vcpulist(int argc, char **argv) } libxl_free_vcpu_list(list); } + free(domlist); } else { for (; argc > 0; ++argv, --argc) { if (domain_qualifier_to_domid(*argv, &domid, 0) < 0) { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Maybe Matching Threads
- [PATCH 1/3] libxenlight: Clean up logging arrangements
- [PATCH] xl: make libxl_uuid2string internal to libxenlight
- [PATCH] libxl: make libxl communicate with xenstored by socket or xenbus driver
- [PATCH] xl: Update memory info in xenstore when use ''xl mem-set''
- [PATCH 2/2] 4.1.2 blktap2 cleanup fixes.