Commit b9144570 authored by Pavel Emelyanov's avatar Pavel Emelyanov

img: Introduce generic routine for collecting image entries

On restore we typically read an image and put the entries into
some hash/list/whatever to work on them later. It's handy to have
a generic routine for doing so.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 00a1a4d4
...@@ -120,34 +120,19 @@ static struct file_desc_ops eventfd_desc_ops = { ...@@ -120,34 +120,19 @@ static struct file_desc_ops eventfd_desc_ops = {
.open = eventfd_open, .open = eventfd_open,
}; };
int collect_eventfd(void) static int collect_one_efd(void *obj, ProtobufCMessage *msg)
{ {
struct eventfd_file_info *info = NULL; struct eventfd_file_info *info = obj;
int ret, image_fd;
image_fd = open_image_ro(CR_FD_EVENTFD);
if (image_fd < 0)
return -1;
while (1) {
ret = -1;
info = xmalloc(sizeof(*info)); info->efe = pb_msg(msg, EventfdFileEntry);
if (!info) file_desc_add(&info->d, info->efe->id, &eventfd_desc_ops);
break; pr_info_eventfd("Collected ", info->efe);
ret = pb_read_one_eof(image_fd, &info->efe, PB_EVENTFD); return 0;
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);
}
err: int collect_eventfd(void)
xfree(info ? info->efe : NULL); {
xfree(info); return collect_image(CR_FD_EVENTFD, PB_EVENTFD,
close(image_fd); sizeof(struct eventfd_file_info), collect_one_efd);
return ret;
} }
...@@ -148,59 +148,39 @@ static struct file_desc_ops desc_ops = { ...@@ -148,59 +148,39 @@ static struct file_desc_ops desc_ops = {
.open = eventpoll_open, .open = eventpoll_open,
}; };
int collect_eventpoll(void) static int collect_one_epoll_tfd(void *o, ProtobufCMessage *msg)
{ {
int image_fd; struct eventpoll_tfd_file_info *info = o;
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;
info = xmalloc(sizeof(*info)); info->tdefe = pb_msg(msg, EventpollTfdEntry);
if (!info) list_add(&info->list, &eventpoll_tfds);
goto err; pr_info_eventpoll_tfd("Collected ", info->tdefe);
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);
}
close_safe(&image_fd); return 0;
}
image_fd = open_image_ro(CR_FD_EVENTPOLL); static int collect_one_epoll(void *o, ProtobufCMessage *msg)
if (image_fd < 0) {
return -1; struct eventpoll_file_info *info = o;
while (1) { info->efe = pb_msg(msg, EventpollFileEntry);
struct eventpoll_file_info *info; file_desc_add(&info->d, info->efe->id, &desc_ops);
pr_info_eventpoll("Collected ", info->efe);
ret = -1; return 0;
info = xmalloc(sizeof(*info)); }
if (!info)
goto err;
ret = pb_read_one_eof(image_fd, &info->efe, PB_EVENTPOLL); int collect_eventpoll(void)
if (ret < 0) {
goto err; int ret;
else if (!ret)
break;
pr_info_eventpoll("Collected ", info->efe); ret = collect_image(CR_FD_EVENTPOLL_TFD, PB_EVENTPOLL_TFD,
file_desc_add(&info->d, info->efe->id, &desc_ops); 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; return ret;
} }
...@@ -123,44 +123,40 @@ static struct file_desc_ops fifo_desc_ops = { ...@@ -123,44 +123,40 @@ static struct file_desc_ops fifo_desc_ops = {
.open = open_fifo_fd, .open = open_fifo_fd,
}; };
int collect_fifo(void) static int collect_one_fifo(void *o, ProtobufCMessage *base)
{ {
struct fifo_info *info = NULL, *f; struct fifo_info *info = o, *f;
int img, ret;
img = open_image_ro(CR_FD_FIFO); info->fe = pb_msg(base, FifoEntry);
if (img < 0) pr_info("Collected fifo entry ID %#x PIPE ID %#x\n",
return -1; info->fe->id, info->fe->pipe_id);
while (1) { file_desc_add(&info->d, info->fe->id, &fifo_desc_ops);
ret = -1;
info = xzalloc(sizeof(*info));
if (!info)
break;
ret = pb_read_one_eof(img, &info->fe, PB_FIFO); /* check who will restore the fifo data */
if (ret <= 0) list_for_each_entry(f, &fifo_head, list)
if (f->fe->pipe_id == info->fe->pipe_id)
break; break;
pr_info("Collected fifo entry ID %#x PIPE ID %#x\n", if (&f->list == &fifo_head) {
info->fe->id, info->fe->pipe_id); list_add(&info->list, &fifo_head);
info->restore_data = true;
file_desc_add(&info->d, info->fe->id, &fifo_desc_ops); } else {
INIT_LIST_HEAD(&info->list);
info->restore_data = false;
}
/* check who will restore the fifo data */ return 0;
list_for_each_entry(f, &fifo_head, list) }
if (f->fe->pipe_id == info->fe->pipe_id)
break;
if (&f->list == &fifo_head) { int collect_fifo(void)
list_add(&info->list, &fifo_head); {
info->restore_data = true; int ret;
}
}
xfree(info ? info->fe : NULL); ret = collect_image(CR_FD_FIFO, PB_FIFO,
xfree(info); sizeof(struct fifo_info), collect_one_fifo);
close(img); 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;
} }
...@@ -427,44 +427,28 @@ static struct file_desc_ops reg_desc_ops = { ...@@ -427,44 +427,28 @@ static struct file_desc_ops reg_desc_ops = {
.open = open_fe_fd, .open = open_fe_fd,
}; };
int collect_reg_files(void) static int collect_one_regfile(void *o, ProtobufCMessage *base)
{ {
struct reg_file_info *rfi = NULL; struct reg_file_info *rfi = o;
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;
rfi->rfe = rfe; rfi->rfe = pb_msg(base, RegFileEntry);
rfi->path = rfe->name; 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, &reg_desc_ops);
pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id); return 0;
file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops); }
}
if (rfi) { int collect_reg_files(void)
xfree(rfi->path); {
xfree(rfi); 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;
} }
...@@ -72,6 +72,9 @@ extern int pb_write_one(int fd, void *obj, int type); ...@@ -72,6 +72,9 @@ extern int pb_write_one(int fd, void *obj, int type);
#define pb_repeated_size(__obj, __member) \ #define pb_repeated_size(__obj, __member) \
(sizeof(*(__obj)->__member) * (__obj)->n_ ##__member) (sizeof(*(__obj)->__member) * (__obj)->n_ ##__member)
#define pb_msg(__base, __type) \
container_of(__base, __type, base)
#include <google/protobuf-c/protobuf-c.h> #include <google/protobuf-c/protobuf-c.h>
extern void do_pb_show_plain(int fd, int type, int single_entry, 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, ...@@ -87,4 +90,6 @@ extern void do_pb_show_plain(int fd, int type, int single_entry,
#define pb_show_vertical(__fd, __type) \ #define pb_show_vertical(__fd, __type) \
do_pb_show_plain(__fd, __type, 1, NULL, 0) 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__ */ #endif /* PROTOBUF_H__ */
...@@ -210,66 +210,40 @@ static int collect_mark(struct inotify_wd_info *mark) ...@@ -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; return -1;
} }
int collect_inotify(void) static int collect_one_ify(void *o, ProtobufCMessage *msg)
{ {
struct inotify_file_info *info; struct inotify_file_info *info = o;
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);
}
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; return 0;
}
image_fd = open_image_ro(CR_FD_INOTIFY_WD);
if (image_fd < 0)
goto err;
while (1) { static int collect_one_wd(void *o, ProtobufCMessage *msg)
ret = -1; {
mark = xmalloc(sizeof(*mark)); struct inotify_wd_info *mark = o;
if (!mark)
goto err;
ret = pb_read_one_eof(image_fd, &mark->iwe, PB_INOTIFY_WD); mark->iwe = pb_msg(msg, InotifyWdEntry);
if (ret < 0) return collect_mark(mark);
goto err; }
else if (!ret)
break;
if (collect_mark(mark)) { int collect_inotify(void)
ret = -1; {
pr_err("Can't find inotify with id 0x%08x\n", mark->iwe->id); int ret;
goto err;
}
}
ret = 0; ret = collect_image(CR_FD_INOTIFY, PB_INOTIFY,
err: sizeof(struct inotify_file_info), collect_one_ify);
close_safe(&image_fd); if (!ret)
ret = collect_image(CR_FD_INOTIFY_WD, PB_INOTIFY_WD,
sizeof(struct inotify_wd_info), collect_one_wd);
return ret; return ret;
} }
...@@ -308,48 +308,42 @@ static struct file_desc_ops pipe_desc_ops = { ...@@ -308,48 +308,42 @@ static struct file_desc_ops pipe_desc_ops = {
.want_transport = want_transport, .want_transport = want_transport,
}; };
int collect_pipes(void) static int collect_one_pipe(void *o, ProtobufCMessage *base)
{ {
struct pipe_info *pi = NULL, *tmp; struct pipe_info *pi = o, *tmp;
int fd, ret = -1;
fd = open_image_ro(CR_FD_PIPES); pi->pe = pb_msg(base, PipeEntry);
if (fd < 0)
return -1;
while (1) { pi->create = 0;
ret = -1; pr_info("Collected pipe entry ID %#x PIPE ID %#x\n",
pi = xmalloc(sizeof(*pi)); pi->pe->id, pi->pe->pipe_id);
if (pi == NULL)
break;
pi->create = 0;
ret = pb_read_one_eof(fd, &pi->pe, PB_PIPES);
if (ret <= 0)
break;
pr_info("Collected pipe entry ID %#x PIPE ID %#x\n", file_desc_add(&pi->d, pi->pe->id, &pipe_desc_ops);
pi->pe->id, pi->pe->pipe_id);
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 (&tmp->list == &pipes)
if (pi->pe->pipe_id == tmp->pe->pipe_id) INIT_LIST_HEAD(&pi->pipe_list);
break; else
list_add(&pi->pipe_list, &tmp->pipe_list);
if (&tmp->list == &pipes) list_add_tail(&pi->list, &pipes);
INIT_LIST_HEAD(&pi->pipe_list);
else
list_add(&pi->pipe_list, &tmp->pipe_list);
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) int dump_one_pipe_data(struct pipe_data_dump *pd, int lfd, const struct fd_parms *p)
......
...@@ -471,3 +471,42 @@ err: ...@@ -471,3 +471,42 @@ err:
xfree(buf); xfree(buf);
return ret; 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;
}
...@@ -118,30 +118,18 @@ static struct file_desc_ops signalfd_desc_ops = { ...@@ -118,30 +118,18 @@ static struct file_desc_ops signalfd_desc_ops = {
.open = signalfd_open, .open = signalfd_open,
}; };
int collect_signalfd(void) static int collect_one_sigfd(void *o, ProtobufCMessage *msg)
{ {
struct signalfd_info *info = NULL; struct signalfd_info *info = o;
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;
ret = pb_read_one_eof(image_fd, &info->sfe, PB_SIGNALFD); info->sfe = pb_msg(msg, SignalfdEntry);
if (ret <= 0) file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops);
break;
file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops); return 0;
} }
xfree(info ? info->sfe : NULL); int collect_signalfd(void)
xfree(info); {
close(image_fd); return collect_image(CR_FD_SIGNALFD, PB_SIGNALFD,
return ret; sizeof(struct signalfd_info), collect_one_sigfd);
} }
...@@ -293,36 +293,22 @@ static struct file_desc_ops inet_desc_ops = { ...@@ -293,36 +293,22 @@ static struct file_desc_ops inet_desc_ops = {
.open = open_inet_sk, .open = open_inet_sk,
}; };
int collect_inet_sockets(void) static int collect_one_inetsk(void *o, ProtobufCMessage *base)
{ {
struct inet_sk_info *ii = NULL; struct inet_sk_info *ii = o;
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;
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)) return 0;
tcp_locked_conn_add(ii); }
}
if (ii)
xfree(ii);
close(fd); int collect_inet_sockets(void)
return ret; {
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) static int open_inet_sk(struct file_desc *d)
......
...@@ -719,62 +719,51 @@ static struct file_desc_ops unix_desc_ops = { ...@@ -719,62 +719,51 @@ static struct file_desc_ops unix_desc_ops = {
.want_transport = unixsk_should_open_transport, .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; struct unix_sk_info *ui = o;
int fd, ret;
pr_info("Reading unix sockets in\n"); ui->ue = pb_msg(base, UnixSkEntry);
fd = open_image_ro(CR_FD_UNIXSK); if (ui->ue->name.len) {
if (fd < 0) { if (ui->ue->name.len >= UNIX_PATH_MAX) {
if (errno == ENOENT) pr_err("Bad unix name len %d\n", (int)ui->ue->name.len);
return 0;
else
return -1; 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) { ui->name = (void *)ui->ue->name.data;
ret = -1;
if (ui->ue->name.len >= UNIX_PATH_MAX) { /*
pr_err("Bad unix name len %d\n", (int)ui->ue->name.len); * Make FS clean from sockets we're about to
break; * 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;
}
/* int collect_unix_sockets(void)
* Make FS clean from sockets we're about to {
* restore. See for how we bind them for details int ret;
*/
if (ui->name[0] != '\0' &&
!(ui->ue->uflags & USK_EXTERN))
unlink(ui->name);
} else
ui->name = NULL;
ui->peer = NULL; pr_info("Reading unix sockets in\n");
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);
}
xfree(ui); ret = collect_image(CR_FD_UNIXSK, PB_UNIXSK,
close(fd); 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) int resolve_unix_peers(void)
......
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