mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-28 21:07:43 +00:00
memfd: don't reopen file descriptors for memory mappings
One memfd can be shared by a few restored files. Only of these files is restored with a file created with memfd_open. Others are restored by reopening memfd files via /proc/self/fd/. It seems unnecessary for restoring memfd memory mappings. We can always use the origin file. Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
parent
28e854d662
commit
e86e8dac0d
@ -2509,7 +2509,7 @@ static int open_filemap(int pid, struct vma_area *vma)
|
|||||||
ret = plugin_fd;
|
ret = plugin_fd;
|
||||||
} else if (vma->e->status & VMA_AREA_MEMFD) {
|
} else if (vma->e->status & VMA_AREA_MEMFD) {
|
||||||
if (!inherited_fd(vma->vmfd, &ret))
|
if (!inherited_fd(vma->vmfd, &ret))
|
||||||
ret = memfd_open(vma->vmfd, &flags);
|
ret = memfd_open(vma->vmfd, &flags, true);
|
||||||
} else {
|
} else {
|
||||||
ret = open_path(vma->vmfd, do_open_reg_noseek_flags, &flags);
|
ret = open_path(vma->vmfd, do_open_reg_noseek_flags, &flags);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#ifndef __CR_MEMFD_H__
|
#ifndef __CR_MEMFD_H__
|
||||||
#define __CR_MEMFD_H__
|
#define __CR_MEMFD_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "int.h"
|
#include "int.h"
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ extern int is_memfd(dev_t dev);
|
|||||||
extern int dump_one_memfd_cond(int lfd, u32 *id, struct fd_parms *parms);
|
extern int dump_one_memfd_cond(int lfd, u32 *id, struct fd_parms *parms);
|
||||||
extern const struct fdtype_ops memfd_dump_ops;
|
extern const struct fdtype_ops memfd_dump_ops;
|
||||||
|
|
||||||
extern int memfd_open(struct file_desc *d, u32 *fdflags);
|
extern int memfd_open(struct file_desc *d, u32 *fdflags, bool filemap);
|
||||||
extern struct collect_image_info memfd_cinfo;
|
extern struct collect_image_info memfd_cinfo;
|
||||||
extern struct file_desc *collect_memfd(u32 id);
|
extern struct file_desc *collect_memfd(u32 id);
|
||||||
extern int apply_memfd_seals(void);
|
extern int apply_memfd_seals(void);
|
||||||
|
@ -323,7 +323,7 @@ static int memfd_open_inode(struct memfd_restore_inode *inode)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memfd_open(struct file_desc *d, u32 *fdflags)
|
int memfd_open(struct file_desc *d, u32 *fdflags, bool filemap)
|
||||||
{
|
{
|
||||||
struct memfd_info *mfi;
|
struct memfd_info *mfi;
|
||||||
MemfdFileEntry *mfe;
|
MemfdFileEntry *mfe;
|
||||||
@ -342,6 +342,9 @@ int memfd_open(struct file_desc *d, u32 *fdflags)
|
|||||||
/* Reopen the fd with original permissions */
|
/* Reopen the fd with original permissions */
|
||||||
flags = fdflags ? *fdflags : mfe->flags;
|
flags = fdflags ? *fdflags : mfe->flags;
|
||||||
|
|
||||||
|
if (filemap && (flags & O_ACCMODE) == O_RDWR)
|
||||||
|
return fd;
|
||||||
|
|
||||||
if (!mfi->inode->was_opened_rw && (flags & O_ACCMODE) == O_RDWR) {
|
if (!mfi->inode->was_opened_rw && (flags & O_ACCMODE) == O_RDWR) {
|
||||||
/*
|
/*
|
||||||
* If there is only a single RW-opened fd for a memfd, it can
|
* If there is only a single RW-opened fd for a memfd, it can
|
||||||
@ -367,7 +370,7 @@ int memfd_open(struct file_desc *d, u32 *fdflags)
|
|||||||
_fd = __open_proc(PROC_SELF, 0, flags, "fd/%d", fd);
|
_fd = __open_proc(PROC_SELF, 0, flags, "fd/%d", fd);
|
||||||
if (_fd < 0)
|
if (_fd < 0)
|
||||||
pr_perror("Can't reopen memfd id=%d", mfe->id);
|
pr_perror("Can't reopen memfd id=%d", mfe->id);
|
||||||
else if ((flags & O_ACCMODE) == O_RDWR)
|
else if (!filemap && (flags & O_ACCMODE) == O_RDWR)
|
||||||
pr_warn("execveat(fd=%d, ..., AT_EMPTY_PATH) might fail after restore; memfd id=%d\n", _fd, mfe->id);
|
pr_warn("execveat(fd=%d, ..., AT_EMPTY_PATH) might fail after restore; memfd id=%d\n", _fd, mfe->id);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -382,7 +385,7 @@ static int memfd_open_fe_fd(struct file_desc *d, int *new_fd)
|
|||||||
if (inherited_fd(d, new_fd))
|
if (inherited_fd(d, new_fd))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fd = memfd_open(d, NULL);
|
fd = memfd_open(d, NULL, false);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user