X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fswap.c;h=d5bf153f29bb91ce8e129600c59b9fc993c2883c;hp=a7e2126edde5780ca3bb1e1f880c7985a71078dd;hb=3ef63c317481c2b3f1fe39e1b0f130aac3544522;hpb=9eb977db5b89b44f254ab40c1876a76b7d7ea2d0 diff --git a/src/core/swap.c b/src/core/swap.c index a7e2126ed..d5bf153f2 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -39,6 +39,7 @@ #include "exit-status.h" #include "def.h" #include "path-util.h" +#include "virt.h" static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { [SWAP_DEAD] = UNIT_INACTIVE, @@ -86,8 +87,9 @@ static void swap_init(Unit *u) { exec_context_init(&s->exec_context); s->exec_context.std_output = u->manager->default_std_output; s->exec_context.std_error = u->manager->default_std_error; + kill_context_init(&s->kill_context); - s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; + s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; s->timer_watch.type = WATCH_INVALID; @@ -116,9 +118,8 @@ static void swap_done(Unit *u) { free(s->what); s->what = NULL; - free(s->parameters_etc_fstab.what); free(s->parameters_fragment.what); - s->parameters_etc_fstab.what = s->parameters_fragment.what = NULL; + s->parameters_fragment.what = NULL; exec_context_done(&s->exec_context); exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); @@ -166,28 +167,17 @@ static int swap_add_mount_links(Swap *s) { static int swap_add_target_links(Swap *s) { Unit *tu; - SwapParameters *p; int r; assert(s); - if (s->from_fragment) - p = &s->parameters_fragment; - else if (s->from_etc_fstab) - p = &s->parameters_etc_fstab; - else + if (!s->from_fragment) return 0; - if ((r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu)) < 0) + r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu); + if (r < 0) return r; - if (!p->noauto && - !p->nofail && - s->from_etc_fstab && - UNIT(s)->manager->running_as == MANAGER_SYSTEM) - if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0) - return r; - return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true); } @@ -201,8 +191,6 @@ static int swap_add_device_links(Swap *s) { if (s->from_fragment) p = &s->parameters_fragment; - else if (s->from_etc_fstab) - p = &s->parameters_etc_fstab; else return 0; @@ -222,11 +210,15 @@ static int swap_add_default_dependencies(Swap *s) { assert(s); - if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + if (UNIT(s)->manager->running_as != MANAGER_SYSTEM) + return 0; - if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) - return r; - } + 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; return 0; } @@ -249,7 +241,7 @@ static int swap_verify(Swap *s) { return -EINVAL; } - if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) { + if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) { log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id); return -EINVAL; } @@ -278,8 +270,6 @@ static int swap_load(Unit *u) { if (!s->what) { if (s->parameters_fragment.what) s->what = strdup(s->parameters_fragment.what); - else if (s->parameters_etc_fstab.what) - s->what = strdup(s->parameters_etc_fstab.what); else if (s->parameters_proc_swaps.what) s->what = strdup(s->parameters_proc_swaps.what); else @@ -310,12 +300,16 @@ static int swap_load(Unit *u) { if (UNIT(s)->default_dependencies) if ((r = swap_add_default_dependencies(s)) < 0) return r; + + r = unit_exec_context_defaults(u, &s->exec_context); + if (r < 0) + return r; } return swap_verify(s); } -int swap_add_one( +static int swap_add_one( Manager *m, const char *what, const char *what_proc_swaps, @@ -329,9 +323,11 @@ int swap_add_one( bool delete = false; int r; SwapParameters *p; + Swap *first; assert(m); assert(what); + assert(what_proc_swaps); e = unit_name_from_path(what, ".swap"); if (!e) @@ -339,8 +335,7 @@ int swap_add_one( u = manager_get_unit(m, e); - if (what_proc_swaps && - u && + if (u && SWAP(u)->from_proc_swaps && !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps)) return -EEXIST; @@ -368,54 +363,37 @@ int swap_add_one( } else delete = false; - if (what_proc_swaps) { - Swap *first; + p = &SWAP(u)->parameters_proc_swaps; - p = &SWAP(u)->parameters_proc_swaps; + if (!p->what) { + if (!(wp = strdup(what_proc_swaps))) { + r = -ENOMEM; + goto fail; + } - if (!p->what) { - if (!(wp = strdup(what_proc_swaps))) { + if (!m->swaps_by_proc_swaps) + if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) { r = -ENOMEM; goto fail; } - if (!m->swaps_by_proc_swaps) - if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) { - r = -ENOMEM; - goto fail; - } - - free(p->what); - p->what = wp; - - first = hashmap_get(m->swaps_by_proc_swaps, wp); - LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u)); - - if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0) - goto fail; - } - - if (set_flags) { - SWAP(u)->is_active = true; - SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps; - } - - SWAP(u)->from_proc_swaps = true; + free(p->what); + p->what = wp; - } else { - p = &SWAP(u)->parameters_etc_fstab; + first = hashmap_get(m->swaps_by_proc_swaps, wp); + LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u)); - if (!(wp = strdup(what))) { - r = -ENOMEM; + if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0) goto fail; - } - - free(p->what); - p->what = wp; + } - SWAP(u)->from_etc_fstab = true; + if (set_flags) { + SWAP(u)->is_active = true; + SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps; } + SWAP(u)->from_proc_swaps = true; + p->priority = priority; p->noauto = noauto; p->nofail = nofail; @@ -568,34 +546,36 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) { else if (s->from_fragment) p = &s->parameters_fragment; else - p = &s->parameters_etc_fstab; + p = NULL; fprintf(f, "%sSwap State: %s\n" "%sResult: %s\n" "%sWhat: %s\n" - "%sPriority: %i\n" - "%sNoAuto: %s\n" - "%sNoFail: %s\n" - "%sFrom /etc/fstab: %s\n" "%sFrom /proc/swaps: %s\n" "%sFrom fragment: %s\n", prefix, swap_state_to_string(s->state), prefix, swap_result_to_string(s->result), prefix, s->what, - prefix, p->priority, - prefix, yes_no(p->noauto), - prefix, yes_no(p->nofail), - prefix, yes_no(s->from_etc_fstab), prefix, yes_no(s->from_proc_swaps), prefix, yes_no(s->from_fragment)); + if (p) + fprintf(f, + "%sPriority: %i\n" + "%sNoAuto: %s\n" + "%sNoFail: %s\n", + prefix, p->priority, + prefix, yes_no(p->noauto), + prefix, yes_no(p->nofail)); + if (s->control_pid > 0) fprintf(f, "%sControl PID: %lu\n", prefix, (unsigned long) s->control_pid); exec_context_dump(&s->exec_context, f, prefix); + kill_context_dump(&s->kill_context, f, prefix); } static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { @@ -621,6 +601,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { UNIT(s)->cgroup_bondings, UNIT(s)->cgroup_attributes, NULL, + UNIT(s)->id, NULL, &pid)) < 0) goto fail; @@ -667,9 +648,9 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { if (f != SWAP_SUCCESS) s->result = f; - if (s->exec_context.kill_mode != KILL_NONE) { + if (s->kill_context.kill_mode != KILL_NONE) { int sig = (state == SWAP_ACTIVATING_SIGTERM || - state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; + state == SWAP_DEACTIVATING_SIGTERM) ? s->kill_context.kill_signal : SIGKILL; if (s->control_pid > 0) { if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) @@ -679,7 +660,7 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { wait_for_exit = true; } - if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) { + if (s->kill_context.kill_mode == KILL_CONTROL_GROUP) { if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { r = -ENOMEM; @@ -732,8 +713,6 @@ static void swap_enter_activating(Swap *s) { if (s->from_fragment) priority = s->parameters_fragment.priority; - else if (s->from_etc_fstab) - priority = s->parameters_etc_fstab.priority; else priority = -1; @@ -823,6 +802,9 @@ static int swap_start(Unit *u) { assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED); + if (detect_container(NULL) > 0) + return -EPERM; + s->result = SWAP_SUCCESS; swap_enter_activating(s); return 0; @@ -843,6 +825,9 @@ static int swap_stop(Unit *u) { assert(s->state == SWAP_ACTIVATING || s->state == SWAP_ACTIVE); + if (detect_container(NULL) > 0) + return -EPERM; + swap_enter_deactivating(s); return 0; } @@ -928,7 +913,7 @@ static bool swap_check_gc(Unit *u) { assert(s); - return s->from_etc_fstab || s->from_proc_swaps; + return s->from_proc_swaps; } static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { @@ -943,7 +928,7 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { s->control_pid = 0; - if (is_clean_exit(code, status)) + if (is_clean_exit(code, status, NULL)) f = SWAP_SUCCESS; else if (code == CLD_EXITED) f = SWAP_FAILURE_EXIT_CODE; @@ -1021,7 +1006,7 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) { break; case SWAP_ACTIVATING_SIGTERM: - if (s->exec_context.send_sigkill) { + if (s->kill_context.send_sigkill) { log_warning("%s activation timed out. Killing.", u->id); swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); } else { @@ -1031,7 +1016,7 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) { break; case SWAP_DEACTIVATING_SIGTERM: - if (s->exec_context.send_sigkill) { + if (s->kill_context.send_sigkill) { log_warning("%s deactivation timed out. Killing.", u->id); swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); } else { @@ -1269,8 +1254,6 @@ static int swap_enumerate(Manager *m) { return -errno; } - /* We rely on mount.c to load /etc/fstab for us */ - if ((r = swap_load_proc_swaps(m, false)) < 0) swap_shutdown(m); @@ -1288,7 +1271,7 @@ static void swap_reset_failed(Unit *u) { s->result = SWAP_SUCCESS; } -static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { +static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) { Swap *s = SWAP(u); int r = 0; Set *pid_set = NULL; @@ -1310,23 +1293,25 @@ static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError * if (kill(s->control_pid, signo) < 0) r = -errno; - if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) { + if (who == KILL_ALL) { int q; - if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) return -ENOMEM; /* Exclude the control pid from being killed via the cgroup */ - if (s->control_pid > 0) - if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) { + if (s->control_pid > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->control_pid)); + if (q < 0) { r = q; goto finish; } + } q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL); - if (q < 0) - if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) - r = q; + if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; } finish: @@ -1369,8 +1354,9 @@ static const char* const swap_result_table[_SWAP_RESULT_MAX] = { DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult); const UnitVTable swap_vtable = { - .suffix = ".swap", .object_size = sizeof(Swap), + .exec_context_offset = offsetof(Swap, exec_context), + .sections = "Unit\0" "Swap\0" @@ -1378,7 +1364,6 @@ const UnitVTable swap_vtable = { .no_alias = true, .no_instances = true, - .show_status = true, .init = swap_init, .load = swap_load, @@ -1414,5 +1399,23 @@ const UnitVTable swap_vtable = { .following_set = swap_following_set, .enumerate = swap_enumerate, - .shutdown = swap_shutdown + .shutdown = swap_shutdown, + + .status_message_formats = { + .starting_stopping = { + [0] = "Activating swap %s...", + [1] = "Deactivating swap %s...", + }, + .finished_start_job = { + [JOB_DONE] = "Activated swap %s.", + [JOB_FAILED] = "Failed to activate swap %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + [JOB_TIMEOUT] = "Timed out activating swap %s.", + }, + .finished_stop_job = { + [JOB_DONE] = "Deactivated swap %s.", + [JOB_FAILED] = "Failed deactivating swap %s.", + [JOB_TIMEOUT] = "Timed out deactivating swap %s.", + }, + }, };