[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 9 of 9] xl: support on_{poweroff, reboot, crash} domain configuration options
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxx> # Date 1280140563 -3600 # Node ID 113b04a7e60718c8730368a045a49ddd56e64fac # Parent ee265e700eede4111e429a3c55d2c78f31805028 xl: support on_{poweroff,reboot,crash} domain configuration options. Adds on_watchdog compared to xend. I have further plans for struct domain_config so it isn't as pointless as it first looks. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> diff -r ee265e700eed -r 113b04a7e607 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Mon Jul 26 11:36:03 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Mon Jul 26 11:36:03 2010 +0100 @@ -99,6 +99,38 @@ struct save_file_header { uint32_t optional_data_len; /* skip, or skip tail, if not understood */ }; + +enum action_on_shutdown { + ACTION_DESTROY, + + ACTION_RESTART, + ACTION_RESTART_RENAME, + + ACTION_PRESERVE, + + ACTION_COREDUMP_DESTROY, + ACTION_COREDUMP_RESTART, +}; + +static char *action_on_shutdown_names[] = { + [ACTION_DESTROY] = "destroy", + + [ACTION_RESTART] = "restart", + [ACTION_RESTART_RENAME] = "rename-restart", + + [ACTION_PRESERVE] = "preserve", + + [ACTION_COREDUMP_DESTROY] = "coredump-destroy", + [ACTION_COREDUMP_RESTART] = "coredump-restart", +}; + +struct domain_config { + enum action_on_shutdown on_poweroff; + enum action_on_shutdown on_reboot; + enum action_on_shutdown on_watchdog; + enum action_on_shutdown on_crash; +}; + /* Optional data, in order: * 4 bytes uint32_t config file size * n bytes config file in Unix text file format @@ -472,11 +504,28 @@ static void printf_info(int domid, printf(")\n"); } +static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a) +{ + int i; + const char *n; + + for (i = 0; i < sizeof(action_on_shutdown_names) / sizeof(action_on_shutdown_names[0]); i++) { + n = action_on_shutdown_names[i]; + + if (strcmp(buf, n) == 0) { + *a = i; + return 1; + } + } + return 0; +} + static void parse_config_data(const char *configfile_filename_report, const char *configfile_data, int configfile_len, libxl_domain_create_info *c_info, libxl_domain_build_info *b_info, + struct domain_config *d_config, libxl_device_disk **disks, int *num_disks, libxl_device_nic **vifs, @@ -551,6 +600,35 @@ static void parse_config_data(const char if (!xlu_cfg_get_long (config, "memory", &l)) { b_info->max_memkb = l * 1024; b_info->target_memkb = b_info->max_memkb; + } + + if (xlu_cfg_get_string (config, "on_poweroff", &buf)) + buf = "destroy"; + if (!parse_action_on_shutdown(buf, &d_config->on_poweroff)) { + fprintf(stderr, "Unknown on_poweroff action \"%s\" specified\n", buf); + exit(1); + } + + if (xlu_cfg_get_string (config, "on_reboot", &buf)) + buf = "restart"; + if (!parse_action_on_shutdown(buf, &d_config->on_reboot)) { + fprintf(stderr, "Unknown on_reboot action \"%s\" specified\n", buf); + exit(1); + } + + if (xlu_cfg_get_string (config, "on_watchdog", &buf)) + buf = "destroy"; + if (!parse_action_on_shutdown(buf, &d_config->on_watchdog)) { + fprintf(stderr, "Unknown on_watchdog action \"%s\" specified\n", buf); + exit(1); + } + + + if (xlu_cfg_get_string (config, "on_crash", &buf)) + buf = "destroy"; + if (!parse_action_on_shutdown(buf, &d_config->on_crash)) { + fprintf(stderr, "Unknown on_crash action \"%s\" specified\n", buf); + exit(1); } /* libxl_get_required_shadow_memory() must be called after final values @@ -988,16 +1066,112 @@ int autoconnect_console(int hvm) _exit(1); } -/* Returns 1 if domain should be restarted */ -static int handle_domain_death(struct libxl_ctx *ctx, uint32_t domid, libxl_event *event, struct libxl_dominfo *info) -{ - if (info->shutdown_reason != SHUTDOWN_suspend) { - LOG("Domain %d needs to be clean: destroying the domain", domid); +/* Returns 1 if domain should be restarted, 2 if domain should be renamed then restarted */ +static int handle_domain_death(struct libxl_ctx *ctx, uint32_t domid, libxl_event *event, + libxl_domain_create_info *c_info, + struct domain_config *d_config, struct libxl_dominfo *info) +{ + int restart = 0; + enum action_on_shutdown action; + + switch (info->shutdown_reason) { + case LIBXL_SHUTDOWN_POWEROFF: + action = d_config->on_poweroff; + break; + case LIBXL_SHUTDOWN_REBOOT: + action = d_config->on_reboot; + break; + case LIBXL_SHUTDOWN_SUSPEND: + return 0; + case LIBXL_SHUTDOWN_CRASH: + action = d_config->on_crash; + break; + case LIBXL_SHUTDOWN_WATCHDOG: + action = d_config->on_watchdog; + break; + } + + LOG("Action for shutdown reason code %d is %s", info->shutdown_reason, action_on_shutdown_names[action]); + + if (action == ACTION_COREDUMP_DESTROY || action == ACTION_COREDUMP_RESTART) { + char *corefile; + int rc; + + if (asprintf(&corefile, "/var/xen/dump/%s", c_info->name) < 0) { + LOG("failed to construct core dump path"); + } else { + LOG("dumping core to %s", corefile); + rc=libxl_domain_core_dump(ctx, domid, corefile); + if (rc) LOG("core dump failed (rc=%d).", rc); + } + /* No point crying over spilled milk, continue on failure. */ + + if (action == ACTION_COREDUMP_DESTROY) + action = ACTION_DESTROY; + else + action = ACTION_RESTART; + } + + switch (action) { + case ACTION_PRESERVE: + break; + + case ACTION_RESTART_RENAME: + restart = 2; + break; + + case ACTION_RESTART: + restart = 1; + /* fall-through */ + case ACTION_DESTROY: + LOG("Domain %d needs to be cleaned up: destroying the domain", domid); libxl_domain_destroy(ctx, domid, 0); - if (info->shutdown_reason == SHUTDOWN_reboot) - return 1; - } - return 0; + break; + + case ACTION_COREDUMP_DESTROY: + case ACTION_COREDUMP_RESTART: + /* Already handled these above. */ + abort(); + } + + return restart; +} + +static int preserve_domain(struct libxl_ctx *ctx, uint32_t domid, libxl_event *event, + libxl_domain_create_info *c_info, + struct domain_config *d_config, struct libxl_dominfo *info) +{ + time_t now; + struct tm tm; + char stime[24]; + + uint8_t new_uuid[16]; + + int rc; + + now = time(NULL); + if (now == ((time_t) -1)) { + LOG("Failed to get current time for domain rename"); + return 0; + } + + tzset(); + if (gmtime_r(&now, &tm) == NULL) { + LOG("Failed to convert time to UTC"); + return 0; + } + + if (!strftime(&stime[0], sizeof(stime), "-%Y%m%dT%H%MZ", &tm)) { + LOG("Failed to format time as a string"); + return 0; + } + + random_uuid(&new_uuid[0]); + + LOG("Preserving domain %d %s with suffix%s", domid, c_info->name, stime); + rc = libxl_domain_preserve(ctx, domid, c_info, stime, new_uuid); + + return rc == 0 ? 1 : 0; } struct domain_create { @@ -1016,6 +1190,8 @@ struct domain_create { static int create_domain(struct domain_create *dom_info) { + struct domain_config d_config; + libxl_domain_create_info c_info; libxl_domain_build_info b_info; libxl_domain_build_state state; @@ -1150,7 +1326,7 @@ static int create_domain(struct domain_c if (!dom_info->quiet) printf("Parsing config file %s\n", config_file); - parse_config_data(config_file, config_data, config_len, &c_info, &b_info, &disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info); + parse_config_data(config_file, config_data, config_len, &c_info, &b_info, &d_config, &disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info); if (dom_info->dryrun) return 0; @@ -1369,13 +1545,20 @@ start: switch (event.type) { case LIBXL_EVENT_DOMAIN_DEATH: ret = libxl_event_get_domain_death_info(&ctx, domid, &event, &info); - if (ret < 0) continue; LOG("Domain %d is dead", domid); if (ret) { - if (handle_domain_death(&ctx, domid, &event, &info)) { + switch (handle_domain_death(&ctx, domid, &event, &c_info, &d_config, &info)) { + case 2: + if (!preserve_domain(&ctx, domid, &event, &c_info, &d_config, &info)) + /* If we fail then exit leaving the old domain in place. */ + exit(-1); + + /* Otherwise fall through and restart. */ + case 1: + libxl_free_waiter(w1); libxl_free_waiter(w2); free(w1); @@ -1387,9 +1570,10 @@ start: LOG("Done. Rebooting now"); sleep(2); goto start; + case 0: + LOG("Done. Exiting now"); + exit(0); } - LOG("Done. Exiting now"); - exit(0); } break; case LIBXL_EVENT_DISK_EJECT: @@ -1898,6 +2082,8 @@ void list_domains_details(void) void list_domains_details(void) { struct libxl_dominfo *info; + struct domain_config d_config; + char *config_file; uint8_t *data; int nb_domain, i, len, rc; @@ -1923,7 +2109,7 @@ void list_domains_details(void) if (rc) continue; CHK_ERRNO(asprintf(&config_file, "<domid %d data>", info[i].domid)); - parse_config_data(config_file, (char *)data, len, &c_info, &b_info, &disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info); + parse_config_data(config_file, (char *)data, len, &c_info, &b_info, &d_config, &disks, &num_disks, &vifs, &num_vifs, &vif2s, &num_vif2s, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, &dm_info); printf_info(info[i].domid, &c_info, &b_info, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info); free(data); free(config_file); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |