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-12-19 21:35:00 +04:00
|
|
|
#include <dlfcn.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"
|
2013-12-19 21:35:00 +04:00
|
|
|
#include "plugin.h"
|
2014-06-09 17:26:17 +04:00
|
|
|
#include "mount.h"
|
2014-08-15 17:02:21 -05:00
|
|
|
#include "cgroup.h"
|
2014-10-01 18:56:41 +04:00
|
|
|
#include "cpu.h"
|
2014-09-03 23:43:23 +04:00
|
|
|
#include "action-scripts.h"
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2014-08-06 21:56:24 +02:00
|
|
|
#include "setproctitle.h"
|
|
|
|
|
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);
|
2014-06-09 17:26:17 +04:00
|
|
|
INIT_LIST_HEAD(&opts.ext_mounts);
|
Add inherit fd support
There are cases where a process's file descriptor cannot be restored
from the checkpoint images. For example, a pipe file descriptor with
one end in the checkpointed process and the other end in a separate
process (that was not part of the checkpointed process tree) cannot be
restored because after checkpoint the pipe will be broken.
There are also cases where the user wants to use a new file during
restore instead of the original file at checkpoint time. For example,
the user wants to change the log file of a process from /path/to/oldlog
to /path/to/newlog.
In these cases, criu's caller should set up a new file descriptor to be
inherited by the restored process and specify the file descriptor with the
--inherit-fd command line option. The argument of --inherit-fd has the
format fd[%d]:%s, where %d tells criu which of its own file descriptors
to use for restoring the file identified by %s.
As a debugging aid, if the argument has the format debug[%d]:%s, it tells
criu to write out the string after colon to the file descriptor %d. This
can be used, for example, as an easy way to leave a "restore marker"
in the output stream of the process.
It's important to note that inherit fd support breaks applications
that depend on the state of the file descriptor being inherited. So,
consider inherit fd only for specific use cases that you know for sure
won't break the application.
For examples please visit http://criu.org/Category:HOWTO.
v2: Added a check in send_fd_to_self() to avoid closing an inherit fd.
Also, as an extra measure of caution, added checks in the inherit fd
look up functions to make sure that the inherit fd hasn't been reused.
The patch also includes minor cosmetic changes.
Signed-off-by: Saied Kazemi <saied@google.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2014-12-09 23:20:00 +03:00
|
|
|
INIT_LIST_HEAD(&opts.inherit_fds);
|
2014-08-15 17:02:21 -05:00
|
|
|
INIT_LIST_HEAD(&opts.new_cgroup_roots);
|
2014-01-31 13:05:44 +04:00
|
|
|
|
cpuinfo: x86 -- Add dump and validation of cpuinfo image, v2
On Wed, Oct 01, 2014 at 04:57:40PM +0400, Pavel Emelyanov wrote:
> On 10/01/2014 01:07 AM, Cyrill Gorcunov wrote:
> > On Tue, Sep 30, 2014 at 09:18:53PM +0400, Cyrill Gorcunov wrote:
> >> If a user requested criu to dump cpuinfo image then we
> >> write one on dump and verify on restore. At the moment
> >> we require all cpu feature bits to match the destination
> >> cpu in a sake of simplicity, but in future we need deps
> >> engine which would filer out bits and test if cpu we're
> >> restoring on is more capable than one we were dumping at
> >> allowing to proceed restore procedure.
> >>
> >> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> >
> > Updated to new img format
Something like attached?
>From 59272a9514311e6736cddee08d5f88aa95d49189 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov@openvz.org>
Date: Thu, 25 Sep 2014 16:04:10 +0400
Subject: [PATCH] cpuinfo: x86 -- Add dump and validation of cpuinfo image
If a user requested criu to dump cpuinfo image then we
write one on dump and verify on restore. At the moment
we require all cpu feature bits to match the destination
cpu in a sake of simplicity, but in future we need deps
engine which would filer out bits and test if cpu we're
restoring on is more capable than one we were dumping at
allowing to proceed restore procedure.
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2014-10-01 17:53:50 +04:00
|
|
|
opts.cpu_cap = CPU_CAP_DEFAULT;
|
2014-08-06 22:23:00 +04:00
|
|
|
opts.manage_cgroups = false;
|
2014-09-02 00:45:00 +04:00
|
|
|
opts.ps_socket = -1;
|
2013-10-30 02:48:38 +04:00
|
|
|
}
|
|
|
|
|
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:
|
2014-01-08 19:33:04 -08:00
|
|
|
pr_msg("Error: unknown namespace: %s\n", ptr);
|
2012-01-31 22:28:22 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-01-31 13:05:44 +04:00
|
|
|
static int parse_cpu_cap(struct cr_options *opts, const char *optarg)
|
|
|
|
{
|
|
|
|
bool inverse = false;
|
|
|
|
|
|
|
|
#define ____cpu_set_cap(__opts, __cap, __inverse) \
|
|
|
|
do { \
|
|
|
|
if ((__inverse)) \
|
|
|
|
(__opts)->cpu_cap &= ~(__cap); \
|
|
|
|
else \
|
|
|
|
(__opts)->cpu_cap |= (__cap); \
|
|
|
|
} while (0)
|
|
|
|
|
2014-09-30 21:18:44 +04:00
|
|
|
if (!optarg) {
|
|
|
|
____cpu_set_cap(opts, CPU_CAP_ALL, false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-01-31 13:05:44 +04:00
|
|
|
for (; *optarg; optarg++) {
|
|
|
|
if (optarg[0] == '^') {
|
|
|
|
inverse = !inverse;
|
|
|
|
continue;
|
|
|
|
} else if (optarg[0] == ',') {
|
|
|
|
inverse = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncmp(optarg, "fpu", 3))
|
|
|
|
____cpu_set_cap(opts, CPU_CAP_FPU, inverse);
|
2014-09-30 21:18:45 +04:00
|
|
|
else if (!strncmp(optarg, "all", 3))
|
2014-01-31 13:05:44 +04:00
|
|
|
____cpu_set_cap(opts, CPU_CAP_ALL, inverse);
|
2014-09-30 21:18:45 +04:00
|
|
|
else if (!strncmp(optarg, "none", 3))
|
|
|
|
____cpu_set_cap(opts, CPU_CAP_NONE, inverse);
|
|
|
|
else if (!strncmp(optarg, "cpu", 3))
|
|
|
|
____cpu_set_cap(opts, CPU_CAP_CPU, inverse);
|
2014-01-31 13:05:44 +04:00
|
|
|
else
|
|
|
|
goto Esyntax;
|
|
|
|
}
|
|
|
|
#undef ____cpu_set_cap
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
Esyntax:
|
|
|
|
pr_err("Unknown FPU mode `%s' selected\n", optarg);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-08-06 21:56:24 +02:00
|
|
|
int main(int argc, char *argv[], char *envp[])
|
2011-09-23 12:00:45 +04:00
|
|
|
{
|
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;
|
2014-01-08 19:33:05 -08:00
|
|
|
bool usage_error = true;
|
2014-03-22 20:14:00 +04:00
|
|
|
bool has_exec_cmd = false;
|
2011-10-13 19:43:52 +04:00
|
|
|
int opt, idx;
|
2014-02-04 18:03:00 +04:00
|
|
|
int log_level = LOG_UNSET;
|
2013-11-15 23:04:29 +04:00
|
|
|
char *imgs_dir = ".";
|
|
|
|
char *work_dir = NULL;
|
2014-09-10 15:46:06 +04:00
|
|
|
static const char short_opts[] = "dSsRf:F:t:p:hcD:o:n:v::xVr:jlW:L:M:";
|
2014-01-08 19:33:03 -08:00
|
|
|
static struct option long_opts[] = {
|
|
|
|
{ "tree", required_argument, 0, 't' },
|
|
|
|
{ "pid", required_argument, 0, 'p' },
|
|
|
|
{ "leave-stopped", no_argument, 0, 's' },
|
|
|
|
{ "leave-running", no_argument, 0, 'R' },
|
|
|
|
{ "restore-detached", no_argument, 0, 'd' },
|
2014-09-10 15:46:06 +04:00
|
|
|
{ "restore-sibling", no_argument, 0, 'S' },
|
2014-01-08 19:33:03 -08:00
|
|
|
{ "daemon", no_argument, 0, 'd' },
|
|
|
|
{ "contents", no_argument, 0, 'c' },
|
|
|
|
{ "file", required_argument, 0, 'f' },
|
|
|
|
{ "fields", required_argument, 0, 'F' },
|
|
|
|
{ "images-dir", required_argument, 0, 'D' },
|
|
|
|
{ "work-dir", required_argument, 0, 'W' },
|
|
|
|
{ "log-file", required_argument, 0, 'o' },
|
|
|
|
{ "namespaces", required_argument, 0, 'n' },
|
|
|
|
{ "root", required_argument, 0, 'r' },
|
|
|
|
{ USK_EXT_PARAM, no_argument, 0, 'x' },
|
|
|
|
{ "help", no_argument, 0, 'h' },
|
2014-08-26 08:08:00 +04:00
|
|
|
{ SK_EST_PARAM, no_argument, 0, 1042 },
|
|
|
|
{ "close", required_argument, 0, 1043 },
|
|
|
|
{ "log-pid", no_argument, 0, 1044},
|
2014-01-08 19:33:03 -08:00
|
|
|
{ "version", no_argument, 0, 'V'},
|
2014-08-26 08:08:00 +04:00
|
|
|
{ "evasive-devices", no_argument, 0, 1045},
|
|
|
|
{ "pidfile", required_argument, 0, 1046},
|
|
|
|
{ "veth-pair", required_argument, 0, 1047},
|
|
|
|
{ "action-script", required_argument, 0, 1049},
|
|
|
|
{ LREMAP_PARAM, no_argument, 0, 1041},
|
2014-01-08 19:33:03 -08:00
|
|
|
{ OPT_SHELL_JOB, no_argument, 0, 'j'},
|
|
|
|
{ OPT_FILE_LOCKS, no_argument, 0, 'l'},
|
2014-08-26 08:08:00 +04:00
|
|
|
{ "page-server", no_argument, 0, 1050},
|
|
|
|
{ "address", required_argument, 0, 1051},
|
|
|
|
{ "port", required_argument, 0, 1052},
|
|
|
|
{ "prev-images-dir", required_argument, 0, 1053},
|
|
|
|
{ "ms", no_argument, 0, 1054},
|
|
|
|
{ "track-mem", no_argument, 0, 1055},
|
|
|
|
{ "auto-dedup", no_argument, 0, 1056},
|
2014-01-08 19:33:03 -08:00
|
|
|
{ "libdir", required_argument, 0, 'L'},
|
2014-09-30 21:18:44 +04:00
|
|
|
{ "cpu-cap", optional_argument, 0, 1057},
|
2014-08-26 08:08:00 +04:00
|
|
|
{ "force-irmap", no_argument, 0, 1058},
|
2014-06-09 17:26:17 +04:00
|
|
|
{ "ext-mount-map", required_argument, 0, 'M'},
|
2014-08-26 08:08:00 +04:00
|
|
|
{ "exec-cmd", no_argument, 0, 1059},
|
|
|
|
{ "manage-cgroups", no_argument, 0, 1060},
|
|
|
|
{ "cgroup-root", required_argument, 0, 1061},
|
Add inherit fd support
There are cases where a process's file descriptor cannot be restored
from the checkpoint images. For example, a pipe file descriptor with
one end in the checkpointed process and the other end in a separate
process (that was not part of the checkpointed process tree) cannot be
restored because after checkpoint the pipe will be broken.
There are also cases where the user wants to use a new file during
restore instead of the original file at checkpoint time. For example,
the user wants to change the log file of a process from /path/to/oldlog
to /path/to/newlog.
In these cases, criu's caller should set up a new file descriptor to be
inherited by the restored process and specify the file descriptor with the
--inherit-fd command line option. The argument of --inherit-fd has the
format fd[%d]:%s, where %d tells criu which of its own file descriptors
to use for restoring the file identified by %s.
As a debugging aid, if the argument has the format debug[%d]:%s, it tells
criu to write out the string after colon to the file descriptor %d. This
can be used, for example, as an easy way to leave a "restore marker"
in the output stream of the process.
It's important to note that inherit fd support breaks applications
that depend on the state of the file descriptor being inherited. So,
consider inherit fd only for specific use cases that you know for sure
won't break the application.
For examples please visit http://criu.org/Category:HOWTO.
v2: Added a check in send_fd_to_self() to avoid closing an inherit fd.
Also, as an extra measure of caution, added checks in the inherit fd
look up functions to make sure that the inherit fd hasn't been reused.
The patch also includes minor cosmetic changes.
Signed-off-by: Saied Kazemi <saied@google.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2014-12-09 23:20:00 +03:00
|
|
|
{ "inherit-fd", required_argument, 0, 1062},
|
2014-01-08 19:33:03 -08:00
|
|
|
{ },
|
|
|
|
};
|
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();
|
2014-07-14 22:24:24 +04:00
|
|
|
if (restrict_uid(getuid(), getgid()))
|
|
|
|
return 1;
|
2012-08-07 02:00:39 +04:00
|
|
|
|
2014-08-06 21:56:24 +02:00
|
|
|
setproctitle_init(argc, argv, envp);
|
|
|
|
|
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
|
|
|
|
2014-06-30 20:30:44 +04:00
|
|
|
if (!strcmp(argv[1], "swrk")) {
|
2014-06-17 21:08:49 +04:00
|
|
|
/*
|
|
|
|
* This is to start criu service worker from libcriu calls.
|
|
|
|
* The usage is "criu swrk <fd>" and is not for CLI/scripts.
|
|
|
|
* The arguments semantics can change at any tyme with the
|
|
|
|
* corresponding lib call change.
|
|
|
|
*/
|
2014-06-30 20:30:44 +04:00
|
|
|
opts.swrk_restore = true;
|
2014-06-17 21:08:49 +04:00
|
|
|
return cr_service_work(atoi(argv[2]));
|
2014-06-30 20:30:44 +04:00
|
|
|
}
|
2014-06-17 21:08:49 +04:00
|
|
|
|
2012-04-16 14:14:41 +04:00
|
|
|
while (1) {
|
2014-01-08 19:33:03 -08:00
|
|
|
idx = -1;
|
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);
|
2014-01-08 19:33:03 -08:00
|
|
|
if (pid <= 0)
|
|
|
|
goto bad_arg;
|
2011-10-13 19:43:52 +04:00
|
|
|
break;
|
2013-04-02 11:58:15 +04:00
|
|
|
case 't':
|
|
|
|
tree_id = atoi(optarg);
|
2014-01-08 19:33:03 -08:00
|
|
|
if (tree_id <= 0)
|
|
|
|
goto bad_arg;
|
2013-04-02 11:58:15 +04:00
|
|
|
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;
|
2013-12-27 15:58:27 +04:00
|
|
|
case 'F':
|
|
|
|
opts.show_fmt = 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;
|
2014-09-10 15:46:06 +04:00
|
|
|
case 'S':
|
|
|
|
opts.restore_sibling = 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))
|
2014-01-08 19:33:03 -08:00
|
|
|
goto bad_arg;
|
2012-01-26 15:27:00 +04:00
|
|
|
break;
|
2012-02-17 22:51:23 +04:00
|
|
|
case 'v':
|
2014-02-04 18:03:00 +04:00
|
|
|
if (log_level == LOG_UNSET)
|
|
|
|
log_level = 0;
|
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;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1041:
|
2012-09-26 06:39:23 +04:00
|
|
|
pr_info("Will allow link remaps on FS\n");
|
|
|
|
opts.link_remap_ok = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1042:
|
2012-04-28 17:15:12 +04:00
|
|
|
pr_info("Will dump TCP connections\n");
|
|
|
|
opts.tcp_established_ok = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1043: {
|
2012-04-28 20:37:54 +04:00
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = atoi(optarg);
|
|
|
|
pr_info("Closing fd %d\n", fd);
|
|
|
|
close(fd);
|
|
|
|
break;
|
|
|
|
}
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1044:
|
2012-05-02 14:42:00 +04:00
|
|
|
opts.log_file_per_pid = 1;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1045:
|
2012-08-07 19:33:49 +04:00
|
|
|
opts.evasive_devices = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1046:
|
2012-08-14 12:54:00 +04:00
|
|
|
opts.pidfile = optarg;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1047:
|
2012-09-02 01:07:32 +04:00
|
|
|
{
|
2014-02-11 23:53:40 +04:00
|
|
|
char *aux;
|
2012-09-02 01:07:32 +04:00
|
|
|
|
2014-02-11 23:53:40 +04:00
|
|
|
aux = strchr(optarg, '=');
|
|
|
|
if (aux == NULL)
|
2014-01-08 19:33:03 -08:00
|
|
|
goto bad_arg;
|
2012-09-02 01:07:32 +04:00
|
|
|
|
2014-02-11 23:53:40 +04:00
|
|
|
*aux = '\0';
|
|
|
|
if (veth_pair_add(optarg, aux + 1))
|
|
|
|
return 1;
|
2012-09-02 01:07:32 +04:00
|
|
|
}
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1049:
|
2014-09-03 23:43:23 +04:00
|
|
|
if (add_script(optarg, 0))
|
|
|
|
return 1;
|
2012-09-17 20:05:23 +04:00
|
|
|
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1050:
|
2013-03-12 21:23:06 +04:00
|
|
|
opts.use_page_server = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1051:
|
2013-08-11 12:01:14 +04:00
|
|
|
opts.addr = optarg;
|
2013-03-12 21:23:06 +04:00
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1052:
|
2013-08-11 12:01:14 +04:00
|
|
|
opts.ps_port = htons(atoi(optarg));
|
2014-01-08 19:33:03 -08:00
|
|
|
if (!opts.ps_port)
|
|
|
|
goto bad_arg;
|
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;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1053:
|
2013-05-08 15:52:48 +04:00
|
|
|
opts.img_parent = optarg;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1055:
|
2013-05-08 15:52:48 +04:00
|
|
|
opts.track_mem = true;
|
2013-04-11 17:50:42 +04:00
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1056:
|
2013-12-17 19:27:11 +04:00
|
|
|
opts.auto_dedup = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1057:
|
2014-01-31 13:05:44 +04:00
|
|
|
if (parse_cpu_cap(&opts, optarg))
|
|
|
|
goto usage;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1058:
|
2014-03-06 14:56:03 +04:00
|
|
|
opts.force_irmap = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1054:
|
2013-04-23 23:38:47 +04:00
|
|
|
opts.check_ms_kernel = true;
|
|
|
|
break;
|
2013-12-19 21:35:00 +04:00
|
|
|
case 'L':
|
2013-12-26 11:08:54 +04:00
|
|
|
opts.libdir = optarg;
|
2013-12-19 21:35:00 +04:00
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1059:
|
2014-03-22 20:14:00 +04:00
|
|
|
has_exec_cmd = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1060:
|
2014-08-06 22:23:00 +04:00
|
|
|
opts.manage_cgroups = true;
|
|
|
|
break;
|
2014-08-26 08:08:00 +04:00
|
|
|
case 1061:
|
2014-08-15 17:02:21 -05:00
|
|
|
{
|
2014-08-22 16:10:27 +04:00
|
|
|
char *path, *ctl;
|
2014-08-15 17:02:21 -05:00
|
|
|
|
2014-08-22 16:10:27 +04:00
|
|
|
path = strchr(optarg, ':');
|
|
|
|
if (path) {
|
|
|
|
*path = '\0';
|
|
|
|
path++;
|
|
|
|
ctl = optarg;
|
2014-08-15 17:02:21 -05:00
|
|
|
} else {
|
2014-08-22 16:10:27 +04:00
|
|
|
path = optarg;
|
|
|
|
ctl = NULL;
|
2014-08-15 17:02:21 -05:00
|
|
|
}
|
|
|
|
|
2014-08-22 16:10:27 +04:00
|
|
|
if (new_cg_root_add(ctl, path))
|
|
|
|
return -1;
|
2014-08-15 17:02:21 -05:00
|
|
|
}
|
|
|
|
break;
|
Add inherit fd support
There are cases where a process's file descriptor cannot be restored
from the checkpoint images. For example, a pipe file descriptor with
one end in the checkpointed process and the other end in a separate
process (that was not part of the checkpointed process tree) cannot be
restored because after checkpoint the pipe will be broken.
There are also cases where the user wants to use a new file during
restore instead of the original file at checkpoint time. For example,
the user wants to change the log file of a process from /path/to/oldlog
to /path/to/newlog.
In these cases, criu's caller should set up a new file descriptor to be
inherited by the restored process and specify the file descriptor with the
--inherit-fd command line option. The argument of --inherit-fd has the
format fd[%d]:%s, where %d tells criu which of its own file descriptors
to use for restoring the file identified by %s.
As a debugging aid, if the argument has the format debug[%d]:%s, it tells
criu to write out the string after colon to the file descriptor %d. This
can be used, for example, as an easy way to leave a "restore marker"
in the output stream of the process.
It's important to note that inherit fd support breaks applications
that depend on the state of the file descriptor being inherited. So,
consider inherit fd only for specific use cases that you know for sure
won't break the application.
For examples please visit http://criu.org/Category:HOWTO.
v2: Added a check in send_fd_to_self() to avoid closing an inherit fd.
Also, as an extra measure of caution, added checks in the inherit fd
look up functions to make sure that the inherit fd hasn't been reused.
The patch also includes minor cosmetic changes.
Signed-off-by: Saied Kazemi <saied@google.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2014-12-09 23:20:00 +03:00
|
|
|
case 1062:
|
|
|
|
if (inherit_fd_add(optarg) < 0)
|
|
|
|
return 1;
|
|
|
|
break;
|
2014-06-09 17:26:17 +04:00
|
|
|
case 'M':
|
|
|
|
{
|
|
|
|
char *aux;
|
|
|
|
|
|
|
|
aux = strchr(optarg, ':');
|
|
|
|
if (aux == NULL)
|
|
|
|
goto bad_arg;
|
|
|
|
|
|
|
|
*aux = '\0';
|
|
|
|
if (ext_mount_add(optarg, aux + 1))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
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':
|
2014-01-08 19:33:05 -08:00
|
|
|
usage_error = false;
|
|
|
|
goto usage;
|
2011-10-13 19:43:52 +04:00
|
|
|
default:
|
|
|
|
goto usage;
|
|
|
|
}
|
2011-10-04 01:50:19 +04:00
|
|
|
}
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2014-09-10 15:46:06 +04:00
|
|
|
if (!opts.restore_detach && opts.restore_sibling) {
|
|
|
|
pr_msg("--restore-sibling only makes sense with --restore-detach\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-15 23:04:29 +04:00
|
|
|
if (work_dir == NULL)
|
|
|
|
work_dir = imgs_dir;
|
|
|
|
|
2014-01-08 19:33:05 -08:00
|
|
|
if (optind >= argc) {
|
|
|
|
pr_msg("Error: command is required\n");
|
2012-07-28 09:08:46 +04:00
|
|
|
goto usage;
|
2014-01-08 19:33:05 -08:00
|
|
|
}
|
2012-07-28 09:08:46 +04:00
|
|
|
|
2014-03-22 20:14:00 +04:00
|
|
|
if (has_exec_cmd) {
|
|
|
|
if (argc - optind <= 1) {
|
|
|
|
pr_msg("Error: --exec-cmd requires a command\n");
|
|
|
|
goto usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(argv[optind], "restore")) {
|
|
|
|
pr_msg("Error: --exec-cmd is available for the restore command only\n");
|
|
|
|
goto usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (opts.restore_detach) {
|
|
|
|
pr_msg("Error: --restore-detached and --exec-cmd cannot be used together\n");
|
|
|
|
goto usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
opts.exec_cmd = xmalloc((argc - optind) * sizeof(char *));
|
|
|
|
memcpy(opts.exec_cmd, &argv[optind + 1], (argc - optind - 1) * sizeof(char *));
|
|
|
|
opts.exec_cmd[argc - optind - 1] = NULL;
|
|
|
|
}
|
|
|
|
|
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);
|
2014-01-08 19:33:02 -08:00
|
|
|
if (ret < 0)
|
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
|
|
|
|
Add inherit fd support
There are cases where a process's file descriptor cannot be restored
from the checkpoint images. For example, a pipe file descriptor with
one end in the checkpointed process and the other end in a separate
process (that was not part of the checkpointed process tree) cannot be
restored because after checkpoint the pipe will be broken.
There are also cases where the user wants to use a new file during
restore instead of the original file at checkpoint time. For example,
the user wants to change the log file of a process from /path/to/oldlog
to /path/to/newlog.
In these cases, criu's caller should set up a new file descriptor to be
inherited by the restored process and specify the file descriptor with the
--inherit-fd command line option. The argument of --inherit-fd has the
format fd[%d]:%s, where %d tells criu which of its own file descriptors
to use for restoring the file identified by %s.
As a debugging aid, if the argument has the format debug[%d]:%s, it tells
criu to write out the string after colon to the file descriptor %d. This
can be used, for example, as an easy way to leave a "restore marker"
in the output stream of the process.
It's important to note that inherit fd support breaks applications
that depend on the state of the file descriptor being inherited. So,
consider inherit fd only for specific use cases that you know for sure
won't break the application.
For examples please visit http://criu.org/Category:HOWTO.
v2: Added a check in send_fd_to_self() to avoid closing an inherit fd.
Also, as an extra measure of caution, added checks in the inherit fd
look up functions to make sure that the inherit fd hasn't been reused.
The patch also includes minor cosmetic changes.
Signed-off-by: Saied Kazemi <saied@google.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2014-12-09 23:20:00 +03:00
|
|
|
if (!list_empty(&opts.inherit_fds)) {
|
|
|
|
if (strcmp(argv[optind], "restore")) {
|
|
|
|
pr_err("--inherit-fd is restore-only option\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/* now that log file is set up, print inherit fd list */
|
|
|
|
inherit_fd_log();
|
|
|
|
}
|
|
|
|
|
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")) {
|
2014-10-13 13:48:58 +00:00
|
|
|
preload_socket_modules();
|
|
|
|
|
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;
|
|
|
|
|
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");
|
2014-03-22 20:14:00 +04:00
|
|
|
|
|
|
|
ret = cr_restore_tasks();
|
|
|
|
if (ret == 0 && opts.exec_cmd) {
|
|
|
|
close_pid_proc();
|
|
|
|
execvp(opts.exec_cmd[0], opts.exec_cmd);
|
|
|
|
pr_perror("Failed to exec command %s", opts.exec_cmd[0]);
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret != 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"))
|
2014-09-04 20:39:07 +04:00
|
|
|
return cr_page_server(opts.restore_detach, -1) > 0 ? 0 : 1;
|
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-12-17 19:27:07 +04:00
|
|
|
if (!strcmp(argv[optind], "dedup"))
|
|
|
|
return cr_dedup() != 0;
|
|
|
|
|
2014-10-01 18:56:41 +04:00
|
|
|
if (!strcmp(argv[optind], "cpuinfo")) {
|
|
|
|
if (!argv[optind + 1])
|
|
|
|
goto usage;
|
|
|
|
if (!strcmp(argv[optind + 1], "dump"))
|
|
|
|
return cpuinfo_dump();
|
|
|
|
else if (!strcmp(argv[optind + 1], "check"))
|
|
|
|
return cpuinfo_check();
|
|
|
|
}
|
|
|
|
|
2014-01-08 19:33:04 -08:00
|
|
|
pr_msg("Error: 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-12-17 19:27:07 +04:00
|
|
|
" criu dedup\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-12-17 19:27:07 +04:00
|
|
|
" dedup remove duplicates in memory dump\n"
|
2014-10-01 18:56:41 +04:00
|
|
|
" cpuinfo dump writes cpu information into image file\n"
|
|
|
|
" cpuinfo check validates cpu information read from image file\n"
|
2013-05-14 13:49:44 -07:00
|
|
|
);
|
2012-04-29 09:23:12 +04:00
|
|
|
|
2014-01-08 19:33:05 -08:00
|
|
|
if (usage_error) {
|
2012-12-12 23:49:12 +03:00
|
|
|
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"
|
2014-09-10 15:46:06 +04:00
|
|
|
" -S|--restore-sibling restore root task as sibling\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"
|
2014-09-30 21:18:45 +04:00
|
|
|
" --cpu-cap [CAP] require certain cpu capability. CAP: may be one of:\n"
|
|
|
|
" 'cpu','fpu','all','none'. To disable capability, prefix it with '^'.\n"
|
2014-03-22 20:14:00 +04:00
|
|
|
" --exec-cmd execute the command specified after '--' on successful\n"
|
|
|
|
" restore making it the parent of the restored process\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-12-19 21:35:00 +04:00
|
|
|
" -L|--libdir path to a plugin directory (by default " CR_PLUGIN_DEFAULT ")\n"
|
2014-03-06 14:56:03 +04:00
|
|
|
" --force-irmap force resolving names for inotify/fsnotify watches\n"
|
2014-06-09 17:26:17 +04:00
|
|
|
" -M|--ext-mount-map KEY:VALUE\n"
|
|
|
|
" add external mount mapping\n"
|
2014-08-06 22:23:00 +04:00
|
|
|
" --manage-cgroups dump or restore cgroups the process is in\n"
|
2014-08-15 17:02:21 -05:00
|
|
|
" --cgroup-root [controller:]/newroot\n"
|
|
|
|
" change the root cgroup the controller will be\n"
|
|
|
|
" installed into. No controller means that root is the\n"
|
|
|
|
" default for all controllers not specified.\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"
|
2014-01-08 19:36:23 -08:00
|
|
|
" -v[NUM] set logging level (higher level means more output):\n"
|
|
|
|
" -v1|-v - only errors and messages\n"
|
|
|
|
" -v2|-vv - also warnings (default level)\n"
|
2014-01-08 19:36:25 -08:00
|
|
|
" -v3|-vvv - also information messages and timestamps\n"
|
2014-01-08 19:36:23 -08:00
|
|
|
" -v4|-vvvv - lots of debug\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"
|
2014-02-21 18:42:00 +04:00
|
|
|
" --auto-dedup when used on dump it will deduplicate \"old\" data in\n"
|
|
|
|
" pages images of previous dump\n"
|
2014-02-21 18:42:48 +04:00
|
|
|
" when used on restore, as soon as page is restored, it\n"
|
|
|
|
" will be punched from the image.\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"
|
2013-12-27 15:58:27 +04:00
|
|
|
" -F|--fields FIELDS show specified fields (comma separated)\n"
|
2013-05-02 02:48:10 -07:00
|
|
|
" -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
|
|
|
|
2014-01-08 19:33:05 -08:00
|
|
|
return 0;
|
2011-12-20 19:47:06 +04:00
|
|
|
|
|
|
|
opt_pid_missing:
|
2014-01-08 19:33:04 -08:00
|
|
|
pr_msg("Error: pid not specified\n");
|
2013-12-12 10:02:27 -08:00
|
|
|
return 1;
|
2014-01-08 19:33:03 -08:00
|
|
|
|
|
|
|
bad_arg:
|
|
|
|
if (idx < 0) /* short option */
|
|
|
|
pr_msg("Error: invalid argument for -%c: %s\n",
|
|
|
|
opt, optarg);
|
|
|
|
else /* long option */
|
|
|
|
pr_msg("Error: invalid argument for --%s: %s\n",
|
|
|
|
long_opts[idx].name, optarg);
|
|
|
|
return 1;
|
2011-09-23 12:00:45 +04:00
|
|
|
}
|