[CRIU] Re: [PATCH 13/14] pstree: Migrate SIDs/PGIDs if requested

Cyrill Gorcunov gorcunov at gmail.com
Sat Oct 6 15:26:09 EDT 2012


On Sat, Oct 06, 2012 at 10:58:42AM +0400, Cyrill Gorcunov wrote:
> 
> In case if user asked us to migrate session we need to
> walk over all process entries and update SIDs and PGIDs
> where needed.
---

Guys, here is updated variant. Actually I'm not sure
if anyone received the whole series since at least
Andrew has reported that he didn't receive anything
due to openvz.org MX problems.
-------------- next part --------------
>From 2b458c4eb37c81fd87972de505743ab684b79ac3 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Sat, 6 Oct 2012 10:39:52 +0400
Subject: [PATCH 13/14] pstree: Migrate SIDs/PGIDs if requested

In case if user asked us to migrate session we need to
walk over all process entries and update SIDs and PGIDs
where needed.

This should be done before we restore the order of process
entities creation.

An example of usage if migrating a task

| # ps
| pid sid comm
|  2   2 bash
|  3   2  `- my_app
|  4   4 bash
|  5   4  `- ps
|
| # crtools dump -t 3 --ext-tty
| # crtools restore -t 3 --ext-tty
| # ps
| pid sid comm
|  4   4 bash
|  5   4  `- crtools
|  3   4      `- my_app

Also this patches takes into account --ext-tty option,
the real hanlding of tty entries is addressed in next
patch for simplicity.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-restore.c     |    2 +-
 include/pstree.h |   10 ++++++-
 pstree.c         |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index c961cc6..3f6d219 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -958,7 +958,7 @@ int cr_restore_tasks(pid_t pid, struct cr_options *opts)
 	if (prepare_task_entries() < 0)
 		return -1;
 
-	if (prepare_pstree() < 0)
+	if (prepare_pstree(opts) < 0)
 		return -1;
 
 	if (prepare_pstree_ids() < 0)
diff --git a/include/pstree.h b/include/pstree.h
index 83310c4..8ca1c26 100644
--- a/include/pstree.h
+++ b/include/pstree.h
@@ -25,6 +25,14 @@ struct pid {
 	pid_t virt;
 };
 
+struct pstree_opts {
+	bool			root_inherit_sid;
+	bool			root_inherit_pgid;
+
+	pid_t			new_sid;
+	pid_t			new_pgid;
+};
+
 struct pstree_item {
 	struct pstree_item	*parent;
 	struct list_head	children;	/* list of my children */
@@ -54,7 +62,7 @@ extern struct pstree_item *pstree_item_next(struct pstree_item *item);
 	for (pi = root_item; pi != NULL; pi = pstree_item_next(pi))
 
 extern bool restore_before_setsid(struct pstree_item *child);
-extern int prepare_pstree(void);
+extern int prepare_pstree(struct cr_options *opts);
 extern int prepare_pstree_ids(void);
 
 extern int dump_pstree(struct pstree_item *root_item);
diff --git a/pstree.c b/pstree.c
index 6acf492..b6e5daf 100644
--- a/pstree.c
+++ b/pstree.c
@@ -10,6 +10,7 @@
 #include "protobuf/pstree.pb-c.h"
 
 struct pstree_item *root_item;
+static struct pstree_opts *pstree_opts;
 
 void free_pstree(struct pstree_item *root_item)
 {
@@ -107,8 +108,57 @@ err:
 	return ret;
 }
 
+int pstree_inherit(struct pstree_opts *opts)
+{
+	struct pstree_item *pi;
+	pid_t old_sid, old_pgid;
+
+	BUG_ON(!opts);
+
+	if (!opts->root_inherit_sid && !opts->root_inherit_pgid)
+		return 0;
+
+	pr_info("SID/PGID inheritance PID %d (SID %d -> %d PGID %d -> %d)\n",
+		root_item->pid.virt, root_item->sid, opts->new_sid,
+		root_item->pgid, opts->new_pgid);
+
+	old_sid  = root_item->sid;
+	old_pgid = root_item->pgid;
+
+#define SID_PGID_UPDATE(_pi, _old_sid, _old_pgid)		\
+	do {							\
+		if (opts->root_inherit_pgid) {			\
+			if (_pi->pgid == _old_pgid)		\
+				_pi->pgid = opts->new_pgid;	\
+		}						\
+								\
+		if (opts->root_inherit_sid) {			\
+			if (_pi->sid == _old_sid)		\
+				_pi->sid = opts->new_sid;	\
+			if (_pi->pgid == _old_sid)		\
+				_pi->pgid = opts->new_sid;	\
+		}						\
+	} while (0)
+
+	if (opts->root_inherit_pgid)
+		root_item->pgid = opts->new_pgid;
+
+	if (opts->root_inherit_sid) {
+		root_item->sid = opts->new_sid;
+		if (root_item->pgid == old_sid)
+			root_item->pgid = opts->new_sid;
+	}
+
+	for_each_pstree_item(pi)
+		SID_PGID_UPDATE(pi, old_sid, old_pgid);
+
+#undef SID_PGID_UPDATE
+
+	return 0;
+}
+
 static int max_pid = 0;
-int prepare_pstree(void)
+int prepare_pstree(struct cr_options *opts)
 {
 	int ret = 0, i, ps_fd;
 	struct pstree_item *pi, *parent = NULL;
@@ -195,6 +245,24 @@ int prepare_pstree(void)
 		pstree_entry__free_unpacked(e, NULL);
 	}
 
+	if (ret)
+		goto err;
+
+	/*
+	 * SID/PGIDs migration should be done early before we
+	 * do recreate tasks creation order.
+	 */
+	pstree_opts = xzalloc(sizeof(*pstree_opts));
+	if (!pstree_opts)
+		goto err;
+
+	pstree_opts->root_inherit_sid	= opts->inherit_sid | opts->ext_tty;
+	pstree_opts->root_inherit_pgid	= opts->ext_tty;
+	pstree_opts->new_sid		= getsid(getpid());
+	pstree_opts->new_pgid		= getpgid(getpid());
+
+	ret = pstree_inherit(pstree_opts);
+
 err:
 	close(ps_fd);
 	return ret;
@@ -205,6 +273,8 @@ int prepare_pstree_ids(void)
 	struct pstree_item *item, *child, *helper, *tmp;
 	LIST_HEAD(helpers);
 
+	BUG_ON(!pstree_opts);
+
 	/*
 	 * Some task can be reparented to init. A helper task should be added
 	 * for restoring sid of such tasks. The helper tasks will be exited
@@ -331,6 +401,11 @@ int prepare_pstree_ids(void)
 		if (gleader)
 			continue;
 
+		if (pstree_opts->root_inherit_pgid) {
+			if (pstree_opts->new_pgid == item->pgid)
+				continue;
+		}
+
 		helper = alloc_pstree_item();
 		if (helper == NULL)
 			return -1;
-- 
1.7.7.6



More information about the CRIU mailing list