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:
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) {
/*
......
#ifndef __CR_MOUNT_H__
#define __CR_MOUNT_H__
extern int mntns_root;
extern int mntns_collect_root(pid_t pid);
struct proc_mountinfo;
......
......@@ -15,6 +15,7 @@ enum sfd_type {
* For dump -- target ns' proc
* For restore -- CRIU ns' proc
*/
ROOT_FD_OFF, /* Root of the namespace we dump/restore */
SERVICE_FD_MAX
};
......
......@@ -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)) {
......
......@@ -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) {
......@@ -484,6 +486,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) {
......@@ -1582,8 +1588,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");
......@@ -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)) {
......
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