[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