mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-03 15:23:04 +00:00
crtools: R/W API rewrite
Kill all the macros for reading/writing image parts. New API looks like * write_img_buf/write_img Write an object into an image. Reports 0 for OK, -1 for error. The _buf version accepts object size as an argument, the other one uses sizeof() * read_img_buf/read_img Reads an object from image. Reports 0 for OK, -1 for error or EOF. * read_img_buf_eof/read_img Reads an object from image. Reports 1 for OK, 0 for EOF and -1 for error. This is not symmetrical with the previous one, but it was done deliberately to make it possible to write code like ret = read_img_bug_eof(); if (ret <= 0) return ret; /* 0 means OK, all is done, -1 means error was met */. ... /* 1 means object was read, can proceed */ Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
parent
dbf3c1a8cd
commit
164ccc095f
9 changed files with 167 additions and 127 deletions
43
cr-dump.c
43
cr-dump.c
|
|
@ -127,8 +127,10 @@ static int dump_one_reg_file(int type, struct fd_parms *p, int lfd,
|
|||
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8x addr: %16lx\n",
|
||||
type, len, p->flags, p->pos, p->fd_name);
|
||||
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_FDINFO], &e, err);
|
||||
write_safe(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.len, err);
|
||||
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.len))
|
||||
goto err;
|
||||
|
||||
ret = 0;
|
||||
err:
|
||||
|
|
@ -189,7 +191,8 @@ static int dump_pipe_and_data(int lfd, struct pipe_entry *e,
|
|||
}
|
||||
|
||||
e->bytes = has_bytes;
|
||||
write_ptr_safe(fd_pipes, e, err_close);
|
||||
if (write_img(fd_pipes, e))
|
||||
goto err_close;
|
||||
|
||||
if (has_bytes) {
|
||||
ret = splice(steal_pipe[0], NULL, fd_pipes,
|
||||
|
|
@ -224,8 +227,7 @@ static int dump_one_pipe(struct fd_parms *p, unsigned int id, int lfd,
|
|||
|
||||
if (p->flags & O_WRONLY) {
|
||||
e.bytes = 0;
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_PIPES], &e, err);
|
||||
ret = 0;
|
||||
ret = write_img(cr_fdset->fds[CR_FD_PIPES], &e);
|
||||
} else
|
||||
ret = dump_pipe_and_data(lfd, &e, cr_fdset);
|
||||
|
||||
|
|
@ -395,7 +397,8 @@ 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->fds[CR_FD_SHMEM], &e, err);
|
||||
if (write_img(cr_fdset->fds[CR_FD_SHMEM], &e))
|
||||
goto err;
|
||||
} else if (vma_entry_is(vma, VMA_FILE_PRIVATE) ||
|
||||
vma_entry_is(vma, VMA_FILE_SHARED)) {
|
||||
struct fd_parms p = {
|
||||
|
|
@ -612,7 +615,8 @@ static int dump_task_core_seized(pid_t pid, int pid_dir, struct proc_pid_stat *s
|
|||
core->header.arch = HEADER_ARCH_X86_64;
|
||||
core->header.flags = 0;
|
||||
|
||||
write_ptr_safe(fd_core, core, err_free);
|
||||
if (write_img(fd_core, core))
|
||||
goto err_free;
|
||||
|
||||
pr_info("OK\n");
|
||||
ret = 0;
|
||||
|
|
@ -814,21 +818,24 @@ 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->fds[CR_FD_PSTREE], &e, err);
|
||||
if (write_img(cr_fdset->fds[CR_FD_PSTREE], &e))
|
||||
goto err;
|
||||
|
||||
pr_info("Children:");
|
||||
for (i = 0; i < item->nr_children; i++) {
|
||||
pr_info(" %d", item->children[i]);
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE],
|
||||
&item->children[i], err);
|
||||
if (write_img(cr_fdset->fds[CR_FD_PSTREE],
|
||||
&item->children[i]))
|
||||
goto err;
|
||||
}
|
||||
pr_info("\n");
|
||||
|
||||
pr_info("Threads:\n");
|
||||
for (i = 0; i < item->nr_threads; i++) {
|
||||
pr_info(" %d", item->threads[i]);
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_PSTREE],
|
||||
&item->threads[i], err);
|
||||
if (write_img(cr_fdset->fds[CR_FD_PSTREE],
|
||||
&item->threads[i]))
|
||||
goto err;
|
||||
}
|
||||
pr_info("\n");
|
||||
}
|
||||
|
|
@ -889,7 +896,8 @@ static int finalize_core(pid_t pid, struct list_head *vma_area_list, struct cr_f
|
|||
|
||||
/* Ending marker */
|
||||
memzero_p(&ve);
|
||||
write_ptr_safe(fd_core, &ve, err);
|
||||
if (write_img(fd_core, &ve))
|
||||
goto err;
|
||||
|
||||
pr_info("OK (%li written)\n", num);
|
||||
|
||||
|
|
@ -908,8 +916,10 @@ static int finalize_core(pid_t pid, struct list_head *vma_area_list, struct cr_f
|
|||
|
||||
/* Ending marker */
|
||||
if (va == 0) {
|
||||
write_ptr_safe(fd_core, &zero_page_entry, err);
|
||||
write_ptr_safe(fd_pages_shmem, &zero_page_entry, err);
|
||||
if (write_img(fd_core, &zero_page_entry))
|
||||
goto err;
|
||||
if (write_img(fd_pages_shmem, &zero_page_entry))
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1007,7 +1017,8 @@ static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset)
|
|||
core->header.arch = HEADER_ARCH_X86_64;
|
||||
core->header.flags = 0;
|
||||
|
||||
write_ptr_safe(fd_core, core, err_free);
|
||||
if (write_img(fd_core, core))
|
||||
goto err_free;
|
||||
|
||||
pr_info("OK\n");
|
||||
ret = 0;
|
||||
|
|
|
|||
10
cr-restore.c
10
cr-restore.c
|
|
@ -1104,7 +1104,8 @@ static inline int fork_with_pid(int pid)
|
|||
goto err;
|
||||
}
|
||||
|
||||
write_safe(fd, buf, strlen(buf), err_unlock);
|
||||
if (write_img_buf(fd, buf, strlen(buf)))
|
||||
goto err_unlock;
|
||||
|
||||
ret = fork();
|
||||
if (ret < 0) {
|
||||
|
|
@ -1460,8 +1461,8 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
|
|||
*/
|
||||
lseek(fd_pstree, MAGIC_OFFSET, SEEK_SET);
|
||||
while (1) {
|
||||
ret = read_ptr_safe_eof(fd_pstree, &pstree_entry, err);
|
||||
if (!ret) {
|
||||
ret = read_img_eof(fd_pstree, &pstree_entry);
|
||||
if (ret <= 0) {
|
||||
pr_perror("Pid %d not found in process tree\n", pid);
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -1595,7 +1596,8 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
|
|||
*/
|
||||
lseek(fd_pstree, sizeof(u32) * pstree_entry.nr_children, SEEK_CUR);
|
||||
for (i = 0; i < pstree_entry.nr_threads; i++) {
|
||||
read_ptr_safe(fd_pstree, &thread_args[i].pid, err);
|
||||
if (read_img(fd_pstree, &thread_args[i].pid) < 0)
|
||||
goto err;
|
||||
|
||||
/* skip self */
|
||||
if (thread_args[i].pid == pid)
|
||||
|
|
|
|||
105
cr-show.c
105
cr-show.c
|
|
@ -58,8 +58,10 @@ static void show_shmem(int fd_shmem)
|
|||
pr_img_head(CR_FD_SHMEM);
|
||||
|
||||
while (1) {
|
||||
int ret = read_ptr_safe_eof(fd_shmem, &e, out);
|
||||
if (!ret)
|
||||
int ret;
|
||||
|
||||
ret = read_img_eof(fd_shmem, &e);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
pr_info("0x%lx-0x%lx id %lu\n", e.start, e.end, e.shmid);
|
||||
}
|
||||
|
|
@ -75,8 +77,10 @@ static void show_files(int fd_files)
|
|||
pr_img_head(CR_FD_FDINFO);
|
||||
|
||||
while (1) {
|
||||
int ret = read_ptr_safe_eof(fd_files, &e, out);
|
||||
if (!ret)
|
||||
int ret;
|
||||
|
||||
ret = read_img_eof(fd_files, &e);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
pr_info("type: %02x len: %02x flags: %4x pos: %8x addr: %16lx id: %s",
|
||||
|
|
@ -107,8 +111,10 @@ static void show_pipes(int fd_pipes)
|
|||
pr_img_head(CR_FD_PIPES);
|
||||
|
||||
while (1) {
|
||||
int ret = read_ptr_safe_eof(fd_pipes, &e, out);
|
||||
if (!ret)
|
||||
int ret;
|
||||
|
||||
ret = read_img_eof(fd_pipes, &e);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
pr_info("fd: %8lx pipeid: %8lx flags: %8lx bytes: %8lx\n",
|
||||
e.fd, e.pipeid, e.flags, e.bytes);
|
||||
|
|
@ -127,7 +133,8 @@ static void show_vma(int fd_vma)
|
|||
|
||||
pr_info("\n\t---[VMA areas]---\n");
|
||||
while (1) {
|
||||
read_ptr_safe(fd_vma, &ve, out);
|
||||
if (read_img(fd_vma, &ve) < 0)
|
||||
break;
|
||||
|
||||
if (final_vma_entry(&ve))
|
||||
break;
|
||||
|
|
@ -136,8 +143,6 @@ static void show_vma(int fd_vma)
|
|||
vma_area.vma = ve;
|
||||
pr_info_vma(&vma_area);
|
||||
}
|
||||
out:
|
||||
; /* to placate gcc */
|
||||
}
|
||||
|
||||
static void show_pages(int fd_pages, bool show_content)
|
||||
|
|
@ -150,7 +155,8 @@ static void show_pages(int fd_pages, bool show_content)
|
|||
unsigned long addr;
|
||||
int i, j;
|
||||
|
||||
read_ptr_safe(fd_pages, &e, out);
|
||||
if (read_img(fd_pages, &e) < 0)
|
||||
break;
|
||||
if (final_page_entry(&e))
|
||||
break;
|
||||
|
||||
|
|
@ -181,7 +187,8 @@ static void show_pages(int fd_pages, bool show_content)
|
|||
|
||||
pr_info("\t");
|
||||
for (i = 0; i < DEF_PAGES_PER_LINE; i++) {
|
||||
read_ptr_safe(fd_pages, &e, out);
|
||||
if (read_img(fd_pages, &e) < 0)
|
||||
goto out;
|
||||
if (final_page_entry(&e)) {
|
||||
pr_info("\n");
|
||||
goto out;
|
||||
|
|
@ -203,8 +210,10 @@ static void show_sigacts(int fd_sigacts)
|
|||
pr_img_head(CR_FD_SIGACT);
|
||||
|
||||
while (1) {
|
||||
int ret = read_ptr_safe_eof(fd_sigacts, &e, out);
|
||||
if (!ret)
|
||||
int ret;
|
||||
|
||||
ret = read_img_eof(fd_sigacts, &e);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
pr_info("sigaction: %016lx mask: %08lx "
|
||||
"flags: %016lx restorer: %016lx\n",
|
||||
|
|
@ -229,8 +238,8 @@ static int show_pstree(int fd_pstree, struct list_head *collect)
|
|||
int ret;
|
||||
struct pstree_item *item = NULL;
|
||||
|
||||
ret = read_ptr_safe_eof(fd_pstree, &e, out);
|
||||
if (!ret)
|
||||
ret = read_img_eof(fd_pstree, &e);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
pr_info("pid: %8d nr_children: %8d nr_threads: %8d\n",
|
||||
e.pid, e.nr_children, e.nr_threads);
|
||||
|
|
@ -255,8 +264,8 @@ static int show_pstree(int fd_pstree, struct list_head *collect)
|
|||
pr_info("\\\n");
|
||||
pr_info(" +--- children: ");
|
||||
while (e.nr_children--) {
|
||||
ret = read_ptr_safe_eof(fd_pstree, &pid, out);
|
||||
if (!ret)
|
||||
ret = read_img_eof(fd_pstree, &pid);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
pr_info(" %6d", pid);
|
||||
}
|
||||
|
|
@ -267,8 +276,8 @@ static int show_pstree(int fd_pstree, struct list_head *collect)
|
|||
pr_info(" \\\n");
|
||||
pr_info(" --- threads: ");
|
||||
while (e.nr_threads--) {
|
||||
ret = read_ptr_safe_eof(fd_pstree, &pid, out);
|
||||
if (!ret)
|
||||
ret = read_img_eof(fd_pstree, &pid);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
pr_info(" %6d", pid);
|
||||
if (item)
|
||||
|
|
@ -294,7 +303,8 @@ static void show_core_regs(int fd_core)
|
|||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, arch.gpregs), SEEK_SET);
|
||||
|
||||
read_ptr_safe(fd_core, ®s, err);
|
||||
if (read_img(fd_core, ®s) < 0)
|
||||
goto err;
|
||||
|
||||
pr_regs4(regs, cs, ip, ds, es);
|
||||
pr_regs4(regs, ss, sp, fs, gs);
|
||||
|
|
@ -311,49 +321,23 @@ err:
|
|||
|
||||
static void show_core_rest(int fd_core)
|
||||
{
|
||||
u64 mm_start_data, mm_end_data, mm_start_stack, mm_start_brk;
|
||||
u64 mm_brk, mm_start_code, mm_end_code;
|
||||
char comm[TASK_COMM_LEN];
|
||||
u32 personality;
|
||||
struct task_core_entry tc;
|
||||
int i;
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.personality), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &personality, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.comm), SEEK_SET);
|
||||
read_safe(fd_core, comm, TASK_COMM_LEN, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_brk), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_brk, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_start_code), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_code, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_end_code), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_end_code, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_start_stack), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_stack, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_start_data), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_data, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_end_data), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_end_data, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc.mm_start_brk), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_brk, err);
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc), SEEK_SET);
|
||||
if (read_img(fd_core, &tc) < 0)
|
||||
goto err;
|
||||
|
||||
pr_info("\n\t---[Task parameters]---\n");
|
||||
pr_info("\tPersonality: %x\n", personality);
|
||||
pr_info("\tCommand: %s\n", comm);
|
||||
pr_info("\tBrk: %lx\n", mm_brk);
|
||||
pr_info("\tStart code: %lx\n", mm_start_code);
|
||||
pr_info("\tEnd code: %lx\n", mm_end_code);
|
||||
pr_info("\tStart stack: %lx\n", mm_start_stack);
|
||||
pr_info("\tStart data: %lx\n", mm_start_data);
|
||||
pr_info("\tEnd data: %lx\n", mm_end_data);
|
||||
pr_info("\tStart brk: %lx\n", mm_start_brk);
|
||||
pr_info("\tPersonality: %x\n", tc.personality);
|
||||
pr_info("\tCommand: %s\n", tc.comm);
|
||||
pr_info("\tBrk: %lx\n", tc.mm_brk);
|
||||
pr_info("\tStart code: %lx\n", tc.mm_start_code);
|
||||
pr_info("\tEnd code: %lx\n", tc.mm_end_code);
|
||||
pr_info("\tStart stack: %lx\n", tc.mm_start_stack);
|
||||
pr_info("\tStart data: %lx\n", tc.mm_start_data);
|
||||
pr_info("\tEnd data: %lx\n", tc.mm_end_data);
|
||||
pr_info("\tStart brk: %lx\n", tc.mm_start_brk);
|
||||
pr_info("\n");
|
||||
|
||||
err:
|
||||
|
|
@ -410,7 +394,8 @@ static int cr_parse_file(struct cr_options *opts)
|
|||
goto err;
|
||||
}
|
||||
|
||||
read_ptr_safe(fd, &magic, err);
|
||||
if (read_img(fd, &magic) < 0)
|
||||
goto err;
|
||||
|
||||
switch (magic) {
|
||||
case FDINFO_MAGIC:
|
||||
|
|
|
|||
|
|
@ -142,7 +142,9 @@ struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask, struct cr_fdset
|
|||
}
|
||||
|
||||
pr_debug("Opened %s with %d\n", path, ret);
|
||||
write_ptr_safe(ret, &fdset_template[i].magic, err);
|
||||
if (write_img(ret, &fdset_template[i].magic))
|
||||
goto err;
|
||||
|
||||
cr_fdset->fds[i] = ret;
|
||||
}
|
||||
err:
|
||||
|
|
@ -177,7 +179,8 @@ struct cr_fdset *prep_cr_fdset_for_restore(int pid, unsigned long use_mask)
|
|||
}
|
||||
|
||||
pr_debug("Opened %s with %d\n", path, ret);
|
||||
read_ptr_safe(ret, &magic, err);
|
||||
if (read_img(ret, &magic) < 0)
|
||||
goto err;
|
||||
if (magic != fdset_template[i].magic) {
|
||||
close(ret);
|
||||
pr_err("Magic doesn't match for %s\n", path);
|
||||
|
|
|
|||
3
files.c
3
files.c
|
|
@ -603,7 +603,8 @@ int try_fixup_file_map(int pid, struct vma_entry *vma_entry, int fd)
|
|||
lseek(fd, -sizeof(*vma_entry), SEEK_CUR);
|
||||
vma_entry->fd = fmap_fd->fd;
|
||||
|
||||
write_ptr_safe(fd, vma_entry, err);
|
||||
if (write_img(fd, vma_entry))
|
||||
goto err;
|
||||
|
||||
free(fmap_fd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
|
@ -116,40 +117,73 @@ extern void printk(const char *format, ...);
|
|||
|
||||
#define BUG_ON(condition) BUG_ON_HANDLER((condition))
|
||||
|
||||
#define write_ptr(fd, ptr) \
|
||||
write(fd, (ptr), sizeof(*(ptr)))
|
||||
/*
|
||||
* Write buffer @ptr of @size bytes into @fd file
|
||||
* Returns
|
||||
* 0 on success
|
||||
* -1 on error (error message is printed)
|
||||
*/
|
||||
static inline int write_img_buf(int fd, void *ptr, int size)
|
||||
{
|
||||
int ret;
|
||||
ret = write(fd, ptr, size);
|
||||
if (ret == size)
|
||||
return 0;
|
||||
|
||||
#define write_ptr_safe(fd, ptr, err) \
|
||||
jerr(write_ptr(fd, ptr) != sizeof(*(ptr)), err)
|
||||
if (ret < 0)
|
||||
pr_perror("Can't write img file\n");
|
||||
else
|
||||
pr_err("Img trimmed %d/%d\n", ret, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define write_safe(fd, ptr, size, err) \
|
||||
jerr(write(fd, (ptr), (size)) != (size), err)
|
||||
#define write_img(fd, ptr) write_img_buf((fd), (ptr), sizeof(*(ptr)))
|
||||
|
||||
#define write_safe_imm(fd, imm, err) \
|
||||
do { \
|
||||
typeof(imm) x__ = imm; \
|
||||
write_ptr_safe(fd, &x__, err); \
|
||||
} while (0)
|
||||
/*
|
||||
* Read buffer @ptr of @size bytes from @fd file
|
||||
* Returns
|
||||
* 1 on success
|
||||
* 0 on EOF (silently)
|
||||
* -1 on error (error message is printed)
|
||||
*/
|
||||
static inline int read_img_buf_eof(int fd, void *ptr, int size)
|
||||
{
|
||||
int ret;
|
||||
ret = read(fd, ptr, size);
|
||||
if (ret == size)
|
||||
return 1;
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
#define read_safe(fd, ptr, size, err) \
|
||||
jerr(read(fd, ptr, (size)) != (size), err)
|
||||
if (ret < 0)
|
||||
pr_perror("Can't read img file\n");
|
||||
else
|
||||
pr_err("Img trimmed %d/%d\n", ret, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define read_ptr_safe(fd, ptr, err) \
|
||||
jerr(read(fd, ptr, sizeof(*(ptr))) != sizeof(*(ptr)), err)
|
||||
#define read_img_eof(fd, ptr) read_img_buf_eof((fd), (ptr), sizeof(*(ptr)))
|
||||
|
||||
#define read_safe_eof(fd, ptr, size, err) \
|
||||
({ \
|
||||
size_t rc__ = read(fd, ptr, (size)); \
|
||||
if (rc__ && rc__ != (size)) { \
|
||||
pr_err("img corruption %d/%d\n", \
|
||||
rc__, (size)); \
|
||||
goto err; \
|
||||
} \
|
||||
rc__; \
|
||||
})
|
||||
/*
|
||||
* Read buffer @ptr of @size bytes from @fd file
|
||||
* Returns
|
||||
* 1 on success
|
||||
* -1 on error or EOF (error message is printed)
|
||||
*/
|
||||
static inline int read_img_buf(int fd, void *ptr, int size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#define read_ptr_safe_eof(fd, ptr, err) \
|
||||
read_safe_eof(fd, ptr, sizeof(*(ptr)), err)
|
||||
ret = read_img_buf_eof(fd, ptr, size);
|
||||
if (ret == 0) {
|
||||
pr_err("Unexpected EOF\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define read_img(fd, ptr) read_img_buf((fd), (ptr), sizeof(*(ptr)))
|
||||
|
||||
#define memzero_p(p) memset(p, 0, sizeof(*p))
|
||||
#define memzero(p, size) memset(p, 0, size)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libnetlink.h"
|
||||
#include "util.h"
|
||||
|
|
|
|||
|
|
@ -472,7 +472,8 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
|
|||
lseek(cr_fdset->fds[CR_FD_PAGES], 0, SEEK_END);
|
||||
|
||||
/* Ending page */
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_PAGES], &zero_page_entry, err_restore);
|
||||
if (write_img(cr_fdset->fds[CR_FD_PAGES], &zero_page_entry))
|
||||
goto err_restore;
|
||||
|
||||
pr_info("\n");
|
||||
pr_info("Summary: %16li pages dumped\n", nrpages_dumped);
|
||||
|
|
|
|||
34
sockets.c
34
sockets.c
|
|
@ -187,7 +187,8 @@ static int dump_one_inet(struct socket_desc *_sk, int fd, struct cr_fdset *cr_fd
|
|||
ie.backlog = sk->wqlen;
|
||||
memcpy(ie.src_addr, sk->src_addr, sizeof(u32) * 4);
|
||||
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_INETSK], &ie, err);
|
||||
if (write_img(cr_fdset->fds[CR_FD_INETSK], &ie))
|
||||
goto err;
|
||||
|
||||
pr_info("Dumping inet socket at %d\n", fd);
|
||||
show_one_inet("Dumping", sk);
|
||||
|
|
@ -270,8 +271,10 @@ static int dump_one_unix(struct socket_desc *_sk, int fd, struct cr_fdset *cr_fd
|
|||
ue.pad = 0;
|
||||
ue.peer = sk->peer_ino;
|
||||
|
||||
write_ptr_safe(cr_fdset->fds[CR_FD_UNIXSK], &ue, err);
|
||||
write_safe(cr_fdset->fds[CR_FD_UNIXSK], sk->name, ue.namelen, err);
|
||||
if (write_img(cr_fdset->fds[CR_FD_UNIXSK], &ue))
|
||||
goto err;
|
||||
if (write_img_buf(cr_fdset->fds[CR_FD_UNIXSK], sk->name, ue.namelen))
|
||||
goto err;
|
||||
|
||||
pr_info("Dumping unix socket at %d\n", fd);
|
||||
show_one_unix("Dumping", sk);
|
||||
|
|
@ -941,8 +944,8 @@ static int prepare_unix_sockets(int pid)
|
|||
while (1) {
|
||||
struct unix_sk_entry ue;
|
||||
|
||||
ret = read_ptr_safe_eof(usk_fd, &ue, err);
|
||||
if (ret == 0)
|
||||
ret = read_img_eof(usk_fd, &ue);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
ret = open_unix_sk(&ue, &usk_fd);
|
||||
|
|
@ -1025,8 +1028,8 @@ static int prepare_inet_sockets(int pid)
|
|||
while (1) {
|
||||
struct inet_sk_entry ie;
|
||||
|
||||
ret = read_ptr_safe_eof(isk_fd, &ie, err);
|
||||
if (ret == 0)
|
||||
ret = read_img_eof(isk_fd, &ie);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
ret = open_inet_sk(&ie, &isk_fd);
|
||||
|
|
@ -1059,8 +1062,8 @@ void show_inetsk(int fd)
|
|||
while (1) {
|
||||
char src_addr[INET_ADDR_LEN] = "<unknown>";
|
||||
|
||||
ret = read_ptr_safe_eof(fd, &ie, out);
|
||||
if (!ret)
|
||||
ret = read_img_eof(fd, &ie);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
if (inet_ntop(AF_INET, (void *)ie.src_addr, src_addr,
|
||||
|
|
@ -1087,27 +1090,26 @@ void show_unixsk(int fd)
|
|||
pr_img_head(CR_FD_UNIXSK);
|
||||
|
||||
while (1) {
|
||||
ret = read_ptr_safe_eof(fd, &ue, out);
|
||||
if (!ret)
|
||||
ret = read_img_eof(fd, &ue);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
pr_info("fd %4d type %2d state %2d namelen %4d backlog %4d id %6d peer %6d",
|
||||
ue.fd, ue.type, ue.state, ue.namelen, ue.namelen, ue.id, ue.peer);
|
||||
|
||||
if (ue.namelen) {
|
||||
ret = read_safe_eof(fd, buf, ue.namelen, out);
|
||||
if (!ret)
|
||||
ret = read_img_buf(fd, buf, ue.namelen);
|
||||
if (ret < 0) {
|
||||
pr_info("\n");
|
||||
goto out;
|
||||
}
|
||||
if (!buf[0])
|
||||
buf[0] = '@';
|
||||
pr_info(" --> %s\n", buf);
|
||||
} else
|
||||
pr_info("\n");
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret)
|
||||
pr_info("\n");
|
||||
pr_img_tail(CR_FD_UNIXSK);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue