mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-03 07:45:17 +00:00
files: Add ability to use read link in dump_one_reg_file
To be able to dump procfs namespace entries we will need to analyze the link name first and then figure out if the file referred indeed a procfs entry or it's plain regular file. This means we read link early, and to escape double reading of same link, once we read it we remember it in fd_parms structure which we pass to dump_one_reg_file. Still the dump_one_reg_file is not solely used from inside of dump_one_file, but from a number of other places (fifo, special files) where fd_parms is filled only partially and fill_fd_params is not even called. Thus dump_one_reg_file must be ready for such scenario and read the link name by own if the caller has not provided one. To achieve all this we do - extend fd_parms structure to have a reference on a new fd_link structure, thus if caller already read the link name it might assign the reference and call for dump_one_reg_file - tune up dump_one_reg_file to fill own copy of fd_link structure if the caller has not provied one [ xemul: Added const to fill_fdlink arg ] Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
19ce784db5
commit
4531f0ac7d
25
files-reg.c
25
files-reg.c
@@ -432,36 +432,37 @@ static int check_path_remap(char *rpath, int plen, const struct stat *ost, int l
|
||||
|
||||
int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
|
||||
{
|
||||
char rpath[PATH_MAX + 1] = ".", *path = rpath + 1;
|
||||
int len, rfd;
|
||||
struct fd_link _link, *link;
|
||||
int rfd;
|
||||
|
||||
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
|
||||
|
||||
len = read_fd_link(lfd, path, sizeof(rpath) - 1);
|
||||
if (len < 0) {
|
||||
pr_err("Can't read link\n");
|
||||
return len;
|
||||
}
|
||||
if (!p->link) {
|
||||
if (fill_fdlink(lfd, p, &_link))
|
||||
return -1;
|
||||
link = &_link;
|
||||
} else
|
||||
link = p->link;
|
||||
|
||||
pr_info("Dumping path for %d fd via self %d [%s]\n",
|
||||
p->fd, lfd, path);
|
||||
p->fd, lfd, &link->name[1]);
|
||||
|
||||
/*
|
||||
* The regular path we can handle should start with slash.
|
||||
*/
|
||||
if (path[0] != '/') {
|
||||
pr_err("The path [%s] is not supported\n", path);
|
||||
if (link->name[1] != '/') {
|
||||
pr_err("The path [%s] is not supported\n", &link->name[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (check_path_remap(rpath, len, &p->stat, lfd, id))
|
||||
if (check_path_remap(link->name, link->len, &p->stat, lfd, id))
|
||||
return -1;
|
||||
|
||||
rfe.id = id;
|
||||
rfe.flags = p->flags;
|
||||
rfe.pos = p->pos;
|
||||
rfe.fown = (FownEntry *)&p->fown;
|
||||
rfe.name = path;
|
||||
rfe.name = &link->name[1];
|
||||
|
||||
rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
|
||||
|
||||
|
25
files.c
25
files.c
@@ -135,6 +135,22 @@ int do_dump_gen_file(struct fd_parms *p, int lfd,
|
||||
return pb_write_one(fdinfo, &e, PB_FDINFO);
|
||||
}
|
||||
|
||||
int fill_fdlink(int lfd, const struct fd_parms *p, struct fd_link *link)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
link->name[0] = '.';
|
||||
|
||||
len = read_fd_link(lfd, &link->name[1], sizeof(link->name) - 1);
|
||||
if (len < 0) {
|
||||
pr_err("Can't read link for pid %d fd %d\n", p->pid, p->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
link->len = len + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd,
|
||||
struct fd_opts *opts, struct fd_parms *p)
|
||||
{
|
||||
@@ -244,8 +260,15 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
|
||||
return dump_unsupp_fd(&p);
|
||||
}
|
||||
|
||||
if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode))
|
||||
if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode)) {
|
||||
struct fd_link link;
|
||||
|
||||
if (fill_fdlink(lfd, &p, &link))
|
||||
return -1;
|
||||
|
||||
p.link = &link;
|
||||
return dump_reg_file(&p, lfd, fdinfo);
|
||||
}
|
||||
|
||||
if (S_ISFIFO(p.stat.st_mode)) {
|
||||
if (statfs.f_type == PIPEFS_MAGIC)
|
||||
|
@@ -17,6 +17,11 @@ struct cr_fdset;
|
||||
struct rst_info;
|
||||
struct parasite_ctl;
|
||||
|
||||
struct fd_link {
|
||||
char name[PATH_MAX + 1];
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct fd_parms {
|
||||
int fd;
|
||||
unsigned long pos;
|
||||
@@ -25,6 +30,7 @@ struct fd_parms {
|
||||
struct stat stat;
|
||||
pid_t pid;
|
||||
FownEntry fown;
|
||||
struct fd_link *link;
|
||||
|
||||
struct parasite_ctl *ctl;
|
||||
};
|
||||
@@ -33,8 +39,11 @@ struct fd_parms {
|
||||
(struct fd_parms) { \
|
||||
.fd = FD_DESC_INVALID, \
|
||||
.fown = FOWN_ENTRY__INIT, \
|
||||
.link = NULL, \
|
||||
}
|
||||
|
||||
extern int fill_fdlink(int lfd, const struct fd_parms *p, struct fd_link *link);
|
||||
|
||||
struct file_desc;
|
||||
|
||||
struct fdinfo_list_entry {
|
||||
|
Reference in New Issue
Block a user