[CRIU] [PATCH 10/18] util: Add rmdirp helper

Cyrill Gorcunov gorcunov at openvz.org
Sun Apr 9 15:28:42 PDT 2017


Will need to remove ghost dirs.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 criu/include/util.h |  2 ++
 criu/util.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/criu/include/util.h b/criu/include/util.h
index 91587ef1c358..4bc1f6aa5da8 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -253,6 +253,8 @@ static inline bool issubpath(const char *path, const char *sub_path)
  */
 int mkdirpat(int fd, const char *path, int mode);
 
+int rmdirp(const char *path, size_t keep);
+
 /*
  * Tests whether a path is a prefix of another path. This is different than
  * strstartswith because "/foo" is _not_ a path prefix of "/foobar", since they
diff --git a/criu/util.c b/criu/util.c
index dad9386a776b..bb59a8ddc6ce 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -903,6 +903,46 @@ int mkdirpat(int fd, const char *path, int mode)
 	return 0;
 }
 
+/*
+ * Remove directory @path together with parents,
+ * keeping @keep len of path if provided. Directories
+ * must be empty of course.
+ */
+int rmdirp(const char *path, size_t keep)
+{
+	char made_path[PATH_MAX], *pos;
+	size_t len = strlen(path);
+	int ret;
+
+	if (len >= PATH_MAX) {
+		pr_err("path %s is longer than PATH_MAX\n", path);
+		return -ENOSPC;
+	}
+
+	/* Nothing to do */
+	if (len <= keep)
+		return 0;
+
+	strcpy(made_path, path);
+
+	for (pos = strrchr(made_path, '/');
+	     pos && (pos - made_path) >= keep;
+	     pos = strrchr(made_path, '/')) {
+		ret = rmdir(made_path);
+
+		if (ret < 0 && errno != ENOENT) {
+			ret = -errno;
+			pr_perror("Can't delete %s", made_path);
+			goto out;
+		}
+		*pos = '\0';
+	}
+
+	ret = 0;
+out:
+	return ret;
+}
+
 bool is_path_prefix(const char *path, const char *prefix)
 {
 	if (strstartswith(path, prefix)) {
-- 
2.7.4



More information about the CRIU mailing list