Commit 022e3b9b authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

mount: add support for external block devices

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

Options:
dump:      --external dev[MAJOR:MINOR]:VAL
restore:   --external dev[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.

v2: use --ext-mount-map instead of --external on dump
v3: clean up
v4: use --external on dump and on restore
v5: VAL:DEVPATH -> dev[VAL]:DEVPATH on restore
Signed-off-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent c39aad4c
......@@ -607,11 +607,6 @@ int main(int argc, char *argv[], char *envp[])
if (log_init(opts.output))
return 1;
if (!list_empty(&opts.external) && strcmp(argv[optind], "dump")) {
pr_err("--external is dump-only option\n");
return 1;
}
if (!list_empty(&opts.inherit_fds)) {
if (strcmp(argv[optind], "restore")) {
pr_err("--inherit-fd is restore-only option\n");
......@@ -778,9 +773,12 @@ usage:
" force criu to (try to) dump/restore these filesystem's\n"
" mountpoints even if fs is not supported.\n"
" --external RES dump objects from this list as external resources:\n"
" Formats of RES:\n"
" Formats of RES on dump:\n"
" tty[rdev:dev]\n"
" file[mnt_id:inode]\n"
" dev[maj:min]:VAL\n"
" Formats of RES on restore:\n"
" dev[VAL]:DEVPATH\n"
" --inherit-fd fd[<num>]:<existing>\n"
" Inherit file descriptors. This allows to treat file descriptor\n"
" <num> as being already opened via <existing> one and instead of\n"
......
......@@ -1592,3 +1592,17 @@ bool external_lookup_id(char *id)
return true;
return false;
}
char *external_lookup_by_key(char *key)
{
struct external *ext;
int len = strlen(key);
list_for_each_entry(ext, &opts.external, node) {
if (strncmp(ext->id, key, len))
continue;
if (ext->id[len] == ':')
return ext->id + len + 1;
}
return NULL;
}
......@@ -177,6 +177,7 @@ extern int inherit_fd_fini(void);
extern bool external_lookup_id(char *id);
extern int inherit_fd_lookup_id(char *id);
extern char *external_lookup_by_key(char *id);
extern bool inherited_fd(struct file_desc *, int *fdp);
......
......@@ -38,6 +38,8 @@
#undef LOG_PREFIX
#define LOG_PREFIX "mnt: "
static struct fstype fstypes[];
int ext_mount_add(char *key, char *val)
{
struct ext_mount *em;
......@@ -483,15 +485,42 @@ 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) {
char *val;
val = external_lookup_by_key(devstr);
if (val) {
char *source;
int len;
len = strlen(val) + sizeof("dev[]");
source = xmalloc(len);
if (source == NULL)
return -1;
snprintf(source, len, "dev[%s]", val);
info->fstype = &fstypes[1];
BUG_ON(info->fstype->code != FSTYPE__AUTO);
xfree(info->source);
info->source = source;
return 0;
}
}
return -ENOTSUP;
}
static struct mount_info *find_widest_shared(struct mount_info *m)
......@@ -2084,6 +2113,11 @@ static char *resolve_source(struct mount_info *mi)
if (mi->fstype->code == FSTYPE__AUTO) {
struct stat st;
char *val;
val = external_lookup_by_key(mi->source);
if (val)
return val;
if (!stat(mi->source, &st) && S_ISBLK(st.st_mode) &&
major(st.st_rdev) == kdev_major(mi->s_dev) &&
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment