[CRIU] [PATCH 2/2] remap: add a dead pid /proc remap
Andrew Vagin
avagin at parallels.com
Tue Sep 9 03:26:04 PDT 2014
On Fri, Sep 05, 2014 at 02:38:05PM -0500, Tycho Andersen wrote:
> If a file like /proc/20/mountinfo is open, but 20 is a zombie (or doesn't exist
> any more), we can't read this file at all, so a link remap won't work. Instead,
> we add a new remap, called the dead process remap, which forks a TASK_HELPER as
> that dead pid so that the restore task can open the new /proc/20/mountinfo
> instead.
I would like to have a test case in the zdtm test suite for this case.
>
> Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
> ---
> files-reg.c | 73 +++++++++++++++++++++++++++++++++++++++++-
> include/fs-magic.h | 4 +++
> protobuf/remap-file-path.proto | 5 +++
> 3 files changed, 81 insertions(+), 1 deletion(-)
>
> diff --git a/files-reg.c b/files-reg.c
> index 0ffce0e..eadd15f 100644
> --- a/files-reg.c
> +++ b/files-reg.c
> @@ -24,6 +24,7 @@
> #include "asm/atomic.h"
> #include "namespaces.h"
> #include "proc_parse.h"
> +#include "pstree.h"
>
> #include "protobuf.h"
> #include "protobuf/regfile.pb-c.h"
> @@ -227,6 +228,28 @@ static int open_remap_linked(struct reg_file_info *rfi,
> return 0;
> }
>
> +static int open_remap_dead_process(struct reg_file_info *rfi,
> + RemapFilePathEntry *rfe)
> +{
> + struct pstree_item *helper;
> +
> + helper = alloc_pstree_item_with_rst();
> + if (!helper)
> + return -1;
> +
> + helper->sid = root_item->sid;
> + helper->pgid = root_item->sid;
> + helper->pid.virt = rfe->remap_id;
> + helper->state = TASK_HELPER;
> + helper->parent = root_item;
> + list_add_tail(&helper->sibling, &root_item->children);
> + task_entries->nr_helpers++;
> +
> + pr_info("Added a helper for restoring /proc/%d\n", helper->pid.virt);
> +
> + return 0;
> +}
> +
> static int collect_one_remap(void *obj, ProtobufCMessage *msg)
> {
> int ret = -1;
> @@ -248,8 +271,10 @@ static int collect_one_remap(void *obj, ProtobufCMessage *msg)
>
> if (rfe->remap_id & REMAP_GHOST)
> ret = open_remap_ghost(rfi, rfe);
> - else
> + else if (!rfe->has_remap_type)
I think we should have a separate type for this case.
> ret = open_remap_linked(rfi, rfe);
> + else if (rfe->remap_type == REMAP_TYPE__PROCFS)
> + ret = open_remap_dead_process(rfi, rfe);
> out:
> return ret;
> }
> @@ -498,6 +523,20 @@ static int dump_linked_remap(char *path, int len, const struct stat *ost,
> &rpe, PB_REMAP_FPATH);
> }
>
> +static int dump_dead_process_remap(pid_t pid, char *path, int len, const struct stat *ost,
> + int lfd, u32 id, struct ns_id *nsid)
> +{
> + RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT;
> +
> + rpe.orig_id = id;
> + rpe.remap_id = pid;
> + rpe.has_remap_type = true;
> + rpe.remap_type = REMAP_TYPE__PROCFS;
> +
> + return pb_write_one(fdset_fd(glob_fdset, CR_FD_REMAP_FPATH),
> + &rpe, PB_REMAP_FPATH);
> +}
> +
> static bool is_sillyrename_name(char *name)
> {
> int i;
> @@ -539,6 +578,38 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
> struct stat pst;
> const struct stat *ost = &parms->stat;
>
> + if (parms->fs_type == PROC_SUPER_MAGIC) {
> + /* The file points to /proc/pid/<foo> where pid is a dead
> + * process. We remap this file by adding this pid to be
> + * fork()ed into a TASK_HELPER state so that we can point to it
> + * on restore.
> + */
> + pid_t pid;
> + char *start, *end;
> +
> + /* skip "./proc/" */
> + start = strstr(rpath, "/") + 1;
> + if (!start)
> + return -1;
> + start = strstr(start, "/") + 1;
> + if (!start)
> + return -1;
> + pid = strtol(start, &end, 10);
> +
> + /* if we didn't find another /, this path something
> + * like ./proc/kmsg, which we shouldn't mess with. */
> + if (*end == '/') {
> + *end = 0;
> + ret = access(rpath, F_OK);
> + *end = '/';
> +
> + if (ret) {
> + pr_info("Dumping dead process remap of %d\n", pid);
> + return dump_dead_process_remap(pid, rpath + 1, plen - 1, ost, lfd, id, nsid);
> + }
> + }
> + }
> +
> if (ost->st_nlink == 0)
> /*
> * Unpleasant, but easy case. File is completely invisible
> diff --git a/include/fs-magic.h b/include/fs-magic.h
> index 13c4961..777d736 100644
> --- a/include/fs-magic.h
> +++ b/include/fs-magic.h
> @@ -41,4 +41,8 @@
> #define AUFS_SUPER_MAGIC 0x61756673
> #endif
>
> +#ifndef PROC_SUPER_MAGIC
> +#define PROC_SUPER_MAGIC 0x9fa0
> +#endif
> +
> #endif /* __CR_FS_MAGIC_H__ */
> diff --git a/protobuf/remap-file-path.proto b/protobuf/remap-file-path.proto
> index faeb745..294cdec 100644
> --- a/protobuf/remap-file-path.proto
> +++ b/protobuf/remap-file-path.proto
> @@ -1,4 +1,9 @@
> +enum remap_type {
Can we add a type for linked files? And I think its value should be 0.
LINKED = 0;
PROCFS = 1;
> + PROCFS = 0;
> +};
> +
> message remap_file_path_entry {
> required uint32 orig_id = 1;
> required uint32 remap_id = 2;
> + optional uint32 remap_type = 3;
> }
> --
> 1.9.1
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list