Commit 15209d3f authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

crtools: Make fdset be an array of file descriptors

Path is not needed there -- we can call the get_image_path() in prep_cr_fdset_
routines and in parasite-syscall.c when required.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent e710c5c5
......@@ -128,8 +128,8 @@ static int dump_one_reg_file(int type, unsigned long fd_name, int lfd,
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8x addr: %16lx\n",
type, len, flags, pos, fd_name);
write_ptr_safe(cr_fdset->desc[CR_FD_FDINFO].fd, &e, err);
write_safe(cr_fdset->desc[CR_FD_FDINFO].fd, big_buffer, e.len, err);
write_ptr_safe(cr_fdset->fds[CR_FD_FDINFO], &e, err);
write_safe(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.len, err);
ret = 0;
err:
......@@ -160,7 +160,7 @@ static int dump_pipe_and_data(int lfd, struct pipe_entry *e,
int has_bytes;
int ret = -1;
fd_pipes = cr_fdset->desc[CR_FD_PIPES].fd;
fd_pipes = cr_fdset->fds[CR_FD_PIPES];
pr_info("Dumping data from pipe %x\n", e->pipeid);
if (pipe(steal_pipe) < 0) {
......@@ -219,7 +219,7 @@ static int dump_one_pipe(int fd, int lfd, unsigned int id, unsigned int flags,
if (flags & O_WRONLY) {
e.bytes = 0;
write_ptr_safe(cr_fdset->desc[CR_FD_PIPES].fd, &e, err);
write_ptr_safe(cr_fdset->fds[CR_FD_PIPES], &e, err);
ret = 0;
} else
ret = dump_pipe_and_data(lfd, &e, cr_fdset);
......@@ -387,7 +387,7 @@ static int dump_task_mappings(pid_t pid, struct list_head *vma_area_list, struct
pr_info("shmem: s: %16lx e: %16lx shmid: %16lx\n",
e.start, e.end, e.shmid);
write_ptr_safe(cr_fdset->desc[CR_FD_SHMEM].fd, &e, err);
write_ptr_safe(cr_fdset->fds[CR_FD_SHMEM], &e, err);
} else if (vma_entry_is(vma, VMA_FILE_PRIVATE) ||
vma_entry_is(vma, VMA_FILE_SHARED)) {
......@@ -651,7 +651,7 @@ err:
static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset)
{
struct core_entry *core = xzalloc(sizeof(*core));
int fd_core = cr_fdset->desc[CR_FD_CORE].fd;
int fd_core = cr_fdset->fds[CR_FD_CORE];
int ret = -1;
unsigned long brk;
......@@ -866,12 +866,12 @@ static int dump_pstree(pid_t pid, struct list_head *pstree_list, struct cr_fdset
e.nr_children = item->nr_children;
e.nr_threads = item->nr_threads;
write_ptr_safe(cr_fdset->desc[CR_FD_PSTREE].fd, &e, err);
write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE], &e, err);
pr_info("Children:");
for (i = 0; i < item->nr_children; i++) {
pr_info(" %d", item->children[i]);
write_ptr_safe(cr_fdset->desc[CR_FD_PSTREE].fd,
write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE],
&item->children[i], err);
}
pr_info("\n");
......@@ -879,7 +879,7 @@ static int dump_pstree(pid_t pid, struct list_head *pstree_list, struct cr_fdset
pr_info("Threads:\n");
for (i = 0; i < item->nr_threads; i++) {
pr_info(" %d", item->threads[i]);
write_ptr_safe(cr_fdset->desc[CR_FD_PSTREE].fd,
write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE],
&item->threads[i], err);
}
pr_info("\n");
......@@ -906,8 +906,8 @@ static struct vma_area *find_vma_by_addr(struct list_head *vma_area_list, unsign
static int append_thread_core(struct cr_fdset *dst, struct cr_fdset *src)
{
const int size = sizeof(struct core_entry);
int fd_core_dst = dst->desc[CR_FD_CORE].fd;
int fd_code_src = src->desc[CR_FD_CORE].fd;
int fd_core_dst = dst->fds[CR_FD_CORE];
int fd_code_src = src->fds[CR_FD_CORE];
int ret = -1;
lseek(fd_core_dst, 0, SEEK_END);
......@@ -937,9 +937,9 @@ static int finalize_core(pid_t pid, struct list_head *vma_area_list, struct cr_f
pr_info("Finalizing core (pid: %d)\n", pid);
pr_info("----------------------------------------\n");
fd_core = cr_fdset->desc[CR_FD_CORE].fd;
fd_pages = cr_fdset->desc[CR_FD_PAGES].fd;
fd_pages_shmem = cr_fdset->desc[CR_FD_PAGES_SHMEM].fd;
fd_core = cr_fdset->fds[CR_FD_CORE];
fd_pages = cr_fdset->fds[CR_FD_PAGES];
fd_pages_shmem = cr_fdset->fds[CR_FD_PAGES_SHMEM];
lseek(fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET);
lseek(fd_pages, MAGIC_OFFSET, SEEK_SET);
......@@ -1043,7 +1043,7 @@ err_strno:
static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset)
{
struct core_entry *core = xzalloc(sizeof(*core));
int fd_core = cr_fdset->desc[CR_FD_CORE].fd;
int fd_core = cr_fdset->fds[CR_FD_CORE];
int ret = -1;
pr_info("\n");
......@@ -1224,17 +1224,17 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts)
list_for_each_entry(item, &pstree_list, list) {
cr_fdset = alloc_cr_fdset(item->pid);
cr_fdset = alloc_cr_fdset();
if (!cr_fdset)
goto err;
if (item->pid == pid) {
if (prep_cr_fdset_for_dump(cr_fdset, CR_FD_DESC_ALL))
if (prep_cr_fdset_for_dump(cr_fdset, item->pid, CR_FD_DESC_ALL))
goto err;
if (dump_pstree(pid, &pstree_list, cr_fdset))
goto err;
} else {
if (prep_cr_fdset_for_dump(cr_fdset, CR_FD_DESC_NOPSTREE))
if (prep_cr_fdset_for_dump(cr_fdset, item->pid, CR_FD_DESC_NOPSTREE))
goto err;
}
......@@ -1249,11 +1249,12 @@ int cr_dump_tasks(pid_t pid, struct cr_options *opts)
if (item->pid == item->threads[i])
continue;
cr_fdset_thread = alloc_cr_fdset(item->threads[i]);
cr_fdset_thread = alloc_cr_fdset();
if (!cr_fdset_thread)
goto err;
if (prep_cr_fdset_for_dump(cr_fdset_thread, CR_FD_DESC_CORE))
if (prep_cr_fdset_for_dump(cr_fdset_thread,
item->threads[i], CR_FD_DESC_CORE))
goto err;
if (dump_task_thread(item->threads[i], cr_fdset_thread))
......
......@@ -427,7 +427,7 @@ err:
static int collect_pstree(struct list_head *head, pid_t pid, struct cr_fdset *cr_fdset)
{
int fd = cr_fdset->desc[CR_FD_PSTREE].fd;
int fd = cr_fdset->fds[CR_FD_PSTREE];
struct pstree_item *item = NULL;
struct pstree_entry e;
int ret = -1;
......@@ -497,11 +497,11 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
LIST_HEAD(pstree_list);
int i, ret = -1;
cr_fdset = alloc_cr_fdset(pid);
cr_fdset = alloc_cr_fdset();
if (!cr_fdset)
goto out;
ret = prep_cr_fdset_for_restore(cr_fdset,
ret = prep_cr_fdset_for_restore(cr_fdset, pid,
CR_FD_DESC_USE(CR_FD_PSTREE));
if (ret)
goto out;
......@@ -514,24 +514,24 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
* Yeah, I know we read the same file for second
* time here, but this saves us from code duplication.
*/
lseek(cr_fdset->desc[CR_FD_PSTREE].fd, MAGIC_OFFSET, SEEK_SET);
show_pstree(cr_fdset->desc[CR_FD_PSTREE].fd);
lseek(cr_fdset->fds[CR_FD_PSTREE], MAGIC_OFFSET, SEEK_SET);
show_pstree(cr_fdset->fds[CR_FD_PSTREE]);
close_cr_fdset(cr_fdset);
free_cr_fdset(&cr_fdset);
list_for_each_entry(item, &pstree_list, list) {
cr_fdset = alloc_cr_fdset(item->pid);
cr_fdset = alloc_cr_fdset();
if (!cr_fdset)
goto out;
ret = prep_cr_fdset_for_restore(cr_fdset, CR_FD_DESC_NOPSTREE);
ret = prep_cr_fdset_for_restore(cr_fdset, item->pid, CR_FD_DESC_NOPSTREE);
if (ret)
goto out;
lseek(cr_fdset->desc[CR_FD_CORE].fd, MAGIC_OFFSET, SEEK_SET);
show_core(cr_fdset->desc[CR_FD_CORE].fd, opts->show_pages_content);
lseek(cr_fdset->fds[CR_FD_CORE], MAGIC_OFFSET, SEEK_SET);
show_core(cr_fdset->fds[CR_FD_CORE], opts->show_pages_content);
if (item->nr_threads > 1) {
struct cr_fdset *cr_fdset_th;
......@@ -542,11 +542,12 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
if (item->threads[i] == item->pid)
continue;
cr_fdset_th = alloc_cr_fdset(item->threads[i]);
cr_fdset_th = alloc_cr_fdset();
if (!cr_fdset)
goto out;
ret = prep_cr_fdset_for_restore(cr_fdset_th, CR_FD_DESC_CORE);
ret = prep_cr_fdset_for_restore(cr_fdset_th,
item->threads[i], CR_FD_DESC_CORE);
if (ret)
goto out;
......@@ -554,8 +555,8 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
pr_info("Thread: %d\n", item->threads[i]);
pr_info("----------------------------------------\n");
lseek(cr_fdset_th->desc[CR_FD_CORE].fd, MAGIC_OFFSET, SEEK_SET);
show_core(cr_fdset_th->desc[CR_FD_CORE].fd, opts->show_pages_content);
lseek(cr_fdset_th->fds[CR_FD_CORE], MAGIC_OFFSET, SEEK_SET);
show_core(cr_fdset_th->fds[CR_FD_CORE], opts->show_pages_content);
pr_info("----------------------------------------\n");
......@@ -564,15 +565,15 @@ static int cr_show_all(unsigned long pid, struct cr_options *opts)
}
}
show_pipes(cr_fdset->desc[CR_FD_PIPES].fd);
show_pipes(cr_fdset->fds[CR_FD_PIPES]);
show_files(cr_fdset->desc[CR_FD_FDINFO].fd);
show_files(cr_fdset->fds[CR_FD_FDINFO]);
show_shmem(cr_fdset->desc[CR_FD_SHMEM].fd);
show_shmem(cr_fdset->fds[CR_FD_SHMEM]);
show_sigacts(cr_fdset->desc[CR_FD_SIGACT].fd);
show_sigacts(cr_fdset->fds[CR_FD_SIGACT]);
show_unixsk(cr_fdset->desc[CR_FD_UNIXSK].fd);
show_unixsk(cr_fdset->fds[CR_FD_UNIXSK]);
close_cr_fdset(cr_fdset);
free_cr_fdset(&cr_fdset);
......
......@@ -87,36 +87,24 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
},
};
struct cr_fdset *alloc_cr_fdset(pid_t pid)
struct cr_fdset *alloc_cr_fdset(void)
{
struct cr_fdset *cr_fdset;
unsigned int i;
int ret;
cr_fdset = xzalloc(sizeof(*cr_fdset));
if (!cr_fdset)
goto err;
for (i = 0; i < CR_FD_MAX; i++) {
ret = get_image_path(cr_fdset->desc[i].path,
sizeof(cr_fdset->desc[i].path),
fdset_template[i].fmt, pid);
if (ret) {
xfree(cr_fdset);
return NULL;
}
cr_fdset->desc[i].fd = -1;
}
err:
cr_fdset = xmalloc(sizeof(*cr_fdset));
if (cr_fdset)
for (i = 0; i < CR_FD_MAX; i++)
cr_fdset->fds[i] = -1;
return cr_fdset;
}
int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset,
int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, int pid,
unsigned long use_mask)
{
unsigned int i;
int ret = -1;
char path[PATH_MAX];
if (!cr_fdset)
goto err;
......@@ -125,40 +113,39 @@ int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset,
if (!(use_mask & CR_FD_DESC_USE(i)))
continue;
ret = unlink(cr_fdset->desc[i].path);
if (ret && errno != ENOENT) {
pr_perror("Unable to unlink %s (%s)\n",
cr_fdset->desc[i].path,
strerror(errno));
ret = get_image_path(path, sizeof(path),
fdset_template[i].fmt, pid);
if (ret)
goto err;
} else
ret = -1;
cr_fdset->desc[i].fd = open(cr_fdset->desc[i].path,
O_RDWR | O_CREAT | O_EXCL,
CR_FD_PERM);
if (cr_fdset->desc[i].fd < 0) {
pr_perror("Unable to open %s (%s)\n",
cr_fdset->desc[i].path,
strerror(errno));
ret = unlink(path);
if (ret && errno != ENOENT) {
pr_perror("Unable to unlink %s (%s)\n", path, strerror(errno));
goto err;
}
pr_debug("Opened %s with %d\n",
cr_fdset->desc[i].path,
cr_fdset->desc[i].fd);
ret = open(path, O_RDWR | O_CREAT | O_EXCL, CR_FD_PERM);
if (ret < 0) {
pr_perror("Unable to open %s (%s)\n", path, strerror(errno));
goto err;
}
write_ptr_safe(cr_fdset->desc[i].fd, &fdset_template[i].magic, err);
pr_debug("Opened %s with %d\n", path, ret);
write_ptr_safe(ret, &fdset_template[i].magic, err);
cr_fdset->fds[i] = ret;
}
ret = 0;
err:
return ret;
}
int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset,
int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, int pid,
unsigned long use_mask)
{
unsigned int i;
int ret = -1;
char path[PATH_MAX];
u32 magic;
if (!cr_fdset)
......@@ -168,27 +155,28 @@ int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset,
if (!(use_mask & CR_FD_DESC_USE(i)))
continue;
cr_fdset->desc[i].fd = open(cr_fdset->desc[i].path,
O_RDWR, CR_FD_PERM);
if (cr_fdset->desc[i].fd < 0) {
pr_perror("Unable to open %s (%s)\n",
cr_fdset->desc[i].path,
strerror(errno));
ret = get_image_path(path, sizeof(path),
fdset_template[i].fmt, pid);
if (ret)
goto err;
}
pr_debug("Opened %s with %d\n",
cr_fdset->desc[i].path,
cr_fdset->desc[i].fd);
ret = open(path, O_RDWR, CR_FD_PERM);
if (ret < 0) {
pr_perror("Unable to open %s (%s)\n", path, strerror(errno));
goto err;
}
read_ptr_safe(cr_fdset->desc[i].fd, &magic, err);
pr_debug("Opened %s with %d\n", path, ret);
read_ptr_safe(ret, &magic, err);
if (magic != fdset_template[i].magic) {
pr_err("Magic doesn't match for %s\n",
cr_fdset->desc[i].path);
close(ret);
pr_err("Magic doesn't match for %s\n", path);
goto err;
}
cr_fdset->fds[i] = ret;
}
ret = 0;
err:
return ret;
......@@ -202,14 +190,12 @@ void close_cr_fdset(struct cr_fdset *cr_fdset)
return;
for (i = 0; i < CR_FD_MAX; i++) {
if (cr_fdset->desc[i].fd == -1)
if (cr_fdset->fds[i] == -1)
continue;
pr_debug("Closed %s with %d\n",
cr_fdset->desc[i].path,
cr_fdset->desc[i].fd);
close(cr_fdset->desc[i].fd);
cr_fdset->desc[i].fd = -1;
pr_debug("Closed %d/%d\n", i, cr_fdset->fds[i]);
close(cr_fdset->fds[i]);
cr_fdset->fds[i] = -1;
}
}
......
......@@ -70,14 +70,8 @@ extern int open_image_ro_nocheck(const char *fmt, int pid);
#define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid"
#define LAST_PID_PERM 0666
/* file descriptors */
struct cr_fd_desc {
char path[PATH_MAX]; /* the path, based on pid */
int fd; /* descriptor for open/close */
};
struct cr_fdset {
struct cr_fd_desc desc[CR_FD_MAX];
int fds[CR_FD_MAX];
};
#define CR_FD_DESC_USE(type) ((1 << (type)))
......@@ -91,10 +85,10 @@ int cr_restore_tasks(pid_t pid, struct cr_options *opts);
int cr_show(unsigned long pid, struct cr_options *opts);
int convert_to_elf(char *elf_path, int fd_core);
struct cr_fdset *alloc_cr_fdset(pid_t pid);
int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset,
struct cr_fdset *alloc_cr_fdset(void);
int prep_cr_fdset_for_dump(struct cr_fdset *cr_fdset, int pid,
unsigned long use_mask);
int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset,
int prep_cr_fdset_for_restore(struct cr_fdset *cr_fdset, int pid,
unsigned long use_mask);
void close_cr_fdset(struct cr_fdset *cr_fdset);
void free_cr_fdset(struct cr_fdset **cr_fdset);
......
......@@ -345,29 +345,22 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
{
parasite_args_cmd_dumpsigacts_t parasite_sigacts = { };
int status, path_len, ret = -1;
int status, ret = -1;
pr_info("\n");
pr_info("Dumping sigactions (pid: %d)\n", ctl->pid);
pr_info("----------------------------------------\n");
path_len = strlen(cr_fdset->desc[CR_FD_SIGACT].path);
if (path_len > sizeof(parasite_sigacts.open_path)) {
pr_panic("Dumping sigactions path is too long (%d while %d allowed)\n",
path_len, sizeof(parasite_sigacts.open_path));
if (get_image_path(parasite_sigacts.open_path,
sizeof(parasite_sigacts.open_path),
fdset_template[CR_FD_SIGACT].fmt, ctl->pid))
goto out;
}
if (fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM_DUMP)) {
if (fchmod(cr_fdset->fds[CR_FD_SIGACT], CR_FD_PERM_DUMP)) {
pr_perror("Can't change permissions on sigactions file\n");
goto out;
}
strncpy(parasite_sigacts.open_path,
cr_fdset->desc[CR_FD_SIGACT].path,
sizeof(parasite_sigacts.open_path));
parasite_sigacts.open_flags = O_WRONLY;
parasite_sigacts.open_mode = CR_FD_PERM_DUMP;
......@@ -376,7 +369,7 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
sizeof(parasite_sigacts));
err:
jerr(fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM), out);
jerr(fchmod(cr_fdset->fds[CR_FD_SIGACT], CR_FD_PERM), out);
out:
pr_info("----------------------------------------\n");
......@@ -397,22 +390,18 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
unsigned long nrpages_dumped = 0;
struct vma_area *vma_area;
siginfo_t siginfo;
int status, path_len, ret = -1;
int status, ret = -1;
pr_info("\n");
pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, ctl->pid);
pr_info("----------------------------------------\n");
path_len = strlen(cr_fdset->desc[CR_FD_PAGES].path);
pr_info("Dumping pages %s\n", cr_fdset->desc[CR_FD_PAGES].path);
if (path_len > sizeof(parasite_dumppages.open_path)) {
pr_panic("Dumping pages path is too long (%d while %d allowed)\n",
path_len, sizeof(parasite_dumppages.open_path));
if (get_image_path(parasite_dumppages.open_path,
sizeof(parasite_dumppages.open_path),
fdset_template[CR_FD_PAGES].fmt, ctl->pid))
goto out;
}
if (fchmod(cr_fdset->desc[CR_FD_PAGES].fd, CR_FD_PERM_DUMP)) {
if (fchmod(cr_fdset->fds[CR_FD_PAGES], CR_FD_PERM_DUMP)) {
pr_perror("Can't change permissions on pages file\n");
goto out;
}
......@@ -421,11 +410,7 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
* Make sure the data is on disk since we will re-open
* it in another process.
*/
fsync(cr_fdset->desc[CR_FD_PAGES].fd);
strncpy(parasite_dumppages.open_path,
cr_fdset->desc[CR_FD_PAGES].path,
sizeof(parasite_dumppages.open_path));
fsync(cr_fdset->fds[CR_FD_PAGES]);
parasite_dumppages.open_flags = O_WRONLY;
parasite_dumppages.open_mode = CR_FD_PERM_DUMP;
......@@ -484,16 +469,16 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
* We don't know the position in file since it's updated
* outside of our process.
*/
lseek(cr_fdset->desc[CR_FD_PAGES].fd, 0, SEEK_END);
lseek(cr_fdset->fds[CR_FD_PAGES], 0, SEEK_END);
/* Ending page */
write_ptr_safe(cr_fdset->desc[CR_FD_PAGES].fd, &zero_page_entry, err_restore);
write_ptr_safe(cr_fdset->fds[CR_FD_PAGES], &zero_page_entry, err_restore);
pr_info("\n");
pr_info("Summary: %16li pages dumped\n", nrpages_dumped);
err_restore:
jerr(fchmod(cr_fdset->desc[CR_FD_PAGES].fd, CR_FD_PERM), out);
jerr(fchmod(cr_fdset->fds[CR_FD_PAGES], CR_FD_PERM), out);
out:
pr_info("----------------------------------------\n");
......
......@@ -162,8 +162,8 @@ static int dump_one_unix(struct socket_desc *_sk, char *fd, struct cr_fdset *cr_
ue.pad = 0;
ue.peer = sk->peer_ino;
write_ptr_safe(cr_fdset->desc[CR_FD_UNIXSK].fd, &ue, err);
write_safe(cr_fdset->desc[CR_FD_UNIXSK].fd, sk->name, ue.namelen, err);
write_ptr_safe(cr_fdset->fds[CR_FD_UNIXSK], &ue, err);
write_safe(cr_fdset->fds[CR_FD_UNIXSK], sk->name, ue.namelen, err);
pr_info("Dumping unix socket at %s\n", fd);
show_one_unix("Dumping", sk);
......
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