X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fswap.c;h=4ffe19f1e84a3052f60d48e3ba3d38388264925e;hb=4dba533a137486719fb385c45fc2ff75593fdf53;hp=078ad9fbbffc470469e42282ae7aabd532467ac6;hpb=008d348eddce97ef807fb908484efb0ade3172c5;p=elogind.git diff --git a/src/swap.c b/src/swap.c index 078ad9fbb..4ffe19f1e 100644 --- a/src/swap.c +++ b/src/swap.c @@ -36,6 +36,7 @@ #include "dbus-swap.h" #include "special.h" #include "bus-errors.h" +#include "exit-status.h" static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { [SWAP_DEAD] = UNIT_INACTIVE, @@ -81,6 +82,7 @@ static void swap_unset_proc_swaps(Swap *s) { s->timeout_usec = DEFAULT_TIMEOUT_USEC; exec_context_init(&s->exec_context); + s->exec_context.std_output = EXEC_OUTPUT_KMSG; s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; @@ -175,6 +177,7 @@ static int swap_add_target_links(Swap *s) { return r; if (!p->noauto && + !p->nofail && (p->handle || s->meta.manager->swap_auto) && s->from_etc_fstab && s->meta.manager->running_as == MANAGER_SYSTEM) @@ -199,9 +202,15 @@ static int swap_add_device_links(Swap *s) { else return 0; - return unit_add_node_link(UNIT(s), s->what, - !p->noauto && p->nofail && - s->meta.manager->running_as == MANAGER_SYSTEM); + if (is_device_path(s->what)) + return unit_add_node_link(UNIT(s), s->what, + !p->noauto && p->nofail && + s->meta.manager->running_as == MANAGER_SYSTEM); + else + /* File based swap devices need to be ordered after + * remount-rootfs.service, since they might need a + * writable file system. */ + return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_ROOTFS_SERVICE, NULL, true); } static int swap_add_default_dependencies(Swap *s) { @@ -211,7 +220,7 @@ static int swap_add_default_dependencies(Swap *s) { if (s->meta.manager->running_as == MANAGER_SYSTEM) { - if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTED_BY, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) return r; } @@ -256,6 +265,8 @@ static int swap_load(Unit *u) { return r; if (u->meta.load_state == UNIT_LOADED) { + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) + return r; if (s->meta.fragment_path) s->from_fragment = true; @@ -289,7 +300,7 @@ static int swap_load(Unit *u) { if ((r = swap_add_target_links(s)) < 0) return r; - if ((r = unit_add_default_cgroup(u)) < 0) + if ((r = unit_add_default_cgroups(u)) < 0) return r; if (s->meta.default_dependencies) @@ -495,7 +506,7 @@ static void swap_set_state(Swap *s, SwapState state) { swap_state_to_string(old_state), swap_state_to_string(state)); - unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); } static int swap_coldplug(Unit *u) { @@ -989,13 +1000,23 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) { break; case SWAP_ACTIVATING_SIGTERM: - log_warning("%s activation timed out. Killing.", u->meta.id); - swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false); + if (s->exec_context.send_sigkill) { + log_warning("%s activation timed out. Killing.", u->meta.id); + swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false); + } else { + log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->meta.id); + swap_enter_dead(s, false); + } break; case SWAP_DEACTIVATING_SIGTERM: - log_warning("%s deactivation timed out. Killing.", u->meta.id); - swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false); + if (s->exec_context.send_sigkill) { + log_warning("%s deactivation timed out. Killing.", u->meta.id); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false); + } else { + log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->meta.id); + swap_enter_dead(s, false); + } break; case SWAP_ACTIVATING_SIGKILL: @@ -1073,7 +1094,7 @@ int swap_fd_event(Manager *m, int events) { assert(m); assert(events & EPOLLPRI); - if ((r == swap_load_proc_swaps(m, true)) < 0) { + if ((r = swap_load_proc_swaps(m, true)) < 0) { log_error("Failed to reread /proc/swaps: %s", strerror(-r)); /* Reset flags, just in case, for late calls */ @@ -1162,6 +1183,39 @@ static Unit *swap_following(Unit *u) { return UNIT(first); } +static int swap_following_set(Unit *u, Set **_set) { + Swap *s = SWAP(u); + Swap *other; + Set *set; + int r; + + assert(s); + assert(_set); + + if (LIST_JUST_US(same_proc_swaps, s)) { + *_set = NULL; + return 0; + } + + if (!(set = set_new(NULL, NULL))) + return -ENOMEM; + + LIST_FOREACH_AFTER(same_proc_swaps, other, s) + if ((r = set_put(set, other)) < 0) + goto fail; + + LIST_FOREACH_BEFORE(same_proc_swaps, other, s) + if ((r = set_put(set, other)) < 0) + goto fail; + + *_set = set; + return 1; + +fail: + set_free(set); + return r; +} + static void swap_shutdown(Manager *m) { assert(m); @@ -1319,6 +1373,7 @@ const UnitVTable swap_vtable = { .bus_invalidating_properties = bus_swap_invalidating_properties, .following = swap_following, + .following_set = swap_following_set, .enumerate = swap_enumerate, .shutdown = swap_shutdown