[CRIU] [PATCH 8/9] mount: Add helper for searching for shared peer
Pavel Emelyanov
xemul at parallels.com
Tue Nov 11 06:51:14 PST 2014
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
mount.c | 66 +++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/mount.c b/mount.c
index 264b72c..c7a8594 100644
--- a/mount.c
+++ b/mount.c
@@ -388,6 +388,24 @@ static struct mount_info *get_widest_peer(struct mount_info *m)
return NULL;
}
+static struct mount_info *find_shared_peer(struct mount_info *m,
+ struct mount_info *ct, char *ct_mountpoint, int m_mpnt_l)
+{
+ struct mount_info *cm;
+
+ list_for_each_entry(cm, &m->children, siblings) {
+ if (strcmp(ct_mountpoint, cm->mountpoint + m_mpnt_l))
+ continue;
+
+ if (!mounts_equal(cm, ct, false))
+ break;
+
+ return cm;
+ }
+
+ return NULL;
+}
+
static inline int path_length(char *path)
{
int off;
@@ -409,7 +427,7 @@ static inline int path_length(char *path)
static int validate_shared(struct mount_info *m)
{
- struct mount_info *t, *ct, *cm, *tmp;
+ struct mount_info *t, *ct;
int t_root_l, m_root_l, t_mpnt_l, m_mpnt_l, len;
char *m_root_rpath;
LIST_HEAD(children);
@@ -467,6 +485,7 @@ static int validate_shared(struct mount_info *m)
/* Search a child, which is visiable in both mounts. */
list_for_each_entry(ct, &t->children, siblings) {
char *ct_mpnt_rpath;
+ struct mount_info *cm;
if (ct->is_ns_root)
continue;
@@ -494,41 +513,28 @@ static int validate_shared(struct mount_info *m)
* described above path corrections).
*/
- list_for_each_entry_safe(cm, tmp, &m->children, siblings) {
- if (strcmp(ct_mpnt_rpath, cm->mountpoint + m_mpnt_l))
- continue;
-
- if (!mounts_equal(cm, ct, false)) {
- pr_err("Two shared mounts on same spaces have different mounts\n");
- pr_err("%d:%s\n", cm->mnt_id, cm->mountpoint);
- pr_err("%d:%s\n", ct->mnt_id, ct->mountpoint);
- return -1;
- }
-
- list_move(&cm->siblings, &children);
- break;
- }
- if (&cm->siblings == &m->children) {
- list_splice(&children, &m->children);
+ cm = find_shared_peer(m, ct, ct_mpnt_rpath, m_mpnt_l);
+ if (!cm)
+ goto err;
- pr_err("%d:%s and %d:%s have different set of mounts\n",
- m->mnt_id, m->mountpoint, t->mnt_id, t->mountpoint);
- pr_err("For example %d:%s\n", ct->mnt_id, ct->mountpoint);
- return -1;
- }
+ /*
+ * Keep this one aside. At the end of t's children scan we should
+ * move _all_ m's children here (the list_empty check below).
+ */
+ list_move(&cm->siblings, &children);
}
- if (!list_empty(&m->children)) {
+ if (!list_empty(&m->children))
+ goto err;
- cm = list_first_entry(&m->children, struct mount_info, siblings);
- pr_err("%d:%s and %d:%s have different set of mounts\n",
- m->mnt_id, m->mountpoint, t->mnt_id, t->mountpoint);
- pr_err("For example %d:%s\n", cm->mnt_id, cm->mountpoint);
- list_splice(&children, &m->children);
- return -1;
- }
list_splice(&children, &m->children);
return 0;
+
+err:
+ list_splice(&children, &m->children);
+ pr_err("%d:%s and %d:%s have different set of mounts\n",
+ m->mnt_id, m->mountpoint, t->mnt_id, t->mountpoint);
+ return -1;
}
/*
--
1.8.4.2
More information about the CRIU
mailing list