[3/4] mount: add support for external block devices (v2)

Submitted by Andrei Vagin on April 22, 2016, 5:58 a.m.

Details

Message ID 1461304725-25889-3-git-send-email-avagin@openvz.org
State Rejected
Series "Series without cover letter"
Headers show

Commit Message

Andrei Vagin April 22, 2016, 5:58 a.m.
From: Andrew Vagin <avagin@virtuozzo.com>

The idea is to allow to dump and restore mounts of
a specified block device.

Options:
dump:		--ext-mount-map dev[MAJOR:MINOR]:VAL
restore:	--ext-mount-map VAL:DEVPATH

If we find a mount with a specified block device, we
set its type into FSTYPE__AUTO and write VAL into
the "source" field.

VAL is replaced on DEVPATH on restore.

https://jira.sw.ru/browse/PSBM-39381

v2: use --ext-mount-map instead of --external on dump

Signed-off-by: Andrew Vagin <avagin@virtuozzo.com>
---
 Documentation/criu.txt |  6 +++---
 criu/mount.c           | 39 +++++++++++++++++++++++++++++++++------
 2 files changed, 36 insertions(+), 9 deletions(-)

Patch hide | download patch | download mbox

diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index 1982f5d..07da757 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -176,9 +176,9 @@  In other words, do not use it until really needed.
     where locks are not holed by someone outside of it.
 
 *-M*, *--ext-mount-map* '<KEY>'*:*'<VAL>'::
-    Setup mapping for external mounts. '<KEY>' is a mountpoint inside container
-    and corresponding '<VAL>' is a string that will be written into the image
-    as mountpoint\'s root value.
+    Setup mapping for external mounts. '<KEY>' is a mountpoint or a device
+    (dev[maj:min]]) inside container and corresponding '<VAL>' is a string
+    that will be written into the image as mountpoint\'s root or source value.
 
 *--link-remap*::
     Allow one to link unlinked files back when possible (modifies FS till *restore*).
diff --git a/criu/mount.c b/criu/mount.c
index f57b10c..9c87c68 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -40,6 +40,8 @@ 
 #undef	LOG_PREFIX
 #define LOG_PREFIX "mnt: "
 
+static struct fstype fstypes[];
+
 int ext_mount_add(char *key, char *val)
 {
 	struct ext_mount *em;
@@ -487,15 +489,31 @@  static void mnt_tree_show(struct mount_info *tree, int off)
 static int try_resolve_ext_mount(struct mount_info *info)
 {
 	struct ext_mount *em;
+	char devstr[64];
 
 	em = ext_mount_lookup(info->mountpoint + 1 /* trim the . */);
-	if (em == NULL)
-		return -ENOTSUP;
+	if (em) {
+		pr_info("Found %s mapping for %s mountpoint\n",
+				em->val, info->mountpoint);
+		info->external = em;
+		return 0;
+	}
 
-	pr_info("Found %s mapping for %s mountpoint\n",
-			em->val, info->mountpoint);
-	info->external = em;
-	return 0;
+	snprintf(devstr, sizeof(devstr), "dev[%d/%d]",
+			kdev_major(info->s_dev),  kdev_minor(info->s_dev));
+
+	if (info->fstype->code == FSTYPE__UNSUPPORTED) {
+		em = ext_mount_lookup(devstr);
+		if (em) {
+			info->fstype = &fstypes[1];
+			BUG_ON(info->fstype->code != FSTYPE__AUTO);
+			xfree(info->source);
+			info->source = xstrdup(em->val);
+			return 0;
+		}
+	}
+
+	return -ENOTSUP;
 }
 
 static struct mount_info *find_widest_shared(struct mount_info *m)
@@ -2091,6 +2109,15 @@  static char *resolve_source(struct mount_info *mi)
 
 	if (mi->fstype->code == FSTYPE__AUTO) {
 		struct stat st;
+		char devstr[64];
+		struct ext_mount *key;
+
+		snprintf(devstr, sizeof(devstr), mi->source,
+				kdev_major(mi->s_dev), kdev_minor(mi->s_dev));
+
+		key = ext_mount_lookup(devstr);
+		if (key)
+			return key->val;
 
 		if (!stat(mi->source, &st) && S_ISBLK(st.st_mode) &&
 		    major(st.st_rdev) == kdev_major(mi->s_dev) &&