diff --git a/eventfd.c b/eventfd.c index bbb5a5b35..7098368e2 100644 --- a/eventfd.c +++ b/eventfd.c @@ -126,8 +126,14 @@ static int collect_one_efd(void *obj, ProtobufCMessage *msg) return file_desc_add(&info->d, info->efe->id, &eventfd_desc_ops); } +struct collect_image_info eventfd_cinfo = { + .fd_type = CR_FD_EVENTFD, + .pb_type = PB_EVENTFD, + .priv_size = sizeof(struct eventfd_file_info), + .collect = collect_one_efd, +}; + int collect_eventfd(void) { - return collect_image(CR_FD_EVENTFD, PB_EVENTFD, - sizeof(struct eventfd_file_info), collect_one_efd); + return collect_image(&eventfd_cinfo); } diff --git a/eventpoll.c b/eventpoll.c index 92a5bcc96..54710128d 100644 --- a/eventpoll.c +++ b/eventpoll.c @@ -176,6 +176,13 @@ static int collect_one_epoll_tfd(void *o, ProtobufCMessage *msg) return 0; } +struct collect_image_info epoll_tfd_cinfo = { + .fd_type = CR_FD_EVENTPOLL_TFD, + .pb_type = PB_EVENTPOLL_TFD, + .priv_size = sizeof(struct eventpoll_tfd_file_info), + .collect = collect_one_epoll_tfd, +}; + static int collect_one_epoll(void *o, ProtobufCMessage *msg) { struct eventpoll_file_info *info = o; @@ -185,17 +192,20 @@ static int collect_one_epoll(void *o, ProtobufCMessage *msg) return file_desc_add(&info->d, info->efe->id, &desc_ops); } +struct collect_image_info epoll_cinfo = { + .fd_type = CR_FD_EVENTPOLL, + .pb_type = PB_EVENTPOLL, + .priv_size = sizeof(struct eventpoll_file_info), + .collect = collect_one_epoll, +}; + int collect_eventpoll(void) { int ret; - ret = collect_image(CR_FD_EVENTPOLL_TFD, PB_EVENTPOLL_TFD, - sizeof(struct eventpoll_tfd_file_info), - collect_one_epoll_tfd); + ret = collect_image(&epoll_tfd_cinfo); if (!ret) - ret = collect_image(CR_FD_EVENTPOLL, PB_EVENTPOLL, - sizeof(struct eventpoll_file_info), - collect_one_epoll); + ret = collect_image(&epoll_cinfo); return ret; } diff --git a/fifo.c b/fifo.c index 738957274..d3d6a6e0c 100644 --- a/fifo.c +++ b/fifo.c @@ -142,12 +142,18 @@ static int collect_one_fifo(void *o, ProtobufCMessage *base) } +struct collect_image_info fifo_cinfo = { + .fd_type = CR_FD_FIFO, + .pb_type = PB_FIFO, + .priv_size = sizeof(struct fifo_info), + .collect = collect_one_fifo, +}; + int collect_fifo(void) { int ret; - ret = collect_image(CR_FD_FIFO, PB_FIFO, - sizeof(struct fifo_info), collect_one_fifo); + ret = collect_image(&fifo_cinfo); if (!ret) ret = collect_pipe_data(CR_FD_FIFO_DATA, pd_hash_fifo); diff --git a/files-reg.c b/files-reg.c index 16f64424e..dd7a4438d 100644 --- a/files-reg.c +++ b/files-reg.c @@ -192,6 +192,12 @@ out: return ret; } +struct collect_image_info remap_cinfo = { + .fd_type = CR_FD_REMAP_FPATH, + .pb_type = PB_REMAP_FPATH, + .collect = collect_one_remap, +}; + static int dump_ghost_file(int _fd, u32 id, const struct stat *st) { int img; @@ -559,6 +565,13 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base) return file_desc_add(&rfi->d, rfi->rfe->id, ®_desc_ops); } +struct collect_image_info reg_file_cinfo = { + .fd_type = CR_FD_REG_FILES, + .pb_type = PB_REG_FILES, + .priv_size = sizeof(struct reg_file_info), + .collect = collect_one_regfile, +}; + int prepare_shared_reg_files(void) { ghost_file_mutex = shmalloc(sizeof(*ghost_file_mutex)); @@ -573,11 +586,9 @@ int collect_reg_files(void) { int ret; - ret = collect_image(CR_FD_REG_FILES, PB_REG_FILES, - sizeof(struct reg_file_info), collect_one_regfile); + ret = collect_image(®_file_cinfo); if (!ret) - ret = collect_image(CR_FD_REMAP_FPATH, PB_REMAP_FPATH, - 0, collect_one_remap); + ret = collect_image(&remap_cinfo); return ret; } diff --git a/fsnotify.c b/fsnotify.c index 69ce85333..4e28ba0ca 100644 --- a/fsnotify.c +++ b/fsnotify.c @@ -459,6 +459,14 @@ static int collect_one_inotify(void *o, ProtobufCMessage *msg) return file_desc_add(&info->d, info->ife->id, &inotify_desc_ops); } +struct collect_image_info inotify_cinfo = { + .fd_type = CR_FD_INOTIFY, + .pb_type = PB_INOTIFY, + .priv_size = sizeof(struct fsnotify_file_info), + .collect = collect_one_inotify, + .flags = COLLECT_OPTIONAL, +}; + static int collect_one_fanotify(void *o, ProtobufCMessage *msg) { struct fsnotify_file_info *info = o; @@ -470,6 +478,14 @@ static int collect_one_fanotify(void *o, ProtobufCMessage *msg) return file_desc_add(&info->d, info->ffe->id, &fanotify_desc_ops); } +struct collect_image_info fanotify_cinfo = { + .fd_type = CR_FD_FANOTIFY, + .pb_type = PB_FANOTIFY, + .priv_size = sizeof(struct fsnotify_file_info), + .collect = collect_one_fanotify, + .flags = COLLECT_OPTIONAL, +}; + static int collect_one_inotify_mark(void *o, ProtobufCMessage *msg) { struct fsnotify_mark_info *mark = o; @@ -481,6 +497,14 @@ static int collect_one_inotify_mark(void *o, ProtobufCMessage *msg) return collect_inotify_mark(mark); } +struct collect_image_info inotify_mark_cinfo = { + .fd_type = CR_FD_INOTIFY_WD, + .pb_type = PB_INOTIFY_WD, + .priv_size = sizeof(struct fsnotify_mark_info), + .collect = collect_one_inotify_mark, + .flags = COLLECT_OPTIONAL, +}; + static int collect_one_fanotify_mark(void *o, ProtobufCMessage *msg) { struct fsnotify_mark_info *mark = o; @@ -492,27 +516,25 @@ static int collect_one_fanotify_mark(void *o, ProtobufCMessage *msg) return collect_fanotify_mark(mark); } +struct collect_image_info fanotify_mark_cinfo = { + .fd_type = CR_FD_FANOTIFY_MARK, + .pb_type = PB_FANOTIFY_MARK, + .priv_size = sizeof(struct fsnotify_mark_info), + .collect = collect_one_fanotify_mark, + .flags = COLLECT_OPTIONAL, +}; + int collect_inotify(void) { int ret; - ret = collect_image(CR_FD_INOTIFY, PB_INOTIFY, - sizeof(struct fsnotify_file_info), collect_one_inotify); - if (ret && errno == ENOENT) - return 0; + ret = collect_image(&inotify_cinfo); if (!ret) - ret = collect_image(CR_FD_INOTIFY_WD, PB_INOTIFY_WD, - sizeof(struct fsnotify_mark_info), - collect_one_inotify_mark); + ret = collect_image(&inotify_mark_cinfo); if (!ret) - ret = collect_image(CR_FD_FANOTIFY, PB_FANOTIFY, - sizeof(struct fsnotify_file_info), - collect_one_fanotify); - if (ret && errno == ENOENT) - return 0; + ret = collect_image(&fanotify_cinfo); if (!ret) - ret = collect_image(CR_FD_FANOTIFY_MARK, PB_FANOTIFY_MARK, - sizeof(struct fsnotify_mark_info), - collect_one_fanotify_mark); + ret = collect_image(&fanotify_mark_cinfo); + return ret; } diff --git a/include/protobuf.h b/include/protobuf.h index 1d438d10b..6a8636da0 100644 --- a/include/protobuf.h +++ b/include/protobuf.h @@ -45,9 +45,17 @@ extern void do_pb_show_plain(int fd, int type, int single_entry, #define pb_show_vertical(__fd, __type) \ do_pb_show_plain(__fd, __type, 1, NULL, NULL) -int collect_image(int fd_t, int obj_t, unsigned size, - int (*collect)(void *obj, ProtobufCMessage *msg)); -int collect_image_sh(int fd_t, int obj_t, unsigned size, - int (*collect)(void *obj, ProtobufCMessage *msg)); +struct collect_image_info { + int fd_type; + int pb_type; + unsigned int priv_size; + int (*collect)(void *, ProtobufCMessage *); + unsigned flags; +}; + +#define COLLECT_SHARED 0x1 /* use shared memory for obj-s */ +#define COLLECT_OPTIONAL 0x2 /* image file may be missing */ + +int collect_image(struct collect_image_info *); #endif /* __CR_PROTOBUF_H__ */ diff --git a/namespaces.c b/namespaces.c index 8088b838e..5f50b003a 100644 --- a/namespaces.c +++ b/namespaces.c @@ -297,15 +297,17 @@ static int collect_one_nsfile(void *o, ProtobufCMessage *base) return file_desc_add(&nfi->d, nfi->nfe->id, &ns_desc_ops); } +struct collect_image_info nsfile_cinfo = { + .fd_type = CR_FD_NS_FILES, + .pb_type = PB_NS_FILES, + .priv_size = sizeof(struct ns_file_info), + .collect = collect_one_nsfile, + .flags = COLLECT_OPTIONAL, +}; + int collect_ns_files(void) { - int ret; - - ret = collect_image(CR_FD_NS_FILES, PB_NS_FILES, - sizeof(struct ns_file_info), collect_one_nsfile); - if (ret < 0 && errno == ENOENT) - ret = 0; - return ret; + return collect_image(&nsfile_cinfo); } int dump_task_ns_ids(struct pstree_item *item) diff --git a/pipes.c b/pipes.c index ecaa1ba32..8db276d02 100644 --- a/pipes.c +++ b/pipes.c @@ -389,12 +389,18 @@ static int collect_one_pipe(void *o, ProtobufCMessage *base) } +struct collect_image_info pipe_cinfo = { + .fd_type = CR_FD_PIPES, + .pb_type = PB_PIPES, + .priv_size = sizeof(struct pipe_info), + .collect = collect_one_pipe, +}; + int collect_pipes(void) { int ret; - ret = collect_image(CR_FD_PIPES, PB_PIPES, - sizeof(struct pipe_info), collect_one_pipe); + ret = collect_image(&pipe_cinfo); if (!ret) ret = collect_pipe_data(CR_FD_PIPES_DATA, pd_hash_pipes); diff --git a/protobuf.c b/protobuf.c index ba11e8581..ff7ddfc46 100644 --- a/protobuf.c +++ b/protobuf.c @@ -600,58 +600,58 @@ err: return ret; } -static int __collect_image(int fd_t, int obj_t, unsigned size, - int (*collect)(void *obj, ProtobufCMessage *msg), - void * (*alloc)(size_t size), - void (*free)(void *ptr)) +int collect_image(struct collect_image_info *cinfo) { int fd, ret; + void *(*o_alloc)(size_t size) = malloc; + void (*o_free)(void *ptr) = free; - fd = open_image(fd_t, O_RSTR); - if (fd < 0) - return -1; + pr_info("Collecting %d/%d (flags %x)\n", + cinfo->fd_type, cinfo->pb_type, cinfo->flags); + + fd = open_image(cinfo->fd_type, O_RSTR); + if (fd < 0) { + if ((cinfo->flags & COLLECT_OPTIONAL) && (errno == ENOENT)) + return 0; + else + return -1; + } + + if (cinfo->flags & COLLECT_SHARED) { + o_alloc = shmalloc; + o_free = shfree_last; + } while (1) { void *obj; ProtobufCMessage *msg; - if (size) { + if (cinfo->priv_size) { ret = -1; - obj = alloc(size); + obj = o_alloc(cinfo->priv_size); if (!obj) break; } else obj = NULL; - ret = pb_read_one_eof(fd, &msg, obj_t); + ret = pb_read_one_eof(fd, &msg, cinfo->pb_type); if (ret <= 0) { - free(obj); + o_free(obj); break; } - ret = collect(obj, msg); + ret = cinfo->collect(obj, msg); if (ret < 0) { - free(obj); - cr_pb_descs[obj_t].free(msg, NULL); + o_free(obj); + cr_pb_descs[cinfo->pb_type].free(msg, NULL); break; } - if (!size) - cr_pb_descs[obj_t].free(msg, NULL); + if (!cinfo->priv_size) + cr_pb_descs[cinfo->pb_type].free(msg, NULL); } close(fd); + pr_debug(" `- ... done\n"); return ret; } - -int collect_image(int fd_t, int obj_t, unsigned size, - int (*collect)(void *obj, ProtobufCMessage *msg)) -{ - return __collect_image(fd_t, obj_t, size, collect, malloc, free); -} - -int collect_image_sh(int fd_t, int obj_t, unsigned size, - int (*collect)(void *obj, ProtobufCMessage *msg)) -{ - return __collect_image(fd_t, obj_t, size, collect, shmalloc, shfree_last); -} diff --git a/signalfd.c b/signalfd.c index 1b92d05c4..fc515022d 100644 --- a/signalfd.c +++ b/signalfd.c @@ -120,13 +120,15 @@ static int collect_one_sigfd(void *o, ProtobufCMessage *msg) return file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops); } +struct collect_image_info signalfd_cinfo = { + .fd_type = CR_FD_SIGNALFD, + .pb_type = PB_SIGNALFD, + .priv_size = sizeof(struct signalfd_info), + .collect = collect_one_sigfd, + .flags = COLLECT_OPTIONAL, +}; + int collect_signalfd(void) { - int ret = collect_image(CR_FD_SIGNALFD, PB_SIGNALFD, - sizeof(struct signalfd_info), collect_one_sigfd); - - if (ret < 0 && errno == ENOENT) - return 0; - - return ret; + return collect_image(&signalfd_cinfo); } diff --git a/sk-inet.c b/sk-inet.c index 40c7a7f2c..328405ad5 100644 --- a/sk-inet.c +++ b/sk-inet.c @@ -401,10 +401,16 @@ static int collect_one_inetsk(void *o, ProtobufCMessage *base) return file_desc_add(&ii->d, ii->ie->id, &inet_desc_ops); } +struct collect_image_info inet_sk_cinfo = { + .fd_type = CR_FD_INETSK, + .pb_type = PB_INETSK, + .priv_size = sizeof(struct inet_sk_info), + .collect = collect_one_inetsk, +}; + int collect_inet_sockets(void) { - return collect_image(CR_FD_INETSK, PB_INETSK, - sizeof(struct inet_sk_info), collect_one_inetsk); + return collect_image(&inet_sk_cinfo); } static int inet_validate_address(InetSkEntry *ie) diff --git a/sk-netlink.c b/sk-netlink.c index c6f6f0bdf..c1175561e 100644 --- a/sk-netlink.c +++ b/sk-netlink.c @@ -234,13 +234,15 @@ static int collect_one_netlink_sk(void *o, ProtobufCMessage *base) return file_desc_add(&si->d, si->nse->id, &netlink_sock_desc_ops); } +struct collect_image_info netlink_sk_cinfo = { + .fd_type = CR_FD_NETLINKSK, + .pb_type = PB_NETLINKSK, + .priv_size = sizeof(struct netlink_sock_info), + .collect = collect_one_netlink_sk, + .flags = COLLECT_OPTIONAL, +}; + int collect_netlink_sockets(void) { - int ret = collect_image(CR_FD_NETLINKSK, PB_NETLINKSK, - sizeof(struct netlink_sock_info), collect_one_netlink_sk); - - if (ret < 0 && errno == ENOENT) - return 0; - - return ret; + return collect_image(&netlink_sk_cinfo); } diff --git a/sk-packet.c b/sk-packet.c index 702e02ab1..37faf1d6b 100644 --- a/sk-packet.c +++ b/sk-packet.c @@ -499,13 +499,15 @@ static int collect_one_packet_sk(void *o, ProtobufCMessage *base) return file_desc_add(&si->d, si->pse->id, &packet_sock_desc_ops); } +struct collect_image_info packet_sk_cinfo = { + .fd_type = CR_FD_PACKETSK, + .pb_type = PB_PACKETSK, + .priv_size = sizeof(struct packet_sock_info), + .collect = collect_one_packet_sk, + .flags = COLLECT_OPTIONAL, +}; + int collect_packet_sockets(void) { - int ret = collect_image(CR_FD_PACKETSK, PB_PACKETSK, - sizeof(struct packet_sock_info), collect_one_packet_sk); - - if (ret < 0 && errno == ENOENT) - return 0; - - return ret; + return collect_image(&packet_sk_cinfo); } diff --git a/sk-unix.c b/sk-unix.c index 6c2a292a8..dd03f81dc 100644 --- a/sk-unix.c +++ b/sk-unix.c @@ -826,14 +826,21 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base) return file_desc_add(&ui->d, ui->ue->id, &unix_desc_ops); } +struct collect_image_info unix_sk_cinfo = { + .fd_type = CR_FD_UNIXSK, + .pb_type = PB_UNIXSK, + .priv_size = sizeof(struct unix_sk_info), + .collect = collect_one_unixsk, + .flags = COLLECT_SHARED, +}; + int collect_unix_sockets(void) { int ret; pr_info("Reading unix sockets in\n"); - ret = collect_image_sh(CR_FD_UNIXSK, PB_UNIXSK, - sizeof(struct unix_sk_info), collect_one_unixsk); + ret = collect_image(&unix_sk_cinfo); if (!ret) ret = read_sk_queues(); diff --git a/tty.c b/tty.c index 09c97995b..bc188b4f2 100644 --- a/tty.c +++ b/tty.c @@ -938,6 +938,14 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg) return 0; } +struct collect_image_info tty_info_cinfo = { + .fd_type = CR_FD_TTY_INFO, + .pb_type = PB_TTY_INFO, + .priv_size = sizeof(struct tty_info_entry), + .collect = collect_one_tty_info_entry, + .flags = COLLECT_OPTIONAL, +}; + static int collect_one_tty(void *obj, ProtobufCMessage *msg) { struct tty_info *info = obj; @@ -975,19 +983,21 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg) return file_desc_add(&info->d, info->tfe->id, &tty_desc_ops); } +struct collect_image_info tty_cinfo = { + .fd_type = CR_FD_TTY, + .pb_type = PB_TTY, + .priv_size = sizeof(struct tty_info), + .collect = collect_one_tty, + .flags = COLLECT_OPTIONAL, +}; + int collect_tty(void) { int ret; - ret = collect_image(CR_FD_TTY_INFO, PB_TTY_INFO, - sizeof(struct tty_info_entry), - collect_one_tty_info_entry); - if (ret && errno == ENOENT) - return 0; + ret = collect_image(&tty_info_cinfo); if (!ret) - ret = collect_image(CR_FD_TTY, PB_TTY, - sizeof(struct tty_info), - collect_one_tty); + ret = collect_image(&tty_cinfo); if (!ret) ret = tty_verify_active_pairs();