2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 14:25:49 +00:00

files: Move regular files handling code to files-reg

Instead of spreading regular files handling code over
files.c and cr-dump.c move it to files-reg.c.

This allows to extend regular file handling code in
future without disturbing other source files and
make code logically coupled, where files.c is mostly
a place for general file handling code unrelated to
file type specifics.

While mostly it was code tossing there is some change
I have to notice -- the structure ghost_file was previously
declared in two paces cr-dump.c and files.c, in cr-dump.c
it was used for dumping while in files.c it was used
for restore. The structure had different members.

So to resolve this conflict the ghost_file structure
was renamed to ghost_file_dumpee.

Nothing else is changed.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Cyrill Gorcunov
2012-06-20 20:00:30 +04:00
committed by Pavel Emelyanov
parent ebb8066599
commit 4140c9e4ec
5 changed files with 446 additions and 415 deletions

228
files.c
View File

@@ -81,13 +81,6 @@ struct fdinfo_list_entry *file_master(struct file_desc *d)
struct fdinfo_list_entry, desc_list);
}
struct reg_file_info {
struct reg_file_entry rfe;
char *remap_path;
char *path;
struct file_desc d;
};
void show_saved_files(void)
{
int i;
@@ -157,184 +150,6 @@ int rst_file_params(int fd, fown_t *fown, int flags)
return 0;
}
static int open_fe_fd(struct file_desc *d);
static struct file_desc_ops reg_desc_ops = {
.type = FDINFO_REG,
.open = open_fe_fd,
};
struct ghost_file {
u32 id;
char *path;
struct list_head list;
};
static LIST_HEAD(ghost_files);
void clear_ghost_files(void)
{
struct ghost_file *gf;
pr_info("Unlinking ghosts\n");
list_for_each_entry(gf, &ghost_files, list) {
pr_info("\t`- %s\n", gf->path);
unlink(gf->path);
}
}
static int open_remap_ghost(struct reg_file_info *rfi,
struct remap_file_path_entry *rfe)
{
struct ghost_file *gf;
struct ghost_file_entry gfe;
int gfd, ifd;
list_for_each_entry(gf, &ghost_files, list)
if (gf->id == rfe->remap_id)
goto gf_found;
/*
* Ghost not found. We will create one in the same dir
* as the very first client of it thus resolving any
* issues with cross-device links.
*/
pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);
gf = xmalloc(sizeof(*gf));
if (!gf)
return -1;
gf->path = xmalloc(PATH_MAX);
if (!gf->path)
return -1;
ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id);
if (ifd < 0)
return -1;
if (read_img(ifd, &gfe) < 0)
return -1;
snprintf(gf->path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id);
gfd = open(gf->path, O_WRONLY | O_CREAT | O_EXCL, gfe.mode);
if (gfd < 0) {
pr_perror("Can't open ghost file");
return -1;
}
if (fchown(gfd, gfe.uid, gfe.gid) < 0) {
pr_perror("Can't reset user/group on ghost %#x\n", rfe->remap_id);
return -1;
}
if (copy_file(ifd, gfd, 0) < 0)
return -1;
close(ifd);
close(gfd);
gf->id = rfe->remap_id;
list_add_tail(&gf->list, &ghost_files);
gf_found:
rfi->remap_path = gf->path;
return 0;
}
static int collect_remaps(void)
{
int fd, ret = 0;
fd = open_image_ro(CR_FD_REMAP_FPATH);
if (fd < 0)
return -1;
while (1) {
struct remap_file_path_entry rfe;
struct file_desc *fdesc;
struct reg_file_info *rfi;
ret = read_img_eof(fd, &rfe);
if (ret <= 0)
break;
ret = -1;
if (!(rfe.remap_id & REMAP_GHOST)) {
pr_err("Non ghost remap not supported @%#x\n",
rfe.orig_id);
break;
}
fdesc = find_file_desc_raw(FDINFO_REG, rfe.orig_id);
if (fdesc == NULL) {
pr_err("Remap for non existing file %#x\n",
rfe.orig_id);
break;
}
rfe.remap_id &= ~REMAP_GHOST;
rfi = container_of(fdesc, struct reg_file_info, d);
pr_info("Configuring remap %#x -> %#x\n", rfi->rfe.id, rfe.remap_id);
ret = open_remap_ghost(rfi, &rfe);
if (ret < 0)
break;
}
close(fd);
return ret;
}
int collect_reg_files(void)
{
struct reg_file_info *rfi = NULL;
int fd, ret = -1;
fd = open_image_ro(CR_FD_REG_FILES);
if (fd < 0)
return -1;
while (1) {
int len;
rfi = xmalloc(sizeof(*rfi));
ret = -1;
if (rfi == NULL)
break;
rfi->path = NULL;
ret = read_img_eof(fd, &rfi->rfe);
if (ret <= 0)
break;
len = rfi->rfe.len;
rfi->path = xmalloc(len + 1);
ret = -1;
if (rfi->path == NULL)
break;
ret = read_img_buf(fd, rfi->path, len);
if (ret < 0)
break;
rfi->remap_path = NULL;
rfi->path[len] = '\0';
pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe.id);
file_desc_add(&rfi->d, rfi->rfe.id, &reg_desc_ops);
}
if (rfi) {
xfree(rfi->path);
xfree(rfi);
}
close(fd);
return collect_remaps();
}
static int collect_fd(int pid, struct fdinfo_entry *e, struct rst_info *rst_info)
{
struct fdinfo_list_entry *l, *le = &fdinfo_list[nr_fdinfo_list];
@@ -403,49 +218,6 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info)
return ret;
}
static int open_fe_fd(struct file_desc *d)
{
struct reg_file_info *rfi;
int tmp;
rfi = container_of(d, struct reg_file_info, d);
if (rfi->remap_path)
if (link(rfi->remap_path, rfi->path) < 0) {
pr_perror("Can't link %s -> %s\n",
rfi->remap_path, rfi->path);
return -1;
}
tmp = open(rfi->path, rfi->rfe.flags);
if (tmp < 0) {
pr_perror("Can't open file %s", rfi->path);
return -1;
}
if (rfi->remap_path)
unlink(rfi->path);
lseek(tmp, rfi->rfe.pos, SEEK_SET);
if (restore_fown(tmp, &rfi->rfe.fown))
return -1;
return tmp;
}
int open_reg_by_id(u32 id)
{
struct file_desc *fd;
fd = find_file_desc_raw(FDINFO_REG, id);
if (fd == NULL) {
pr_perror("Can't find regfile for %#x\n", id);
return -1;
}
return open_fe_fd(fd);
}
#define SETFL_MASK (O_APPEND | O_ASYNC | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
int set_fd_flags(int fd, int flags)
{