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"
33 #include "formats-util.h"
34 #include "fstab-util.h"
35 #include "parse-util.h"
36 #include "path-util.h"
38 #include "string-util.h"
40 #include "udev-util.h"
41 #include "unit-name.h"
45 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
46 [SWAP_DEAD
] = UNIT_INACTIVE
,
47 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
48 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
49 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
50 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
51 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
52 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
53 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
54 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
55 [SWAP_FAILED
] = UNIT_FAILED
58 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
59 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
61 static void swap_unset_proc_swaps(Swap
*s
) {
64 if (!s
->from_proc_swaps
)
67 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
69 s
->from_proc_swaps
= false;
72 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
79 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
83 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
86 first
= hashmap_get(swaps
, s
->devnode
);
88 LIST_REMOVE(same_devnode
, first
, s
);
90 hashmap_replace(swaps
, first
->devnode
, first
);
92 hashmap_remove(swaps
, s
->devnode
);
94 s
->devnode
= mfree(s
->devnode
);
98 s
->devnode
= strdup(devnode
);
102 first
= hashmap_get(swaps
, s
->devnode
);
103 LIST_PREPEND(same_devnode
, first
, s
);
105 return hashmap_replace(swaps
, first
->devnode
, first
);
111 static void swap_init(Unit
*u
) {
115 assert(UNIT(s
)->load_state
== UNIT_STUB
);
117 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
119 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
120 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
122 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
124 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
126 u
->ignore_on_isolate
= true;
129 static void swap_unwatch_control_pid(Swap
*s
) {
132 if (s
->control_pid
<= 0)
135 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
139 static void swap_done(Unit
*u
) {
144 swap_unset_proc_swaps(s
);
145 swap_set_devnode(s
, NULL
);
147 s
->what
= mfree(s
->what
);
148 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
149 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
151 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
152 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
153 s
->control_command
= NULL
;
155 swap_unwatch_control_pid(s
);
157 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
160 static int swap_arm_timer(Swap
*s
) {
165 if (s
->timeout_usec
<= 0) {
166 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
170 if (s
->timer_event_source
) {
171 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_usec
);
175 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
178 r
= sd_event_add_time(
179 UNIT(s
)->manager
->event
,
180 &s
->timer_event_source
,
182 now(CLOCK_MONOTONIC
) + s
->timeout_usec
, 0,
183 swap_dispatch_timer
, s
);
187 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
192 static int swap_add_device_links(Swap
*s
) {
198 if (!s
->from_fragment
)
201 if (is_device_path(s
->what
))
202 return unit_add_node_link(UNIT(s
), s
->what
, UNIT(s
)->manager
->running_as
== MANAGER_SYSTEM
);
204 /* File based swap devices need to be ordered after
205 * systemd-remount-fs.service, since they might need a
206 * writable file system. */
207 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
210 static int swap_add_default_dependencies(Swap
*s
) {
213 if (UNIT(s
)->manager
->running_as
!= MANAGER_SYSTEM
)
216 if (detect_container() > 0)
219 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
222 static int swap_verify(Swap
*s
) {
223 _cleanup_free_
char *e
= NULL
;
226 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
229 r
= unit_name_from_path(s
->what
, ".swap", &e
);
231 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
233 if (!unit_has_name(UNIT(s
), e
)) {
234 log_unit_error(UNIT(s
), "Value of What= and unit name do not match, not loading.");
238 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
239 log_unit_error(UNIT(s
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
246 static int swap_load_devnode(Swap
*s
) {
247 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
253 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
256 d
= udev_device_new_from_devnum(UNIT(s
)->manager
->udev
, 'b', st
.st_rdev
);
260 p
= udev_device_get_devnode(d
);
264 return swap_set_devnode(s
, p
);
267 static int swap_load(Unit
*u
) {
272 assert(u
->load_state
== UNIT_STUB
);
274 /* Load a .swap file */
275 r
= unit_load_fragment_and_dropin_optional(u
);
279 if (u
->load_state
== UNIT_LOADED
) {
281 if (UNIT(s
)->fragment_path
)
282 s
->from_fragment
= true;
285 if (s
->parameters_fragment
.what
)
286 s
->what
= strdup(s
->parameters_fragment
.what
);
287 else if (s
->parameters_proc_swaps
.what
)
288 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
290 r
= unit_name_to_path(u
->id
, &s
->what
);
299 path_kill_slashes(s
->what
);
301 if (!UNIT(s
)->description
) {
302 r
= unit_set_description(u
, s
->what
);
307 r
= unit_require_mounts_for(UNIT(s
), s
->what
);
311 r
= swap_add_device_links(s
);
315 r
= swap_load_devnode(s
);
319 r
= unit_patch_contexts(u
);
323 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
327 r
= unit_set_default_slice(u
);
331 if (UNIT(s
)->default_dependencies
) {
332 r
= swap_add_default_dependencies(s
);
338 return swap_verify(s
);
341 static int swap_setup_unit(
344 const char *what_proc_swaps
,
348 _cleanup_free_
char *e
= NULL
;
356 assert(what_proc_swaps
);
358 r
= unit_name_from_path(what
, ".swap", &e
);
360 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
362 u
= manager_get_unit(m
, e
);
365 SWAP(u
)->from_proc_swaps
&&
366 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
)) {
367 log_error("Swap %s appeared twice with different device paths %s and %s", e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
374 u
= unit_new(m
, sizeof(Swap
));
378 r
= unit_add_name(u
, e
);
382 SWAP(u
)->what
= strdup(what
);
383 if (!SWAP(u
)->what
) {
388 unit_add_to_load_queue(u
);
392 p
= &SWAP(u
)->parameters_proc_swaps
;
395 p
->what
= strdup(what_proc_swaps
);
403 SWAP(u
)->is_active
= true;
404 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
407 SWAP(u
)->from_proc_swaps
= true;
409 p
->priority
= priority
;
411 unit_add_to_dbus_queue(u
);
415 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
423 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
424 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
425 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
432 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
436 /* If this is a block device, then let's add duplicates for
437 * all other names of this block device */
438 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
441 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
445 /* Add the main device node */
446 dn
= udev_device_get_devnode(d
);
447 if (dn
&& !streq(dn
, device
))
448 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
450 /* Add additional units for all symlinks */
451 first
= udev_device_get_devlinks_list_entry(d
);
452 udev_list_entry_foreach(item
, first
) {
455 /* Don't bother with the /dev/block links */
456 p
= udev_list_entry_get_name(item
);
458 if (streq(p
, device
))
461 if (path_startswith(p
, "/dev/block/"))
464 if (stat(p
, &st
) >= 0)
465 if (!S_ISBLK(st
.st_mode
) ||
466 st
.st_rdev
!= udev_device_get_devnum(d
))
469 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
475 static void swap_set_state(Swap
*s
, SwapState state
) {
481 old_state
= s
->state
;
484 if (state
!= SWAP_ACTIVATING
&&
485 state
!= SWAP_ACTIVATING_SIGTERM
&&
486 state
!= SWAP_ACTIVATING_SIGKILL
&&
487 state
!= SWAP_ACTIVATING_DONE
&&
488 state
!= SWAP_DEACTIVATING
&&
489 state
!= SWAP_DEACTIVATING_SIGTERM
&&
490 state
!= SWAP_DEACTIVATING_SIGKILL
) {
491 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
492 swap_unwatch_control_pid(s
);
493 s
->control_command
= NULL
;
494 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
497 if (state
!= old_state
)
498 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
500 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
502 /* If there other units for the same device node have a job
503 queued it might be worth checking again if it is runnable
504 now. This is necessary, since swap_start() refuses
505 operation with EAGAIN if there's already another job for
506 the same device node queued. */
507 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
508 if (UNIT(other
)->job
)
509 job_add_to_run_queue(UNIT(other
)->job
);
512 static int swap_coldplug(Unit
*u
) {
514 SwapState new_state
= SWAP_DEAD
;
518 assert(s
->state
== SWAP_DEAD
);
520 if (s
->deserialized_state
!= s
->state
)
521 new_state
= s
->deserialized_state
;
522 else if (s
->from_proc_swaps
)
523 new_state
= SWAP_ACTIVE
;
525 if (new_state
== s
->state
)
528 if (new_state
== SWAP_ACTIVATING
||
529 new_state
== SWAP_ACTIVATING_SIGTERM
||
530 new_state
== SWAP_ACTIVATING_SIGKILL
||
531 new_state
== SWAP_ACTIVATING_DONE
||
532 new_state
== SWAP_DEACTIVATING
||
533 new_state
== SWAP_DEACTIVATING_SIGTERM
||
534 new_state
== SWAP_DEACTIVATING_SIGKILL
) {
536 if (s
->control_pid
<= 0)
539 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
543 r
= swap_arm_timer(s
);
548 swap_set_state(s
, new_state
);
552 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
559 if (s
->from_proc_swaps
)
560 p
= &s
->parameters_proc_swaps
;
561 else if (s
->from_fragment
)
562 p
= &s
->parameters_fragment
;
570 "%sFrom /proc/swaps: %s\n"
571 "%sFrom fragment: %s\n",
572 prefix
, swap_state_to_string(s
->state
),
573 prefix
, swap_result_to_string(s
->result
),
575 prefix
, yes_no(s
->from_proc_swaps
),
576 prefix
, yes_no(s
->from_fragment
));
579 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
586 prefix
, strempty(p
->options
));
588 if (s
->control_pid
> 0)
590 "%sControl PID: "PID_FMT
"\n",
591 prefix
, s
->control_pid
);
593 exec_context_dump(&s
->exec_context
, f
, prefix
);
594 kill_context_dump(&s
->kill_context
, f
, prefix
);
597 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
600 ExecParameters exec_params
= {
601 .apply_permissions
= true,
602 .apply_chroot
= true,
603 .apply_tty_stdin
= true,
604 .bus_endpoint_fd
= -1,
614 (void) unit_realize_cgroup(UNIT(s
));
615 if (s
->reset_cpu_usage
) {
616 (void) unit_reset_cpu_usage(UNIT(s
));
617 s
->reset_cpu_usage
= false;
620 r
= unit_setup_exec_runtime(UNIT(s
));
624 r
= swap_arm_timer(s
);
628 exec_params
.environment
= UNIT(s
)->manager
->environment
;
629 exec_params
.confirm_spawn
= UNIT(s
)->manager
->confirm_spawn
;
630 exec_params
.cgroup_supported
= UNIT(s
)->manager
->cgroup_supported
;
631 exec_params
.cgroup_path
= UNIT(s
)->cgroup_path
;
632 exec_params
.cgroup_delegate
= s
->cgroup_context
.delegate
;
633 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(s
)->manager
);
635 r
= exec_spawn(UNIT(s
),
644 r
= unit_watch_pid(UNIT(s
), pid
);
646 /* FIXME: we need to do something here */
654 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
658 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
661 if (f
!= SWAP_SUCCESS
)
664 exec_runtime_destroy(s
->exec_runtime
);
665 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
667 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
669 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
672 static void swap_enter_active(Swap
*s
, SwapResult f
) {
675 if (f
!= SWAP_SUCCESS
)
678 swap_set_state(s
, SWAP_ACTIVE
);
681 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
686 if (f
!= SWAP_SUCCESS
)
689 r
= unit_kill_context(
692 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
693 KILL_KILL
: KILL_TERMINATE
,
701 r
= swap_arm_timer(s
);
705 swap_set_state(s
, state
);
706 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
707 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
708 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
709 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
711 swap_enter_dead(s
, SWAP_SUCCESS
);
716 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
717 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
720 static void swap_enter_activating(Swap
*s
) {
721 _cleanup_free_
char *opts
= NULL
;
726 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
727 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
729 if (s
->from_fragment
) {
732 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
734 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
735 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
736 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
738 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
739 if (s
->parameters_fragment
.options
)
740 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
742 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
748 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
752 if (s
->parameters_fragment
.options
|| opts
) {
753 r
= exec_command_append(s
->control_command
, "-o",
754 opts
? : s
->parameters_fragment
.options
, NULL
);
759 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
763 swap_unwatch_control_pid(s
);
765 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
769 swap_set_state(s
, SWAP_ACTIVATING
);
774 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
775 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
778 static void swap_enter_deactivating(Swap
*s
) {
783 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
784 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
786 r
= exec_command_set(s
->control_command
,
793 swap_unwatch_control_pid(s
);
795 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
799 swap_set_state(s
, SWAP_DEACTIVATING
);
804 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
805 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
808 static int swap_start(Unit
*u
) {
809 Swap
*s
= SWAP(u
), *other
;
813 /* We cannot fulfill this request right now, try again later
816 if (s
->state
== SWAP_DEACTIVATING
||
817 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
818 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
819 s
->state
== SWAP_ACTIVATING_SIGTERM
||
820 s
->state
== SWAP_ACTIVATING_SIGKILL
)
823 if (s
->state
== SWAP_ACTIVATING
)
826 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
828 if (detect_container() > 0)
831 /* If there's a job for another swap unit for the same node
832 * running, then let's not dispatch this one for now, and wait
833 * until that other job has finished. */
834 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
835 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
838 s
->result
= SWAP_SUCCESS
;
839 s
->reset_cpu_usage
= true;
841 swap_enter_activating(s
);
845 static int swap_stop(Unit
*u
) {
850 if (s
->state
== SWAP_DEACTIVATING
||
851 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
852 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
853 s
->state
== SWAP_ACTIVATING_SIGTERM
||
854 s
->state
== SWAP_ACTIVATING_SIGKILL
)
857 assert(s
->state
== SWAP_ACTIVATING
||
858 s
->state
== SWAP_ACTIVATING_DONE
||
859 s
->state
== SWAP_ACTIVE
);
861 if (detect_container() > 0)
864 swap_enter_deactivating(s
);
868 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
875 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
876 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
878 if (s
->control_pid
> 0)
879 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
881 if (s
->control_command_id
>= 0)
882 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
887 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
893 if (streq(key
, "state")) {
896 state
= swap_state_from_string(value
);
898 log_unit_debug(u
, "Failed to parse state value: %s", value
);
900 s
->deserialized_state
= state
;
901 } else if (streq(key
, "result")) {
904 f
= swap_result_from_string(value
);
906 log_unit_debug(u
, "Failed to parse result value: %s", value
);
907 else if (f
!= SWAP_SUCCESS
)
909 } else if (streq(key
, "control-pid")) {
912 if (parse_pid(value
, &pid
) < 0)
913 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
915 s
->control_pid
= pid
;
917 } else if (streq(key
, "control-command")) {
920 id
= swap_exec_command_from_string(value
);
922 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
924 s
->control_command_id
= id
;
925 s
->control_command
= s
->exec_command
+ id
;
928 log_unit_debug(u
, "Unknown serialization key: %s", key
);
933 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
936 return state_translation_table
[SWAP(u
)->state
];
939 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
942 return swap_state_to_string(SWAP(u
)->state
);
945 _pure_
static bool swap_check_gc(Unit
*u
) {
950 return s
->from_proc_swaps
;
953 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
960 if (pid
!= s
->control_pid
)
965 if (is_clean_exit(code
, status
, NULL
))
967 else if (code
== CLD_EXITED
)
968 f
= SWAP_FAILURE_EXIT_CODE
;
969 else if (code
== CLD_KILLED
)
970 f
= SWAP_FAILURE_SIGNAL
;
971 else if (code
== CLD_DUMPED
)
972 f
= SWAP_FAILURE_CORE_DUMP
;
974 assert_not_reached("Unknown code");
976 if (f
!= SWAP_SUCCESS
)
979 if (s
->control_command
) {
980 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
982 s
->control_command
= NULL
;
983 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
986 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
987 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
991 case SWAP_ACTIVATING
:
992 case SWAP_ACTIVATING_DONE
:
993 case SWAP_ACTIVATING_SIGTERM
:
994 case SWAP_ACTIVATING_SIGKILL
:
996 if (f
== SWAP_SUCCESS
)
997 swap_enter_active(s
, f
);
999 swap_enter_dead(s
, f
);
1002 case SWAP_DEACTIVATING
:
1003 case SWAP_DEACTIVATING_SIGKILL
:
1004 case SWAP_DEACTIVATING_SIGTERM
:
1006 swap_enter_dead(s
, f
);
1010 assert_not_reached("Uh, control process died at wrong time.");
1013 /* Notify clients about changed exit status */
1014 unit_add_to_dbus_queue(u
);
1017 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1018 Swap
*s
= SWAP(userdata
);
1021 assert(s
->timer_event_source
== source
);
1025 case SWAP_ACTIVATING
:
1026 case SWAP_ACTIVATING_DONE
:
1027 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1028 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1031 case SWAP_DEACTIVATING
:
1032 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1033 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1036 case SWAP_ACTIVATING_SIGTERM
:
1037 if (s
->kill_context
.send_sigkill
) {
1038 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1039 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1041 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1042 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1046 case SWAP_DEACTIVATING_SIGTERM
:
1047 if (s
->kill_context
.send_sigkill
) {
1048 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1049 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1051 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1052 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1056 case SWAP_ACTIVATING_SIGKILL
:
1057 case SWAP_DEACTIVATING_SIGKILL
:
1058 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1059 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1063 assert_not_reached("Timeout at wrong time.");
1069 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1075 rewind(m
->proc_swaps
);
1077 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1080 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1083 k
= fscanf(m
->proc_swaps
,
1084 "%ms " /* device/file */
1085 "%*s " /* type of swap */
1086 "%*s " /* swap size */
1088 "%i\n", /* priority */
1094 log_warning("Failed to parse /proc/swaps:%u.", i
);
1098 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1101 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1103 k
= swap_process_new(m
, d
, prio
, set_flags
);
1111 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1112 Manager
*m
= userdata
;
1117 assert(revents
& EPOLLPRI
);
1119 r
= swap_load_proc_swaps(m
, true);
1121 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1123 /* Reset flags, just in case, for late calls */
1124 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1125 Swap
*swap
= SWAP(u
);
1127 swap
->is_active
= swap
->just_activated
= false;
1133 manager_dispatch_load_queue(m
);
1135 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1136 Swap
*swap
= SWAP(u
);
1138 if (!swap
->is_active
) {
1139 /* This has just been deactivated */
1141 swap_unset_proc_swaps(swap
);
1143 switch (swap
->state
) {
1146 swap_enter_dead(swap
, SWAP_SUCCESS
);
1151 swap_set_state(swap
, swap
->state
);
1156 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1158 } else if (swap
->just_activated
) {
1160 /* New swap entry */
1162 switch (swap
->state
) {
1166 swap_enter_active(swap
, SWAP_SUCCESS
);
1169 case SWAP_ACTIVATING
:
1170 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1174 /* Nothing really changed, but let's
1175 * issue an notification call
1176 * nonetheless, in case somebody is
1177 * waiting for this. */
1178 swap_set_state(swap
, swap
->state
);
1183 /* Reset the flags for later calls */
1184 swap
->is_active
= swap
->just_activated
= false;
1190 static Unit
*swap_following(Unit
*u
) {
1192 Swap
*other
, *first
= NULL
;
1196 /* If the user configured the swap through /etc/fstab or
1197 * a device unit, follow that. */
1199 if (s
->from_fragment
)
1202 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1203 if (other
->from_fragment
)
1206 /* Otherwise make everybody follow the unit that's named after
1207 * the swap device in the kernel */
1209 if (streq_ptr(s
->what
, s
->devnode
))
1212 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1213 if (streq_ptr(other
->what
, other
->devnode
))
1216 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1217 if (streq_ptr(other
->what
, other
->devnode
))
1223 /* Fall back to the first on the list */
1227 static int swap_following_set(Unit
*u
, Set
**_set
) {
1228 Swap
*s
= SWAP(u
), *other
;
1235 if (LIST_JUST_US(same_devnode
, s
)) {
1240 set
= set_new(NULL
);
1244 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1245 r
= set_put(set
, other
);
1258 static void swap_shutdown(Manager
*m
) {
1261 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1263 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1265 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1268 static int swap_enumerate(Manager
*m
) {
1273 if (!m
->proc_swaps
) {
1274 m
->proc_swaps
= fopen("/proc/swaps", "re");
1276 return errno
== ENOENT
? 0 : -errno
;
1278 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1282 /* Dispatch this before we dispatch SIGCHLD, so that
1283 * we always get the events from /proc/swaps before
1284 * the SIGCHLD of /sbin/swapon. */
1285 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1289 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1292 r
= swap_load_proc_swaps(m
, false);
1303 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1304 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1305 _cleanup_free_
char *e
= NULL
;
1313 dn
= udev_device_get_devnode(dev
);
1317 r
= unit_name_from_path(dn
, ".swap", &e
);
1321 s
= hashmap_get(m
->units
, e
);
1323 r
= swap_set_devnode(s
, dn
);
1325 first
= udev_device_get_devlinks_list_entry(dev
);
1326 udev_list_entry_foreach(item
, first
) {
1327 _cleanup_free_
char *n
= NULL
;
1330 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1334 s
= hashmap_get(m
->units
, n
);
1336 q
= swap_set_devnode(s
, dn
);
1345 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1350 dn
= udev_device_get_devnode(dev
);
1354 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1357 q
= swap_set_devnode(s
, NULL
);
1365 static void swap_reset_failed(Unit
*u
) {
1370 if (s
->state
== SWAP_FAILED
)
1371 swap_set_state(s
, SWAP_DEAD
);
1373 s
->result
= SWAP_SUCCESS
;
1376 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1377 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1380 static int swap_get_timeout(Unit
*u
, uint64_t *timeout
) {
1384 if (!s
->timer_event_source
)
1387 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
1394 static bool swap_supported(void) {
1395 static int supported
= -1;
1397 /* If swap support is not available in the kernel, or we are
1398 * running in a container we don't support swap units, and any
1399 * attempts to starting one should fail immediately. */
1403 access("/proc/swaps", F_OK
) >= 0 &&
1404 detect_container() <= 0;
1409 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1410 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1411 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1414 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1416 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1417 [SWAP_SUCCESS
] = "success",
1418 [SWAP_FAILURE_RESOURCES
] = "resources",
1419 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1420 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1421 [SWAP_FAILURE_SIGNAL
] = "signal",
1422 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1425 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1427 const UnitVTable swap_vtable
= {
1428 .object_size
= sizeof(Swap
),
1429 .exec_context_offset
= offsetof(Swap
, exec_context
),
1430 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1431 .kill_context_offset
= offsetof(Swap
, kill_context
),
1432 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1438 .private_section
= "Swap",
1441 .no_instances
= true,
1447 .coldplug
= swap_coldplug
,
1451 .start
= swap_start
,
1456 .get_timeout
= swap_get_timeout
,
1458 .serialize
= swap_serialize
,
1459 .deserialize_item
= swap_deserialize_item
,
1461 .active_state
= swap_active_state
,
1462 .sub_state_to_string
= swap_sub_state_to_string
,
1464 .check_gc
= swap_check_gc
,
1466 .sigchld_event
= swap_sigchld_event
,
1468 .reset_failed
= swap_reset_failed
,
1470 .bus_vtable
= bus_swap_vtable
,
1471 .bus_set_property
= bus_swap_set_property
,
1472 .bus_commit_properties
= bus_swap_commit_properties
,
1474 .following
= swap_following
,
1475 .following_set
= swap_following_set
,
1477 .enumerate
= swap_enumerate
,
1478 .shutdown
= swap_shutdown
,
1479 .supported
= swap_supported
,
1481 .status_message_formats
= {
1482 .starting_stopping
= {
1483 [0] = "Activating swap %s...",
1484 [1] = "Deactivating swap %s...",
1486 .finished_start_job
= {
1487 [JOB_DONE
] = "Activated swap %s.",
1488 [JOB_FAILED
] = "Failed to activate swap %s.",
1489 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1491 .finished_stop_job
= {
1492 [JOB_DONE
] = "Deactivated swap %s.",
1493 [JOB_FAILED
] = "Failed deactivating swap %s.",
1494 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",