[CRIU] [PATCH 2/2] remap: add a dead pid /proc remap
Tycho Andersen
tycho.andersen at canonical.com
Fri Sep 5 12:38:05 PDT 2014
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.
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)
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 {
+ 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
More information about the CRIU
mailing list