diff --git a/configure.ac b/configure.ac index 1ba5b61bf..7628a9306 100644 --- a/configure.ac +++ b/configure.ac @@ -252,6 +252,8 @@ AS_IF([test "x$enable_criu" != "xno"], [ AC_MSG_NOTICE([CRIU version doesn't support join-ns API])]) PKG_CHECK_MODULES([CRIU_PRE_DUMP], [criu > 3.16.1], [have_criu_pre_dump="yes"], [have_criu_pre_dump="no" AC_MSG_NOTICE([CRIU version doesn't support for pre-dumping])]) + PKG_CHECK_MODULES([CRIU_NETWORK_LOCK_SKIP], [criu >= 3.19], [have_criu_network_lock_skip="yes"], [have_criu_network_lock_skip="no" + AC_MSG_NOTICE([CRIU version doesn't support CRIU_NETWORK_LOCK_SKIP])]) AS_IF([test "$have_criu" = "yes"], [ AC_DEFINE([HAVE_CRIU], 1, [Define if CRIU is available]) ]) @@ -261,6 +263,10 @@ AS_IF([test "x$enable_criu" != "xno"], [ AS_IF([test "$have_criu_pre_dump" = "yes"], [ AC_DEFINE([CRIU_PRE_DUMP_SUPPORT], 1, [Define if CRIU pre-dump support is available]) ]) + AS_IF([test "$have_criu_network_lock_skip" = "yes"], [ + AC_DEFINE([CRIU_NETWORK_LOCK_SKIP_SUPPORT], 1, [Define if CRIU_NETWORK_LOCK_SKIP is available]) + ]) + ], [AC_MSG_NOTICE([CRIU support disabled per user request])]) FOUND_LIBS=$LIBS diff --git a/src/checkpoint.c b/src/checkpoint.c index 0cee27ac1..c734193d6 100644 --- a/src/checkpoint.c +++ b/src/checkpoint.c @@ -44,6 +44,7 @@ enum OPTION_SHELL_JOB, OPTION_EXT_UNIX_SK, OPTION_FILE_LOCKS, + OPTION_NETWORK_LOCK_METHOD, OPTION_PARENT_PATH, OPTION_PRE_DUMP, OPTION_MANAGE_CGROUPS_MODE, @@ -61,6 +62,7 @@ static struct argp_option options[] { "ext-unix-sk", OPTION_EXT_UNIX_SK, 0, 0, "allow external unix sockets", 0 }, { "shell-job", OPTION_SHELL_JOB, 0, 0, "allow shell jobs", 0 }, { "file-locks", OPTION_FILE_LOCKS, 0, 0, "allow file locks", 0 }, + { "network-lock", OPTION_NETWORK_LOCK_METHOD, 0, 0, "set network lock method", 0 }, #ifdef CRIU_PRE_DUMP_SUPPORT { "parent-path", OPTION_PARENT_PATH, "DIR", 0, "path for previous criu image files in pre-dump", 0 }, { "pre-dump", OPTION_PRE_DUMP, 0, 0, "dump container's memory information only, leave the container running after this", 0 }, @@ -72,6 +74,25 @@ static struct argp_option options[] static char args_doc[] = "checkpoint CONTAINER"; +int +crun_parse_network_lock_method (char *param arg_unused) +{ +#if HAVE_CRIU && HAVE_DLOPEN + if (strcmp (param, "iptables") == 0) + return CRIU_NETWORK_LOCK_IPTABLES; + else if (strcmp (param, "nftables") == 0) + return CRIU_NETWORK_LOCK_NFTABLES; +# if CRIU_NETWORK_LOCK_SKIP_SUPPORT + else if (strcmp (param, "skip") == 0) + return CRIU_NETWORK_LOCK_SKIP; +# endif + else + libcrun_fail_with_error (0, "unknown network lock method specified"); +#else + return 0; +#endif +} + int crun_parse_manage_cgroups_mode (char *param arg_unused) { @@ -139,6 +160,10 @@ parse_opt (int key, char *arg, struct argp_state *state) cr_options.manage_cgroups_mode = crun_parse_manage_cgroups_mode (argp_mandatory_argument (arg, state)); break; + case OPTION_NETWORK_LOCK_METHOD: + cr_options.network_lock_method = crun_parse_network_lock_method (argp_mandatory_argument (arg, state)); + break; + default: return ARGP_ERR_UNKNOWN; } diff --git a/src/checkpoint.h b/src/checkpoint.h index 21230a2c4..8a34096b1 100644 --- a/src/checkpoint.h +++ b/src/checkpoint.h @@ -21,6 +21,7 @@ #include "crun.h" int crun_parse_manage_cgroups_mode (char *param); +int crun_parse_network_lock_method (char *param); int crun_command_checkpoint (struct crun_global_arguments *global_args, int argc, char **argv, libcrun_error_t *error); #endif diff --git a/src/libcrun/container.h b/src/libcrun/container.h index a80036331..ccae7bf47 100644 --- a/src/libcrun/container.h +++ b/src/libcrun/container.h @@ -187,6 +187,7 @@ struct libcrun_checkpoint_restore_s char *parent_path; bool pre_dump; int manage_cgroups_mode; + int network_lock_method; char *lsm_profile; char *lsm_mount_context; }; diff --git a/src/libcrun/criu.c b/src/libcrun/criu.c index be2ed43fb..2e4e0d9da 100644 --- a/src/libcrun/criu.c +++ b/src/libcrun/criu.c @@ -79,6 +79,7 @@ struct libcriu_wrapper_s void (*criu_set_leave_running) (bool leave_running); void (*criu_set_manage_cgroups) (bool manage); void (*criu_set_manage_cgroups_mode) (enum criu_cg_mode mode); + void (*criu_set_network_lock) (enum criu_network_lock_method method); void (*criu_set_notify_cb) (int (*cb) (char *action, criu_notify_arg_t na)); void (*criu_set_orphan_pts_master) (bool orphan_pts_master); void (*criu_set_images_dir_fd) (int fd); @@ -163,6 +164,7 @@ load_wrapper (struct libcriu_wrapper_s **wrapper_out, libcrun_error_t *err) LOAD_CRIU_FUNCTION (criu_set_log_level, false); LOAD_CRIU_FUNCTION (criu_set_manage_cgroups, false); LOAD_CRIU_FUNCTION (criu_set_manage_cgroups_mode, false); + LOAD_CRIU_FUNCTION (criu_set_network_lock, true); LOAD_CRIU_FUNCTION (criu_set_notify_cb, false); LOAD_CRIU_FUNCTION (criu_set_orphan_pts_master, false); LOAD_CRIU_FUNCTION (criu_set_parent_images, false); @@ -645,6 +647,9 @@ libcrun_container_checkpoint_linux_criu (libcrun_container_status_t *status, lib libcriu_wrapper->criu_set_manage_cgroups_mode (cr_options->manage_cgroups_mode); libcriu_wrapper->criu_set_manage_cgroups (true); + if (libcriu_wrapper->criu_set_network_lock) + libcriu_wrapper->criu_set_network_lock (cr_options->network_lock_method); + ret = libcriu_wrapper->criu_dump (); if (UNLIKELY (ret != 0)) return crun_make_error (err, 0, @@ -979,6 +984,7 @@ libcrun_container_restore_linux_criu (libcrun_container_status_t *status, libcru libcriu_wrapper->criu_set_file_locks (cr_options->file_locks); libcriu_wrapper->criu_set_orphan_pts_master (true); libcriu_wrapper->criu_set_manage_cgroups (true); + libcriu_wrapper->criu_set_network_lock (cr_options->network_lock_method); libcriu_wrapper->criu_set_log_level (4); libcriu_wrapper->criu_set_log_file (CRIU_RESTORE_LOG_FILE); diff --git a/src/restore.c b/src/restore.c index f83f1fb13..cb8fad2ef 100644 --- a/src/restore.c +++ b/src/restore.c @@ -44,6 +44,7 @@ enum OPTION_CONSOLE_SOCKET, OPTION_FILE_LOCKS, OPTION_MANAGE_CGROUPS_MODE, + OPTION_NETWORK_LOCK_METHOD, OPTION_LSM_PROFILE, OPTION_LSM_MOUNT_CONTEXT, }; @@ -69,6 +70,7 @@ static struct argp_option options[] "path to a socket that will receive the ptmx end of the tty", 0 }, { "file-locks", OPTION_FILE_LOCKS, 0, 0, "allow file locks", 0 }, { "manage-cgroups-mode", OPTION_MANAGE_CGROUPS_MODE, "MODE", 0, "cgroups mode: 'soft' (default), 'ignore', 'full' and 'strict'", 0 }, + { "network-lock", OPTION_NETWORK_LOCK_METHOD, 0, 0, "set network lock method", 0 }, { "lsm-profile", OPTION_LSM_PROFILE, "VALUE", 0, "Specify an LSM profile to be used during restore in the form of TYPE:NAME", 0 }, { "lsm-mount-context", OPTION_LSM_MOUNT_CONTEXT, "VALUE", 0, "Specify an LSM mount context to be used during restore", 0 }, { @@ -129,6 +131,10 @@ parse_opt (int key, char *arg, struct argp_state *state) cr_options.manage_cgroups_mode = crun_parse_manage_cgroups_mode (argp_mandatory_argument (arg, state)); break; + case OPTION_NETWORK_LOCK_METHOD: + cr_options.network_lock_method = crun_parse_network_lock_method (argp_mandatory_argument (arg, state)); + break; + case OPTION_LSM_PROFILE: cr_options.lsm_profile = argp_mandatory_argument (arg, state); break;