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 "types.h"
7 : : #include "signalfd.h"
8 : : #include "proc_parse.h"
9 : : #include "crtools.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 : 2 : int is_signalfd_link(int lfd)
24 : : {
25 : 2 : return is_anon_link_type(lfd, "[signalfd]");
26 : : }
27 : :
28 : : struct signalfd_dump_arg {
29 : : u32 id;
30 : : const struct fd_parms *p;
31 : : bool dumped;
32 : : };
33 : :
34 : 0 : void show_signalfd(int fd, struct cr_options *o)
35 : : {
36 : 0 : pb_show_plain(fd, PB_SIGNALFD);
37 : 0 : }
38 : :
39 : 2 : static int dump_signalfd_entry(union fdinfo_entries *e, void *arg)
40 : : {
41 : 2 : struct signalfd_dump_arg *da = arg;
42 : :
43 [ - + ]: 2 : if (da->dumped) {
44 : 0 : pr_err("Several counters in a file?\n");
45 : 0 : return -1;
46 : : }
47 : :
48 : 2 : da->dumped = true;
49 : 2 : e->sfd.id = da->id;
50 : 2 : e->sfd.flags = da->p->flags;
51 : 2 : e->sfd.fown = (FownEntry *)&da->p->fown;
52 : :
53 : 2 : return pb_write_one(fdset_fd(glob_fdset, CR_FD_SIGNALFD),
54 : 2 : &e->sfd, PB_SIGNALFD);
55 : : }
56 : :
57 : 2 : static int dump_one_signalfd(int lfd, u32 id, const struct fd_parms *p)
58 : : {
59 : 2 : struct signalfd_dump_arg da = { .id = id, .p = p, };
60 : 2 : return parse_fdinfo(lfd, FD_TYPES__SIGNALFD, dump_signalfd_entry, &da);
61 : : }
62 : :
63 : : static const struct fdtype_ops signalfd_ops = {
64 : : .type = FD_TYPES__SIGNALFD,
65 : : .dump = dump_one_signalfd,
66 : : };
67 : :
68 : 2 : int dump_signalfd(struct fd_parms *p, int lfd, const struct cr_fdset *set)
69 : : {
70 : 2 : return do_dump_gen_file(p, lfd, &signalfd_ops, set);
71 : : }
72 : :
73 : 2 : static void sigset_fill(sigset_t *to, unsigned long long from)
74 : : {
75 : : int sig;
76 : :
77 : 2 : pr_info("\tCalculating sigmask for %Lx\n", from);
78 : 2 : sigemptyset(to);
79 [ + + ]: 130 : for (sig = 1; sig < NSIG; sig++)
80 [ + + ]: 128 : if (from & (1ULL << (sig - 1))) {
81 : 2 : pr_debug("\t\tAdd %d signal to mask\n", sig);
82 : 2 : sigaddset(to, sig);
83 : : }
84 : 2 : }
85 : :
86 : 2 : static int signalfd_open(struct file_desc *d)
87 : : {
88 : : struct signalfd_info *info;
89 : : int tmp;
90 : : sigset_t mask;
91 : :
92 : 2 : info = container_of(d, struct signalfd_info, d);
93 : 2 : pr_info("Restoring signalfd %#x\n", info->sfe->id);
94 : :
95 : 2 : sigset_fill(&mask, info->sfe->sigmask);
96 : 2 : tmp = signalfd(-1, &mask, 0);
97 [ - + ]: 2 : if (tmp < 0) {
98 : 0 : pr_perror("Can't create signalfd %#08x", info->sfe->id);
99 : : return -1;
100 : : }
101 : :
102 [ - + ]: 2 : if (rst_file_params(tmp, info->sfe->fown, info->sfe->flags)) {
103 : 0 : pr_perror("Can't restore params on signalfd %#08x",
104 : : info->sfe->id);
105 : : goto err_close;
106 : : }
107 : :
108 : : return tmp;
109 : :
110 : : err_close:
111 : 2 : close(tmp);
112 : : return -1;
113 : : }
114 : :
115 : : static struct file_desc_ops signalfd_desc_ops = {
116 : : .type = FD_TYPES__SIGNALFD,
117 : : .open = signalfd_open,
118 : : };
119 : :
120 : 3 : static int collect_one_sigfd(void *o, ProtobufCMessage *msg)
121 : : {
122 : 3 : struct signalfd_info *info = o;
123 : :
124 : 3 : info->sfe = pb_msg(msg, SignalfdEntry);
125 : 3 : file_desc_add(&info->d, info->sfe->id, &signalfd_desc_ops);
126 : :
127 : 3 : return 0;
128 : : }
129 : :
130 : 355 : int collect_signalfd(void)
131 : : {
132 : 355 : return collect_image(CR_FD_SIGNALFD, PB_SIGNALFD,
133 : : sizeof(struct signalfd_info), collect_one_sigfd);
134 : : }
|