[CRIU] [PATCH 20/27] servicefd: add a service fd for current root
Andrey Vagin
avagin at openvz.org
Thu Apr 10 04:04:03 PDT 2014
It's already used for dumping files and it will be used for restoring,
so it should be service fd to avoid intersection with restored
descriptors.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 3 +++
files-reg.c | 11 +++++++++--
include/mount.h | 1 -
include/servicefd.h | 1 +
irmap.c | 10 +++++++++-
mount.c | 17 +++++++++++++----
sk-unix.c | 3 +++
7 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 3142e05..6a9c4e5 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2548,6 +2548,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
close_image_dir();
+ close_service_fd(PROC_FD_OFF);
+ close_service_fd(ROOT_FD_OFF);
+
__gcov_flush();
pr_info("task_args: %p\n"
diff --git a/files-reg.c b/files-reg.c
index 750b356..fba683b 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -334,10 +334,12 @@ dump_entry:
static void __rollback_link_remaps(bool do_unlink)
{
struct link_remap_rlb *rlb, *tmp;
+ int mntns_root;
if (!opts.link_remap_ok)
return;
+ mntns_root = get_service_fd(ROOT_FD_OFF);
list_for_each_entry_safe(rlb, tmp, &link_remaps, list) {
list_del(&rlb->list);
if (do_unlink)
@@ -356,6 +358,7 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
FownEntry fwn = FOWN_ENTRY__INIT;
struct link_remap_rlb *rlb;
+ int mntns_root;
if (!opts.link_remap_ok) {
pr_err("Can't create link remap for %s. "
@@ -363,6 +366,8 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
return -1;
}
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
/*
* Linked remapping -- we create a hard link on a removed file
* in the directory original file used to sit.
@@ -467,9 +472,9 @@ static inline bool nfs_silly_rename(char *rpath, const struct fd_parms *parms)
static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms, int lfd, u32 id)
{
- int ret;
- struct stat pst;
const struct stat *ost = &parms->stat;
+ int ret, mntns_root;
+ struct stat pst;
if (ost->st_nlink == 0)
/*
@@ -492,6 +497,8 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
return dump_linked_remap(rpath + 1, plen - 1, ost, lfd, id);
}
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
ret = fstatat(mntns_root, rpath, &pst, 0);
if (ret < 0) {
/*
diff --git a/include/mount.h b/include/mount.h
index 67c506e..b312c83 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -1,7 +1,6 @@
#ifndef __CR_MOUNT_H__
#define __CR_MOUNT_H__
-extern int mntns_root;
extern int mntns_collect_root(pid_t pid);
struct proc_mountinfo;
diff --git a/include/servicefd.h b/include/servicefd.h
index f855fe8..0e1992c 100644
--- a/include/servicefd.h
+++ b/include/servicefd.h
@@ -15,6 +15,7 @@ enum sfd_type {
* For dump -- target ns' proc
* For restore -- CRIU ns' proc
*/
+ ROOT_FD_OFF, /* paths are resolved relative to this root */
SERVICE_FD_MAX
};
diff --git a/irmap.c b/irmap.c
index 1af4a95..2be1331 100644
--- a/irmap.c
+++ b/irmap.c
@@ -67,10 +67,13 @@ static int irmap_update_stat(struct irmap *i)
{
struct stat st;
unsigned hv;
+ int mntns_root;
if (i->ino)
return 0;
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
pr_debug("Refresh stat for %s\n", i->path);
if (fstatat(mntns_root, i->path + 1, &st, AT_SYMLINK_NOFOLLOW)) {
pr_perror("Can't stat %s", i->path);
@@ -96,13 +99,15 @@ static int irmap_update_stat(struct irmap *i)
*/
static int irmap_update_dir(struct irmap *t)
{
- int fd, nr = 0, dlen;
+ int fd, nr = 0, dlen, mntns_root;
DIR *dfd;
struct dirent *de;
if (t->nr_kids >= 0)
return 0;
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
pr_debug("Refilling %s dir\n", t->path);
fd = openat(mntns_root, t->path + 1, O_RDONLY);
if (fd < 0) {
@@ -184,6 +189,9 @@ static struct irmap *irmap_scan(struct irmap *t, unsigned int dev, unsigned long
static int irmap_revalidate(struct irmap *c, struct irmap **p)
{
struct stat st;
+ int mntns_root;
+
+ mntns_root = get_service_fd(ROOT_FD_OFF);
pr_debug("Revalidate stat for %s\n", c->path);
if (fstatat(mntns_root, c->path + 1, &st, AT_SYMLINK_NOFOLLOW)) {
diff --git a/mount.c b/mount.c
index f807ba9..d606022 100644
--- a/mount.c
+++ b/mount.c
@@ -38,7 +38,6 @@ static struct mount_info *mntinfo;
* for umounting or path resolution.
*/
static struct mount_info *mntinfo_tree;
-int mntns_root = -1;
static DIR *open_mountpoint(struct mount_info *pm);
static int close_mountpoint(DIR *dfd);
@@ -74,6 +73,9 @@ static inline int fsroot_mounted(struct mount_info *mi)
int open_mount(unsigned int s_dev)
{
struct mount_info *i;
+ int mntns_root;
+
+ mntns_root = get_service_fd(ROOT_FD_OFF);
for (i = mntinfo; i != NULL; i = i->next)
if (s_dev == i->s_dev) {
@@ -525,6 +527,10 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
int ret;
if (mnt_fd == -1) {
+ int mntns_root;
+
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
snprintf(path, sizeof(path), ".%s", pm->mountpoint);
mnt_fd = openat(mntns_root, path, O_RDONLY);
if (mnt_fd < 0) {
@@ -1757,7 +1763,7 @@ int mntns_collect_root(pid_t pid)
int ret;
char path[PATH_MAX + 1];
- close_safe(&mntns_root);
+ close_service_fd(ROOT_FD_OFF);
if (!(root_ns_mask & CLONE_NEWNS)) {
/*
@@ -1804,8 +1810,11 @@ int mntns_collect_root(pid_t pid)
}
set_root:
- mntns_root = fd;
- return 0;
+ ret = 0;
+ if (install_service_fd(ROOT_FD_OFF, fd) < 0)
+ ret = -1;
+ close(fd);
+ return ret;
}
struct ns_desc mnt_ns_desc = NS_DESC_ENTRY(CLONE_NEWNS, "mnt");
diff --git a/sk-unix.c b/sk-unix.c
index c2991ae..a36a1a1 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -403,6 +403,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
struct stat st;
char rpath[PATH_MAX];
bool drop_path = false;
+ int mntns_root;
if (name[0] != '/') {
pr_warn("Relative bind path '%s' "
@@ -416,6 +417,8 @@ static int unix_collect_one(const struct unix_diag_msg *m,
goto skip;
}
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
snprintf(rpath, sizeof(rpath), ".%s", name);
if (fstatat(mntns_root, rpath, &st, 0)) {
--
1.8.5.3
More information about the CRIU
mailing list