Commit 87a49bdf authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

servicefd: add a service fd for current root

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 302591aa
...@@ -333,10 +333,13 @@ dump_entry: ...@@ -333,10 +333,13 @@ dump_entry:
static void __rollback_link_remaps(bool do_unlink) static void __rollback_link_remaps(bool do_unlink)
{ {
struct link_remap_rlb *rlb, *tmp; struct link_remap_rlb *rlb, *tmp;
int mntns_root;
if (!opts.link_remap_ok) if (!opts.link_remap_ok)
return; return;
mntns_root = get_service_fd(ROOT_FD_OFF);
list_for_each_entry_safe(rlb, tmp, &link_remaps, list) { list_for_each_entry_safe(rlb, tmp, &link_remaps, list) {
list_del(&rlb->list); list_del(&rlb->list);
if (do_unlink) if (do_unlink)
...@@ -355,6 +358,7 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp) ...@@ -355,6 +358,7 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
RegFileEntry rfe = REG_FILE_ENTRY__INIT; RegFileEntry rfe = REG_FILE_ENTRY__INIT;
FownEntry fwn = FOWN_ENTRY__INIT; FownEntry fwn = FOWN_ENTRY__INIT;
struct link_remap_rlb *rlb; struct link_remap_rlb *rlb;
int mntns_root;
if (!opts.link_remap_ok) { if (!opts.link_remap_ok) {
pr_err("Can't create link remap for %s. " 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) ...@@ -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. */ /* 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); 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) { if (linkat(lfd, "", mntns_root, link_name, AT_EMPTY_PATH) < 0) {
pr_perror("Can't link remap to %s", path); pr_perror("Can't link remap to %s", path);
return -1; return -1;
...@@ -466,7 +472,7 @@ static inline bool nfs_silly_rename(char *rpath, const struct fd_parms *parms) ...@@ -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) 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; struct stat pst;
const struct stat *ost = &parms->stat; const struct stat *ost = &parms->stat;
...@@ -491,6 +497,8 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms, ...@@ -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); 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); ret = fstatat(mntns_root, rpath, &pst, 0);
if (ret < 0) { if (ret < 0) {
/* /*
......
#ifndef __CR_MOUNT_H__ #ifndef __CR_MOUNT_H__
#define __CR_MOUNT_H__ #define __CR_MOUNT_H__
extern int mntns_root;
extern int mntns_collect_root(pid_t pid); extern int mntns_collect_root(pid_t pid);
struct proc_mountinfo; struct proc_mountinfo;
......
...@@ -15,6 +15,7 @@ enum sfd_type { ...@@ -15,6 +15,7 @@ enum sfd_type {
* For dump -- target ns' proc * For dump -- target ns' proc
* For restore -- CRIU ns' proc * For restore -- CRIU ns' proc
*/ */
ROOT_FD_OFF, /* Root of the namespace we dump/restore */
SERVICE_FD_MAX SERVICE_FD_MAX
}; };
......
...@@ -66,11 +66,14 @@ static struct irmap hints[] = { ...@@ -66,11 +66,14 @@ static struct irmap hints[] = {
static int irmap_update_stat(struct irmap *i) static int irmap_update_stat(struct irmap *i)
{ {
struct stat st; struct stat st;
int mntns_root;
unsigned hv; unsigned hv;
if (i->ino) if (i->ino)
return 0; return 0;
mntns_root = get_service_fd(ROOT_FD_OFF);
pr_debug("Refresh stat for %s\n", i->path); pr_debug("Refresh stat for %s\n", i->path);
if (fstatat(mntns_root, i->path + 1, &st, AT_SYMLINK_NOFOLLOW)) { if (fstatat(mntns_root, i->path + 1, &st, AT_SYMLINK_NOFOLLOW)) {
pr_perror("Can't stat %s", i->path); pr_perror("Can't stat %s", i->path);
...@@ -96,13 +99,15 @@ static int irmap_update_stat(struct irmap *i) ...@@ -96,13 +99,15 @@ static int irmap_update_stat(struct irmap *i)
*/ */
static int irmap_update_dir(struct irmap *t) static int irmap_update_dir(struct irmap *t)
{ {
int fd, nr = 0, dlen; int fd, nr = 0, dlen, mntns_root;
DIR *dfd; DIR *dfd;
struct dirent *de; struct dirent *de;
if (t->nr_kids >= 0) if (t->nr_kids >= 0)
return 0; return 0;
mntns_root = get_service_fd(ROOT_FD_OFF);
pr_debug("Refilling %s dir\n", t->path); pr_debug("Refilling %s dir\n", t->path);
fd = openat(mntns_root, t->path + 1, O_RDONLY); fd = openat(mntns_root, t->path + 1, O_RDONLY);
if (fd < 0) { if (fd < 0) {
...@@ -184,6 +189,9 @@ static struct irmap *irmap_scan(struct irmap *t, unsigned int dev, unsigned long ...@@ -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) static int irmap_revalidate(struct irmap *c, struct irmap **p)
{ {
struct stat st; struct stat st;
int mntns_root;
mntns_root = get_service_fd(ROOT_FD_OFF);
pr_debug("Revalidate stat for %s\n", c->path); pr_debug("Revalidate stat for %s\n", c->path);
if (fstatat(mntns_root, c->path + 1, &st, AT_SYMLINK_NOFOLLOW)) { if (fstatat(mntns_root, c->path + 1, &st, AT_SYMLINK_NOFOLLOW)) {
......
...@@ -38,7 +38,6 @@ static struct mount_info *mntinfo; ...@@ -38,7 +38,6 @@ static struct mount_info *mntinfo;
* for umounting or path resolution. * for umounting or path resolution.
*/ */
static struct mount_info *mntinfo_tree; static struct mount_info *mntinfo_tree;
int mntns_root = -1;
static DIR *open_mountpoint(struct mount_info *pm); static DIR *open_mountpoint(struct mount_info *pm);
static int close_mountpoint(DIR *dfd); static int close_mountpoint(DIR *dfd);
...@@ -74,6 +73,9 @@ static inline int fsroot_mounted(struct mount_info *mi) ...@@ -74,6 +73,9 @@ static inline int fsroot_mounted(struct mount_info *mi)
int open_mount(unsigned int s_dev) int open_mount(unsigned int s_dev)
{ {
struct mount_info *i; struct mount_info *i;
int mntns_root;
mntns_root = get_service_fd(ROOT_FD_OFF);
for (i = mntinfo; i != NULL; i = i->next) for (i = mntinfo; i != NULL; i = i->next)
if (s_dev == i->s_dev) { if (s_dev == i->s_dev) {
...@@ -484,6 +486,10 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd) ...@@ -484,6 +486,10 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
int ret; int ret;
if (mnt_fd == -1) { if (mnt_fd == -1) {
int mntns_root;
mntns_root = get_service_fd(ROOT_FD_OFF);
snprintf(path, sizeof(path), ".%s", pm->mountpoint); snprintf(path, sizeof(path), ".%s", pm->mountpoint);
mnt_fd = openat(mntns_root, path, O_RDONLY); mnt_fd = openat(mntns_root, path, O_RDONLY);
if (mnt_fd < 0) { if (mnt_fd < 0) {
...@@ -1582,8 +1588,9 @@ int mntns_collect_root(pid_t pid) ...@@ -1582,8 +1588,9 @@ int mntns_collect_root(pid_t pid)
} }
set_root: set_root:
mntns_root = fd; ret = install_service_fd(ROOT_FD_OFF, fd);
return 0; close(fd);
return ret < 0 ? -1 : 0;
} }
struct ns_desc mnt_ns_desc = NS_DESC_ENTRY(CLONE_NEWNS, "mnt"); struct ns_desc mnt_ns_desc = NS_DESC_ENTRY(CLONE_NEWNS, "mnt");
...@@ -403,6 +403,7 @@ static int unix_collect_one(const struct unix_diag_msg *m, ...@@ -403,6 +403,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
struct stat st; struct stat st;
char rpath[PATH_MAX]; char rpath[PATH_MAX];
bool drop_path = false; bool drop_path = false;
int mntns_root;
if (name[0] != '/') { if (name[0] != '/') {
pr_warn("Relative bind path '%s' " pr_warn("Relative bind path '%s' "
...@@ -416,6 +417,8 @@ static int unix_collect_one(const struct unix_diag_msg *m, ...@@ -416,6 +417,8 @@ static int unix_collect_one(const struct unix_diag_msg *m,
goto skip; goto skip;
} }
mntns_root = get_service_fd(ROOT_FD_OFF);
uv = RTA_DATA(tb[UNIX_DIAG_VFS]); uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
snprintf(rpath, sizeof(rpath), ".%s", name); snprintf(rpath, sizeof(rpath), ".%s", name);
if (fstatat(mntns_root, rpath, &st, 0)) { if (fstatat(mntns_root, rpath, &st, 0)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment