Skip to content

Commit aadc753

Browse files
committed
pping: Reopen output file on SIGHUP
Make the user space process reopen the output file (if used with the -w/--write option) when it recieves a SIGHUP signal. This makes it possible to for example rotate the output files with logrotate. In case the program receives the SIGHUP signal is BEFORE the output file has been moved, the program will throw a warning and then continue writing to its current file handle until another SIGHUP signal is received. Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
1 parent 965d34f commit aadc753

File tree

1 file changed

+47
-9
lines changed

1 file changed

+47
-9
lines changed

pping/pping.c

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,6 @@ static int report_aggregated_rtt_map(struct output_context *out_ctx, int map_fd,
14511451
return err;
14521452
}
14531453

1454-
14551454
static int report_aggregated_rtts(struct output_context *out_ctx,
14561455
struct aggregation_maps *maps,
14571456
struct aggregation_config *agg_conf)
@@ -1710,6 +1709,26 @@ static int close_output(struct output_context *out_ctx)
17101709
return err;
17111710
}
17121711

1712+
/* Will try to reopen *out_ctx
1713+
* If it is able to open the new output it will return 0, replace *out_ctx with
1714+
* the new output and close the old output_context. If it fails at opening a
1715+
* new output_context it will return a negative error code and *out_ctx will
1716+
* remain unchanged */
1717+
static int reopen_output(struct output_context **out_ctx, const char *filename,
1718+
struct aggregation_config *agg_conf)
1719+
{
1720+
struct output_context *new_out;
1721+
1722+
new_out = open_output(filename, (*out_ctx)->format, agg_conf);
1723+
if (!new_out)
1724+
return -errno;
1725+
1726+
close_output(*out_ctx);
1727+
1728+
*out_ctx = new_out;
1729+
return 0;
1730+
}
1731+
17131732
static int init_signalfd(void)
17141733
{
17151734
sigset_t mask;
@@ -1718,6 +1737,7 @@ static int init_signalfd(void)
17181737
sigemptyset(&mask);
17191738
sigaddset(&mask, SIGINT);
17201739
sigaddset(&mask, SIGTERM);
1740+
sigaddset(&mask, SIGHUP);
17211741

17221742
fd = signalfd(-1, &mask, 0);
17231743
if (fd < 0)
@@ -1733,25 +1753,38 @@ static int init_signalfd(void)
17331753
return fd;
17341754
}
17351755

1736-
/* Returns PPING_ABORT to indicate the program should be halted or a negative
1737-
* error code */
1738-
static int handle_signalfd(int sigfd)
1756+
/* Returns 0 if signal was successfully handled, PPING_ABORT if signal
1757+
* indicates program should be halted or a negative error code on failure. */
1758+
static int handle_signalfd(int sigfd, struct output_context **out_ctx,
1759+
const char *filename,
1760+
struct aggregation_config *agg_conf)
17391761
{
17401762
struct signalfd_siginfo siginfo;
1741-
int ret;
1763+
int ret, err;
17421764

17431765
ret = read(sigfd, &siginfo, sizeof(siginfo));
17441766
if (ret != sizeof(siginfo)) {
17451767
fprintf(stderr, "Failed reading signalfd\n");
17461768
return -EBADFD;
17471769
}
17481770

1749-
if (siginfo.ssi_signo == SIGINT || siginfo.ssi_signo == SIGTERM) {
1771+
if (siginfo.ssi_signo == SIGHUP) {
1772+
if (filename) {
1773+
err = reopen_output(out_ctx, filename, agg_conf);
1774+
if (err)
1775+
fprintf(stderr,
1776+
"Warning: failed reopening %s: %s\n",
1777+
filename, get_libbpf_strerror(err));
1778+
} // If not writing to file, simply ignore the SIGHUP
1779+
} else if (siginfo.ssi_signo == SIGINT ||
1780+
siginfo.ssi_signo == SIGTERM) {
17501781
return PPING_ABORT;
17511782
} else {
17521783
fprintf(stderr, "Unexpected signal %d\n", siginfo.ssi_signo);
17531784
return -EBADMSG;
17541785
}
1786+
1787+
return 0;
17551788
}
17561789

17571790
static int init_perfbuffer(struct bpf_object *obj, struct pping_config *config,
@@ -2050,8 +2083,13 @@ static int epoll_poll_events(int epfd, struct pping_config *config,
20502083
&config->agg_conf);
20512084
break;
20522085
case PPING_EPEVENT_TYPE_SIGNAL:
2053-
err = handle_signalfd(events[i].data.u64 &
2054-
PPING_EPEVENT_MASK);
2086+
err = handle_signalfd(
2087+
events[i].data.u64 & PPING_EPEVENT_MASK,
2088+
&config->out_ctx,
2089+
config->write_to_file ? config->filename : NULL,
2090+
config->bpf_config.agg_rtts ?
2091+
&config->agg_conf :
2092+
NULL);
20552093
break;
20562094
case PPING_EPEVENT_TYPE_PIPE:
20572095
err = handle_pipefd(events[i].data.u64 &
@@ -2156,7 +2194,7 @@ int main(int argc, char *argv[])
21562194
return EXIT_FAILURE;
21572195
}
21582196

2159-
// Setup signalhandling (allow graceful shutdown on SIGINT/SIGTERM)
2197+
// Setup signalhandling (allow graceful shutdown on SIGINT/SIGTERM, reopen on SIGHUP)
21602198
sigfd = init_signalfd();
21612199
if (sigfd < 0) {
21622200
fprintf(stderr, "Failed creating signalfd: %s\n",

0 commit comments

Comments
 (0)