[CRIU] [PATCH 2/4] servicefd: add a service fd for current root
Andrey Vagin
avagin at openvz.org
Tue Apr 15 01:31:40 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>
---
files-reg.c | 10 +++++++++-
include/mount.h | 1 -
include/servicefd.h | 1 +
irmap.c | 10 +++++++++-
mount.c | 13 ++++++++++---
sk-unix.c | 3 +++
6 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/files-reg.c b/files-reg.c
index 7c783b5..5b6c4a3 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -333,10 +333,13 @@ 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)
@@ -355,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. "
@@ -389,6 +393,8 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
/* Any 'unique' name works here actually. Remap works by reg-file ids. */
snprintf(tmp + 1, sizeof(link_name) - (size_t)(tmp - link_name - 1), "link_remap.%d", rfe.id);
+ mntns_root = get_service_fd(ROOT_FD_OFF);
+
if (linkat(lfd, "", mntns_root, link_name, AT_EMPTY_PATH) < 0) {
pr_perror("Can't link remap to %s", path);
return -1;
@@ -466,7 +472,7 @@ 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;
+ int ret, mntns_root;
struct stat pst;
const struct stat *ost = &parms->stat;
@@ -491,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 a76c027..a2bc17d 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..1cf93de 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,
SERVICE_FD_MAX
};
diff --git a/irmap.c b/irmap.c
index 1af4a95..22750d2 100644
--- a/irmap.c
+++ b/irmap.c
@@ -66,11 +66,14 @@ static struct irmap hints[] = {
static int irmap_update_stat(struct irmap *i)
{
struct stat st;
+ int mntns_root;
unsigned hv;
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 0dcfcfd..adce76a 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 int open_mountpoint(struct mount_info *pm);
@@ -73,6 +72,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) {
@@ -482,6 +484,10 @@ static int __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) {
@@ -1569,8 +1575,9 @@ int mntns_collect_root(pid_t pid)
}
set_root:
- mntns_root = fd;
- return 0;
+ ret = install_service_fd(ROOT_FD_OFF, fd);
+ close(fd);
+ return ret < 0 ? -1 : 0;
}
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