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:
return ret;
}
static int reg_files_fd = -1;
struct fd_parms {
unsigned long fd_name;
unsigned long pos;
......@@ -102,24 +104,8 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
bool do_close_lfd)
{
struct fdinfo_entry e;
char fd_str[128];
int len;
int ret = -1;
snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
if (len < 0) {
pr_perror("Can't readlink %s", fd_str);
goto err;
}
big_buffer[len] = '\0';
pr_info("Dumping path for %lx fd via self %d [%s]\n",
p->fd_name, lfd, big_buffer);
if (do_close_lfd)
close(lfd);
e.type = p->type;
e.addr = p->fd_name;
e.id = p->id;
......@@ -128,18 +114,41 @@ static int dump_one_reg_file(const struct fd_parms *p, int lfd,
if (ret < 0)
goto err;
e.rfe.len = len;
e.rfe.flags = p->flags;
e.rfe.pos = p->pos;
e.rfe.id = e.id;
if (ret) { /* new ID generated */
char fd_str[128];
int len;
struct reg_file_entry rfe;
snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
if (len < 0) {
pr_perror("Can't readlink %s", fd_str);
goto err;
}
big_buffer[len] = '\0';
pr_info("Dumping path for %lx fd via self %d [%s]\n",
p->fd_name, lfd, big_buffer);
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n",
p->type, len, p->flags, p->pos, p->fd_name);
rfe.len = len;
rfe.flags = p->flags;
rfe.pos = p->pos;
rfe.id = e.id;
if (write_img(reg_files_fd, &rfe))
goto err;
if (write_img_buf(reg_files_fd, big_buffer, len))
goto err;
}
if (do_close_lfd)
close(lfd);
pr_info("fdinfo: type: %2x flags: %4x pos: %8lx addr: %16lx\n",
p->type, p->flags, p->pos, p->fd_name);
if (write_img(cr_fdset->fds[CR_FD_FDINFO], &e))
goto err;
if (write_img_buf(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.rfe.len))
goto err;
ret = 0;
err:
......@@ -1478,6 +1487,10 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
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;
shmems = xmalloc(SHMEMS_SIZE);
if (!shmems)
......@@ -1514,6 +1527,7 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
fd_id_show_tree();
err:
close(reg_files_fd);
pstree_switch_state(&pstree_list, opts);
free_pstree(&pstree_list);
......
......@@ -83,17 +83,38 @@ static void show_files(int fd_files)
if (ret <= 0)
goto out;
pr_msg("type: %s flags: %4x pos: %lx "
"addr: %16lx id: %8x",
fdtype2s(e.type), e.rfe.flags, e.rfe.pos, e.addr, e.id);
if (e.rfe.len) {
int ret = read(fd_files, local_buf, e.rfe.len);
if (ret != e.rfe.len) {
pr_perror("Can't read %d bytes", e.rfe.len);
pr_msg("type: %s addr: %16lx id: %8x",
fdtype2s(e.type), e.addr, e.id);
pr_msg("\n");
}
out:
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;
}
local_buf[e.rfe.len] = 0;
local_buf[rfe.len] = 0;
pr_msg(" --> %s", local_buf);
}
......@@ -101,7 +122,7 @@ static void show_files(int fd_files)
}
out:
pr_img_tail(CR_FD_FDINFO);
pr_img_tail(CR_FD_REG_FILES);
}
static void show_pipes(int fd_pipes)
......@@ -521,6 +542,9 @@ static int cr_parse_file(struct cr_options *opts)
case IPCNS_SEM_MAGIC:
show_ipc_sem(fd);
break;
case REG_FILES_MAGIC:
show_reg_files(fd);
break;
default:
pr_err("Unknown magic %x on %s\n", magic, opts->show_dump_file);
goto err;
......
......@@ -58,18 +58,6 @@ static struct fdinfo_desc *find_fd(u64 id)
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)
{
int i;
......@@ -147,9 +135,6 @@ int prepare_fd_pid(int pid)
if (ret <= 0)
break;
if (e.rfe.len)
lseek(fdinfo_fd, e.rfe.len, SEEK_CUR);
if (fd_is_special(&e))
continue;
......@@ -164,19 +149,49 @@ int prepare_fd_pid(int pid)
static int open_fe_fd(struct fdinfo_entry *fe, int fd)
{
struct reg_file_entry rfe;
char path[PATH_MAX];
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;
tmp = open(path, fe->rfe.flags);
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;
}
close(tmp);
path[rfe.len] = '\0';
tmp = open(path, rfe.flags);
if (tmp < 0) {
pr_perror("Can't open file %s", path);
return -1;
}
lseek(tmp, fe->rfe.pos, SEEK_SET);
lseek(tmp, rfe.pos, SEEK_SET);
return tmp;
}
......@@ -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,
int fdinfo_fd, int state)
{
if (state != FD_STATE_RECV) {
lseek(fdinfo_fd, fe->rfe.len, SEEK_CUR);
if (state != FD_STATE_RECV)
return 0;
}
if (fe->type == FDINFO_MAP)
return open_fmap(pid, fe, fdinfo_fd);
......@@ -482,11 +495,8 @@ int prepare_fds(int pid)
if (fd_is_special(&fe))
ret = open_special_fdinfo(pid, &fe,
fdinfo_fd, state);
else {
offset = lseek(fdinfo_fd, 0, SEEK_CUR);
else
ret = open_fdinfo(pid, &fe, &fdinfo_fd, state);
lseek(fdinfo_fd, offset + fe.rfe.len, SEEK_SET);
}
if (ret)
break;
......
......@@ -57,7 +57,6 @@ struct fdinfo_entry {
u64 addr;
u8 type;
u32 id;
struct reg_file_entry rfe;
} __packed;
#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