References: bug#1176189 Usage of xl save -p|-c will suspend the domU. As a result the monitoring xl process with get a LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN/LIBXL_SHUTDOWN_REASON_SUSPEND event. This will cause it to exit because it does not know the -p/-c flags were used to keep the domU active. As a result the final shutdown will not destroy the domU. Write a flag to xenstore to let the monitoring process know about the usage of -p/-c. Remove the flag once the suspend is done. Recognize the flag in the monitoring process. Keep going if the flag is seen. Watch again for @releaseDomain events. Keep going if the event type and shutdown reason remains the same. --- tools/xl/Makefile | 3 ++- tools/xl/xl.h | 1 + tools/xl/xl_saverestore.c | 15 ++++++++++++ tools/xl/xl_vmcontrol.c | 48 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -26,6 +26,7 @@ XL_OBJS += xl_vmcontrol.o xl_saverestore XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog) +$(XL_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(XL_OBJS): CFLAGS += $(CFLAGS_XL) $(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs it. @@ -33,7 +34,7 @@ $(XL_OBJS): CFLAGS += -include $(XEN_ROO all: xl xl: $(XL_OBJS) - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) -lyajl $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) -lyajl $(APPEND_LDFLAGS) .PHONY: install install: all --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -303,6 +303,7 @@ typedef enum { DOMAIN_RESTART_SOFT_RESET, /* Soft reset should be performed */ } domain_restart_type; +#define XL_SAVE_PAUSE_CHECKPOINT "suse-xl-save-pc" extern void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh); extern void apply_global_affinity_masks(libxl_domain_type type, libxl_bitmap *vcpu_affinity_array, --- a/tools/xl/xl_saverestore.c +++ b/tools/xl/xl_saverestore.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -127,6 +128,8 @@ static int save_domain(uint32_t domid, i const char *filename, int checkpoint, int leavepaused, const char *override_config_file) { + struct xs_handle *xsh = NULL; + char path[80]; int fd; uint8_t *config_data; int config_len; @@ -144,12 +147,24 @@ static int save_domain(uint32_t domid, i fprintf(stderr, "Failed to open temp file %s for writing\n", filename); exit(EXIT_FAILURE); } + if (leavepaused || checkpoint) + { + snprintf(path, sizeof(path), "/libxl/%u/" XL_SAVE_PAUSE_CHECKPOINT, domid); + xsh = xs_open(0); + if (xsh) + xs_write(xsh, XBT_NULL, path, leavepaused ? "p" : "c", 1); + } save_domain_core_writeconfig(fd, filename, config_data, config_len); int rc = libxl_domain_suspend_suse(ctx, domid, fd, &props, NULL); close(fd); + if (xsh) { + xs_rm(xsh, XBT_NULL, path); + xs_close(xsh); + } + if (rc < 0) { fprintf(stderr, "Failed to save domain, resuming domain\n"); libxl_domain_resume(ctx, domid, 1, 0); --- a/tools/xl/xl_vmcontrol.c +++ b/tools/xl/xl_vmcontrol.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -668,6 +669,10 @@ int create_domain(struct domain_create * int migrate_fd = dom_info->migrate_fd; bool config_in_json; + libxl_event_type type = 0; + uint8_t shutdown_reason = 0; + bool is_in_suspend = false; + int i; int need_daemon = daemonize; int ret, rc; @@ -1034,6 +1039,24 @@ start: ret = domain_wait_event(domid, &event); if (ret) goto out; + if (is_in_suspend) { + if ( type == event->type && event->u.domain_shutdown.shutdown_reason == shutdown_reason) { + struct timespec req = { .tv_nsec = 123456789, }; + libxl_evdisable_domain_death(ctx, deathw); + deathw = NULL; + ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw); + if (ret) goto out; + libxl_event_free(ctx, event); + LOG("Domain %u still suspended", domid); + nanosleep(&req, NULL); + continue; + } + is_in_suspend = false; + LOG("Domain %u left suspend state", domid); + } + type = event->type; + shutdown_reason = event->u.domain_shutdown.shutdown_reason; + switch (event->type) { case LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN: @@ -1095,14 +1118,39 @@ start: goto start; case DOMAIN_RESTART_NONE: + { + struct xs_handle *xsh = xs_open(0); + + if (xsh) { + char path[80]; + unsigned int len = 0; + char *val; + + snprintf(path, sizeof(path), "/libxl/%u/" XL_SAVE_PAUSE_CHECKPOINT, domid); + val = xs_read(xsh, XBT_NULL, path, &len); + xs_close(xsh); + LOG("Got %p '%s' from %s, len %u", val, val ?:"", path, len); + free(val); + if (val) + { + is_in_suspend = true; + libxl_evdisable_domain_death(ctx, deathw); + deathw = NULL; + ret = libxl_evenable_domain_death(ctx, domid, 0, &deathw); + if (ret) goto out; + break; + } + } LOG("Done. Exiting now"); libxl_event_free(ctx, event); ret = 0; goto out; + } default: abort(); } + break; case LIBXL_EVENT_TYPE_DOMAIN_DEATH: LOG("Domain %u has been destroyed.", domid);