Stefano Stabellini
2009-Nov-25 14:11 UTC
[Xen-devel] [PATCH] libxenlight: clean up the domain when it dies
Hi all, this patch adds two functions to libxenlight to be able to recognize when a particular domain dies. After creating a domain, xl uses these functions to wait for its death and clean up its resources. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- diff -r d05451fd6464 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Fri Nov 20 17:23:11 2009 +0000 +++ b/tools/libxl/libxl.c Mon Nov 23 17:49:23 2009 +0000 @@ -54,9 +54,18 @@ { libxl_free_all(ctx); free(ctx->alloc_ptrs); - ctx->alloc_ptrs = NULL; + ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *)); + if (!ctx->alloc_ptrs) + return ERROR_NOMEM; + return 0; +} + +int libxl_ctx_close(struct libxl_ctx *ctx) +{ + libxl_ctx_free(ctx); + free(ctx->alloc_ptrs); xc_interface_close(ctx->xch); - xs_daemon_close(ctx->xsh); + xs_daemon_close(ctx->xsh); return 0; } @@ -352,6 +361,46 @@ return 0; } +int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int *fd) +{ + if (!xs_watch(ctx->xsh, "@releaseDomain", "domain_death")) + return -1; + *fd = xs_fileno(ctx->xsh); + return 0; +} + +int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t *info) +{ + unsigned int num; + int nb_domain, i, rc = 0; + char **vec = NULL; + xc_dominfo_t *list = NULL; + + vec = xs_read_watch(ctx->xsh, &num); + if (!vec) + return 0; + if (!strcmp(vec[XS_WATCH_TOKEN], "domain_death")) { + list = libxl_domain_infolist(ctx, &nb_domain); + for (i = 0; i < nb_domain; i++) { + if (domid == list[i].domid) { + if (list[i].running || (!list[i].shutdown && !list[i].crashed && !list[i].dying)) + goto out; + *info = list[i]; + rc = 1; + goto out; + } + } + memset(info, 0x00, sizeof(xc_dominfo_t)); + rc = 1; + goto out; + } + +out: + free(list); + free(vec); + return rc; +} + static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid) { char *pid; @@ -409,11 +458,6 @@ } if (libxl_destroy_device_model(ctx, domid) < 0) XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d", domid); - rc = xc_domain_destroy(ctx->xch, domid); - if (rc < 0) { - XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); - return -1; - } if (libxl_devices_destroy(ctx, domid, force) < 0) XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", domid); if (!xs_rm(ctx->xsh, XBT_NULL, dom_path)) @@ -421,6 +465,11 @@ snprintf(vm_path, sizeof(vm_path), "/vm/%s", libxl_uuid_to_string(ctx, uuid)); if (!xs_rm(ctx->xsh, XBT_NULL, vm_path)) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path); + rc = xc_domain_destroy(ctx->xch, domid); + if (rc < 0) { + XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid); + return -1; + } return 0; } diff -r d05451fd6464 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Fri Nov 20 17:23:11 2009 +0000 +++ b/tools/libxl/libxl.h Mon Nov 23 17:49:23 2009 +0000 @@ -227,6 +227,7 @@ /* context functions */ int libxl_ctx_init(struct libxl_ctx *ctx); int libxl_ctx_free(struct libxl_ctx *ctx); +int libxl_ctx_close(struct libxl_ctx *ctx); int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data); /* domain related functions */ @@ -238,6 +239,9 @@ uint32_t domid, int fd); int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req); int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force); + +int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int *fd); +int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t *info); int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid); int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid); diff -r d05451fd6464 tools/libxl/xl.c --- a/tools/libxl/xl.c Fri Nov 20 17:23:11 2009 +0000 +++ b/tools/libxl/xl.c Mon Nov 23 17:49:23 2009 +0000 @@ -25,7 +25,10 @@ #include <sys/time.h> /* for time */ #include <getopt.h> #include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include <sys/socket.h> +#include <sys/select.h> #include <arpa/inet.h> #include <xenctrl.h> @@ -584,13 +587,17 @@ libxl_device_vkb *vkbs = NULL; libxl_device_console console; int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 0; - int i; + int i, fd; + int need_daemon = 1; libxl_device_model_starting *dm_starting = 0; printf("Parsing config file %s\n", filename); parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info); if (debug) printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info); + +start: + domid = 0; libxl_ctx_init(&ctx); libxl_ctx_set_log(&ctx, log_callback, NULL); @@ -631,6 +638,36 @@ libxl_device_pci_add(&ctx, domid, &pcidevs[i]); libxl_domain_unpause(&ctx, domid); + + if (need_daemon) { + daemon(0, 0); + need_daemon = 0; + } + + libxl_wait_for_domain_death(&ctx, domid, &fd); + while (1) { + int ret; + fd_set rfds; + xc_dominfo_t info; + memset(&info, 0x00, sizeof(xc_dominfo_t)); + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + ret = select(fd + 1, &rfds, NULL, NULL, NULL); + if (!ret) + continue; + if (libxl_is_domain_dead(&ctx, domid, &info)) { + if (info.crashed || info.dying || (info.shutdown && (info.shutdown_reason != SHUTDOWN_suspend))) { + libxl_domain_destroy(&ctx, domid, 0); + if (info.shutdown && (info.shutdown_reason == SHUTDOWN_reboot)) { + libxl_ctx_free(&ctx); + goto start; + } + } + exit(0); + } + } for (i = 0; i < num_vifs; i++) { free(vifs[i].smac); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel