chiark / gitweb /
unit: handle nicely of certain unit types are not supported on specific systems
[elogind.git] / src / core / swap.c
index 1204386cdbc144e3984bdc5dc35172ce1d28825b..cb19d0f1236e50a75e35de76aef7761434a291a6 100644 (file)
@@ -35,7 +35,7 @@
 #include "unit-name.h"
 #include "dbus-swap.h"
 #include "special.h"
-#include "bus-errors.h"
+#include "bus-common-errors.h"
 #include "exit-status.h"
 #include "def.h"
 #include "path-util.h"
@@ -191,20 +191,16 @@ static int swap_arm_timer(Swap *s) {
 }
 
 static int swap_add_device_links(Swap *s) {
-        SwapParameters *p;
-
         assert(s);
 
         if (!s->what)
                 return 0;
 
-        if (s->from_fragment)
-                p = &s->parameters_fragment;
-        else
+        if (!s->from_fragment)
                 return 0;
 
         if (is_device_path(s->what))
-                return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
+                return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
         else
                 /* File based swap devices need to be ordered after
                  * systemd-remount-fs.service, since they might need a
@@ -213,9 +209,6 @@ static int swap_add_device_links(Swap *s) {
 }
 
 static int swap_add_default_dependencies(Swap *s) {
-        bool nofail, noauto;
-        int r;
-
         assert(s);
 
         if (UNIT(s)->manager->running_as != SYSTEMD_SYSTEM)
@@ -224,29 +217,7 @@ static int swap_add_default_dependencies(Swap *s) {
         if (detect_container(NULL) > 0)
                 return 0;
 
-        r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
-        if (r < 0)
-                return r;
-
-        if (!s->from_fragment)
-                /* The swap unit can either be for an alternative device name, in which
-                 * case we don't need to add the dependency on swap.target because this unit
-                 * is following a different unit which will have this dependency added,
-                 * or it can be derived from /proc/swaps, in which case it was started
-                 * manually, and should not become a dependency of swap.target. */
-                return 0;
-
-        nofail = s->parameters_fragment.nofail;
-        noauto = s->parameters_fragment.noauto;
-
-        if (!noauto) {
-                if (nofail)
-                        r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
-                else
-                        r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
-        }
-
-        return r < 0 ? r : 0;
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
 }
 
 static int swap_verify(Swap *s) {
@@ -262,12 +233,12 @@ static int swap_verify(Swap *s) {
 
         b = unit_has_name(UNIT(s), e);
         if (!b) {
-                log_error_unit(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
+                log_unit_error(UNIT(s)->id, "%s: Value of \"What\" and unit name do not match, not loading.", UNIT(s)->id);
                 return -EINVAL;
         }
 
         if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
-                log_error_unit(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
+                log_unit_error(UNIT(s)->id, "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.", UNIT(s)->id);
                 return -EINVAL;
         }
 
@@ -371,8 +342,6 @@ static int swap_add_one(
                 const char *what,
                 const char *what_proc_swaps,
                 int priority,
-                bool noauto,
-                bool nofail,
                 bool set_flags) {
 
         _cleanup_free_ char *e = NULL;
@@ -435,15 +404,13 @@ static int swap_add_one(
         SWAP(u)->from_proc_swaps = true;
 
         p->priority = priority;
-        p->noauto = noauto;
-        p->nofail = nofail;
 
         unit_add_to_dbus_queue(u);
 
         return 0;
 
 fail:
-        log_warning_unit(e, "Failed to load swap unit: %s", strerror(-r));
+        log_unit_warning_errno(e, r, "Failed to load swap unit: %m");
 
         if (delete && u)
                 unit_free(u);
@@ -460,7 +427,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
 
         assert(m);
 
-        r = swap_add_one(m, device, device, prio, false, false, set_flags);
+        r = swap_add_one(m, device, device, prio, set_flags);
         if (r < 0)
                 return r;
 
@@ -476,7 +443,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
         /* Add the main device node */
         dn = udev_device_get_devnode(d);
         if (dn && !streq(dn, device))
-                swap_add_one(m, dn, device, prio, false, false, set_flags);
+                swap_add_one(m, dn, device, prio, set_flags);
 
         /* Add additional units for all symlinks */
         first = udev_device_get_devlinks_list_entry(d);
@@ -497,7 +464,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
                             st.st_rdev != udev_device_get_devnum(d))
                                 continue;
 
-                swap_add_one(m, p, device, prio, false, false, set_flags);
+                swap_add_one(m, p, device, prio, set_flags);
         }
 
         return r;
@@ -525,7 +492,7 @@ static void swap_set_state(Swap *s, SwapState state) {
         }
 
         if (state != old_state)
-                log_debug_unit(UNIT(s)->id,
+                log_unit_debug(UNIT(s)->id,
                                "%s changed %s -> %s",
                                UNIT(s)->id,
                                swap_state_to_string(old_state),
@@ -606,12 +573,8 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
         if (p)
                 fprintf(f,
                         "%sPriority: %i\n"
-                        "%sNoAuto: %s\n"
-                        "%sNoFail: %s\n"
                         "%sOptions: %s\n",
                         prefix, p->priority,
-                        prefix, yes_no(p->noauto),
-                        prefix, yes_no(p->nofail),
                         prefix, strempty(p->options));
 
         if (s->control_pid > 0)
@@ -650,6 +613,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
         exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
         exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
         exec_params.cgroup_path = UNIT(s)->cgroup_path;
+        exec_params.cgroup_delegate = s->cgroup_context.delegate;
         exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
         exec_params.unit_id = UNIT(s)->id;
 
@@ -710,7 +674,8 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
         r = unit_kill_context(
                         UNIT(s),
                         &s->kill_context,
-                        state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
+                        (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
+                        KILL_KILL : KILL_TERMINATE,
                         -1,
                         s->control_pid,
                         false);
@@ -733,7 +698,7 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
         return;
 
 fail:
-        log_warning_unit(UNIT(s)->id,
+        log_unit_warning(UNIT(s)->id,
                          "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
 
         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
@@ -862,7 +827,7 @@ static void swap_enter_activating(Swap *s) {
         return;
 
 fail:
-        log_warning_unit(UNIT(s)->id,
+        log_unit_warning(UNIT(s)->id,
                          "%s failed to run 'swapon' task: %s",
                          UNIT(s)->id, strerror(-r));
         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
@@ -894,7 +859,7 @@ static void swap_enter_deactivating(Swap *s) {
         return;
 
 fail:
-        log_warning_unit(UNIT(s)->id,
+        log_unit_warning(UNIT(s)->id,
                          "%s failed to run 'swapoff' task: %s",
                          UNIT(s)->id, strerror(-r));
         swap_enter_active(s, SWAP_FAILURE_RESOURCES);
@@ -981,7 +946,7 @@ static int swap_deserialize_item(Unit *u, const char *key, const char *value, FD
 
                 state = swap_state_from_string(value);
                 if (state < 0)
-                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                        log_unit_debug(u->id, "Failed to parse state value %s", value);
                 else
                         s->deserialized_state = state;
         } else if (streq(key, "result")) {
@@ -989,14 +954,14 @@ static int swap_deserialize_item(Unit *u, const char *key, const char *value, FD
 
                 f = swap_result_from_string(value);
                 if (f < 0)
-                        log_debug_unit(u->id, "Failed to parse result value %s", value);
+                        log_unit_debug(u->id, "Failed to parse result value %s", value);
                 else if (f != SWAP_SUCCESS)
                         s->result = f;
         } else if (streq(key, "control-pid")) {
                 pid_t pid;
 
                 if (parse_pid(value, &pid) < 0)
-                        log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
+                        log_unit_debug(u->id, "Failed to parse control-pid value %s", value);
                 else
                         s->control_pid = pid;
 
@@ -1005,13 +970,13 @@ static int swap_deserialize_item(Unit *u, const char *key, const char *value, FD
 
                 id = swap_exec_command_from_string(value);
                 if (id < 0)
-                        log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
+                        log_unit_debug(u->id, "Failed to parse exec-command value %s", value);
                 else {
                         s->control_command_id = id;
                         s->control_command = s->exec_command + id;
                 }
         } else
-                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
+                log_unit_debug(u->id, "Unknown serialization key '%s'", key);
 
         return 0;
 }
@@ -1069,8 +1034,8 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
         }
 
-        log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
-                      u->id,
+        log_unit_full(u->id,
+                      f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
                       "%s swap process exited, code=%s status=%i",
                       u->id, sigchld_code_to_string(code), status);
 
@@ -1112,38 +1077,38 @@ static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userd
 
         case SWAP_ACTIVATING:
         case SWAP_ACTIVATING_DONE:
-                log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
+                log_unit_warning(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
                 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
                 break;
 
         case SWAP_DEACTIVATING:
-                log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
+                log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
                 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
                 break;
 
         case SWAP_ACTIVATING_SIGTERM:
                 if (s->kill_context.send_sigkill) {
-                        log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
+                        log_unit_warning(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
                         swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
                 } else {
-                        log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
+                        log_unit_warning(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
                 }
                 break;
 
         case SWAP_DEACTIVATING_SIGTERM:
                 if (s->kill_context.send_sigkill) {
-                        log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
+                        log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
                         swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
                 } else {
-                        log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
+                        log_unit_warning(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
                 }
                 break;
 
         case SWAP_ACTIVATING_SIGKILL:
         case SWAP_DEACTIVATING_SIGKILL:
-                log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
+                log_unit_warning(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
                 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
                 break;
 
@@ -1205,7 +1170,7 @@ static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v
 
         r = swap_load_proc_swaps(m, true);
         if (r < 0) {
-                log_error("Failed to reread /proc/swaps: %s", strerror(-r));
+                log_error_errno(r, "Failed to reread /proc/swaps: %m");
 
                 /* Reset flags, just in case, for late calls */
                 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
@@ -1488,6 +1453,21 @@ static int swap_get_timeout(Unit *u, uint64_t *timeout) {
         return 1;
 }
 
+static bool swap_supported(Manager *m) {
+        static int supported = -1;
+
+        /* If swap support is not available in the kernel, or we are
+         * running in a container we don't support swap units, and any
+         * attempts to starting one should fail immediately. */
+
+        if (supported < 0)
+                supported =
+                        access("/proc/swaps", F_OK) >= 0 &&
+                        detect_container(NULL) <= 0;
+
+        return supported;
+}
+
 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
         [SWAP_DEAD] = "dead",
         [SWAP_ACTIVATING] = "activating",
@@ -1574,6 +1554,7 @@ const UnitVTable swap_vtable = {
 
         .enumerate = swap_enumerate,
         .shutdown = swap_shutdown,
+        .supported = swap_supported,
 
         .status_message_formats = {
                 .starting_stopping = {