Skip to content

Commit

Permalink
signal: handle SIGUSR1 with signalfd
Browse files Browse the repository at this point in the history
we use internally SIGUSR1 as a hack to force the check of the
container processes.

commit d91cc43 changed the way some
signals are handled but forgot to handle SIGUSR1, so that receiving
SIGUSR1 would crash conmon.

Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2119072

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe authored and haircommander committed Aug 26, 2022
1 parent 19110c9 commit 1420874
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/conmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ int main(int argc, char *argv[])
.pid_to_handler = pid_to_handler,
.exit_status_cache = NULL,
};
int signal_fd = get_signal_descriptor(SIGCHLD);
int signal_fd = get_signal_descriptor();
if (signal_fd < 0)
pexit("Failed to create signalfd for SIGCHLD");
pexit("Failed to create signalfd");
int signal_fd_tag = g_unix_fd_add(signal_fd, G_IO_IN, on_signalfd_cb, &data);

if (opt_exit_command)
Expand Down
5 changes: 2 additions & 3 deletions src/ctr_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,8 @@ gboolean on_signalfd_cb(gint fd, G_GNUC_UNUSED GIOCondition condition, gpointer
{
struct pid_check_data *data = (struct pid_check_data *)user_data;

/* dequeue the signal from the signalfd */
int sig = dequeue_signal_event(fd);
g_assert_cmpint(sig, ==, SIGCHLD);
/* drop the signal from the signalfd */
drop_signal_event(fd);

check_child_processes(data->pid_to_handler, data->exit_status_cache);
return G_SOURCE_CONTINUE;
Expand Down
26 changes: 14 additions & 12 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ static bool retryable_error(int err)
}
#endif

static void get_signal_descriptor_mask(sigset_t *set)
{
sigemptyset(set);
sigaddset(set, SIGCHLD);
sigaddset(set, SIGUSR1);
sigprocmask(SIG_BLOCK, set, NULL);
}

ssize_t write_all(int fd, const void *buf, size_t count)
{
size_t remaining = count;
Expand Down Expand Up @@ -94,21 +102,18 @@ int set_pdeathsig(int sig)
return prctl(PR_SET_PDEATHSIG, sig);
}

int get_signal_descriptor(int sig)
int get_signal_descriptor()
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_BLOCK, &set, NULL);
get_signal_descriptor_mask(&set);
return signalfd(-1, &set, SFD_CLOEXEC);
}

int dequeue_signal_event(int fd)
void drop_signal_event(int fd)
{
struct signalfd_siginfo siginfo;
ssize_t s = read(fd, &siginfo, sizeof siginfo);
g_assert_cmpint(s, ==, sizeof siginfo);
return siginfo.ssi_signo;
}

#endif
Expand All @@ -129,12 +134,10 @@ int set_pdeathsig(int sig)
return procctl(P_PID, getpid(), PROC_PDEATHSIG_CTL, &sig);
}

int get_signal_descriptor(int sig)
int get_signal_descriptor()
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_BLOCK, &set, NULL);
get_signal_descriptor_mask(&set);

int kq = kqueue();
fcntl(kq, F_SETFD, FD_CLOEXEC);
Expand All @@ -146,14 +149,13 @@ int get_signal_descriptor(int sig)
return kq;
}

int dequeue_signal_event(int kq)
void drop_signal_event(int kq)
{
struct kevent kev;
int n = kevent(kq, NULL, 0, &kev, 1, NULL);
if (n != 1) {
pexit("failed to read signal event");
}
return kev.ident;
}

#endif
4 changes: 2 additions & 2 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ int set_subreaper(gboolean enabled);

int set_pdeathsig(int sig);

int get_signal_descriptor(int sig);
int dequeue_signal_event(int fd);
int get_signal_descriptor();
void drop_signal_event(int fd);

#endif /* !defined(UTILS_H) */

0 comments on commit 1420874

Please sign in to comment.