[CRIU] [PATCH 02/15] restore: get real pid for each task (v2)
Andrey Vagin
avagin at openvz.org
Mon Sep 23 06:33:25 EDT 2013
For the root task the clone syscall returns the pid in criu's pidns,
but for other processes the clone syscall returns PID in the restored
namespace.
The /proc/self link contains the PID value of the current process, so if
we want to determing the PID in a criu's pidns, we should use criu's
/proc.
v2: readlink() does not append a null byte to buf, so we must do that
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 36 ++++++++++++++++++++++++++++++++++--
files.c | 1 +
include/crtools.h | 3 ++-
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index c35ec7f..71aae4d 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -953,7 +953,7 @@ static inline int fork_with_pid(struct pstree_item *item)
if (ret < 0)
pr_perror("Can't fork for %d", pid);
- if (ca.clone_flags & CLONE_NEWPID)
+ if (item == root_item)
item->pid.real = ret;
if (opts.pidfile && root_item == item) {
@@ -1149,6 +1149,27 @@ static int restore_task_with_children(void *_arg)
current = ca->item;
+ if (current != root_item) {
+ char buf[PATH_MAX];
+ int fd;
+
+ /* Determine PID in CRIU's namespace */
+ fd = get_service_fd(CR_PROC_FD_OFF);
+ if (fd < 0)
+ exit(1);
+
+ ret = readlinkat(fd, "self", buf, sizeof(buf) - 1);
+ if (ret < 0) {
+ pr_perror("Unable to read the /proc/self link");
+ exit(1);
+ }
+ buf[ret] = '\0';
+
+ current->pid.real = atoi(buf);
+ pr_debug("PID: real %d virt %d\n",
+ current->pid.real, current->pid.virt);
+ }
+
if ( !(ca->clone_flags & CLONE_FILES))
close_safe(&ca->fd);
@@ -1293,9 +1314,20 @@ static int restore_switch_stage(int next_stage)
static int restore_root_task(struct pstree_item *init)
{
- int ret;
+ int ret, fd;
struct sigaction act, old_act;
+ fd = open("/proc", O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ pr_perror("Unable to open /proc");
+ return -1;
+ }
+
+ ret = install_service_fd(CR_PROC_FD_OFF, fd);
+ close(fd);
+ if (ret < 0)
+ return -1;
+
ret = sigaction(SIGCHLD, NULL, &act);
if (ret < 0) {
pr_perror("sigaction() failed");
diff --git a/files.c b/files.c
index 8193d59..e194a22 100644
--- a/files.c
+++ b/files.c
@@ -933,6 +933,7 @@ int prepare_fds(struct pstree_item *me)
if (me->rst->fdt)
futex_inc_and_wake(&me->rst->fdt->fdt_lock);
out:
+ close_service_fd(CR_PROC_FD_OFF);
tty_fini_fds();
return ret;
}
diff --git a/include/crtools.h b/include/crtools.h
index f15cbc6..a574b46 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -54,10 +54,11 @@ enum sfd_type {
LOG_FD_OFF,
LOG_DIR_FD_OFF,
IMG_FD_OFF,
- PROC_FD_OFF,
+ PROC_FD_OFF, /* /proc in the restored pidns */
CTL_TTY_OFF,
SELF_STDIN_OFF,
PARENT_FD_OFF,
+ CR_PROC_FD_OFF, /* /proc in criu's pidns */
SERVICE_FD_MAX
};
--
1.8.3.1
More information about the CRIU
mailing list