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@xxxxxxxxxxxxx>
---
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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|