1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
10 #include "alloc-util.h"
11 #include "dbus-swap.h"
12 #include "dbus-unit.h"
13 #include "device-util.h"
16 #include "exit-status.h"
18 #include "format-util.h"
19 #include "fstab-util.h"
20 #include "parse-util.h"
21 #include "path-util.h"
22 #include "process-util.h"
23 #include "serialize.h"
25 #include "string-table.h"
26 #include "string-util.h"
28 #include "unit-name.h"
32 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
33 [SWAP_DEAD
] = UNIT_INACTIVE
,
34 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
35 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
36 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
37 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
38 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
39 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
40 [SWAP_FAILED
] = UNIT_FAILED
,
41 [SWAP_CLEANING
] = UNIT_MAINTENANCE
,
44 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
45 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
46 static int swap_process_proc_swaps(Manager
*m
);
48 static bool SWAP_STATE_WITH_PROCESS(SwapState state
) {
53 SWAP_DEACTIVATING_SIGTERM
,
54 SWAP_DEACTIVATING_SIGKILL
,
58 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
61 return state_translation_table
[SWAP(u
)->state
];
64 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
67 return swap_state_to_string(SWAP(u
)->state
);
70 _pure_
static bool swap_may_gc(Unit
*u
) {
75 if (s
->from_proc_swaps
)
81 _pure_
static bool swap_is_extrinsic(Unit
*u
) {
84 return MANAGER_IS_USER(u
->manager
);
87 static void swap_unset_proc_swaps(Swap
*s
) {
90 if (!s
->from_proc_swaps
)
93 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
94 s
->from_proc_swaps
= false;
97 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
104 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &path_hash_ops
);
108 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
111 first
= hashmap_get(swaps
, s
->devnode
);
113 LIST_REMOVE(same_devnode
, first
, s
);
115 hashmap_replace(swaps
, first
->devnode
, first
);
117 hashmap_remove(swaps
, s
->devnode
);
119 s
->devnode
= mfree(s
->devnode
);
123 s
->devnode
= strdup(devnode
);
127 first
= hashmap_get(swaps
, s
->devnode
);
128 LIST_PREPEND(same_devnode
, first
, s
);
130 return hashmap_replace(swaps
, first
->devnode
, first
);
136 static void swap_init(Unit
*u
) {
140 assert(UNIT(s
)->load_state
== UNIT_STUB
);
142 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
144 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
145 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
147 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
149 u
->ignore_on_isolate
= true;
152 static void swap_unwatch_control_pid(Swap
*s
) {
155 if (s
->control_pid
<= 0)
158 unit_unwatch_pid(UNIT(s
), TAKE_PID(s
->control_pid
));
161 static void swap_done(Unit
*u
) {
166 swap_unset_proc_swaps(s
);
167 swap_set_devnode(s
, NULL
);
169 s
->what
= mfree(s
->what
);
170 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
171 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
173 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
, false);
174 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
175 s
->control_command
= NULL
;
177 dynamic_creds_unref(&s
->dynamic_creds
);
179 swap_unwatch_control_pid(s
);
181 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
184 static int swap_arm_timer(Swap
*s
, usec_t usec
) {
189 if (s
->timer_event_source
) {
190 r
= sd_event_source_set_time(s
->timer_event_source
, usec
);
194 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
197 if (usec
== USEC_INFINITY
)
200 r
= sd_event_add_time(
201 UNIT(s
)->manager
->event
,
202 &s
->timer_event_source
,
205 swap_dispatch_timer
, s
);
209 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
214 static SwapParameters
* swap_get_parameters(Swap
*s
) {
217 if (s
->from_proc_swaps
)
218 return &s
->parameters_proc_swaps
;
220 if (s
->from_fragment
)
221 return &s
->parameters_fragment
;
226 static int swap_add_device_dependencies(Swap
*s
) {
227 UnitDependencyMask mask
;
236 p
= swap_get_parameters(s
);
240 mask
= s
->from_proc_swaps
? UNIT_DEPENDENCY_PROC_SWAP
: UNIT_DEPENDENCY_FILE
;
242 if (is_device_path(p
->what
)) {
243 r
= unit_add_node_dependency(UNIT(s
), p
->what
, UNIT_REQUIRES
, mask
);
247 return unit_add_blockdev_dependency(UNIT(s
), p
->what
, mask
);
250 /* File based swap devices need to be ordered after systemd-remount-fs.service, since they might need
251 * a writable file system. */
252 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, true, mask
);
255 static int swap_add_default_dependencies(Swap
*s
) {
260 if (!UNIT(s
)->default_dependencies
)
263 if (!MANAGER_IS_SYSTEM(UNIT(s
)->manager
))
266 if (detect_container() > 0)
269 /* swap units generated for the swap dev links are missing the
270 * ordering dep against the swap target. */
271 r
= unit_add_dependency_by_name(UNIT(s
), UNIT_BEFORE
, SPECIAL_SWAP_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
275 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
278 static int swap_verify(Swap
*s
) {
279 _cleanup_free_
char *e
= NULL
;
282 assert(UNIT(s
)->load_state
== UNIT_LOADED
);
284 r
= unit_name_from_path(s
->what
, ".swap", &e
);
286 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
288 if (!unit_has_name(UNIT(s
), e
))
289 return log_unit_error_errno(UNIT(s
), SYNTHETIC_ERRNO(ENOEXEC
), "Value of What= and unit name do not match, not loading.");
291 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
)
292 return log_unit_error_errno(UNIT(s
), SYNTHETIC_ERRNO(ENOEXEC
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
297 static int swap_load_devnode(Swap
*s
) {
298 _cleanup_free_
char *p
= NULL
;
304 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
307 r
= devname_from_stat_rdev(&st
, &p
);
309 log_unit_full_errno(UNIT(s
), r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
, r
,
310 "Failed to get device node for swap %s: %m", s
->what
);
314 return swap_set_devnode(s
, p
);
317 static int swap_add_extras(Swap
*s
) {
322 if (UNIT(s
)->fragment_path
)
323 s
->from_fragment
= true;
326 if (s
->parameters_fragment
.what
)
327 s
->what
= strdup(s
->parameters_fragment
.what
);
328 else if (s
->parameters_proc_swaps
.what
)
329 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
331 r
= unit_name_to_path(UNIT(s
)->id
, &s
->what
);
340 path_simplify(s
->what
);
342 if (!UNIT(s
)->description
) {
343 r
= unit_set_description(UNIT(s
), s
->what
);
348 r
= unit_require_mounts_for(UNIT(s
), s
->what
, UNIT_DEPENDENCY_IMPLICIT
);
352 r
= swap_add_device_dependencies(s
);
356 r
= swap_load_devnode(s
);
360 r
= unit_patch_contexts(UNIT(s
));
364 r
= unit_add_exec_dependencies(UNIT(s
), &s
->exec_context
);
368 r
= unit_set_default_slice(UNIT(s
));
372 r
= swap_add_default_dependencies(s
);
379 static int swap_load(Unit
*u
) {
384 assert(u
->load_state
== UNIT_STUB
);
386 /* Load a .swap file */
387 bool fragment_optional
= s
->from_proc_swaps
;
388 r
= unit_load_fragment_and_dropin(u
, !fragment_optional
);
390 /* Add in some extras, and do so either when we successfully loaded something or when /proc/swaps is
392 if (u
->load_state
== UNIT_LOADED
|| s
->from_proc_swaps
)
393 q
= swap_add_extras(s
);
399 if (u
->load_state
!= UNIT_LOADED
)
402 return swap_verify(s
);
405 static int swap_setup_unit(
408 const char *what_proc_swaps
,
412 _cleanup_free_
char *e
= NULL
;
420 assert(what_proc_swaps
);
422 r
= unit_name_from_path(what
, ".swap", &e
);
424 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
426 u
= manager_get_unit(m
, e
);
428 SWAP(u
)->from_proc_swaps
&&
429 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
))
430 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
),
431 "Swap %s appeared twice with different device paths %s and %s",
432 e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
437 r
= unit_new_for_name(m
, sizeof(Swap
), e
, &u
);
441 SWAP(u
)->what
= strdup(what
);
442 if (!SWAP(u
)->what
) {
447 unit_add_to_load_queue(u
);
451 p
= &SWAP(u
)->parameters_proc_swaps
;
454 p
->what
= strdup(what_proc_swaps
);
461 /* The unit is definitely around now, mark it as loaded if it was previously referenced but could not be
462 * loaded. After all we can load it now, from the data in /proc/swaps. */
463 if (IN_SET(u
->load_state
, UNIT_NOT_FOUND
, UNIT_BAD_SETTING
, UNIT_ERROR
)) {
464 u
->load_state
= UNIT_LOADED
;
469 SWAP(u
)->is_active
= true;
470 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
473 SWAP(u
)->from_proc_swaps
= true;
475 p
->priority
= priority
;
476 p
->priority_set
= true;
478 unit_add_to_dbus_queue(u
);
482 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
490 static void swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
491 _cleanup_(sd_device_unrefp
) sd_device
*d
= NULL
;
492 const char *dn
, *devlink
;
493 struct stat st
, st_link
;
498 if (swap_setup_unit(m
, device
, device
, prio
, set_flags
) < 0)
501 /* If this is a block device, then let's add duplicates for
502 * all other names of this block device */
503 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
506 r
= sd_device_new_from_stat_rdev(&d
, &st
);
508 return (void) log_full_errno(r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
, r
,
509 "Failed to allocate device for swap %s: %m", device
);
511 /* Add the main device node */
512 if (sd_device_get_devname(d
, &dn
) >= 0 && !streq(dn
, device
))
513 (void) swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
515 /* Add additional units for all symlinks */
516 FOREACH_DEVICE_DEVLINK(d
, devlink
) {
518 /* Don't bother with the /dev/block links */
519 if (streq(devlink
, device
))
522 if (path_startswith(devlink
, "/dev/block/"))
525 if (stat(devlink
, &st_link
) >= 0 &&
526 (!S_ISBLK(st_link
.st_mode
) ||
527 st_link
.st_rdev
!= st
.st_rdev
))
530 (void) swap_setup_unit(m
, devlink
, device
, prio
, set_flags
);
534 static void swap_set_state(Swap
*s
, SwapState state
) {
539 if (s
->state
!= state
)
540 bus_unit_send_pending_change_signal(UNIT(s
), false);
542 old_state
= s
->state
;
545 if (!SWAP_STATE_WITH_PROCESS(state
)) {
546 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
547 swap_unwatch_control_pid(s
);
548 s
->control_command
= NULL
;
549 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
552 if (state
!= old_state
)
553 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
555 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], 0);
557 /* If there other units for the same device node have a job
558 queued it might be worth checking again if it is runnable
559 now. This is necessary, since swap_start() refuses
560 operation with EAGAIN if there's already another job for
561 the same device node queued. */
562 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
563 if (UNIT(other
)->job
)
564 job_add_to_run_queue(UNIT(other
)->job
);
567 static int swap_coldplug(Unit
*u
) {
569 SwapState new_state
= SWAP_DEAD
;
573 assert(s
->state
== SWAP_DEAD
);
575 if (s
->deserialized_state
!= s
->state
)
576 new_state
= s
->deserialized_state
;
577 else if (s
->from_proc_swaps
)
578 new_state
= SWAP_ACTIVE
;
580 if (new_state
== s
->state
)
583 if (s
->control_pid
> 0 &&
584 pid_is_unwaited(s
->control_pid
) &&
585 SWAP_STATE_WITH_PROCESS(new_state
)) {
587 r
= unit_watch_pid(UNIT(s
), s
->control_pid
, false);
591 r
= swap_arm_timer(s
, usec_add(u
->state_change_timestamp
.monotonic
, s
->timeout_usec
));
596 if (!IN_SET(new_state
, SWAP_DEAD
, SWAP_FAILED
)) {
597 (void) unit_setup_dynamic_creds(u
);
598 (void) unit_setup_exec_runtime(u
);
601 swap_set_state(s
, new_state
);
605 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
612 if (s
->from_proc_swaps
)
613 p
= &s
->parameters_proc_swaps
;
614 else if (s
->from_fragment
)
615 p
= &s
->parameters_fragment
;
622 "%sClean Result: %s\n"
624 "%sFrom /proc/swaps: %s\n"
625 "%sFrom fragment: %s\n"
627 prefix
, swap_state_to_string(s
->state
),
628 prefix
, swap_result_to_string(s
->result
),
629 prefix
, swap_result_to_string(s
->clean_result
),
631 prefix
, yes_no(s
->from_proc_swaps
),
632 prefix
, yes_no(s
->from_fragment
),
633 prefix
, yes_no(swap_is_extrinsic(u
)));
636 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
643 prefix
, strempty(p
->options
));
646 "%sTimeoutSec: %s\n",
647 prefix
, FORMAT_TIMESPAN(s
->timeout_usec
, USEC_PER_SEC
));
649 if (s
->control_pid
> 0)
651 "%sControl PID: "PID_FMT
"\n",
652 prefix
, s
->control_pid
);
654 exec_context_dump(&s
->exec_context
, f
, prefix
);
655 kill_context_dump(&s
->kill_context
, f
, prefix
);
656 cgroup_context_dump(UNIT(s
), f
, prefix
);
659 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
661 _cleanup_(exec_params_clear
) ExecParameters exec_params
= {
662 .flags
= EXEC_APPLY_SANDBOXING
|EXEC_APPLY_CHROOT
|EXEC_APPLY_TTY_STDIN
,
675 r
= unit_prepare_exec(UNIT(s
));
679 r
= swap_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->timeout_usec
));
683 r
= unit_set_exec_params(UNIT(s
), &exec_params
);
687 r
= exec_spawn(UNIT(s
),
697 r
= unit_watch_pid(UNIT(s
), pid
, true);
706 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
711 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
714 if (s
->result
== SWAP_SUCCESS
)
717 unit_log_result(UNIT(s
), s
->result
== SWAP_SUCCESS
, swap_result_to_string(s
->result
));
718 unit_warn_leftover_processes(UNIT(s
), unit_log_leftover_process_stop
);
719 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
721 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
, true);
723 unit_destroy_runtime_data(UNIT(s
), &s
->exec_context
);
725 unit_unref_uid_gid(UNIT(s
), true);
727 dynamic_creds_destroy(&s
->dynamic_creds
);
730 static void swap_enter_active(Swap
*s
, SwapResult f
) {
733 if (s
->result
== SWAP_SUCCESS
)
736 swap_set_state(s
, SWAP_ACTIVE
);
739 static void swap_enter_dead_or_active(Swap
*s
, SwapResult f
) {
742 if (s
->from_proc_swaps
) {
743 swap_enter_active(s
, f
);
745 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
746 if (UNIT(other
)->job
)
747 swap_enter_dead_or_active(other
, f
);
749 swap_enter_dead(s
, f
);
752 static int state_to_kill_operation(Swap
*s
, SwapState state
) {
753 if (state
== SWAP_DEACTIVATING_SIGTERM
) {
754 if (unit_has_job_type(UNIT(s
), JOB_RESTART
))
757 return KILL_TERMINATE
;
763 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
768 if (s
->result
== SWAP_SUCCESS
)
771 r
= unit_kill_context(UNIT(s
),
773 state_to_kill_operation(s
, state
),
781 r
= swap_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->timeout_usec
));
785 swap_set_state(s
, state
);
786 } else if (state
== SWAP_DEACTIVATING_SIGTERM
&& s
->kill_context
.send_sigkill
)
787 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
789 swap_enter_dead_or_active(s
, SWAP_SUCCESS
);
794 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
795 swap_enter_dead_or_active(s
, SWAP_FAILURE_RESOURCES
);
798 static void swap_enter_activating(Swap
*s
) {
799 _cleanup_free_
char *opts
= NULL
;
804 unit_warn_leftover_processes(UNIT(s
), unit_log_leftover_process_start
);
806 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
807 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
809 if (s
->from_fragment
) {
812 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
814 log_unit_warning_errno(UNIT(s
), r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
815 else if (r
> 0 && s
->parameters_fragment
.priority_set
)
816 log_unit_warning(UNIT(s
), "Duplicate swap priority configuration by Priority= and Options= fields.");
818 if (r
<= 0 && s
->parameters_fragment
.priority_set
) {
819 if (s
->parameters_fragment
.options
)
820 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
822 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
830 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
834 if (s
->parameters_fragment
.options
|| opts
) {
835 r
= exec_command_append(s
->control_command
, "-o",
836 opts
?: s
->parameters_fragment
.options
, NULL
);
841 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
845 swap_unwatch_control_pid(s
);
847 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
851 swap_set_state(s
, SWAP_ACTIVATING
);
855 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
856 swap_enter_dead_or_active(s
, SWAP_FAILURE_RESOURCES
);
859 static void swap_enter_deactivating(Swap
*s
) {
864 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
865 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
867 r
= exec_command_set(s
->control_command
,
874 swap_unwatch_control_pid(s
);
876 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
880 swap_set_state(s
, SWAP_DEACTIVATING
);
885 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
886 swap_enter_dead_or_active(s
, SWAP_FAILURE_RESOURCES
);
889 static void swap_cycle_clear(Swap
*s
) {
892 s
->result
= SWAP_SUCCESS
;
893 exec_command_reset_status_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
894 UNIT(s
)->reset_accounting
= true;
897 static int swap_start(Unit
*u
) {
903 /* We cannot fulfill this request right now, try again later please! */
906 SWAP_DEACTIVATING_SIGTERM
,
907 SWAP_DEACTIVATING_SIGKILL
,
912 if (s
->state
== SWAP_ACTIVATING
)
915 assert(IN_SET(s
->state
, SWAP_DEAD
, SWAP_FAILED
));
917 if (detect_container() > 0)
920 /* If there's a job for another swap unit for the same node
921 * running, then let's not dispatch this one for now, and wait
922 * until that other job has finished. */
923 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
924 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
927 r
= unit_acquire_invocation_id(u
);
932 swap_enter_activating(s
);
936 static int swap_stop(Unit
*u
) {
943 case SWAP_DEACTIVATING
:
944 case SWAP_DEACTIVATING_SIGTERM
:
945 case SWAP_DEACTIVATING_SIGKILL
:
949 case SWAP_ACTIVATING
:
950 case SWAP_ACTIVATING_DONE
:
951 /* There's a control process pending, directly enter kill mode */
952 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_SUCCESS
);
956 if (detect_container() > 0)
959 swap_enter_deactivating(s
);
963 /* If we are currently cleaning, then abort it, brutally. */
964 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
968 assert_not_reached();
972 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
979 (void) serialize_item(f
, "state", swap_state_to_string(s
->state
));
980 (void) serialize_item(f
, "result", swap_result_to_string(s
->result
));
982 if (s
->control_pid
> 0)
983 (void) serialize_item_format(f
, "control-pid", PID_FMT
, s
->control_pid
);
985 if (s
->control_command_id
>= 0)
986 (void) serialize_item(f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
991 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
997 if (streq(key
, "state")) {
1000 state
= swap_state_from_string(value
);
1002 log_unit_debug(u
, "Failed to parse state value: %s", value
);
1004 s
->deserialized_state
= state
;
1005 } else if (streq(key
, "result")) {
1008 f
= swap_result_from_string(value
);
1010 log_unit_debug(u
, "Failed to parse result value: %s", value
);
1011 else if (f
!= SWAP_SUCCESS
)
1013 } else if (streq(key
, "control-pid")) {
1016 if (parse_pid(value
, &pid
) < 0)
1017 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
1019 s
->control_pid
= pid
;
1021 } else if (streq(key
, "control-command")) {
1024 id
= swap_exec_command_from_string(value
);
1026 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
1028 s
->control_command_id
= id
;
1029 s
->control_command
= s
->exec_command
+ id
;
1032 log_unit_debug(u
, "Unknown serialization key: %s", key
);
1037 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
1044 if (pid
!= s
->control_pid
)
1047 /* Let's scan /proc/swaps before we process SIGCHLD. For the reasoning see the similar code in
1049 (void) swap_process_proc_swaps(u
->manager
);
1053 if (is_clean_exit(code
, status
, EXIT_CLEAN_COMMAND
, NULL
))
1055 else if (code
== CLD_EXITED
)
1056 f
= SWAP_FAILURE_EXIT_CODE
;
1057 else if (code
== CLD_KILLED
)
1058 f
= SWAP_FAILURE_SIGNAL
;
1059 else if (code
== CLD_DUMPED
)
1060 f
= SWAP_FAILURE_CORE_DUMP
;
1062 assert_not_reached();
1064 if (s
->result
== SWAP_SUCCESS
)
1067 if (s
->control_command
) {
1068 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
1070 s
->control_command
= NULL
;
1071 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
1074 unit_log_process_exit(
1077 swap_exec_command_to_string(s
->control_command_id
),
1083 case SWAP_ACTIVATING
:
1084 case SWAP_ACTIVATING_DONE
:
1086 if (f
== SWAP_SUCCESS
|| s
->from_proc_swaps
)
1087 swap_enter_active(s
, f
);
1089 swap_enter_dead(s
, f
);
1092 case SWAP_DEACTIVATING
:
1093 case SWAP_DEACTIVATING_SIGKILL
:
1094 case SWAP_DEACTIVATING_SIGTERM
:
1096 swap_enter_dead_or_active(s
, f
);
1100 if (s
->clean_result
== SWAP_SUCCESS
)
1101 s
->clean_result
= f
;
1103 swap_enter_dead(s
, SWAP_SUCCESS
);
1107 assert_not_reached();
1110 /* Notify clients about changed exit status */
1111 unit_add_to_dbus_queue(u
);
1114 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1115 Swap
*s
= SWAP(userdata
);
1118 assert(s
->timer_event_source
== source
);
1122 case SWAP_ACTIVATING
:
1123 case SWAP_ACTIVATING_DONE
:
1124 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1125 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1128 case SWAP_DEACTIVATING
:
1129 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1130 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1133 case SWAP_DEACTIVATING_SIGTERM
:
1134 if (s
->kill_context
.send_sigkill
) {
1135 log_unit_warning(UNIT(s
), "Swap process timed out. Killing.");
1136 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1138 log_unit_warning(UNIT(s
), "Swap process timed out. Skipping SIGKILL. Ignoring.");
1139 swap_enter_dead_or_active(s
, SWAP_FAILURE_TIMEOUT
);
1143 case SWAP_DEACTIVATING_SIGKILL
:
1144 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1145 swap_enter_dead_or_active(s
, SWAP_FAILURE_TIMEOUT
);
1149 log_unit_warning(UNIT(s
), "Cleaning timed out. killing.");
1151 if (s
->clean_result
== SWAP_SUCCESS
)
1152 s
->clean_result
= SWAP_FAILURE_TIMEOUT
;
1154 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, 0);
1158 assert_not_reached();
1164 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1167 rewind(m
->proc_swaps
);
1169 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1171 for (unsigned i
= 1;; i
++) {
1172 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1175 k
= fscanf(m
->proc_swaps
,
1176 "%ms " /* device/file */
1177 "%*s " /* type of swap */
1178 "%*s " /* swap size */
1180 "%i\n", /* priority */
1186 log_warning("Failed to parse /proc/swaps:%u.", i
);
1190 ssize_t l
= cunescape(dev
, UNESCAPE_RELAX
, &d
);
1192 return log_error_errno(l
, "Failed to unescape device path: %m");
1194 device_found_node(m
, d
, DEVICE_FOUND_SWAP
, DEVICE_FOUND_SWAP
);
1196 (void) swap_process_new(m
, d
, prio
, set_flags
);
1202 static int swap_process_proc_swaps(Manager
*m
) {
1207 r
= swap_load_proc_swaps(m
, true);
1209 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1211 /* Reset flags, just in case, for late calls */
1212 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1213 Swap
*swap
= SWAP(u
);
1217 swap
->is_active
= swap
->just_activated
= false;
1223 manager_dispatch_load_queue(m
);
1225 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1226 Swap
*swap
= SWAP(u
);
1230 if (!swap
->is_active
) {
1232 swap_unset_proc_swaps(swap
);
1234 switch (swap
->state
) {
1237 /* This has just been deactivated */
1238 swap_enter_dead(swap
, SWAP_SUCCESS
);
1243 swap_set_state(swap
, swap
->state
);
1248 device_found_node(m
, swap
->what
, DEVICE_NOT_FOUND
, DEVICE_FOUND_SWAP
);
1250 } else if (swap
->just_activated
) {
1252 /* New swap entry */
1254 switch (swap
->state
) {
1258 (void) unit_acquire_invocation_id(u
);
1259 swap_cycle_clear(swap
);
1260 swap_enter_active(swap
, SWAP_SUCCESS
);
1263 case SWAP_ACTIVATING
:
1264 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1268 /* Nothing really changed, but let's
1269 * issue an notification call
1270 * nonetheless, in case somebody is
1271 * waiting for this. */
1272 swap_set_state(swap
, swap
->state
);
1277 /* Reset the flags for later calls */
1278 swap
->is_active
= swap
->just_activated
= false;
1284 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1285 Manager
*m
= ASSERT_PTR(userdata
);
1287 assert(revents
& EPOLLPRI
);
1289 return swap_process_proc_swaps(m
);
1292 static Unit
*swap_following(Unit
*u
) {
1298 /* If the user configured the swap through /etc/fstab or
1299 * a device unit, follow that. */
1301 if (s
->from_fragment
)
1304 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1305 if (other
->from_fragment
)
1308 /* Otherwise, make everybody follow the unit that's named after
1309 * the swap device in the kernel */
1311 if (streq_ptr(s
->what
, s
->devnode
))
1314 LIST_FOREACH(same_devnode
, other
, s
->same_devnode_next
)
1315 if (streq_ptr(other
->what
, other
->devnode
))
1318 LIST_FOREACH_BACKWARDS(same_devnode
, other
, s
->same_devnode_prev
) {
1319 if (streq_ptr(other
->what
, other
->devnode
))
1325 /* Fall back to the first on the list */
1329 static int swap_following_set(Unit
*u
, Set
**_set
) {
1331 _cleanup_set_free_ Set
*set
= NULL
;
1337 if (LIST_JUST_US(same_devnode
, s
)) {
1342 set
= set_new(NULL
);
1346 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1347 r
= set_put(set
, other
);
1352 *_set
= TAKE_PTR(set
);
1356 static void swap_shutdown(Manager
*m
) {
1359 m
->swap_event_source
= sd_event_source_disable_unref(m
->swap_event_source
);
1360 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1361 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1364 static void swap_enumerate(Manager
*m
) {
1369 if (!m
->proc_swaps
) {
1370 m
->proc_swaps
= fopen("/proc/swaps", "re");
1371 if (!m
->proc_swaps
) {
1372 if (errno
== ENOENT
)
1373 log_debug_errno(errno
, "Not swap enabled, skipping enumeration.");
1375 log_warning_errno(errno
, "Failed to open /proc/swaps, ignoring: %m");
1380 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1382 log_error_errno(r
, "Failed to watch /proc/swaps: %m");
1386 /* Dispatch this before we dispatch SIGCHLD, so that
1387 * we always get the events from /proc/swaps before
1388 * the SIGCHLD of /sbin/swapon. */
1389 r
= sd_event_source_set_priority(m
->swap_event_source
, SD_EVENT_PRIORITY_NORMAL
-10);
1391 log_error_errno(r
, "Failed to change /proc/swaps priority: %m");
1395 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1398 r
= swap_load_proc_swaps(m
, false);
1408 int swap_process_device_new(Manager
*m
, sd_device
*dev
) {
1409 _cleanup_free_
char *e
= NULL
;
1410 const char *dn
, *devlink
;
1417 if (sd_device_get_devname(dev
, &dn
) < 0)
1420 r
= unit_name_from_path(dn
, ".swap", &e
);
1422 log_debug_errno(r
, "Cannot convert device name '%s' to unit name, ignoring: %m", dn
);
1426 u
= manager_get_unit(m
, e
);
1428 r
= swap_set_devnode(SWAP(u
), dn
);
1430 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
1431 _cleanup_free_
char *n
= NULL
;
1434 q
= unit_name_from_path(devlink
, ".swap", &n
);
1435 if (q
== -EINVAL
) /* If the name is not convertible to unit name, we can't manage it */
1440 u
= manager_get_unit(m
, n
);
1442 q
= swap_set_devnode(SWAP(u
), dn
);
1451 int swap_process_device_remove(Manager
*m
, sd_device
*dev
) {
1456 r
= sd_device_get_devname(dev
, &dn
);
1460 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1463 q
= swap_set_devnode(s
, NULL
);
1471 static void swap_reset_failed(Unit
*u
) {
1476 if (s
->state
== SWAP_FAILED
)
1477 swap_set_state(s
, SWAP_DEAD
);
1479 s
->result
= SWAP_SUCCESS
;
1480 s
->clean_result
= SWAP_SUCCESS
;
1483 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1484 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1487 static int swap_get_timeout(Unit
*u
, usec_t
*timeout
) {
1495 if (!s
->timer_event_source
)
1498 r
= sd_event_source_get_time(s
->timer_event_source
, &t
);
1501 if (t
== USEC_INFINITY
)
1508 static bool swap_supported(void) {
1509 static int supported
= -1;
1511 /* If swap support is not available in the kernel, or we are
1512 * running in a container we don't support swap units, and any
1513 * attempts to starting one should fail immediately. */
1517 access("/proc/swaps", F_OK
) >= 0 &&
1518 detect_container() <= 0;
1523 static int swap_control_pid(Unit
*u
) {
1528 return s
->control_pid
;
1531 static int swap_clean(Unit
*u
, ExecCleanMask mask
) {
1532 _cleanup_strv_free_
char **l
= NULL
;
1539 if (s
->state
!= SWAP_DEAD
)
1542 r
= exec_context_get_clean_directories(&s
->exec_context
, u
->manager
->prefix
, mask
, &l
);
1546 if (strv_isempty(l
))
1549 swap_unwatch_control_pid(s
);
1550 s
->clean_result
= SWAP_SUCCESS
;
1551 s
->control_command
= NULL
;
1552 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
1554 r
= swap_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->exec_context
.timeout_clean_usec
));
1558 r
= unit_fork_and_watch_rm_rf(u
, l
, &s
->control_pid
);
1562 swap_set_state(s
, SWAP_CLEANING
);
1567 log_unit_warning_errno(u
, r
, "Failed to initiate cleaning: %m");
1568 s
->clean_result
= SWAP_FAILURE_RESOURCES
;
1569 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
1573 static int swap_can_clean(Unit
*u
, ExecCleanMask
*ret
) {
1578 return exec_context_get_clean_mask(&s
->exec_context
, ret
);
1581 static int swap_can_start(Unit
*u
) {
1587 r
= unit_test_start_limit(u
);
1589 swap_enter_dead(s
, SWAP_FAILURE_START_LIMIT_HIT
);
1596 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1597 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1598 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1601 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1603 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1604 [SWAP_SUCCESS
] = "success",
1605 [SWAP_FAILURE_RESOURCES
] = "resources",
1606 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1607 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1608 [SWAP_FAILURE_SIGNAL
] = "signal",
1609 [SWAP_FAILURE_CORE_DUMP
] = "core-dump",
1610 [SWAP_FAILURE_START_LIMIT_HIT
] = "start-limit-hit",
1613 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1615 const UnitVTable swap_vtable
= {
1616 .object_size
= sizeof(Swap
),
1617 .exec_context_offset
= offsetof(Swap
, exec_context
),
1618 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1619 .kill_context_offset
= offsetof(Swap
, kill_context
),
1620 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1621 .dynamic_creds_offset
= offsetof(Swap
, dynamic_creds
),
1627 .private_section
= "Swap",
1635 .coldplug
= swap_coldplug
,
1639 .start
= swap_start
,
1643 .clean
= swap_clean
,
1644 .can_clean
= swap_can_clean
,
1646 .get_timeout
= swap_get_timeout
,
1648 .serialize
= swap_serialize
,
1649 .deserialize_item
= swap_deserialize_item
,
1651 .active_state
= swap_active_state
,
1652 .sub_state_to_string
= swap_sub_state_to_string
,
1654 .will_restart
= unit_will_restart_default
,
1656 .may_gc
= swap_may_gc
,
1657 .is_extrinsic
= swap_is_extrinsic
,
1659 .sigchld_event
= swap_sigchld_event
,
1661 .reset_failed
= swap_reset_failed
,
1663 .control_pid
= swap_control_pid
,
1665 .bus_set_property
= bus_swap_set_property
,
1666 .bus_commit_properties
= bus_swap_commit_properties
,
1668 .following
= swap_following
,
1669 .following_set
= swap_following_set
,
1671 .enumerate
= swap_enumerate
,
1672 .shutdown
= swap_shutdown
,
1673 .supported
= swap_supported
,
1675 .status_message_formats
= {
1676 .starting_stopping
= {
1677 [0] = "Activating swap %s...",
1678 [1] = "Deactivating swap %s...",
1680 .finished_start_job
= {
1681 [JOB_DONE
] = "Activated swap %s.",
1682 [JOB_FAILED
] = "Failed to activate swap %s.",
1683 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1685 .finished_stop_job
= {
1686 [JOB_DONE
] = "Deactivated swap %s.",
1687 [JOB_FAILED
] = "Failed deactivating swap %s.",
1688 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",
1692 .can_start
= swap_can_start
,