1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/epoll.h>
29 #include "alloc-util.h"
30 #include "dbus-swap.h"
32 #include "exit-status.h"
34 #include "formats-util.h"
35 #include "fstab-util.h"
36 #include "parse-util.h"
37 #include "path-util.h"
38 #include "process-util.h"
40 #include "string-table.h"
41 #include "string-util.h"
43 #include "udev-util.h"
44 #include "unit-name.h"
48 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
49 [SWAP_DEAD
] = UNIT_INACTIVE
,
50 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
51 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
52 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
53 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
54 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
55 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
56 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
57 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
58 [SWAP_FAILED
] = UNIT_FAILED
61 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
62 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
64 static void swap_unset_proc_swaps(Swap
*s
) {
67 if (!s
->from_proc_swaps
)
70 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
72 s
->from_proc_swaps
= false;
75 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
82 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
86 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
89 first
= hashmap_get(swaps
, s
->devnode
);
91 LIST_REMOVE(same_devnode
, first
, s
);
93 hashmap_replace(swaps
, first
->devnode
, first
);
95 hashmap_remove(swaps
, s
->devnode
);
97 s
->devnode
= mfree(s
->devnode
);
101 s
->devnode
= strdup(devnode
);
105 first
= hashmap_get(swaps
, s
->devnode
);
106 LIST_PREPEND(same_devnode
, first
, s
);
108 return hashmap_replace(swaps
, first
->devnode
, first
);
114 static void swap_init(Unit
*u
) {
118 assert(UNIT(s
)->load_state
== UNIT_STUB
);
120 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
122 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
123 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
125 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
127 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
129 u
->ignore_on_isolate
= true;
132 static void swap_unwatch_control_pid(Swap
*s
) {
135 if (s
->control_pid
<= 0)
138 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
142 static void swap_done(Unit
*u
) {
147 swap_unset_proc_swaps(s
);
148 swap_set_devnode(s
, NULL
);
150 s
->what
= mfree(s
->what
);
151 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
152 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
154 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
155 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
156 s
->control_command
= NULL
;
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
, UNIT(s
)->manager
->running_as
== MANAGER_SYSTEM
, 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 (UNIT(s
)->manager
->running_as
!= MANAGER_SYSTEM
)
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 u
= unit_new(m
, sizeof(Swap
));
388 r
= unit_add_name(u
, e
);
392 SWAP(u
)->what
= strdup(what
);
393 if (!SWAP(u
)->what
) {
398 unit_add_to_load_queue(u
);
402 p
= &SWAP(u
)->parameters_proc_swaps
;
405 p
->what
= strdup(what_proc_swaps
);
413 SWAP(u
)->is_active
= true;
414 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
417 SWAP(u
)->from_proc_swaps
= true;
419 p
->priority
= priority
;
421 unit_add_to_dbus_queue(u
);
425 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
433 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
434 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
435 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
442 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
446 /* If this is a block device, then let's add duplicates for
447 * all other names of this block device */
448 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
451 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
455 /* Add the main device node */
456 dn
= udev_device_get_devnode(d
);
457 if (dn
&& !streq(dn
, device
))
458 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
460 /* Add additional units for all symlinks */
461 first
= udev_device_get_devlinks_list_entry(d
);
462 udev_list_entry_foreach(item
, first
) {
465 /* Don't bother with the /dev/block links */
466 p
= udev_list_entry_get_name(item
);
468 if (streq(p
, device
))
471 if (path_startswith(p
, "/dev/block/"))
474 if (stat(p
, &st
) >= 0)
475 if (!S_ISBLK(st
.st_mode
) ||
476 st
.st_rdev
!= udev_device_get_devnum(d
))
479 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
485 static void swap_set_state(Swap
*s
, SwapState state
) {
491 old_state
= s
->state
;
494 if (state
!= SWAP_ACTIVATING
&&
495 state
!= SWAP_ACTIVATING_SIGTERM
&&
496 state
!= SWAP_ACTIVATING_SIGKILL
&&
497 state
!= SWAP_ACTIVATING_DONE
&&
498 state
!= SWAP_DEACTIVATING
&&
499 state
!= SWAP_DEACTIVATING_SIGTERM
&&
500 state
!= SWAP_DEACTIVATING_SIGKILL
) {
501 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
502 swap_unwatch_control_pid(s
);
503 s
->control_command
= NULL
;
504 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
507 if (state
!= old_state
)
508 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
510 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
512 /* If there other units for the same device node have a job
513 queued it might be worth checking again if it is runnable
514 now. This is necessary, since swap_start() refuses
515 operation with EAGAIN if there's already another job for
516 the same device node queued. */
517 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
518 if (UNIT(other
)->job
)
519 job_add_to_run_queue(UNIT(other
)->job
);
522 static int swap_coldplug(Unit
*u
) {
524 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 (s
->control_pid
> 0 &&
539 pid_is_unwaited(s
->control_pid
) &&
542 SWAP_ACTIVATING_SIGTERM
,
543 SWAP_ACTIVATING_SIGKILL
,
544 SWAP_ACTIVATING_DONE
,
546 SWAP_DEACTIVATING_SIGTERM
,
547 SWAP_DEACTIVATING_SIGKILL
)) {
549 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
553 r
= swap_arm_timer(s
, usec_add(u
->state_change_timestamp
.monotonic
, s
->timeout_usec
));
558 swap_set_state(s
, new_state
);
562 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
569 if (s
->from_proc_swaps
)
570 p
= &s
->parameters_proc_swaps
;
571 else if (s
->from_fragment
)
572 p
= &s
->parameters_fragment
;
580 "%sFrom /proc/swaps: %s\n"
581 "%sFrom fragment: %s\n",
582 prefix
, swap_state_to_string(s
->state
),
583 prefix
, swap_result_to_string(s
->result
),
585 prefix
, yes_no(s
->from_proc_swaps
),
586 prefix
, yes_no(s
->from_fragment
));
589 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
596 prefix
, strempty(p
->options
));
598 if (s
->control_pid
> 0)
600 "%sControl PID: "PID_FMT
"\n",
601 prefix
, s
->control_pid
);
603 exec_context_dump(&s
->exec_context
, f
, prefix
);
604 kill_context_dump(&s
->kill_context
, f
, prefix
);
607 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
610 ExecParameters exec_params
= {
611 .apply_permissions
= true,
612 .apply_chroot
= true,
613 .apply_tty_stdin
= true,
614 .bus_endpoint_fd
= -1,
624 (void) unit_realize_cgroup(UNIT(s
));
625 if (s
->reset_cpu_usage
) {
626 (void) unit_reset_cpu_usage(UNIT(s
));
627 s
->reset_cpu_usage
= false;
630 r
= unit_setup_exec_runtime(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
.confirm_spawn
= UNIT(s
)->manager
->confirm_spawn
;
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
),
654 r
= unit_watch_pid(UNIT(s
), pid
);
656 /* FIXME: we need to do something here */
664 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
668 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
671 if (f
!= SWAP_SUCCESS
)
674 exec_runtime_destroy(s
->exec_runtime
);
675 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
677 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
679 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
682 static void swap_enter_active(Swap
*s
, SwapResult f
) {
685 if (f
!= SWAP_SUCCESS
)
688 swap_set_state(s
, SWAP_ACTIVE
);
691 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
696 if (f
!= SWAP_SUCCESS
)
699 r
= unit_kill_context(
702 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
703 KILL_KILL
: KILL_TERMINATE
,
711 r
= swap_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->timeout_usec
));
715 swap_set_state(s
, state
);
716 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
717 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
718 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
719 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
721 swap_enter_dead(s
, SWAP_SUCCESS
);
726 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
727 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
730 static void swap_enter_activating(Swap
*s
) {
731 _cleanup_free_
char *opts
= NULL
;
736 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
737 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
739 if (s
->from_fragment
) {
742 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
744 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
745 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
746 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
748 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
749 if (s
->parameters_fragment
.options
)
750 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
752 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
758 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
762 if (s
->parameters_fragment
.options
|| opts
) {
763 r
= exec_command_append(s
->control_command
, "-o",
764 opts
? : s
->parameters_fragment
.options
, NULL
);
769 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
773 swap_unwatch_control_pid(s
);
775 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
779 swap_set_state(s
, SWAP_ACTIVATING
);
784 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
785 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
788 static void swap_enter_deactivating(Swap
*s
) {
793 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
794 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
796 r
= exec_command_set(s
->control_command
,
803 swap_unwatch_control_pid(s
);
805 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
809 swap_set_state(s
, SWAP_DEACTIVATING
);
814 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
815 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
818 static int swap_start(Unit
*u
) {
819 Swap
*s
= SWAP(u
), *other
;
823 /* We cannot fulfill this request right now, try again later
826 if (s
->state
== SWAP_DEACTIVATING
||
827 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
828 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
829 s
->state
== SWAP_ACTIVATING_SIGTERM
||
830 s
->state
== SWAP_ACTIVATING_SIGKILL
)
833 if (s
->state
== SWAP_ACTIVATING
)
836 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
838 if (detect_container() > 0)
841 /* If there's a job for another swap unit for the same node
842 * running, then let's not dispatch this one for now, and wait
843 * until that other job has finished. */
844 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
845 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
848 s
->result
= SWAP_SUCCESS
;
849 s
->reset_cpu_usage
= true;
851 swap_enter_activating(s
);
855 static int swap_stop(Unit
*u
) {
860 if (s
->state
== SWAP_DEACTIVATING
||
861 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
862 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
863 s
->state
== SWAP_ACTIVATING_SIGTERM
||
864 s
->state
== SWAP_ACTIVATING_SIGKILL
)
867 assert(s
->state
== SWAP_ACTIVATING
||
868 s
->state
== SWAP_ACTIVATING_DONE
||
869 s
->state
== SWAP_ACTIVE
);
871 if (detect_container() > 0)
874 swap_enter_deactivating(s
);
878 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
885 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
886 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
888 if (s
->control_pid
> 0)
889 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
891 if (s
->control_command_id
>= 0)
892 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
897 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
903 if (streq(key
, "state")) {
906 state
= swap_state_from_string(value
);
908 log_unit_debug(u
, "Failed to parse state value: %s", value
);
910 s
->deserialized_state
= state
;
911 } else if (streq(key
, "result")) {
914 f
= swap_result_from_string(value
);
916 log_unit_debug(u
, "Failed to parse result value: %s", value
);
917 else if (f
!= SWAP_SUCCESS
)
919 } else if (streq(key
, "control-pid")) {
922 if (parse_pid(value
, &pid
) < 0)
923 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
925 s
->control_pid
= pid
;
927 } else if (streq(key
, "control-command")) {
930 id
= swap_exec_command_from_string(value
);
932 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
934 s
->control_command_id
= id
;
935 s
->control_command
= s
->exec_command
+ id
;
938 log_unit_debug(u
, "Unknown serialization key: %s", key
);
943 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
946 return state_translation_table
[SWAP(u
)->state
];
949 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
952 return swap_state_to_string(SWAP(u
)->state
);
955 _pure_
static bool swap_check_gc(Unit
*u
) {
960 return s
->from_proc_swaps
;
963 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
970 if (pid
!= s
->control_pid
)
975 if (is_clean_exit(code
, status
, NULL
))
977 else if (code
== CLD_EXITED
)
978 f
= SWAP_FAILURE_EXIT_CODE
;
979 else if (code
== CLD_KILLED
)
980 f
= SWAP_FAILURE_SIGNAL
;
981 else if (code
== CLD_DUMPED
)
982 f
= SWAP_FAILURE_CORE_DUMP
;
984 assert_not_reached("Unknown code");
986 if (f
!= SWAP_SUCCESS
)
989 if (s
->control_command
) {
990 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
992 s
->control_command
= NULL
;
993 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
996 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
997 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
1001 case SWAP_ACTIVATING
:
1002 case SWAP_ACTIVATING_DONE
:
1003 case SWAP_ACTIVATING_SIGTERM
:
1004 case SWAP_ACTIVATING_SIGKILL
:
1006 if (f
== SWAP_SUCCESS
)
1007 swap_enter_active(s
, f
);
1009 swap_enter_dead(s
, f
);
1012 case SWAP_DEACTIVATING
:
1013 case SWAP_DEACTIVATING_SIGKILL
:
1014 case SWAP_DEACTIVATING_SIGTERM
:
1016 swap_enter_dead(s
, f
);
1020 assert_not_reached("Uh, control process died at wrong time.");
1023 /* Notify clients about changed exit status */
1024 unit_add_to_dbus_queue(u
);
1027 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1028 Swap
*s
= SWAP(userdata
);
1031 assert(s
->timer_event_source
== source
);
1035 case SWAP_ACTIVATING
:
1036 case SWAP_ACTIVATING_DONE
:
1037 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1038 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1041 case SWAP_DEACTIVATING
:
1042 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1043 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1046 case SWAP_ACTIVATING_SIGTERM
:
1047 if (s
->kill_context
.send_sigkill
) {
1048 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1049 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1051 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1052 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1056 case SWAP_DEACTIVATING_SIGTERM
:
1057 if (s
->kill_context
.send_sigkill
) {
1058 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1059 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1061 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1062 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1066 case SWAP_ACTIVATING_SIGKILL
:
1067 case SWAP_DEACTIVATING_SIGKILL
:
1068 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1069 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1073 assert_not_reached("Timeout at wrong time.");
1079 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1085 rewind(m
->proc_swaps
);
1087 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1090 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1093 k
= fscanf(m
->proc_swaps
,
1094 "%ms " /* device/file */
1095 "%*s " /* type of swap */
1096 "%*s " /* swap size */
1098 "%i\n", /* priority */
1104 log_warning("Failed to parse /proc/swaps:%u.", i
);
1108 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1111 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1113 k
= swap_process_new(m
, d
, prio
, set_flags
);
1121 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1122 Manager
*m
= userdata
;
1127 assert(revents
& EPOLLPRI
);
1129 r
= swap_load_proc_swaps(m
, true);
1131 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1133 /* Reset flags, just in case, for late calls */
1134 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1135 Swap
*swap
= SWAP(u
);
1137 swap
->is_active
= swap
->just_activated
= false;
1143 manager_dispatch_load_queue(m
);
1145 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1146 Swap
*swap
= SWAP(u
);
1148 if (!swap
->is_active
) {
1149 /* This has just been deactivated */
1151 swap_unset_proc_swaps(swap
);
1153 switch (swap
->state
) {
1156 swap_enter_dead(swap
, SWAP_SUCCESS
);
1161 swap_set_state(swap
, swap
->state
);
1166 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1168 } else if (swap
->just_activated
) {
1170 /* New swap entry */
1172 switch (swap
->state
) {
1176 swap_enter_active(swap
, SWAP_SUCCESS
);
1179 case SWAP_ACTIVATING
:
1180 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1184 /* Nothing really changed, but let's
1185 * issue an notification call
1186 * nonetheless, in case somebody is
1187 * waiting for this. */
1188 swap_set_state(swap
, swap
->state
);
1193 /* Reset the flags for later calls */
1194 swap
->is_active
= swap
->just_activated
= false;
1200 static Unit
*swap_following(Unit
*u
) {
1202 Swap
*other
, *first
= NULL
;
1206 /* If the user configured the swap through /etc/fstab or
1207 * a device unit, follow that. */
1209 if (s
->from_fragment
)
1212 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1213 if (other
->from_fragment
)
1216 /* Otherwise, make everybody follow the unit that's named after
1217 * the swap device in the kernel */
1219 if (streq_ptr(s
->what
, s
->devnode
))
1222 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1223 if (streq_ptr(other
->what
, other
->devnode
))
1226 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1227 if (streq_ptr(other
->what
, other
->devnode
))
1233 /* Fall back to the first on the list */
1237 static int swap_following_set(Unit
*u
, Set
**_set
) {
1238 Swap
*s
= SWAP(u
), *other
;
1245 if (LIST_JUST_US(same_devnode
, s
)) {
1250 set
= set_new(NULL
);
1254 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1255 r
= set_put(set
, other
);
1268 static void swap_shutdown(Manager
*m
) {
1271 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1273 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1275 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1278 static void swap_enumerate(Manager
*m
) {
1283 if (!m
->proc_swaps
) {
1284 m
->proc_swaps
= fopen("/proc/swaps", "re");
1285 if (!m
->proc_swaps
) {
1286 if (errno
== ENOENT
)
1287 log_debug("Not swap enabled, skipping enumeration");
1289 log_error_errno(errno
, "Failed to open /proc/swaps: %m");
1294 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1296 log_error_errno(r
, "Failed to watch /proc/swaps: %m");
1300 /* Dispatch this before we dispatch SIGCHLD, so that
1301 * we always get the events from /proc/swaps before
1302 * the SIGCHLD of /sbin/swapon. */
1303 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1305 log_error_errno(r
, "Failed to change /proc/swaps priority: %m");
1309 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1312 r
= swap_load_proc_swaps(m
, false);
1322 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1323 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1324 _cleanup_free_
char *e
= NULL
;
1332 dn
= udev_device_get_devnode(dev
);
1336 r
= unit_name_from_path(dn
, ".swap", &e
);
1340 s
= hashmap_get(m
->units
, e
);
1342 r
= swap_set_devnode(s
, dn
);
1344 first
= udev_device_get_devlinks_list_entry(dev
);
1345 udev_list_entry_foreach(item
, first
) {
1346 _cleanup_free_
char *n
= NULL
;
1349 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1353 s
= hashmap_get(m
->units
, n
);
1355 q
= swap_set_devnode(s
, dn
);
1364 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1369 dn
= udev_device_get_devnode(dev
);
1373 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1376 q
= swap_set_devnode(s
, NULL
);
1384 static void swap_reset_failed(Unit
*u
) {
1389 if (s
->state
== SWAP_FAILED
)
1390 swap_set_state(s
, SWAP_DEAD
);
1392 s
->result
= SWAP_SUCCESS
;
1395 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1396 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1399 static int swap_get_timeout(Unit
*u
, usec_t
*timeout
) {
1404 if (!s
->timer_event_source
)
1407 r
= sd_event_source_get_time(s
->timer_event_source
, &t
);
1410 if (t
== USEC_INFINITY
)
1417 static bool swap_supported(void) {
1418 static int supported
= -1;
1420 /* If swap support is not available in the kernel, or we are
1421 * running in a container we don't support swap units, and any
1422 * attempts to starting one should fail immediately. */
1426 access("/proc/swaps", F_OK
) >= 0 &&
1427 detect_container() <= 0;
1432 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1433 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1434 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1437 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1439 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1440 [SWAP_SUCCESS
] = "success",
1441 [SWAP_FAILURE_RESOURCES
] = "resources",
1442 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1443 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1444 [SWAP_FAILURE_SIGNAL
] = "signal",
1445 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1448 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1450 const UnitVTable swap_vtable
= {
1451 .object_size
= sizeof(Swap
),
1452 .exec_context_offset
= offsetof(Swap
, exec_context
),
1453 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1454 .kill_context_offset
= offsetof(Swap
, kill_context
),
1455 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1461 .private_section
= "Swap",
1464 .no_instances
= true,
1470 .coldplug
= swap_coldplug
,
1474 .start
= swap_start
,
1479 .get_timeout
= swap_get_timeout
,
1481 .serialize
= swap_serialize
,
1482 .deserialize_item
= swap_deserialize_item
,
1484 .active_state
= swap_active_state
,
1485 .sub_state_to_string
= swap_sub_state_to_string
,
1487 .check_gc
= swap_check_gc
,
1489 .sigchld_event
= swap_sigchld_event
,
1491 .reset_failed
= swap_reset_failed
,
1493 .bus_vtable
= bus_swap_vtable
,
1494 .bus_set_property
= bus_swap_set_property
,
1495 .bus_commit_properties
= bus_swap_commit_properties
,
1497 .following
= swap_following
,
1498 .following_set
= swap_following_set
,
1500 .enumerate
= swap_enumerate
,
1501 .shutdown
= swap_shutdown
,
1502 .supported
= swap_supported
,
1504 .status_message_formats
= {
1505 .starting_stopping
= {
1506 [0] = "Activating swap %s...",
1507 [1] = "Deactivating swap %s...",
1509 .finished_start_job
= {
1510 [JOB_DONE
] = "Activated swap %s.",
1511 [JOB_FAILED
] = "Failed to activate swap %s.",
1512 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1514 .finished_stop_job
= {
1515 [JOB_DONE
] = "Deactivated swap %s.",
1516 [JOB_FAILED
] = "Failed deactivating swap %s.",
1517 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",