2011-09-23 12:00:45 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
2011-10-13 19:43:52 +04:00
|
|
|
#include <getopt.h>
|
|
|
|
#include <string.h>
|
2012-02-17 22:51:23 +04:00
|
|
|
#include <ctype.h>
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
2013-03-12 21:23:06 +04:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
2013-01-09 17:02:47 +04:00
|
|
|
#include "asm/types.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#include "compiler.h"
|
|
|
|
#include "crtools.h"
|
2013-11-06 17:21:11 +04:00
|
|
|
#include "cr_options.h"
|
2011-12-26 22:12:03 +04:00
|
|
|
#include "sockets.h"
|
2012-01-31 22:28:22 +04:00
|
|
|
#include "syscall.h"
|
2012-04-28 17:15:12 +04:00
|
|
|
#include "files.h"
|
|
|
|
#include "sk-inet.h"
|
2012-09-02 01:07:32 +04:00
|
|
|
#include "net.h"
|
2013-02-11 19:24:06 +04:00
|
|
|
#include "version.h"
|
2013-03-12 21:23:06 +04:00
|
|
|
#include "page-xfer.h"
|
2013-03-27 20:11:00 +04:00
|
|
|
#include "tty.h"
|
2013-03-27 20:17:59 +04:00
|
|
|
#include "file-lock.h"
|
2013-09-13 13:43:56 +04:00
|
|
|
#include "cr-service.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-04-19 11:48:00 +04:00
|
|
|
struct cr_options opts;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2013-10-30 02:48:38 +04:00
|
|
|
void init_opts(void)
|
|
|
|
{
|
|
|
|
memset(&opts, 0, sizeof(opts));
|
|
|
|
|
|
|
|
/* Default options */
|
|
|
|
opts.final_state = TASK_DEAD;
|
|
|
|
INIT_LIST_HEAD(&opts.veth_pairs);
|
|
|
|
INIT_LIST_HEAD(&opts.scripts);
|
|
|
|
}
|
|
|
|
|
2012-05-12 02:34:22 +04:00
|
|
|
static int parse_ns_string(const char *ptr)
|
2012-01-31 22:28:22 +04:00
|
|
|
{
|
|
|
|
const char *end = ptr + strlen(ptr);
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (ptr[3] != ',' && ptr[3] != '\0')
|
|
|
|
goto bad_ns;
|
|
|
|
if (!strncmp(ptr, "uts", 3))
|
2013-01-17 18:14:55 +04:00
|
|
|
opts.rst_namespaces_flags |= CLONE_NEWUTS;
|
2012-01-31 22:28:55 +04:00
|
|
|
else if (!strncmp(ptr, "ipc", 3))
|
2013-01-17 18:14:55 +04:00
|
|
|
opts.rst_namespaces_flags |= CLONE_NEWIPC;
|
2012-05-12 03:30:10 +04:00
|
|
|
else if (!strncmp(ptr, "mnt", 3))
|
2013-01-17 18:14:55 +04:00
|
|
|
opts.rst_namespaces_flags |= CLONE_NEWNS;
|
2012-06-22 00:38:00 +04:00
|
|
|
else if (!strncmp(ptr, "pid", 3))
|
2013-01-17 18:14:55 +04:00
|
|
|
opts.rst_namespaces_flags |= CLONE_NEWPID;
|
2012-08-02 08:06:29 +04:00
|
|
|
else if (!strncmp(ptr, "net", 3))
|
2013-01-17 18:14:55 +04:00
|
|
|
opts.rst_namespaces_flags |= CLONE_NEWNET;
|
2012-01-31 22:28:22 +04:00
|
|
|
else
|
|
|
|
goto bad_ns;
|
|
|
|
ptr += 4;
|
|
|
|
} while (ptr < end);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
bad_ns:
|
|
|
|
pr_err("Unknown namespace '%s'\n", ptr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2013-04-02 11:58:15 +04:00
|
|
|
pid_t pid = 0, tree_id = 0;
|
2011-09-23 12:00:45 +04:00
|
|
|
int ret = -1;
|
2011-10-13 19:43:52 +04:00
|
|
|
int opt, idx;
|
2012-02-17 22:51:23 +04:00
|
|
|
int log_level = 0;
|
2013-11-15 23:04:29 +04:00
|
|
|
char *imgs_dir = ".";
|
|
|
|
char *work_dir = NULL;
|
2011-10-13 19:43:52 +04:00
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
|
|
|
|
|
2012-08-07 02:00:39 +04:00
|
|
|
cr_pb_init();
|
2013-09-28 15:51:09 +04:00
|
|
|
restrict_uid(getuid(), getgid());
|
2012-08-07 02:00:39 +04:00
|
|
|
|
2012-03-02 14:01:08 +04:00
|
|
|
if (argc < 2)
|
2011-09-23 12:00:45 +04:00
|
|
|
goto usage;
|
|
|
|
|
2013-10-30 02:48:38 +04:00
|
|
|
init_opts();
|
2011-11-22 22:09:28 +04:00
|
|
|
|
2012-09-13 14:45:06 +04:00
|
|
|
if (init_service_fd())
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2012-09-13 14:45:06 +04:00
|
|
|
|
2012-04-16 14:14:41 +04:00
|
|
|
while (1) {
|
2013-11-15 23:04:26 +04:00
|
|
|
static const char short_opts[] = "dsRf:t:p:hcD:o:n:v::xVr:jlW:";
|
2012-04-16 14:23:05 +04:00
|
|
|
static struct option long_opts[] = {
|
|
|
|
{ "tree", required_argument, 0, 't' },
|
2013-04-02 11:58:15 +04:00
|
|
|
{ "pid", required_argument, 0, 'p' },
|
2012-04-16 14:23:05 +04:00
|
|
|
{ "leave-stopped", no_argument, 0, 's' },
|
2013-04-11 17:50:42 +04:00
|
|
|
{ "leave-running", no_argument, 0, 'R' },
|
2012-04-16 14:23:05 +04:00
|
|
|
{ "restore-detached", no_argument, 0, 'd' },
|
2013-05-20 19:11:19 +04:00
|
|
|
{ "daemon", no_argument, 0, 'd' },
|
2012-04-16 14:23:05 +04:00
|
|
|
{ "contents", no_argument, 0, 'c' },
|
|
|
|
{ "file", required_argument, 0, 'f' },
|
|
|
|
{ "images-dir", required_argument, 0, 'D' },
|
2013-11-15 23:04:26 +04:00
|
|
|
{ "work-dir", required_argument, 0, 'W' },
|
2012-04-16 14:23:05 +04:00
|
|
|
{ "log-file", required_argument, 0, 'o' },
|
|
|
|
{ "namespaces", required_argument, 0, 'n' },
|
2012-08-02 16:07:43 +04:00
|
|
|
{ "root", required_argument, 0, 'r' },
|
2013-03-26 19:32:53 +04:00
|
|
|
{ USK_EXT_PARAM, no_argument, 0, 'x' },
|
2012-04-16 14:23:05 +04:00
|
|
|
{ "help", no_argument, 0, 'h' },
|
2012-04-28 17:15:12 +04:00
|
|
|
{ SK_EST_PARAM, no_argument, 0, 42 },
|
2012-04-28 20:37:54 +04:00
|
|
|
{ "close", required_argument, 0, 43 },
|
2012-05-02 14:42:00 +04:00
|
|
|
{ "log-pid", no_argument, 0, 44},
|
2012-07-19 16:51:58 +04:00
|
|
|
{ "version", no_argument, 0, 'V'},
|
2012-08-07 19:33:49 +04:00
|
|
|
{ "evasive-devices", no_argument, 0, 45},
|
2012-08-14 12:54:00 +04:00
|
|
|
{ "pidfile", required_argument, 0, 46},
|
2012-09-02 01:07:32 +04:00
|
|
|
{ "veth-pair", required_argument, 0, 47},
|
2012-09-17 20:05:23 +04:00
|
|
|
{ "action-script", required_argument, 0, 49},
|
2012-09-26 06:39:23 +04:00
|
|
|
{ LREMAP_PARAM, no_argument, 0, 41},
|
2013-03-27 20:11:00 +04:00
|
|
|
{ OPT_SHELL_JOB, no_argument, 0, 'j'},
|
2013-03-27 20:17:59 +04:00
|
|
|
{ OPT_FILE_LOCKS, no_argument, 0, 'l'},
|
2013-03-12 21:23:06 +04:00
|
|
|
{ "page-server", no_argument, 0, 50},
|
|
|
|
{ "address", required_argument, 0, 51},
|
|
|
|
{ "port", required_argument, 0, 52},
|
2013-05-08 15:52:48 +04:00
|
|
|
{ "prev-images-dir", required_argument, 0, 53},
|
2013-04-23 23:38:47 +04:00
|
|
|
{ "ms", no_argument, 0, 54},
|
2013-05-08 15:52:48 +04:00
|
|
|
{ "track-mem", no_argument, 0, 55},
|
2012-04-16 14:23:05 +04:00
|
|
|
{ },
|
|
|
|
};
|
|
|
|
|
2012-07-19 16:50:04 +04:00
|
|
|
opt = getopt_long(argc, argv, short_opts, long_opts, &idx);
|
2012-04-16 14:14:41 +04:00
|
|
|
if (opt == -1)
|
|
|
|
break;
|
|
|
|
|
2011-10-13 19:43:52 +04:00
|
|
|
switch (opt) {
|
ctrools: Rewrite task/threads stopping engine is back
This commit brings the former "Rewrite task/threads stopping engine"
commit back. Handling it separately is too complex so better try
to handle it in-place.
Note some tests might fault, it's expected.
---
Stopping tasks with STOP and proceeding with SEIZE is actually excessive --
the SEIZE if enough. Moreover, just killing a task with STOP is also racy,
since task should be given some time to come to sleep before its proc
can be parsed.
Rewrite all this code to SEIZE task and all its threads from the very beginning.
With this we can distinguish stopped task state and migrate it properly (not
supported now, need to implement).
This thing however has one BIG problem -- after we SEIZE-d a task we should
seize
it's threads, but we should do it in a loop -- reading /proc/pid/task and
seizing
them again and again, until the contents of this dir stops changing (not done
now).
Besides, after we seized a task and all its threads we cannot scan it's children
list once -- task can get reparented to init and any task's child can call clone
with CLONE_PARENT flag thus repopulating the children list of the already seized
task (not done also)
This patch is ugly, yes, but splitting it doesn't help to review it much, sorry
:(
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 19:45:31 +04:00
|
|
|
case 's':
|
2012-03-01 19:09:02 +04:00
|
|
|
opts.final_state = TASK_STOPPED;
|
ctrools: Rewrite task/threads stopping engine is back
This commit brings the former "Rewrite task/threads stopping engine"
commit back. Handling it separately is too complex so better try
to handle it in-place.
Note some tests might fault, it's expected.
---
Stopping tasks with STOP and proceeding with SEIZE is actually excessive --
the SEIZE if enough. Moreover, just killing a task with STOP is also racy,
since task should be given some time to come to sleep before its proc
can be parsed.
Rewrite all this code to SEIZE task and all its threads from the very beginning.
With this we can distinguish stopped task state and migrate it properly (not
supported now, need to implement).
This thing however has one BIG problem -- after we SEIZE-d a task we should
seize
it's threads, but we should do it in a loop -- reading /proc/pid/task and
seizing
them again and again, until the contents of this dir stops changing (not done
now).
Besides, after we seized a task and all its threads we cannot scan it's children
list once -- task can get reparented to init and any task's child can call clone
with CLONE_PARENT flag thus repopulating the children list of the already seized
task (not done also)
This patch is ugly, yes, but splitting it doesn't help to review it much, sorry
:(
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 19:45:31 +04:00
|
|
|
break;
|
2013-04-11 17:50:42 +04:00
|
|
|
case 'R':
|
|
|
|
opts.final_state = TASK_ALIVE;
|
|
|
|
break;
|
2012-04-19 11:48:00 +04:00
|
|
|
case 'x':
|
|
|
|
opts.ext_unix_sk = true;
|
|
|
|
break;
|
2013-04-02 11:58:15 +04:00
|
|
|
case 'p':
|
2011-10-13 19:43:52 +04:00
|
|
|
pid = atoi(optarg);
|
|
|
|
break;
|
2013-04-02 11:58:15 +04:00
|
|
|
case 't':
|
|
|
|
tree_id = atoi(optarg);
|
|
|
|
break;
|
2011-12-05 15:57:47 +04:00
|
|
|
case 'c':
|
|
|
|
opts.show_pages_content = true;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
opts.show_dump_file = optarg;
|
|
|
|
break;
|
2012-08-02 16:07:43 +04:00
|
|
|
case 'r':
|
|
|
|
opts.root = optarg;
|
|
|
|
break;
|
2012-01-18 23:24:37 +04:00
|
|
|
case 'd':
|
|
|
|
opts.restore_detach = true;
|
|
|
|
break;
|
2011-12-07 13:48:00 +04:00
|
|
|
case 'D':
|
2013-11-15 23:04:29 +04:00
|
|
|
imgs_dir = optarg;
|
2011-12-07 13:48:00 +04:00
|
|
|
break;
|
2013-11-15 23:04:26 +04:00
|
|
|
case 'W':
|
2013-11-15 23:04:29 +04:00
|
|
|
work_dir = optarg;
|
2013-11-15 23:04:26 +04:00
|
|
|
break;
|
2011-12-08 18:39:00 +04:00
|
|
|
case 'o':
|
2013-10-10 11:11:05 +04:00
|
|
|
opts.output = optarg;
|
2011-12-08 18:39:00 +04:00
|
|
|
break;
|
2012-01-26 15:27:00 +04:00
|
|
|
case 'n':
|
2012-05-12 02:34:22 +04:00
|
|
|
if (parse_ns_string(optarg))
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2012-01-26 15:27:00 +04:00
|
|
|
break;
|
2012-02-17 22:51:23 +04:00
|
|
|
case 'v':
|
2013-09-14 14:58:23 +04:00
|
|
|
if (optarg) {
|
|
|
|
if (optarg[0] == 'v')
|
|
|
|
/* handle -vvvvv */
|
|
|
|
log_level += strlen(optarg) + 1;
|
|
|
|
else
|
|
|
|
log_level = atoi(optarg);
|
|
|
|
} else
|
2013-06-11 20:12:03 +04:00
|
|
|
log_level++;
|
2012-02-17 22:51:23 +04:00
|
|
|
break;
|
2012-09-26 06:39:23 +04:00
|
|
|
case 41:
|
|
|
|
pr_info("Will allow link remaps on FS\n");
|
|
|
|
opts.link_remap_ok = true;
|
|
|
|
break;
|
2012-04-28 17:15:12 +04:00
|
|
|
case 42:
|
|
|
|
pr_info("Will dump TCP connections\n");
|
|
|
|
opts.tcp_established_ok = true;
|
|
|
|
break;
|
2012-04-28 20:37:54 +04:00
|
|
|
case 43: {
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = atoi(optarg);
|
|
|
|
pr_info("Closing fd %d\n", fd);
|
|
|
|
close(fd);
|
|
|
|
break;
|
|
|
|
}
|
2012-05-02 14:42:00 +04:00
|
|
|
case 44:
|
|
|
|
opts.log_file_per_pid = 1;
|
|
|
|
break;
|
2012-08-07 19:33:49 +04:00
|
|
|
case 45:
|
|
|
|
opts.evasive_devices = true;
|
|
|
|
break;
|
2012-08-14 12:54:00 +04:00
|
|
|
case 46:
|
|
|
|
opts.pidfile = optarg;
|
|
|
|
break;
|
2012-09-02 01:07:32 +04:00
|
|
|
case 47:
|
|
|
|
{
|
|
|
|
struct veth_pair *n;
|
|
|
|
|
|
|
|
n = xmalloc(sizeof(*n));
|
|
|
|
if (n == NULL)
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2012-09-02 01:07:32 +04:00
|
|
|
n->outside = strchr(optarg, '=');
|
|
|
|
if (n->outside == NULL) {
|
|
|
|
xfree(n);
|
2013-04-12 13:00:05 -07:00
|
|
|
pr_err("Invalid argument for --veth-pair\n");
|
2012-09-02 01:07:32 +04:00
|
|
|
goto usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
*n->outside++ = '\0';
|
|
|
|
n->inside = optarg;
|
|
|
|
list_add(&n->node, &opts.veth_pairs);
|
|
|
|
}
|
|
|
|
break;
|
2012-09-17 20:05:23 +04:00
|
|
|
case 49:
|
|
|
|
{
|
|
|
|
struct script *script;
|
|
|
|
|
|
|
|
script = xmalloc(sizeof(struct script));
|
|
|
|
if (script == NULL)
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2012-09-17 20:05:23 +04:00
|
|
|
|
|
|
|
script->path = optarg;
|
|
|
|
list_add(&script->node, &opts.scripts);
|
|
|
|
}
|
|
|
|
break;
|
2013-03-12 21:23:06 +04:00
|
|
|
case 50:
|
|
|
|
opts.use_page_server = true;
|
|
|
|
break;
|
|
|
|
case 51:
|
2013-08-11 12:01:14 +04:00
|
|
|
opts.addr = optarg;
|
2013-03-12 21:23:06 +04:00
|
|
|
break;
|
|
|
|
case 52:
|
2013-08-11 12:01:14 +04:00
|
|
|
opts.ps_port = htons(atoi(optarg));
|
|
|
|
if (!opts.ps_port) {
|
2013-03-12 21:23:06 +04:00
|
|
|
pr_err("Bad port\n");
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2013-03-12 21:23:06 +04:00
|
|
|
}
|
|
|
|
break;
|
2012-10-18 15:51:57 +04:00
|
|
|
case 'j':
|
|
|
|
opts.shell_job = true;
|
|
|
|
break;
|
2013-01-17 16:09:27 +08:00
|
|
|
case 'l':
|
|
|
|
opts.handle_file_locks = true;
|
|
|
|
break;
|
2013-04-11 17:50:42 +04:00
|
|
|
case 53:
|
2013-05-08 15:52:48 +04:00
|
|
|
opts.img_parent = optarg;
|
|
|
|
break;
|
|
|
|
case 55:
|
|
|
|
opts.track_mem = true;
|
2013-04-11 17:50:42 +04:00
|
|
|
break;
|
2013-04-23 23:38:47 +04:00
|
|
|
case 54:
|
|
|
|
opts.check_ms_kernel = true;
|
|
|
|
break;
|
2012-07-19 16:51:58 +04:00
|
|
|
case 'V':
|
2013-09-14 15:00:17 +04:00
|
|
|
pr_msg("Version: %s\n", CRIU_VERSION);
|
2013-09-14 15:01:32 +04:00
|
|
|
if (strcmp(CRIU_GITID, "0"))
|
|
|
|
pr_msg("GitID: %s\n", CRIU_GITID);
|
2012-07-19 16:51:58 +04:00
|
|
|
return 0;
|
2011-10-13 19:43:52 +04:00
|
|
|
case 'h':
|
|
|
|
default:
|
|
|
|
goto usage;
|
|
|
|
}
|
2011-10-04 01:50:19 +04:00
|
|
|
}
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2013-11-15 23:04:29 +04:00
|
|
|
if (work_dir == NULL)
|
|
|
|
work_dir = imgs_dir;
|
|
|
|
|
2012-07-28 09:08:46 +04:00
|
|
|
if (optind >= argc)
|
|
|
|
goto usage;
|
|
|
|
|
2013-11-15 23:04:29 +04:00
|
|
|
/* We must not open imgs dir, if service is called */
|
|
|
|
if (strcmp(argv[optind], "service")) {
|
|
|
|
ret = open_image_dir(imgs_dir);
|
|
|
|
if (ret < 0) {
|
|
|
|
pr_perror("Can't open imgs directory");
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2013-11-15 23:04:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chdir(work_dir)) {
|
|
|
|
pr_perror("Can't change directory to %s", work_dir);
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2013-11-15 23:04:29 +04:00
|
|
|
}
|
|
|
|
|
2013-11-19 22:50:20 +04:00
|
|
|
log_set_loglevel(log_level);
|
|
|
|
|
|
|
|
if (log_init(opts.output))
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2013-11-19 22:50:20 +04:00
|
|
|
|
|
|
|
if (opts.img_parent)
|
|
|
|
pr_info("Will do snapshot from %s\n", opts.img_parent);
|
|
|
|
|
2013-05-08 14:23:22 +04:00
|
|
|
if (!strcmp(argv[optind], "dump")) {
|
2013-04-02 11:58:15 +04:00
|
|
|
if (!tree_id)
|
2012-03-27 11:04:23 +04:00
|
|
|
goto opt_pid_missing;
|
2013-12-13 14:32:18 +04:00
|
|
|
return cr_dump_tasks(tree_id);
|
2013-05-08 14:23:22 +04:00
|
|
|
}
|
|
|
|
|
2013-05-14 12:00:40 +04:00
|
|
|
if (!strcmp(argv[optind], "pre-dump")) {
|
|
|
|
if (!tree_id)
|
|
|
|
goto opt_pid_missing;
|
|
|
|
|
|
|
|
if (!opts.track_mem) {
|
|
|
|
pr_info("Enforcing memory tracking for pre-dump.\n");
|
|
|
|
opts.track_mem = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (opts.final_state == TASK_DEAD) {
|
|
|
|
pr_info("Enforcing tasks run after pre-dump.\n");
|
|
|
|
opts.final_state = TASK_ALIVE;
|
|
|
|
}
|
|
|
|
|
2013-12-12 10:02:28 -08:00
|
|
|
return cr_pre_dump_tasks(tree_id) != 0;
|
2013-05-14 12:00:40 +04:00
|
|
|
}
|
|
|
|
|
2013-05-08 14:23:22 +04:00
|
|
|
if (!strcmp(argv[optind], "restore")) {
|
2013-05-08 13:41:42 +04:00
|
|
|
if (tree_id)
|
|
|
|
pr_warn("Using -t with criu restore is obsoleted\n");
|
2013-12-12 10:02:28 -08:00
|
|
|
return cr_restore_tasks() != 0;
|
2013-05-08 14:23:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(argv[optind], "show"))
|
2013-12-12 10:02:28 -08:00
|
|
|
return cr_show(pid) != 0;
|
2013-05-08 14:23:22 +04:00
|
|
|
|
|
|
|
if (!strcmp(argv[optind], "check"))
|
2013-12-12 10:02:28 -08:00
|
|
|
return cr_check() != 0;
|
2013-05-08 14:23:22 +04:00
|
|
|
|
|
|
|
if (!strcmp(argv[optind], "exec")) {
|
2013-04-02 11:58:15 +04:00
|
|
|
if (!pid)
|
|
|
|
pid = tree_id; /* old usage */
|
2012-12-17 22:56:06 +03:00
|
|
|
if (!pid)
|
|
|
|
goto opt_pid_missing;
|
2013-12-12 10:02:28 -08:00
|
|
|
return cr_exec(pid, argv + optind + 1) != 0;
|
2011-10-13 19:43:52 +04:00
|
|
|
}
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2013-05-08 14:23:22 +04:00
|
|
|
if (!strcmp(argv[optind], "page-server"))
|
2013-12-12 10:02:28 -08:00
|
|
|
return cr_page_server(opts.restore_detach) != 0;
|
2013-05-15 14:42:51 +04:00
|
|
|
|
2013-09-13 13:43:56 +04:00
|
|
|
if (!strcmp(argv[optind], "service"))
|
2013-09-13 13:44:09 +04:00
|
|
|
return cr_service(opts.restore_detach);
|
2013-09-13 13:43:56 +04:00
|
|
|
|
2013-05-15 14:42:51 +04:00
|
|
|
pr_msg("Unknown command \"%s\"\n", argv[optind]);
|
2011-09-23 12:00:45 +04:00
|
|
|
usage:
|
2013-05-14 13:49:44 -07:00
|
|
|
pr_msg("\n"
|
|
|
|
"Usage:\n"
|
2013-05-14 13:49:48 -07:00
|
|
|
" criu dump|pre-dump -t PID [<options>]\n"
|
2013-05-14 13:49:44 -07:00
|
|
|
" criu restore [<options>]\n"
|
|
|
|
" criu show (-D DIR)|(-f FILE) [<options>]\n"
|
|
|
|
" criu check [--ms]\n"
|
|
|
|
" criu exec -p PID <syscall-string>\n"
|
2013-05-15 14:42:08 +04:00
|
|
|
" criu page-server\n"
|
2013-09-13 13:44:09 +04:00
|
|
|
" criu service [<options>]\n"
|
2013-05-14 13:49:44 -07:00
|
|
|
"\n"
|
|
|
|
"Commands:\n"
|
|
|
|
" dump checkpoint a process/tree identified by pid\n"
|
|
|
|
" pre-dump pre-dump task(s) minimizing their frozen time\n"
|
2013-05-14 13:49:46 -07:00
|
|
|
" restore restore a process/tree\n"
|
2013-05-14 13:49:44 -07:00
|
|
|
" show show dump file(s) contents\n"
|
|
|
|
" check checks whether the kernel support is up-to-date\n"
|
|
|
|
" exec execute a system call by other task\n"
|
|
|
|
" page-server launch page server\n"
|
2013-09-13 13:44:09 +04:00
|
|
|
" service launch service\n"
|
2013-05-14 13:49:44 -07:00
|
|
|
);
|
2012-04-29 09:23:12 +04:00
|
|
|
|
2012-12-12 23:49:12 +03:00
|
|
|
if (argc < 2) {
|
|
|
|
pr_msg("\nTry -h|--help for more info\n");
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2012-12-12 23:49:12 +03:00
|
|
|
}
|
|
|
|
|
2013-05-02 02:48:08 -07:00
|
|
|
pr_msg("\n"
|
|
|
|
"Dump/Restore options:\n"
|
|
|
|
"\n"
|
|
|
|
"* Generic:\n"
|
2013-05-14 13:49:46 -07:00
|
|
|
" -t|--tree PID checkpoint a process tree identified by PID\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
" -d|--restore-detached detach after restore\n"
|
2013-05-02 02:48:13 -07:00
|
|
|
" -s|--leave-stopped leave tasks in stopped state after checkpoint\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
" -R|--leave-running leave tasks in running state after checkpoint\n"
|
2013-05-14 13:49:47 -07:00
|
|
|
" -D|--images-dir DIR directory for image files\n"
|
2013-12-12 10:14:24 -08:00
|
|
|
" --pidfile FILE write root task, service or page-server pid to FILE\n"
|
2013-12-12 10:14:23 -08:00
|
|
|
" -W|--work-dir DIR directory to cd and write logs/pidfiles/stats to\n"
|
2013-12-12 10:14:26 -08:00
|
|
|
" (if not specified, value of --images-dir is used)\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
"\n"
|
|
|
|
"* Special resources support:\n"
|
|
|
|
" -x|--" USK_EXT_PARAM " allow external unix connections\n"
|
|
|
|
" --" SK_EST_PARAM " checkpoint/restore established TCP connections\n"
|
2013-05-02 02:48:10 -07:00
|
|
|
" -r|--root PATH change the root filesystem (when run in mount namespace)\n"
|
2013-05-02 02:48:13 -07:00
|
|
|
" --evasive-devices use any path to a device file if the original one\n"
|
|
|
|
" is inaccessible\n"
|
|
|
|
" --veth-pair IN=OUT map inside veth device name to outside one\n"
|
|
|
|
" --link-remap allow to link unlinked files back when possible\n"
|
2013-05-02 02:48:10 -07:00
|
|
|
" --action-script FILE add an external action script\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
" -j|--" OPT_SHELL_JOB " allow to dump and restore shell jobs\n"
|
2013-05-02 02:48:09 -07:00
|
|
|
" -l|--" OPT_FILE_LOCKS " handle file locks, for safety, only used for container\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
"\n"
|
|
|
|
"* Logging:\n"
|
2013-11-15 21:51:19 +04:00
|
|
|
" -o|--log-file FILE log file name\n"
|
2013-05-02 02:48:13 -07:00
|
|
|
" --log-pid enable per-process logging to separate FILE.pid files\n"
|
2013-09-14 14:58:23 +04:00
|
|
|
" -v[NUM] set logging level:\n"
|
2013-06-11 20:12:03 +04:00
|
|
|
" -v0 - messages regardless of log level\n"
|
|
|
|
" -v1, -v - errors, when we are in trouble\n"
|
|
|
|
" -v2, -vv - warnings (default)\n"
|
|
|
|
" -v3, -vvv - informative, everything is fine\n"
|
|
|
|
" -v4, -vvvv - debug only\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
"\n"
|
2013-05-14 12:11:51 +04:00
|
|
|
"* Memory dumping options:\n"
|
|
|
|
" --track-mem turn on memory changes tracker in kernel\n"
|
|
|
|
" --prev-images-dir DIR path to images from previous dump (relative to -D)\n"
|
2013-05-15 14:41:43 +04:00
|
|
|
" --page-server send pages to page server (see options below as well)\n"
|
2013-05-14 12:11:51 +04:00
|
|
|
"\n"
|
2013-12-12 10:14:25 -08:00
|
|
|
"Page/Service server options:\n"
|
2013-09-13 13:44:09 +04:00
|
|
|
" --address ADDR address of server or service\n"
|
2013-05-02 02:48:10 -07:00
|
|
|
" --port PORT port of page server\n"
|
2013-05-20 19:11:19 +04:00
|
|
|
" -d|--daemon run in the background after creating socket\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
"\n"
|
|
|
|
"Show options:\n"
|
2013-05-02 02:48:10 -07:00
|
|
|
" -f|--file FILE show contents of a checkpoint file\n"
|
|
|
|
" -D|--images-dir DIR directory where to get images from\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
" -c|--contents show contents of pages dumped in hexdump format\n"
|
2013-05-02 02:48:10 -07:00
|
|
|
" -p|--pid PID show files relevant to PID (filter -D flood)\n"
|
2013-05-02 02:48:08 -07:00
|
|
|
"\n"
|
|
|
|
"Other options:\n"
|
|
|
|
" -h|--help show this text\n"
|
|
|
|
" -V|--version show version\n"
|
|
|
|
" --ms don't check not yet merged kernel features\n"
|
|
|
|
);
|
2012-07-19 16:50:04 +04:00
|
|
|
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2011-12-20 19:47:06 +04:00
|
|
|
|
|
|
|
opt_pid_missing:
|
2012-07-28 09:09:52 +04:00
|
|
|
pr_msg("No pid specified (-t option missing)\n");
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|