Branch data Line data Source code
1 : : #include <unistd.h>
2 : : #include <signal.h>
3 : : #include <sys/signalfd.h>
4 : :
5 : : #include "compiler.h"
6 : : #include "asm/types.h"
7 : : #include "signalfd.h"
8 : : #include "proc_parse.h"
9 : : #include "fdset.h"
10 : : #include "image.h"
11 : : #include "util.h"
12 : : #include "log.h"
13 : : #include "files.h"
14 : :
15 : : #include "protobuf.h"
16 : : #include "protobuf/signalfd.pb-c.h"
17 : :
18 : : struct signalfd_info {
19 : : SignalfdEntry *sfe;
20 : : struct file_desc d;
21 : : };
22 : :
23 : 4 : int is_signalfd_link(char *link)
24 : : {
25 : 4 : return is_anon_link_type(link, "[signalfd]");
26 : : }
27 : :
28 : : struct signalfd_dump_arg {
29 : : u32 id;
30 : : const struct fd_parms *p;
31 : : bool dumped;
32 : : };
33 : :
34 : 4 : static int dump_signalfd_entry(union fdinfo_entries *e, void *arg)
35 : : {
36 : : struct signalfd_dump_arg *da = arg;
37 : :
38 [ - + ]: 4 : if (da->dumped) {
39 : 0 : pr_err("Several counters in a file?\n");
40 : 0 : return -1;
41 : : }
42 : :
43 : 4 : da->dumped = true;
44 : 4 : e->sfd.id = da->id;
45 : 4 : e->sfd.flags = da->p->flags;
46 : 4 : e->sfd.fown = (FownEntry *)&da->p->fown;
47 : :
48 : 4 : return pb_write_one(fdset_fd(glob_fdset, CR_FD_SIGNALFD),
49 : 4 : &e->sfd, PB_SIGNALFD);
50 : : }
51 : :
52 : 4 : static int dump_one_signalfd(int lfd, u32 id, const struct fd_parms *p)
53 : : {
54 : 4 : struct signalfd_dump_arg da = { .id = id, .p = p, };
55 : 4 : return parse_fdinfo(lfd, FD_TYPES__SIGNALFD, dump_signalfd_entry, &da);
56 : : }
57 : :
58 : : const struct fdtype_ops signalfd_dump_ops = {
59 : : .type = FD_TYPES__SIGNALFD,
60 : : .dump = dump_one_signalfd,
61 : : };
62 : :
63 : 2 : static void sigset_fill(sigset_t *to, unsigned long long from)
64 : : {
65 : : int sig;
66 : :
67 : 2 : pr_info("\tCalculating sigmask for %Lx\n", from);
68 : 2 : sigemptyset(to);
69 [ + + ]: 130 : for (sig = 1; sig < NSIG; sig++)
70 [ + + ]: 128 : if (from & (1ULL << (sig - 1))) {
71 : 2 : pr_debug("\t\tAdd %d signal to mask\n", sig);
72 : 2 : sigaddset(to, sig);
73 : : }
74 : 2 : }
75 : :
76 : 2 : static int signalfd_open(struct file_desc *d)
77 : : {
78 : : struct signalfd_info *info;
79 : : int tmp;
80 : : sigset_t mask;
81 : :
82 : : info = container_of(d, struct signalfd_info, d);
83 : 2 : pr_info("Restoring signalfd %#x\n", info->sfe->id);
84 : :
85 : 2 : sigset_fill(&mask, info->sfe->sigmask);
86 : 2 : tmp = signalfd(-1, &mask, 0);
87 [ - + ]: 2 : if (tmp < 0) {
88 : 0 : pr_perror("Can't create signalfd %#08x", info->sfe->id);
89 : 0 : return -1;
90 : : }
91 : :
92 [ - + ]: 2 : if (rst_file_params(tmp, info->sfe->fown, info->sfe->flags)) {
93 : 0 : pr_perror("Can't restore params on signalfd %#08x",
94 : : info->sfe->id);
95 : : goto err_close;
96 : : }
97 : :
98 : : return tmp;
99 : :
100 : : err_close:
101 : 0 : close(tmp);
102 : 0 : return -1;
103 : : }
104 : :
105 : : static struct file_desc_ops signalfd_desc_ops = {
106 : : .type = FD_TYPES__SIGNALFD,
107 : : .open = signalfd_open,
108 : : };
109 : :
110 : 2 : static int collect_one_sigfd(void *o, ProtobufCMessage *msg)
111 : : {
112 : : struct signalfd_info *info = o;
113 : :
114 : 2 : info->sfe = pb_msg(msg, SignalfdEntry);
115 : 2 : return file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops);
116 : : }
117 : :
118 : : struct collect_image_info signalfd_cinfo = {
119 : : .fd_type = CR_FD_SIGNALFD,
120 : : .pb_type = PB_SIGNALFD,
121 : : .priv_size = sizeof(struct signalfd_info),
122 : : .collect = collect_one_sigfd,
123 : : .flags = COLLECT_OPTIONAL,
124 : : };
|