Commit da409cc6 authored by Pavel Emelyanov's avatar Pavel Emelyanov

signalfd: Dumping and restoring

Only the fact of the fd presence, its flags and fown and the sigmask.
The sigpending state is tightly coupled with the task's sigpending
state which is not yet supported.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 8097a8dc
......@@ -59,6 +59,7 @@ OBJS += eventfd.o
OBJS += eventpoll.o
OBJS += mount.o
OBJS += inotify.o
OBJS += signalfd.o
OBJS += pstree.o
OBJS += protobuf.o
......
......@@ -44,6 +44,7 @@
#include "eventfd.h"
#include "eventpoll.h"
#include "inotify.h"
#include "signalfd.h"
#include "pstree.h"
#include "mount.h"
......@@ -291,6 +292,8 @@ static int dump_one_file(pid_t pid, int fd, int lfd, char fd_flags,
return dump_eventpoll(&p, lfd, cr_fdset);
else if (is_inotify_link(lfd))
return dump_inotify(&p, lfd, cr_fdset);
else if (is_signalfd_link(lfd))
return dump_signalfd(&p, lfd, cr_fdset);
else
return dump_unsupp_fd(&p);
}
......
......@@ -40,6 +40,7 @@
#include "sk-inet.h"
#include "eventfd.h"
#include "eventpoll.h"
#include "signalfd.h"
#include "proc_parse.h"
#include "restorer-blob.h"
#include "crtools.h"
......@@ -107,6 +108,9 @@ static int prepare_shared(void)
if (collect_eventpoll())
return -1;
if (collect_signalfd())
return -1;
if (collect_inotify())
return -1;
......
......@@ -3,6 +3,7 @@
#include "crtools.h"
#include "image.h"
#include "eventpoll.h"
#include "signalfd.h"
#include "inotify.h"
#include "sockets.h"
#include "uts_ns.h"
......@@ -92,6 +93,7 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
FD_ENTRY(EVENTFD, "eventfd", show_eventfds),
FD_ENTRY(EVENTPOLL, "eventpoll", show_eventpoll),
FD_ENTRY(EVENTPOLL_TFD, "eventpoll-tfd", show_eventpoll_tfd),
FD_ENTRY(SIGNALFD, "signalfd", show_signalfd),
FD_ENTRY(INOTIFY, "inotify", show_inotify),
FD_ENTRY(INOTIFY_WD, "inotify-wd", show_inotify_wd),
FD_ENTRY(CORE, "core-%d", show_core),
......
......@@ -69,6 +69,7 @@ enum {
CR_FD_EVENTFD,
CR_FD_EVENTPOLL,
CR_FD_EVENTPOLL_TFD,
CR_FD_SIGNALFD,
CR_FD_INOTIFY,
CR_FD_INOTIFY_WD,
_CR_FD_GLOB_TO,
......
......@@ -53,6 +53,7 @@
#define EVENTFD_MAGIC 0x44523722 /* Anapa */
#define EVENTPOLL_MAGIC 0x45023858 /* Krasnodar */
#define EVENTPOLL_TFD_MAGIC 0x44433746 /* Novorossiysk */
#define SIGNALFD_MAGIC 0x57323820 /* Uglich */
#define INOTIFY_MAGIC 0x48424431 /* Volgograd */
#define INOTIFY_WD_MAGIC 0x54562009 /* Svetlogorsk (Rauschen) */
#define MOUNTPOINTS_MAGIC 0x55563928 /* Petushki */
......
#ifndef __CR_SIGNALFD_H__
#define __CR_SIGNALFD_H__
struct cr_fdset;
struct fd_parms;
struct cr_options;
extern int is_signalfd_link(int lfd);
extern int dump_signalfd(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern void show_signalfd(int fd, struct cr_options *o);
extern int collect_signalfd(void);
#endif
#include <unistd.h>
#include <signal.h>
#include <sys/signalfd.h>
#include "compiler.h"
#include "types.h"
#include "signalfd.h"
#include "proc_parse.h"
#include "crtools.h"
#include "image.h"
#include "util.h"
#include "log.h"
#include "files.h"
#include "protobuf.h"
#include "protobuf/signalfd.pb-c.h"
struct signalfd_info {
SignalfdEntry *sfe;
struct file_desc d;
};
int is_signalfd_link(int lfd)
{
return is_anon_link_type(lfd, "[signalfd]");
}
struct signalfd_dump_arg {
u32 id;
const struct fd_parms *p;
bool dumped;
};
void show_signalfd(int fd, struct cr_options *o)
{
pb_show_plain(fd, signalfd_entry);
}
static int dump_signalfd_entry(union fdinfo_entries *e, void *arg)
{
struct signalfd_dump_arg *da = arg;
if (da->dumped) {
pr_err("Several counters in a file?\n");
return -1;
}
da->dumped = true;
e->sfd.id = da->id;
e->sfd.flags = da->p->flags;
e->sfd.fown = (FownEntry *)&da->p->fown;
return pb_write(fdset_fd(glob_fdset, CR_FD_SIGNALFD),
&e->sfd, signalfd_entry);
}
static int dump_one_signalfd(int lfd, u32 id, const struct fd_parms *p)
{
struct signalfd_dump_arg da = { .id = id, .p = p, };
return parse_fdinfo(lfd, FD_TYPES__SIGNALFD, dump_signalfd_entry, &da);
}
static const struct fdtype_ops signalfd_ops = {
.type = FD_TYPES__SIGNALFD,
.make_gen_id = make_gen_id,
.dump = dump_one_signalfd,
};
int dump_signalfd(struct fd_parms *p, int lfd, const struct cr_fdset *set)
{
return do_dump_gen_file(p, lfd, &signalfd_ops, set);
}
static void sigset_fill(sigset_t *to, unsigned long long from)
{
int sig;
pr_info("\tCalculating sigmask for %Lx\n", from);
sigemptyset(to);
for (sig = 1; sig < NSIG; sig++)
if (from & (1ULL << (sig - 1))) {
pr_debug("\t\tAdd %d signal to mask\n", sig);
sigaddset(to, sig);
}
}
static int signalfd_open(struct file_desc *d)
{
struct signalfd_info *info;
int tmp;
sigset_t mask;
info = container_of(d, struct signalfd_info, d);
pr_info("Restoring signalfd %#x\n", info->sfe->id);
sigset_fill(&mask, info->sfe->sigmask);
tmp = signalfd(-1, &mask, 0);
if (tmp < 0) {
pr_perror("Can't create signalfd %#08x", info->sfe->id);
return -1;
}
if (rst_file_params(tmp, info->sfe->fown, info->sfe->flags)) {
pr_perror("Can't restore params on signalfd %#08x",
info->sfe->id);
goto err_close;
}
return tmp;
err_close:
close(tmp);
return -1;
}
static struct file_desc_ops signalfd_desc_ops = {
.type = FD_TYPES__SIGNALFD,
.open = signalfd_open,
};
int collect_signalfd(void)
{
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;
ret = pb_read_eof(image_fd, &info->sfe, signalfd_entry);
if (ret <= 0)
break;
file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops);
}
xfree(info ? info->sfe : NULL);
xfree(info);
close(image_fd);
return ret;
}
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