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/>.
23 #include <sys/epoll.h>
29 #include "alloc-util.h"
30 #include "dbus-swap.h"
32 #include "exit-status.h"
34 #include "formats-util.h"
35 #include "fstab-util.h"
36 #include "parse-util.h"
37 #include "path-util.h"
38 #include "process-util.h"
40 #include "string-table.h"
41 #include "string-util.h"
43 #include "udev-util.h"
44 #include "unit-name.h"
48 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
49 [SWAP_DEAD
] = UNIT_INACTIVE
,
50 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
51 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
52 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
53 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
54 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
55 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
56 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
57 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
58 [SWAP_FAILED
] = UNIT_FAILED
61 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
62 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
64 static void swap_unset_proc_swaps(Swap
*s
) {
67 if (!s
->from_proc_swaps
)
70 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
72 s
->from_proc_swaps
= false;
75 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
82 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
86 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
89 first
= hashmap_get(swaps
, s
->devnode
);
91 LIST_REMOVE(same_devnode
, first
, s
);
93 hashmap_replace(swaps
, first
->devnode
, first
);
95 hashmap_remove(swaps
, s
->devnode
);
97 s
->devnode
= mfree(s
->devnode
);
101 s
->devnode
= strdup(devnode
);
105 first
= hashmap_get(swaps
, s
->devnode
);
106 LIST_PREPEND(same_devnode
, first
, s
);
108 return hashmap_replace(swaps
, first
->devnode
, first
);
114 static void swap_init(Unit
*u
) {
118 assert(UNIT(s
)->load_state
== UNIT_STUB
);
120 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
122 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
123 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
125 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
127 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
129 u
->ignore_on_isolate
= true;
132 static void swap_unwatch_control_pid(Swap
*s
) {
135 if (s
->control_pid
<= 0)
138 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
142 static void swap_done(Unit
*u
) {
147 swap_unset_proc_swaps(s
);
148 swap_set_devnode(s
, NULL
);
150 s
->what
= mfree(s
->what
);
151 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
152 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
154 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
155 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
156 s
->control_command
= NULL
;
158 swap_unwatch_control_pid(s
);
160 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
163 static int swap_arm_timer(Swap
*s
) {
168 if (s
->timeout_usec
<= 0) {
169 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
173 if (s
->timer_event_source
) {
174 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_usec
);
178 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
181 r
= sd_event_add_time(
182 UNIT(s
)->manager
->event
,
183 &s
->timer_event_source
,
185 now(CLOCK_MONOTONIC
) + s
->timeout_usec
, 0,
186 swap_dispatch_timer
, s
);
190 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
195 static int swap_add_device_links(Swap
*s
) {
201 if (!s
->from_fragment
)
204 if (is_device_path(s
->what
))
205 return unit_add_node_link(UNIT(s
), s
->what
, UNIT(s
)->manager
->running_as
== MANAGER_SYSTEM
);
207 /* File based swap devices need to be ordered after
208 * systemd-remount-fs.service, since they might need a
209 * writable file system. */
210 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
213 static int swap_add_default_dependencies(Swap
*s
) {
218 if (!UNIT(s
)->default_dependencies
)
221 if (UNIT(s
)->manager
->running_as
!= MANAGER_SYSTEM
)
224 if (detect_container() > 0)
227 /* swap units generated for the swap dev links are missing the
228 * ordering dep against the swap target. */
229 r
= unit_add_dependency_by_name(UNIT(s
), UNIT_BEFORE
, SPECIAL_SWAP_TARGET
, NULL
, true);
233 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
236 static int swap_verify(Swap
*s
) {
237 _cleanup_free_
char *e
= NULL
;
240 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
243 r
= unit_name_from_path(s
->what
, ".swap", &e
);
245 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
247 if (!unit_has_name(UNIT(s
), e
)) {
248 log_unit_error(UNIT(s
), "Value of What= and unit name do not match, not loading.");
252 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
253 log_unit_error(UNIT(s
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
260 static int swap_load_devnode(Swap
*s
) {
261 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
267 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
270 d
= udev_device_new_from_devnum(UNIT(s
)->manager
->udev
, 'b', st
.st_rdev
);
274 p
= udev_device_get_devnode(d
);
278 return swap_set_devnode(s
, p
);
281 static int swap_load(Unit
*u
) {
286 assert(u
->load_state
== UNIT_STUB
);
288 /* Load a .swap file */
289 r
= unit_load_fragment_and_dropin_optional(u
);
293 if (u
->load_state
== UNIT_LOADED
) {
295 if (UNIT(s
)->fragment_path
)
296 s
->from_fragment
= true;
299 if (s
->parameters_fragment
.what
)
300 s
->what
= strdup(s
->parameters_fragment
.what
);
301 else if (s
->parameters_proc_swaps
.what
)
302 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
304 r
= unit_name_to_path(u
->id
, &s
->what
);
313 path_kill_slashes(s
->what
);
315 if (!UNIT(s
)->description
) {
316 r
= unit_set_description(u
, s
->what
);
321 r
= unit_require_mounts_for(UNIT(s
), s
->what
);
325 r
= swap_add_device_links(s
);
329 r
= swap_load_devnode(s
);
333 r
= unit_patch_contexts(u
);
337 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
341 r
= unit_set_default_slice(u
);
345 r
= swap_add_default_dependencies(s
);
350 return swap_verify(s
);
353 static int swap_setup_unit(
356 const char *what_proc_swaps
,
360 _cleanup_free_
char *e
= NULL
;
368 assert(what_proc_swaps
);
370 r
= unit_name_from_path(what
, ".swap", &e
);
372 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
374 u
= manager_get_unit(m
, e
);
377 SWAP(u
)->from_proc_swaps
&&
378 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
)) {
379 log_error("Swap %s appeared twice with different device paths %s and %s", e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
386 u
= unit_new(m
, sizeof(Swap
));
390 r
= unit_add_name(u
, e
);
394 SWAP(u
)->what
= strdup(what
);
395 if (!SWAP(u
)->what
) {
400 unit_add_to_load_queue(u
);
404 p
= &SWAP(u
)->parameters_proc_swaps
;
407 p
->what
= strdup(what_proc_swaps
);
415 SWAP(u
)->is_active
= true;
416 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
419 SWAP(u
)->from_proc_swaps
= true;
421 p
->priority
= priority
;
423 unit_add_to_dbus_queue(u
);
427 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
435 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
436 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
437 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
444 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
448 /* If this is a block device, then let's add duplicates for
449 * all other names of this block device */
450 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
453 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
457 /* Add the main device node */
458 dn
= udev_device_get_devnode(d
);
459 if (dn
&& !streq(dn
, device
))
460 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
462 /* Add additional units for all symlinks */
463 first
= udev_device_get_devlinks_list_entry(d
);
464 udev_list_entry_foreach(item
, first
) {
467 /* Don't bother with the /dev/block links */
468 p
= udev_list_entry_get_name(item
);
470 if (streq(p
, device
))
473 if (path_startswith(p
, "/dev/block/"))
476 if (stat(p
, &st
) >= 0)
477 if (!S_ISBLK(st
.st_mode
) ||
478 st
.st_rdev
!= udev_device_get_devnum(d
))
481 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
487 static void swap_set_state(Swap
*s
, SwapState state
) {
493 old_state
= s
->state
;
496 if (state
!= SWAP_ACTIVATING
&&
497 state
!= SWAP_ACTIVATING_SIGTERM
&&
498 state
!= SWAP_ACTIVATING_SIGKILL
&&
499 state
!= SWAP_ACTIVATING_DONE
&&
500 state
!= SWAP_DEACTIVATING
&&
501 state
!= SWAP_DEACTIVATING_SIGTERM
&&
502 state
!= SWAP_DEACTIVATING_SIGKILL
) {
503 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
504 swap_unwatch_control_pid(s
);
505 s
->control_command
= NULL
;
506 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
509 if (state
!= old_state
)
510 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
512 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
514 /* If there other units for the same device node have a job
515 queued it might be worth checking again if it is runnable
516 now. This is necessary, since swap_start() refuses
517 operation with EAGAIN if there's already another job for
518 the same device node queued. */
519 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
520 if (UNIT(other
)->job
)
521 job_add_to_run_queue(UNIT(other
)->job
);
524 static int swap_coldplug(Unit
*u
) {
526 SwapState new_state
= SWAP_DEAD
;
530 assert(s
->state
== SWAP_DEAD
);
532 if (s
->deserialized_state
!= s
->state
)
533 new_state
= s
->deserialized_state
;
534 else if (s
->from_proc_swaps
)
535 new_state
= SWAP_ACTIVE
;
537 if (new_state
== s
->state
)
540 if (s
->control_pid
> 0 &&
541 pid_is_unwaited(s
->control_pid
) &&
544 SWAP_ACTIVATING_SIGTERM
,
545 SWAP_ACTIVATING_SIGKILL
,
546 SWAP_ACTIVATING_DONE
,
548 SWAP_DEACTIVATING_SIGTERM
,
549 SWAP_DEACTIVATING_SIGKILL
)) {
551 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
555 r
= swap_arm_timer(s
);
560 swap_set_state(s
, new_state
);
564 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
571 if (s
->from_proc_swaps
)
572 p
= &s
->parameters_proc_swaps
;
573 else if (s
->from_fragment
)
574 p
= &s
->parameters_fragment
;
582 "%sFrom /proc/swaps: %s\n"
583 "%sFrom fragment: %s\n",
584 prefix
, swap_state_to_string(s
->state
),
585 prefix
, swap_result_to_string(s
->result
),
587 prefix
, yes_no(s
->from_proc_swaps
),
588 prefix
, yes_no(s
->from_fragment
));
591 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
598 prefix
, strempty(p
->options
));
600 if (s
->control_pid
> 0)
602 "%sControl PID: "PID_FMT
"\n",
603 prefix
, s
->control_pid
);
605 exec_context_dump(&s
->exec_context
, f
, prefix
);
606 kill_context_dump(&s
->kill_context
, f
, prefix
);
609 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
612 ExecParameters exec_params
= {
613 .apply_permissions
= true,
614 .apply_chroot
= true,
615 .apply_tty_stdin
= true,
616 .bus_endpoint_fd
= -1,
626 (void) unit_realize_cgroup(UNIT(s
));
627 if (s
->reset_cpu_usage
) {
628 (void) unit_reset_cpu_usage(UNIT(s
));
629 s
->reset_cpu_usage
= false;
632 r
= unit_setup_exec_runtime(UNIT(s
));
636 r
= swap_arm_timer(s
);
640 exec_params
.environment
= UNIT(s
)->manager
->environment
;
641 exec_params
.confirm_spawn
= UNIT(s
)->manager
->confirm_spawn
;
642 exec_params
.cgroup_supported
= UNIT(s
)->manager
->cgroup_supported
;
643 exec_params
.cgroup_path
= UNIT(s
)->cgroup_path
;
644 exec_params
.cgroup_delegate
= s
->cgroup_context
.delegate
;
645 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(s
)->manager
);
647 r
= exec_spawn(UNIT(s
),
656 r
= unit_watch_pid(UNIT(s
), pid
);
658 /* FIXME: we need to do something here */
666 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
670 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
673 if (f
!= SWAP_SUCCESS
)
676 exec_runtime_destroy(s
->exec_runtime
);
677 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
679 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
681 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
684 static void swap_enter_active(Swap
*s
, SwapResult f
) {
687 if (f
!= SWAP_SUCCESS
)
690 swap_set_state(s
, SWAP_ACTIVE
);
693 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
698 if (f
!= SWAP_SUCCESS
)
701 r
= unit_kill_context(
704 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
705 KILL_KILL
: KILL_TERMINATE
,
713 r
= swap_arm_timer(s
);
717 swap_set_state(s
, state
);
718 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
719 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
720 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
721 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
723 swap_enter_dead(s
, SWAP_SUCCESS
);
728 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
729 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
732 static void swap_enter_activating(Swap
*s
) {
733 _cleanup_free_
char *opts
= NULL
;
738 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
739 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
741 if (s
->from_fragment
) {
744 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
746 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
747 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
748 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
750 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
751 if (s
->parameters_fragment
.options
)
752 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
754 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
760 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
764 if (s
->parameters_fragment
.options
|| opts
) {
765 r
= exec_command_append(s
->control_command
, "-o",
766 opts
? : s
->parameters_fragment
.options
, NULL
);
771 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
775 swap_unwatch_control_pid(s
);
777 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
781 swap_set_state(s
, SWAP_ACTIVATING
);
786 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
787 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
790 static void swap_enter_deactivating(Swap
*s
) {
795 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
796 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
798 r
= exec_command_set(s
->control_command
,
805 swap_unwatch_control_pid(s
);
807 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
811 swap_set_state(s
, SWAP_DEACTIVATING
);
816 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
817 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
820 static int swap_start(Unit
*u
) {
821 Swap
*s
= SWAP(u
), *other
;
825 /* We cannot fulfill this request right now, try again later
828 if (s
->state
== SWAP_DEACTIVATING
||
829 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
830 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
831 s
->state
== SWAP_ACTIVATING_SIGTERM
||
832 s
->state
== SWAP_ACTIVATING_SIGKILL
)
835 if (s
->state
== SWAP_ACTIVATING
)
838 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
840 if (detect_container() > 0)
843 /* If there's a job for another swap unit for the same node
844 * running, then let's not dispatch this one for now, and wait
845 * until that other job has finished. */
846 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
847 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
850 s
->result
= SWAP_SUCCESS
;
851 s
->reset_cpu_usage
= true;
853 swap_enter_activating(s
);
857 static int swap_stop(Unit
*u
) {
862 if (s
->state
== SWAP_DEACTIVATING
||
863 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
864 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
865 s
->state
== SWAP_ACTIVATING_SIGTERM
||
866 s
->state
== SWAP_ACTIVATING_SIGKILL
)
869 assert(s
->state
== SWAP_ACTIVATING
||
870 s
->state
== SWAP_ACTIVATING_DONE
||
871 s
->state
== SWAP_ACTIVE
);
873 if (detect_container() > 0)
876 swap_enter_deactivating(s
);
880 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
887 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
888 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
890 if (s
->control_pid
> 0)
891 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
893 if (s
->control_command_id
>= 0)
894 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
899 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
905 if (streq(key
, "state")) {
908 state
= swap_state_from_string(value
);
910 log_unit_debug(u
, "Failed to parse state value: %s", value
);
912 s
->deserialized_state
= state
;
913 } else if (streq(key
, "result")) {
916 f
= swap_result_from_string(value
);
918 log_unit_debug(u
, "Failed to parse result value: %s", value
);
919 else if (f
!= SWAP_SUCCESS
)
921 } else if (streq(key
, "control-pid")) {
924 if (parse_pid(value
, &pid
) < 0)
925 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
927 s
->control_pid
= pid
;
929 } else if (streq(key
, "control-command")) {
932 id
= swap_exec_command_from_string(value
);
934 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
936 s
->control_command_id
= id
;
937 s
->control_command
= s
->exec_command
+ id
;
940 log_unit_debug(u
, "Unknown serialization key: %s", key
);
945 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
948 return state_translation_table
[SWAP(u
)->state
];
951 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
954 return swap_state_to_string(SWAP(u
)->state
);
957 _pure_
static bool swap_check_gc(Unit
*u
) {
962 return s
->from_proc_swaps
;
965 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
972 if (pid
!= s
->control_pid
)
977 if (is_clean_exit(code
, status
, NULL
))
979 else if (code
== CLD_EXITED
)
980 f
= SWAP_FAILURE_EXIT_CODE
;
981 else if (code
== CLD_KILLED
)
982 f
= SWAP_FAILURE_SIGNAL
;
983 else if (code
== CLD_DUMPED
)
984 f
= SWAP_FAILURE_CORE_DUMP
;
986 assert_not_reached("Unknown code");
988 if (f
!= SWAP_SUCCESS
)
991 if (s
->control_command
) {
992 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
994 s
->control_command
= NULL
;
995 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
998 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
999 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
1003 case SWAP_ACTIVATING
:
1004 case SWAP_ACTIVATING_DONE
:
1005 case SWAP_ACTIVATING_SIGTERM
:
1006 case SWAP_ACTIVATING_SIGKILL
:
1008 if (f
== SWAP_SUCCESS
)
1009 swap_enter_active(s
, f
);
1011 swap_enter_dead(s
, f
);
1014 case SWAP_DEACTIVATING
:
1015 case SWAP_DEACTIVATING_SIGKILL
:
1016 case SWAP_DEACTIVATING_SIGTERM
:
1018 swap_enter_dead(s
, f
);
1022 assert_not_reached("Uh, control process died at wrong time.");
1025 /* Notify clients about changed exit status */
1026 unit_add_to_dbus_queue(u
);
1029 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1030 Swap
*s
= SWAP(userdata
);
1033 assert(s
->timer_event_source
== source
);
1037 case SWAP_ACTIVATING
:
1038 case SWAP_ACTIVATING_DONE
:
1039 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1040 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1043 case SWAP_DEACTIVATING
:
1044 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1045 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1048 case SWAP_ACTIVATING_SIGTERM
:
1049 if (s
->kill_context
.send_sigkill
) {
1050 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1051 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1053 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1054 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1058 case SWAP_DEACTIVATING_SIGTERM
:
1059 if (s
->kill_context
.send_sigkill
) {
1060 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1061 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1063 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1064 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1068 case SWAP_ACTIVATING_SIGKILL
:
1069 case SWAP_DEACTIVATING_SIGKILL
:
1070 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1071 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1075 assert_not_reached("Timeout at wrong time.");
1081 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1087 rewind(m
->proc_swaps
);
1089 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1092 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1095 k
= fscanf(m
->proc_swaps
,
1096 "%ms " /* device/file */
1097 "%*s " /* type of swap */
1098 "%*s " /* swap size */
1100 "%i\n", /* priority */
1106 log_warning("Failed to parse /proc/swaps:%u.", i
);
1110 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1113 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1115 k
= swap_process_new(m
, d
, prio
, set_flags
);
1123 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1124 Manager
*m
= userdata
;
1129 assert(revents
& EPOLLPRI
);
1131 r
= swap_load_proc_swaps(m
, true);
1133 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1135 /* Reset flags, just in case, for late calls */
1136 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1137 Swap
*swap
= SWAP(u
);
1139 swap
->is_active
= swap
->just_activated
= false;
1145 manager_dispatch_load_queue(m
);
1147 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1148 Swap
*swap
= SWAP(u
);
1150 if (!swap
->is_active
) {
1151 /* This has just been deactivated */
1153 swap_unset_proc_swaps(swap
);
1155 switch (swap
->state
) {
1158 swap_enter_dead(swap
, SWAP_SUCCESS
);
1163 swap_set_state(swap
, swap
->state
);
1168 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1170 } else if (swap
->just_activated
) {
1172 /* New swap entry */
1174 switch (swap
->state
) {
1178 swap_enter_active(swap
, SWAP_SUCCESS
);
1181 case SWAP_ACTIVATING
:
1182 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1186 /* Nothing really changed, but let's
1187 * issue an notification call
1188 * nonetheless, in case somebody is
1189 * waiting for this. */
1190 swap_set_state(swap
, swap
->state
);
1195 /* Reset the flags for later calls */
1196 swap
->is_active
= swap
->just_activated
= false;
1202 static Unit
*swap_following(Unit
*u
) {
1204 Swap
*other
, *first
= NULL
;
1208 /* If the user configured the swap through /etc/fstab or
1209 * a device unit, follow that. */
1211 if (s
->from_fragment
)
1214 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1215 if (other
->from_fragment
)
1218 /* Otherwise, make everybody follow the unit that's named after
1219 * the swap device in the kernel */
1221 if (streq_ptr(s
->what
, s
->devnode
))
1224 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1225 if (streq_ptr(other
->what
, other
->devnode
))
1228 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1229 if (streq_ptr(other
->what
, other
->devnode
))
1235 /* Fall back to the first on the list */
1239 static int swap_following_set(Unit
*u
, Set
**_set
) {
1240 Swap
*s
= SWAP(u
), *other
;
1247 if (LIST_JUST_US(same_devnode
, s
)) {
1252 set
= set_new(NULL
);
1256 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1257 r
= set_put(set
, other
);
1270 static void swap_shutdown(Manager
*m
) {
1273 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1275 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1277 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1280 static void swap_enumerate(Manager
*m
) {
1285 if (!m
->proc_swaps
) {
1286 m
->proc_swaps
= fopen("/proc/swaps", "re");
1287 if (!m
->proc_swaps
) {
1288 if (errno
== ENOENT
)
1289 log_debug("Not swap enabled, skipping enumeration");
1291 log_error_errno(errno
, "Failed to open /proc/swaps: %m");
1296 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1298 log_error_errno(r
, "Failed to watch /proc/swaps: %m");
1302 /* Dispatch this before we dispatch SIGCHLD, so that
1303 * we always get the events from /proc/swaps before
1304 * the SIGCHLD of /sbin/swapon. */
1305 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1307 log_error_errno(r
, "Failed to change /proc/swaps priority: %m");
1311 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1314 r
= swap_load_proc_swaps(m
, false);
1324 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1325 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1326 _cleanup_free_
char *e
= NULL
;
1334 dn
= udev_device_get_devnode(dev
);
1338 r
= unit_name_from_path(dn
, ".swap", &e
);
1342 s
= hashmap_get(m
->units
, e
);
1344 r
= swap_set_devnode(s
, dn
);
1346 first
= udev_device_get_devlinks_list_entry(dev
);
1347 udev_list_entry_foreach(item
, first
) {
1348 _cleanup_free_
char *n
= NULL
;
1351 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1355 s
= hashmap_get(m
->units
, n
);
1357 q
= swap_set_devnode(s
, dn
);
1366 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1371 dn
= udev_device_get_devnode(dev
);
1375 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1378 q
= swap_set_devnode(s
, NULL
);
1386 static void swap_reset_failed(Unit
*u
) {
1391 if (s
->state
== SWAP_FAILED
)
1392 swap_set_state(s
, SWAP_DEAD
);
1394 s
->result
= SWAP_SUCCESS
;
1397 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1398 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1401 static int swap_get_timeout(Unit
*u
, uint64_t *timeout
) {
1405 if (!s
->timer_event_source
)
1408 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
1415 static bool swap_supported(void) {
1416 static int supported
= -1;
1418 /* If swap support is not available in the kernel, or we are
1419 * running in a container we don't support swap units, and any
1420 * attempts to starting one should fail immediately. */
1424 access("/proc/swaps", F_OK
) >= 0 &&
1425 detect_container() <= 0;
1430 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1431 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1432 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1435 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1437 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1438 [SWAP_SUCCESS
] = "success",
1439 [SWAP_FAILURE_RESOURCES
] = "resources",
1440 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1441 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1442 [SWAP_FAILURE_SIGNAL
] = "signal",
1443 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1446 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1448 const UnitVTable swap_vtable
= {
1449 .object_size
= sizeof(Swap
),
1450 .exec_context_offset
= offsetof(Swap
, exec_context
),
1451 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1452 .kill_context_offset
= offsetof(Swap
, kill_context
),
1453 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1459 .private_section
= "Swap",
1462 .no_instances
= true,
1468 .coldplug
= swap_coldplug
,
1472 .start
= swap_start
,
1477 .get_timeout
= swap_get_timeout
,
1479 .serialize
= swap_serialize
,
1480 .deserialize_item
= swap_deserialize_item
,
1482 .active_state
= swap_active_state
,
1483 .sub_state_to_string
= swap_sub_state_to_string
,
1485 .check_gc
= swap_check_gc
,
1487 .sigchld_event
= swap_sigchld_event
,
1489 .reset_failed
= swap_reset_failed
,
1491 .bus_vtable
= bus_swap_vtable
,
1492 .bus_set_property
= bus_swap_set_property
,
1493 .bus_commit_properties
= bus_swap_commit_properties
,
1495 .following
= swap_following
,
1496 .following_set
= swap_following_set
,
1498 .enumerate
= swap_enumerate
,
1499 .shutdown
= swap_shutdown
,
1500 .supported
= swap_supported
,
1502 .status_message_formats
= {
1503 .starting_stopping
= {
1504 [0] = "Activating swap %s...",
1505 [1] = "Deactivating swap %s...",
1507 .finished_start_job
= {
1508 [JOB_DONE
] = "Activated swap %s.",
1509 [JOB_FAILED
] = "Failed to activate swap %s.",
1510 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1512 .finished_stop_job
= {
1513 [JOB_DONE
] = "Deactivated swap %s.",
1514 [JOB_FAILED
] = "Failed deactivating swap %s.",
1515 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",