When we're searching for toplevel devpts mount into which
the toplevel /dev/ptmx device is pointing to we should use
mnt_id from mountinfo first, this is most reliable way to
detect mounting.

But on old kernels mnt_id may not be present so we should
try s_dev lookup then and here is a nit -- mointinfo keeps
superblock device in kernel format while the source s_dev
is obtained from the stat() syscall so we should use
kdev_to_odev helper to not miss device if there are many
devpts mounted on the node.

Signed-off-by: Cyrill Gorcunov <gorcu...@virtuozzo.com>
---
 criu/include/mount.h |  2 +-
 criu/mount.c         | 20 +++++++++++++-------
 criu/tty.c           |  2 +-
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/criu/include/mount.h b/criu/include/mount.h
index e19f767..0d47d0f 100644
--- a/criu/include/mount.h
+++ b/criu/include/mount.h
@@ -105,7 +105,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 mount_resolve_devpts_mnt_id(int mnt_id, int s_dev);
 extern struct mount_info *lookup_first_fstype(int code);
 
 extern int restore_task_mnt_ns(struct pstree_item *current);
diff --git a/criu/mount.c b/criu/mount.c
index ba3d60d..5e645aa 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -245,10 +245,11 @@ static struct mount_info 
*lookup_mnt_sdev_on_root(unsigned int s_dev)
 {
        struct mount_info *m;
 
-       for (m = mntinfo; m != NULL; m = m->next)
-               if (m->s_dev == s_dev &&
+       for (m = mntinfo; m != NULL; m = m->next) {
+               if (kdev_to_odev(m->s_dev) == s_dev &&
                    is_root(m->root))
                        return m;
+       }
 
        return NULL;
 }
@@ -293,14 +294,19 @@ static struct mount_info *mount_resolve_path(struct 
mount_info *mntinfo_tree, co
  * in properties). It's done for backward compatibility,
  * see drivers/tty/pty.c:ptmx_open.
  */
-int mount_resolve_devpts_mnt_id(int s_dev)
+int mount_resolve_devpts_mnt_id(int mnt_id, int s_dev)
 {
-       struct mount_info *mi;
+       struct mount_info *mi = NULL;
+
+       if (mnt_id != -1)
+               mi = lookup_mnt_id(mnt_id);
 
-       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;
+               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) {
diff --git a/criu/tty.c b/criu/tty.c
index 10b489f..1eb239b 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -2042,7 +2042,7 @@ static int dump_one_tty(int lfd, u32 id, const struct 
fd_parms *p)
        e.fown          = (FownEntry *)&p->fown;
 
        if (is_pty(driver)) {
-               mnt_id = mount_resolve_devpts_mnt_id(p->stat.st_dev);
+               mnt_id = mount_resolve_devpts_mnt_id(p->mnt_id, p->stat.st_dev);
                if (mnt_id < 0) {
                        pr_info("Can't obtain mnt_id on tty %d id %#x\n", lfd, 
id);
                        return -1;
-- 
2.7.5

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to