2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <sys/epoll.h>
27 #include "alloc-util.h"
28 #include "dbus-swap.h"
30 #include "exit-status.h"
32 #include "formats-util.h"
33 #include "fstab-util.h"
34 #include "parse-util.h"
35 #include "path-util.h"
36 #include "process-util.h"
38 #include "string-table.h"
39 #include "string-util.h"
41 #include "udev-util.h"
42 #include "unit-name.h"
46 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
47 [SWAP_DEAD
] = UNIT_INACTIVE
,
48 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
49 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
50 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
51 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
52 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
53 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
54 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
55 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
56 [SWAP_FAILED
] = UNIT_FAILED
59 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
60 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
62 static void swap_unset_proc_swaps(Swap
*s
) {
65 if (!s
->from_proc_swaps
)
68 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
70 s
->from_proc_swaps
= false;
73 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
80 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
84 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
87 first
= hashmap_get(swaps
, s
->devnode
);
89 LIST_REMOVE(same_devnode
, first
, s
);
91 hashmap_replace(swaps
, first
->devnode
, first
);
93 hashmap_remove(swaps
, s
->devnode
);
95 s
->devnode
= mfree(s
->devnode
);
99 s
->devnode
= strdup(devnode
);
103 first
= hashmap_get(swaps
, s
->devnode
);
104 LIST_PREPEND(same_devnode
, first
, s
);
106 return hashmap_replace(swaps
, first
->devnode
, first
);
112 static void swap_init(Unit
*u
) {
116 assert(UNIT(s
)->load_state
== UNIT_STUB
);
118 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
120 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
121 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
123 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
125 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
127 u
->ignore_on_isolate
= true;
130 static void swap_unwatch_control_pid(Swap
*s
) {
133 if (s
->control_pid
<= 0)
136 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
140 static void swap_done(Unit
*u
) {
145 swap_unset_proc_swaps(s
);
146 swap_set_devnode(s
, NULL
);
148 s
->what
= mfree(s
->what
);
149 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
150 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
152 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
153 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
154 s
->control_command
= NULL
;
156 dynamic_creds_unref(&s
->dynamic_creds
);
158 swap_unwatch_control_pid(s
);
160 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
163 static int swap_arm_timer(Swap
*s
, usec_t usec
) {
168 if (s
->timer_event_source
) {
169 r
= sd_event_source_set_time(s
->timer_event_source
, usec
);
173 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
176 if (usec
== USEC_INFINITY
)
179 r
= sd_event_add_time(
180 UNIT(s
)->manager
->event
,
181 &s
->timer_event_source
,
184 swap_dispatch_timer
, s
);
188 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
193 static int swap_add_device_links(Swap
*s
) {
199 if (!s
->from_fragment
)
202 if (is_device_path(s
->what
))
203 return unit_add_node_link(UNIT(s
), s
->what
, MANAGER_IS_SYSTEM(UNIT(s
)->manager
), UNIT_BINDS_TO
);
205 /* File based swap devices need to be ordered after
206 * systemd-remount-fs.service, since they might need a
207 * writable file system. */
208 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
211 static int swap_add_default_dependencies(Swap
*s
) {
216 if (!UNIT(s
)->default_dependencies
)
219 if (!MANAGER_IS_SYSTEM(UNIT(s
)->manager
))
222 if (detect_container() > 0)
225 /* swap units generated for the swap dev links are missing the
226 * ordering dep against the swap target. */
227 r
= unit_add_dependency_by_name(UNIT(s
), UNIT_BEFORE
, SPECIAL_SWAP_TARGET
, NULL
, true);
231 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
234 static int swap_verify(Swap
*s
) {
235 _cleanup_free_
char *e
= NULL
;
238 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
241 r
= unit_name_from_path(s
->what
, ".swap", &e
);
243 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
245 if (!unit_has_name(UNIT(s
), e
)) {
246 log_unit_error(UNIT(s
), "Value of What= and unit name do not match, not loading.");
250 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
251 log_unit_error(UNIT(s
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
258 static int swap_load_devnode(Swap
*s
) {
259 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
265 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
268 d
= udev_device_new_from_devnum(UNIT(s
)->manager
->udev
, 'b', st
.st_rdev
);
272 p
= udev_device_get_devnode(d
);
276 return swap_set_devnode(s
, p
);
279 static int swap_load(Unit
*u
) {
284 assert(u
->load_state
== UNIT_STUB
);
286 /* Load a .swap file */
287 r
= unit_load_fragment_and_dropin_optional(u
);
291 if (u
->load_state
== UNIT_LOADED
) {
293 if (UNIT(s
)->fragment_path
)
294 s
->from_fragment
= true;
297 if (s
->parameters_fragment
.what
)
298 s
->what
= strdup(s
->parameters_fragment
.what
);
299 else if (s
->parameters_proc_swaps
.what
)
300 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
302 r
= unit_name_to_path(u
->id
, &s
->what
);
311 path_kill_slashes(s
->what
);
313 if (!UNIT(s
)->description
) {
314 r
= unit_set_description(u
, s
->what
);
319 r
= unit_require_mounts_for(UNIT(s
), s
->what
);
323 r
= swap_add_device_links(s
);
327 r
= swap_load_devnode(s
);
331 r
= unit_patch_contexts(u
);
335 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
339 r
= unit_set_default_slice(u
);
343 r
= swap_add_default_dependencies(s
);
348 return swap_verify(s
);
351 static int swap_setup_unit(
354 const char *what_proc_swaps
,
358 _cleanup_free_
char *e
= NULL
;
366 assert(what_proc_swaps
);
368 r
= unit_name_from_path(what
, ".swap", &e
);
370 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
372 u
= manager_get_unit(m
, e
);
375 SWAP(u
)->from_proc_swaps
&&
376 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
)) {
377 log_error("Swap %s appeared twice with different device paths %s and %s", e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
384 r
= unit_new_for_name(m
, sizeof(Swap
), e
, &u
);
388 SWAP(u
)->what
= strdup(what
);
389 if (!SWAP(u
)->what
) {
394 unit_add_to_load_queue(u
);
398 p
= &SWAP(u
)->parameters_proc_swaps
;
401 p
->what
= strdup(what_proc_swaps
);
409 SWAP(u
)->is_active
= true;
410 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
413 SWAP(u
)->from_proc_swaps
= true;
415 p
->priority
= priority
;
417 unit_add_to_dbus_queue(u
);
421 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
429 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
430 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
431 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
438 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
442 /* If this is a block device, then let's add duplicates for
443 * all other names of this block device */
444 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
447 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
451 /* Add the main device node */
452 dn
= udev_device_get_devnode(d
);
453 if (dn
&& !streq(dn
, device
))
454 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
456 /* Add additional units for all symlinks */
457 first
= udev_device_get_devlinks_list_entry(d
);
458 udev_list_entry_foreach(item
, first
) {
461 /* Don't bother with the /dev/block links */
462 p
= udev_list_entry_get_name(item
);
464 if (streq(p
, device
))
467 if (path_startswith(p
, "/dev/block/"))
470 if (stat(p
, &st
) >= 0)
471 if (!S_ISBLK(st
.st_mode
) ||
472 st
.st_rdev
!= udev_device_get_devnum(d
))
475 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
481 static void swap_set_state(Swap
*s
, SwapState state
) {
487 old_state
= s
->state
;
490 if (state
!= SWAP_ACTIVATING
&&
491 state
!= SWAP_ACTIVATING_SIGTERM
&&
492 state
!= SWAP_ACTIVATING_SIGKILL
&&
493 state
!= SWAP_ACTIVATING_DONE
&&
494 state
!= SWAP_DEACTIVATING
&&
495 state
!= SWAP_DEACTIVATING_SIGTERM
&&
496 state
!= SWAP_DEACTIVATING_SIGKILL
) {
497 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
498 swap_unwatch_control_pid(s
);
499 s
->control_command
= NULL
;
500 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
503 if (state
!= old_state
)
504 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
506 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
508 /* If there other units for the same device node have a job
509 queued it might be worth checking again if it is runnable
510 now. This is necessary, since swap_start() refuses
511 operation with EAGAIN if there's already another job for
512 the same device node queued. */
513 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
514 if (UNIT(other
)->job
)
515 job_add_to_run_queue(UNIT(other
)->job
);
518 static int swap_coldplug(Unit
*u
) {
520 SwapState new_state
= SWAP_DEAD
;
524 assert(s
->state
== SWAP_DEAD
);
526 if (s
->deserialized_state
!= s
->state
)
527 new_state
= s
->deserialized_state
;
528 else if (s
->from_proc_swaps
)
529 new_state
= SWAP_ACTIVE
;
531 if (new_state
== s
->state
)
534 if (s
->control_pid
> 0 &&
535 pid_is_unwaited(s
->control_pid
) &&
538 SWAP_ACTIVATING_SIGTERM
,
539 SWAP_ACTIVATING_SIGKILL
,
540 SWAP_ACTIVATING_DONE
,
542 SWAP_DEACTIVATING_SIGTERM
,
543 SWAP_DEACTIVATING_SIGKILL
)) {
545 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
549 r
= swap_arm_timer(s
, usec_add(u
->state_change_timestamp
.monotonic
, s
->timeout_usec
));
554 if (!IN_SET(new_state
, SWAP_DEAD
, SWAP_FAILED
))
555 (void) unit_setup_dynamic_creds(u
);
557 swap_set_state(s
, new_state
);
561 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
568 if (s
->from_proc_swaps
)
569 p
= &s
->parameters_proc_swaps
;
570 else if (s
->from_fragment
)
571 p
= &s
->parameters_fragment
;
579 "%sFrom /proc/swaps: %s\n"
580 "%sFrom fragment: %s\n",
581 prefix
, swap_state_to_string(s
->state
),
582 prefix
, swap_result_to_string(s
->result
),
584 prefix
, yes_no(s
->from_proc_swaps
),
585 prefix
, yes_no(s
->from_fragment
));
588 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
595 prefix
, strempty(p
->options
));
597 if (s
->control_pid
> 0)
599 "%sControl PID: "PID_FMT
"\n",
600 prefix
, s
->control_pid
);
602 exec_context_dump(&s
->exec_context
, f
, prefix
);
603 kill_context_dump(&s
->kill_context
, f
, prefix
);
606 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
609 ExecParameters exec_params
= {
610 .flags
= EXEC_APPLY_PERMISSIONS
|EXEC_APPLY_CHROOT
|EXEC_APPLY_TTY_STDIN
,
620 (void) unit_realize_cgroup(UNIT(s
));
621 if (s
->reset_cpu_usage
) {
622 (void) unit_reset_cpu_usage(UNIT(s
));
623 s
->reset_cpu_usage
= false;
626 r
= unit_setup_exec_runtime(UNIT(s
));
630 r
= unit_setup_dynamic_creds(UNIT(s
));
634 r
= swap_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->timeout_usec
));
638 exec_params
.environment
= UNIT(s
)->manager
->environment
;
639 exec_params
.flags
|= UNIT(s
)->manager
->confirm_spawn
? EXEC_CONFIRM_SPAWN
: 0;
640 exec_params
.cgroup_supported
= UNIT(s
)->manager
->cgroup_supported
;
641 exec_params
.cgroup_path
= UNIT(s
)->cgroup_path
;
642 exec_params
.cgroup_delegate
= s
->cgroup_context
.delegate
;
643 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(s
)->manager
);
645 r
= exec_spawn(UNIT(s
),
655 r
= unit_watch_pid(UNIT(s
), pid
);
657 /* FIXME: we need to do something here */
665 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
669 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
672 if (s
->result
== SWAP_SUCCESS
)
675 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
677 exec_runtime_destroy(s
->exec_runtime
);
678 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
680 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
682 unit_unref_uid_gid(UNIT(s
), true);
684 dynamic_creds_destroy(&s
->dynamic_creds
);
687 static void swap_enter_active(Swap
*s
, SwapResult f
) {
690 if (s
->result
== SWAP_SUCCESS
)
693 swap_set_state(s
, SWAP_ACTIVE
);
696 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
701 if (s
->result
== SWAP_SUCCESS
)
704 r
= unit_kill_context(
707 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
708 KILL_KILL
: KILL_TERMINATE
,
716 r
= swap_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->timeout_usec
));
720 swap_set_state(s
, state
);
721 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
722 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
723 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
724 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
726 swap_enter_dead(s
, SWAP_SUCCESS
);
731 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
732 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
735 static void swap_enter_activating(Swap
*s
) {
736 _cleanup_free_
char *opts
= NULL
;
741 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
742 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
744 if (s
->from_fragment
) {
747 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
749 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
750 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
751 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
753 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
754 if (s
->parameters_fragment
.options
)
755 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
757 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
763 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
767 if (s
->parameters_fragment
.options
|| opts
) {
768 r
= exec_command_append(s
->control_command
, "-o",
769 opts
? : s
->parameters_fragment
.options
, NULL
);
774 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
778 swap_unwatch_control_pid(s
);
780 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
784 swap_set_state(s
, SWAP_ACTIVATING
);
789 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
790 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
793 static void swap_enter_deactivating(Swap
*s
) {
798 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
799 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
801 r
= exec_command_set(s
->control_command
,
808 swap_unwatch_control_pid(s
);
810 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
814 swap_set_state(s
, SWAP_DEACTIVATING
);
819 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
820 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
823 static int swap_start(Unit
*u
) {
824 Swap
*s
= SWAP(u
), *other
;
829 /* We cannot fulfill this request right now, try again later
832 if (s
->state
== SWAP_DEACTIVATING
||
833 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
834 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
835 s
->state
== SWAP_ACTIVATING_SIGTERM
||
836 s
->state
== SWAP_ACTIVATING_SIGKILL
)
839 if (s
->state
== SWAP_ACTIVATING
)
842 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
844 if (detect_container() > 0)
847 /* If there's a job for another swap unit for the same node
848 * running, then let's not dispatch this one for now, and wait
849 * until that other job has finished. */
850 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
851 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
854 r
= unit_start_limit_test(u
);
856 swap_enter_dead(s
, SWAP_FAILURE_START_LIMIT_HIT
);
860 r
= unit_acquire_invocation_id(u
);
864 s
->result
= SWAP_SUCCESS
;
865 s
->reset_cpu_usage
= true;
867 swap_enter_activating(s
);
871 static int swap_stop(Unit
*u
) {
876 if (s
->state
== SWAP_DEACTIVATING
||
877 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
878 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
879 s
->state
== SWAP_ACTIVATING_SIGTERM
||
880 s
->state
== SWAP_ACTIVATING_SIGKILL
)
883 assert(s
->state
== SWAP_ACTIVATING
||
884 s
->state
== SWAP_ACTIVATING_DONE
||
885 s
->state
== SWAP_ACTIVE
);
887 if (detect_container() > 0)
890 swap_enter_deactivating(s
);
894 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
901 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
902 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
904 if (s
->control_pid
> 0)
905 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
907 if (s
->control_command_id
>= 0)
908 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
913 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
919 if (streq(key
, "state")) {
922 state
= swap_state_from_string(value
);
924 log_unit_debug(u
, "Failed to parse state value: %s", value
);
926 s
->deserialized_state
= state
;
927 } else if (streq(key
, "result")) {
930 f
= swap_result_from_string(value
);
932 log_unit_debug(u
, "Failed to parse result value: %s", value
);
933 else if (f
!= SWAP_SUCCESS
)
935 } else if (streq(key
, "control-pid")) {
938 if (parse_pid(value
, &pid
) < 0)
939 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
941 s
->control_pid
= pid
;
943 } else if (streq(key
, "control-command")) {
946 id
= swap_exec_command_from_string(value
);
948 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
950 s
->control_command_id
= id
;
951 s
->control_command
= s
->exec_command
+ id
;
954 log_unit_debug(u
, "Unknown serialization key: %s", key
);
959 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
962 return state_translation_table
[SWAP(u
)->state
];
965 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
968 return swap_state_to_string(SWAP(u
)->state
);
971 _pure_
static bool swap_check_gc(Unit
*u
) {
976 return s
->from_proc_swaps
;
979 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
986 if (pid
!= s
->control_pid
)
991 if (is_clean_exit(code
, status
, EXIT_CLEAN_COMMAND
, NULL
))
993 else if (code
== CLD_EXITED
)
994 f
= SWAP_FAILURE_EXIT_CODE
;
995 else if (code
== CLD_KILLED
)
996 f
= SWAP_FAILURE_SIGNAL
;
997 else if (code
== CLD_DUMPED
)
998 f
= SWAP_FAILURE_CORE_DUMP
;
1000 assert_not_reached("Unknown code");
1002 if (s
->result
== SWAP_SUCCESS
)
1005 if (s
->control_command
) {
1006 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
1008 s
->control_command
= NULL
;
1009 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
1012 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
1013 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
1017 case SWAP_ACTIVATING
:
1018 case SWAP_ACTIVATING_DONE
:
1019 case SWAP_ACTIVATING_SIGTERM
:
1020 case SWAP_ACTIVATING_SIGKILL
:
1022 if (f
== SWAP_SUCCESS
)
1023 swap_enter_active(s
, f
);
1025 swap_enter_dead(s
, f
);
1028 case SWAP_DEACTIVATING
:
1029 case SWAP_DEACTIVATING_SIGKILL
:
1030 case SWAP_DEACTIVATING_SIGTERM
:
1032 swap_enter_dead(s
, f
);
1036 assert_not_reached("Uh, control process died at wrong time.");
1039 /* Notify clients about changed exit status */
1040 unit_add_to_dbus_queue(u
);
1043 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1044 Swap
*s
= SWAP(userdata
);
1047 assert(s
->timer_event_source
== source
);
1051 case SWAP_ACTIVATING
:
1052 case SWAP_ACTIVATING_DONE
:
1053 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1054 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1057 case SWAP_DEACTIVATING
:
1058 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1059 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1062 case SWAP_ACTIVATING_SIGTERM
:
1063 if (s
->kill_context
.send_sigkill
) {
1064 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1065 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1067 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1068 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1072 case SWAP_DEACTIVATING_SIGTERM
:
1073 if (s
->kill_context
.send_sigkill
) {
1074 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1075 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1077 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1078 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1082 case SWAP_ACTIVATING_SIGKILL
:
1083 case SWAP_DEACTIVATING_SIGKILL
:
1084 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1085 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1089 assert_not_reached("Timeout at wrong time.");
1095 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1101 rewind(m
->proc_swaps
);
1103 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1106 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1109 k
= fscanf(m
->proc_swaps
,
1110 "%ms " /* device/file */
1111 "%*s " /* type of swap */
1112 "%*s " /* swap size */
1114 "%i\n", /* priority */
1120 log_warning("Failed to parse /proc/swaps:%u.", i
);
1124 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1127 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1129 k
= swap_process_new(m
, d
, prio
, set_flags
);
1137 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1138 Manager
*m
= userdata
;
1143 assert(revents
& EPOLLPRI
);
1145 r
= swap_load_proc_swaps(m
, true);
1147 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1149 /* Reset flags, just in case, for late calls */
1150 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1151 Swap
*swap
= SWAP(u
);
1153 swap
->is_active
= swap
->just_activated
= false;
1159 manager_dispatch_load_queue(m
);
1161 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1162 Swap
*swap
= SWAP(u
);
1164 if (!swap
->is_active
) {
1165 /* This has just been deactivated */
1167 swap_unset_proc_swaps(swap
);
1169 switch (swap
->state
) {
1172 swap_enter_dead(swap
, SWAP_SUCCESS
);
1177 swap_set_state(swap
, swap
->state
);
1182 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1184 } else if (swap
->just_activated
) {
1186 /* New swap entry */
1188 switch (swap
->state
) {
1192 (void) unit_acquire_invocation_id(UNIT(swap
));
1193 swap_enter_active(swap
, SWAP_SUCCESS
);
1196 case SWAP_ACTIVATING
:
1197 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1201 /* Nothing really changed, but let's
1202 * issue an notification call
1203 * nonetheless, in case somebody is
1204 * waiting for this. */
1205 swap_set_state(swap
, swap
->state
);
1210 /* Reset the flags for later calls */
1211 swap
->is_active
= swap
->just_activated
= false;
1217 static Unit
*swap_following(Unit
*u
) {
1219 Swap
*other
, *first
= NULL
;
1223 /* If the user configured the swap through /etc/fstab or
1224 * a device unit, follow that. */
1226 if (s
->from_fragment
)
1229 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1230 if (other
->from_fragment
)
1233 /* Otherwise, make everybody follow the unit that's named after
1234 * the swap device in the kernel */
1236 if (streq_ptr(s
->what
, s
->devnode
))
1239 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1240 if (streq_ptr(other
->what
, other
->devnode
))
1243 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1244 if (streq_ptr(other
->what
, other
->devnode
))
1250 /* Fall back to the first on the list */
1254 static int swap_following_set(Unit
*u
, Set
**_set
) {
1255 Swap
*s
= SWAP(u
), *other
;
1262 if (LIST_JUST_US(same_devnode
, s
)) {
1267 set
= set_new(NULL
);
1271 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1272 r
= set_put(set
, other
);
1285 static void swap_shutdown(Manager
*m
) {
1288 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1290 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1292 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1295 static void swap_enumerate(Manager
*m
) {
1300 if (!m
->proc_swaps
) {
1301 m
->proc_swaps
= fopen("/proc/swaps", "re");
1302 if (!m
->proc_swaps
) {
1303 if (errno
== ENOENT
)
1304 log_debug("Not swap enabled, skipping enumeration");
1306 log_error_errno(errno
, "Failed to open /proc/swaps: %m");
1311 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1313 log_error_errno(r
, "Failed to watch /proc/swaps: %m");
1317 /* Dispatch this before we dispatch SIGCHLD, so that
1318 * we always get the events from /proc/swaps before
1319 * the SIGCHLD of /sbin/swapon. */
1320 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1322 log_error_errno(r
, "Failed to change /proc/swaps priority: %m");
1326 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1329 r
= swap_load_proc_swaps(m
, false);
1339 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1340 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1341 _cleanup_free_
char *e
= NULL
;
1349 dn
= udev_device_get_devnode(dev
);
1353 r
= unit_name_from_path(dn
, ".swap", &e
);
1357 s
= hashmap_get(m
->units
, e
);
1359 r
= swap_set_devnode(s
, dn
);
1361 first
= udev_device_get_devlinks_list_entry(dev
);
1362 udev_list_entry_foreach(item
, first
) {
1363 _cleanup_free_
char *n
= NULL
;
1366 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1370 s
= hashmap_get(m
->units
, n
);
1372 q
= swap_set_devnode(s
, dn
);
1381 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1386 dn
= udev_device_get_devnode(dev
);
1390 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1393 q
= swap_set_devnode(s
, NULL
);
1401 static void swap_reset_failed(Unit
*u
) {
1406 if (s
->state
== SWAP_FAILED
)
1407 swap_set_state(s
, SWAP_DEAD
);
1409 s
->result
= SWAP_SUCCESS
;
1412 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1413 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1416 static int swap_get_timeout(Unit
*u
, usec_t
*timeout
) {
1421 if (!s
->timer_event_source
)
1424 r
= sd_event_source_get_time(s
->timer_event_source
, &t
);
1427 if (t
== USEC_INFINITY
)
1434 static bool swap_supported(void) {
1435 static int supported
= -1;
1437 /* If swap support is not available in the kernel, or we are
1438 * running in a container we don't support swap units, and any
1439 * attempts to starting one should fail immediately. */
1443 access("/proc/swaps", F_OK
) >= 0 &&
1444 detect_container() <= 0;
1449 static int swap_control_pid(Unit
*u
) {
1454 return s
->control_pid
;
1457 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1458 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1459 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1462 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1464 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1465 [SWAP_SUCCESS
] = "success",
1466 [SWAP_FAILURE_RESOURCES
] = "resources",
1467 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1468 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1469 [SWAP_FAILURE_SIGNAL
] = "signal",
1470 [SWAP_FAILURE_CORE_DUMP
] = "core-dump",
1471 [SWAP_FAILURE_START_LIMIT_HIT
] = "start-limit-hit",
1474 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1476 const UnitVTable swap_vtable
= {
1477 .object_size
= sizeof(Swap
),
1478 .exec_context_offset
= offsetof(Swap
, exec_context
),
1479 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1480 .kill_context_offset
= offsetof(Swap
, kill_context
),
1481 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1482 .dynamic_creds_offset
= offsetof(Swap
, dynamic_creds
),
1488 .private_section
= "Swap",
1494 .coldplug
= swap_coldplug
,
1498 .start
= swap_start
,
1503 .get_timeout
= swap_get_timeout
,
1505 .serialize
= swap_serialize
,
1506 .deserialize_item
= swap_deserialize_item
,
1508 .active_state
= swap_active_state
,
1509 .sub_state_to_string
= swap_sub_state_to_string
,
1511 .check_gc
= swap_check_gc
,
1513 .sigchld_event
= swap_sigchld_event
,
1515 .reset_failed
= swap_reset_failed
,
1517 .control_pid
= swap_control_pid
,
1519 .bus_vtable
= bus_swap_vtable
,
1520 .bus_set_property
= bus_swap_set_property
,
1521 .bus_commit_properties
= bus_swap_commit_properties
,
1523 .following
= swap_following
,
1524 .following_set
= swap_following_set
,
1526 .enumerate
= swap_enumerate
,
1527 .shutdown
= swap_shutdown
,
1528 .supported
= swap_supported
,
1530 .status_message_formats
= {
1531 .starting_stopping
= {
1532 [0] = "Activating swap %s...",
1533 [1] = "Deactivating swap %s...",
1535 .finished_start_job
= {
1536 [JOB_DONE
] = "Activated swap %s.",
1537 [JOB_FAILED
] = "Failed to activate swap %s.",
1538 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1540 .finished_stop_job
= {
1541 [JOB_DONE
] = "Deactivated swap %s.",
1542 [JOB_FAILED
] = "Failed deactivating swap %s.",
1543 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",