diff options
-rw-r--r-- | src/dbus-swap.c | 7 | ||||
-rw-r--r-- | src/swap.c | 122 | ||||
-rw-r--r-- | src/swap.h | 18 |
3 files changed, 94 insertions, 53 deletions
diff --git a/src/dbus-swap.c b/src/dbus-swap.c index 5ed33b50b4..09cd1e8b9c 100644 --- a/src/dbus-swap.c +++ b/src/dbus-swap.c @@ -36,6 +36,7 @@ BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate") \ BUS_EXEC_CONTEXT_INTERFACE \ " <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \ + " <property name=\"Result\" type=\"s\" access=\"read\"/>\n" \ " </interface>\n" #define INTROSPECTION \ @@ -59,7 +60,8 @@ const char bus_swap_invalidating_properties[] = "Priority\0" "ExecActivate\0" "ExecDeactivate\0" - "ControlPID\0"; + "ControlPID\0" + "Result\0"; static int bus_swap_append_priority(DBusMessageIter *i, const char *property, void *data) { Swap *s = data; @@ -84,12 +86,15 @@ static int bus_swap_append_priority(DBusMessageIter *i, const char *property, vo return 0; } +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_swap_append_swap_result, swap_result, SwapResult); + static const BusProperty bus_swap_properties[] = { { "What", bus_property_append_string, "s", offsetof(Swap, what), true }, { "Priority", bus_swap_append_priority, "i", 0 }, BUS_EXEC_COMMAND_PROPERTY("ExecActivate", offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]), false), BUS_EXEC_COMMAND_PROPERTY("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), false), { "ControlPID", bus_property_append_pid, "u", offsetof(Swap, control_pid) }, + { "Result", bus_swap_append_swap_result,"s", offsetof(Swap, result) }, { NULL, } }; diff --git a/src/swap.c b/src/swap.c index b4a5b3c084..9c72732b94 100644 --- a/src/swap.c +++ b/src/swap.c @@ -90,7 +90,7 @@ static void swap_init(Unit *u) { s->timer_watch.type = WATCH_INVALID; - s->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; UNIT(s)->ignore_on_isolate = true; } @@ -571,6 +571,7 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) { fprintf(f, "%sSwap State: %s\n" + "%sResult: %s\n" "%sWhat: %s\n" "%sPriority: %i\n" "%sNoAuto: %s\n" @@ -580,6 +581,7 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) { "%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), @@ -636,33 +638,33 @@ fail: return r; } -static void swap_enter_dead(Swap *s, bool success) { +static void swap_enter_dead(Swap *s, SwapResult f) { assert(s); - if (!success) - s->failure = true; + if (f != SWAP_SUCCESS) + s->result = f; - swap_set_state(s, s->failure ? SWAP_FAILED : SWAP_DEAD); + swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); } -static void swap_enter_active(Swap *s, bool success) { +static void swap_enter_active(Swap *s, SwapResult f) { assert(s); - if (!success) - s->failure = true; + if (f != SWAP_SUCCESS) + s->result = f; swap_set_state(s, SWAP_ACTIVE); } -static void swap_enter_signal(Swap *s, SwapState state, bool success) { +static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { int r; Set *pid_set = NULL; bool wait_for_exit = false; assert(s); - if (!success) - s->failure = true; + if (f != SWAP_SUCCESS) + s->result = f; if (s->exec_context.kill_mode != KILL_NONE) { int sig = (state == SWAP_ACTIVATING_SIGTERM || @@ -705,14 +707,14 @@ static void swap_enter_signal(Swap *s, SwapState state, bool success) { swap_set_state(s, state); } else - swap_enter_dead(s, true); + swap_enter_dead(s, SWAP_SUCCESS); return; fail: log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); - swap_enter_dead(s, false); + swap_enter_dead(s, SWAP_FAILURE_RESOURCES); if (pid_set) set_free(pid_set); @@ -767,17 +769,14 @@ static void swap_enter_activating(Swap *s) { fail: log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r)); - swap_enter_dead(s, false); + swap_enter_dead(s, SWAP_FAILURE_RESOURCES); } -static void swap_enter_deactivating(Swap *s, bool success) { +static void swap_enter_deactivating(Swap *s) { int r; assert(s); - if (!success) - s->failure = true; - s->control_command_id = SWAP_EXEC_DEACTIVATE; s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE; @@ -799,7 +798,7 @@ static void swap_enter_deactivating(Swap *s, bool success) { fail: log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r)); - swap_enter_active(s, false); + swap_enter_active(s, SWAP_FAILURE_RESOURCES); } static int swap_start(Unit *u) { @@ -822,7 +821,7 @@ static int swap_start(Unit *u) { assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED); - s->failure = false; + s->result = SWAP_SUCCESS; swap_enter_activating(s); return 0; } @@ -842,7 +841,7 @@ static int swap_stop(Unit *u) { assert(s->state == SWAP_ACTIVATING || s->state == SWAP_ACTIVE); - swap_enter_deactivating(s, true); + swap_enter_deactivating(s); return 0; } @@ -854,7 +853,7 @@ static int swap_serialize(Unit *u, FILE *f, FDSet *fds) { assert(fds); unit_serialize_item(u, f, "state", swap_state_to_string(s->state)); - unit_serialize_item(u, f, "failure", yes_no(s->failure)); + unit_serialize_item(u, f, "result", swap_result_to_string(s->result)); if (s->control_pid > 0) unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); @@ -878,14 +877,14 @@ static int swap_deserialize_item(Unit *u, const char *key, const char *value, FD log_debug("Failed to parse state value %s", value); else s->deserialized_state = state; - } else if (streq(key, "failure")) { - int b; - - if ((b = parse_boolean(value)) < 0) - log_debug("Failed to parse failure value %s", value); - else - s->failure = b || s->failure; - + } else if (streq(key, "result")) { + SwapResult f; + + f = swap_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != SWAP_SUCCESS) + s->result = f; } else if (streq(key, "control-pid")) { pid_t pid; @@ -932,7 +931,7 @@ static bool swap_check_gc(Unit *u) { static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { Swap *s = SWAP(u); - bool success; + SwapResult f; assert(s); assert(pid >= 0); @@ -942,16 +941,28 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { s->control_pid = 0; - success = is_clean_exit(code, status); - s->failure = s->failure || !success; + if (is_clean_exit(code, status)) + f = SWAP_SUCCESS; + else if (code == CLD_EXITED) + f = SWAP_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SWAP_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SWAP_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (f != SWAP_SUCCESS) + s->result = f; if (s->control_command) { exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + s->control_command = NULL; s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; } - log_full(success ? LOG_DEBUG : LOG_NOTICE, + log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE, "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status); switch (s->state) { @@ -960,20 +971,20 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { case SWAP_ACTIVATING_SIGTERM: case SWAP_ACTIVATING_SIGKILL: - if (success) - swap_enter_active(s, true); + if (f == SWAP_SUCCESS) + swap_enter_active(s, f); else - swap_enter_dead(s, false); + swap_enter_dead(s, f); break; case SWAP_DEACTIVATING: case SWAP_DEACTIVATING_SIGKILL: case SWAP_DEACTIVATING_SIGTERM: - if (success) - swap_enter_dead(s, true); + if (f == SWAP_SUCCESS) + swap_enter_dead(s, f); else - swap_enter_dead(s, false); + swap_enter_dead(s, f); break; default: @@ -999,38 +1010,38 @@ static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case SWAP_ACTIVATING: log_warning("%s activation timed out. Stopping.", u->id); - swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, false); + swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); break; case SWAP_DEACTIVATING: log_warning("%s deactivation timed out. Stopping.", u->id); - swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, false); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); break; case SWAP_ACTIVATING_SIGTERM: if (s->exec_context.send_sigkill) { log_warning("%s activation timed out. Killing.", u->id); - swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, false); + swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); } else { log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id); - swap_enter_dead(s, false); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); } break; case SWAP_DEACTIVATING_SIGTERM: if (s->exec_context.send_sigkill) { log_warning("%s deactivation timed out. Killing.", u->id); - swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, false); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); } else { log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id); - swap_enter_dead(s, false); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); } break; case SWAP_ACTIVATING_SIGKILL: case SWAP_DEACTIVATING_SIGKILL: log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id); - swap_enter_dead(s, false); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); break; default: @@ -1129,7 +1140,7 @@ int swap_fd_event(Manager *m, int events) { switch (swap->state) { case SWAP_ACTIVE: - swap_enter_dead(swap, true); + swap_enter_dead(swap, SWAP_SUCCESS); break; default: @@ -1145,7 +1156,7 @@ int swap_fd_event(Manager *m, int events) { case SWAP_DEAD: case SWAP_FAILED: - swap_enter_active(swap, true); + swap_enter_active(swap, SWAP_SUCCESS); break; default: @@ -1272,7 +1283,7 @@ static void swap_reset_failed(Unit *u) { if (s->state == SWAP_FAILED) swap_set_state(s, SWAP_DEAD); - s->failure = false; + s->result = SWAP_SUCCESS; } static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { @@ -1343,6 +1354,17 @@ static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand); +static const char* const swap_result_table[_SWAP_RESULT_MAX] = { + [SWAP_SUCCESS] = "success", + [SWAP_FAILURE_RESOURCES] = "resources", + [SWAP_FAILURE_TIMEOUT] = "timeout", + [SWAP_FAILURE_EXIT_CODE] = "exit-code", + [SWAP_FAILURE_SIGNAL] = "signal", + [SWAP_FAILURE_CORE_DUMP] = "core-dump" +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult); + const UnitVTable swap_vtable = { .suffix = ".swap", .object_size = sizeof(Swap), diff --git a/src/swap.h b/src/swap.h index ea98bc2a6f..62d08da30b 100644 --- a/src/swap.h +++ b/src/swap.h @@ -56,6 +56,17 @@ typedef struct SwapParameters { bool handle:1; } SwapParameters; +typedef enum SwapResult { + SWAP_SUCCESS, + SWAP_FAILURE_RESOURCES, + SWAP_FAILURE_TIMEOUT, + SWAP_FAILURE_EXIT_CODE, + SWAP_FAILURE_SIGNAL, + SWAP_FAILURE_CORE_DUMP, + _SWAP_RESULT_MAX, + _SWAP_RESULT_INVALID = -1 +} SwapResult; + struct Swap { Unit meta; @@ -69,13 +80,13 @@ struct Swap { bool from_proc_swaps:1; bool from_fragment:1; - bool failure:1; - /* Used while looking for swaps that vanished or got added * from/to /proc/swaps */ bool is_active:1; bool just_activated:1; + SwapResult result; + usec_t timeout_usec; ExecCommand exec_command[_SWAP_EXEC_COMMAND_MAX]; @@ -111,4 +122,7 @@ SwapState swap_state_from_string(const char *s); const char* swap_exec_command_to_string(SwapExecCommand i); SwapExecCommand swap_exec_command_from_string(const char *s); +const char* swap_result_to_string(SwapResult i); +SwapResult swap_result_from_string(const char *s); + #endif |