1. qemu migration入口函数
主要做以下工作:
1)分析传入参数;
2) 创建管道和进程;
3)调用start_migration()开始迁移;
4)suspend qemu monitor;
+/* Migration monitor command */ + +void do_migrate(int detach, const char *uri) +{ + MigrationState *s; + int fds[2]; + const char *ptr; + char *command = NULL; + char **argv = NULL; + int i; + + if (strstart(uri, "exec:", &ptr)) { + char *subcommand = urldecode(ptr); + if (subcommand == NULL) { + term_printf("Allocation error\n"); + return; + } + + command = strdup("/bin/sh"); + argv = qemu_mallocz(sizeof(char *) * 4); + argv[0] = strdup("sh"); + argv[1] = strdup("-c"); + argv[2] = subcommand; + argv[3] = NULL; + } else if (strstart(uri, "ssh:", &ptr)) { + char *host, *end; + int qemu_argc, daemonize = 0, incoming = 0, argc, i; + char **qemu_argv; + + if (ptr[0] != '/' && ptr[1] != '/') { + term_printf("Malformed ssh uri\n"); + return; + } + + qemu_get_launch_info(&qemu_argc, &qemu_argv, &daemonize, &incoming); + + argc = 3 + qemu_argc; + if (!daemonize) + argc++; + if (!incoming) + argc++; + + host = strdup(ptr + 2); + end = strchr(host, '/'); + if (end) *end = 0; + + command = strdup("ssh"); + argv = qemu_mallocz(sizeof(char *) * (argc + 1)); + argv[0] = strdup("ssh"); + argv[1] = strdup("-XC"); + argv[2] = host; + + for (i = 0; i < qemu_argc; i++) + argv[3 + i] = strdup(qemu_argv[i]); + + if (!daemonize) + argv[3 + i++] = strdup("-daemonize"); + if (!incoming) + argv[3 + i++] = strdup("-incoming"); + argv[3 + i] = NULL; + } else { + term_printf("Unknown migration protocol '%s'\n", uri); + return; + } + + if (pipe(fds) == -1) { + term_printf("pipe()\n"); + return; + } + +#if 0 + term_printf("execlp('%s'", command); + for (i = 0; argv[i]; i++) { + term_printf(", '%s'", argv[i]); + } + term_printf(", NULL);\n"); + return; +#endif + + s = qemu_mallocz(sizeof(MigrationState)); + if (s == NULL) { + term_printf("Allocation error\n"); + return; + } + + s->fd = fds[1]; + s->pid = fork(); + if (s->pid == -1) { + term_printf("fork error\n"); + return; + } + if (s->pid == 0) { + close(fds[1]); + dup2(fds[0], STDIN_FILENO); + execvp(command, argv); + exit(1); + } else + close(fds[0]); + + s->detach = detach; + s->has_error = qemu_mallocz(sizeof(int)); +#if 1 + qemu_free(command); + for (i = 0; argv[i]; i++) + qemu_free(argv[i]); + qemu_free(argv); +#endif + + if (start_migration(s) == -1) + term_printf("Could not start migration\n"); + else if (!s->detach) + monitor_suspend(); +}
2.