[CRIU] [PATCH 1/2] zdtm: Add filesystem specific helpers
Cyrill Gorcunov
gorcunov at openvz.org
Fri Sep 4 06:43:48 PDT 2015
In particular we have to find out if we're
running on btrfs filesystem for proper device
number mangling.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
test/zdtm/lib/fs.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
test/zdtm/lib/fs.h | 46 +++++++++++++++++++++++++++++
2 files changed, 133 insertions(+)
diff --git a/test/zdtm/lib/fs.c b/test/zdtm/lib/fs.c
index 506580c8c180..04788e9c4539 100644
--- a/test/zdtm/lib/fs.c
+++ b/test/zdtm/lib/fs.c
@@ -5,6 +5,93 @@
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
+#include <limits.h>
#include "zdtmtst.h"
#include "fs.h"
+
+mnt_info_t *mnt_info_alloc(void)
+{
+ mnt_info_t *m = malloc(sizeof(*m));
+ if (m)
+ memset(m, 0, sizeof(*m));
+ return m;
+}
+
+void mnt_info_free(mnt_info_t **m)
+{
+ if (m && *m) {
+ free(*m);
+ *m = NULL;
+ }
+}
+
+mnt_info_t *get_cwd_mnt_info(void)
+{
+ int mnt_id, parent_mnt_id;
+ unsigned int kmaj, kmin;
+ char str[1024], *cwd;
+ int ret;
+ FILE *f;
+
+ mnt_info_t *m = NULL;
+
+ char mountpoint[PATH_MAX];
+ char root[PATH_MAX];
+
+ char *fsname = NULL;
+ size_t len = 0, best_len = 0;
+
+ f = fopen("/proc/self/mountinfo", "r");
+ if (!f)
+ return NULL;
+
+ cwd = get_current_dir_name();
+ if (!cwd)
+ goto err;
+
+ m = mnt_info_alloc();
+ if (!m)
+ goto err;
+
+ while (fgets(str, sizeof(str), f)) {
+ char *hyphen = strchr(str, '-');
+ ret = sscanf(str, "%i %i %u:%u %s %s",
+ &mnt_id, &parent_mnt_id,
+ &kmaj, &kmin,
+ root, mountpoint);
+ if (ret != 6 || !hyphen)
+ goto err;
+ ret = sscanf(hyphen + 1, " %ms", &fsname);
+ if (ret != 1)
+ goto err;
+
+ len = strlen(mountpoint);
+ if (!strncmp(mountpoint, cwd, len)) {
+ if (len > best_len) {
+ best_len = len;
+
+ m->mnt_id = mnt_id;
+ m->parent_mnt_id = parent_mnt_id;
+ m->s_dev = MKKDEV(kmaj, kmin);
+
+ strncpy(m->root, root, sizeof(m->root));
+ strncpy(m->mountpoint, mountpoint, sizeof(m->mountpoint));
+ strncpy(m->fsname, fsname, sizeof(m->fsname));
+ }
+ }
+
+ free(fsname);
+ fsname = NULL;
+ }
+
+out:
+ free(cwd);
+ fclose(f);
+
+ return m;
+
+err:
+ mnt_info_free(&m);
+ goto out;
+}
diff --git a/test/zdtm/lib/fs.h b/test/zdtm/lib/fs.h
index b161ab184d49..c574709dcc33 100644
--- a/test/zdtm/lib/fs.h
+++ b/test/zdtm/lib/fs.h
@@ -1,3 +1,49 @@
#ifndef ZDTM_FS_H_
#define ZDTM_FS_H_
+
+#define _BSD_SOURCE
+#include <sys/types.h>
+
+#include <limits.h>
+
+#define KDEV_MINORBITS 20
+#define KDEV_MINORMASK ((1UL << KDEV_MINORBITS) - 1)
+#define MKKDEV(ma, mi) (((ma) << KDEV_MINORBITS) | (mi))
+
+static inline unsigned int kdev_major(unsigned int kdev)
+{
+ return kdev >> KDEV_MINORBITS;
+}
+
+static inline unsigned int kdev_minor(unsigned int kdev)
+{
+ return kdev & KDEV_MINORMASK;
+}
+
+static inline dev_t kdev_to_odev(unsigned int kdev)
+{
+ /*
+ * New kernels encode devices in a new form.
+ * See kernel's fs/stat.c for details, there
+ * choose_32_64 helpers which are the key.
+ */
+ unsigned major = kdev_major(kdev);
+ unsigned minor = kdev_minor(kdev);
+
+ return makedev(major, minor);
+}
+
+typedef struct {
+ int mnt_id;
+ int parent_mnt_id;
+ unsigned int s_dev;
+ char root[PATH_MAX];
+ char mountpoint[PATH_MAX];
+ char fsname[64];
+} mnt_info_t;
+
+extern mnt_info_t *mnt_info_alloc(void);
+extern void mnt_info_free(mnt_info_t **m);
+extern mnt_info_t *get_cwd_mnt_info(void);
+
#endif /* ZDTM_FS_H_ */
--
2.4.3
More information about the CRIU
mailing list