2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 01:51:51 +00:00
criu/eventfd.c
Pavel Emelyanov 9fc1d6bbeb fdinfo: Make fdinfo.type be an enum
This types specifies a strict set of what is hidden behind
the fd. Thus these numbers should be in the description of
the fdinfo message.

Plus protobuf makes shure nothing else will be there.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2012-07-19 10:18:37 +04:00

154 lines
3.0 KiB
C

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/eventfd.h>
#include "compiler.h"
#include "types.h"
#include "eventfd.h"
#include "proc_parse.h"
#include "crtools.h"
#include "image.h"
#include "util.h"
#include "log.h"
#include "protobuf.h"
#include "protobuf/eventfd.pb-c.h"
struct eventfd_file_info {
EventfdFileEntry *efe;
struct file_desc d;
};
/* Checks if file desciptor @lfd is eventfd */
int is_eventfd_link(int lfd)
{
return is_anon_link_type(lfd, "[eventfd]");
}
static void pr_info_eventfd(char *action, EventfdFileEntry *efe)
{
pr_info("%seventfd: id %#08x flags %#04x counter %#016lx\n",
action, efe->id, efe->flags, efe->counter);
}
void show_eventfds(int fd, struct cr_options *o)
{
pb_show_plain(fd, eventfd_file_entry);
}
struct eventfd_dump_arg {
u32 id;
const struct fd_parms *p;
bool dumped;
};
static int dump_eventfd_entry(union fdinfo_entries *e, void *arg)
{
struct eventfd_dump_arg *da = arg;
if (da->dumped) {
pr_err("Several counters in a file?\n");
return -1;
}
da->dumped = true;
e->efd.id = da->id;
e->efd.flags = da->p->flags;
e->efd.fown = (FownEntry *)&da->p->fown;
pr_info_eventfd("Dumping ", &e->efd);
return pb_write(fdset_fd(glob_fdset, CR_FD_EVENTFD),
&e->efd, eventfd_file_entry);
}
static int dump_one_eventfd(int lfd, u32 id, const struct fd_parms *p)
{
struct eventfd_dump_arg da = { .id = id, .p = p, };
return parse_fdinfo(lfd, FD_TYPES__EVENTFD, dump_eventfd_entry, &da);
}
static const struct fdtype_ops eventfd_ops = {
.type = FD_TYPES__EVENTFD,
.make_gen_id = make_gen_id,
.dump = dump_one_eventfd,
};
int dump_eventfd(struct fd_parms *p, int lfd, const struct cr_fdset *set)
{
return do_dump_gen_file(p, lfd, &eventfd_ops, set);
}
static int eventfd_open(struct file_desc *d)
{
struct eventfd_file_info *info;
int tmp;
info = container_of(d, struct eventfd_file_info, d);
tmp = eventfd(info->efe->counter, 0);
if (tmp < 0) {
pr_perror("Can't create eventfd %#08x",
info->efe->id);
return -1;
}
if (rst_file_params(tmp, info->efe->fown, info->efe->flags)) {
pr_perror("Can't restore params on eventfd %#08x",
info->efe->id);
goto err_close;
}
return tmp;
err_close:
close(tmp);
return -1;
}
static struct file_desc_ops eventfd_desc_ops = {
.type = FD_TYPES__EVENTFD,
.open = eventfd_open,
};
int collect_eventfd(void)
{
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;
info = xmalloc(sizeof(*info));
if (!info)
break;
ret = pb_read_eof(image_fd, &info->efe, eventfd_file_entry);
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:
xfree(info ? info->efe : NULL);
xfree(info);
close(image_fd);
return ret;
}