Merge pull request #6932 from poettering/notify-pam
fix handling of cgroup empty events for Type=notify services
This commit is contained in:
commit
81473e6f20
|
@ -936,7 +936,18 @@
|
|||
<para>Note that for each unit making use of this option a PAM session handler process will be maintained as
|
||||
part of the unit and stays around as long as the unit is active, to ensure that appropriate actions can be
|
||||
taken when the unit and hence the PAM session terminates. This process is named <literal>(sd-pam)</literal> and
|
||||
is an immediate child process of the unit's main process.</para></listitem>
|
||||
is an immediate child process of the unit's main process.</para>
|
||||
|
||||
<para>Note that when this option is used for a unit it is very likely (depending on PAM configuration) that the
|
||||
main unit process will be migrated to its own session scope unit when it is activated. This process will hence
|
||||
be associated with two units: the unit it was originally started from (and for which
|
||||
<varname>PAMName=</varname> was configured), and the session scope unit. Any child processes of that process
|
||||
will however be associated with the session scope unit only. This has implications when used in combination
|
||||
with <varname>NotifyAccess=</varname><option>all</option>, as these child processes will not be able to affect
|
||||
changes in the original unit through notification messages. These messages will be considered belonging to the
|
||||
session scope unit and not the original unit. It is hence not recommended to use <varname>PAMName=</varname> in
|
||||
combination with <varname>NotifyAccess=</varname><option>all</option>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
|
|
@ -1401,8 +1401,7 @@ static int service_spawn(
|
|||
static int main_pid_good(Service *s) {
|
||||
assert(s);
|
||||
|
||||
/* Returns 0 if the pid is dead, 1 if it is good, -1 if we
|
||||
* don't know */
|
||||
/* Returns 0 if the pid is dead, > 0 if it is good, < 0 if we don't know */
|
||||
|
||||
/* If we know the pid file, then let's just check if it is
|
||||
* still valid */
|
||||
|
@ -1423,9 +1422,13 @@ static int main_pid_good(Service *s) {
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
_pure_ static int control_pid_good(Service *s) {
|
||||
static int control_pid_good(Service *s) {
|
||||
assert(s);
|
||||
|
||||
/* Returns 0 if the control PID is dead, > 0 if it is good. We never actually return < 0 here, but in order to
|
||||
* make this function as similar as possible to main_pid_good() and cgroup_good(), we pretend that < 0 also
|
||||
* means: we can't figure it out. */
|
||||
|
||||
return s->control_pid > 0;
|
||||
}
|
||||
|
||||
|
@ -1434,6 +1437,9 @@ static int cgroup_good(Service *s) {
|
|||
|
||||
assert(s);
|
||||
|
||||
/* Returns 0 if the cgroup is empty or doesn't exist, > 0 if it is exists and is populated, < 0 if we can't
|
||||
* figure it out */
|
||||
|
||||
if (!UNIT(s)->cgroup_path)
|
||||
return 0;
|
||||
|
||||
|
@ -1441,7 +1447,7 @@ static int cgroup_good(Service *s) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return !r;
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
static bool service_shall_restart(Service *s) {
|
||||
|
@ -2865,7 +2871,9 @@ static void service_notify_cgroup_empty_event(Unit *u) {
|
|||
* SIGCHLD for. */
|
||||
|
||||
case SERVICE_START:
|
||||
if (s->type == SERVICE_NOTIFY) {
|
||||
if (s->type == SERVICE_NOTIFY &&
|
||||
main_pid_good(s) == 0 &&
|
||||
control_pid_good(s) == 0) {
|
||||
/* No chance of getting a ready notification anymore */
|
||||
service_enter_stop_post(s, SERVICE_FAILURE_PROTOCOL);
|
||||
break;
|
||||
|
@ -2874,7 +2882,10 @@ static void service_notify_cgroup_empty_event(Unit *u) {
|
|||
/* Fall through */
|
||||
|
||||
case SERVICE_START_POST:
|
||||
if (s->pid_file_pathspec) {
|
||||
if (s->pid_file_pathspec &&
|
||||
main_pid_good(s) == 0 &&
|
||||
control_pid_good(s) == 0) {
|
||||
|
||||
/* Give up hoping for the daemon to write its PID file */
|
||||
log_unit_warning(u, "Daemon never wrote its PID file. Failing.");
|
||||
|
||||
|
@ -2895,7 +2906,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
|
|||
case SERVICE_STOP_SIGTERM:
|
||||
case SERVICE_STOP_SIGKILL:
|
||||
|
||||
if (main_pid_good(s) <= 0 && !control_pid_good(s))
|
||||
if (main_pid_good(s) <= 0 && control_pid_good(s) <= 0)
|
||||
service_enter_stop_post(s, SERVICE_SUCCESS);
|
||||
|
||||
break;
|
||||
|
@ -2903,7 +2914,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
|
|||
case SERVICE_STOP_POST:
|
||||
case SERVICE_FINAL_SIGTERM:
|
||||
case SERVICE_FINAL_SIGKILL:
|
||||
if (main_pid_good(s) <= 0 && !control_pid_good(s))
|
||||
if (main_pid_good(s) <= 0 && control_pid_good(s) <= 0)
|
||||
service_enter_dead(s, SERVICE_SUCCESS, true);
|
||||
|
||||
break;
|
||||
|
@ -3040,7 +3051,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||
case SERVICE_STOP_SIGTERM:
|
||||
case SERVICE_STOP_SIGKILL:
|
||||
|
||||
if (!control_pid_good(s))
|
||||
if (control_pid_good(s) <= 0)
|
||||
service_enter_stop_post(s, f);
|
||||
|
||||
/* If there is still a control process, wait for that first */
|
||||
|
@ -3050,7 +3061,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||
case SERVICE_FINAL_SIGTERM:
|
||||
case SERVICE_FINAL_SIGKILL:
|
||||
|
||||
if (!control_pid_good(s))
|
||||
if (control_pid_good(s) <= 0)
|
||||
service_enter_dead(s, f, true);
|
||||
break;
|
||||
|
||||
|
@ -3131,7 +3142,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||
r = service_load_pid_file(s, !has_start_post);
|
||||
if (!has_start_post && r < 0) {
|
||||
r = service_demand_pid_file(s);
|
||||
if (r < 0 || !cgroup_good(s))
|
||||
if (r < 0 || cgroup_good(s) == 0)
|
||||
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
|
||||
break;
|
||||
}
|
||||
|
@ -3153,7 +3164,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||
r = service_load_pid_file(s, true);
|
||||
if (r < 0) {
|
||||
r = service_demand_pid_file(s);
|
||||
if (r < 0 || !cgroup_good(s))
|
||||
if (r < 0 || cgroup_good(s) == 0)
|
||||
service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue