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 "dbus-swap.h"
31 #include "exit-status.h"
32 #include "formats-util.h"
33 #include "fstab-util.h"
34 #include "path-util.h"
36 #include "string-util.h"
37 #include "udev-util.h"
38 #include "unit-name.h"
43 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
44 [SWAP_DEAD
] = UNIT_INACTIVE
,
45 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
46 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
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 int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
57 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
59 static void swap_unset_proc_swaps(Swap
*s
) {
62 if (!s
->from_proc_swaps
)
65 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
67 s
->from_proc_swaps
= false;
70 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
77 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
81 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
84 first
= hashmap_get(swaps
, s
->devnode
);
86 LIST_REMOVE(same_devnode
, first
, s
);
88 hashmap_replace(swaps
, first
->devnode
, first
);
90 hashmap_remove(swaps
, s
->devnode
);
92 s
->devnode
= mfree(s
->devnode
);
96 s
->devnode
= strdup(devnode
);
100 first
= hashmap_get(swaps
, s
->devnode
);
101 LIST_PREPEND(same_devnode
, first
, s
);
103 return hashmap_replace(swaps
, first
->devnode
, first
);
109 static void swap_init(Unit
*u
) {
113 assert(UNIT(s
)->load_state
== UNIT_STUB
);
115 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
117 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
118 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
120 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
122 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
124 u
->ignore_on_isolate
= true;
127 static void swap_unwatch_control_pid(Swap
*s
) {
130 if (s
->control_pid
<= 0)
133 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
137 static void swap_done(Unit
*u
) {
142 swap_unset_proc_swaps(s
);
143 swap_set_devnode(s
, NULL
);
145 s
->what
= mfree(s
->what
);
146 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
147 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
149 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
150 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
151 s
->control_command
= NULL
;
153 swap_unwatch_control_pid(s
);
155 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
158 static int swap_arm_timer(Swap
*s
) {
163 if (s
->timeout_usec
<= 0) {
164 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
168 if (s
->timer_event_source
) {
169 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_usec
);
173 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
176 r
= sd_event_add_time(
177 UNIT(s
)->manager
->event
,
178 &s
->timer_event_source
,
180 now(CLOCK_MONOTONIC
) + s
->timeout_usec
, 0,
181 swap_dispatch_timer
, s
);
185 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
190 static int swap_add_device_links(Swap
*s
) {
196 if (!s
->from_fragment
)
199 if (is_device_path(s
->what
))
200 return unit_add_node_link(UNIT(s
), s
->what
, UNIT(s
)->manager
->running_as
== MANAGER_SYSTEM
);
202 /* File based swap devices need to be ordered after
203 * systemd-remount-fs.service, since they might need a
204 * writable file system. */
205 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
208 static int swap_add_default_dependencies(Swap
*s
) {
211 if (UNIT(s
)->manager
->running_as
!= MANAGER_SYSTEM
)
214 if (detect_container() > 0)
217 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
220 static int swap_verify(Swap
*s
) {
221 _cleanup_free_
char *e
= NULL
;
224 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
227 r
= unit_name_from_path(s
->what
, ".swap", &e
);
229 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
231 if (!unit_has_name(UNIT(s
), e
)) {
232 log_unit_error(UNIT(s
), "Value of What= and unit name do not match, not loading.");
236 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
237 log_unit_error(UNIT(s
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
244 static int swap_load_devnode(Swap
*s
) {
245 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
251 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
254 d
= udev_device_new_from_devnum(UNIT(s
)->manager
->udev
, 'b', st
.st_rdev
);
258 p
= udev_device_get_devnode(d
);
262 return swap_set_devnode(s
, p
);
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
) {
279 if (UNIT(s
)->fragment_path
)
280 s
->from_fragment
= true;
283 if (s
->parameters_fragment
.what
)
284 s
->what
= strdup(s
->parameters_fragment
.what
);
285 else if (s
->parameters_proc_swaps
.what
)
286 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
288 r
= unit_name_to_path(u
->id
, &s
->what
);
297 path_kill_slashes(s
->what
);
299 if (!UNIT(s
)->description
) {
300 r
= unit_set_description(u
, s
->what
);
305 r
= unit_require_mounts_for(UNIT(s
), s
->what
);
309 r
= swap_add_device_links(s
);
313 r
= swap_load_devnode(s
);
317 r
= unit_patch_contexts(u
);
321 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
325 r
= unit_set_default_slice(u
);
329 if (UNIT(s
)->default_dependencies
) {
330 r
= swap_add_default_dependencies(s
);
336 return swap_verify(s
);
339 static int swap_setup_unit(
342 const char *what_proc_swaps
,
346 _cleanup_free_
char *e
= NULL
;
354 assert(what_proc_swaps
);
356 r
= unit_name_from_path(what
, ".swap", &e
);
358 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
360 u
= manager_get_unit(m
, e
);
363 SWAP(u
)->from_proc_swaps
&&
364 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
)) {
365 log_error("Swap %s appeared twice with different device paths %s and %s", e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
372 u
= unit_new(m
, sizeof(Swap
));
376 r
= unit_add_name(u
, e
);
380 SWAP(u
)->what
= strdup(what
);
381 if (!SWAP(u
)->what
) {
386 unit_add_to_load_queue(u
);
390 p
= &SWAP(u
)->parameters_proc_swaps
;
393 p
->what
= strdup(what_proc_swaps
);
401 SWAP(u
)->is_active
= true;
402 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
405 SWAP(u
)->from_proc_swaps
= true;
407 p
->priority
= priority
;
409 unit_add_to_dbus_queue(u
);
413 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
421 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
422 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
423 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
430 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
434 /* If this is a block device, then let's add duplicates for
435 * all other names of this block device */
436 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
439 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
443 /* Add the main device node */
444 dn
= udev_device_get_devnode(d
);
445 if (dn
&& !streq(dn
, device
))
446 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
448 /* Add additional units for all symlinks */
449 first
= udev_device_get_devlinks_list_entry(d
);
450 udev_list_entry_foreach(item
, first
) {
453 /* Don't bother with the /dev/block links */
454 p
= udev_list_entry_get_name(item
);
456 if (streq(p
, device
))
459 if (path_startswith(p
, "/dev/block/"))
462 if (stat(p
, &st
) >= 0)
463 if (!S_ISBLK(st
.st_mode
) ||
464 st
.st_rdev
!= udev_device_get_devnum(d
))
467 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
473 static void swap_set_state(Swap
*s
, SwapState state
) {
479 old_state
= s
->state
;
482 if (state
!= SWAP_ACTIVATING
&&
483 state
!= SWAP_ACTIVATING_SIGTERM
&&
484 state
!= SWAP_ACTIVATING_SIGKILL
&&
485 state
!= SWAP_ACTIVATING_DONE
&&
486 state
!= SWAP_DEACTIVATING
&&
487 state
!= SWAP_DEACTIVATING_SIGTERM
&&
488 state
!= SWAP_DEACTIVATING_SIGKILL
) {
489 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
490 swap_unwatch_control_pid(s
);
491 s
->control_command
= NULL
;
492 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
495 if (state
!= old_state
)
496 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
498 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
500 /* If there other units for the same device node have a job
501 queued it might be worth checking again if it is runnable
502 now. This is necessary, since swap_start() refuses
503 operation with EAGAIN if there's already another job for
504 the same device node queued. */
505 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
506 if (UNIT(other
)->job
)
507 job_add_to_run_queue(UNIT(other
)->job
);
510 static int swap_coldplug(Unit
*u
) {
512 SwapState new_state
= SWAP_DEAD
;
516 assert(s
->state
== SWAP_DEAD
);
518 if (s
->deserialized_state
!= s
->state
)
519 new_state
= s
->deserialized_state
;
520 else if (s
->from_proc_swaps
)
521 new_state
= SWAP_ACTIVE
;
523 if (new_state
== s
->state
)
526 if (new_state
== SWAP_ACTIVATING
||
527 new_state
== SWAP_ACTIVATING_SIGTERM
||
528 new_state
== SWAP_ACTIVATING_SIGKILL
||
529 new_state
== SWAP_ACTIVATING_DONE
||
530 new_state
== SWAP_DEACTIVATING
||
531 new_state
== SWAP_DEACTIVATING_SIGTERM
||
532 new_state
== SWAP_DEACTIVATING_SIGKILL
) {
534 if (s
->control_pid
<= 0)
537 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
541 r
= swap_arm_timer(s
);
546 swap_set_state(s
, new_state
);
550 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
557 if (s
->from_proc_swaps
)
558 p
= &s
->parameters_proc_swaps
;
559 else if (s
->from_fragment
)
560 p
= &s
->parameters_fragment
;
568 "%sFrom /proc/swaps: %s\n"
569 "%sFrom fragment: %s\n",
570 prefix
, swap_state_to_string(s
->state
),
571 prefix
, swap_result_to_string(s
->result
),
573 prefix
, yes_no(s
->from_proc_swaps
),
574 prefix
, yes_no(s
->from_fragment
));
577 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
584 prefix
, strempty(p
->options
));
586 if (s
->control_pid
> 0)
588 "%sControl PID: "PID_FMT
"\n",
589 prefix
, s
->control_pid
);
591 exec_context_dump(&s
->exec_context
, f
, prefix
);
592 kill_context_dump(&s
->kill_context
, f
, prefix
);
595 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
598 ExecParameters exec_params
= {
599 .apply_permissions
= true,
600 .apply_chroot
= true,
601 .apply_tty_stdin
= true,
602 .bus_endpoint_fd
= -1,
612 (void) unit_realize_cgroup(UNIT(s
));
613 if (s
->reset_cpu_usage
) {
614 (void) unit_reset_cpu_usage(UNIT(s
));
615 s
->reset_cpu_usage
= false;
618 r
= unit_setup_exec_runtime(UNIT(s
));
622 r
= swap_arm_timer(s
);
626 exec_params
.environment
= UNIT(s
)->manager
->environment
;
627 exec_params
.confirm_spawn
= UNIT(s
)->manager
->confirm_spawn
;
628 exec_params
.cgroup_supported
= UNIT(s
)->manager
->cgroup_supported
;
629 exec_params
.cgroup_path
= UNIT(s
)->cgroup_path
;
630 exec_params
.cgroup_delegate
= s
->cgroup_context
.delegate
;
631 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(s
)->manager
);
633 r
= exec_spawn(UNIT(s
),
642 r
= unit_watch_pid(UNIT(s
), pid
);
644 /* FIXME: we need to do something here */
652 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
656 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
659 if (f
!= SWAP_SUCCESS
)
662 exec_runtime_destroy(s
->exec_runtime
);
663 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
665 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
667 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
670 static void swap_enter_active(Swap
*s
, SwapResult f
) {
673 if (f
!= SWAP_SUCCESS
)
676 swap_set_state(s
, SWAP_ACTIVE
);
679 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
684 if (f
!= SWAP_SUCCESS
)
687 r
= unit_kill_context(
690 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
691 KILL_KILL
: KILL_TERMINATE
,
699 r
= swap_arm_timer(s
);
703 swap_set_state(s
, state
);
704 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
705 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
706 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
707 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
709 swap_enter_dead(s
, SWAP_SUCCESS
);
714 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
715 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
718 static void swap_enter_activating(Swap
*s
) {
719 _cleanup_free_
char *opts
= NULL
;
724 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
725 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
727 if (s
->from_fragment
) {
730 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
732 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
733 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
734 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
736 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
737 if (s
->parameters_fragment
.options
)
738 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
740 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
746 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
750 if (s
->parameters_fragment
.options
|| opts
) {
751 r
= exec_command_append(s
->control_command
, "-o",
752 opts
? : s
->parameters_fragment
.options
, NULL
);
757 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
761 swap_unwatch_control_pid(s
);
763 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
767 swap_set_state(s
, SWAP_ACTIVATING
);
772 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
773 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
776 static void swap_enter_deactivating(Swap
*s
) {
781 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
782 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
784 r
= exec_command_set(s
->control_command
,
791 swap_unwatch_control_pid(s
);
793 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
797 swap_set_state(s
, SWAP_DEACTIVATING
);
802 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
803 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
806 static int swap_start(Unit
*u
) {
807 Swap
*s
= SWAP(u
), *other
;
811 /* We cannot fulfill this request right now, try again later
814 if (s
->state
== SWAP_DEACTIVATING
||
815 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
816 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
817 s
->state
== SWAP_ACTIVATING_SIGTERM
||
818 s
->state
== SWAP_ACTIVATING_SIGKILL
)
821 if (s
->state
== SWAP_ACTIVATING
)
824 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
826 if (detect_container() > 0)
829 /* If there's a job for another swap unit for the same node
830 * running, then let's not dispatch this one for now, and wait
831 * until that other job has finished. */
832 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
833 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
836 s
->result
= SWAP_SUCCESS
;
837 s
->reset_cpu_usage
= true;
839 swap_enter_activating(s
);
843 static int swap_stop(Unit
*u
) {
848 if (s
->state
== SWAP_DEACTIVATING
||
849 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
850 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
851 s
->state
== SWAP_ACTIVATING_SIGTERM
||
852 s
->state
== SWAP_ACTIVATING_SIGKILL
)
855 assert(s
->state
== SWAP_ACTIVATING
||
856 s
->state
== SWAP_ACTIVATING_DONE
||
857 s
->state
== SWAP_ACTIVE
);
859 if (detect_container() > 0)
862 swap_enter_deactivating(s
);
866 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
873 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
874 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
876 if (s
->control_pid
> 0)
877 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
879 if (s
->control_command_id
>= 0)
880 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
885 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
891 if (streq(key
, "state")) {
894 state
= swap_state_from_string(value
);
896 log_unit_debug(u
, "Failed to parse state value: %s", value
);
898 s
->deserialized_state
= state
;
899 } else if (streq(key
, "result")) {
902 f
= swap_result_from_string(value
);
904 log_unit_debug(u
, "Failed to parse result value: %s", value
);
905 else if (f
!= SWAP_SUCCESS
)
907 } else if (streq(key
, "control-pid")) {
910 if (parse_pid(value
, &pid
) < 0)
911 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
913 s
->control_pid
= pid
;
915 } else if (streq(key
, "control-command")) {
918 id
= swap_exec_command_from_string(value
);
920 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
922 s
->control_command_id
= id
;
923 s
->control_command
= s
->exec_command
+ id
;
926 log_unit_debug(u
, "Unknown serialization key: %s", key
);
931 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
934 return state_translation_table
[SWAP(u
)->state
];
937 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
940 return swap_state_to_string(SWAP(u
)->state
);
943 _pure_
static bool swap_check_gc(Unit
*u
) {
948 return s
->from_proc_swaps
;
951 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
958 if (pid
!= s
->control_pid
)
963 if (is_clean_exit(code
, status
, NULL
))
965 else if (code
== CLD_EXITED
)
966 f
= SWAP_FAILURE_EXIT_CODE
;
967 else if (code
== CLD_KILLED
)
968 f
= SWAP_FAILURE_SIGNAL
;
969 else if (code
== CLD_DUMPED
)
970 f
= SWAP_FAILURE_CORE_DUMP
;
972 assert_not_reached("Unknown code");
974 if (f
!= SWAP_SUCCESS
)
977 if (s
->control_command
) {
978 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
980 s
->control_command
= NULL
;
981 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
984 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
985 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
989 case SWAP_ACTIVATING
:
990 case SWAP_ACTIVATING_DONE
:
991 case SWAP_ACTIVATING_SIGTERM
:
992 case SWAP_ACTIVATING_SIGKILL
:
994 if (f
== SWAP_SUCCESS
)
995 swap_enter_active(s
, f
);
997 swap_enter_dead(s
, f
);
1000 case SWAP_DEACTIVATING
:
1001 case SWAP_DEACTIVATING_SIGKILL
:
1002 case SWAP_DEACTIVATING_SIGTERM
:
1004 swap_enter_dead(s
, f
);
1008 assert_not_reached("Uh, control process died at wrong time.");
1011 /* Notify clients about changed exit status */
1012 unit_add_to_dbus_queue(u
);
1015 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1016 Swap
*s
= SWAP(userdata
);
1019 assert(s
->timer_event_source
== source
);
1023 case SWAP_ACTIVATING
:
1024 case SWAP_ACTIVATING_DONE
:
1025 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1026 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1029 case SWAP_DEACTIVATING
:
1030 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1031 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1034 case SWAP_ACTIVATING_SIGTERM
:
1035 if (s
->kill_context
.send_sigkill
) {
1036 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1037 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1039 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1040 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1044 case SWAP_DEACTIVATING_SIGTERM
:
1045 if (s
->kill_context
.send_sigkill
) {
1046 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1047 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1049 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1050 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1054 case SWAP_ACTIVATING_SIGKILL
:
1055 case SWAP_DEACTIVATING_SIGKILL
:
1056 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1057 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1061 assert_not_reached("Timeout at wrong time.");
1067 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1073 rewind(m
->proc_swaps
);
1075 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1078 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1081 k
= fscanf(m
->proc_swaps
,
1082 "%ms " /* device/file */
1083 "%*s " /* type of swap */
1084 "%*s " /* swap size */
1086 "%i\n", /* priority */
1092 log_warning("Failed to parse /proc/swaps:%u.", i
);
1096 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1099 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1101 k
= swap_process_new(m
, d
, prio
, set_flags
);
1109 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1110 Manager
*m
= userdata
;
1115 assert(revents
& EPOLLPRI
);
1117 r
= swap_load_proc_swaps(m
, true);
1119 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1121 /* Reset flags, just in case, for late calls */
1122 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1123 Swap
*swap
= SWAP(u
);
1125 swap
->is_active
= swap
->just_activated
= false;
1131 manager_dispatch_load_queue(m
);
1133 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1134 Swap
*swap
= SWAP(u
);
1136 if (!swap
->is_active
) {
1137 /* This has just been deactivated */
1139 swap_unset_proc_swaps(swap
);
1141 switch (swap
->state
) {
1144 swap_enter_dead(swap
, SWAP_SUCCESS
);
1149 swap_set_state(swap
, swap
->state
);
1154 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1156 } else if (swap
->just_activated
) {
1158 /* New swap entry */
1160 switch (swap
->state
) {
1164 swap_enter_active(swap
, SWAP_SUCCESS
);
1167 case SWAP_ACTIVATING
:
1168 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1172 /* Nothing really changed, but let's
1173 * issue an notification call
1174 * nonetheless, in case somebody is
1175 * waiting for this. */
1176 swap_set_state(swap
, swap
->state
);
1181 /* Reset the flags for later calls */
1182 swap
->is_active
= swap
->just_activated
= false;
1188 static Unit
*swap_following(Unit
*u
) {
1190 Swap
*other
, *first
= NULL
;
1194 /* If the user configured the swap through /etc/fstab or
1195 * a device unit, follow that. */
1197 if (s
->from_fragment
)
1200 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1201 if (other
->from_fragment
)
1204 /* Otherwise make everybody follow the unit that's named after
1205 * the swap device in the kernel */
1207 if (streq_ptr(s
->what
, s
->devnode
))
1210 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1211 if (streq_ptr(other
->what
, other
->devnode
))
1214 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1215 if (streq_ptr(other
->what
, other
->devnode
))
1221 /* Fall back to the first on the list */
1225 static int swap_following_set(Unit
*u
, Set
**_set
) {
1226 Swap
*s
= SWAP(u
), *other
;
1233 if (LIST_JUST_US(same_devnode
, s
)) {
1238 set
= set_new(NULL
);
1242 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1243 r
= set_put(set
, other
);
1256 static void swap_shutdown(Manager
*m
) {
1259 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1261 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1263 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1266 static int swap_enumerate(Manager
*m
) {
1271 if (!m
->proc_swaps
) {
1272 m
->proc_swaps
= fopen("/proc/swaps", "re");
1274 return errno
== ENOENT
? 0 : -errno
;
1276 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1280 /* Dispatch this before we dispatch SIGCHLD, so that
1281 * we always get the events from /proc/swaps before
1282 * the SIGCHLD of /sbin/swapon. */
1283 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1287 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1290 r
= swap_load_proc_swaps(m
, false);
1301 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1302 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1303 _cleanup_free_
char *e
= NULL
;
1311 dn
= udev_device_get_devnode(dev
);
1315 r
= unit_name_from_path(dn
, ".swap", &e
);
1319 s
= hashmap_get(m
->units
, e
);
1321 r
= swap_set_devnode(s
, dn
);
1323 first
= udev_device_get_devlinks_list_entry(dev
);
1324 udev_list_entry_foreach(item
, first
) {
1325 _cleanup_free_
char *n
= NULL
;
1328 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1332 s
= hashmap_get(m
->units
, n
);
1334 q
= swap_set_devnode(s
, dn
);
1343 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1348 dn
= udev_device_get_devnode(dev
);
1352 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1355 q
= swap_set_devnode(s
, NULL
);
1363 static void swap_reset_failed(Unit
*u
) {
1368 if (s
->state
== SWAP_FAILED
)
1369 swap_set_state(s
, SWAP_DEAD
);
1371 s
->result
= SWAP_SUCCESS
;
1374 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1375 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1378 static int swap_get_timeout(Unit
*u
, uint64_t *timeout
) {
1382 if (!s
->timer_event_source
)
1385 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
1392 static bool swap_supported(void) {
1393 static int supported
= -1;
1395 /* If swap support is not available in the kernel, or we are
1396 * running in a container we don't support swap units, and any
1397 * attempts to starting one should fail immediately. */
1401 access("/proc/swaps", F_OK
) >= 0 &&
1402 detect_container() <= 0;
1407 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1408 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1409 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1412 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1414 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1415 [SWAP_SUCCESS
] = "success",
1416 [SWAP_FAILURE_RESOURCES
] = "resources",
1417 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1418 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1419 [SWAP_FAILURE_SIGNAL
] = "signal",
1420 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1423 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1425 const UnitVTable swap_vtable
= {
1426 .object_size
= sizeof(Swap
),
1427 .exec_context_offset
= offsetof(Swap
, exec_context
),
1428 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1429 .kill_context_offset
= offsetof(Swap
, kill_context
),
1430 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1436 .private_section
= "Swap",
1439 .no_instances
= true,
1445 .coldplug
= swap_coldplug
,
1449 .start
= swap_start
,
1454 .get_timeout
= swap_get_timeout
,
1456 .serialize
= swap_serialize
,
1457 .deserialize_item
= swap_deserialize_item
,
1459 .active_state
= swap_active_state
,
1460 .sub_state_to_string
= swap_sub_state_to_string
,
1462 .check_gc
= swap_check_gc
,
1464 .sigchld_event
= swap_sigchld_event
,
1466 .reset_failed
= swap_reset_failed
,
1468 .bus_vtable
= bus_swap_vtable
,
1469 .bus_set_property
= bus_swap_set_property
,
1470 .bus_commit_properties
= bus_swap_commit_properties
,
1472 .following
= swap_following
,
1473 .following_set
= swap_following_set
,
1475 .enumerate
= swap_enumerate
,
1476 .shutdown
= swap_shutdown
,
1477 .supported
= swap_supported
,
1479 .status_message_formats
= {
1480 .starting_stopping
= {
1481 [0] = "Activating swap %s...",
1482 [1] = "Deactivating swap %s...",
1484 .finished_start_job
= {
1485 [JOB_DONE
] = "Activated swap %s.",
1486 [JOB_FAILED
] = "Failed to activate swap %s.",
1487 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1489 .finished_stop_job
= {
1490 [JOB_DONE
] = "Deactivated swap %s.",
1491 [JOB_FAILED
] = "Failed deactivating swap %s.",
1492 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",