[CRIU] [PATCH] mnt: Introduce and use issubpath helper

Pavel Emelyanov xemul at parallels.com
Thu Nov 6 04:40:34 PST 2014


When we validate the mount tree not to have overmounts we need to 
check one path to be the sub-path of another. Here's a helper for
this.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>

---

diff --git a/include/util.h b/include/util.h
index 0816029..e54823b 100644
--- a/include/util.h
+++ b/include/util.h
@@ -192,13 +192,17 @@ extern int read_fd_link(int lfd, char *buf, size_t size);
 int vaddr_to_pfn(unsigned long vaddr, u64 *pfn);
 
 /*
- * Check whether @str starts with @sub
+ * Check whether @str starts with @sub and report the
+ * next character of @str in @end
  */
-static inline bool strstartswith(const char *str, const char *sub)
+static inline bool strstartswith2(const char *str, const char *sub, char *end)
 {
 	while (1) {
-		if (*sub == '\0') /* end of sub -- match */
+		if (*sub == '\0') /* end of sub -- match */ {
+			if (end)
+				*end = *str;
 			return true;
+		}
 		if (*str == '\0') /* end of str, sub is NOT ended -- miss */
 			return false;
 		if (*str != *sub)
@@ -209,6 +213,24 @@ static inline bool strstartswith(const char *str, const char *sub)
 	}
 }
 
+static inline bool strstartswith(const char *str, const char *sub)
+{
+	return strstartswith2(str, sub, NULL);
+}
+
+/*
+ * Checks whether the @path has @sub_path as a sub path, i.e.
+ * sub_path is the beginning of path and the last component
+ * match is full (next character terminates path component).
+ */
+
+static inline bool issubpath(const char *path, const char *sub_path)
+{
+	char end;
+	return strstartswith2(path, sub_path, &end) &&
+		(end == '/' || end == '\0');
+}
+
 /*
  * mkdir -p
  */
diff --git a/mount.c b/mount.c
index f62fd04..3ec70f8 100644
--- a/mount.c
+++ b/mount.c
@@ -479,19 +479,11 @@ static int validate_mounts(struct mount_info *info, bool for_dump)
 		}
 
 		list_for_each_entry(t, &m->parent->children, siblings) {
-			int tlen, mlen;
-
 			if (m == t)
 				continue;
-
-			tlen = strlen(t->mountpoint);
-			mlen = strlen(m->mountpoint);
-			if (mlen < tlen)
-				continue;
-			if (strncmp(t->mountpoint, m->mountpoint, tlen))
-				continue;
-			if (mlen > tlen && m->mountpoint[tlen] != '/')
+			if (!issubpath(m->mountpoint, t->mountpoint))
 				continue;
+
 			pr_err("%d:%s is overmounted\n", m->mnt_id, m->mountpoint);
 			return -1;
 		}



More information about the CRIU mailing list