[CRIU] [PATCH v3 2/4] mount: Add forced mounts sceleton
Pavel Emelyanov
xemul at virtuozzo.com
Wed Jul 13 05:46:36 PDT 2016
On 06/29/2016 02:49 PM, Kirill Tkhai wrote:
> Mechanism for mounts, which are forced by criu during dump stage.
>
> v2: New patch, splitted from v1's "[2/3] mount: Forced mount unmounted binfmt_misc to do not lost its content"
> Cleanup for dump failed case is added
>
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
> criu/cr-dump.c | 1 +
> criu/include/mount.h | 1 +
> criu/mount.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 78 insertions(+)
>
> diff --git a/criu/cr-dump.c b/criu/cr-dump.c
> index 00d28e9..7609544 100644
> --- a/criu/cr-dump.c
> +++ b/criu/cr-dump.c
> @@ -1588,6 +1588,7 @@ static int cr_dump_finish(int ret)
> if (ret || post_dump_ret || opts.final_state == TASK_ALIVE) {
> network_unlock();
> delete_link_remaps();
> + cleanup_forced_mounts();
> }
> pstree_switch_state(root_item,
> (ret || post_dump_ret) ?
> diff --git a/criu/include/mount.h b/criu/include/mount.h
> index c7992ac..423b6d0 100644
> --- a/criu/include/mount.h
> +++ b/criu/include/mount.h
> @@ -127,5 +127,6 @@ extern int ext_mount_add(char *key, char *val);
> extern int mntns_maybe_create_roots(void);
> extern int read_mnt_ns_img(void);
> extern void cleanup_mnt_ns(void);
> +extern void cleanup_forced_mounts(void);
>
> #endif /* __CR_MOUNT_H__ */
> diff --git a/criu/mount.c b/criu/mount.c
> index 55f248d..4a288e4 100644
> --- a/criu/mount.c
> +++ b/criu/mount.c
> @@ -41,6 +41,15 @@
> #define LOG_PREFIX "mnt: "
>
> static struct fstype fstypes[];
> +static LIST_HEAD(forced_mounts_list);
> +
> +struct forced_mount {
> + struct list_head list;
> + unsigned int ns_id;
> + unsigned int mnt_id;
> + char *path;
> + pid_t pid;
> +};
Why separate structure? We have mount_info already, let's add
necessary flags on it.
>
> int ext_mount_add(char *key, char *val)
> {
> @@ -3685,4 +3694,71 @@ int dump_mnt_namespaces(void)
> return 0;
> }
>
> +static int add_forced_mount(pid_t pid, const char *path)
> +{
> + struct forced_mount *fm;
> + int fd, mnt_id, ret = 0;
> + unsigned int ns_id;
> +
> + if (read_ns_id(pid, &mnt_ns_desc, &ns_id) < 0 || !ns_id) {
I don't get why we need to read this stuff from kernel, while we have all
the ns_id engine at hands. If you need to add binfmt_misc mountpoint, you
want it per-namespace, not per-task, don't you?
> + pr_err("Can't read mnt_ns id\n");
> + return -1;
> + }
> +
> + fm = xmalloc(sizeof(*fm));
> + if (!fm)
> + return -1;
> +
> + fd = open(path, O_PATH|O_DIRECTORY);
> + if (fd < 0) {
> + pr_perror("Can't open %s\n", path);
> + goto err_free;
> + }
> +
> + ret = get_fd_mntid(fd, &mnt_id);
> + close(fd);
> +
> + if (ret < 0) {
> + pr_err("Can't get mnt_id of %s\n", path);
> + goto err_free;
> + }
> +
> + fm->path = xstrdup(path);
> + if (!fm->path)
> + goto err_free;
> +
> + fm->ns_id = ns_id;
> + fm->mnt_id = mnt_id;
> + fm->pid = pid;
> + list_add(&fm->list, &forced_mounts_list);
> +
> + return 0;
> +err_free:
> + pr_err("Can't add forced mount\n");
> + free(fm);
> + return -1;
> +}
> +
> +void cleanup_forced_mounts(void)
> +{
> + struct forced_mount *fm;
> + int mnt_fd, ret;
> +
> + list_for_each_entry(fm, &forced_mounts_list, list) {
> + ret = switch_ns(fm->pid, &mnt_ns_desc, &mnt_fd);
> + if (ret) {
> + pr_err("Can't switch to pid's %u mnt_ns\n", fm->pid);
> + continue;
> + }
> +
> + if (umount(fm->path) < 0)
> + pr_perror("Can't umount forced mount %s\n", fm->path);
> +
> + if (restore_ns(mnt_fd, &mnt_ns_desc)) {
> + pr_err("cleanup_forced_mounts exiting with wrong mnt_ns\n");
> + return;
> + }
> + }
> +}
> +
> struct ns_desc mnt_ns_desc = NS_DESC_ENTRY(CLONE_NEWNS, "mnt");
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
> .
>
More information about the CRIU
mailing list