[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 27/29] xl: split out save/restore related code
Add some function declarations to xl.h because they are now needed in multiple files. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- tools/xl/Makefile | 2 +- tools/xl/xl.h | 6 + tools/xl/xl_cmdimpl.c | 227 -------------------------------------- tools/xl/xl_saverestore.c | 273 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 280 insertions(+), 228 deletions(-) create mode 100644 tools/xl/xl_saverestore.c diff --git a/tools/xl/Makefile b/tools/xl/Makefile index 0f966684be..9982b936c4 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -20,7 +20,7 @@ XL_OBJS += xl_tmem.o xl_parse.o xl_cpupool.o xl_flask.o XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cd.o xl_mem.o XL_OBJS += xl_psr.o xl_info.o xl_console.o xl_misc.o -XL_OBJS += xl_vmcontrol.o +XL_OBJS += xl_vmcontrol.o xl_saverestore.o $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog) $(XL_OBJS): CFLAGS += $(CFLAGS_XL) diff --git a/tools/xl/xl.h b/tools/xl/xl.h index 62d010076b..65b89ce717 100644 --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -96,6 +96,12 @@ struct save_file_header { #define SAVEFILE_BYTEORDER_VALUE ((uint32_t)0x01020304UL) +void save_domain_core_begin(uint32_t domid, + const char *override_config_file, + uint8_t **config_data_r, + int *config_len_r); +void save_domain_core_writeconfig(int fd, const char *source, + const uint8_t *config_data, int config_len); /* * The xl process should always return either EXIT_SUCCESS or diff --git a/tools/xl/xl_cmdimpl.c b/tools/xl/xl_cmdimpl.c index b3a17d5fa6..c41ae31814 100644 --- a/tools/xl/xl_cmdimpl.c +++ b/tools/xl/xl_cmdimpl.c @@ -99,133 +99,6 @@ void help(const char *command) } #ifndef LIBXL_HAVE_NO_SUSPEND_RESUME -static void save_domain_core_begin(uint32_t domid, - const char *override_config_file, - uint8_t **config_data_r, - int *config_len_r) -{ - int rc; - libxl_domain_config d_config; - char *config_c = 0; - - /* configuration file in optional data: */ - - libxl_domain_config_init(&d_config); - - if (override_config_file) { - void *config_v = 0; - rc = libxl_read_file_contents(ctx, override_config_file, - &config_v, config_len_r); - if (rc) { - fprintf(stderr, "unable to read overridden config file\n"); - exit(EXIT_FAILURE); - } - parse_config_data(override_config_file, config_v, *config_len_r, - &d_config); - free(config_v); - } else { - rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config); - if (rc) { - fprintf(stderr, "unable to retrieve domain configuration\n"); - exit(EXIT_FAILURE); - } - } - - config_c = libxl_domain_config_to_json(ctx, &d_config); - if (!config_c) { - fprintf(stderr, "unable to convert config file to JSON\n"); - exit(EXIT_FAILURE); - } - *config_data_r = (uint8_t *)config_c; - *config_len_r = strlen(config_c) + 1; /* including trailing '\0' */ - - libxl_domain_config_dispose(&d_config); -} - -static void save_domain_core_writeconfig(int fd, const char *source, - const uint8_t *config_data, int config_len) -{ - struct save_file_header hdr; - uint8_t *optdata_begin; - union { uint32_t u32; char b[4]; } u32buf; - - memset(&hdr, 0, sizeof(hdr)); - memcpy(hdr.magic, savefileheader_magic, sizeof(hdr.magic)); - hdr.byteorder = SAVEFILE_BYTEORDER_VALUE; - hdr.mandatory_flags = XL_MANDATORY_FLAG_STREAMv2; - - optdata_begin= 0; - -#define ADD_OPTDATA(ptr, len) ({ \ - if ((len)) { \ - hdr.optional_data_len += (len); \ - optdata_begin = xrealloc(optdata_begin, hdr.optional_data_len); \ - memcpy(optdata_begin + hdr.optional_data_len - (len), \ - (ptr), (len)); \ - } \ - }) - - u32buf.u32 = config_len; - ADD_OPTDATA(u32buf.b, 4); - ADD_OPTDATA(config_data, config_len); - if (config_len) - hdr.mandatory_flags |= XL_MANDATORY_FLAG_JSON; - - /* that's the optional data */ - - CHK_ERRNOVAL(libxl_write_exactly( - ctx, fd, &hdr, sizeof(hdr), source, "header")); - CHK_ERRNOVAL(libxl_write_exactly( - ctx, fd, optdata_begin, hdr.optional_data_len, - source, "header")); - - free(optdata_begin); - - fprintf(stderr, "Saving to %s new xl format (info" - " 0x%"PRIx32"/0x%"PRIx32"/%"PRIu32")\n", - source, hdr.mandatory_flags, hdr.optional_flags, - hdr.optional_data_len); -} - -static int save_domain(uint32_t domid, const char *filename, int checkpoint, - int leavepaused, const char *override_config_file) -{ - int fd; - uint8_t *config_data; - int config_len; - - save_domain_core_begin(domid, override_config_file, - &config_data, &config_len); - - if (!config_len) { - fputs(" Savefile will not contain xl domain config\n", stderr); - } - - fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644); - if (fd < 0) { - fprintf(stderr, "Failed to open temp file %s for writing\n", filename); - exit(EXIT_FAILURE); - } - - save_domain_core_writeconfig(fd, filename, config_data, config_len); - - int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL); - close(fd); - - if (rc < 0) { - fprintf(stderr, "Failed to save domain, resuming domain\n"); - libxl_domain_resume(ctx, domid, 1, 0); - } - else if (leavepaused || checkpoint) { - if (leavepaused) - libxl_domain_pause(ctx, domid); - libxl_domain_resume(ctx, domid, 1, 0); - } - else - libxl_domain_destroy(ctx, domid, 0); - - exit(rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS); -} static pid_t create_migration_child(const char *rune, int *send_fd, int *recv_fd) @@ -667,74 +540,6 @@ static void migrate_receive(int debug, int daemonize, int monitor, exit(EXIT_SUCCESS); } -int main_restore(int argc, char **argv) -{ - const char *checkpoint_file = NULL; - const char *config_file = NULL; - struct domain_create dom_info; - int paused = 0, debug = 0, daemonize = 1, monitor = 1, - console_autoconnect = 0, vnc = 0, vncautopass = 0; - int opt, rc; - static struct option opts[] = { - {"vncviewer", 0, 0, 'V'}, - {"vncviewer-autopass", 0, 0, 'A'}, - COMMON_LONG_OPTS - }; - - SWITCH_FOREACH_OPT(opt, "FcpdeVA", opts, "restore", 1) { - case 'c': - console_autoconnect = 1; - break; - case 'p': - paused = 1; - break; - case 'd': - debug = 1; - break; - case 'F': - daemonize = 0; - break; - case 'e': - daemonize = 0; - monitor = 0; - break; - case 'V': - vnc = 1; - break; - case 'A': - vnc = vncautopass = 1; - break; - } - - if (argc-optind == 1) { - checkpoint_file = argv[optind]; - } else if (argc-optind == 2) { - config_file = argv[optind]; - checkpoint_file = argv[optind + 1]; - } else { - help("restore"); - return EXIT_FAILURE; - } - - memset(&dom_info, 0, sizeof(dom_info)); - dom_info.debug = debug; - dom_info.daemonize = daemonize; - dom_info.monitor = monitor; - dom_info.paused = paused; - dom_info.config_file = config_file; - dom_info.restore_file = checkpoint_file; - dom_info.migrate_fd = -1; - dom_info.send_back_fd = -1; - dom_info.vnc = vnc; - dom_info.vncautopass = vncautopass; - dom_info.console_autoconnect = console_autoconnect; - - rc = create_domain(&dom_info); - if (rc < 0) - return EXIT_FAILURE; - - return EXIT_SUCCESS; -} int main_migrate_receive(int argc, char **argv) { @@ -785,38 +590,6 @@ int main_migrate_receive(int argc, char **argv) return EXIT_SUCCESS; } -int main_save(int argc, char **argv) -{ - uint32_t domid; - const char *filename; - const char *config_filename = NULL; - int checkpoint = 0; - int leavepaused = 0; - int opt; - - SWITCH_FOREACH_OPT(opt, "cp", NULL, "save", 2) { - case 'c': - checkpoint = 1; - break; - case 'p': - leavepaused = 1; - break; - } - - if (argc-optind > 3) { - help("save"); - return EXIT_FAILURE; - } - - domid = xfind_domain(argv[optind]); - filename = argv[optind + 1]; - if ( argc - optind >= 3 ) - config_filename = argv[optind + 2]; - - save_domain(domid, filename, checkpoint, leavepaused, config_filename); - return EXIT_SUCCESS; -} - int main_migrate(int argc, char **argv) { uint32_t domid; diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c new file mode 100644 index 0000000000..918c189af0 --- /dev/null +++ b/tools/xl/xl_saverestore.c @@ -0,0 +1,273 @@ +/* + * Copyright 2009-2017 Citrix Ltd and other contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include <fcntl.h> +#include <inttypes.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <time.h> +#include <unistd.h> + +#include <libxl.h> +#include <libxl_utils.h> +#include <libxlutil.h> + +#include "xl.h" +#include "xl_utils.h" +#include "xl_parse.h" + +#ifndef LIBXL_HAVE_NO_SUSPEND_RESUME + +void save_domain_core_begin(uint32_t domid, + const char *override_config_file, + uint8_t **config_data_r, + int *config_len_r) +{ + int rc; + libxl_domain_config d_config; + char *config_c = 0; + + /* configuration file in optional data: */ + + libxl_domain_config_init(&d_config); + + if (override_config_file) { + void *config_v = 0; + rc = libxl_read_file_contents(ctx, override_config_file, + &config_v, config_len_r); + if (rc) { + fprintf(stderr, "unable to read overridden config file\n"); + exit(EXIT_FAILURE); + } + parse_config_data(override_config_file, config_v, *config_len_r, + &d_config); + free(config_v); + } else { + rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config); + if (rc) { + fprintf(stderr, "unable to retrieve domain configuration\n"); + exit(EXIT_FAILURE); + } + } + + config_c = libxl_domain_config_to_json(ctx, &d_config); + if (!config_c) { + fprintf(stderr, "unable to convert config file to JSON\n"); + exit(EXIT_FAILURE); + } + *config_data_r = (uint8_t *)config_c; + *config_len_r = strlen(config_c) + 1; /* including trailing '\0' */ + + libxl_domain_config_dispose(&d_config); +} + +void save_domain_core_writeconfig(int fd, const char *source, + const uint8_t *config_data, int config_len) +{ + struct save_file_header hdr; + uint8_t *optdata_begin; + union { uint32_t u32; char b[4]; } u32buf; + + memset(&hdr, 0, sizeof(hdr)); + memcpy(hdr.magic, savefileheader_magic, sizeof(hdr.magic)); + hdr.byteorder = SAVEFILE_BYTEORDER_VALUE; + hdr.mandatory_flags = XL_MANDATORY_FLAG_STREAMv2; + + optdata_begin= 0; + +#define ADD_OPTDATA(ptr, len) ({ \ + if ((len)) { \ + hdr.optional_data_len += (len); \ + optdata_begin = xrealloc(optdata_begin, hdr.optional_data_len); \ + memcpy(optdata_begin + hdr.optional_data_len - (len), \ + (ptr), (len)); \ + } \ + }) + + u32buf.u32 = config_len; + ADD_OPTDATA(u32buf.b, 4); + ADD_OPTDATA(config_data, config_len); + if (config_len) + hdr.mandatory_flags |= XL_MANDATORY_FLAG_JSON; + + /* that's the optional data */ + + CHK_ERRNOVAL(libxl_write_exactly( + ctx, fd, &hdr, sizeof(hdr), source, "header")); + CHK_ERRNOVAL(libxl_write_exactly( + ctx, fd, optdata_begin, hdr.optional_data_len, + source, "header")); + + free(optdata_begin); + + fprintf(stderr, "Saving to %s new xl format (info" + " 0x%"PRIx32"/0x%"PRIx32"/%"PRIu32")\n", + source, hdr.mandatory_flags, hdr.optional_flags, + hdr.optional_data_len); +} + +static int save_domain(uint32_t domid, const char *filename, int checkpoint, + int leavepaused, const char *override_config_file) +{ + int fd; + uint8_t *config_data; + int config_len; + + save_domain_core_begin(domid, override_config_file, + &config_data, &config_len); + + if (!config_len) { + fputs(" Savefile will not contain xl domain config\n", stderr); + } + + fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd < 0) { + fprintf(stderr, "Failed to open temp file %s for writing\n", filename); + exit(EXIT_FAILURE); + } + + save_domain_core_writeconfig(fd, filename, config_data, config_len); + + int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL); + close(fd); + + if (rc < 0) { + fprintf(stderr, "Failed to save domain, resuming domain\n"); + libxl_domain_resume(ctx, domid, 1, 0); + } + else if (leavepaused || checkpoint) { + if (leavepaused) + libxl_domain_pause(ctx, domid); + libxl_domain_resume(ctx, domid, 1, 0); + } + else + libxl_domain_destroy(ctx, domid, 0); + + exit(rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS); +} + +int main_restore(int argc, char **argv) +{ + const char *checkpoint_file = NULL; + const char *config_file = NULL; + struct domain_create dom_info; + int paused = 0, debug = 0, daemonize = 1, monitor = 1, + console_autoconnect = 0, vnc = 0, vncautopass = 0; + int opt, rc; + static struct option opts[] = { + {"vncviewer", 0, 0, 'V'}, + {"vncviewer-autopass", 0, 0, 'A'}, + COMMON_LONG_OPTS + }; + + SWITCH_FOREACH_OPT(opt, "FcpdeVA", opts, "restore", 1) { + case 'c': + console_autoconnect = 1; + break; + case 'p': + paused = 1; + break; + case 'd': + debug = 1; + break; + case 'F': + daemonize = 0; + break; + case 'e': + daemonize = 0; + monitor = 0; + break; + case 'V': + vnc = 1; + break; + case 'A': + vnc = vncautopass = 1; + break; + } + + if (argc-optind == 1) { + checkpoint_file = argv[optind]; + } else if (argc-optind == 2) { + config_file = argv[optind]; + checkpoint_file = argv[optind + 1]; + } else { + help("restore"); + return EXIT_FAILURE; + } + + memset(&dom_info, 0, sizeof(dom_info)); + dom_info.debug = debug; + dom_info.daemonize = daemonize; + dom_info.monitor = monitor; + dom_info.paused = paused; + dom_info.config_file = config_file; + dom_info.restore_file = checkpoint_file; + dom_info.migrate_fd = -1; + dom_info.send_back_fd = -1; + dom_info.vnc = vnc; + dom_info.vncautopass = vncautopass; + dom_info.console_autoconnect = console_autoconnect; + + rc = create_domain(&dom_info); + if (rc < 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +int main_save(int argc, char **argv) +{ + uint32_t domid; + const char *filename; + const char *config_filename = NULL; + int checkpoint = 0; + int leavepaused = 0; + int opt; + + SWITCH_FOREACH_OPT(opt, "cp", NULL, "save", 2) { + case 'c': + checkpoint = 1; + break; + case 'p': + leavepaused = 1; + break; + } + + if (argc-optind > 3) { + help("save"); + return EXIT_FAILURE; + } + + domid = xfind_domain(argv[optind]); + filename = argv[optind + 1]; + if ( argc - optind >= 3 ) + config_filename = argv[optind + 2]; + + save_domain(domid, filename, checkpoint, leavepaused, config_filename); + return EXIT_SUCCESS; +} + +#endif /* LIBXL_HAVE_NO_SUSPEND_RESUME */ + + + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |