diff --git a/criu/cr-service.c b/criu/cr-service.c index a1987e713..88d4af725 100644 --- a/criu/cr-service.c +++ b/criu/cr-service.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "crtools.h" #include "cr_options.h" @@ -459,6 +460,12 @@ static int setup_opts_from_req(int sk, CriuOpts *req) if (req->has_ghost_limit) opts.ghost_limit = req->ghost_limit; + if (req->has_empty_ns) { + opts.empty_ns = req->empty_ns; + if (req->empty_ns & ~(CLONE_NEWNET)) + goto err; + } + if (req->n_irmap_scan_paths) { for (i = 0; i < req->n_irmap_scan_paths; i++) { if (irmap_scan_path_add(req->irmap_scan_paths[i])) diff --git a/criu/crtools.c b/criu/crtools.c index 9cf747593..fa4c4f766 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -67,6 +67,7 @@ void init_opts(void) opts.ps_socket = -1; opts.ghost_limit = DEFAULT_GHOST_LIMIT; opts.timeout = DEFAULT_TIMEOUT; + opts.empty_ns = 0; } static int parse_ns_string(const char *ptr) @@ -272,6 +273,7 @@ int main(int argc, char *argv[], char *envp[]) { "lsm-profile", required_argument, 0, 1071 }, { "timeout", required_argument, 0, 1072 }, { "external", required_argument, 0, 1073 }, + { "empty-ns", required_argument, 0, 1074 }, { }, }; @@ -543,6 +545,14 @@ int main(int argc, char *argv[], char *envp[]) if (add_external(optarg)) return 1; break; + case 1074: + if (!strcmp("net", optarg)) + opts.empty_ns |= CLONE_NEWNET; + else { + pr_err("Unsupported empty namespace: %s", optarg); + return 1; + } + break; case 'V': pr_msg("Version: %s\n", CRIU_VERSION); if (strcmp(CRIU_GITID, "0")) @@ -792,6 +802,9 @@ usage: " tty[rdev:dev]\n" " pipe[inode]\n" " socket[inode]\n" +" --empty-ns {net}\n" +" Create a namespace, but don't restore its properies.\n" +" An user will retore them from action scripts.\n" "\n" "* Logging:\n" " -o|--log-file FILE log file name\n" diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h index 5c0e6332e..a6f0b3ee6 100644 --- a/criu/include/cr_options.h +++ b/criu/include/cr_options.h @@ -106,6 +106,7 @@ struct cr_options { bool lsm_supplied; char *lsm_profile; unsigned int timeout; + unsigned int empty_ns; }; extern struct cr_options opts; diff --git a/criu/net.c b/criu/net.c index 349859c6a..cf1e821bc 100644 --- a/criu/net.c +++ b/criu/net.c @@ -1062,16 +1062,18 @@ int dump_net_ns(int ns_id) return -1; ret = mount_ns_sysfs(); - if (!ret) - ret = dump_netns_conf(fds); - if (!ret) - ret = dump_links(fds); - if (!ret) - ret = dump_ifaddr(fds); - if (!ret) - ret = dump_route(fds); - if (!ret) - ret = dump_rule(fds); + if (!(opts.empty_ns & CLONE_NEWNET)) { + if (!ret) + ret = dump_netns_conf(fds); + if (!ret) + ret = dump_links(fds); + if (!ret) + ret = dump_ifaddr(fds); + if (!ret) + ret = dump_route(fds); + if (!ret) + ret = dump_rule(fds); + } if (!ret) ret = dump_iptables(fds); if (!ret) @@ -1088,21 +1090,23 @@ int dump_net_ns(int ns_id) int prepare_net_ns(int pid) { - int ret; + int ret = 0; NetnsEntry *netns = NULL; - ret = restore_netns_conf(pid, &netns); - if (!ret) - ret = restore_links(pid, &netns); - if (netns) - netns_entry__free_unpacked(netns, NULL); + if (!(opts.empty_ns & CLONE_NEWNET)) { + ret = restore_netns_conf(pid, &netns); + if (!ret) + ret = restore_links(pid, &netns); + if (netns) + netns_entry__free_unpacked(netns, NULL); - if (!ret) - ret = restore_ifaddr(pid); - if (!ret) - ret = restore_route(pid); - if (!ret) - ret = restore_rule(pid); + if (!ret) + ret = restore_ifaddr(pid); + if (!ret) + ret = restore_route(pid); + if (!ret) + ret = restore_rule(pid); + } if (!ret) ret = restore_iptables(pid); if (!ret) diff --git a/images/rpc.proto b/images/rpc.proto index 4f6ed8df1..fac4b9fa0 100644 --- a/images/rpc.proto +++ b/images/rpc.proto @@ -89,6 +89,7 @@ message criu_opts { optional uint32 ghost_limit = 35 [default = 0x100000]; repeated string irmap_scan_paths = 36; repeated string external = 37; + optional uint32 empty_ns = 38; } message criu_dump_resp {