[CRIU] [RFC PATCH 2/5] autofs: dump stage introduced
Pavel Emelyanov
xemul at parallels.com
Mon Nov 23 11:21:39 PST 2015
On 11/23/2015 08:22 PM, Stanislav Kinsburskiy wrote:
> Autofs doesn't need any special dump tricks.
> However, we don't want to dump it, if controlling pipe is not empty, because
> it means, that kernel has some state, which we don't want to carry with us.
>
> We also need to update mount options, because "pgrp=" option content is pid
> namespace dependant. There are two ways how to do so:
> 1) Clone a process in desired pid namespace and collect mounts within it or
> 2) Replace AutoFS real prgp with container's one on dump.
>
> This patch implements the second.
>
> Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
> ---
> mount.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 144 insertions(+)
>
> diff --git a/mount.c b/mount.c
> index 562d6ca..c07d2d1 100644
> --- a/mount.c
> +++ b/mount.c
> @@ -1383,6 +1383,145 @@ static int always_fail(struct mount_info *pm)
> return -1;
> }
>
> +/*
> + * AutoFS options have to be fixed:
> + * - "timeout" have to be removed
Why?
> + * - "pgrp" have to be updated to virtual pid value
> + */
> +static int autofs_fixup_options(struct mount_info *new)
> +{
> + char **options;
> + int nr_opts, i, err = -1;
> +
> + split(new->options, ',', &options, &nr_opts);
> + if (!options)
> + return -1;
> +
> + xfree(new->options);
> + new->options = xzalloc(1);
> + if (!new->options)
> + return -ENOMEM;
> +
> + for (i = 0; i < nr_opts; i++) {
> + char *opt = options[i];
> +
> + if (!strncmp(opt, "timeout=", strlen("timeout=")))
> + continue;
> + if (!strncmp(opt, "pgrp=", strlen("pgrp="))) {
> + int real_pid, virt_pid = -1;
> + struct pstree_item *item;
> +
> + if (sscanf(opt, "pgrp=%d", &real_pid) != 1) {
> + pr_err("Failed to get pgrp: %s\n", opt);
> + goto out;
> + }
> +
> + for_each_pstree_item(item) {
> + if (item->pid.real == real_pid) {
> + virt_pid = item->pid.virt;
> + break;
> + }
> + }
We have pid_in_pstree() helper doing almost the same. Plz, fix one to
return either item with matching pid, or vpid itself.
> + pr_info("real pid: %d, virt pid: %d\n", real_pid, virt_pid);
> +
> + if (virt_pid == -1) {
> + pr_err("Failed to find process entry %d\n",
> + real_pid);
> + goto out;
> + }
> +
> + /* This should be enough: "pgrp=" + pid */
> + opt = xrealloc(opt, 32);
> + if (!opt)
> + goto out;
> +
> + if (snprintf(opt, 32, "pgrp=%d", virt_pid) == 32)
Comment above says it should be enough space in opt variable.
> + return -1;
> +
> + options[i] = opt;
> + }
> +
> + if (attach_option(new, opt))
> + goto out;
> + }
> +
> + err = 0;
> +out:
> + for (i = 0; i < nr_opts; i++)
> + xfree(options[i]);
> + xfree(options);
> + return err;
> +}
> +
> +static int autofs_dump(struct mount_info *pm)
> +{
> + unsigned pgrp, fd;
> + int pipe_fd, pipe_size, steal_pipe[2];
> + ssize_t bytes;
> + int err;
> +
> + /* TODO: we are called wthin proper pid namespace. We can't use blobal
> + * proc and have to mount proc somewhere */
What does this comment mean?
> +
> + pr_info("autofs mount options: %s\n", pm->options);
> + if (sscanf(pm->options, "fd=%d,pgrp=%d%*s", &fd, &pgrp) != 2) {
> + pr_err("Unsupported autofs mount options: %s\n", pm->options);
> + return -EINVAL;
> + }
> +
> + pr_info("automount: pgrp: %d, fd: %d\n", pgrp, fd);
> +
> + pipe_fd = open_proc(pgrp, "fd/%d", fd);
> + if (pipe_fd < 0) {
> + pr_perror("Can't open automount pipe\n");
> + return pipe_fd;
> + }
> +
> + pipe_size = fcntl(pipe_fd, F_GETPIPE_SZ);
> + if (pipe_size < 0) {
> + err = -errno;
> + pr_perror("Can't obtain piped data size\n");
> + goto close_pipe;
> + }
> +
> + if (pipe(steal_pipe) < 0) {
> + err = -errno;
> + pr_perror("Can't create pipe for stealing data");
> + goto close_pipe;
> + }
> +
> + bytes = tee(pipe_fd, steal_pipe[1], pipe_size, SPLICE_F_NONBLOCK);
> + if (bytes < 0) {
> + if (errno != EAGAIN) {
> + err = -errno;
> + pr_perror("Can't pick pipe data");
> + goto close_steal;
> + }
> +
> + bytes = 0;
> + }
> +
> + if (bytes) {
> + err = -ENOTSUP;
> + pr_perror("Can't dump autofs mount, when autmount pipe is not empty\n");
> + goto close_steal;
> + }
There's an fd_fas_data() helper out there. Does it work for this case?
> +
> + err = autofs_fixup_options(pm);
> + if (err)
> + goto close_steal;
> +
> + err = 0;
> +
> +close_steal:
> + close(steal_pipe[0]);
> + close(steal_pipe[1]);
> +close_pipe:
> + close(pipe_fd);
> + return err;
> +}
> +
> static struct fstype fstypes[32] = {
> {
> .name = "unsupported",
> @@ -1451,6 +1590,11 @@ static struct fstype fstypes[32] = {
> .name = "overlay",
> .code = FSTYPE__OVERLAYFS,
> .parse = overlayfs_parse,
> + }, {
> + .name = "autofs",
> + .code = FSTYPE__AUTOFS,
> + .dump = autofs_dump,
> + .restore = always_fail,
> },
> };
>
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
> .
>
More information about the CRIU
mailing list