[CRIU] [PATCH 2/7] tty: mount -- Add mount_resolve_devpts_mnt_id helper
Cyrill Gorcunov
gorcunov at openvz.org
Thu Feb 2 00:02:04 PST 2017
We will need it to distinguish multiple devpts mounted.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
criu/include/mount.h | 1 +
criu/mount.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/criu/include/mount.h b/criu/include/mount.h
index a692b550bb91..62ad2676880d 100644
--- a/criu/include/mount.h
+++ b/criu/include/mount.h
@@ -102,6 +102,7 @@ extern struct mount_info *lookup_mnt_sdev(unsigned int s_dev);
extern dev_t phys_stat_resolve_dev(struct ns_id *, dev_t st_dev, const char *path);
extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev,
struct ns_id *, const char *path);
+extern int mount_resolve_devpts_mnt_id(int s_dev);
extern int restore_task_mnt_ns(struct pstree_item *current);
extern void fini_restore_mntns(void);
diff --git a/criu/mount.c b/criu/mount.c
index 4ba6cc27e9eb..69d8fbd764ef 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -234,6 +234,20 @@ struct mount_info *lookup_mnt_sdev(unsigned int s_dev)
return NULL;
}
+/* Lookup for sdev skipping bind mounts */
+static struct mount_info *lookup_mnt_sdev_on_root(unsigned int s_dev)
+{
+ struct mount_info *m;
+
+ for (m = mntinfo; m; m = m->next) {
+ if (m->s_dev == s_dev &&
+ is_root(m->root))
+ return m;
+ }
+
+ return NULL;
+}
+
static struct mount_info *mount_resolve_path(struct mount_info *mntinfo_tree, const char *path)
{
size_t pathlen = strlen(path);
@@ -263,6 +277,46 @@ static struct mount_info *mount_resolve_path(struct mount_info *mntinfo_tree, co
return m;
}
+/*
+ * Figuring out mount id is a bit tricky for PTYs: when
+ * several devpts mounted they have own superblocks
+ * thus opening /dev/<dirs>/ptmx leads to slave
+ * peers lay into /dev/<dirs>/0 and etc, but the
+ * exception is toplevel /dev/ptmx, when opened the
+ * kernel lookups for first "pts" downlevel directory mounted
+ * at /dev/pts (which of course must have DEVPTS_SUPER_MAGIC
+ * in properties). It's done for backward compatibility,
+ * see drivers/tty/pty.c:ptmx_open.
+ */
+int mount_resolve_devpts_mnt_id(int s_dev)
+{
+ struct mount_info *mi;
+
+ mi = lookup_mnt_sdev_on_root(s_dev);
+ if (!mi) {
+ pr_err("No devpts mount point found for s_dev %#x\n", s_dev);
+ return -1;
+ }
+
+ if (mi->fstype->code == FSTYPE__DEVPTS) {
+ return mi->mnt_id;
+ } else if (mi->fstype->code == FSTYPE__DEVTMPFS) {
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "%s/pts/ptmx", mi->ns_mountpoint + 1);
+ mi = mount_resolve_path(mi, path);
+ if (!mi) {
+ pr_err("Can't resolve %s\n", path);
+ return -1;
+ }
+ if (mi->fstype->code == FSTYPE__DEVPTS)
+ return mi->mnt_id;
+ }
+
+ pr_err("Can't resolve devpts for s_dev %#x\n", s_dev);
+ return -1;
+}
+
dev_t phys_stat_resolve_dev(struct ns_id *ns, dev_t st_dev, const char *path)
{
struct mount_info *m;
--
2.7.4
More information about the CRIU
mailing list