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 = {
.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);
}
......@@ -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;
}
......@@ -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;
}
......@@ -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, &reg_desc_ops);
pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id);
file_desc_add(&rfi->d, rfi->rfe->id, &reg_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;
}
......@@ -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 <google/protobuf-c/protobuf-c.h>
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__ */
......@@ -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;
}
......@@ -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)
......
......@@ -471,3 +471,42 @@ err:
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;
}
......@@ -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);
}
......@@ -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)
......
......@@ -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)
......
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