mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4d3ec1a9f | ||
|
|
51befb492c | ||
|
|
7850378e15 | ||
|
|
438d6b4e63 | ||
|
|
712f68f9da |
+22
-2
@@ -4,8 +4,8 @@ Change Log
|
|||||||
All relevant changes are documented in this file.
|
All relevant changes are documented in this file.
|
||||||
|
|
||||||
|
|
||||||
[4.4][UNRELEASED]
|
[4.4][] - 2023-05-15
|
||||||
-----------------
|
--------------------
|
||||||
|
|
||||||
> **Note 1:** this release contains changes to the `.conf` parser. If you
|
> **Note 1:** this release contains changes to the `.conf` parser. If you
|
||||||
> have .conf file statements with comment character (`#`) in the command
|
> have .conf file statements with comment character (`#`) in the command
|
||||||
@@ -307,6 +307,23 @@ All relevant changes are documented in this file.
|
|||||||
reload, halt, poweroff, suspend. Also, prevent `SIGHUP` and `SIGUSR1`
|
reload, halt, poweroff, suspend. Also, prevent `SIGHUP` and `SIGUSR1`
|
||||||
signals when in shutdown or reboot
|
signals when in shutdown or reboot
|
||||||
* Fix #352: separate runlevel S from runlevel 0
|
* Fix #352: separate runlevel S from runlevel 0
|
||||||
|
* Fix #355: regression in v3.2 stopping a process and its group
|
||||||
|
|
||||||
|
In Finit v3.2 a regression was introduced that affects the way Finit
|
||||||
|
stops a supervised process and its process group.
|
||||||
|
|
||||||
|
Instead of sending SIGTERM to the process, and thus delegating the
|
||||||
|
responsibility to that process to inform any children it may have, as
|
||||||
|
of commit 91a9c83 Finit sends SIGTERM to the entire process group.
|
||||||
|
For SIGKILL this is fine, SIGKILL only runs as cleanup and as a last
|
||||||
|
ditch effort if the process doesn't respond to SIGTERM.
|
||||||
|
|
||||||
|
This regression, introduced in v3.2, directly affects services like
|
||||||
|
`avahi-autoipd` that have forked off children that it needs to tell to
|
||||||
|
exit cleanly before it returns. With the patch in question these
|
||||||
|
children are never allowed to complete, which in turn causes lingering
|
||||||
|
169.254 link-local addresses on interfaces.
|
||||||
|
|
||||||
* Fix bootmisc plugin: octal permission on `/run/lock` and `/var/lock`
|
* Fix bootmisc plugin: octal permission on `/run/lock` and `/var/lock`
|
||||||
|
|
||||||
* Ensure `initctl cond get` support the flux state (exit code 255)
|
* Ensure `initctl cond get` support the flux state (exit code 255)
|
||||||
@@ -340,6 +357,9 @@ All relevant changes are documented in this file.
|
|||||||
However, on `initctl reload` (and no change to .conf files) the arg
|
However, on `initctl reload` (and no change to .conf files) the arg
|
||||||
list was lost while parsing the .conf files. Leading to a false
|
list was lost while parsing the .conf files. Leading to a false
|
||||||
positive 'diff' in args causing nginx to be unnecessarily restarted.
|
positive 'diff' in args causing nginx to be unnecessarily restarted.
|
||||||
|
* Fix issue with disabled "linewrap" on the console TTY after login.
|
||||||
|
The root cause is `qemu-system-x86_64 -nographics` disabling it when
|
||||||
|
starting up. The correct `\e[?7h` escape code is now used.
|
||||||
|
|
||||||
|
|
||||||
[4.3][] - 2022-05-15
|
[4.3][] - 2022-05-15
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT([Finit],[4.4-rc2],[https://github.com/troglobit/finit/issues],[finit],[https://troglobit.com/projects/finit/])
|
AC_INIT([Finit],[4.4],[https://github.com/troglobit/finit/issues],[finit],[https://troglobit.com/projects/finit/])
|
||||||
AC_CONFIG_AUX_DIR(aux)
|
AC_CONFIG_AUX_DIR(aux)
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ static int stop(svc_t *svc, void *user_data)
|
|||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
svc_stop(svc);
|
svc_stop(svc);
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -77,6 +78,7 @@ static int start(svc_t *svc, void *user_data)
|
|||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
svc_start(svc);
|
svc_start(svc);
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,9 @@ char *console(void)
|
|||||||
|
|
||||||
void console_init(void)
|
void console_init(void)
|
||||||
{
|
{
|
||||||
|
/* Enable line wrap, if disabled previously, e.g., qemu */
|
||||||
|
dprint(STDOUT_FILENO, "\033[?7h", 5);
|
||||||
|
|
||||||
log_init();
|
log_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-13
@@ -173,7 +173,7 @@ static int service_script_del(pid_t pid)
|
|||||||
if (ptr->pid != pid)
|
if (ptr->pid != pid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dbg("Collected service %s script PID %d.", svc_ident(ptr->svc, NULL, 0), pid);
|
dbg("Collected service %s script PID %d, killing process group.", svc_ident(ptr->svc, NULL, 0), pid);
|
||||||
service_timeout_cancel(ptr->svc);
|
service_timeout_cancel(ptr->svc);
|
||||||
kill(-ptr->pid, SIGKILL);
|
kill(-ptr->pid, SIGKILL);
|
||||||
TAILQ_REMOVE(&svc_assoc_list, ptr, link);
|
TAILQ_REMOVE(&svc_assoc_list, ptr, link);
|
||||||
@@ -610,13 +610,6 @@ static int service_start(svc_t *svc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't start if it conflicts with something else already started */
|
|
||||||
if (svc_conflicts(svc)) {
|
|
||||||
logit(LOG_INFO, "Not starting %s, conflicts with %s",
|
|
||||||
svc_ident(svc, NULL, 0), svc->conflict);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
compose_cmdline(svc, cmdline, sizeof(cmdline));
|
compose_cmdline(svc, cmdline, sizeof(cmdline));
|
||||||
if (svc_is_sysv(svc))
|
if (svc_is_sysv(svc))
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", cmdline);
|
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", cmdline);
|
||||||
@@ -865,7 +858,7 @@ static void service_kill(svc_t *svc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg("%s: Sending SIGKILL to pid:%d", pid_get_name(svc->pid, NULL, 0), svc->pid);
|
dbg("%s: Sending SIGKILL to process group %d", pid_get_name(svc->pid, NULL, 0), svc->pid);
|
||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s[%d], sending SIGKILL ...",
|
logit(LOG_CONSOLE | LOG_NOTICE, "Stopping %s[%d], sending SIGKILL ...",
|
||||||
svc_ident(svc, NULL, 0), svc->pid);
|
svc_ident(svc, NULL, 0), svc->pid);
|
||||||
if (runlevel != 1)
|
if (runlevel != 1)
|
||||||
@@ -969,9 +962,14 @@ int service_stop(svc_t *svc)
|
|||||||
|
|
||||||
if (!svc_is_sysv(svc)) {
|
if (!svc_is_sysv(svc)) {
|
||||||
if (svc->pid > 1) {
|
if (svc->pid > 1) {
|
||||||
/* Kill all children in the same proess group, e.g. logit */
|
/*
|
||||||
rc = kill(-svc->pid, svc->sighalt);
|
* Send SIGTERM to parent process of process group, not to the
|
||||||
dbg("kill(-%d, %d) => rc %d, errno %d", svc->pid, svc->sighalt, rc, errno);
|
* entire group. This gives the process time to properly stop
|
||||||
|
* and/or forward TERM to its children. If it does not respond
|
||||||
|
* in within a reasonable timeout we SIGKILL the entire group.
|
||||||
|
*/
|
||||||
|
rc = kill(svc->pid, svc->sighalt);
|
||||||
|
dbg("kill(%d, %d) => rc %d, errno %d", svc->pid, svc->sighalt, rc, errno);
|
||||||
/* PID lost or forking process never really started */
|
/* PID lost or forking process never really started */
|
||||||
if (rc == -1 && (errno == ESRCH || errno == ENOENT)) {
|
if (rc == -1 && (errno == ESRCH || errno == ENOENT)) {
|
||||||
service_cleanup(svc);
|
service_cleanup(svc);
|
||||||
@@ -1732,6 +1730,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
else
|
else
|
||||||
memset(svc->ifstmt, 0, sizeof(svc->ifstmt));
|
memset(svc->ifstmt, 0, sizeof(svc->ifstmt));
|
||||||
svc->manual = manual;
|
svc->manual = manual;
|
||||||
|
svc->nowarn = nowarn;
|
||||||
svc->respawn = respawn;
|
svc->respawn = respawn;
|
||||||
svc->forking = forking;
|
svc->forking = forking;
|
||||||
svc->restart_max = restart_max;
|
svc->restart_max = restart_max;
|
||||||
@@ -1837,6 +1836,8 @@ void service_monitor(pid_t lost, int status)
|
|||||||
dbg("collected script %s(%d), normal exit: %d, signaled: %d, exit code: %d",
|
dbg("collected script %s(%d), normal exit: %d, signaled: %d, exit code: %d",
|
||||||
svc->state == SVC_CLEANUP_STATE ? svc->post_script : svc->pre_script,
|
svc->state == SVC_CLEANUP_STATE ? svc->post_script : svc->pre_script,
|
||||||
lost, WIFEXITED(status), WIFSIGNALED(status), WEXITSTATUS(status));
|
lost, WIFEXITED(status), WIFSIGNALED(status), WEXITSTATUS(status));
|
||||||
|
/* Kill all children in the same proess group, e.g. logit */
|
||||||
|
dbg("Killing lingering children in same process group ...");
|
||||||
kill(-svc->pid, SIGKILL);
|
kill(-svc->pid, SIGKILL);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -1858,8 +1859,8 @@ void service_monitor(pid_t lost, int status)
|
|||||||
logit(LOG_CONSOLE | LOG_NOTICE, "Stopped %s[%d]", svc_ident(svc, NULL, 0), lost);
|
logit(LOG_CONSOLE | LOG_NOTICE, "Stopped %s[%d]", svc_ident(svc, NULL, 0), lost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Terminate any children in the same proess group, e.g. logit */
|
/* Terminate any children in the same proess group, e.g. logit */
|
||||||
|
dbg("Killing lingering children in same process group ...");
|
||||||
kill(-svc->pid, SIGKILL);
|
kill(-svc->pid, SIGKILL);
|
||||||
|
|
||||||
/* Try removing PID file (in case service does not clean up after itself) */
|
/* Try removing PID file (in case service does not clean up after itself) */
|
||||||
@@ -2269,6 +2270,15 @@ restart:
|
|||||||
case SVC_HALTED_STATE:
|
case SVC_HALTED_STATE:
|
||||||
if (enabled)
|
if (enabled)
|
||||||
svc_set_state(svc, SVC_WAITING_STATE);
|
svc_set_state(svc, SVC_WAITING_STATE);
|
||||||
|
else {
|
||||||
|
if (svc_is_conflict(svc)) {
|
||||||
|
logit(svc->nowarn ? LOG_DEBUG : LOG_INFO,
|
||||||
|
"%s in conflict with %s, checking again ...",
|
||||||
|
svc_ident(svc, NULL, 0), svc->conflict);
|
||||||
|
if (!svc_conflicts(svc))
|
||||||
|
svc_unblock(svc);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SVC_DONE_STATE:
|
case SVC_DONE_STATE:
|
||||||
@@ -2335,6 +2345,16 @@ restart:
|
|||||||
if (sm_is_in_teardown(&sm))
|
if (sm_is_in_teardown(&sm))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Don't start if it conflicts with something else already started */
|
||||||
|
if (svc_conflicts(svc)) {
|
||||||
|
logit(svc->nowarn ? LOG_DEBUG : LOG_INFO,
|
||||||
|
"Not starting %s, conflicts with %s",
|
||||||
|
svc_ident(svc, NULL, 0), svc->conflict);
|
||||||
|
svc_conflict(svc);
|
||||||
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (svc_has_pre(svc)) {
|
if (svc_has_pre(svc)) {
|
||||||
svc_set_state(svc, SVC_SETUP_STATE);
|
svc_set_state(svc, SVC_SETUP_STATE);
|
||||||
service_pre_script(svc);
|
service_pre_script(svc);
|
||||||
|
|||||||
+1
-1
@@ -132,7 +132,7 @@ void stty(int fd, speed_t speed)
|
|||||||
dprint(fd, "\033[?25h", 6);
|
dprint(fd, "\033[?25h", 6);
|
||||||
|
|
||||||
/* Enable line wrap, if disabled previously */
|
/* Enable line wrap, if disabled previously */
|
||||||
dprint(fd, "\033[7h", 4);
|
dprint(fd, "\033[?7h", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ typedef enum {
|
|||||||
SVC_BLOCK_USER,
|
SVC_BLOCK_USER,
|
||||||
SVC_BLOCK_BUSY,
|
SVC_BLOCK_BUSY,
|
||||||
SVC_BLOCK_RESTARTING,
|
SVC_BLOCK_RESTARTING,
|
||||||
|
SVC_BLOCK_CONFLICT,
|
||||||
} svc_block_t;
|
} svc_block_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -125,6 +126,7 @@ typedef struct svc {
|
|||||||
svc_type_t type; /* Service, run, task, ... */
|
svc_type_t type; /* Service, run, task, ... */
|
||||||
char 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` */
|
char manual; /* run/task that require `initctl start foo` */
|
||||||
|
char nowarn; /* Skip or log warning if cmd missing or conflicts */
|
||||||
const int dirty; /* 0: unmodified, 1: modified */
|
const int dirty; /* 0: unmodified, 1: modified */
|
||||||
const int removed;
|
const int removed;
|
||||||
int starting; /* ... waiting for pidfile to be re-asserted */
|
int starting; /* ... waiting for pidfile to be re-asserted */
|
||||||
@@ -270,6 +272,7 @@ static inline int svc_is_busy (svc_t *svc) { return svc && svc->block == SV
|
|||||||
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 int svc_is_crashing (svc_t *svc) { return svc && svc->block == SVC_BLOCK_CRASHING; }
|
||||||
static inline int svc_is_restart (svc_t *svc) { return svc && svc->block == SVC_BLOCK_RESTARTING; }
|
static inline int svc_is_restart (svc_t *svc) { return svc && svc->block == SVC_BLOCK_RESTARTING; }
|
||||||
|
static inline int svc_is_conflict (svc_t *svc) { return svc && svc->block == SVC_BLOCK_CONFLICT; }
|
||||||
|
|
||||||
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)
|
||||||
@@ -278,6 +281,7 @@ static inline void svc_busy (svc_t *svc) { if (svc) svc->block = SVC_BLOC
|
|||||||
static inline void svc_missing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_MISSING; }
|
static inline void svc_missing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_MISSING; }
|
||||||
static inline void svc_restarting (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_RESTARTING; }
|
static inline void svc_restarting (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_RESTARTING; }
|
||||||
static inline void svc_crashing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_CRASHING; }
|
static inline void svc_crashing (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_CRASHING; }
|
||||||
|
static inline void svc_conflict (svc_t *svc) { if (svc) svc->block = SVC_BLOCK_CONFLICT; }
|
||||||
|
|
||||||
/* Has condition in configuration and cond is allowed? */
|
/* Has condition in configuration and cond is allowed? */
|
||||||
static inline int svc_has_cond(svc_t *svc)
|
static inline int svc_has_cond(svc_t *svc)
|
||||||
@@ -350,6 +354,9 @@ static inline char *svc_status(svc_t *svc)
|
|||||||
|
|
||||||
case SVC_BLOCK_RESTARTING:
|
case SVC_BLOCK_RESTARTING:
|
||||||
return "restart";
|
return "restart";
|
||||||
|
case SVC_BLOCK_CONFLICT:
|
||||||
|
return "conflict";
|
||||||
|
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user