LCOV - code coverage report
Current view: top level - home/snorch/criu - crtools.c (source / functions) Hit Total Coverage
Test: coverage3.info Lines: 90 194 46.4 %
Date: 2014-04-22 Functions: 2 4 50.0 %
Branches: 58 159 36.5 %

           Branch data     Line data    Source code
       1                 :            : #include <stdio.h>
       2                 :            : #include <stdlib.h>
       3                 :            : #include <limits.h>
       4                 :            : #include <unistd.h>
       5                 :            : #include <errno.h>
       6                 :            : #include <getopt.h>
       7                 :            : #include <string.h>
       8                 :            : #include <ctype.h>
       9                 :            : 
      10                 :            : #include <fcntl.h>
      11                 :            : 
      12                 :            : #include <sys/types.h>
      13                 :            : #include <sys/stat.h>
      14                 :            : 
      15                 :            : #include <sys/socket.h>
      16                 :            : #include <netinet/in.h>
      17                 :            : #include <arpa/inet.h>
      18                 :            : 
      19                 :            : #include <dlfcn.h>
      20                 :            : 
      21                 :            : #include "asm/types.h"
      22                 :            : 
      23                 :            : #include "compiler.h"
      24                 :            : #include "crtools.h"
      25                 :            : #include "cr_options.h"
      26                 :            : #include "sockets.h"
      27                 :            : #include "syscall.h"
      28                 :            : #include "files.h"
      29                 :            : #include "sk-inet.h"
      30                 :            : #include "net.h"
      31                 :            : #include "version.h"
      32                 :            : #include "page-xfer.h"
      33                 :            : #include "tty.h"
      34                 :            : #include "file-lock.h"
      35                 :            : #include "cr-service.h"
      36                 :            : #include "plugin.h"
      37                 :            : 
      38                 :            : struct cr_options opts;
      39                 :            : 
      40                 :       3702 : void init_opts(void)
      41                 :            : {
      42                 :            :         memset(&opts, 0, sizeof(opts));
      43                 :            : 
      44                 :            :         /* Default options */
      45                 :       3702 :         opts.final_state = TASK_DEAD;
      46                 :            :         INIT_LIST_HEAD(&opts.veth_pairs);
      47                 :            :         INIT_LIST_HEAD(&opts.scripts);
      48                 :            : 
      49                 :       3702 :         opts.cpu_cap = CPU_CAP_ALL;
      50                 :       3702 : }
      51                 :            : 
      52                 :          0 : static int parse_ns_string(const char *ptr)
      53                 :            : {
      54                 :          0 :         const char *end = ptr + strlen(ptr);
      55                 :            : 
      56                 :            :         do {
      57         [ #  # ]:          0 :                 if (ptr[3] != ',' && ptr[3] != '\0')
      58                 :            :                         goto bad_ns;
      59         [ #  # ]:          0 :                 if (!strncmp(ptr, "uts", 3))
      60                 :          0 :                         opts.rst_namespaces_flags |= CLONE_NEWUTS;
      61         [ #  # ]:          0 :                 else if (!strncmp(ptr, "ipc", 3))
      62                 :          0 :                         opts.rst_namespaces_flags |= CLONE_NEWIPC;
      63         [ #  # ]:          0 :                 else if (!strncmp(ptr, "mnt", 3))
      64                 :          0 :                         opts.rst_namespaces_flags |= CLONE_NEWNS;
      65         [ #  # ]:          0 :                 else if (!strncmp(ptr, "pid", 3))
      66                 :          0 :                         opts.rst_namespaces_flags |= CLONE_NEWPID;
      67         [ #  # ]:          0 :                 else if (!strncmp(ptr, "net", 3))
      68                 :          0 :                         opts.rst_namespaces_flags |= CLONE_NEWNET;
      69                 :            :                 else
      70                 :            :                         goto bad_ns;
      71                 :          0 :                 ptr += 4;
      72         [ #  # ]:          0 :         } while (ptr < end);
      73                 :            :         return 0;
      74                 :            : 
      75                 :            : bad_ns:
      76                 :          0 :         pr_msg("Error: unknown namespace: %s\n", ptr);
      77                 :          0 :         return -1;
      78                 :            : }
      79                 :            : 
      80                 :          0 : static int parse_cpu_cap(struct cr_options *opts, const char *optarg)
      81                 :            : {
      82                 :            :         bool inverse = false;
      83                 :            : 
      84                 :            : #define ____cpu_set_cap(__opts, __cap, __inverse)       \
      85                 :            :         do {                                            \
      86                 :            :                 if ((__inverse))                        \
      87                 :            :                         (__opts)->cpu_cap &= ~(__cap);   \
      88                 :            :                 else                                    \
      89                 :            :                         (__opts)->cpu_cap |=  (__cap);       \
      90                 :            :         } while (0)
      91                 :            : 
      92         [ #  # ]:          0 :         for (; *optarg; optarg++) {
      93         [ #  # ]:          0 :                 if (optarg[0] == '^') {
      94                 :          0 :                         inverse = !inverse;
      95                 :          0 :                         continue;
      96         [ #  # ]:          0 :                 } else if (optarg[0] == ',') {
      97                 :            :                         inverse = false;
      98                 :          0 :                         continue;
      99                 :            :                 }
     100                 :            : 
     101         [ #  # ]:          0 :                 if (!strncmp(optarg, "fpu", 3))
     102         [ #  # ]:          0 :                         ____cpu_set_cap(opts, CPU_CAP_FPU, inverse);
     103         [ #  # ]:          0 :                 if (!strncmp(optarg, "all", 3))
     104         [ #  # ]:          0 :                         ____cpu_set_cap(opts, CPU_CAP_ALL, inverse);
     105                 :            :                 else
     106                 :            :                         goto Esyntax;
     107                 :            :         }
     108                 :            : #undef ____cpu_set_cap
     109                 :            : 
     110                 :            :         return 0;
     111                 :            : 
     112                 :            : Esyntax:
     113                 :          0 :         pr_err("Unknown FPU mode `%s' selected\n", optarg);
     114                 :            :         return -1;
     115                 :            : }
     116                 :            : 
     117                 :       3702 : int main(int argc, char *argv[])
     118                 :            : {
     119                 :            :         pid_t pid = 0, tree_id = 0;
     120                 :            :         int ret = -1;
     121                 :            :         bool usage_error = true;
     122                 :            :         bool has_exec_cmd = false;
     123                 :            :         int opt, idx;
     124                 :            :         int log_level = LOG_UNSET;
     125                 :            :         char *imgs_dir = ".";
     126                 :            :         char *work_dir = NULL;
     127                 :            :         static const char short_opts[] = "dsRf:F:t:p:hcD:o:n:v::xVr:jlW:L:";
     128                 :            :         static struct option long_opts[] = {
     129                 :            :                 { "tree", required_argument, 0, 't' },
     130                 :            :                 { "pid", required_argument, 0, 'p' },
     131                 :            :                 { "leave-stopped", no_argument, 0, 's' },
     132                 :            :                 { "leave-running", no_argument, 0, 'R' },
     133                 :            :                 { "restore-detached", no_argument, 0, 'd' },
     134                 :            :                 { "daemon", no_argument, 0, 'd' },
     135                 :            :                 { "contents", no_argument, 0, 'c' },
     136                 :            :                 { "file", required_argument, 0, 'f' },
     137                 :            :                 { "fields", required_argument, 0, 'F' },
     138                 :            :                 { "images-dir", required_argument, 0, 'D' },
     139                 :            :                 { "work-dir", required_argument, 0, 'W' },
     140                 :            :                 { "log-file", required_argument, 0, 'o' },
     141                 :            :                 { "namespaces", required_argument, 0, 'n' },
     142                 :            :                 { "root", required_argument, 0, 'r' },
     143                 :            :                 { USK_EXT_PARAM, no_argument, 0, 'x' },
     144                 :            :                 { "help", no_argument, 0, 'h' },
     145                 :            :                 { SK_EST_PARAM, no_argument, 0, 42 },
     146                 :            :                 { "close", required_argument, 0, 43 },
     147                 :            :                 { "log-pid", no_argument, 0, 44},
     148                 :            :                 { "version", no_argument, 0, 'V'},
     149                 :            :                 { "evasive-devices", no_argument, 0, 45},
     150                 :            :                 { "pidfile", required_argument, 0, 46},
     151                 :            :                 { "veth-pair", required_argument, 0, 47},
     152                 :            :                 { "action-script", required_argument, 0, 49},
     153                 :            :                 { LREMAP_PARAM, no_argument, 0, 41},
     154                 :            :                 { OPT_SHELL_JOB, no_argument, 0, 'j'},
     155                 :            :                 { OPT_FILE_LOCKS, no_argument, 0, 'l'},
     156                 :            :                 { "page-server", no_argument, 0, 50},
     157                 :            :                 { "address", required_argument, 0, 51},
     158                 :            :                 { "port", required_argument, 0, 52},
     159                 :            :                 { "prev-images-dir", required_argument, 0, 53},
     160                 :            :                 { "ms", no_argument, 0, 54},
     161                 :            :                 { "track-mem", no_argument, 0, 55},
     162                 :            :                 { "auto-dedup", no_argument, 0, 56},
     163                 :            :                 { "libdir", required_argument, 0, 'L'},
     164                 :            :                 { "cpu-cap", required_argument, 0, 57},
     165                 :            :                 { "force-irmap", no_argument, 0, 58},
     166                 :            :                 { "exec-cmd", no_argument, 0, 59},
     167                 :            :                 { },
     168                 :            :         };
     169                 :            : 
     170                 :            :         BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
     171                 :            : 
     172                 :       3702 :         cr_pb_init();
     173                 :       3702 :         restrict_uid(getuid(), getgid());
     174                 :            : 
     175         [ +  - ]:       3702 :         if (argc < 2)
     176                 :            :                 goto usage;
     177                 :            : 
     178                 :       3702 :         init_opts();
     179                 :            : 
     180         [ +  - ]:       3702 :         if (init_service_fd())
     181                 :            :                 return 1;
     182                 :            : 
     183                 :            :         while (1) {
     184                 :      44470 :                 idx = -1;
     185                 :      44470 :                 opt = getopt_long(argc, argv, short_opts, long_opts, &idx);
     186         [ +  + ]:      44470 :                 if (opt == -1)
     187                 :            :                         break;
     188                 :            : 
     189   [ -  -  +  +  :      40768 :                 switch (opt) {
          -  +  -  -  -  
          +  +  +  -  +  
          -  +  +  +  -  
          -  +  +  -  +  
          +  +  +  -  +  
          +  +  +  -  -  
             -  +  -  -  
                      - ]
     190                 :            :                 case 's':
     191                 :          0 :                         opts.final_state = TASK_STOPPED;
     192                 :          0 :                         break;
     193                 :            :                 case 'R':
     194                 :       1344 :                         opts.final_state = TASK_ALIVE;
     195                 :       1344 :                         break;
     196                 :            :                 case 'x':
     197                 :       2804 :                         opts.ext_unix_sk = true;
     198                 :       2804 :                         break;
     199                 :            :                 case 'p':
     200                 :          0 :                         pid = atoi(optarg);
     201         [ #  # ]:          0 :                         if (pid <= 0)
     202                 :            :                                 goto bad_arg;
     203                 :            :                         break;
     204                 :            :                 case 't':
     205                 :       1792 :                         tree_id = atoi(optarg);
     206         [ +  - ]:       1792 :                         if (tree_id <= 0)
     207                 :            :                                 goto bad_arg;
     208                 :            :                         break;
     209                 :            :                 case 'c':
     210                 :          0 :                         opts.show_pages_content = true;
     211                 :          0 :                         break;
     212                 :            :                 case 'f':
     213                 :          0 :                         opts.show_dump_file = optarg;
     214                 :          0 :                         break;
     215                 :            :                 case 'F':
     216                 :          0 :                         opts.show_fmt = optarg;
     217                 :          0 :                         break;
     218                 :            :                 case 'r':
     219                 :       1260 :                         opts.root = optarg;
     220                 :       1260 :                         break;
     221                 :            :                 case 'd':
     222                 :       1908 :                         opts.restore_detach = true;
     223                 :       1908 :                         break;
     224                 :            :                 case 'D':
     225                 :       3700 :                         imgs_dir = optarg;
     226                 :       3700 :                         break;
     227                 :            :                 case 'W':
     228                 :          0 :                         work_dir = optarg;
     229                 :          0 :                         break;
     230                 :            :                 case 'o':
     231                 :       3700 :                         opts.output = optarg;
     232                 :       3700 :                         break;
     233                 :            :                 case 'n':
     234         [ #  # ]:          0 :                         if (parse_ns_string(optarg))
     235                 :            :                                 goto bad_arg;
     236                 :            :                         break;
     237                 :            :                 case 'v':
     238         [ +  - ]:       3700 :                         if (log_level == LOG_UNSET)
     239                 :            :                                 log_level = 0;
     240         [ +  - ]:       3700 :                         if (optarg) {
     241         [ -  + ]:       3700 :                                 if (optarg[0] == 'v')
     242                 :            :                                         /* handle -vvvvv */
     243                 :          0 :                                         log_level += strlen(optarg) + 1;
     244                 :            :                                 else
     245                 :            :                                         log_level = atoi(optarg);
     246                 :            :                         } else
     247                 :          0 :                                 log_level++;
     248                 :            :                         break;
     249                 :            :                 case 41:
     250                 :        112 :                         pr_info("Will allow link remaps on FS\n");
     251                 :        112 :                         opts.link_remap_ok = true;
     252                 :        112 :                         break;
     253                 :            :                 case 42:
     254                 :       2804 :                         pr_info("Will dump TCP connections\n");
     255                 :       2804 :                         opts.tcp_established_ok = true;
     256                 :       2804 :                         break;
     257                 :            :                 case 43: {
     258                 :            :                         int fd;
     259                 :            : 
     260                 :          0 :                         fd = atoi(optarg);
     261                 :          0 :                         pr_info("Closing fd %d\n", fd);
     262                 :          0 :                         close(fd);
     263                 :      40768 :                         break;
     264                 :            :                 }
     265                 :            :                 case 44:
     266                 :          0 :                         opts.log_file_per_pid = 1;
     267                 :          0 :                         break;
     268                 :            :                 case 45:
     269                 :       1792 :                         opts.evasive_devices = true;
     270                 :       1792 :                         break;
     271                 :            :                 case 46:
     272                 :       1260 :                         opts.pidfile = optarg;
     273                 :       1260 :                         break;
     274                 :            :                 case 47:
     275                 :            :                         {
     276                 :            :                                 char *aux;
     277                 :            : 
     278                 :          0 :                                 aux = strchr(optarg, '=');
     279         [ #  # ]:          0 :                                 if (aux == NULL)
     280                 :            :                                         goto bad_arg;
     281                 :            : 
     282                 :          0 :                                 *aux = '\0';
     283         [ #  # ]:          0 :                                 if (veth_pair_add(optarg, aux + 1))
     284                 :            :                                         return 1;
     285                 :            :                         }
     286                 :            :                         break;
     287                 :            :                 case 49:
     288                 :            :                         {
     289                 :            :                                 struct script *script;
     290                 :            : 
     291         [ -  + ]:       1344 :                                 script = xmalloc(sizeof(struct script));
     292         [ +  - ]:       1344 :                                 if (script == NULL)
     293                 :            :                                         return 1;
     294                 :            : 
     295                 :       1344 :                                 script->path = optarg;
     296                 :       1344 :                                 list_add(&script->node, &opts.scripts);
     297                 :            :                         }
     298                 :            :                         break;
     299                 :            :                 case 50:
     300                 :        896 :                         opts.use_page_server = true;
     301                 :        896 :                         break;
     302                 :            :                 case 51:
     303                 :        896 :                         opts.addr = optarg;
     304                 :        896 :                         break;
     305                 :            :                 case 52:
     306         [ -  + ]:       1792 :                         opts.ps_port = htons(atoi(optarg));
     307         [ +  - ]:       1792 :                         if (!opts.ps_port)
     308                 :            :                                 goto bad_arg;
     309                 :            :                         break;
     310                 :            :                 case 'j':
     311                 :          0 :                         opts.shell_job = true;
     312                 :          0 :                         break;
     313                 :            :                 case 'l':
     314                 :       2804 :                         opts.handle_file_locks = true;
     315                 :       2804 :                         break;
     316                 :            :                 case 53:
     317                 :       1344 :                         opts.img_parent = optarg;
     318                 :       1344 :                         break;
     319                 :            :                 case 55:
     320                 :       1792 :                         opts.track_mem = true;
     321                 :       1792 :                         break;
     322                 :            :                 case 56:
     323                 :       3700 :                         opts.auto_dedup = true;
     324                 :       3700 :                         break;
     325                 :            :                 case 57:
     326         [ #  # ]:          0 :                         if (parse_cpu_cap(&opts, optarg))
     327                 :            :                                 goto usage;
     328                 :            :                         break;
     329                 :            :                 case 58:
     330                 :          0 :                         opts.force_irmap = true;
     331                 :          0 :                         break;
     332                 :            :                 case 54:
     333                 :          0 :                         opts.check_ms_kernel = true;
     334                 :          0 :                         break;
     335                 :            :                 case 'L':
     336                 :         24 :                         opts.libdir = optarg;
     337                 :         24 :                         break;
     338                 :            :                 case 59:
     339                 :            :                         has_exec_cmd = true;
     340                 :            :                         break;
     341                 :            :                 case 'V':
     342                 :          0 :                         pr_msg("Version: %s\n", CRIU_VERSION);
     343                 :            :                         if (strcmp(CRIU_GITID, "0"))
     344                 :          0 :                                 pr_msg("GitID: %s\n", CRIU_GITID);
     345                 :          0 :                         return 0;
     346                 :            :                 case 'h':
     347                 :            :                         usage_error = false;
     348                 :          0 :                         goto usage;
     349                 :            :                 default:
     350                 :            :                         goto usage;
     351                 :            :                 }
     352                 :            :         }
     353                 :            : 
     354         [ +  - ]:       3702 :         if (work_dir == NULL)
     355                 :            :                 work_dir = imgs_dir;
     356                 :            : 
     357         [ -  + ]:       3702 :         if (optind >= argc) {
     358                 :          0 :                 pr_msg("Error: command is required\n");
     359                 :          0 :                 goto usage;
     360                 :            :         }
     361                 :            : 
     362         [ -  + ]:       3702 :         if (has_exec_cmd) {
     363         [ #  # ]:          0 :                 if (argc - optind <= 1) {
     364                 :          0 :                         pr_msg("Error: --exec-cmd requires a command\n");
     365                 :          0 :                         goto usage;
     366                 :            :                 }
     367                 :            : 
     368         [ #  # ]:          0 :                 if (strcmp(argv[optind], "restore")) {
     369                 :          0 :                         pr_msg("Error: --exec-cmd is available for the restore command only\n");
     370                 :          0 :                         goto usage;
     371                 :            :                 }
     372                 :            : 
     373         [ #  # ]:          0 :                 if (opts.restore_detach) {
     374                 :          0 :                         pr_msg("Error: --restore-detached and --exec-cmd cannot be used together\n");
     375                 :          0 :                         goto usage;
     376                 :            :                 }
     377                 :            : 
     378         [ #  # ]:          0 :                 opts.exec_cmd = xmalloc((argc - optind) * sizeof(char *));
     379                 :          0 :                 memcpy(opts.exec_cmd, &argv[optind + 1], (argc - optind - 1) * sizeof(char *));
     380                 :          0 :                 opts.exec_cmd[argc - optind - 1] = NULL;
     381                 :            :         }
     382                 :            : 
     383                 :            :         /* We must not open imgs dir, if service is called */
     384         [ +  - ]:       3702 :         if (strcmp(argv[optind], "service")) {
     385                 :       3702 :                 ret = open_image_dir(imgs_dir);
     386         [ +  - ]:       3702 :                 if (ret < 0)
     387                 :            :                         return 1;
     388                 :            :         }
     389                 :            : 
     390         [ -  + ]:       3702 :         if (chdir(work_dir)) {
     391                 :          0 :                 pr_perror("Can't change directory to %s", work_dir);
     392                 :          0 :                 return 1;
     393                 :            :         }
     394                 :            : 
     395                 :       3702 :         log_set_loglevel(log_level);
     396                 :            : 
     397         [ +  - ]:       3702 :         if (log_init(opts.output))
     398                 :            :                 return 1;
     399                 :            : 
     400         [ +  + ]:       3702 :         if (opts.img_parent)
     401                 :       1344 :                 pr_info("Will do snapshot from %s\n", opts.img_parent);
     402                 :            : 
     403         [ +  + ]:       3702 :         if (!strcmp(argv[optind], "dump")) {
     404         [ +  - ]:        448 :                 if (!tree_id)
     405                 :            :                         goto opt_pid_missing;
     406                 :        448 :                 return cr_dump_tasks(tree_id);
     407                 :            :         }
     408                 :            : 
     409         [ +  + ]:       3254 :         if (!strcmp(argv[optind], "pre-dump")) {
     410         [ +  - ]:       1344 :                 if (!tree_id)
     411                 :            :                         goto opt_pid_missing;
     412                 :            : 
     413                 :       1344 :                 return cr_pre_dump_tasks(tree_id) != 0;
     414                 :            :         }
     415                 :            : 
     416         [ +  + ]:       1910 :         if (!strcmp(argv[optind], "restore")) {
     417         [ -  + ]:       1012 :                 if (tree_id)
     418                 :          0 :                         pr_warn("Using -t with criu restore is obsoleted\n");
     419                 :            : 
     420                 :       1012 :                 ret = cr_restore_tasks();
     421 [ +  - ][ -  + ]:        448 :                 if (ret == 0 && opts.exec_cmd) {
     422                 :          0 :                         close_pid_proc();
     423                 :          0 :                         execvp(opts.exec_cmd[0], opts.exec_cmd);
     424                 :          0 :                         pr_perror("Failed to exec command %s", opts.exec_cmd[0]);
     425                 :            :                         ret = 1;
     426                 :            :                 }
     427                 :            : 
     428                 :        448 :                 return ret != 0;
     429                 :            :         }
     430                 :            : 
     431         [ -  + ]:        898 :         if (!strcmp(argv[optind], "show"))
     432                 :          0 :                 return cr_show(pid) != 0;
     433                 :            : 
     434         [ +  + ]:        898 :         if (!strcmp(argv[optind], "check"))
     435                 :          2 :                 return cr_check() != 0;
     436                 :            : 
     437         [ -  + ]:        896 :         if (!strcmp(argv[optind], "exec")) {
     438         [ #  # ]:          0 :                 if (!pid)
     439                 :            :                         pid = tree_id; /* old usage */
     440         [ #  # ]:          0 :                 if (!pid)
     441                 :            :                         goto opt_pid_missing;
     442                 :          0 :                 return cr_exec(pid, argv + optind + 1) != 0;
     443                 :            :         }
     444                 :            : 
     445         [ +  - ]:        896 :         if (!strcmp(argv[optind], "page-server"))
     446                 :        896 :                 return cr_page_server(opts.restore_detach) > 0 ? 0 : 1;
     447                 :            : 
     448         [ #  # ]:          0 :         if (!strcmp(argv[optind], "service"))
     449                 :          0 :                 return cr_service(opts.restore_detach);
     450                 :            : 
     451         [ #  # ]:          0 :         if (!strcmp(argv[optind], "dedup"))
     452                 :          0 :                 return cr_dedup() != 0;
     453                 :            : 
     454                 :          0 :         pr_msg("Error: unknown command: %s\n", argv[optind]);
     455                 :            : usage:
     456                 :          0 :         pr_msg("\n"
     457                 :            : "Usage:\n"
     458                 :            : "  criu dump|pre-dump -t PID [<options>]\n"
     459                 :            : "  criu restore [<options>]\n"
     460                 :            : "  criu show (-D DIR)|(-f FILE) [<options>]\n"
     461                 :            : "  criu check [--ms]\n"
     462                 :            : "  criu exec -p PID <syscall-string>\n"
     463                 :            : "  criu page-server\n"
     464                 :            : "  criu service [<options>]\n"
     465                 :            : "  criu dedup\n"
     466                 :            : "\n"
     467                 :            : "Commands:\n"
     468                 :            : "  dump           checkpoint a process/tree identified by pid\n"
     469                 :            : "  pre-dump       pre-dump task(s) minimizing their frozen time\n"
     470                 :            : "  restore        restore a process/tree\n"
     471                 :            : "  show           show dump file(s) contents\n"
     472                 :            : "  check          checks whether the kernel support is up-to-date\n"
     473                 :            : "  exec           execute a system call by other task\n"
     474                 :            : "  page-server    launch page server\n"
     475                 :            : "  service        launch service\n"
     476                 :            : "  dedup          remove duplicates in memory dump\n"
     477                 :            :         );
     478                 :            : 
     479         [ #  # ]:          0 :         if (usage_error) {
     480                 :          0 :                 pr_msg("\nTry -h|--help for more info\n");
     481                 :          0 :                 return 1;
     482                 :            :         }
     483                 :            : 
     484                 :          0 :         pr_msg("\n"
     485                 :            : "Dump/Restore options:\n"
     486                 :            : "\n"
     487                 :            : "* Generic:\n"
     488                 :            : "  -t|--tree PID         checkpoint a process tree identified by PID\n"
     489                 :            : "  -d|--restore-detached detach after restore\n"
     490                 :            : "  -s|--leave-stopped    leave tasks in stopped state after checkpoint\n"
     491                 :            : "  -R|--leave-running    leave tasks in running state after checkpoint\n"
     492                 :            : "  -D|--images-dir DIR   directory for image files\n"
     493                 :            : "     --pidfile FILE     write root task, service or page-server pid to FILE\n"
     494                 :            : "  -W|--work-dir DIR     directory to cd and write logs/pidfiles/stats to\n"
     495                 :            : "                        (if not specified, value of --images-dir is used)\n"
     496                 :            : "     --cpu-cap CAP      require certain cpu capability. CAP: may be one of:\n"
     497                 :            : "                        'fpu','all'. To disable capability, prefix it with '^'.\n"
     498                 :            : "     --exec-cmd         execute the command specified after '--' on successful\n"
     499                 :            : "                        restore making it the parent of the restored process\n"
     500                 :            : "\n"
     501                 :            : "* Special resources support:\n"
     502                 :            : "  -x|--" USK_EXT_PARAM "      allow external unix connections\n"
     503                 :            : "     --" SK_EST_PARAM "  checkpoint/restore established TCP connections\n"
     504                 :            : "  -r|--root PATH        change the root filesystem (when run in mount namespace)\n"
     505                 :            : "  --evasive-devices     use any path to a device file if the original one\n"
     506                 :            : "                        is inaccessible\n"
     507                 :            : "  --veth-pair IN=OUT    map inside veth device name to outside one\n"
     508                 :            : "  --link-remap          allow to link unlinked files back when possible\n"
     509                 :            : "  --action-script FILE  add an external action script\n"
     510                 :            : "  -j|--" OPT_SHELL_JOB "        allow to dump and restore shell jobs\n"
     511                 :            : "  -l|--" OPT_FILE_LOCKS "       handle file locks, for safety, only used for container\n"
     512                 :            : "  -L|--libdir           path to a plugin directory (by default " CR_PLUGIN_DEFAULT ")\n"
     513                 :            : "  --force-irmap         force resolving names for inotify/fsnotify watches\n"
     514                 :            : "\n"
     515                 :            : "* Logging:\n"
     516                 :            : "  -o|--log-file FILE    log file name\n"
     517                 :            : "     --log-pid          enable per-process logging to separate FILE.pid files\n"
     518                 :            : "  -v[NUM]               set logging level (higher level means more output):\n"
     519                 :            : "                          -v1|-v    - only errors and messages\n"
     520                 :            : "                          -v2|-vv   - also warnings (default level)\n"
     521                 :            : "                          -v3|-vvv  - also information messages and timestamps\n"
     522                 :            : "                          -v4|-vvvv - lots of debug\n"
     523                 :            : "\n"
     524                 :            : "* Memory dumping options:\n"
     525                 :            : "  --track-mem           turn on memory changes tracker in kernel\n"
     526                 :            : "  --prev-images-dir DIR path to images from previous dump (relative to -D)\n"
     527                 :            : "  --page-server         send pages to page server (see options below as well)\n"
     528                 :            : "  --auto-dedup          when used on dump it will deduplicate \"old\" data in\n"
     529                 :            : "                        pages images of previous dump\n"
     530                 :            : "                        when used on restore, as soon as page is restored, it\n"
     531                 :            : "                        will be punched from the image.\n"
     532                 :            : "\n"
     533                 :            : "Page/Service server options:\n"
     534                 :            : "  --address ADDR        address of server or service\n"
     535                 :            : "  --port PORT           port of page server\n"
     536                 :            : "  -d|--daemon           run in the background after creating socket\n"
     537                 :            : "\n"
     538                 :            : "Show options:\n"
     539                 :            : "  -f|--file FILE        show contents of a checkpoint file\n"
     540                 :            : "  -F|--fields FIELDS    show specified fields (comma separated)\n"
     541                 :            : "  -D|--images-dir DIR   directory where to get images from\n"
     542                 :            : "  -c|--contents         show contents of pages dumped in hexdump format\n"
     543                 :            : "  -p|--pid PID          show files relevant to PID (filter -D flood)\n"
     544                 :            : "\n"
     545                 :            : "Other options:\n"
     546                 :            : "  -h|--help             show this text\n"
     547                 :            : "  -V|--version          show version\n"
     548                 :            : "     --ms               don't check not yet merged kernel features\n"
     549                 :            :         );
     550                 :            : 
     551                 :          0 :         return 0;
     552                 :            : 
     553                 :            : opt_pid_missing:
     554                 :          0 :         pr_msg("Error: pid not specified\n");
     555                 :          0 :         return 1;
     556                 :            : 
     557                 :            : bad_arg:
     558         [ #  # ]:          0 :         if (idx < 0) /* short option */
     559                 :          0 :                 pr_msg("Error: invalid argument for -%c: %s\n",
     560                 :            :                                 opt, optarg);
     561                 :            :         else /* long option */
     562                 :          0 :                 pr_msg("Error: invalid argument for --%s: %s\n",
     563                 :            :                                 long_opts[idx].name, optarg);
     564                 :            :         return 1;
     565                 :            : }

Generated by: LCOV version 1.9