Fix #274: allow manual:yes on sysv/service/run/task

Prior to this change only service stanzas respected the manual:yes
option, now it (should) work on any svc_t type.  Not tested on ttys.

The initctl tool has been given an extra manual=yes output for these
types of run/task/service entries, shown only when the manual option
is set.

Example:

root@anarchy:~# initctl status foo.sh
     Status : stopped (code=exited, status=0/SUCCESS, manual=yes)
   Identity : foo.sh                                ~~~~~~~~~~~~
Description : Hej foo
     Origin : /etc/finit.d/enabled/foo.conf
Environment :
Condition(s):
    Command : /root/foo.sh
   PID file : none
        PID : 0
       User : root
      Group : root
     Uptime : N/A
     Starts : 1
   Restarts : 0 (0/10)
  Runlevels : [--2345----]

Notice also the new `Starts : 1` which is a counter for the number of
starts in the current runlevel.  On runlevel change it is reset to 0.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2022-06-16 17:57:55 +02:00
parent 6de67ed107
commit 5f908cae49
3 changed files with 21 additions and 12 deletions
+12 -9
View File
@@ -692,16 +692,17 @@ static char *svc_environ(svc_t *svc, char *buf, size_t len)
return buf;
}
static char *exit_status(int status, char *buf, size_t len)
static char *exit_status(svc_t *svc, char *buf, size_t len)
{
int rc, sig;
rc = WEXITSTATUS(status);
sig = WTERMSIG(status);
rc = WEXITSTATUS(svc->status);
sig = WTERMSIG(svc->status);
if (WIFEXITED(status))
snprintf(buf, len, " (code=exited, status=%d%s)", rc, code2str(rc));
else if (WIFSIGNALED(status))
if (WIFEXITED(svc->status))
snprintf(buf, len, " (code=exited, status=%d%s%s)", rc, code2str(rc),
svc->manual ? ", manual=yes" : "");
else if (WIFSIGNALED(svc->status))
snprintf(buf, len, " (code=signal, status=%d%s)", sig, sig2str(sig));
return buf;
@@ -717,7 +718,7 @@ static char *status(svc_t *svc, int full)
s = svc_status(svc);
switch (svc->state) {
case SVC_HALTED_STATE:
exit_status(svc->status, ok, sizeof(ok));
exit_status(svc, ok, sizeof(ok));
color = "\e[1m";
break;
@@ -726,7 +727,7 @@ static char *status(svc_t *svc, int full)
break;
case SVC_DONE_STATE:
exit_status(svc->status, ok, sizeof(ok));
exit_status(svc, ok, sizeof(ok));
if (WIFEXITED(svc->status)) {
if (WEXITSTATUS(svc->status))
color = "\e[1;31m";
@@ -741,7 +742,7 @@ static char *status(svc_t *svc, int full)
break;
default:
exit_status(svc->status, ok, sizeof(ok));
exit_status(svc, ok, sizeof(ok));
color = "\e[1;33m";
break;
}
@@ -831,6 +832,8 @@ static int show_status(char *arg)
printf(" User : %s\n", svc->username);
printf(" Group : %s\n", svc->group);
printf(" Uptime : %s\n", svc->pid ? uptime(now - svc->start_time, uptm, sizeof(uptm)) : uptm);
if (svc->manual)
printf(" Starts : %d\n", svc->once);
printf(" Restarts : %d (%d/%d)\n", svc->restart_tot, svc->restart_cnt, svc->restart_max);
printf(" Runlevels : %s\n", runlevel_string(runlevel, svc->runlevels));
if (cgrp && svc->pid > 1) {
+7 -2
View File
@@ -1374,7 +1374,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
return errno = ENOMEM;
}
if (type == SVC_TYPE_SERVICE && manual)
if (manual)
svc_stop(svc);
} else {
_d("Found existing svc for %s name %s id %s type %d", cmd, name, id, type);
@@ -1463,6 +1463,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
parse_env(svc, env);
if (file)
strlcpy(svc->file, file, sizeof(svc->file));
svc->manual = manual;
svc->respawn = respawn;
svc->forking = forking;
svc->restart_max = restart_max;
@@ -1920,7 +1921,11 @@ restart:
case SVC_TYPE_TASK:
case SVC_TYPE_RUN:
svc_set_state(svc, SVC_DONE_STATE);
if (svc->manual) {
svc_stop(svc);
svc_set_state(svc, SVC_HALTED_STATE);
} else
svc_set_state(svc, SVC_DONE_STATE);
break;
default:
+2 -1
View File
@@ -121,7 +121,8 @@ typedef struct svc {
int status; /* From waitpid() when process is collected */
const svc_state_t state; /* Paused, Reloading, Restart, Running, ... */
svc_type_t type; /* Service, run, task, ... */
int protect; /* Services like dbus-daemon & udev by Finit */
char protect; /* Services like dbus-daemon & udev by Finit */
char manual; /* run/task that require `initctl start foo` */
const int dirty; /* 0: unmodified, 1: modified */
const int removed;
int starting; /* ... waiting for pidfile to be re-asserted */