From: Jingxian He hejingxian@huawei.com
Add reuse file method for recover file state of deleted files.
Conflict:NA Reference:https://gitee.com/src-openeuler/criu/pulls/21 Signed-off-by: Jingxian He hejingxian@huawei.com --- criu/files-reg.c | 75 +++++++++++++++++++++++++++++++++++++--- criu/files.c | 24 ++++++++++--- criu/include/files-reg.h | 9 +++++ 3 files changed, 99 insertions(+), 9 deletions(-)
diff --git a/criu/files-reg.c b/criu/files-reg.c index 6bbcbee..46e9eab 100644 --- a/criu/files-reg.c +++ b/criu/files-reg.c @@ -1184,6 +1184,70 @@ int strip_deleted(struct fd_link *link) return 0; }
+int add_reuse_file(u32 id, int fd, int pid) +{ + int retval; + char buf[256] = {0}; + + retval = snprintf(buf, 256, "%u,%d,%d", id, fd, pid); + if (retval <= 0) + return -EFAULT; + + fd = open(ADD_REUSE_FILE_PATH, O_WRONLY, 0); + if (fd < 0) { + pr_err("open file:%s fail\n", ADD_REUSE_FILE_PATH); + return fd; + } + + retval = write(fd, buf, strlen(buf)); + close(fd); + return retval < 0 ? -1 : 0; +} + + +int repair_reuse_file(int id) +{ + int retval, fd; + char buf[256] = {0}; + + retval = snprintf(buf, 256, "%u", id); + if (retval <= 0) + return -EFAULT; + + fd = open(REPAIR_REUSE_FILE_PATH, O_WRONLY, 0); + if (fd < 0) { + pr_err("open file:%s fail\n", REPAIR_REUSE_FILE_PATH); + return fd; + } + retval = write(fd, buf, strlen(buf)); + + close(fd); + return retval < 0 ? -1 : 0; +} + +int get_reuse_file(void) +{ + int fd; + ssize_t count; + int retval = -1; + char buf[32] = {0}; + + fd = open(REUSE_FILE_PATH, O_RDONLY , 0); + if (fd < 0) { + pr_err("open file:%s fail\n", REUSE_FILE_PATH); + return fd; + } + + count = read(fd, buf, sizeof(buf)); + if (count > 0) + retval = atoi(buf); + + close(fd); + return retval; +} + +extern int dst_pid; +extern int need_reuse_flag; static int check_path_remap(struct fd_link *link, const struct fd_parms *parms, int lfd, u32 id, struct ns_id *nsid) { @@ -1301,9 +1365,12 @@ static int check_path_remap(struct fd_link *link, const struct fd_parms *parms, * name. */
- if (errno == ENOENT) - return dump_linked_remap(rpath + 1, plen - 1, - ost, lfd, id, nsid); + if (errno == ENOENT) { + pr_info("start add no exist file:%s\n", rpath + 1); + add_reuse_file(id, lfd, dst_pid); + need_reuse_flag = O_REUSE; + return 0; + }
pr_perror("Can't stat path"); return -1; @@ -1724,7 +1791,7 @@ ext: rfe.mode = p->stat.st_mode;
if (S_ISREG(p->stat.st_mode) && should_check_size(rfe.flags) && - !store_validation_data(&rfe, p, lfd)) + (need_reuse_flag != O_REUSE) && !store_validation_data(&rfe, p, lfd)) return -1;
fe.type = FD_TYPES__REG; diff --git a/criu/files.c b/criu/files.c index 0ebf26e..16d34fd 100644 --- a/criu/files.c +++ b/criu/files.c @@ -720,7 +720,7 @@ int dump_my_file(int lfd, u32 *id, int *type) }
int dst_pid; - +int need_reuse_flag; int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, struct parasite_drain_fd *dfds) { @@ -758,7 +758,7 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
for (i = 0; i < nr_fds; i++) { FdinfoEntry e = FDINFO_ENTRY__INIT; - + need_reuse_flag = 0; ret = dump_one_file(item->pid, dfds->fds[i + off], lfds[i], opts + i, ctl, &e, dfds); if (ret < 0) @@ -768,7 +768,7 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, ret = 0; continue; } - + e.flags |= need_reuse_flag; pr_info("write fdinfoEntry fd=%d id=%d\n", (&e)->fd, (&e)->id); ret = pb_write_one(img, &e, PB_FDINFO); if (ret) @@ -964,8 +964,8 @@ int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info, bool fake) { struct file_desc *fdesc;
- pr_info("Collect fdinfo pid=%d fd=%d id=%#x\n", - pid, e->fd, e->id); + pr_info("Collect fdinfo pid=%d fd=%d id=%#x flags:%x\n", + pid, e->fd, e->id, e->flags);
fdesc = find_file_desc(e); if (fdesc == NULL) { @@ -1255,6 +1255,7 @@ static int open_fd(struct fdinfo_list_entry *fle) struct fdinfo_list_entry *flem; int new_fd = -1, ret;
+ pr_info("open file flags:%x\n", fle->fe->flags); flem = file_master(d); if (fle != flem) { BUG_ON (fle->stage != FLE_INITIALIZED); @@ -1276,6 +1277,19 @@ static int open_fd(struct fdinfo_list_entry *fle) return 0; } } + } else if (fle->fe->flags & O_REUSE) { + pr_info("find reuse file:%d\n", d->id); + ret = repair_reuse_file(d->id); + if (!ret) { + new_fd = get_reuse_file(); + pr_info("get reuse file:%d\n", new_fd); + if (new_fd <= 0 || setup_and_serve_out(fle, new_fd) < 0) { + pr_err("setup reuse file fail\n"); + return -1; + } + fle->stage = FLE_RESTORED; + return 0; + } }
/* diff --git a/criu/include/files-reg.h b/criu/include/files-reg.h index 458fe89..4ec0e14 100644 --- a/criu/include/files-reg.h +++ b/criu/include/files-reg.h @@ -64,4 +64,13 @@ extern int strip_deleted(struct fd_link *link);
extern int dead_pid_conflict(void);
+#define ADD_REUSE_FILE_PATH "/sys/kernel/add_reuse_file" +#define REPAIR_REUSE_FILE_PATH "/sys/kernel/repair_reuse_file" +#define REUSE_FILE_PATH "/sys/kernel/reuse_file" +#define O_REUSE 0100000000 + +extern int add_reuse_file(u32 id, int fd, int pid); +extern int repair_reuse_file(int id); +extern int get_reuse_file(void); + #endif /* __CR_FILES_REG_H__ */