core: unify call we use to synthesize cgroup empty events when we stopped watching any unit PIDs

This code is very similar in scope and service units, let's unify it in
one function. This changes little for service units, but for scope units
makes sure we go through the cgroup queue, which is something we should
do anyway.
This commit is contained in:
Lennart Poettering
2018-01-23 21:22:50 +01:00
parent 5cdabc8d7b
commit 11aef522c1
4 changed files with 38 additions and 18 deletions
+25
View File
@@ -1827,6 +1827,31 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) {
return ret;
}
int unit_synthesize_cgroup_empty_event(Unit *u) {
int r;
assert(u);
/* Enqueue a synthetic cgroup empty event if this unit doesn't watch any PIDs anymore. This is compatibility
* support for non-unified systems where notifications aren't reliable, and hence need to take whatever we can
* get as notification source as soon as we stopped having any useful PIDs to watch for. */
if (!u->cgroup_path)
return -ENOENT;
r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
if (r < 0)
return r;
if (r > 0) /* On unified we have reliable notifications, and don't need this */
return 0;
if (!set_isempty(u->pids))
return 0;
unit_add_to_cgroup_empty_queue(u);
return 0;
}
int unit_watch_all_pids(Unit *u) {
int r;
+2
View File
@@ -192,6 +192,8 @@ Unit* manager_get_unit_by_pid(Manager *m, pid_t pid);
int unit_search_main_pid(Unit *u, pid_t *ret);
int unit_watch_all_pids(Unit *u);
int unit_synthesize_cgroup_empty_event(Unit *u);
int unit_get_memory_current(Unit *u, uint64_t *ret);
int unit_get_tasks_current(Unit *u, uint64_t *ret);
int unit_get_cpu_usage(Unit *u, nsec_t *ret);
+6 -9
View File
@@ -472,19 +472,16 @@ static void scope_notify_cgroup_empty_event(Unit *u) {
static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
/* If we get a SIGCHLD event for one of the processes we were
interested in, then we look for others to watch, under the
assumption that we'll sooner or later get a SIGCHLD for
them, as the original process we watched was probably the
parent of them, and they are hence now our children. */
assert(u);
/* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to
* watch, under the assumption that we'll sooner or later get a SIGCHLD for them, as the original
* process we watched was probably the parent of them, and they are hence now our children. */
unit_tidy_watch_pids(u, 0, 0);
unit_watch_all_pids(u);
/* If the PID set is empty now, then let's finish this off
(On unified we use proper notifications) */
if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
scope_notify_cgroup_empty_event(u);
/* If the PID set is empty now, then let's finish this off. */
unit_synthesize_cgroup_empty_event(u);
}
static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
+5 -9
View File
@@ -3301,18 +3301,14 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
if (notify_dbus)
unit_add_to_dbus_queue(u);
/* We got one SIGCHLD for the service, let's watch all
* processes that are now running of the service, and watch
* that. Among the PIDs we then watch will be children
* reassigned to us, which hopefully allows us to identify
* when all children are gone */
/* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to watch,
* under the assumption that we'll sooner or later get a SIGCHLD for them, as the original process we watched
* was probably the parent of them, and they are hence now our children. */
unit_tidy_watch_pids(u, s->main_pid, s->control_pid);
unit_watch_all_pids(u);
/* If the PID set is empty now, then let's finish this off
(On unified we use proper notifications) */
if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
unit_add_to_cgroup_empty_queue(u);
/* If the PID set is empty now, then let's check if the cgroup is empty too and finish off the unit. */
unit_synthesize_cgroup_empty_event(u);
}
static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {