Support for custom halt:signal, default SIGTERM

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2020-02-26 18:28:02 +01:00
1 parent decdc1560a
commit 1192506d43
6 files changed
+117 -7

No files matched your search

+7
View File
@@ -231,6 +231,13 @@ Syntax
name:<service-name>
When stopping a service (run/task/sysv/service), either manually or
when moving to another runlevel, Finit starts by sending `SIGTERM`, to
allow the process to shut down gracefully. If the process has not
been collected within 3 seconds, Finit sends `SIGKILL`. To halt the
process using a different signal, use the option `halt:SIGNAL`, e.g.,
`halt:SIGPWR`.
* `inetd service/proto[@iflist] <wait|nowait> [LVLS] /path/to/daemon args`
Launch a daemon when a client initiates a connection on an Internet
port. Available services are listed in the UNIX `/etc/services` file.
+21 -6
View File
@@ -472,9 +472,10 @@ static int service_stop(svc_t *svc)
if (svc->pid <= 1)
return 1;
_d("Sending SIGTERM to pid:%d name:%s", svc->pid, pid_get_name(svc->pid, NULL, 0));
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s:%s, PID: %d, sending SIGTERM ...",
basename(svc->cmd), svc->id, svc->pid);
_d("Sending %s to pid:%d name:%s", sig_name(svc->sighalt),
svc->pid, pid_get_name(svc->pid, NULL, 0));
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s:%s, PID: %d, sending %s ...",
basename(svc->cmd), svc->id, svc->pid, sig_name(svc->sighalt));
} else {
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s stop' ...", svc->cmd);
}
@@ -488,7 +489,7 @@ static int service_stop(svc_t *svc)
if (svc->pid <= 1)
goto cleanup;
res = kill(svc->pid, SIGTERM);
res = kill(svc->pid, svc->sighalt);
/* PID lost or forking process never really started */
if (res == -1 && ESRCH == errno) {
@@ -644,6 +645,17 @@ static void parse_log(svc_t *svc, char *arg)
}
}
static void parse_sighalt(svc_t *svc, char *arg)
{
int signo;
signo = sig_num(arg);
if (signo == -1)
return;
svc->sighalt = signo;
}
/*
* name:<name>
*/
@@ -757,7 +769,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
char *username = NULL, *log = NULL, *pid = NULL;
char *service = NULL, *proto = NULL, *ifaces = NULL;
char *cmd, *desc, *runlevels = NULL, *cond = NULL;
char *name = NULL;
char *name = NULL, *halt = NULL;
svc_t *svc;
plugin_t *plugin = NULL;
@@ -819,6 +831,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
name = cmd;
else if (!strncasecmp(cmd, "manual:yes", 10))
manual = 1;
else if (!strncasecmp(cmd, "halt:", 5))
halt = &cmd[5];
else if (cmd[0] != '/' && strchr(cmd, '/'))
service = cmd; /* inetd service/proto */
else
@@ -945,7 +959,8 @@ recreate:
conf_parse_cond(svc, cond);
parse_name(svc, name);
if (halt)
parse_sighalt(svc, halt);
if (log)
parse_log(svc, log);
if (desc)
+81
View File
@@ -98,6 +98,55 @@ static uev_t sighup_watcher, sigint_watcher, sigpwr_watcher;
static uev_t sigchld_watcher;
static uev_t sigstop_watcher, sigtstp_watcher, sigcont_watcher;
static struct sigmap {
int num;
char *name;
} signames[] = {
/* ISO C99 signals. */
{ SIGINT, "SIGINT" },
{ SIGILL, "SIGILL" },
{ SIGABRT, "SIGABRT" },
{ SIGFPE, "SIGFPE" },
{ SIGSEGV, "SIGSEGV" },
{ SIGTERM, "SIGTERM" },
/* Historical signals specified by POSIX. */
{ SIGHUP, "SIGHUP" },
{ SIGQUIT, "SIGQUIT" },
{ SIGTRAP, "SIGTRAP" },
{ SIGKILL, "SIGKILL" },
{ SIGBUS, "SIGBUS" },
{ SIGSYS, "SIGSYS" },
{ SIGPIPE, "SIGPIPE" },
{ SIGALRM, "SIGALRM" },
/* New(er) POSIX signals (1003.1-2008, 1003.1-2013). */
{ SIGURG, "SIGURG" },
{ SIGSTOP, "SIGSTOP" },
{ SIGTSTP, "SIGTSTP" },
{ SIGCONT, "SIGCONT" },
{ SIGCHLD, "SIGCHLD" },
{ SIGTTIN, "SIGTTIN" },
{ SIGTTOU, "SIGTTOU" },
{ SIGPOLL, "SIGPOLL" },
{ SIGXCPU, "SIGXCPU" },
{ SIGXFSZ, "SIGXFSZ" },
{ SIGVTALRM, "SIGVTALRM" },
{ SIGPROF, "SIGPROF" },
{ SIGUSR1, "SIGUSR1" },
{ SIGUSR2, "SIGUSR2" },
/* Nonstandard signals found in all modern POSIX systems
(including both BSD and Linux). */
{ SIGWINCH, "SIGWINCH" },
{ SIGSTKFLT, "SIGSTKFLT" },
{ SIGPWR, "SIGPWR" },
/* Archaic names for compatibility. */
{ SIGIO, "SIGIO" },
{ SIGIOT, "SIGIOT" },
{ SIGCLD, "SIGCLD" },
};
void mdadm_wait(void);
void unmount_tmpfs(void);
void unmount_regular(void);
@@ -369,6 +418,38 @@ int sig_stopped(void)
return stopped;
}
/*
* Convert SIGFOO to a number, if it exists
*/
int sig_num(const char *name)
{
size_t i, offset = 0;
if (strncasecmp(name, "SIG", 3))
offset = 3;
for (i = 0; i < NELEMS(signames); i++) {
if (strcasecmp(name, &signames[i].name[offset]))
continue;
return signames[i].num;
}
return -1;
}
const char *sig_name(int signo)
{
size_t i;
for (i = 0; i < NELEMS(signames); i++) {
if (signames[i].num == signo)
return signames[i].name;
}
return "SIGUNKOWN";
}
/*
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
*/
+3
View File
@@ -70,10 +70,13 @@ extern shutop_t halt;
void do_shutdown (shutop_t op);
int sig_stopped (void);
int sig_num (const char *name);
void sig_init (void);
void sig_unblock (void);
void sig_setup (uev_ctx_t *ctx);
const char *sig_name(int signo);
#endif /* FINIT_SIG_H_ */
/**
+3
View File
@@ -104,6 +104,9 @@ svc_t *svc_new(char *cmd, char *id, int type)
/* Default description, if missing */
strlcpy(svc->desc, svc->name, sizeof(svc->desc));
/* Default HALT signal to send */
svc->sighalt = SIGTERM;
TAILQ_INSERT_TAIL(&svc_list, svc, link);
return svc;
+2 -1
View File
@@ -75,7 +75,7 @@ typedef enum {
#define MAX_NUM_FDS 64 /* Max number of I/O plugins */
#define MAX_NUM_SVC_ARGS 32
/* Time after SIGTERM that we SIGKILL stopping processes */
/* Time after SIGTERM (svc->sighalt) that we SIGKILL stopping processes */
#define SVC_TERM_TIMEOUT 3000
/*
@@ -95,6 +95,7 @@ typedef struct svc {
struct rlimit rlimit[RLIMIT_NLIMITS];
/* Service details */
int sighalt; /* Signal to stop prorcess, default: SIGTERM */
pid_t pid;
char pidfile[256];
long start_time; /* Start time, as seconds since boot, from sysinfo() */