[CRIU] [PATCH 2/3] file: add a general approach for external files
Andrey Vagin
avagin at openvz.org
Wed Jan 20 18:07:04 PST 2016
From: Andrew Vagin <avagin at virtuozzo.com>
The idea is to call open_cb for /proc/self/fd/X,
where X is an externa file descriptor.
This approach works for files and fifo.
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
crtools.c | 2 ++
files-reg.c | 29 +++++++++++++++++++++++++----
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/crtools.c b/crtools.c
index 039b7a0..fa27622 100644
--- a/crtools.c
+++ b/crtools.c
@@ -781,6 +781,7 @@ usage:
" --external RES dump objects from this list as external resources:\n"
" Formats of RES:\n"
" tty[rdev:dev]\n"
+" files[mnt_id:inode]\n"
" --inherit-fd fd[<num>]:<existing>\n"
" Inherit file descriptors. This allows to treat file descriptor\n"
" <num> as being already opened via <existing> one and instead of\n"
@@ -788,6 +789,7 @@ usage:
" tty[rdev:dev]\n"
" pipe[inode]\n"
" socket[inode]\n"
+" files[mnt_id:inode]\n"
"\n"
"* Logging:\n"
" -o|--log-file FILE log file name\n"
diff --git a/files-reg.c b/files-reg.c
index ea66af0..ec74272 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -1021,6 +1021,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
struct fd_link _link, *link;
struct ns_id *nsid;
struct cr_img *rimg;
+ char ext_id[64];
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
@@ -1031,6 +1032,14 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
} else
link = p->link;
+
+ snprintf(ext_id, sizeof(ext_id), "@file[%x:%"PRIx64"]", p->mnt_id, p->stat.st_ino);
+ if (external_lookup_id(ext_id + 1)) {
+ /* the first symbol will be cut on restore to get an relative path*/
+ rfe.name = xstrdup(ext_id);
+ goto ext;
+ }
+
nsid = lookup_nsid_by_mnt_id(p->mnt_id);
if (nsid == NULL) {
pr_err("Can't lookup mount=%d for fd=%d path=%s\n",
@@ -1056,12 +1065,12 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
if (check_path_remap(link, p, lfd, id, nsid))
return -1;
-
+ rfe.name = &link->name[1];
+ext:
rfe.id = id;
rfe.flags = p->flags;
rfe.pos = p->pos;
rfe.fown = (FownEntry *)&p->fown;
- rfe.name = &link->name[1];
if (S_ISREG(p->stat.st_mode) && should_check_size(rfe.flags)) {
rfe.has_size = true;
@@ -1216,11 +1225,22 @@ int open_path(struct file_desc *d,
struct reg_file_info *rfi;
int tmp, mntns_root;
char *orig_path = NULL;
+ char path[PATH_MAX];
if (inherited_fd(d, &tmp))
return tmp;
rfi = container_of(d, struct reg_file_info, d);
+
+ tmp = inherit_fd_lookup_id(rfi->path);
+ if (tmp >= 0) {
+ mntns_root = open_pid_proc(PROC_SELF);
+ snprintf(path, sizeof(path), "fd/%d", tmp);
+ orig_path = rfi->path;
+ rfi->path = path;
+ goto ext;
+ }
+
if (rfi->remap) {
mutex_lock(ghost_file_mutex);
if (rfi->remap->is_dir) {
@@ -1262,6 +1282,7 @@ int open_path(struct file_desc *d,
}
mntns_root = mntns_get_root_by_mnt_id(rfi->rfe->mnt_id);
+ext:
tmp = open_cb(mntns_root, rfi, arg);
if (tmp < 0) {
pr_perror("Can't open file %s", rfi->path);
@@ -1303,10 +1324,10 @@ int open_path(struct file_desc *d,
unlinkat(mntns_root, rfi->remap->rpath, rfi->remap->is_dir ? AT_REMOVEDIR : 0);
}
- if (orig_path)
- rfi->path = orig_path;
mutex_unlock(ghost_file_mutex);
}
+ if (orig_path)
+ rfi->path = orig_path;
if (restore_fown(tmp, rfi->rfe->fown))
return -1;
--
2.4.3
More information about the CRIU
mailing list