mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 23:05:39 +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)
|
int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
|
||||||
{
|
{
|
||||||
char rpath[PATH_MAX + 1] = ".", *path = rpath + 1;
|
struct fd_link _link, *link;
|
||||||
int len, rfd;
|
int rfd;
|
||||||
|
|
||||||
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
|
RegFileEntry rfe = REG_FILE_ENTRY__INIT;
|
||||||
|
|
||||||
len = read_fd_link(lfd, path, sizeof(rpath) - 1);
|
if (!p->link) {
|
||||||
if (len < 0) {
|
if (fill_fdlink(lfd, p, &_link))
|
||||||
pr_err("Can't read link\n");
|
return -1;
|
||||||
return len;
|
link = &_link;
|
||||||
}
|
} else
|
||||||
|
link = p->link;
|
||||||
|
|
||||||
pr_info("Dumping path for %d fd via self %d [%s]\n",
|
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.
|
* The regular path we can handle should start with slash.
|
||||||
*/
|
*/
|
||||||
if (path[0] != '/') {
|
if (link->name[1] != '/') {
|
||||||
pr_err("The path [%s] is not supported\n", path);
|
pr_err("The path [%s] is not supported\n", &link->name[1]);
|
||||||
return -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;
|
return -1;
|
||||||
|
|
||||||
rfe.id = id;
|
rfe.id = id;
|
||||||
rfe.flags = p->flags;
|
rfe.flags = p->flags;
|
||||||
rfe.pos = p->pos;
|
rfe.pos = p->pos;
|
||||||
rfe.fown = (FownEntry *)&p->fown;
|
rfe.fown = (FownEntry *)&p->fown;
|
||||||
rfe.name = path;
|
rfe.name = &link->name[1];
|
||||||
|
|
||||||
rfd = fdset_fd(glob_fdset, CR_FD_REG_FILES);
|
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);
|
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,
|
static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd,
|
||||||
struct fd_opts *opts, struct fd_parms *p)
|
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);
|
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);
|
return dump_reg_file(&p, lfd, fdinfo);
|
||||||
|
}
|
||||||
|
|
||||||
if (S_ISFIFO(p.stat.st_mode)) {
|
if (S_ISFIFO(p.stat.st_mode)) {
|
||||||
if (statfs.f_type == PIPEFS_MAGIC)
|
if (statfs.f_type == PIPEFS_MAGIC)
|
||||||
|
@@ -17,6 +17,11 @@ struct cr_fdset;
|
|||||||
struct rst_info;
|
struct rst_info;
|
||||||
struct parasite_ctl;
|
struct parasite_ctl;
|
||||||
|
|
||||||
|
struct fd_link {
|
||||||
|
char name[PATH_MAX + 1];
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
struct fd_parms {
|
struct fd_parms {
|
||||||
int fd;
|
int fd;
|
||||||
unsigned long pos;
|
unsigned long pos;
|
||||||
@@ -25,6 +30,7 @@ struct fd_parms {
|
|||||||
struct stat stat;
|
struct stat stat;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
FownEntry fown;
|
FownEntry fown;
|
||||||
|
struct fd_link *link;
|
||||||
|
|
||||||
struct parasite_ctl *ctl;
|
struct parasite_ctl *ctl;
|
||||||
};
|
};
|
||||||
@@ -33,8 +39,11 @@ struct fd_parms {
|
|||||||
(struct fd_parms) { \
|
(struct fd_parms) { \
|
||||||
.fd = FD_DESC_INVALID, \
|
.fd = FD_DESC_INVALID, \
|
||||||
.fown = FOWN_ENTRY__INIT, \
|
.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 file_desc;
|
||||||
|
|
||||||
struct fdinfo_list_entry {
|
struct fdinfo_list_entry {
|
||||||
|
Reference in New Issue
Block a user