mirror of
https://github.com/troglobit/finit.git
synced 2026-11-10 16:31:21 +00:00
Fix #282: add support for oncrash:script to call post:script action
This patch adds the oncrash:script option to call the post:script action, if defined, for a crashing service. The EXIT_CODE variable sent to the script is set to `crashed`. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
278994781b
commit
5dd1a676ac
4 files changed
+41
-10
No files matched your search
+2
-1
@@ -549,7 +549,8 @@ configurable with the following options:
|
|||||||
was originally designed for so not the default behavior
|
was originally designed for so not the default behavior
|
||||||
* `oncrash:reboot` -- when all retries have failed, and the service
|
* `oncrash:reboot` -- when all retries have failed, and the service
|
||||||
has *crashed*, if this option is set the system is rebooted.
|
has *crashed*, if this option is set the system is rebooted.
|
||||||
Note, future releases may include other `oncrash:` actions
|
* `oncrash:script` -- similarly, but instead of rebooting, call the
|
||||||
|
`post:script` action if set, see below.
|
||||||
|
|
||||||
When stopping a service (run/task/sysv/service), either manually or
|
When stopping a service (run/task/sysv/service), either manually or
|
||||||
when moving to another runlevel, Finit starts by sending `SIGTERM`, to
|
when moving to another runlevel, Finit starts by sending `SIGTERM`, to
|
||||||
|
|||||||
+20
-7
@@ -366,10 +366,21 @@ was originally designed for so not the default behavior.
|
|||||||
when all retries have failed, and the service
|
when all retries have failed, and the service
|
||||||
has
|
has
|
||||||
.Em crashed ,
|
.Em crashed ,
|
||||||
if this option is set the system is rebooted. Note, future releases
|
if this option is set the system is rebooted.
|
||||||
may include other
|
.It Cm oncrash:script
|
||||||
.Cm oncrash:
|
Similar to
|
||||||
actions.
|
.Cm oncrash:reboot ,
|
||||||
|
but instead of rebooting this action calls the
|
||||||
|
.Cm post:script
|
||||||
|
(see below) to let the operator decide the best course of action. If
|
||||||
|
the post:script option is not set, this is a no-op.
|
||||||
|
.Pp
|
||||||
|
The post:script is called with the same environment variables
|
||||||
|
.Sy except
|
||||||
|
for the
|
||||||
|
.Cm EXIT_CODE
|
||||||
|
variable which is set to
|
||||||
|
.Cm "crashed" .
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
When stopping a service (run/task/sysv/service), either manually or when
|
When stopping a service (run/task/sysv/service), either manually or when
|
||||||
@@ -412,11 +423,13 @@ or any unique identifier specified in the .conf file. The
|
|||||||
.Cm post:script
|
.Cm post:script
|
||||||
is called with an additional set of environment variables:
|
is called with an additional set of environment variables:
|
||||||
.Bl -tag -offset indent -width 1n
|
.Bl -tag -offset indent -width 1n
|
||||||
.It Cm EXIT_CODE=[exited,signal]
|
.It Cm EXIT_CODE=[exited,signal,crashed]
|
||||||
set to one of
|
set to one of
|
||||||
.Cm exited
|
.Cm exited ,
|
||||||
|
.Cm signal ,
|
||||||
or
|
or
|
||||||
.Cm signal
|
.Cm crashed
|
||||||
|
(see above).
|
||||||
.It Cm EXIT_STATUS=[num,SIGNAME]
|
.It Cm EXIT_STATUS=[num,SIGNAME]
|
||||||
set to one of exit status code from the program, if it exited normally,
|
set to one of exit status code from the program, if it exited normally,
|
||||||
or the signal name (HUP, TERM, etc.) if it exited due to signal
|
or the signal name (HUP, TERM, etc.) if it exited due to signal
|
||||||
|
|||||||
+16
-1
@@ -1403,6 +1403,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
else if (MATCH_CMD(cmd, "oncrash:", arg)) {
|
else if (MATCH_CMD(cmd, "oncrash:", arg)) {
|
||||||
if (MATCH_CMD(arg, "reboot", arg))
|
if (MATCH_CMD(arg, "reboot", arg))
|
||||||
oncrash_action = SVC_ONCRASH_REBOOT;
|
oncrash_action = SVC_ONCRASH_REBOOT;
|
||||||
|
if (MATCH_CMD(arg, "script", arg))
|
||||||
|
oncrash_action = SVC_ONCRASH_SCRIPT;
|
||||||
}
|
}
|
||||||
else if (MATCH_CMD(cmd, "respawn", arg))
|
else if (MATCH_CMD(cmd, "respawn", arg))
|
||||||
respawn = 1;
|
respawn = 1;
|
||||||
@@ -1868,6 +1870,9 @@ static void service_post_script(svc_t *svc)
|
|||||||
setenv("EXIT_STATUS", sig2str(sig), 1);
|
setenv("EXIT_STATUS", sig2str(sig), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (svc_is_crashing(svc))
|
||||||
|
setenv("EXIT_CODE", "crashed", 1);
|
||||||
|
|
||||||
execvp(_PATH_BSHELL, argv);
|
execvp(_PATH_BSHELL, argv);
|
||||||
_exit(EX_OSERR);
|
_exit(EX_OSERR);
|
||||||
}
|
}
|
||||||
@@ -1945,10 +1950,20 @@ static void service_retry(svc_t *svc)
|
|||||||
svc_ident(svc, NULL, 0));
|
svc_ident(svc, NULL, 0));
|
||||||
svc_crashing(svc);
|
svc_crashing(svc);
|
||||||
*restart_cnt = 0;
|
*restart_cnt = 0;
|
||||||
if (svc->oncrash_action == SVC_ONCRASH_REBOOT) {
|
switch (svc->oncrash_action) {
|
||||||
|
case SVC_ONCRASH_REBOOT:
|
||||||
logit(LOG_ERR, "%s issuing reboot", svc_ident(svc, NULL, 0));
|
logit(LOG_ERR, "%s issuing reboot", svc_ident(svc, NULL, 0));
|
||||||
sync();
|
sync();
|
||||||
kill(1, SIGTERM);
|
kill(1, SIGTERM);
|
||||||
|
break;
|
||||||
|
case SVC_ONCRASH_SCRIPT:
|
||||||
|
if (svc_has_post(svc)) {
|
||||||
|
dbg("calling post:script %s, crashing.", svc->post_script);
|
||||||
|
service_post_script(svc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SVC_ONCRASH_IGNORE = 0,
|
SVC_ONCRASH_IGNORE = 0,
|
||||||
SVC_ONCRASH_REBOOT = 1,
|
SVC_ONCRASH_REBOOT,
|
||||||
|
SVC_ONCRASH_SCRIPT,
|
||||||
} svc_oncrash_action_t;
|
} svc_oncrash_action_t;
|
||||||
|
|
||||||
#define MAX_ID_LEN 16
|
#define MAX_ID_LEN 16
|
||||||
@@ -260,6 +261,7 @@ static inline int svc_is_updated (svc_t *svc) { return svc && 1 == svc->dirty
|
|||||||
static inline int svc_is_blocked (svc_t *svc) { return svc && svc->block != SVC_BLOCK_NONE; }
|
static inline int svc_is_blocked (svc_t *svc) { return svc && svc->block != SVC_BLOCK_NONE; }
|
||||||
static inline int svc_is_busy (svc_t *svc) { return svc && svc->block == SVC_BLOCK_BUSY; }
|
static inline int svc_is_busy (svc_t *svc) { return svc && svc->block == SVC_BLOCK_BUSY; }
|
||||||
static inline int svc_is_missing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_MISSING; }
|
static inline int svc_is_missing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_MISSING; }
|
||||||
|
static inline int svc_is_crashing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_CRASHING; }
|
||||||
|
|
||||||
static inline void svc_unblock (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_NONE; }
|
static inline void svc_unblock (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_NONE; }
|
||||||
#define svc_start(svc) svc_unblock(svc)
|
#define svc_start(svc) svc_unblock(svc)
|
||||||
|
|||||||
Reference in new issue
Block a user