[Devel] [PATCH rh7 v3] ve/devpts: Assign container's @devpts_sb on first mount

Cyrill Gorcunov gorcunov at virtuozzo.com
Wed Jul 22 10:50:20 PDT 2015


Modern systemd based containers (such as fedora-21, centos-7) already
mounting initial devpts filesystem with @newinstance option but it
turned out that ubuntu-14 lts doesn't, which makes restore procedure
to fail because we're using get_exec_env as a namespace mark and the
kernel mounts new superblock for container internally. This is done
to isolate devpts between containers but somehow incomplete.

Lets revert commit 2c27d20125f51256d59ec2b278a905321dc64914
to make code closer to native one and assign container's superblock
@devpts_sb at first moutn call.

https://jira.sw.ru/browse/PSBM-34931

Former-patch-by: Vladimir Davydov <vdavydov at virtuozzo.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
CC: Andrey Vagin <avagin at virtuozzo.com>
CC: Konstantin Khorenko <khorenko at virtuozzo.com>
CC: Pavel Emelyanov <xemul at virtuozzo.com>
---
 fs/devpts/inode.c |   39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

Index: linux-pcs7.git/fs/devpts/inode.c
===================================================================
--- linux-pcs7.git.orig/fs/devpts/inode.c
+++ linux-pcs7.git/fs/devpts/inode.c
@@ -402,6 +402,20 @@ fail:
 }
 
 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
+static int test_devpts_sb(struct super_block *s, void *p)
+{
+	return get_exec_env()->devpts_sb == s;
+}
+
+static int set_devpts_sb(struct super_block *s, void *p)
+{
+	int error = set_anon_super(s, p);
+	if (!error && !get_exec_env()->devpts_sb) {
+		atomic_inc(&s->s_active);
+		get_exec_env()->devpts_sb = s;
+	}
+	return error;
+}
 
 /*
  * devpts_mount()
@@ -436,7 +450,6 @@ static struct dentry *devpts_mount(struc
 	int error;
 	struct pts_mount_opts opts;
 	struct super_block *s;
-	struct dentry *root;
 
 	error = parse_mount_options(data, PARSE_MOUNT, &opts);
 	if (error)
@@ -450,29 +463,29 @@ static struct dentry *devpts_mount(struc
 		return ERR_PTR(-EINVAL);
 
 	if (opts.newinstance)
-		root = mount_nodev(fs_type, flags, data, devpts_fill_super);
+		s = sget(fs_type, NULL, set_devpts_sb, flags, NULL);
 	else
-		root = mount_ns(fs_type, flags, data, get_exec_env(), devpts_fill_super);
+		s = sget(fs_type, test_devpts_sb, set_devpts_sb, flags, NULL);
+
+	if (IS_ERR(s))
+		return ERR_CAST(s);
 
-	if (IS_ERR(root))
-		return ERR_CAST(root);
+	if (!s->s_root) {
+		error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
+		if (error)
+			goto out_undo_sget;
+		s->s_flags |= MS_ACTIVE;
+	}
 
-	s = root->d_sb;
 	memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts));
 
 	error = mknod_ptmx(s);
 	if (error)
 		goto out_undo_sget;
 
-	if (!opts.newinstance) {
-		atomic_inc(&s->s_active);
-		get_exec_env()->devpts_sb = s;
-	}
-
-	return root;
+	return dget(s->s_root);
 
 out_undo_sget:
-	dput(root);
 	deactivate_locked_super(s);
 	return ERR_PTR(error);
 }



More information about the Devel mailing list