summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2024-09-04 09:53:49 -0700
committerVito Caputo <vcaputo@pengaru.com>2024-09-04 09:53:49 -0700
commit497ecae46a8ee31122edad3984e1187ed9cc370c (patch)
tree2fe5807527386578896abf77e7468699c8370559
parent9992253bd3a56981ccc2c3992b2057348be99ae3 (diff)
vmon: trigger final snapshot on SIGTERM
When using vmon to monitor a system PID1 will kill it @ shutdown/reboot, and we should save one last snapshot of what's been captured before we exit in that case. SIGTERM is sent first before the SIGKILL killing spree, so let's handle the SIGTERM by writing the snapshot, then exiting the main loop. The service manager can then do something with the produced snapshots after we've exited, if they're considered interesting.
-rw-r--r--src/vmon.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/vmon.c b/src/vmon.c
index 576aebc..0631084 100644
--- a/src/vmon.c
+++ b/src/vmon.c
@@ -66,7 +66,7 @@ typedef struct vmon_t {
#define WIDTH_MIN 200
#define HEIGHT_MIN 28
-static volatile int got_sigchld, got_sigusr1, got_sigint, got_sigquit;
+static volatile int got_sigchld, got_sigusr1, got_sigint, got_sigquit, got_sigterm;
/* return if arg == flag or altflag if provided */
static int is_flag(const char *arg, const char *flag, const char *altflag)
@@ -193,8 +193,8 @@ static void print_help(void)
" -N --now-names Use current time in filenames instead of start time\n"
" -o --output-dir Directory to store saved output to (\".\" if unspecified)\n"
" -p --pid PID of the top-level process to monitor (1 if unspecified)\n"
- " -i --snapshots Save a PNG snapshot every N seconds (SIGUSR1 also snapshots)\n"
- " -s --snapshot Save a PNG snapshot upon receiving SIGCHLD\n"
+ " -i --snapshots Save a PNG snapshot every N seconds (SIG{TERM,USR1} also snapshots)\n"
+ " -s --snapshot Save a PNG snapshot upon receiving SIG{CHLD,TERM,USR1}\n"
" -w --wip-name Name to use for work-in-progress snapshot filename\n"
" -v --version Print version\n"
" -W --width Chart width\n"
@@ -223,25 +223,35 @@ static void print_copyright(void)
}
-/* collect status of child */
+/* collect status of child, triggering snapshot if snapshotting active */
static void handle_sigchld(int signum)
{
got_sigchld = 1;
}
+/* trigger a snapshot */
static void handle_sigusr1(int signum)
{
got_sigusr1 = 1;
}
+/* trigger a snapshot and exit immediately after it's been written */
+static void handle_sigterm(int signum)
+{
+ got_sigterm = 1;
+}
+
+
+/* propagates to child first time, quits second time */
static void handle_sigint(int signum)
{
got_sigint++;
}
+/* propagates to child first time, quits second time */
static void handle_sigquit(int signum)
{
got_sigquit++;
@@ -622,6 +632,11 @@ static vmon_t * vmon_startup(int argc, const char * const *argv)
goto _err_vcr;
}
+ if (signal(SIGTERM, handle_sigterm) == SIG_ERR) {
+ VWM_PERROR("unable to set SIGTERM handler");
+ goto _err_vcr;
+ }
+
if (vmon->snapshots_interval) {
int r;
@@ -855,6 +870,13 @@ int main(int argc, const char * const *argv)
got_sigquit++;
kill(vmon->pid, SIGQUIT);
+ } else if (got_sigterm) {
+ if (vmon->snapshot || vmon->snapshots_interval) {
+ /* simulate sigusr1 to trigger a final snapshot, */
+ got_sigusr1 = 1;
+ }
+
+ vmon->done = 1;
}
if (got_sigchld) {
© All Rights Reserved