chiark / gitweb /
unit: don't Require systemd-journald.socket from units
[elogind.git] / src / core / unit.c
index 98237c81472d5b2095db445cad4732b41978e8a5..3a88996eb7394bfe69c27145bd165f8a24cb07f9 100644 (file)
@@ -46,6 +46,8 @@
 #include "missing.h"
 #include "cgroup-attr.h"
 #include "mkdir.h"
+#include "label.h"
+#include "fileio-label.h"
 
 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = &service_vtable,
@@ -614,9 +616,11 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         /* If syslog or kernel logging is requested, make sure our own
          * logging daemon is run first. */
 
-        if (u->manager->running_as == SYSTEMD_SYSTEM)
-                if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true)) < 0)
+        if (u->manager->running_as == SYSTEMD_SYSTEM) {
+                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
+                if (r < 0)
                         return r;
+        }
 
         return 0;
 }
@@ -2769,7 +2773,7 @@ int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data
         if (!filename_is_safe(name))
                 return -EINVAL;
 
-        p = strjoin(runtime ? "/run/systemd/system/" : "/etc/systemd/systemd/", u->id, ".d", NULL);
+        p = strjoin(runtime ? "/run/systemd/system/" : "/etc/systemd/system/", u->id, ".d", NULL);
         if (!p)
                 return -ENOMEM;
 
@@ -2778,7 +2782,7 @@ int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data
                 return -ENOMEM;
 
         mkdir_p(p, 0755);
-        return write_one_line_file_atomic(q, data);
+        return write_one_line_file_atomic_label(q, data);
 }
 
 int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {
@@ -2792,7 +2796,7 @@ int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {
         if (!filename_is_safe(name))
                 return -EINVAL;
 
-        p = strjoin(runtime ? "/run/systemd/system/" : "/etc/systemd/systemd/", u->id, ".d", NULL);
+        p = strjoin(runtime ? "/run/systemd/system/" : "/etc/systemd/system/", u->id, ".d", NULL);
         if (!p)
                 return -ENOMEM;
 
@@ -2807,6 +2811,82 @@ int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {
         return 0;
 }
 
+int unit_kill_context(
+                Unit *u,
+                KillContext *c,
+                bool sigkill,
+                pid_t main_pid,
+                pid_t control_pid,
+                bool main_pid_alien) {
+
+        int sig, wait_for_exit = 0, r;
+
+        assert(u);
+        assert(c);
+
+        if (c->kill_mode == KILL_NONE)
+                return 0;
+
+        sig = sigkill ? SIGKILL : c->kill_signal;
+
+        if (main_pid > 0) {
+                r = kill_and_sigcont(main_pid, sig);
+
+                if (r < 0 && r != -ESRCH) {
+                        _cleanup_free_ char *comm = NULL;
+                        get_process_comm(main_pid, &comm);
+
+                        log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
+                                         (long) main_pid, strna(comm), strerror(-r));
+                } else
+                        wait_for_exit = !main_pid_alien;
+        }
+
+        if (control_pid > 0) {
+                r = kill_and_sigcont(control_pid, sig);
+
+                if (r < 0 && r != -ESRCH) {
+                        _cleanup_free_ char *comm = NULL;
+                        get_process_comm(control_pid, &comm);
+
+                        log_warning_unit(u->id,
+                                         "Failed to kill control process %li (%s): %s",
+                                         (long) control_pid, strna(comm), strerror(-r));
+                } else
+                        wait_for_exit = true;
+        }
+
+        if (c->kill_mode == KILL_CONTROL_GROUP) {
+                _cleanup_set_free_ Set *pid_set = NULL;
+
+                pid_set = set_new(trivial_hash_func, trivial_compare_func);
+                if (!pid_set)
+                        return -ENOMEM;
+
+                /* Exclude the main/control pids from being killed via the cgroup */
+                if (main_pid > 0) {
+                        r = set_put(pid_set, LONG_TO_PTR(main_pid));
+                        if (r < 0)
+                                return r;
+                }
+
+                if (control_pid > 0) {
+                        r = set_put(pid_set, LONG_TO_PTR(control_pid));
+                        if (r < 0)
+                                return r;
+                }
+
+                r = cgroup_bonding_kill_list(u->cgroup_bondings, sig, true, false, pid_set, NULL);
+                if (r < 0) {
+                        if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
+                                log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
+                } else if (r > 0)
+                        wait_for_exit = true;
+        }
+
+        return wait_for_exit;
+}
+
 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
         [UNIT_ACTIVE] = "active",
         [UNIT_RELOADING] = "reloading",