[CRIU] [PATCH 2/2] ns: Check ns type with type field
Pavel Emelyanov
xemul at parallels.com
Fri Sep 18 07:04:42 PDT 2015
Actually make use of the ns->type field and remove all getpid()'s
and other strange/inconsistent checks.
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
cr-check.c | 5 +++--
include/namespaces.h | 2 +-
mount.c | 42 ++++++++++++++++++++----------------------
namespaces.c | 20 ++++++++++----------
net.c | 8 ++++----
sockets.c | 6 +++---
6 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/cr-check.c b/cr-check.c
index 213610b..75831f6 100644
--- a/cr-check.c
+++ b/cr-check.c
@@ -99,7 +99,8 @@ static int check_sock_diag(void)
int ret;
struct ns_id ns;
- ns.pid = 0;
+ ns.ns_pid = 0;
+ ns.type = NS_CRIU;
ns.net.nlsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
if (ns.net.nlsk < 0) {
pr_perror("Can't make diag socket for check");
@@ -757,7 +758,7 @@ static int (*chk_feature)(void);
int cr_check(void)
{
- struct ns_id ns = { .pid = getpid(), .nd = &mnt_ns_desc };
+ struct ns_id ns = { .type = NS_CRIU, .ns_pid = PROC_SELF, .nd = &mnt_ns_desc };
int ret = 0;
if (!is_root_user())
diff --git a/include/namespaces.h b/include/namespaces.h
index 5b2465b..6ff4f6f 100644
--- a/include/namespaces.h
+++ b/include/namespaces.h
@@ -19,7 +19,7 @@ enum ns_type {
struct ns_id {
unsigned int kid;
unsigned int id;
- pid_t pid;
+ pid_t ns_pid;
struct ns_desc *nd;
struct ns_id *next;
enum ns_type type;
diff --git a/mount.c b/mount.c
index a5a0d2e..f11fe8e 100644
--- a/mount.c
+++ b/mount.c
@@ -806,11 +806,10 @@ static struct mount_info *find_best_external_match(struct mount_info *list, stru
static struct ns_id *find_ext_ns_id(void)
{
- int pid = getpid();
struct ns_id *ns;
for (ns = ns_ids; ns->next; ns = ns->next)
- if (ns->pid == pid && ns->nd == &mnt_ns_desc) {
+ if (ns->type == NS_CRIU && ns->nd == &mnt_ns_desc) {
if (!ns->mnt.mntinfo_list &&
!collect_mntinfo(ns, true))
break;
@@ -1650,9 +1649,9 @@ struct mount_info *collect_mntinfo(struct ns_id *ns, bool for_dump)
{
struct mount_info *pm;
- pm = parse_mountinfo(ns->pid, ns, for_dump);
+ pm = parse_mountinfo(ns->ns_pid, ns, for_dump);
if (!pm) {
- pr_err("Can't parse %d's mountinfo\n", ns->pid);
+ pr_err("Can't parse %d's mountinfo\n", ns->ns_pid);
return NULL;
}
@@ -2342,7 +2341,7 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
if (!img)
return -1;
- if (nsid->id != root_item->ids->mnt_ns_id)
+ if (nsid->type == NS_OTHER)
root_len = print_ns_root(nsid, root, sizeof(root));
pr_debug("Reading mountpoint images\n");
@@ -2475,13 +2474,15 @@ static struct mount_info *read_mnt_ns_img(void)
if (nsid->nd != &mnt_ns_desc)
continue;
- if (nsid->id != root_item->ids->mnt_ns_id)
+ if (nsid->type != NS_ROOT) {
+ BUG_ON(nsid->type == NS_CRIU);
/*
* If we have more than one (root) namespace,
* then we'll need the roots yard.
*/
if (create_mnt_roots())
return NULL;
+ }
if (collect_mnt_from_image(&pms, nsid))
return NULL;
@@ -2507,22 +2508,21 @@ char *rst_get_mnt_root(int mnt_id)
if (m == NULL)
return NULL;
- if (m->nsid->pid == getpid())
- return path;
+ if (m->nsid->type == NS_OTHER)
+ print_ns_root(m->nsid, path, sizeof(path));
- print_ns_root(m->nsid, path, sizeof(path));
return path;
}
-static int do_restore_task_mnt_ns(struct ns_id *nsid)
+static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *current)
{
char path[PATH_MAX];
- if (nsid->pid != getpid()) {
+ if (nsid->ns_pid != current->pid.virt) {
int fd;
futex_wait_while_eq(&nsid->ns_created, 0);
- fd = open_proc(nsid->pid, "ns/mnt");
+ fd = open_proc(nsid->ns_pid, "ns/mnt");
if (fd < 0)
return -1;
@@ -2573,7 +2573,9 @@ int restore_task_mnt_ns(struct pstree_item *current)
return -1;
}
- if (do_restore_task_mnt_ns(nsid))
+ BUG_ON(nsid->type != NS_OTHER);
+
+ if (do_restore_task_mnt_ns(nsid, current))
return -1;
}
@@ -2686,7 +2688,7 @@ int prepare_mnt_ns(void)
{
int ret = -1;
struct mount_info *mis, *old;
- struct ns_id ns = { .pid = PROC_SELF, .nd = &mnt_ns_desc };
+ struct ns_id ns = { .type = NS_CRIU, .ns_pid = PROC_SELF, .nd = &mnt_ns_desc };
if (!(root_ns_mask & CLONE_NEWNS))
return rst_collect_local_mntns();
@@ -2833,7 +2835,7 @@ set_root:
int mntns_get_root_fd(struct ns_id *mntns)
{
- return __mntns_get_root_fd(mntns->pid);
+ return __mntns_get_root_fd(mntns->ns_pid);
}
struct ns_id *lookup_nsid_by_mnt_id(int mnt_id)
@@ -2877,7 +2879,7 @@ static int collect_mntns(struct ns_id *ns, void *__arg)
if (!pms)
return -1;
- if (arg->for_dump && ns->pid != getpid())
+ if (arg->for_dump && ns->type != NS_CRIU)
arg->need_to_validate = true;
mntinfo_add_list(pms);
@@ -2917,19 +2919,15 @@ err:
int dump_mnt_namespaces(void)
{
struct ns_id *nsid;
- int n = 0;
if (!(root_ns_mask & CLONE_NEWNS))
return 0;
for (nsid = ns_ids; nsid != NULL; nsid = nsid->next) {
- if (nsid->nd != &mnt_ns_desc)
- continue;
-
- if (nsid->pid == getpid())
+ if (nsid->nd != &mnt_ns_desc || nsid->type == NS_CRIU)
continue;
- if (++n == 2 && check_mnt_id()) {
+ if ((nsid->type == NS_OTHER) && check_mnt_id()) {
pr_err("Nested mount namespaces are not supported "
"without mnt_id in fdinfo\n");
return -1;
diff --git a/namespaces.c b/namespaces.c
index 8d7c312..0034011 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -128,11 +128,11 @@ static void nsid_add(struct ns_id *ns, struct ns_desc *nd, unsigned int id, pid_
{
ns->nd = nd;
ns->id = id;
- ns->pid = pid;
+ ns->ns_pid = pid;
ns->next = ns_ids;
ns_ids = ns;
- pr_info("Add %s ns %d pid %d\n", nd->str, ns->id, ns->pid);
+ pr_info("Add %s ns %d pid %d\n", nd->str, ns->id, ns->ns_pid);
}
static struct ns_id *__rst_new_ns_id(unsigned int id, pid_t pid,
@@ -162,8 +162,8 @@ int rst_add_ns_id(unsigned int id, struct pstree_item *i, struct ns_desc *nd)
nsid = lookup_ns_by_id(id, nd);
if (nsid) {
- if (pid_rst_prio(pid, nsid->pid))
- nsid->pid = pid;
+ if (pid_rst_prio(pid, nsid->ns_pid))
+ nsid->ns_pid = pid;
return 0;
}
@@ -221,7 +221,7 @@ int walk_namespaces(struct ns_desc *nd, int (*cb)(struct ns_id *, void *), void
if (ns->nd != nd)
continue;
- if (ns->pid == getpid()) {
+ if (ns->type == NS_CRIU) {
if (root_ns_mask & nd->cflag)
continue;
@@ -719,24 +719,24 @@ static int do_dump_namespaces(struct ns_id *ns)
{
int ret;
- ret = switch_ns(ns->pid, ns->nd, NULL);
+ ret = switch_ns(ns->ns_pid, ns->nd, NULL);
if (ret)
return ret;
switch (ns->nd->cflag) {
case CLONE_NEWUTS:
pr_info("Dump UTS namespace %d via %d\n",
- ns->id, ns->pid);
+ ns->id, ns->ns_pid);
ret = dump_uts_ns(ns->id);
break;
case CLONE_NEWIPC:
pr_info("Dump IPC namespace %d via %d\n",
- ns->id, ns->pid);
+ ns->id, ns->ns_pid);
ret = dump_ipc_ns(ns->id);
break;
case CLONE_NEWNET:
pr_info("Dump NET namespace info %d via %d\n",
- ns->id, ns->pid);
+ ns->id, ns->ns_pid);
ret = dump_net_ns(ns->id);
break;
default:
@@ -775,7 +775,7 @@ int dump_namespaces(struct pstree_item *item, unsigned int ns_flags)
for (ns = ns_ids; ns; ns = ns->next) {
/* Skip current namespaces, which are in the list too */
- if (ns->pid == getpid())
+ if (ns->type == NS_CRIU)
continue;
switch (ns->nd->cflag) {
diff --git a/net.c b/net.c
index 082ccb6..90f4bb1 100644
--- a/net.c
+++ b/net.c
@@ -827,9 +827,9 @@ static int prep_ns_sockets(struct ns_id *ns, bool for_dump)
{
int nsret = -1, ret;
- if (ns->pid != getpid()) {
- pr_info("Switching to %d's net for collecting sockets\n", ns->pid);
- if (switch_ns(ns->pid, &net_ns_desc, &nsret))
+ if (ns->type != NS_CRIU) {
+ pr_info("Switching to %d's net for collecting sockets\n", ns->ns_pid);
+ if (switch_ns(ns->ns_pid, &net_ns_desc, &nsret))
return -1;
}
@@ -872,7 +872,7 @@ static int collect_net_ns(struct ns_id *ns, void *oarg)
bool for_dump = (oarg == (void *)1);
int ret;
- pr_info("Collecting netns %d/%d\n", ns->id, ns->pid);
+ pr_info("Collecting netns %d/%d\n", ns->id, ns->ns_pid);
ret = prep_ns_sockets(ns, for_dump);
if (ret)
return ret;
diff --git a/sockets.c b/sockets.c
index 5aa2e7b..c013dce 100644
--- a/sockets.c
+++ b/sockets.c
@@ -698,7 +698,7 @@ int collect_sockets(struct ns_id *ns)
tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, NULL);
if (tmp) {
pr_warn("The current kernel doesn't support packet_diag\n");
- if (ns->pid == 0 || tmp != -ENOENT) /* Fedora 19 */
+ if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */
err = tmp;
}
@@ -708,7 +708,7 @@ int collect_sockets(struct ns_id *ns)
tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, NULL);
if (tmp) {
pr_warn("The current kernel doesn't support netlink_diag\n");
- if (ns->pid == 0 || tmp != -ENOENT) /* Fedora 19 */
+ if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */
err = tmp;
}
@@ -716,7 +716,7 @@ int collect_sockets(struct ns_id *ns)
close(nl);
ns->net.nlsk = -1;
- if (err && (ns->pid == getpid())) {
+ if (err && (ns->type == NS_CRIU)) {
/*
* If netns isn't dumped, criu will fail only
* if an unsupported socket will be really dumped.
--
1.9.3
More information about the CRIU
mailing list