diff --git a/eventfd.c b/eventfd.c index 02e26403..e1b68390 100644 --- a/eventfd.c +++ b/eventfd.c @@ -120,34 +120,19 @@ static struct file_desc_ops eventfd_desc_ops = { .open = eventfd_open, }; -int collect_eventfd(void) +static int collect_one_efd(void *obj, ProtobufCMessage *msg) { - struct eventfd_file_info *info = NULL; - int ret, image_fd; - - image_fd = open_image_ro(CR_FD_EVENTFD); - if (image_fd < 0) - return -1; - - while (1) { - ret = -1; + struct eventfd_file_info *info = obj; - info = xmalloc(sizeof(*info)); - if (!info) - break; + info->efe = pb_msg(msg, EventfdFileEntry); + file_desc_add(&info->d, info->efe->id, &eventfd_desc_ops); + pr_info_eventfd("Collected ", info->efe); - ret = pb_read_one_eof(image_fd, &info->efe, PB_EVENTFD); - if (ret < 0) - goto err; - else if (!ret) - break; - pr_info_eventfd("Collected ", info->efe); - file_desc_add(&info->d, info->efe->id, &eventfd_desc_ops); - } + return 0; +} -err: - xfree(info ? info->efe : NULL); - xfree(info); - close(image_fd); - return ret; +int collect_eventfd(void) +{ + return collect_image(CR_FD_EVENTFD, PB_EVENTFD, + sizeof(struct eventfd_file_info), collect_one_efd); } diff --git a/eventpoll.c b/eventpoll.c index 6c16a8a6..b0367f41 100644 --- a/eventpoll.c +++ b/eventpoll.c @@ -148,59 +148,39 @@ static struct file_desc_ops desc_ops = { .open = eventpoll_open, }; -int collect_eventpoll(void) +static int collect_one_epoll_tfd(void *o, ProtobufCMessage *msg) { - int image_fd; - int ret = -1; - - image_fd = open_image_ro(CR_FD_EVENTPOLL_TFD); - if (image_fd < 0) - return -1; - - while (1) { - struct eventpoll_tfd_file_info *info; + struct eventpoll_tfd_file_info *info = o; - info = xmalloc(sizeof(*info)); - if (!info) - goto err; - - ret = pb_read_one_eof(image_fd, &info->tdefe, PB_EVENTPOLL_TFD); - if (ret < 0) - goto err; - else if (!ret) - break; - - INIT_LIST_HEAD(&info->list); - - list_add(&info->list, &eventpoll_tfds); - pr_info_eventpoll_tfd("Collected ", info->tdefe); - } + info->tdefe = pb_msg(msg, EventpollTfdEntry); + list_add(&info->list, &eventpoll_tfds); + pr_info_eventpoll_tfd("Collected ", info->tdefe); - close_safe(&image_fd); + return 0; +} - image_fd = open_image_ro(CR_FD_EVENTPOLL); - if (image_fd < 0) - return -1; +static int collect_one_epoll(void *o, ProtobufCMessage *msg) +{ + struct eventpoll_file_info *info = o; - while (1) { - struct eventpoll_file_info *info; + info->efe = pb_msg(msg, EventpollFileEntry); + file_desc_add(&info->d, info->efe->id, &desc_ops); + pr_info_eventpoll("Collected ", info->efe); - ret = -1; - info = xmalloc(sizeof(*info)); - if (!info) - goto err; + return 0; +} - ret = pb_read_one_eof(image_fd, &info->efe, PB_EVENTPOLL); - if (ret < 0) - goto err; - else if (!ret) - break; +int collect_eventpoll(void) +{ + int ret; - pr_info_eventpoll("Collected ", info->efe); - file_desc_add(&info->d, info->efe->id, &desc_ops); - } + ret = collect_image(CR_FD_EVENTPOLL_TFD, PB_EVENTPOLL_TFD, + sizeof(struct eventpoll_tfd_file_info), + collect_one_epoll_tfd); + if (!ret) + ret = collect_image(CR_FD_EVENTPOLL, PB_EVENTPOLL, + sizeof(struct eventpoll_file_info), + collect_one_epoll); -err: - close_safe(&image_fd); return ret; } diff --git a/fifo.c b/fifo.c index 00d8f0d1..2de58b9e 100644 --- a/fifo.c +++ b/fifo.c @@ -123,44 +123,40 @@ static struct file_desc_ops fifo_desc_ops = { .open = open_fifo_fd, }; -int collect_fifo(void) +static int collect_one_fifo(void *o, ProtobufCMessage *base) { - struct fifo_info *info = NULL, *f; - int img, ret; + struct fifo_info *info = o, *f; - img = open_image_ro(CR_FD_FIFO); - if (img < 0) - return -1; + info->fe = pb_msg(base, FifoEntry); + pr_info("Collected fifo entry ID %#x PIPE ID %#x\n", + info->fe->id, info->fe->pipe_id); - while (1) { - ret = -1; - info = xzalloc(sizeof(*info)); - if (!info) - break; + file_desc_add(&info->d, info->fe->id, &fifo_desc_ops); - ret = pb_read_one_eof(img, &info->fe, PB_FIFO); - if (ret <= 0) + /* check who will restore the fifo data */ + list_for_each_entry(f, &fifo_head, list) + if (f->fe->pipe_id == info->fe->pipe_id) break; - pr_info("Collected fifo entry ID %#x PIPE ID %#x\n", - info->fe->id, info->fe->pipe_id); - - file_desc_add(&info->d, info->fe->id, &fifo_desc_ops); + if (&f->list == &fifo_head) { + list_add(&info->list, &fifo_head); + info->restore_data = true; + } else { + INIT_LIST_HEAD(&info->list); + info->restore_data = false; + } - /* check who will restore the fifo data */ - list_for_each_entry(f, &fifo_head, list) - if (f->fe->pipe_id == info->fe->pipe_id) - break; + return 0; +} - if (&f->list == &fifo_head) { - list_add(&info->list, &fifo_head); - info->restore_data = true; - } - } +int collect_fifo(void) +{ + int ret; - xfree(info ? info->fe : NULL); - xfree(info); - close(img); + ret = collect_image(CR_FD_FIFO, PB_FIFO, + sizeof(struct fifo_info), collect_one_fifo); + if (!ret) + ret = collect_pipe_data(CR_FD_FIFO_DATA, pd_hash_fifo); - return collect_pipe_data(CR_FD_FIFO_DATA, pd_hash_fifo); + return ret; } diff --git a/files-reg.c b/files-reg.c index 444935cd..49f5c09c 100644 --- a/files-reg.c +++ b/files-reg.c @@ -427,44 +427,28 @@ static struct file_desc_ops reg_desc_ops = { .open = open_fe_fd, }; -int collect_reg_files(void) +static int collect_one_regfile(void *o, ProtobufCMessage *base) { - struct reg_file_info *rfi = NULL; - int fd, ret = -1; - - fd = open_image_ro(CR_FD_REG_FILES); - if (fd < 0) - return -1; - - while (1) { - RegFileEntry *rfe; - - rfi = xmalloc(sizeof(*rfi)); - ret = -1; - if (rfi == NULL) - break; - - rfi->path = NULL; - - ret = pb_read_one_eof(fd, &rfe, PB_REG_FILES); - if (ret <= 0) - break; + struct reg_file_info *rfi = o; - rfi->rfe = rfe; - rfi->path = rfe->name; + rfi->rfe = pb_msg(base, RegFileEntry); + rfi->path = rfi->rfe->name; + rfi->remap_path = NULL; - rfi->remap_path = NULL; + pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id); + file_desc_add(&rfi->d, rfi->rfe->id, ®_desc_ops); - pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id); - file_desc_add(&rfi->d, rfi->rfe->id, ®_desc_ops); - } + return 0; +} - if (rfi) { - xfree(rfi->path); - xfree(rfi); - } +int collect_reg_files(void) +{ + int ret; - close(fd); + ret = collect_image(CR_FD_REG_FILES, PB_REG_FILES, + sizeof(struct reg_file_info), collect_one_regfile); + if (!ret) + ret = collect_remaps(); - return collect_remaps(); + return ret; } diff --git a/include/protobuf.h b/include/protobuf.h index 7da1baa5..6120eedd 100644 --- a/include/protobuf.h +++ b/include/protobuf.h @@ -72,6 +72,9 @@ extern int pb_write_one(int fd, void *obj, int type); #define pb_repeated_size(__obj, __member) \ (sizeof(*(__obj)->__member) * (__obj)->n_ ##__member) +#define pb_msg(__base, __type) \ + container_of(__base, __type, base) + #include extern void do_pb_show_plain(int fd, int type, int single_entry, @@ -87,4 +90,6 @@ 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, 0) +int collect_image(int fd_t, int obj_t, unsigned size, + int (*collect)(void *obj, ProtobufCMessage *msg)); #endif /* PROTOBUF_H__ */ diff --git a/inotify.c b/inotify.c index b2096f41..c4bae6c0 100644 --- a/inotify.c +++ b/inotify.c @@ -210,66 +210,40 @@ static int collect_mark(struct inotify_wd_info *mark) } } + pr_err("Can't find inotify with id 0x%08x\n", mark->iwe->id); return -1; } -int collect_inotify(void) +static int collect_one_ify(void *o, ProtobufCMessage *msg) { - struct inotify_file_info *info; - struct inotify_wd_info *mark; - int image_fd = -1, ret = -1; - - image_fd = open_image_ro(CR_FD_INOTIFY); - if (image_fd < 0) - return -1; - - while (1) { - info = xmalloc(sizeof(*info)); - if (!info) - return -1; - - ret = pb_read_one_eof(image_fd, &info->ife, PB_INOTIFY); - if (ret < 0) - goto err; - else if (!ret) - break; - - INIT_LIST_HEAD(&info->marks); - list_add(&info->list, &info_head); - file_desc_add(&info->d, info->ife->id, &desc_ops); - pr_info("Collected inotify: id 0x%08x flags 0x%08x\n", info->ife->id, info->ife->flags); - } + struct inotify_file_info *info = o; - close_safe(&image_fd); + info->ife = pb_msg(msg, InotifyFileEntry); + INIT_LIST_HEAD(&info->marks); + list_add(&info->list, &info_head); + file_desc_add(&info->d, info->ife->id, &desc_ops); + pr_info("Collected inotify: id 0x%08x flags 0x%08x\n", info->ife->id, info->ife->flags); - ret = -1; - - image_fd = open_image_ro(CR_FD_INOTIFY_WD); - if (image_fd < 0) - goto err; + return 0; +} - while (1) { - ret = -1; - mark = xmalloc(sizeof(*mark)); - if (!mark) - goto err; +static int collect_one_wd(void *o, ProtobufCMessage *msg) +{ + struct inotify_wd_info *mark = o; - ret = pb_read_one_eof(image_fd, &mark->iwe, PB_INOTIFY_WD); - if (ret < 0) - goto err; - else if (!ret) - break; + mark->iwe = pb_msg(msg, InotifyWdEntry); + return collect_mark(mark); +} - if (collect_mark(mark)) { - ret = -1; - pr_err("Can't find inotify with id 0x%08x\n", mark->iwe->id); - goto err; - } - } +int collect_inotify(void) +{ + int ret; - ret = 0; -err: - close_safe(&image_fd); + ret = collect_image(CR_FD_INOTIFY, PB_INOTIFY, + sizeof(struct inotify_file_info), collect_one_ify); + if (!ret) + ret = collect_image(CR_FD_INOTIFY_WD, PB_INOTIFY_WD, + sizeof(struct inotify_wd_info), collect_one_wd); return ret; } diff --git a/pipes.c b/pipes.c index 5bdcfee4..dd2f118e 100644 --- a/pipes.c +++ b/pipes.c @@ -308,48 +308,42 @@ static struct file_desc_ops pipe_desc_ops = { .want_transport = want_transport, }; -int collect_pipes(void) +static int collect_one_pipe(void *o, ProtobufCMessage *base) { - struct pipe_info *pi = NULL, *tmp; - int fd, ret = -1; + struct pipe_info *pi = o, *tmp; - fd = open_image_ro(CR_FD_PIPES); - if (fd < 0) - return -1; + pi->pe = pb_msg(base, PipeEntry); - while (1) { - ret = -1; - pi = xmalloc(sizeof(*pi)); - if (pi == NULL) - break; - - pi->create = 0; - ret = pb_read_one_eof(fd, &pi->pe, PB_PIPES); - if (ret <= 0) - break; + pi->create = 0; + pr_info("Collected pipe entry ID %#x PIPE ID %#x\n", + pi->pe->id, pi->pe->pipe_id); - pr_info("Collected pipe entry ID %#x PIPE ID %#x\n", - pi->pe->id, pi->pe->pipe_id); + file_desc_add(&pi->d, pi->pe->id, &pipe_desc_ops); - file_desc_add(&pi->d, pi->pe->id, &pipe_desc_ops); + list_for_each_entry(tmp, &pipes, list) + if (pi->pe->pipe_id == tmp->pe->pipe_id) + break; - list_for_each_entry(tmp, &pipes, list) - if (pi->pe->pipe_id == tmp->pe->pipe_id) - break; + if (&tmp->list == &pipes) + INIT_LIST_HEAD(&pi->pipe_list); + else + list_add(&pi->pipe_list, &tmp->pipe_list); - if (&tmp->list == &pipes) - INIT_LIST_HEAD(&pi->pipe_list); - else - list_add(&pi->pipe_list, &tmp->pipe_list); + list_add_tail(&pi->list, &pipes); - list_add_tail(&pi->list, &pipes); - } + return 0; +} - xfree(pi); +int collect_pipes(void) +{ + int ret; - close(fd); + ret = collect_image(CR_FD_PIPES, PB_PIPES, + sizeof(struct pipe_info), collect_one_pipe); + if (!ret) + ret = collect_pipe_data(CR_FD_PIPES_DATA, pd_hash_pipes); - return collect_pipe_data(CR_FD_PIPES_DATA, pd_hash_pipes); + return ret; } int dump_one_pipe_data(struct pipe_data_dump *pd, int lfd, const struct fd_parms *p) diff --git a/protobuf.c b/protobuf.c index 5708b18e..023f2283 100644 --- a/protobuf.c +++ b/protobuf.c @@ -471,3 +471,42 @@ int pb_write_one(int fd, void *obj, int type) xfree(buf); return ret; } + +int collect_image(int fd_t, int obj_t, unsigned size, + int (*collect)(void *obj, ProtobufCMessage *msg)) +{ + int fd, ret; + + fd = open_image_ro(fd_t); + if (fd < 0) + return -1; + + while (1) { + void *obj; + ProtobufCMessage *msg; + + if (size) { + ret = -1; + obj = xmalloc(size); + if (!obj) + break; + } else + obj = NULL; + + ret = pb_read_one_eof(fd, &msg, obj_t); + if (ret <= 0) { + xfree(obj); + break; + } + + ret = collect(obj, msg); + if (ret < 0) { + xfree(obj); + cr_pb_descs[obj_t].free(msg, NULL); + break; + } + } + + close(fd); + return ret; +} diff --git a/signalfd.c b/signalfd.c index 011da881..e3b4d56b 100644 --- a/signalfd.c +++ b/signalfd.c @@ -118,30 +118,18 @@ static struct file_desc_ops signalfd_desc_ops = { .open = signalfd_open, }; -int collect_signalfd(void) +static int collect_one_sigfd(void *o, ProtobufCMessage *msg) { - struct signalfd_info *info = NULL; - int ret, image_fd; - - image_fd = open_image_ro(CR_FD_SIGNALFD); - if (image_fd < 0) - return -1; - - while (1) { - ret = -1; - info = xmalloc(sizeof(*info)); - if (!info) - break; + struct signalfd_info *info = o; - ret = pb_read_one_eof(image_fd, &info->sfe, PB_SIGNALFD); - if (ret <= 0) - break; + info->sfe = pb_msg(msg, SignalfdEntry); + file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops); - file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops); - } + return 0; +} - xfree(info ? info->sfe : NULL); - xfree(info); - close(image_fd); - return ret; +int collect_signalfd(void) +{ + return collect_image(CR_FD_SIGNALFD, PB_SIGNALFD, + sizeof(struct signalfd_info), collect_one_sigfd); } diff --git a/sk-inet.c b/sk-inet.c index 9a005bf3..8ff9fdfb 100644 --- a/sk-inet.c +++ b/sk-inet.c @@ -293,36 +293,22 @@ static struct file_desc_ops inet_desc_ops = { .open = open_inet_sk, }; -int collect_inet_sockets(void) +static int collect_one_inetsk(void *o, ProtobufCMessage *base) { - struct inet_sk_info *ii = NULL; - int fd, ret = -1; - - fd = open_image_ro(CR_FD_INETSK); - if (fd < 0) - return -1; - - while (1) { - ii = xmalloc(sizeof(*ii)); - ret = -1; - if (!ii) - break; - - ret = pb_read_one_eof(fd, &ii->ie, PB_INETSK); - if (ret <= 0) - break; + struct inet_sk_info *ii = o; - file_desc_add(&ii->d, ii->ie->id, &inet_desc_ops); + ii->ie = pb_msg(base, InetSkEntry); + file_desc_add(&ii->d, ii->ie->id, &inet_desc_ops); + if (tcp_connection(ii->ie)) + tcp_locked_conn_add(ii); - if (tcp_connection(ii->ie)) - tcp_locked_conn_add(ii); - } - - if (ii) - xfree(ii); + return 0; +} - close(fd); - return ret; +int collect_inet_sockets(void) +{ + return collect_image(CR_FD_INETSK, PB_INETSK, + sizeof(struct inet_sk_info), collect_one_inetsk); } static int open_inet_sk(struct file_desc *d) diff --git a/sk-unix.c b/sk-unix.c index 188dac7f..386f9c21 100644 --- a/sk-unix.c +++ b/sk-unix.c @@ -719,62 +719,51 @@ static struct file_desc_ops unix_desc_ops = { .want_transport = unixsk_should_open_transport, }; -int collect_unix_sockets(void) +static int collect_one_unixsk(void *o, ProtobufCMessage *base) { - struct unix_sk_info *ui = NULL; - int fd, ret; + struct unix_sk_info *ui = o; - pr_info("Reading unix sockets in\n"); + ui->ue = pb_msg(base, UnixSkEntry); - fd = open_image_ro(CR_FD_UNIXSK); - if (fd < 0) { - if (errno == ENOENT) - return 0; - else + if (ui->ue->name.len) { + if (ui->ue->name.len >= UNIX_PATH_MAX) { + pr_err("Bad unix name len %d\n", (int)ui->ue->name.len); return -1; - } - - while (1) { - ret = -1; - ui = xmalloc(sizeof(*ui)); - if (ui == NULL) - break; - - ret = pb_read_one_eof(fd, &ui->ue, PB_UNIXSK); - if (ret <= 0) - break; + } - if (ui->ue->name.len) { - ret = -1; + ui->name = (void *)ui->ue->name.data; - if (ui->ue->name.len >= UNIX_PATH_MAX) { - pr_err("Bad unix name len %d\n", (int)ui->ue->name.len); - break; - } + /* + * Make FS clean from sockets we're about to + * restore. See for how we bind them for details + */ + if (ui->name[0] != '\0' && + !(ui->ue->uflags & USK_EXTERN)) + unlink(ui->name); + } else + ui->name = NULL; + + ui->peer = NULL; + ui->flags = 0; + pr_info(" `- Got 0x%x peer 0x%x\n", ui->ue->ino, ui->ue->peer); + file_desc_add(&ui->d, ui->ue->id, &unix_desc_ops); + list_add_tail(&ui->list, &unix_sockets); - ui->name = (void *)ui->ue->name.data; + return 0; +} - /* - * Make FS clean from sockets we're about to - * restore. See for how we bind them for details - */ - if (ui->name[0] != '\0' && - !(ui->ue->uflags & USK_EXTERN)) - unlink(ui->name); - } else - ui->name = NULL; +int collect_unix_sockets(void) +{ + int ret; - ui->peer = NULL; - ui->flags = 0; - pr_info(" `- Got 0x%x peer 0x%x\n", ui->ue->ino, ui->ue->peer); - file_desc_add(&ui->d, ui->ue->id, &unix_desc_ops); - list_add_tail(&ui->list, &unix_sockets); - } + pr_info("Reading unix sockets in\n"); - xfree(ui); - close(fd); + ret = collect_image(CR_FD_UNIXSK, PB_UNIXSK, + sizeof(struct unix_sk_info), collect_one_unixsk); + if (!ret) + ret = read_sk_queues(); - return read_sk_queues(); + return 0; } int resolve_unix_peers(void)