mirror of
https://github.com/troglobit/finit.git
synced 2026-10-14 10:19:36 +00:00
Support for custom halt:signal, default SIGTERM
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
decdc1560a
commit
1192506d43
6 files changed
+117
-7
No files matched your search
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() */
|
||||
|
||||
Reference in new issue
Block a user