diff --git a/include/criu-plugin.h b/include/criu-plugin.h index cf6a2c535..a76073045 100644 --- a/include/criu-plugin.h +++ b/include/criu-plugin.h @@ -32,6 +32,8 @@ typedef int (cr_plugin_restore_unix_sk_t)(int id); typedef int (cr_plugin_dump_file_t)(int fd, int id); typedef int (cr_plugin_restore_file_t)(int id); +typedef int (cr_plugin_dump_ext_mount_t)(char *mountpoint, int id); + /* Public API */ extern int criu_get_image_dir(void); diff --git a/include/plugin.h b/include/plugin.h index 6c8ab829d..9a077d95c 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -14,4 +14,6 @@ int cr_plugin_restore_unix_sk(int id); int cr_plugin_dump_file(int fd, int id); int cr_plugin_restore_file(int id); +int cr_plugin_dump_ext_mount(char *mountpoint, int id); + #endif diff --git a/include/proc_parse.h b/include/proc_parse.h index 9af46f6a0..ef203156e 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -112,6 +112,7 @@ struct mount_info { char *source; char *options; bool mounted; + bool need_plugin; struct mount_info *next; /* tree linkage */ diff --git a/mount.c b/mount.c index f07206a84..67797fa0d 100644 --- a/mount.c +++ b/mount.c @@ -17,6 +17,7 @@ #include "util.h" #include "util-pie.h" #include "log.h" +#include "plugin.h" #include "mount.h" #include "pstree.h" #include "proc_parse.h" @@ -42,7 +43,7 @@ static DIR *open_mountpoint(struct mount_info *pm); static int close_mountpoint(DIR *dfd); static struct mount_info *mnt_build_tree(struct mount_info *list); -static int validate_mounts(struct mount_info *info); +static int validate_mounts(struct mount_info *info, bool call_plugins); static inline int is_root(char *p) { @@ -294,7 +295,7 @@ static void mnt_tree_show(struct mount_info *tree, int off) pr_info("%*s<--\n", off, ""); } -static int validate_mounts(struct mount_info *info) +static int validate_mounts(struct mount_info *info, bool call_plugins) { struct mount_info *m, *t; @@ -325,9 +326,19 @@ static int validate_mounts(struct mount_info *info) break; } if (&t->mnt_bind == &m->mnt_bind) { - pr_err("%d:%s doesn't have a proper root mount\n", - m->mnt_id, m->mountpoint); - return -1; + int ret = -ENOTSUP; + + if (call_plugins) { + ret = cr_plugin_dump_ext_mount(m->mountpoint, m->mnt_id); + if (ret == 0) + m->need_plugin = true; + } + if (ret < 0) { + if (ret == -ENOTSUP) + pr_err("%d:%s doesn't have a proper root mount\n", + m->mnt_id, m->mountpoint); + return -1; + } } } @@ -716,7 +727,7 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd) return -1; } - if (pm->fstype->dump && pm->fstype->dump(pm)) + if (!pm->need_plugin && pm->fstype->dump && pm->fstype->dump(pm)) return -1; me.mnt_id = pm->mnt_id; @@ -731,6 +742,10 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd) me.has_shared_id = true; me.master_id = pm->master_id; me.has_master_id = true; + if (pm->need_plugin) { + me.has_with_plugin = true; + me.with_plugin = true; + } if (pb_write_one(fd, &me, PB_MNT)) return -1; @@ -756,7 +771,7 @@ int dump_mnt_ns(int ns_pid, int ns_id) if (mnt_build_tree(pm) == NULL) goto err; - if (validate_mounts(pm)) + if (validate_mounts(pm, true)) goto err; pr_info("Dumping mountpoints\n"); @@ -1297,7 +1312,7 @@ static int populate_mnt_ns(int ns_pid, struct mount_info *mis) if (!pms) return -1; - if (validate_mounts(pms)) + if (validate_mounts(pms, false)) return -1; mntinfo_tree = pms; diff --git a/plugin.c b/plugin.c index 222a2f598..434926546 100644 --- a/plugin.c +++ b/plugin.c @@ -19,6 +19,7 @@ struct cr_plugin_entry { cr_plugin_restore_unix_sk_t *cr_plugin_restore_unix_sk; cr_plugin_dump_file_t *cr_plugin_dump_file; cr_plugin_restore_file_t *cr_plugin_restore_file; + cr_plugin_dump_ext_mount_t *cr_plugin_dump_ext_mount; }; struct cr_plugin_entry *next; @@ -31,6 +32,7 @@ struct cr_plugins { struct cr_plugin_entry *cr_plugin_restore_unix_sk; struct cr_plugin_entry *cr_plugin_dump_file; struct cr_plugin_entry *cr_plugin_restore_file; + struct cr_plugin_entry *cr_plugin_dump_ext_mount; }; struct cr_plugins cr_plugins; @@ -87,6 +89,11 @@ int cr_plugin_restore_file(int id) return run_plugin_funcs(cr_plugin_restore_file, id); } +int cr_plugin_dump_ext_mount(char *mountpoint, int id) +{ + return run_plugin_funcs(cr_plugin_dump_ext_mount, mountpoint, id); +} + static int cr_lib_load(char *path) { struct cr_plugin_entry *ce; @@ -106,6 +113,8 @@ static int cr_lib_load(char *path) add_plugin_func(cr_plugin_dump_file); add_plugin_func(cr_plugin_restore_file); + add_plugin_func(cr_plugin_dump_ext_mount); + ce = NULL; f_fini = dlsym(h, "cr_plugin_fini"); if (f_fini) { diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto index ea1ad3c21..ab85de7ec 100644 --- a/protobuf/mnt.proto +++ b/protobuf/mnt.proto @@ -23,4 +23,6 @@ message mnt_entry { optional uint32 shared_id = 10; optional uint32 master_id = 11; + + optional bool with_plugin = 12; }