1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/epoll.h>
33 #include "load-fragment.h"
34 #include "load-dropin.h"
35 #include "unit-name.h"
36 #include "dbus-swap.h"
38 #include "bus-errors.h"
39 #include "exit-status.h"
41 #include "path-util.h"
44 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
45 [SWAP_DEAD
] = UNIT_INACTIVE
,
46 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
47 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
48 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
49 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
50 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
51 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
52 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
53 [SWAP_FAILED
] = UNIT_FAILED
56 static void swap_unset_proc_swaps(Swap
*s
) {
62 if (!s
->parameters_proc_swaps
.what
)
65 /* Remove this unit from the chain of swaps which share the
66 * same kernel swap device. */
67 swaps
= UNIT(s
)->manager
->swaps_by_proc_swaps
;
68 first
= hashmap_get(swaps
, s
->parameters_proc_swaps
.what
);
69 LIST_REMOVE(Swap
, same_proc_swaps
, first
, s
);
72 hashmap_remove_and_replace(swaps
,
73 s
->parameters_proc_swaps
.what
,
74 first
->parameters_proc_swaps
.what
,
77 hashmap_remove(swaps
, s
->parameters_proc_swaps
.what
);
79 free(s
->parameters_proc_swaps
.what
);
80 s
->parameters_proc_swaps
.what
= NULL
;
83 static void swap_init(Unit
*u
) {
87 assert(UNIT(s
)->load_state
== UNIT_STUB
);
89 s
->timeout_usec
= DEFAULT_TIMEOUT_USEC
;
91 exec_context_init(&s
->exec_context
);
92 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
93 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
94 kill_context_init(&s
->kill_context
);
95 cgroup_context_init(&s
->cgroup_context
);
97 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
99 s
->timer_watch
.type
= WATCH_INVALID
;
101 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
103 UNIT(s
)->ignore_on_isolate
= true;
106 static void swap_unwatch_control_pid(Swap
*s
) {
109 if (s
->control_pid
<= 0)
112 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
116 static void swap_done(Unit
*u
) {
121 swap_unset_proc_swaps(s
);
126 free(s
->parameters_fragment
.what
);
127 s
->parameters_fragment
.what
= NULL
;
129 exec_context_done(&s
->exec_context
, manager_is_reloading_or_reexecuting(u
->manager
));
130 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
131 s
->control_command
= NULL
;
133 cgroup_context_done(&s
->cgroup_context
);
135 swap_unwatch_control_pid(s
);
137 unit_unwatch_timer(u
, &s
->timer_watch
);
140 int swap_add_one_mount_link(Swap
*s
, Mount
*m
) {
146 if (UNIT(s
)->load_state
!= UNIT_LOADED
||
147 UNIT(m
)->load_state
!= UNIT_LOADED
)
150 if (is_device_path(s
->what
))
153 if (!path_startswith(s
->what
, m
->where
))
156 r
= unit_add_two_dependencies(UNIT(s
), UNIT_AFTER
, UNIT_REQUIRES
, UNIT(m
), true);
163 static int swap_add_mount_links(Swap
*s
) {
169 LIST_FOREACH(units_by_type
, other
, UNIT(s
)->manager
->units_by_type
[UNIT_MOUNT
])
170 if ((r
= swap_add_one_mount_link(s
, MOUNT(other
))) < 0)
176 static int swap_add_device_links(Swap
*s
) {
184 if (s
->from_fragment
)
185 p
= &s
->parameters_fragment
;
189 if (is_device_path(s
->what
))
190 return unit_add_node_link(UNIT(s
), s
->what
, !p
->noauto
&&
191 UNIT(s
)->manager
->running_as
== SYSTEMD_SYSTEM
);
193 /* File based swap devices need to be ordered after
194 * systemd-remount-fs.service, since they might need a
195 * writable file system. */
196 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
199 static int swap_add_default_dependencies(Swap
*s
) {
200 bool nofail
= false, noauto
= false;
205 if (UNIT(s
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
208 if (detect_container(NULL
) > 0)
211 r
= unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
215 if (s
->from_fragment
) {
216 SwapParameters
*p
= &s
->parameters_fragment
;
224 r
= unit_add_dependency_by_name_inverse(UNIT(s
),
225 UNIT_WANTS
, SPECIAL_SWAP_TARGET
, NULL
, true);
227 r
= unit_add_two_dependencies_by_name_inverse(UNIT(s
),
228 UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SWAP_TARGET
, NULL
, true);
236 static int swap_verify(Swap
*s
) {
238 _cleanup_free_
char *e
= NULL
;
240 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
243 e
= unit_name_from_path(s
->what
, ".swap");
247 b
= unit_has_name(UNIT(s
), e
);
249 log_error_unit(UNIT(s
)->id
,
250 "%s: Value of \"What\" and unit name do not match, not loading.",
255 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
256 log_error_unit(UNIT(s
)->id
,
257 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.",
265 static int swap_load(Unit
*u
) {
270 assert(u
->load_state
== UNIT_STUB
);
272 /* Load a .swap file */
273 r
= unit_load_fragment_and_dropin_optional(u
);
277 if (u
->load_state
== UNIT_LOADED
) {
278 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
282 if (UNIT(s
)->fragment_path
)
283 s
->from_fragment
= true;
286 if (s
->parameters_fragment
.what
)
287 s
->what
= strdup(s
->parameters_fragment
.what
);
288 else if (s
->parameters_proc_swaps
.what
)
289 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
291 s
->what
= unit_name_to_path(u
->id
);
297 path_kill_slashes(s
->what
);
299 if (!UNIT(s
)->description
)
300 if ((r
= unit_set_description(u
, s
->what
)) < 0)
303 r
= swap_add_device_links(s
);
307 r
= swap_add_mount_links(s
);
311 r
= unit_add_default_slice(u
);
315 if (UNIT(s
)->default_dependencies
) {
316 r
= swap_add_default_dependencies(s
);
321 r
= unit_exec_context_defaults(u
, &s
->exec_context
);
326 return swap_verify(s
);
329 static int swap_add_one(
332 const char *what_proc_swaps
,
339 _cleanup_free_
char *e
= NULL
;
348 assert(what_proc_swaps
);
350 e
= unit_name_from_path(what
, ".swap");
354 u
= manager_get_unit(m
, e
);
357 SWAP(u
)->from_proc_swaps
&&
358 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
))
364 u
= unit_new(m
, sizeof(Swap
));
368 r
= unit_add_name(u
, e
);
372 SWAP(u
)->what
= strdup(what
);
373 if (!SWAP(u
)->what
) {
378 unit_add_to_load_queue(u
);
382 p
= &SWAP(u
)->parameters_proc_swaps
;
385 wp
= strdup(what_proc_swaps
);
391 if (!m
->swaps_by_proc_swaps
) {
392 m
->swaps_by_proc_swaps
= hashmap_new(string_hash_func
, string_compare_func
);
393 if (!m
->swaps_by_proc_swaps
) {
402 first
= hashmap_get(m
->swaps_by_proc_swaps
, wp
);
403 LIST_PREPEND(Swap
, same_proc_swaps
, first
, SWAP(u
));
405 r
= hashmap_replace(m
->swaps_by_proc_swaps
, wp
, first
);
411 SWAP(u
)->is_active
= true;
412 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
415 SWAP(u
)->from_proc_swaps
= true;
417 p
->priority
= priority
;
421 unit_add_to_dbus_queue(u
);
426 log_warning_unit(e
, "Failed to load swap unit: %s", strerror(-r
));
436 static int swap_process_new_swap(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
442 if (stat(device
, &st
) >= 0 && S_ISBLK(st
.st_mode
)) {
443 struct udev_device
*d
;
445 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
447 /* So this is a proper swap device. Create swap units
448 * for all names this swap device is known under */
450 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
454 dn
= udev_device_get_devnode(d
);
455 /* Skip dn==device, since that case will be handled below */
456 if (dn
&& !streq(dn
, device
))
457 r
= swap_add_one(m
, dn
, device
, prio
, false, false, set_flags
);
459 /* Add additional units for all symlinks */
460 first
= udev_device_get_devlinks_list_entry(d
);
461 udev_list_entry_foreach(item
, first
) {
464 /* Don't bother with the /dev/block links */
465 p
= udev_list_entry_get_name(item
);
467 if (path_startswith(p
, "/dev/block/"))
470 if (stat(p
, &st
) >= 0)
471 if ((!S_ISBLK(st
.st_mode
)) ||
472 st
.st_rdev
!= udev_device_get_devnum(d
))
475 k
= swap_add_one(m
, p
, device
, prio
, false, false, set_flags
);
480 udev_device_unref(d
);
483 k
= swap_add_one(m
, device
, device
, prio
, false, false, set_flags
);
490 static void swap_set_state(Swap
*s
, SwapState state
) {
495 old_state
= s
->state
;
498 if (state
!= SWAP_ACTIVATING
&&
499 state
!= SWAP_ACTIVATING_SIGTERM
&&
500 state
!= SWAP_ACTIVATING_SIGKILL
&&
501 state
!= SWAP_DEACTIVATING
&&
502 state
!= SWAP_DEACTIVATING_SIGTERM
&&
503 state
!= SWAP_DEACTIVATING_SIGKILL
) {
504 unit_unwatch_timer(UNIT(s
), &s
->timer_watch
);
505 swap_unwatch_control_pid(s
);
506 s
->control_command
= NULL
;
507 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
510 if (state
!= old_state
)
511 log_debug_unit(UNIT(s
)->id
,
512 "%s changed %s -> %s",
514 swap_state_to_string(old_state
),
515 swap_state_to_string(state
));
517 unit_notify(UNIT(s
), state_translation_table
[old_state
],
518 state_translation_table
[state
], true);
521 static int swap_coldplug(Unit
*u
) {
523 SwapState new_state
= SWAP_DEAD
;
527 assert(s
->state
== SWAP_DEAD
);
529 if (s
->deserialized_state
!= s
->state
)
530 new_state
= s
->deserialized_state
;
531 else if (s
->from_proc_swaps
)
532 new_state
= SWAP_ACTIVE
;
534 if (new_state
!= s
->state
) {
536 if (new_state
== SWAP_ACTIVATING
||
537 new_state
== SWAP_ACTIVATING_SIGTERM
||
538 new_state
== SWAP_ACTIVATING_SIGKILL
||
539 new_state
== SWAP_DEACTIVATING
||
540 new_state
== SWAP_DEACTIVATING_SIGTERM
||
541 new_state
== SWAP_DEACTIVATING_SIGKILL
) {
543 if (s
->control_pid
<= 0)
546 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
550 r
= unit_watch_timer(UNIT(s
), CLOCK_MONOTONIC
, true, s
->timeout_usec
, &s
->timer_watch
);
555 swap_set_state(s
, new_state
);
561 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
568 if (s
->from_proc_swaps
)
569 p
= &s
->parameters_proc_swaps
;
570 else if (s
->from_fragment
)
571 p
= &s
->parameters_fragment
;
579 "%sFrom /proc/swaps: %s\n"
580 "%sFrom fragment: %s\n",
581 prefix
, swap_state_to_string(s
->state
),
582 prefix
, swap_result_to_string(s
->result
),
584 prefix
, yes_no(s
->from_proc_swaps
),
585 prefix
, yes_no(s
->from_fragment
));
593 prefix
, yes_no(p
->noauto
),
594 prefix
, yes_no(p
->nofail
));
596 if (s
->control_pid
> 0)
598 "%sControl PID: %lu\n",
599 prefix
, (unsigned long) s
->control_pid
);
601 exec_context_dump(&s
->exec_context
, f
, prefix
);
602 kill_context_dump(&s
->kill_context
, f
, prefix
);
605 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
613 unit_realize_cgroup(UNIT(s
));
615 r
= unit_watch_timer(UNIT(s
), CLOCK_MONOTONIC
, true, s
->timeout_usec
, &s
->timer_watch
);
623 UNIT(s
)->manager
->environment
,
627 UNIT(s
)->manager
->confirm_spawn
,
628 UNIT(s
)->manager
->cgroup_supported
,
629 UNIT(s
)->cgroup_path
,
636 r
= unit_watch_pid(UNIT(s
), pid
);
638 /* FIXME: we need to do something here */
646 unit_unwatch_timer(UNIT(s
), &s
->timer_watch
);
651 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
654 if (f
!= SWAP_SUCCESS
)
657 exec_context_tmp_dirs_done(&s
->exec_context
);
658 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
661 static void swap_enter_active(Swap
*s
, SwapResult f
) {
664 if (f
!= SWAP_SUCCESS
)
667 swap_set_state(s
, SWAP_ACTIVE
);
670 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
675 if (f
!= SWAP_SUCCESS
)
678 r
= unit_kill_context(
681 state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
,
689 r
= unit_watch_timer(UNIT(s
), CLOCK_MONOTONIC
, true, s
->timeout_usec
, &s
->timer_watch
);
693 swap_set_state(s
, state
);
695 swap_enter_dead(s
, SWAP_SUCCESS
);
700 log_warning_unit(UNIT(s
)->id
,
701 "%s failed to kill processes: %s", UNIT(s
)->id
, strerror(-r
));
703 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
706 static void swap_enter_activating(Swap
*s
) {
711 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
712 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
714 if (s
->from_fragment
)
715 priority
= s
->parameters_fragment
.priority
;
722 snprintf(p
, sizeof(p
), "%i", priority
);
725 r
= exec_command_set(
733 r
= exec_command_set(
742 swap_unwatch_control_pid(s
);
744 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
748 swap_set_state(s
, SWAP_ACTIVATING
);
753 log_warning_unit(UNIT(s
)->id
,
754 "%s failed to run 'swapon' task: %s",
755 UNIT(s
)->id
, strerror(-r
));
756 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
759 static void swap_enter_deactivating(Swap
*s
) {
764 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
765 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
767 r
= exec_command_set(s
->control_command
,
774 swap_unwatch_control_pid(s
);
776 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
780 swap_set_state(s
, SWAP_DEACTIVATING
);
785 log_warning_unit(UNIT(s
)->id
,
786 "%s failed to run 'swapoff' task: %s",
787 UNIT(s
)->id
, strerror(-r
));
788 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
791 static int swap_start(Unit
*u
) {
796 /* We cannot fulfill this request right now, try again later
799 if (s
->state
== SWAP_DEACTIVATING
||
800 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
801 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
802 s
->state
== SWAP_ACTIVATING_SIGTERM
||
803 s
->state
== SWAP_ACTIVATING_SIGKILL
)
806 if (s
->state
== SWAP_ACTIVATING
)
809 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
811 if (detect_container(NULL
) > 0)
814 s
->result
= SWAP_SUCCESS
;
815 swap_enter_activating(s
);
819 static int swap_stop(Unit
*u
) {
824 if (s
->state
== SWAP_DEACTIVATING
||
825 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
826 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
827 s
->state
== SWAP_ACTIVATING_SIGTERM
||
828 s
->state
== SWAP_ACTIVATING_SIGKILL
)
831 assert(s
->state
== SWAP_ACTIVATING
||
832 s
->state
== SWAP_ACTIVE
);
834 if (detect_container(NULL
) > 0)
837 swap_enter_deactivating(s
);
841 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
848 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
849 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
851 if (s
->control_pid
> 0)
852 unit_serialize_item_format(u
, f
, "control-pid", "%lu", (unsigned long) s
->control_pid
);
854 if (s
->control_command_id
>= 0)
855 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
857 exec_context_serialize(&s
->exec_context
, UNIT(s
), f
);
862 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
868 if (streq(key
, "state")) {
871 state
= swap_state_from_string(value
);
873 log_debug_unit(u
->id
, "Failed to parse state value %s", value
);
875 s
->deserialized_state
= state
;
876 } else if (streq(key
, "result")) {
879 f
= swap_result_from_string(value
);
881 log_debug_unit(u
->id
, "Failed to parse result value %s", value
);
882 else if (f
!= SWAP_SUCCESS
)
884 } else if (streq(key
, "control-pid")) {
887 if (parse_pid(value
, &pid
) < 0)
888 log_debug_unit(u
->id
, "Failed to parse control-pid value %s", value
);
890 s
->control_pid
= pid
;
892 } else if (streq(key
, "control-command")) {
895 id
= swap_exec_command_from_string(value
);
897 log_debug_unit(u
->id
, "Failed to parse exec-command value %s", value
);
899 s
->control_command_id
= id
;
900 s
->control_command
= s
->exec_command
+ id
;
902 } else if (streq(key
, "tmp-dir")) {
909 s
->exec_context
.tmp_dir
= t
;
910 } else if (streq(key
, "var-tmp-dir")) {
917 s
->exec_context
.var_tmp_dir
= t
;
919 log_debug_unit(u
->id
, "Unknown serialization key '%s'", key
);
924 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
927 return state_translation_table
[SWAP(u
)->state
];
930 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
933 return swap_state_to_string(SWAP(u
)->state
);
936 _pure_
static bool swap_check_gc(Unit
*u
) {
941 return s
->from_proc_swaps
;
944 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
951 if (pid
!= s
->control_pid
)
956 if (is_clean_exit(code
, status
, NULL
))
958 else if (code
== CLD_EXITED
)
959 f
= SWAP_FAILURE_EXIT_CODE
;
960 else if (code
== CLD_KILLED
)
961 f
= SWAP_FAILURE_SIGNAL
;
962 else if (code
== CLD_DUMPED
)
963 f
= SWAP_FAILURE_CORE_DUMP
;
965 assert_not_reached("Unknown code");
967 if (f
!= SWAP_SUCCESS
)
970 if (s
->control_command
) {
971 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
973 s
->control_command
= NULL
;
974 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
977 log_full_unit(f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
,
979 "%s swap process exited, code=%s status=%i",
980 u
->id
, sigchld_code_to_string(code
), status
);
984 case SWAP_ACTIVATING
:
985 case SWAP_ACTIVATING_SIGTERM
:
986 case SWAP_ACTIVATING_SIGKILL
:
988 if (f
== SWAP_SUCCESS
)
989 swap_enter_active(s
, f
);
991 swap_enter_dead(s
, f
);
994 case SWAP_DEACTIVATING
:
995 case SWAP_DEACTIVATING_SIGKILL
:
996 case SWAP_DEACTIVATING_SIGTERM
:
998 if (f
== SWAP_SUCCESS
)
999 swap_enter_dead(s
, f
);
1001 swap_enter_dead(s
, f
);
1005 assert_not_reached("Uh, control process died at wrong time.");
1008 /* Notify clients about changed exit status */
1009 unit_add_to_dbus_queue(u
);
1011 /* Request a reload of /proc/swaps, so that following units
1012 * can follow our state change */
1013 u
->manager
->request_reload
= true;
1016 static void swap_timer_event(Unit
*u
, uint64_t elapsed
, Watch
*w
) {
1020 assert(elapsed
== 1);
1021 assert(w
== &s
->timer_watch
);
1025 case SWAP_ACTIVATING
:
1026 log_warning_unit(u
->id
, "%s activation timed out. Stopping.", u
->id
);
1027 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1030 case SWAP_DEACTIVATING
:
1031 log_warning_unit(u
->id
, "%s deactivation timed out. Stopping.", u
->id
);
1032 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1035 case SWAP_ACTIVATING_SIGTERM
:
1036 if (s
->kill_context
.send_sigkill
) {
1037 log_warning_unit(u
->id
, "%s activation timed out. Killing.", u
->id
);
1038 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1040 log_warning_unit(u
->id
, "%s activation timed out. Skipping SIGKILL. Ignoring.", u
->id
);
1041 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1045 case SWAP_DEACTIVATING_SIGTERM
:
1046 if (s
->kill_context
.send_sigkill
) {
1047 log_warning_unit(u
->id
, "%s deactivation timed out. Killing.", u
->id
);
1048 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1050 log_warning_unit(u
->id
, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", u
->id
);
1051 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1055 case SWAP_ACTIVATING_SIGKILL
:
1056 case SWAP_DEACTIVATING_SIGKILL
:
1057 log_warning_unit(u
->id
, "%s swap process still around after SIGKILL. Ignoring.", u
->id
);
1058 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1062 assert_not_reached("Timeout at wrong time.");
1066 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1072 rewind(m
->proc_swaps
);
1074 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1077 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1080 k
= fscanf(m
->proc_swaps
,
1081 "%ms " /* device/file */
1082 "%*s " /* type of swap */
1083 "%*s " /* swap size */
1085 "%i\n", /* priority */
1091 log_warning("Failed to parse /proc/swaps:%u", i
);
1099 k
= swap_process_new_swap(m
, d
, prio
, set_flags
);
1107 int swap_dispatch_reload(Manager
*m
) {
1108 /* This function should go as soon as the kernel properly notifies us */
1110 if (_likely_(!m
->request_reload
))
1113 m
->request_reload
= false;
1115 return swap_fd_event(m
, EPOLLPRI
);
1118 int swap_fd_event(Manager
*m
, int events
) {
1123 assert(events
& EPOLLPRI
);
1125 r
= swap_load_proc_swaps(m
, true);
1127 log_error("Failed to reread /proc/swaps: %s", strerror(-r
));
1129 /* Reset flags, just in case, for late calls */
1130 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1131 Swap
*swap
= SWAP(u
);
1133 swap
->is_active
= swap
->just_activated
= false;
1139 manager_dispatch_load_queue(m
);
1141 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1142 Swap
*swap
= SWAP(u
);
1144 if (!swap
->is_active
) {
1145 /* This has just been deactivated */
1147 swap
->from_proc_swaps
= false;
1148 swap_unset_proc_swaps(swap
);
1150 switch (swap
->state
) {
1153 swap_enter_dead(swap
, SWAP_SUCCESS
);
1157 swap_set_state(swap
, swap
->state
);
1161 } else if (swap
->just_activated
) {
1163 /* New swap entry */
1165 switch (swap
->state
) {
1169 swap_enter_active(swap
, SWAP_SUCCESS
);
1173 /* Nothing really changed, but let's
1174 * issue an notification call
1175 * nonetheless, in case somebody is
1176 * waiting for this. */
1177 swap_set_state(swap
, swap
->state
);
1182 /* Reset the flags for later calls */
1183 swap
->is_active
= swap
->just_activated
= false;
1189 static Unit
*swap_following(Unit
*u
) {
1191 Swap
*other
, *first
= NULL
;
1195 if (streq_ptr(s
->what
, s
->parameters_proc_swaps
.what
))
1198 /* Make everybody follow the unit that's named after the swap
1199 * device in the kernel */
1201 LIST_FOREACH_AFTER(same_proc_swaps
, other
, s
)
1202 if (streq_ptr(other
->what
, other
->parameters_proc_swaps
.what
))
1205 LIST_FOREACH_BEFORE(same_proc_swaps
, other
, s
) {
1206 if (streq_ptr(other
->what
, other
->parameters_proc_swaps
.what
))
1215 static int swap_following_set(Unit
*u
, Set
**_set
) {
1224 if (LIST_JUST_US(same_proc_swaps
, s
)) {
1229 if (!(set
= set_new(NULL
, NULL
)))
1232 LIST_FOREACH_AFTER(same_proc_swaps
, other
, s
)
1233 if ((r
= set_put(set
, other
)) < 0)
1236 LIST_FOREACH_BEFORE(same_proc_swaps
, other
, s
)
1237 if ((r
= set_put(set
, other
)) < 0)
1248 static void swap_shutdown(Manager
*m
) {
1251 if (m
->proc_swaps
) {
1252 fclose(m
->proc_swaps
);
1253 m
->proc_swaps
= NULL
;
1256 hashmap_free(m
->swaps_by_proc_swaps
);
1257 m
->swaps_by_proc_swaps
= NULL
;
1260 static int swap_enumerate(Manager
*m
) {
1264 if (!m
->proc_swaps
) {
1265 struct epoll_event ev
= {
1267 .data
.ptr
= &m
->swap_watch
,
1270 m
->proc_swaps
= fopen("/proc/swaps", "re");
1272 return (errno
== ENOENT
) ? 0 : -errno
;
1274 m
->swap_watch
.type
= WATCH_SWAP
;
1275 m
->swap_watch
.fd
= fileno(m
->proc_swaps
);
1277 if (epoll_ctl(m
->epoll_fd
, EPOLL_CTL_ADD
, m
->swap_watch
.fd
, &ev
) < 0)
1281 r
= swap_load_proc_swaps(m
, false);
1288 static void swap_reset_failed(Unit
*u
) {
1293 if (s
->state
== SWAP_FAILED
)
1294 swap_set_state(s
, SWAP_DEAD
);
1296 s
->result
= SWAP_SUCCESS
;
1299 static int swap_kill(Unit
*u
, KillWho who
, int signo
, DBusError
*error
) {
1300 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1303 static const char* const swap_state_table
[_SWAP_STATE_MAX
] = {
1304 [SWAP_DEAD
] = "dead",
1305 [SWAP_ACTIVATING
] = "activating",
1306 [SWAP_ACTIVE
] = "active",
1307 [SWAP_DEACTIVATING
] = "deactivating",
1308 [SWAP_ACTIVATING_SIGTERM
] = "activating-sigterm",
1309 [SWAP_ACTIVATING_SIGKILL
] = "activating-sigkill",
1310 [SWAP_DEACTIVATING_SIGTERM
] = "deactivating-sigterm",
1311 [SWAP_DEACTIVATING_SIGKILL
] = "deactivating-sigkill",
1312 [SWAP_FAILED
] = "failed"
1315 DEFINE_STRING_TABLE_LOOKUP(swap_state
, SwapState
);
1317 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1318 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1319 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1322 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1324 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1325 [SWAP_SUCCESS
] = "success",
1326 [SWAP_FAILURE_RESOURCES
] = "resources",
1327 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1328 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1329 [SWAP_FAILURE_SIGNAL
] = "signal",
1330 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1333 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1335 const UnitVTable swap_vtable
= {
1336 .object_size
= sizeof(Swap
),
1343 .private_section
= "Swap",
1344 .exec_context_offset
= offsetof(Swap
, exec_context
),
1345 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1348 .no_instances
= true,
1354 .coldplug
= swap_coldplug
,
1358 .start
= swap_start
,
1363 .serialize
= swap_serialize
,
1364 .deserialize_item
= swap_deserialize_item
,
1366 .active_state
= swap_active_state
,
1367 .sub_state_to_string
= swap_sub_state_to_string
,
1369 .check_gc
= swap_check_gc
,
1371 .sigchld_event
= swap_sigchld_event
,
1372 .timer_event
= swap_timer_event
,
1374 .reset_failed
= swap_reset_failed
,
1376 .bus_interface
= "org.freedesktop.systemd1.Swap",
1377 .bus_message_handler
= bus_swap_message_handler
,
1378 .bus_invalidating_properties
= bus_swap_invalidating_properties
,
1379 .bus_set_property
= bus_swap_set_property
,
1380 .bus_commit_properties
= bus_swap_commit_properties
,
1382 .following
= swap_following
,
1383 .following_set
= swap_following_set
,
1385 .enumerate
= swap_enumerate
,
1386 .shutdown
= swap_shutdown
,
1388 .status_message_formats
= {
1389 .starting_stopping
= {
1390 [0] = "Activating swap %s...",
1391 [1] = "Deactivating swap %s...",
1393 .finished_start_job
= {
1394 [JOB_DONE
] = "Activated swap %s.",
1395 [JOB_FAILED
] = "Failed to activate swap %s.",
1396 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
1397 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1399 .finished_stop_job
= {
1400 [JOB_DONE
] = "Deactivated swap %s.",
1401 [JOB_FAILED
] = "Failed deactivating swap %s.",
1402 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",