X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fswap.c;h=346a5fd7121af758c973fd06e3b71fbbb8594f58;hb=a2c0e528b8b5ba370527db279605e4e4135689c1;hp=b2ca048bcbc0c23c3d476243b1e89e39dc3fb4b7;hpb=3018d31238caabc2e204aa161e647dc1c1b5d1c6;p=elogind.git diff --git a/src/core/swap.c b/src/core/swap.c index b2ca048bc..346a5fd71 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -152,8 +152,8 @@ static void swap_done(Unit *u) { free(s->parameters_fragment.what); s->parameters_fragment.what = NULL; - free(s->parameters_fragment.discard); - s->parameters_fragment.discard = NULL; + free(s->parameters_fragment.options); + s->parameters_fragment.options = NULL; s->exec_runtime = exec_runtime_unref(s->exec_runtime); exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); @@ -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,13 +573,9 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) { if (p) fprintf(f, "%sPriority: %i\n" - "%sNoAuto: %s\n" - "%sNoFail: %s\n" - "%sDiscard: %s\n", + "%sOptions: %s\n", prefix, p->priority, - prefix, yes_no(p->noauto), - prefix, yes_no(p->nofail), - prefix, p->discard ?: "none"); + prefix, strempty(p->options)); if (s->control_pid > 0) fprintf(f, @@ -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,15 +698,80 @@ 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); } +static int mount_find_pri(const char *options, int *ret) { + const char *opt; + char *end; + unsigned long r; + + assert(ret); + + if (!options) + return 0; + + opt = mount_test_option(options, "pri"); + if (!opt) + return 0; + + opt += strlen("pri"); + if (*opt != '=') + return -EINVAL; + + errno = 0; + r = strtoul(opt + 1, &end, 10); + if (errno > 0) + return -errno; + + if (end == opt + 1 || (*end != ',' && *end != 0)) + return -EINVAL; + + *ret = (int) r; + return 1; +} + +static int mount_find_discard(const char *options, char **ret) { + const char *opt; + char *ans; + size_t len; + + assert(ret); + + if (!options) + return 0; + + opt = mount_test_option(options, "discard"); + if (!opt) + return 0; + + opt += strlen("discard"); + if (*opt == ',' || *opt == '\0') + ans = strdup("all"); + else { + if (*opt != '=') + return -EINVAL; + + len = strcspn(opt + 1, ","); + if (len == 0) + return -EINVAL; + + ans = strndup(opt + 1, len); + } + + if (!ans) + return -ENOMEM; + + *ret = ans; + return 1; +} + static void swap_enter_activating(Swap *s) { - int r, priority; - char *discard; + _cleanup_free_ char *discard = NULL; + int r, priority = -1; assert(s); @@ -749,11 +779,11 @@ static void swap_enter_activating(Swap *s) { s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE; if (s->from_fragment) { + mount_find_discard(s->parameters_fragment.options, &discard); + priority = s->parameters_fragment.priority; - discard = s->parameters_fragment.discard; - } else { - priority = -1; - discard = NULL; + if (priority < 0) + mount_find_pri(s->parameters_fragment.options, &priority); } r = exec_command_set(s->control_command, "/sbin/swapon", NULL); @@ -770,9 +800,11 @@ static void swap_enter_activating(Swap *s) { } if (discard && !streq(discard, "none")) { - const char *discard_arg = "--discard"; + const char *discard_arg; - if (!streq(discard, "all")) + if (streq(discard, "all")) + discard_arg = "--discard"; + else discard_arg = strappenda("--discard=", discard); r = exec_command_append(s->control_command, discard_arg, NULL); @@ -795,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); @@ -827,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); @@ -914,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")) { @@ -922,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; @@ -938,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; } @@ -1002,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); @@ -1045,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; @@ -1138,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]) {