1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <sys/socket.h>
9 #include "alloc-util.h"
10 #include "dbus-swap.h"
11 #include "dbus-unit.h"
13 #include "device-util.h"
14 #include "errno-util.h"
16 #include "exit-status.h"
18 #include "format-util.h"
19 #include "fstab-util.h"
20 #include "glyph-util.h"
22 #include "path-util.h"
23 #include "process-util.h"
24 #include "serialize.h"
27 #include "string-table.h"
28 #include "string-util.h"
32 #include "unit-name.h"
35 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
36 [SWAP_DEAD
] = UNIT_INACTIVE
,
37 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
38 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
39 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
40 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
41 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
42 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
43 [SWAP_FAILED
] = UNIT_FAILED
,
44 [SWAP_CLEANING
] = UNIT_MAINTENANCE
,
47 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
48 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
49 static int swap_process_proc_swaps(Manager
*m
);
51 static bool SWAP_STATE_WITH_PROCESS(SwapState state
) {
56 SWAP_DEACTIVATING_SIGTERM
,
57 SWAP_DEACTIVATING_SIGKILL
,
61 static UnitActiveState
swap_active_state(Unit
*u
) {
64 return state_translation_table
[SWAP(u
)->state
];
67 static const char *swap_sub_state_to_string(Unit
*u
) {
70 return swap_state_to_string(SWAP(u
)->state
);
73 static bool swap_may_gc(Unit
*u
) {
74 Swap
*s
= ASSERT_PTR(SWAP(u
));
76 if (s
->from_proc_swaps
)
82 static bool swap_is_extrinsic(Unit
*u
) {
85 return MANAGER_IS_USER(u
->manager
);
88 static void swap_unset_proc_swaps(Swap
*s
) {
91 if (!s
->from_proc_swaps
)
94 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
95 s
->from_proc_swaps
= false;
98 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
105 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &path_hash_ops
);
109 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
112 first
= hashmap_get(swaps
, s
->devnode
);
114 LIST_REMOVE(same_devnode
, first
, s
);
116 hashmap_replace(swaps
, first
->devnode
, first
);
118 hashmap_remove(swaps
, s
->devnode
);
120 s
->devnode
= mfree(s
->devnode
);
124 s
->devnode
= strdup(devnode
);
128 first
= hashmap_get(swaps
, s
->devnode
);
129 LIST_PREPEND(same_devnode
, first
, s
);
131 return hashmap_replace(swaps
, first
->devnode
, first
);
137 static void swap_init(Unit
*u
) {
138 Swap
*s
= ASSERT_PTR(SWAP(u
));
140 assert(u
->load_state
== UNIT_STUB
);
142 s
->timeout_usec
= u
->manager
->defaults
.timeout_start_usec
;
144 s
->exec_context
.std_output
= u
->manager
->defaults
.std_output
;
145 s
->exec_context
.std_error
= u
->manager
->defaults
.std_error
;
147 s
->control_pid
= PIDREF_NULL
;
148 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
150 u
->ignore_on_isolate
= true;
153 static void swap_unwatch_control_pid(Swap
*s
) {
155 unit_unwatch_pidref_done(UNIT(s
), &s
->control_pid
);
158 static void swap_done(Unit
*u
) {
159 Swap
*s
= ASSERT_PTR(SWAP(u
));
161 swap_unset_proc_swaps(s
);
162 swap_set_devnode(s
, NULL
);
164 s
->what
= mfree(s
->what
);
165 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
166 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
168 s
->exec_runtime
= exec_runtime_free(s
->exec_runtime
);
170 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
171 s
->control_command
= NULL
;
173 swap_unwatch_control_pid(s
);
175 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
178 static int swap_arm_timer(Swap
*s
, bool relative
, usec_t usec
) {
181 return unit_arm_timer(UNIT(s
), &s
->timer_event_source
, relative
, usec
, swap_dispatch_timer
);
184 static SwapParameters
* swap_get_parameters(Swap
*s
) {
187 if (s
->from_proc_swaps
)
188 return &s
->parameters_proc_swaps
;
190 if (s
->from_fragment
)
191 return &s
->parameters_fragment
;
196 static int swap_add_device_dependencies(Swap
*s
) {
197 UnitDependencyMask mask
;
206 p
= swap_get_parameters(s
);
210 mask
= s
->from_proc_swaps
? UNIT_DEPENDENCY_PROC_SWAP
: UNIT_DEPENDENCY_FILE
;
212 if (is_device_path(p
->what
)) {
213 r
= unit_add_node_dependency(UNIT(s
), p
->what
, UNIT_REQUIRES
, mask
);
217 return unit_add_blockdev_dependency(UNIT(s
), p
->what
, mask
);
220 /* File based swap devices need to be ordered after systemd-remount-fs.service, since they might need
221 * a writable file system. */
222 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, true, mask
);
225 static int swap_add_default_dependencies(Swap
*s
) {
230 if (!UNIT(s
)->default_dependencies
)
233 if (!MANAGER_IS_SYSTEM(UNIT(s
)->manager
))
236 if (detect_container() > 0)
239 /* swap units generated for the swap dev links are missing the
240 * ordering dep against the swap target. */
241 r
= unit_add_dependency_by_name(UNIT(s
), UNIT_BEFORE
, SPECIAL_SWAP_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
245 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
248 static int swap_verify(Swap
*s
) {
249 _cleanup_free_
char *e
= NULL
;
253 assert(UNIT(s
)->load_state
== UNIT_LOADED
);
255 r
= unit_name_from_path(s
->what
, ".swap", &e
);
257 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
259 if (!unit_has_name(UNIT(s
), e
))
260 return log_unit_error_errno(UNIT(s
), SYNTHETIC_ERRNO(ENOEXEC
), "Value of What= and unit name do not match, not loading.");
265 static int swap_load_devnode(Swap
*s
) {
266 _cleanup_free_
char *p
= NULL
;
272 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
275 r
= devname_from_stat_rdev(&st
, &p
);
277 log_unit_full_errno(UNIT(s
), r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
, r
,
278 "Failed to get device node for swap %s: %m", s
->what
);
282 return swap_set_devnode(s
, p
);
285 static int swap_add_extras(Swap
*s
) {
290 if (UNIT(s
)->fragment_path
)
291 s
->from_fragment
= true;
294 if (s
->parameters_fragment
.what
)
295 s
->what
= strdup(s
->parameters_fragment
.what
);
296 else if (s
->parameters_proc_swaps
.what
)
297 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
299 r
= unit_name_to_path(UNIT(s
)->id
, &s
->what
);
308 path_simplify(s
->what
);
310 if (!UNIT(s
)->description
) {
311 r
= unit_set_description(UNIT(s
), s
->what
);
316 r
= unit_add_mounts_for(UNIT(s
), s
->what
, UNIT_DEPENDENCY_IMPLICIT
, UNIT_MOUNT_REQUIRES
);
320 r
= swap_add_device_dependencies(s
);
324 r
= swap_load_devnode(s
);
328 r
= unit_patch_contexts(UNIT(s
));
332 r
= unit_add_exec_dependencies(UNIT(s
), &s
->exec_context
);
336 r
= unit_set_default_slice(UNIT(s
));
340 r
= swap_add_default_dependencies(s
);
347 static int swap_load(Unit
*u
) {
348 Swap
*s
= ASSERT_PTR(SWAP(u
));
351 assert(u
->load_state
== UNIT_STUB
);
353 /* Load a .swap file */
354 r
= unit_load_fragment_and_dropin(u
, /* fragment_required = */ !s
->from_proc_swaps
);
356 /* Add in some extras, and do so either when we successfully loaded something or when /proc/swaps is
358 if (u
->load_state
== UNIT_LOADED
|| s
->from_proc_swaps
)
359 RET_GATHER(r
, swap_add_extras(s
));
364 if (u
->load_state
!= UNIT_LOADED
)
367 return swap_verify(s
);
370 static int swap_setup_unit(
373 const char *what_proc_swaps
,
377 _cleanup_(unit_freep
) Unit
*new_unit
= NULL
;
378 _cleanup_free_
char *e
= NULL
;
385 assert(what_proc_swaps
);
387 r
= unit_name_from_path(what
, ".swap", &e
);
389 return log_error_errno(r
, "Failed to generate unit name from path: %m");
391 u
= manager_get_unit(m
, e
);
393 s
= ASSERT_PTR(SWAP(u
));
395 if (s
->from_proc_swaps
&&
396 !path_equal(s
->parameters_proc_swaps
.what
, what_proc_swaps
))
397 return log_unit_error_errno(u
, SYNTHETIC_ERRNO(EEXIST
),
398 "Swap appeared twice with different device paths %s and %s, refusing.",
399 s
->parameters_proc_swaps
.what
, what_proc_swaps
);
401 r
= unit_new_for_name(m
, sizeof(Swap
), e
, &new_unit
);
403 return log_warning_errno(r
, "Failed to load swap unit '%s': %m", e
);
406 s
= ASSERT_PTR(SWAP(u
));
408 s
->what
= strdup(what
);
413 SwapParameters
*p
= &s
->parameters_proc_swaps
;
416 p
->what
= strdup(what_proc_swaps
);
421 /* The unit is definitely around now. When we previously fail to load the unit, let's reload the unit
422 * by resetting the load state and load error, and adding the unit to the load queue. */
423 if (UNIT_IS_LOAD_ERROR(u
->load_state
)) {
424 u
->load_state
= UNIT_STUB
;
428 unit_add_to_load_queue(u
);
432 s
->just_activated
= !s
->from_proc_swaps
;
435 s
->from_proc_swaps
= true;
437 p
->priority
= priority
;
438 p
->priority_set
= true;
440 unit_add_to_dbus_queue(u
);
446 static void swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
447 _cleanup_(sd_device_unrefp
) sd_device
*d
= NULL
;
449 struct stat st
, st_link
;
454 if (swap_setup_unit(m
, device
, device
, prio
, set_flags
) < 0)
457 /* If this is a block device, then let's add duplicates for
458 * all other names of this block device */
459 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
462 r
= sd_device_new_from_stat_rdev(&d
, &st
);
464 return (void) log_full_errno(r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
, r
,
465 "Failed to allocate device for swap %s: %m", device
);
467 /* Add the main device node */
468 if (sd_device_get_devname(d
, &dn
) >= 0 && !streq(dn
, device
))
469 (void) swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
471 /* Add additional units for all symlinks */
472 FOREACH_DEVICE_DEVLINK(d
, devlink
) {
474 /* Don't bother with the /dev/block links */
475 if (streq(devlink
, device
))
478 if (path_startswith(devlink
, "/dev/block/"))
481 if (stat(devlink
, &st_link
) >= 0 &&
482 (!S_ISBLK(st_link
.st_mode
) ||
483 st_link
.st_rdev
!= st
.st_rdev
))
486 (void) swap_setup_unit(m
, devlink
, device
, prio
, set_flags
);
490 static void swap_set_state(Swap
*s
, SwapState state
) {
495 if (s
->state
!= state
)
496 bus_unit_send_pending_change_signal(UNIT(s
), false);
498 old_state
= s
->state
;
501 if (!SWAP_STATE_WITH_PROCESS(state
)) {
502 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
503 swap_unwatch_control_pid(s
);
504 s
->control_command
= NULL
;
505 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
508 if (state
!= old_state
)
509 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
511 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], /* reload_success = */ true);
513 /* If there other units for the same device node have a job
514 queued it might be worth checking again if it is runnable
515 now. This is necessary, since swap_start() refuses
516 operation with EAGAIN if there's already another job for
517 the same device node queued. */
518 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
519 if (UNIT(other
)->job
)
520 job_add_to_run_queue(UNIT(other
)->job
);
523 static int swap_coldplug(Unit
*u
) {
524 Swap
*s
= ASSERT_PTR(SWAP(u
));
525 SwapState new_state
= SWAP_DEAD
;
528 assert(s
->state
== SWAP_DEAD
);
530 if (s
->deserialized_state
!= s
->state
)
531 new_state
= s
->deserialized_state
;
532 else if (s
->from_proc_swaps
)
533 new_state
= SWAP_ACTIVE
;
535 if (new_state
== s
->state
)
538 if (pidref_is_set(&s
->control_pid
) &&
539 pidref_is_unwaited(&s
->control_pid
) > 0 &&
540 SWAP_STATE_WITH_PROCESS(new_state
)) {
542 r
= unit_watch_pidref(UNIT(s
), &s
->control_pid
, /* exclusive= */ false);
546 r
= swap_arm_timer(s
, /* relative= */ false, usec_add(u
->state_change_timestamp
.monotonic
, s
->timeout_usec
));
551 if (!IN_SET(new_state
, SWAP_DEAD
, SWAP_FAILED
))
552 (void) unit_setup_exec_runtime(u
);
554 swap_set_state(s
, new_state
);
558 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
559 Swap
*s
= ASSERT_PTR(SWAP(u
));
565 prefix
= strempty(prefix
);
566 prefix2
= strjoina(prefix
, "\t");
568 if (s
->from_proc_swaps
)
569 p
= &s
->parameters_proc_swaps
;
570 else if (s
->from_fragment
)
571 p
= &s
->parameters_fragment
;
578 "%sClean Result: %s\n"
580 "%sFrom /proc/swaps: %s\n"
581 "%sFrom fragment: %s\n"
583 prefix
, swap_state_to_string(s
->state
),
584 prefix
, swap_result_to_string(s
->result
),
585 prefix
, swap_result_to_string(s
->clean_result
),
587 prefix
, yes_no(s
->from_proc_swaps
),
588 prefix
, yes_no(s
->from_fragment
),
589 prefix
, yes_no(swap_is_extrinsic(u
)));
592 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
599 prefix
, strempty(p
->options
));
602 "%sTimeoutSec: %s\n",
603 prefix
, FORMAT_TIMESPAN(s
->timeout_usec
, USEC_PER_SEC
));
605 if (pidref_is_set(&s
->control_pid
))
607 "%sControl PID: "PID_FMT
"\n",
608 prefix
, s
->control_pid
.pid
);
610 exec_context_dump(&s
->exec_context
, f
, prefix
);
611 kill_context_dump(&s
->kill_context
, f
, prefix
);
612 cgroup_context_dump(UNIT(s
), f
, prefix
);
614 for (SwapExecCommand c
= 0; c
< _SWAP_EXEC_COMMAND_MAX
; c
++) {
615 if (!s
->exec_command
[c
].argv
)
618 fprintf(f
, "%s%s %s:\n",
619 prefix
, glyph(GLYPH_ARROW_RIGHT
), swap_exec_command_to_string(c
));
621 exec_command_dump(s
->exec_command
+ c
, f
, prefix2
);
625 static int swap_spawn(Swap
*s
, ExecCommand
*c
, PidRef
*ret_pid
) {
626 _cleanup_(exec_params_shallow_clear
) ExecParameters exec_params
= EXEC_PARAMETERS_INIT(
627 EXEC_APPLY_SANDBOXING
|EXEC_APPLY_CHROOT
|EXEC_APPLY_TTY_STDIN
);
628 _cleanup_(pidref_done
) PidRef pidref
= PIDREF_NULL
;
635 r
= unit_prepare_exec(UNIT(s
));
639 r
= swap_arm_timer(s
, /* relative= */ true, s
->timeout_usec
);
643 r
= unit_set_exec_params(UNIT(s
), &exec_params
);
647 /* Assume the label inherited from systemd as the fallback */
648 exec_params
.fallback_smack_process_label
= NULL
;
650 r
= exec_spawn(UNIT(s
),
660 r
= unit_watch_pidref(UNIT(s
), &pidref
, /* exclusive= */ true);
664 *ret_pid
= TAKE_PIDREF(pidref
);
668 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
671 if (s
->result
== SWAP_SUCCESS
)
674 unit_log_result(UNIT(s
), s
->result
== SWAP_SUCCESS
, swap_result_to_string(s
->result
));
675 unit_warn_leftover_processes(UNIT(s
), /* start = */ false);
677 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
679 s
->exec_runtime
= exec_runtime_destroy(s
->exec_runtime
);
681 unit_destroy_runtime_data(UNIT(s
), &s
->exec_context
, /* destroy_runtime_dir = */ true);
683 unit_unref_uid_gid(UNIT(s
), true);
686 static void swap_enter_active(Swap
*s
, SwapResult f
) {
689 if (s
->result
== SWAP_SUCCESS
)
692 swap_set_state(s
, SWAP_ACTIVE
);
695 static void swap_enter_dead_or_active(Swap
*s
, SwapResult f
) {
698 if (s
->from_proc_swaps
) {
699 swap_enter_active(s
, f
);
701 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
702 if (UNIT(other
)->job
)
703 swap_enter_dead_or_active(other
, f
);
705 swap_enter_dead(s
, f
);
708 static int state_to_kill_operation(Swap
*s
, SwapState state
) {
709 if (state
== SWAP_DEACTIVATING_SIGTERM
) {
710 if (unit_has_job_type(UNIT(s
), JOB_RESTART
))
713 return KILL_TERMINATE
;
719 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
724 if (s
->result
== SWAP_SUCCESS
)
727 r
= unit_kill_context(UNIT(s
), state_to_kill_operation(s
, state
));
729 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
734 r
= swap_arm_timer(s
, /* relative= */ true, s
->timeout_usec
);
736 log_unit_warning_errno(UNIT(s
), r
, "Failed to install timer: %m");
740 swap_set_state(s
, state
);
741 } else if (state
== SWAP_DEACTIVATING_SIGTERM
&& s
->kill_context
.send_sigkill
)
742 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
744 swap_enter_dead_or_active(s
, SWAP_SUCCESS
);
749 swap_enter_dead_or_active(s
, SWAP_FAILURE_RESOURCES
);
752 static void swap_enter_activating(Swap
*s
) {
753 _cleanup_free_
char *opts
= NULL
;
758 unit_warn_leftover_processes(UNIT(s
), /* start = */ true);
760 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
761 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
763 if (s
->from_fragment
) {
766 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
768 log_unit_warning_errno(UNIT(s
), r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
769 else if (r
> 0 && s
->parameters_fragment
.priority_set
)
770 log_unit_warning(UNIT(s
), "Duplicate swap priority configuration by Priority= and Options= fields.");
772 if (r
<= 0 && s
->parameters_fragment
.priority_set
) {
773 if (s
->parameters_fragment
.options
)
774 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
776 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
784 r
= exec_command_set(s
->control_command
, "/sbin/swapon", "--fixpgsz", NULL
);
786 log_unit_warning_errno(UNIT(s
), r
, "Failed to initialize swapon command line: %m");
790 if (s
->parameters_fragment
.options
|| opts
) {
791 r
= exec_command_append(s
->control_command
, "-o",
792 opts
?: s
->parameters_fragment
.options
, NULL
);
794 log_unit_warning_errno(UNIT(s
), r
, "Failed to prepare swapon command line: %m");
799 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
801 log_unit_warning_errno(UNIT(s
), r
, "Failed to prepare swapon command line: %m");
805 swap_unwatch_control_pid(s
);
807 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
809 log_unit_warning_errno(UNIT(s
), r
, "Failed to spawn 'swapon' task: %m");
813 swap_set_state(s
, SWAP_ACTIVATING
);
817 swap_enter_dead_or_active(s
, SWAP_FAILURE_RESOURCES
);
820 static void swap_enter_deactivating(Swap
*s
) {
825 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
826 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
828 r
= exec_command_set(s
->control_command
,
833 log_unit_warning_errno(UNIT(s
), r
, "Failed to prepare swapoff command line: %m");
837 swap_unwatch_control_pid(s
);
839 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
841 log_unit_warning_errno(UNIT(s
), r
, "Failed to spawn 'swapoff' task: %m");
845 swap_set_state(s
, SWAP_DEACTIVATING
);
849 swap_enter_dead_or_active(s
, SWAP_FAILURE_RESOURCES
);
852 static void swap_cycle_clear(Swap
*s
) {
855 s
->result
= SWAP_SUCCESS
;
856 exec_command_reset_status_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
858 if (s
->cgroup_runtime
)
859 s
->cgroup_runtime
->reset_accounting
= true;
862 static int swap_start(Unit
*u
) {
868 /* We cannot fulfill this request right now, try again later please! */
871 SWAP_DEACTIVATING_SIGTERM
,
872 SWAP_DEACTIVATING_SIGKILL
,
877 if (s
->state
== SWAP_ACTIVATING
)
880 assert(IN_SET(s
->state
, SWAP_DEAD
, SWAP_FAILED
));
882 if (detect_container() > 0)
885 /* If there's a job for another swap unit for the same node
886 * running, then let's not dispatch this one for now, and wait
887 * until that other job has finished. */
888 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
889 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
892 r
= unit_acquire_invocation_id(u
);
897 swap_enter_activating(s
);
901 static int swap_stop(Unit
*u
) {
902 Swap
*s
= ASSERT_PTR(SWAP(u
));
906 case SWAP_DEACTIVATING
:
907 case SWAP_DEACTIVATING_SIGTERM
:
908 case SWAP_DEACTIVATING_SIGKILL
:
912 case SWAP_ACTIVATING
:
913 case SWAP_ACTIVATING_DONE
:
914 /* There's a control process pending, directly enter kill mode */
915 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_SUCCESS
);
919 if (detect_container() > 0)
922 swap_enter_deactivating(s
);
926 /* If we are currently cleaning, then abort it, brutally. */
927 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
931 assert_not_reached();
935 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
936 Swap
*s
= ASSERT_PTR(SWAP(u
));
941 (void) serialize_item(f
, "state", swap_state_to_string(s
->state
));
942 (void) serialize_item(f
, "result", swap_result_to_string(s
->result
));
943 (void) serialize_pidref(f
, fds
, "control-pid", &s
->control_pid
);
945 if (s
->control_command_id
>= 0)
946 (void) serialize_item(f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
951 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
952 Swap
*s
= ASSERT_PTR(SWAP(u
));
956 if (streq(key
, "state")) {
959 state
= swap_state_from_string(value
);
961 log_unit_debug(u
, "Failed to parse state value: %s", value
);
963 s
->deserialized_state
= state
;
964 } else if (streq(key
, "result")) {
967 f
= swap_result_from_string(value
);
969 log_unit_debug(u
, "Failed to parse result value: %s", value
);
970 else if (f
!= SWAP_SUCCESS
)
972 } else if (streq(key
, "control-pid")) {
974 if (!pidref_is_set(&s
->control_pid
))
975 (void) deserialize_pidref(fds
, value
, &s
->control_pid
);
977 } else if (streq(key
, "control-command")) {
980 id
= swap_exec_command_from_string(value
);
982 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
984 s
->control_command_id
= id
;
985 s
->control_command
= s
->exec_command
+ id
;
988 log_unit_debug(u
, "Unknown serialization key: %s", key
);
993 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
994 Swap
*s
= ASSERT_PTR(SWAP(u
));
999 if (pid
!= s
->control_pid
.pid
)
1002 /* Let's scan /proc/swaps before we process SIGCHLD. For the reasoning see the similar code in
1004 (void) swap_process_proc_swaps(u
->manager
);
1006 pidref_done(&s
->control_pid
);
1008 if (is_clean_exit(code
, status
, EXIT_CLEAN_COMMAND
, NULL
))
1010 else if (code
== CLD_EXITED
)
1011 f
= SWAP_FAILURE_EXIT_CODE
;
1012 else if (code
== CLD_KILLED
)
1013 f
= SWAP_FAILURE_SIGNAL
;
1014 else if (code
== CLD_DUMPED
)
1015 f
= SWAP_FAILURE_CORE_DUMP
;
1017 assert_not_reached();
1019 if (s
->result
== SWAP_SUCCESS
)
1022 if (s
->control_command
) {
1023 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
1025 s
->control_command
= NULL
;
1026 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
1029 unit_log_process_exit(
1032 swap_exec_command_to_string(s
->control_command_id
),
1038 case SWAP_ACTIVATING
:
1039 case SWAP_ACTIVATING_DONE
:
1041 if (f
== SWAP_SUCCESS
|| s
->from_proc_swaps
)
1042 swap_enter_active(s
, f
);
1044 swap_enter_dead(s
, f
);
1047 case SWAP_DEACTIVATING
:
1048 case SWAP_DEACTIVATING_SIGKILL
:
1049 case SWAP_DEACTIVATING_SIGTERM
:
1051 swap_enter_dead_or_active(s
, f
);
1055 if (s
->clean_result
== SWAP_SUCCESS
)
1056 s
->clean_result
= f
;
1058 swap_enter_dead(s
, SWAP_SUCCESS
);
1062 assert_not_reached();
1065 /* Notify clients about changed exit status */
1066 unit_add_to_dbus_queue(u
);
1069 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1070 Swap
*s
= ASSERT_PTR(SWAP(userdata
));
1072 assert(s
->timer_event_source
== source
);
1076 case SWAP_ACTIVATING
:
1077 case SWAP_ACTIVATING_DONE
:
1078 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1079 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1082 case SWAP_DEACTIVATING
:
1083 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1084 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1087 case SWAP_DEACTIVATING_SIGTERM
:
1088 if (s
->kill_context
.send_sigkill
) {
1089 log_unit_warning(UNIT(s
), "Swap process timed out. Killing.");
1090 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1092 log_unit_warning(UNIT(s
), "Swap process timed out. Skipping SIGKILL. Ignoring.");
1093 swap_enter_dead_or_active(s
, SWAP_FAILURE_TIMEOUT
);
1097 case SWAP_DEACTIVATING_SIGKILL
:
1098 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1099 swap_enter_dead_or_active(s
, SWAP_FAILURE_TIMEOUT
);
1103 log_unit_warning(UNIT(s
), "Cleaning timed out. killing.");
1105 if (s
->clean_result
== SWAP_SUCCESS
)
1106 s
->clean_result
= SWAP_FAILURE_TIMEOUT
;
1108 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, 0);
1112 assert_not_reached();
1118 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1121 rewind(m
->proc_swaps
);
1123 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1125 for (unsigned i
= 1;; i
++) {
1126 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1129 k
= fscanf(m
->proc_swaps
,
1130 "%ms " /* device/file */
1131 "%*s " /* type of swap */
1132 "%*s " /* swap size */
1134 "%i\n", /* priority */
1140 log_warning("Failed to parse /proc/swaps:%u, skipping.", i
);
1144 ssize_t l
= cunescape(dev
, UNESCAPE_RELAX
, &d
);
1146 return log_error_errno(l
, "Failed to unescape device path: %m");
1148 device_found_node(m
, d
, DEVICE_FOUND_SWAP
, DEVICE_FOUND_SWAP
);
1150 (void) swap_process_new(m
, d
, prio
, set_flags
);
1156 static int swap_process_proc_swaps(Manager
*m
) {
1161 r
= swap_load_proc_swaps(m
, true);
1163 /* Reset flags, just in case, for late calls */
1164 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1165 Swap
*swap
= SWAP(u
);
1169 swap
->is_active
= swap
->just_activated
= false;
1175 manager_dispatch_load_queue(m
);
1177 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1178 Swap
*swap
= SWAP(u
);
1182 if (!swap
->is_active
) {
1184 swap_unset_proc_swaps(swap
);
1186 switch (swap
->state
) {
1189 /* This has just been deactivated */
1190 swap_enter_dead(swap
, SWAP_SUCCESS
);
1195 swap_set_state(swap
, swap
->state
);
1199 device_found_node(m
, swap
->what
, DEVICE_NOT_FOUND
, DEVICE_FOUND_SWAP
);
1201 } else if (swap
->just_activated
) {
1203 /* New swap entry */
1205 switch (swap
->state
) {
1209 (void) unit_acquire_invocation_id(u
);
1210 swap_cycle_clear(swap
);
1211 swap_enter_active(swap
, SWAP_SUCCESS
);
1214 case SWAP_ACTIVATING
:
1215 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1219 /* Nothing really changed, but let's issue an notification call nonetheless,
1220 * in case somebody is waiting for this. */
1221 swap_set_state(swap
, swap
->state
);
1225 /* Reset the flags for later calls */
1226 swap
->is_active
= swap
->just_activated
= false;
1232 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1233 Manager
*m
= ASSERT_PTR(userdata
);
1235 assert(revents
& EPOLLPRI
);
1237 return swap_process_proc_swaps(m
);
1240 static Unit
* swap_following(Unit
*u
) {
1241 Swap
*s
= ASSERT_PTR(SWAP(u
));
1244 /* If the user configured the swap through /etc/fstab or
1245 * a device unit, follow that. */
1247 if (s
->from_fragment
)
1250 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1251 if (other
->from_fragment
)
1254 /* Otherwise, make everybody follow the unit that's named after
1255 * the swap device in the kernel */
1257 if (streq_ptr(s
->what
, s
->devnode
))
1260 LIST_FOREACH(same_devnode
, other
, s
->same_devnode_next
)
1261 if (streq_ptr(other
->what
, other
->devnode
))
1264 LIST_FOREACH_BACKWARDS(same_devnode
, other
, s
->same_devnode_prev
) {
1265 if (streq_ptr(other
->what
, other
->devnode
))
1271 /* Fall back to the first on the list */
1275 static int swap_following_set(Unit
*u
, Set
**ret
) {
1276 Swap
*s
= ASSERT_PTR(SWAP(u
));
1277 _cleanup_set_free_ Set
*set
= NULL
;
1282 if (LIST_JUST_US(same_devnode
, s
)) {
1287 set
= set_new(NULL
);
1291 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1292 r
= set_put(set
, other
);
1297 *ret
= TAKE_PTR(set
);
1301 static void swap_shutdown(Manager
*m
) {
1304 m
->swap_event_source
= sd_event_source_disable_unref(m
->swap_event_source
);
1305 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1306 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1309 static void swap_enumerate(Manager
*m
) {
1314 if (!m
->proc_swaps
) {
1315 m
->proc_swaps
= fopen("/proc/swaps", "re");
1316 if (!m
->proc_swaps
) {
1317 if (errno
== ENOENT
)
1318 log_debug_errno(errno
, "Not swap enabled, skipping enumeration.");
1320 log_warning_errno(errno
, "Failed to open %s, ignoring: %m", "/proc/swaps");
1325 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1327 log_error_errno(r
, "Failed to watch /proc/swaps: %m");
1331 /* Dispatch this before we dispatch SIGCHLD, so that
1332 * we always get the events from /proc/swaps before
1333 * the SIGCHLD of /sbin/swapon. */
1334 r
= sd_event_source_set_priority(m
->swap_event_source
, EVENT_PRIORITY_SWAP_TABLE
);
1336 log_error_errno(r
, "Failed to change /proc/swaps priority: %m");
1340 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1343 r
= swap_load_proc_swaps(m
, false);
1353 int swap_process_device_new(Manager
*m
, sd_device
*dev
) {
1354 _cleanup_free_
char *e
= NULL
;
1362 if (sd_device_get_devname(dev
, &dn
) < 0)
1365 r
= unit_name_from_path(dn
, ".swap", &e
);
1367 log_debug_errno(r
, "Cannot convert device name '%s' to unit name, ignoring: %m", dn
);
1371 u
= manager_get_unit(m
, e
);
1373 r
= swap_set_devnode(SWAP(u
), dn
);
1375 FOREACH_DEVICE_DEVLINK(dev
, devlink
) {
1376 _cleanup_free_
char *n
= NULL
;
1379 q
= unit_name_from_path(devlink
, ".swap", &n
);
1380 if (q
== -EINVAL
) /* If the name is not convertible to unit name, we can't manage it */
1385 u
= manager_get_unit(m
, n
);
1387 q
= swap_set_devnode(SWAP(u
), dn
);
1396 int swap_process_device_remove(Manager
*m
, sd_device
*dev
) {
1401 r
= sd_device_get_devname(dev
, &dn
);
1406 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
)))
1407 RET_GATHER(r
, swap_set_devnode(s
, NULL
));
1412 static void swap_reset_failed(Unit
*u
) {
1413 Swap
*s
= ASSERT_PTR(SWAP(u
));
1415 if (s
->state
== SWAP_FAILED
)
1416 swap_set_state(s
, SWAP_DEAD
);
1418 s
->result
= SWAP_SUCCESS
;
1419 s
->clean_result
= SWAP_SUCCESS
;
1422 static void swap_handoff_timestamp(
1424 const struct ucred
*ucred
,
1425 const dual_timestamp
*ts
) {
1427 Swap
*s
= ASSERT_PTR(SWAP(u
));
1432 if (s
->control_pid
.pid
== ucred
->pid
&& s
->control_command
) {
1433 exec_status_handoff(&s
->control_command
->exec_status
, ucred
, ts
);
1434 unit_add_to_dbus_queue(u
);
1438 static int swap_get_timeout(Unit
*u
, usec_t
*timeout
) {
1439 Swap
*s
= ASSERT_PTR(SWAP(u
));
1443 if (!s
->timer_event_source
)
1446 r
= sd_event_source_get_time(s
->timer_event_source
, &t
);
1449 if (t
== USEC_INFINITY
)
1456 static bool swap_supported(void) {
1457 static int supported
= -1;
1459 /* If swap support is not available in the kernel, or we are
1460 * running in a container we don't support swap units, and any
1461 * attempts to starting one should fail immediately. */
1465 access("/proc/swaps", F_OK
) >= 0 &&
1466 detect_container() <= 0;
1471 static PidRef
* swap_control_pid(Unit
*u
) {
1472 return &ASSERT_PTR(SWAP(u
))->control_pid
;
1475 static int swap_clean(Unit
*u
, ExecCleanMask mask
) {
1476 Swap
*s
= ASSERT_PTR(SWAP(u
));
1477 _cleanup_strv_free_
char **l
= NULL
;
1482 if (s
->state
!= SWAP_DEAD
)
1485 r
= exec_context_get_clean_directories(&s
->exec_context
, u
->manager
->prefix
, mask
, &l
);
1489 if (strv_isempty(l
))
1492 swap_unwatch_control_pid(s
);
1493 s
->clean_result
= SWAP_SUCCESS
;
1494 s
->control_command
= NULL
;
1495 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
1497 r
= swap_arm_timer(s
, /* relative= */ true, s
->exec_context
.timeout_clean_usec
);
1499 log_unit_warning_errno(u
, r
, "Failed to install timer: %m");
1503 r
= unit_fork_and_watch_rm_rf(u
, l
, &s
->control_pid
);
1505 log_unit_warning_errno(u
, r
, "Failed to spawn cleaning task: %m");
1509 swap_set_state(s
, SWAP_CLEANING
);
1513 s
->clean_result
= SWAP_FAILURE_RESOURCES
;
1514 s
->timer_event_source
= sd_event_source_disable_unref(s
->timer_event_source
);
1518 static int swap_can_clean(Unit
*u
, ExecCleanMask
*ret
) {
1519 Swap
*s
= ASSERT_PTR(SWAP(u
));
1521 return exec_context_get_clean_mask(&s
->exec_context
, ret
);
1524 static int swap_can_start(Unit
*u
) {
1525 Swap
*s
= ASSERT_PTR(SWAP(u
));
1528 r
= unit_test_start_limit(u
);
1530 swap_enter_dead(s
, SWAP_FAILURE_START_LIMIT_HIT
);
1537 int swap_get_priority(const Swap
*s
) {
1540 if (s
->from_proc_swaps
&& s
->parameters_proc_swaps
.priority_set
)
1541 return s
->parameters_proc_swaps
.priority
;
1543 if (s
->from_fragment
&& s
->parameters_fragment
.priority_set
)
1544 return s
->parameters_fragment
.priority
;
1549 const char* swap_get_options(const Swap
*s
) {
1552 if (s
->from_fragment
)
1553 return s
->parameters_fragment
.options
;
1558 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1559 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1560 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1563 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1565 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1566 [SWAP_SUCCESS
] = "success",
1567 [SWAP_FAILURE_RESOURCES
] = "resources",
1568 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1569 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1570 [SWAP_FAILURE_SIGNAL
] = "signal",
1571 [SWAP_FAILURE_CORE_DUMP
] = "core-dump",
1572 [SWAP_FAILURE_START_LIMIT_HIT
] = "start-limit-hit",
1575 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1577 const UnitVTable swap_vtable
= {
1578 .object_size
= sizeof(Swap
),
1579 .exec_context_offset
= offsetof(Swap
, exec_context
),
1580 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1581 .kill_context_offset
= offsetof(Swap
, kill_context
),
1582 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1583 .cgroup_runtime_offset
= offsetof(Swap
, cgroup_runtime
),
1589 .private_section
= "Swap",
1597 .coldplug
= swap_coldplug
,
1601 .start
= swap_start
,
1604 .clean
= swap_clean
,
1605 .can_clean
= swap_can_clean
,
1607 .get_timeout
= swap_get_timeout
,
1609 .serialize
= swap_serialize
,
1610 .deserialize_item
= swap_deserialize_item
,
1612 .active_state
= swap_active_state
,
1613 .sub_state_to_string
= swap_sub_state_to_string
,
1615 .will_restart
= unit_will_restart_default
,
1617 .may_gc
= swap_may_gc
,
1618 .is_extrinsic
= swap_is_extrinsic
,
1620 .sigchld_event
= swap_sigchld_event
,
1622 .reset_failed
= swap_reset_failed
,
1624 .notify_handoff_timestamp
= swap_handoff_timestamp
,
1626 .control_pid
= swap_control_pid
,
1628 .bus_set_property
= bus_swap_set_property
,
1629 .bus_commit_properties
= bus_swap_commit_properties
,
1631 .following
= swap_following
,
1632 .following_set
= swap_following_set
,
1634 .enumerate
= swap_enumerate
,
1635 .shutdown
= swap_shutdown
,
1636 .supported
= swap_supported
,
1638 .status_message_formats
= {
1639 .starting_stopping
= {
1640 [0] = "Activating swap %s...",
1641 [1] = "Deactivating swap %s...",
1643 .finished_start_job
= {
1644 [JOB_DONE
] = "Activated swap %s.",
1645 [JOB_FAILED
] = "Failed to activate swap %s.",
1646 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1648 .finished_stop_job
= {
1649 [JOB_DONE
] = "Deactivated swap %s.",
1650 [JOB_FAILED
] = "Failed deactivating swap %s.",
1651 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",
1655 .can_start
= swap_can_start
,
1657 .notify_plymouth
= true,