+ if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
+ manager_send_unit_plymouth(m, u);
+
+ } else {
+
+ /* We don't care about D-Bus here, since we'll get an
+ * asynchronous notification for it anyway. */
+
+ if (u->type == UNIT_SERVICE &&
+ UNIT_IS_INACTIVE_OR_FAILED(ns) &&
+ !UNIT_IS_INACTIVE_OR_FAILED(os) &&
+ m->n_reloading <= 0) {
+
+ /* Hmm, if there was no start record written
+ * write it now, so that we always have a nice
+ * pair */
+ if (!u->in_audit) {
+ manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
+
+ if (ns == UNIT_INACTIVE)
+ manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
+ } else
+ /* Write audit record if we have just finished shutting down */
+ manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
+
+ u->in_audit = false;
+ }
+ }
+
+ manager_recheck_journal(m);
+ unit_trigger_notify(u);
+
+ if (u->manager->n_reloading <= 0) {
+ /* Maybe we finished startup and are now ready for
+ * being stopped because unneeded? */
+ unit_check_unneeded(u);
+
+ /* Maybe we finished startup, but something we needed
+ * has vanished? Let's die then. (This happens when
+ * something BindsTo= to a Type=oneshot unit, as these
+ * units go directly from starting to inactive,
+ * without ever entering started.) */
+ unit_check_binds_to(u);
+ }
+
+ unit_add_to_dbus_queue(u);
+ unit_add_to_gc_queue(u);
+}
+
+int unit_watch_pid(Unit *u, pid_t pid) {
+ int q, r;
+
+ assert(u);
+ assert(pid >= 1);
+
+ /* Watch a specific PID. We only support one or two units
+ * watching each PID for now, not more. */
+
+ r = set_ensure_allocated(&u->pids, NULL);
+ if (r < 0)
+ return r;
+
+ r = hashmap_ensure_allocated(&u->manager->watch_pids1, NULL);
+ if (r < 0)
+ return r;
+
+ r = hashmap_put(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
+ if (r == -EEXIST) {
+ r = hashmap_ensure_allocated(&u->manager->watch_pids2, NULL);
+ if (r < 0)
+ return r;
+
+ r = hashmap_put(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
+ }
+
+ q = set_put(u->pids, LONG_TO_PTR(pid));
+ if (q < 0)
+ return q;
+
+ return r;
+}
+
+void unit_unwatch_pid(Unit *u, pid_t pid) {
+ assert(u);
+ assert(pid >= 1);
+
+ hashmap_remove_value(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
+ hashmap_remove_value(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
+ set_remove(u->pids, LONG_TO_PTR(pid));
+}
+
+void unit_unwatch_all_pids(Unit *u) {
+ assert(u);
+
+ while (!set_isempty(u->pids))
+ unit_unwatch_pid(u, PTR_TO_LONG(set_first(u->pids)));
+
+ set_free(u->pids);
+ u->pids = NULL;
+}
+
+static int unit_watch_pids_in_path(Unit *u, const char *path) {
+ _cleanup_closedir_ DIR *d = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ int ret = 0, r;
+
+ assert(u);
+ assert(path);
+
+ /* Adds all PIDs from a specific cgroup path to the set of PIDs we watch. */
+
+ r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, path, &f);
+ if (r >= 0) {
+ pid_t pid;
+
+ while ((r = cg_read_pid(f, &pid)) > 0) {
+ r = unit_watch_pid(u, pid);
+ if (r < 0 && ret >= 0)
+ ret = r;
+ }
+ if (r < 0 && ret >= 0)
+ ret = r;