Commit c2b21fbf authored by Andrei Vagin's avatar Andrei Vagin Committed by Andrei Vagin

criu: add support for external net namespaces

It works like other external resources.
A user specify which namespaces are external and have not to be dumped.
On restore, the user gives file descriptors to preconfigured namespaces.

How to use:
dump:
        --external net[INO]:KEY
restore:
        --inherit-fd fd[NSFD]:KEY

The test script contains more details how to use this:
test/others/netns_ext/run.sh
Acked-by: 's avatarAdrian Reber <areber@redhat.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 3e4cecb9
......@@ -1673,6 +1673,10 @@ static int restore_task_with_children(void *_arg)
* ACT_SETUP_NS scripts, so the root netns has to be created here
*/
if (root_ns_mask & CLONE_NEWNET) {
struct ns_id *ns = net_get_root_ns();
if (ns->ext_key)
ret = net_set_ext(ns);
else
ret = unshare(CLONE_NEWNET);
if (ret) {
pr_perror("Can't unshare net-namespace");
......
......@@ -91,6 +91,7 @@ struct ns_id {
struct ns_desc *nd;
struct ns_id *next;
enum ns_type type;
char *ext_key;
/*
* For mount namespaces on restore -- indicates that
......
......@@ -50,6 +50,8 @@ extern int net_get_nsid(int rtsk, int fd, int *nsid);
extern struct ns_id *net_get_root_ns();
extern int kerndat_nsid(void);
extern void check_has_netns_ioc(int fd, bool *kdat_val, const char *name);
extern int net_set_ext(struct ns_id *ns);
extern struct ns_id *get_root_netns();
extern int read_net_ns_img();
#endif /* __CR_NET_H__ */
......@@ -2075,6 +2075,7 @@ int read_net_ns_img(void)
pr_err("Can not read netns object\n");
return -1;
}
ns->ext_key = ns->net.netns->ext_key;
}
return 0;
......@@ -2198,6 +2199,22 @@ static int dump_netns_ids(int rtsk, struct ns_id *ns)
(void *)&arg);
}
int net_set_ext(struct ns_id *ns)
{
int fd, ret;
fd = inherit_fd_lookup_id(ns->ext_key);
if (fd < 0) {
pr_err("Unable to find an external netns: %s\n", ns->ext_key);
return -1;
}
ret = switch_ns_by_fd(fd, &net_ns_desc, NULL);
close(fd);
return ret;
}
int dump_net_ns(struct ns_id *ns)
{
struct cr_imgset *fds;
......@@ -2208,7 +2225,14 @@ int dump_net_ns(struct ns_id *ns)
return -1;
ret = mount_ns_sysfs();
if (!(opts.empty_ns & CLONE_NEWNET)) {
if (ns->ext_key) {
NetnsEntry netns = NETNS_ENTRY__INIT;
netns.ext_key = ns->ext_key;
ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS);
if (ret)
goto out;
} else if (!(opts.empty_ns & CLONE_NEWNET)) {
int sk;
sk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
......@@ -2252,6 +2276,7 @@ int dump_net_ns(struct ns_id *ns)
if (!ret)
ret = dump_nf_ct(fds, CR_FD_NETNF_EXP);
out:
close(ns_sysfs_fd);
ns_sysfs_fd = -1;
......@@ -2305,7 +2330,7 @@ static int prepare_net_ns_first_stage(struct ns_id *ns)
{
int ret = 0;
if (opts.empty_ns & CLONE_NEWNET)
if (ns->ext_key || (opts.empty_ns & CLONE_NEWNET))
return 0;
ret = restore_netns_conf(ns);
......@@ -2321,7 +2346,7 @@ static int prepare_net_ns_second_stage(struct ns_id *ns)
{
int ret = 0, nsid = ns->id;
if (!(opts.empty_ns & CLONE_NEWNET)) {
if (!(opts.empty_ns & CLONE_NEWNET) && !ns->ext_key) {
if (ns->net.netns)
netns_entry__free_unpacked(ns->net.netns, NULL);
......@@ -2369,7 +2394,14 @@ static int open_net_ns(struct ns_id *nsid)
static int do_create_net_ns(struct ns_id *ns)
{
if (unshare(CLONE_NEWNET)) {
int ret;
if (ns->ext_key)
ret = net_set_ext(ns);
else
ret = unshare(CLONE_NEWNET);
if (ret) {
pr_perror("Unable to create a new netns");
return -1;
}
......@@ -2716,9 +2748,18 @@ static int netns_nr;
static int collect_net_ns(struct ns_id *ns, void *oarg)
{
bool for_dump = (oarg == (void *)1);
char id[64], *val;
int ret;
pr_info("Collecting netns %d/%d\n", ns->id, ns->ns_pid);
snprintf(id, sizeof(id), "net[%u]", ns->kid);
val = external_lookup_by_key(id);
if (!IS_ERR_OR_NULL(val)) {
pr_debug("The %s netns is external\n", id);
ns->ext_key = val;
}
ret = prep_ns_sockets(ns, for_dump);
if (ret)
return ret;
......
......@@ -70,4 +70,5 @@ message netns_entry {
repeated sysctl_entry all_conf6 = 6;
repeated netns_id nsids = 7;
optional string ext_key = 8;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment