[CRIU] [PATCH] Print the mnt_id in current mount namespace
Chen, Hu
hu1.chen at intel.com
Thu Oct 17 10:02:28 MSK 2019
Consdier the below scenarios
1. Open some files
2. unshare -m to enter a new mount namespace
3. Now the files opened in step 1 still point to mnt_id in old namespace.
This patch will print the corresponding mnt_id in current namespace.
Signed-off-by: Chen, Hu <hu1.chen at intel.com>
diff --git a/fs/mount.h b/fs/mount.h
index 711a4093e475..6bbfc2b3b8ba 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -153,3 +153,5 @@ static inline bool is_anon_ns(struct mnt_namespace *ns)
{
return ns->seq == 0;
}
+
+extern struct mount *lookup_mirror_mnt(const struct mount *mnt);
diff --git a/fs/namespace.c b/fs/namespace.c
index fe0e9e1410fe..6184234868b6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -683,6 +683,35 @@ bool __is_local_mountpoint(struct dentry *dentry)
return is_covered;
}
+/*
+ * lookup_mirror_mnt - Return @mnt's mirror mount in the current/local mount
+ * namespace. If mirror isn't found, just return NULL.
+ */
+struct mount *lookup_mirror_mnt(const struct mount *mnt)
+{
+ struct mnt_namespace *ns = current->nsproxy->mnt_ns;
+ struct mount *mnt_local;
+ bool is_matched = false;
+
+ /* mnt belongs to current namesapce */
+ if (mnt->mnt_ns == ns)
+ return mnt;
+
+ down_read(&namespace_sem);
+ list_for_each_entry(mnt_local, &ns->list, mnt_list) {
+ struct super_block *sb = mnt->mnt.mnt_sb;
+ struct super_block *sb_local = mnt_local->mnt.mnt_sb;
+ if ( MAJOR(sb->s_dev) == MAJOR(sb_local->s_dev) &&
+ MINOR(sb->s_dev) == MINOR(sb_local->s_dev)) {
+ is_matched = true;
+ break;
+ }
+ }
+ up_read(&namespace_sem);
+
+ return is_matched ? mnt_local : NULL;
+}
+
static struct mountpoint *lookup_mountpoint(struct dentry *dentry)
{
struct hlist_head *chain = mp_hash(dentry);
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 81882a13212d..3f9f4ac28e0d 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -23,6 +23,7 @@ static int seq_show(struct seq_file *m, void *v)
int f_flags = 0, ret = -ENOENT;
struct file *file = NULL;
struct task_struct *task;
+ struct mount *mount = NULL;
task = get_proc_task(m->private);
if (!task)
@@ -53,9 +54,16 @@ static int seq_show(struct seq_file *m, void *v)
if (ret)
return ret;
- seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n",
+ /* After unshare -m, real_mount(file->f_path.mnt) is not meaningful in
+ * current mount namesapce. We want to know the mnt_id in current mount
+ * namespace */
+ mount = lookup_mirror_mnt(real_mount(file->f_path.mnt));
+ if (!mount)
+ mount = real_mount(file->f_path.mnt);
+
+ seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\nmnt_devname:\t%s\n",
(long long)file->f_pos, f_flags,
- real_mount(file->f_path.mnt)->mnt_id);
+ mount->mnt_id, mount->mnt_devname);
show_fd_locks(m, file, files);
if (seq_has_overflowed(m))
--
2.22.0
More information about the CRIU
mailing list