Commit 6b79601c authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Split regfiles info into separate file

Since now on the fdinfo image only contains plain fdinfo_entry-es.
The tpye == FDINFO_REG files are described by regfiles.img entries
and are matched by te ID in both.

At dump stage each new ID generated results in a new entry in the
regfiles.img. At restore stage open_fe_fd should open a regfile by
the fdinfo's ID. Now this is done in suboptimal way, need to improve.

Show shows both images separately.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 95f957b8
...@@ -87,6 +87,8 @@ err: ...@@ -87,6 +87,8 @@ err:
return ret; return ret;
} }
static int reg_files_fd = -1;
struct fd_parms { struct fd_parms {
unsigned long fd_name; unsigned long fd_name;
unsigned long pos; unsigned long pos;
...@@ -102,9 +104,20 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd, ...@@ -102,9 +104,20 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
bool do_close_lfd) bool do_close_lfd)
{ {
struct fdinfo_entry e; struct fdinfo_entry e;
int ret = -1;
e.type = p->type;
e.addr = p->fd_name;
e.id = p->id;
ret = fd_id_generate(p->pid, &e);
if (ret < 0)
goto err;
if (ret) { /* new ID generated */
char fd_str[128]; char fd_str[128];
int len; int len;
int ret = -1; struct reg_file_entry rfe;
snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd); snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1); len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
...@@ -117,29 +130,25 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd, ...@@ -117,29 +130,25 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
pr_info("Dumping path for %lx fd via self %d [%s]\n", pr_info("Dumping path for %lx fd via self %d [%s]\n",
p->fd_name, lfd, big_buffer); p->fd_name, lfd, big_buffer);
if (do_close_lfd) rfe.len = len;
close(lfd); rfe.flags = p->flags;
rfe.pos = p->pos;
rfe.id = e.id;
e.type = p->type; if (write_img(reg_files_fd, &rfe))
e.addr = p->fd_name; goto err;
e.id = p->id; if (write_img_buf(reg_files_fd, big_buffer, len))
ret = fd_id_generate(p->pid, &e);
if (ret < 0)
goto err; goto err;
}
e.rfe.len = len; if (do_close_lfd)
e.rfe.flags = p->flags; close(lfd);
e.rfe.pos = p->pos;
e.rfe.id = e.id;
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n", pr_info("fdinfo: type: %2x flags: %4x pos: %8lx addr: %16lx\n",
p->type, len, p->flags, p->pos, p->fd_name); p->type, p->flags, p->pos, p->fd_name);
if (write_img(cr_fdset->fds[CR_FD_FDINFO], &e)) if (write_img(cr_fdset->fds[CR_FD_FDINFO], &e))
goto err; goto err;
if (write_img_buf(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.rfe.len))
goto err;
ret = 0; ret = 0;
err: err:
...@@ -1478,6 +1487,10 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts) ...@@ -1478,6 +1487,10 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
collect_sockets(); collect_sockets();
reg_files_fd = open_image(CR_FD_REG_FILES, O_RDWR | O_CREAT | O_EXCL);
if (reg_files_fd < 0)
goto err;
nr_shmems = 0; nr_shmems = 0;
shmems = xmalloc(SHMEMS_SIZE); shmems = xmalloc(SHMEMS_SIZE);
if (!shmems) if (!shmems)
...@@ -1514,6 +1527,7 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts) ...@@ -1514,6 +1527,7 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
fd_id_show_tree(); fd_id_show_tree();
err: err:
close(reg_files_fd);
pstree_switch_state(&pstree_list, opts); pstree_switch_state(&pstree_list, opts);
free_pstree(&pstree_list); free_pstree(&pstree_list);
......
...@@ -83,17 +83,38 @@ static void show_files(int fd_files) ...@@ -83,17 +83,38 @@ static void show_files(int fd_files)
if (ret <= 0) if (ret <= 0)
goto out; goto out;
pr_msg("type: %s flags: %4x pos: %lx " pr_msg("type: %s addr: %16lx id: %8x",
"addr: %16lx id: %8x", fdtype2s(e.type), e.addr, e.id);
fdtype2s(e.type), e.rfe.flags, e.rfe.pos, e.addr, e.id);
pr_msg("\n");
if (e.rfe.len) { }
int ret = read(fd_files, local_buf, e.rfe.len);
if (ret != e.rfe.len) { out:
pr_perror("Can't read %d bytes", e.rfe.len); pr_img_tail(CR_FD_FDINFO);
}
static void show_reg_files(int fd_reg_files)
{
struct reg_file_entry rfe;
pr_img_head(CR_FD_REG_FILES);
while (1) {
int ret;
ret = read_img_eof(fd_reg_files, &rfe);
if (ret <= 0)
goto out;
pr_msg("id: %8x flags: %4x pos: %lx", rfe.id, rfe.flags, rfe.pos);
if (rfe.len) {
int ret = read(fd_reg_files, local_buf, rfe.len);
if (ret != rfe.len) {
pr_perror("Can't read %d bytes", rfe.len);
goto out; goto out;
} }
local_buf[e.rfe.len] = 0; local_buf[rfe.len] = 0;
pr_msg(" --> %s", local_buf); pr_msg(" --> %s", local_buf);
} }
...@@ -101,7 +122,7 @@ static void show_files(int fd_files) ...@@ -101,7 +122,7 @@ static void show_files(int fd_files)
} }
out: out:
pr_img_tail(CR_FD_FDINFO); pr_img_tail(CR_FD_REG_FILES);
} }
static void show_pipes(int fd_pipes) static void show_pipes(int fd_pipes)
...@@ -521,6 +542,9 @@ static int cr_parse_file(struct cr_options *opts) ...@@ -521,6 +542,9 @@ static int cr_parse_file(struct cr_options *opts)
case IPCNS_SEM_MAGIC: case IPCNS_SEM_MAGIC:
show_ipc_sem(fd); show_ipc_sem(fd);
break; break;
case REG_FILES_MAGIC:
show_reg_files(fd);
break;
default: default:
pr_err("Unknown magic %x on %s\n", magic, opts->show_dump_file); pr_err("Unknown magic %x on %s\n", magic, opts->show_dump_file);
goto err; goto err;
......
...@@ -58,18 +58,6 @@ static struct fdinfo_desc *find_fd(u64 id) ...@@ -58,18 +58,6 @@ static struct fdinfo_desc *find_fd(u64 id)
return NULL; return NULL;
} }
static int get_file_path(char *path, struct fdinfo_entry *fe, int fd)
{
if (read(fd, path, fe->rfe.len) != fe->rfe.len) {
pr_perror("Error reading path");
return -1;
}
path[fe->rfe.len] = '\0';
return 0;
}
static int collect_fd(int pid, struct fdinfo_entry *e) static int collect_fd(int pid, struct fdinfo_entry *e)
{ {
int i; int i;
...@@ -147,9 +135,6 @@ int prepare_fd_pid(int pid) ...@@ -147,9 +135,6 @@ int prepare_fd_pid(int pid)
if (ret <= 0) if (ret <= 0)
break; break;
if (e.rfe.len)
lseek(fdinfo_fd, e.rfe.len, SEEK_CUR);
if (fd_is_special(&e)) if (fd_is_special(&e))
continue; continue;
...@@ -164,19 +149,49 @@ int prepare_fd_pid(int pid) ...@@ -164,19 +149,49 @@ int prepare_fd_pid(int pid)
static int open_fe_fd(struct fdinfo_entry *fe, int fd) static int open_fe_fd(struct fdinfo_entry *fe, int fd)
{ {
struct reg_file_entry rfe;
char path[PATH_MAX]; char path[PATH_MAX];
int tmp; int tmp;
if (get_file_path(path, fe, fd)) /* FIXME This should be made in more optimal way */
tmp = open_image_ro(CR_FD_REG_FILES);
if (tmp < 0)
return -1;
while (1) {
int ret;
ret = read_img_eof(tmp, &rfe);
if (ret < 0)
return -1;
if (!ret) {
pr_err("Can't find file id %x\n", fe->id);
return -1;
}
if (rfe.id == fe->id)
break;
lseek(tmp, rfe.len, SEEK_CUR);
}
if (read(tmp, path, rfe.len) != rfe.len) {
pr_perror("Error reading path");
return -1; return -1;
}
tmp = open(path, fe->rfe.flags); close(tmp);
path[rfe.len] = '\0';
tmp = open(path, rfe.flags);
if (tmp < 0) { if (tmp < 0) {
pr_perror("Can't open file %s", path); pr_perror("Can't open file %s", path);
return -1; return -1;
} }
lseek(tmp, fe->rfe.pos, SEEK_SET); lseek(tmp, rfe.pos, SEEK_SET);
return tmp; return tmp;
} }
...@@ -434,10 +449,8 @@ static int open_fdinfo(int pid, struct fdinfo_entry *fe, int *fdinfo_fd, int sta ...@@ -434,10 +449,8 @@ static int open_fdinfo(int pid, struct fdinfo_entry *fe, int *fdinfo_fd, int sta
static int open_special_fdinfo(int pid, struct fdinfo_entry *fe, static int open_special_fdinfo(int pid, struct fdinfo_entry *fe,
int fdinfo_fd, int state) int fdinfo_fd, int state)
{ {
if (state != FD_STATE_RECV) { if (state != FD_STATE_RECV)
lseek(fdinfo_fd, fe->rfe.len, SEEK_CUR);
return 0; return 0;
}
if (fe->type == FDINFO_MAP) if (fe->type == FDINFO_MAP)
return open_fmap(pid, fe, fdinfo_fd); return open_fmap(pid, fe, fdinfo_fd);
...@@ -482,11 +495,8 @@ int prepare_fds(int pid) ...@@ -482,11 +495,8 @@ int prepare_fds(int pid)
if (fd_is_special(&fe)) if (fd_is_special(&fe))
ret = open_special_fdinfo(pid, &fe, ret = open_special_fdinfo(pid, &fe,
fdinfo_fd, state); fdinfo_fd, state);
else { else
offset = lseek(fdinfo_fd, 0, SEEK_CUR);
ret = open_fdinfo(pid, &fe, &fdinfo_fd, state); ret = open_fdinfo(pid, &fe, &fdinfo_fd, state);
lseek(fdinfo_fd, offset + fe.rfe.len, SEEK_SET);
}
if (ret) if (ret)
break; break;
......
...@@ -57,7 +57,6 @@ struct fdinfo_entry { ...@@ -57,7 +57,6 @@ struct fdinfo_entry {
u64 addr; u64 addr;
u8 type; u8 type;
u32 id; u32 id;
struct reg_file_entry rfe;
} __packed; } __packed;
#define fd_is_special(fe) \ #define fd_is_special(fe) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment