From a692a0d0af41f65b46c1246f2b09f4c6af779dc0 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 10 Apr 2017 11:16:03 +0300 Subject: [PATCH] kerndat: Check that "/proc/[pid]/status" file has NS{pid, ..} lines If there is nested pid_ns, we need to be able to get pid in the whole pid hierarhy. This may be taken from "/proc/[pid]/status" file only. Check, that kernel has support for it. Signed-off-by: Kirill Tkhai NSpid is not (yet) supported on Centos7 thus we need this check for compatibility. (cherry-picked from Virtuozzo criu commit https://src.openvz.org/projects/OVZ/repos/criu/commits/94f4653f20) Signed-off-by: Pavel Tikhomirov --- criu/cr-check.c | 13 +++++++++++++ criu/include/kerndat.h | 3 +++ criu/kerndat.c | 31 +++++++++++++++++++++++++++++++ criu/namespaces.c | 1 + 4 files changed, 48 insertions(+) diff --git a/criu/cr-check.c b/criu/cr-check.c index fda17cc53..d35b1bffe 100644 --- a/criu/cr-check.c +++ b/criu/cr-check.c @@ -1346,6 +1346,17 @@ static int check_pidfd_store(void) return 0; } +static int check_ns_pid(void) +{ + if (kerndat_has_nspid() < 0) + return -1; + + if (!kdat.has_nspid) + return -1; + + return 0; +} + static int (*chk_feature)(void); /* @@ -1459,6 +1470,7 @@ int cr_check(void) ret |= check_time_namespace(); ret |= check_newifindex(); ret |= check_pidfd_store(); + ret |= check_ns_pid(); } /* @@ -1568,6 +1580,7 @@ static struct feature_list feature_list[] = { { "nftables", check_nftables_cr }, { "has_ipt_legacy", check_ipt_legacy }, { "pidfd_store", check_pidfd_store }, + { "ns_pid", check_ns_pid }, { NULL, NULL }, }; diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index df57ca185..97dbd17b3 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -71,6 +71,7 @@ struct kerndat_s { bool has_newifindex; bool has_pidfd_open; bool has_pidfd_getfd; + bool has_nspid; }; extern struct kerndat_s kdat; @@ -91,4 +92,6 @@ enum { */ extern int kerndat_fs_virtualized(unsigned int which, u32 kdev); +extern int kerndat_has_nspid(void); + #endif /* __CR_KERNDAT_H__ */ diff --git a/criu/kerndat.c b/criu/kerndat.c index 1e0e2817b..f418f42bd 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -1133,6 +1133,33 @@ out: return ret; } +int kerndat_has_nspid(void) +{ + struct bfd f; + int ret = -1; + char *str; + + f.fd = open("/proc/self/status", O_RDONLY); + if (f.fd < 0) { + pr_perror("Can't open /proc/self/status"); + return -1; + } + if (bfdopenr(&f)) + return -1; + while ((str = breadline(&f)) != NULL) { + if (IS_ERR(str)) + goto close; + if (!strncmp(str, "NSpid:", 6)) { + kdat.has_nspid = true; + break; + } + } + ret = 0; +close: + bclose(&f); + return ret; +} + int kerndat_init(void) { int ret; @@ -1276,6 +1303,10 @@ int kerndat_init(void) } if (!ret) kerndat_has_pidfd_open(); + if (!ret && kerndat_has_nspid()) { + pr_err("kerndat_has_nspid failed when initializing kerndat.\n"); + ret = -1; + } kerndat_lsm(); kerndat_mmap_min_addr(); diff --git a/criu/namespaces.c b/criu/namespaces.c index aecc82f66..b441d2a60 100644 --- a/criu/namespaces.c +++ b/criu/namespaces.c @@ -27,6 +27,7 @@ #include "net.h" #include "cgroup.h" #include "fdstore.h" +#include "kerndat.h" #include "protobuf.h" #include "util.h"