[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2 of 2 V2] libxl: Remus - xl remus command
# HG changeset patch # User Shriram Rajagopalan <rshriram@xxxxxxxxx> # Date 1328070814 28800 # Node ID cf47997255f4a895ce6a9f0f3cd7fc3eaa0b42ba # Parent 2aa138177f5ef6aa44e6136dd1913441c99aa4b5 libxl: Remus - xl remus command xl remus acts as a frontend to enable remus for a given domain. * At the moment, only memory checkpointing and blackhole replication is supported. Support for disk checkpointing and network buffering will be added in future. * Replication is done over ssh connection currently (like live migration with xl). Future versions will have an option to use simple tcp socket based replication channel (for both Remus & live migration). Signed-off-by: Shriram Rajagopalan <rshriram@xxxxxxxxx> diff -r 2aa138177f5e -r cf47997255f4 docs/man/xl.pod.1 --- a/docs/man/xl.pod.1 Tue Jan 31 20:33:34 2012 -0800 +++ b/docs/man/xl.pod.1 Tue Jan 31 20:33:34 2012 -0800 @@ -348,6 +348,39 @@ Send <config> instead of config file fro =back +=item B<remus> [I<OPTIONS>] I<domain-id> I<host> + +Enable Remus HA for domain. By default B<xl> relies on ssh as a transport mechanism +between the two hosts. + +B<OPTIONS> + +=over 4 + +=item B<-i> I<MS> + +Checkpoint domain memory every MS milliseconds (default 200ms). + +=item B<-b> + +Replicate memory checkpoints to /dev/null (blackhole). + +=item B<-u> + +Disable memory checkpoint compression. + +=item B<-s> I<sshcommand> + +Use <sshcommand> instead of ssh. String will be passed to sh. If empty, run +<host> instead of ssh <host> xl migrate-receive -r [-e]. + +=item B<-e> + +On the new host, do not wait in the background (on <host>) for the death of the +domain. See the corresponding option of the I<create> subcommand. + +=back + =item B<pause> I<domain-id> Pause a domain. When in a paused state the domain will still consume diff -r 2aa138177f5e -r cf47997255f4 tools/libxl/xl.h --- a/tools/libxl/xl.h Tue Jan 31 20:33:34 2012 -0800 +++ b/tools/libxl/xl.h Tue Jan 31 20:33:34 2012 -0800 @@ -94,6 +94,7 @@ int main_cpupoolnumasplit(int argc, char int main_getenforce(int argc, char **argv); int main_setenforce(int argc, char **argv); int main_loadpolicy(int argc, char **argv); +int main_remus(int argc, char **argv); void help(const char *command); diff -r 2aa138177f5e -r cf47997255f4 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Tue Jan 31 20:33:34 2012 -0800 +++ b/tools/libxl/xl_cmdimpl.c Tue Jan 31 20:33:34 2012 -0800 @@ -2828,7 +2828,7 @@ static void core_dump_domain(const char } static void migrate_receive(int debug, int daemonize, int monitor, - int send_fd, int recv_fd) + int send_fd, int recv_fd, int remus) { int rc, rc2; char rc_buf; @@ -2863,6 +2863,41 @@ static void migrate_receive(int debug, i exit(-rc); } + if (remus) { + /* If we are here, it means that the sender (primary) has crashed. + * TODO: Split-Brain Check. + */ + fprintf(stderr, "migration target: Remus Failover for domain %u\n", + domid); + + /* + * If domain renaming fails, lets just continue (as we need the domain + * to be up & dom names may not matter much, as long as its reachable + * over network). + * + * If domain unpausing fails, destroy domain ? Or is it better to have + * a consistent copy of the domain (memory, cpu state, disk) + * on atleast one physical host ? Right now, lets just leave the domain + * as is and let the Administrator decide (or troubleshoot). + */ + if (migration_domname) { + rc = libxl_domain_rename(ctx, domid, migration_domname, + common_domname); + if (rc) + fprintf(stderr, "migration target (Remus): " + "Failed to rename domain from %s to %s:%d\n", + migration_domname, common_domname, rc); + } + + rc = libxl_domain_unpause(ctx, domid); + if (rc) + fprintf(stderr, "migration target (Remus): " + "Failed to unpause domain %s (id: %u):%d\n", + common_domname, domid, rc); + + exit(rc ? -ERROR_FAIL: 0); + } + fprintf(stderr, "migration target: Transfer complete," " requesting permission to start domain.\n"); @@ -2989,10 +3024,10 @@ int main_restore(int argc, char **argv) int main_migrate_receive(int argc, char **argv) { - int debug = 0, daemonize = 1, monitor = 1; + int debug = 0, daemonize = 1, monitor = 1, remus = 0; int opt; - while ((opt = def_getopt(argc, argv, "Fed", "migrate-receive", 0)) != -1) { + while ((opt = def_getopt(argc, argv, "Fedr", "migrate-receive", 0)) != -1) { switch (opt) { case 0: case 2: return opt; @@ -3006,6 +3041,9 @@ int main_migrate_receive(int argc, char case 'd': debug = 1; break; + case 'r': + remus = 1; + break; } } @@ -3014,7 +3052,8 @@ int main_migrate_receive(int argc, char return 2; } migrate_receive(debug, daemonize, monitor, - STDOUT_FILENO, STDIN_FILENO); + STDOUT_FILENO, STDIN_FILENO, + remus); return 0; } @@ -5951,6 +5990,106 @@ done: return ret; } +int main_remus(int argc, char **argv) +{ + int opt, rc, daemonize = 1; + const char *ssh_command = "ssh"; + char *host = NULL, *rune = NULL, *domain = NULL; + libxl_domain_remus_info r_info; + int send_fd = -1, recv_fd = -1; + pid_t child = -1; + uint8_t *config_data; + int config_len; + + memset(&r_info, 0, sizeof(libxl_domain_remus_info)); + /* Defaults */ + r_info.interval = 200; + r_info.blackhole = 0; + r_info.compression = 1; + + while ((opt = def_getopt(argc, argv, "bui:s:e", "remus", 2)) != -1) { + switch (opt) { + case 0: case 2: + return opt; + + case 'i': + r_info.interval = atoi(optarg); + break; + case 'b': + r_info.blackhole = 1; + break; + case 'u': + r_info.compression = 0; + break; + case 's': + ssh_command = optarg; + break; + case 'e': + daemonize = 0; + break; + } + } + + domain = argv[optind]; + host = argv[optind + 1]; + + if (r_info.blackhole) { + find_domain(domain); + send_fd = open("/dev/null", O_RDWR, 0644); + if (send_fd < 0) { + perror("failed to open /dev/null"); + exit(-1); + } + } else { + + /* + * TODO: change this to plain TCP socket based channel + * instead of SSH. For both live-migration and Remus. + */ + if (!ssh_command[0]) { + rune = host; + } else { + if (asprintf(&rune, "exec %s %s xl migrate-receive -r %s", + ssh_command, host, + daemonize ? "" : " -e") < 0) + return 1; + } + + save_domain_core_begin(domain, NULL, &config_data, &config_len); + + if (!config_len) { + fprintf(stderr, "No config file stored for running domain and " + "none supplied - cannot start remus.\n"); + exit(1); + } + + child = create_migration_child(rune, &send_fd, &recv_fd); + + migrate_do_preamble(send_fd, recv_fd, child, config_data, config_len, + rune); + } + + /* Point of no return */ + rc = libxl_domain_remus_start(ctx, &r_info, domid, send_fd, recv_fd); + + /* If we are here, it means backup has failed/domain suspend failed. + * Try to resume the domain and exit gracefully. + * TODO: Split-Brain check. + */ + fprintf(stderr, "remus sender: libxl_domain_suspend failed" + " (rc=%d)\n", rc); + + if (rc == ERROR_GUEST_TIMEDOUT) + fprintf(stderr, "Failed to suspend domain at primary.\n"); + else { + fprintf(stderr, "Remus: Backup failed? resuming domain at primary.\n"); + libxl_domain_resume(ctx, domid, 1); + } + + close(send_fd); + return -ERROR_FAIL; +} + /* * Local variables: * mode: C diff -r 2aa138177f5e -r cf47997255f4 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Tue Jan 31 20:33:34 2012 -0800 +++ b/tools/libxl/xl_cmdtable.c Tue Jan 31 20:33:34 2012 -0800 @@ -412,6 +412,20 @@ struct cmd_spec cmd_table[] = { "Loads a new policy int the Flask Xen security module", "<policy file>", }, + { "remus", + &main_remus, 0, + "Enable Remus HA for domain", + "[options] <Domain> [<host>]", + "-i MS Checkpoint domain memory every MS milliseconds (def. 200ms).\n" + "-b Replicate memory checkpoints to /dev/null (blackhole)\n" + "-u Disable memory checkpoint compression.\n" + "-s <sshcommand> Use <sshcommand> instead of ssh. String will be passed\n" + " to sh. If empty, run <host> instead of \n" + " ssh <host> xl migrate-receive -r [-e]\n" + "-e Do not wait in the background (on <host>) for the death\n" + " of the domain." + + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |