2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 05:48:05 +00:00

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.

v3: Add criu feature check

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Kirill Tkhai 2017-04-10 11:16:03 +03:00 committed by Andrei Vagin
parent 9e5945ce87
commit 0e245fca75
4 changed files with 48 additions and 0 deletions

View File

@ -1073,6 +1073,17 @@ static int check_sk_netns(void)
return 0; 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); static int (*chk_feature)(void);
/* /*
@ -1180,6 +1191,7 @@ int cr_check(void)
ret |= check_uffd(); ret |= check_uffd();
ret |= check_uffd_noncoop(); ret |= check_uffd_noncoop();
ret |= check_sk_netns(); ret |= check_sk_netns();
ret |= check_ns_pid();
} }
/* /*
@ -1261,6 +1273,7 @@ static struct feature_list feature_list[] = {
{ "sk_ns", check_sk_netns }, { "sk_ns", check_sk_netns },
{ "nsid", check_nsid }, { "nsid", check_nsid },
{ "link_nsid", check_link_nsid}, { "link_nsid", check_link_nsid},
{ "ns_pid", check_ns_pid},
{ NULL, NULL }, { NULL, NULL },
}; };

View File

@ -66,6 +66,7 @@ struct kerndat_s {
#endif #endif
bool has_nsid; bool has_nsid;
bool has_link_nsid; bool has_link_nsid;
bool has_nspid;
}; };
extern struct kerndat_s kdat; extern struct kerndat_s kdat;
@ -88,5 +89,6 @@ extern int kerndat_fs_virtualized(unsigned int which, u32 kdev);
extern int kerndat_tcp_repair(); extern int kerndat_tcp_repair();
extern int kerndat_uffd(void); extern int kerndat_uffd(void);
extern int kerndat_has_nspid(void);
#endif /* __CR_KERNDAT_H__ */ #endif /* __CR_KERNDAT_H__ */

View File

@ -848,6 +848,32 @@ out_unmap:
return ret; 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 kerndat_init(void)
{ {
int ret; int ret;
@ -904,6 +930,8 @@ int kerndat_init(void)
ret = kerndat_socket_netns(); ret = kerndat_socket_netns();
if (!ret) if (!ret)
ret = kerndat_nsid(); ret = kerndat_nsid();
if (!ret)
ret = kerndat_has_nspid();
kerndat_lsm(); kerndat_lsm();
kerndat_mmap_min_addr(); kerndat_mmap_min_addr();

View File

@ -26,6 +26,7 @@
#include "namespaces.h" #include "namespaces.h"
#include "net.h" #include "net.h"
#include "cgroup.h" #include "cgroup.h"
#include "kerndat.h"
#include "protobuf.h" #include "protobuf.h"
#include "util.h" #include "util.h"
@ -803,6 +804,10 @@ static int set_ns_hookups(struct ns_id *ns)
pr_err("Wrong determined NS_ROOT, or root_item has NS_OTHER user_ns\n"); pr_err("Wrong determined NS_ROOT, or root_item has NS_OTHER user_ns\n");
goto out; goto out;
} }
if (nd == &pid_ns_desc && !kdat.has_nspid) {
pr_err("Can't dump nested pid ns\n");
goto out;
}
list_add(&ns->siblings, &ns->parent->children); list_add(&ns->siblings, &ns->parent->children);
} }