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"
39 #include "string-table.h"
40 #include "string-util.h"
42 #include "udev-util.h"
43 #include "unit-name.h"
47 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
48 [SWAP_DEAD
] = UNIT_INACTIVE
,
49 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
50 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
51 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
52 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
53 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
54 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
55 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
56 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
57 [SWAP_FAILED
] = UNIT_FAILED
60 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
61 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
63 static void swap_unset_proc_swaps(Swap
*s
) {
66 if (!s
->from_proc_swaps
)
69 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
71 s
->from_proc_swaps
= false;
74 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
81 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
85 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
88 first
= hashmap_get(swaps
, s
->devnode
);
90 LIST_REMOVE(same_devnode
, first
, s
);
92 hashmap_replace(swaps
, first
->devnode
, first
);
94 hashmap_remove(swaps
, s
->devnode
);
96 s
->devnode
= mfree(s
->devnode
);
100 s
->devnode
= strdup(devnode
);
104 first
= hashmap_get(swaps
, s
->devnode
);
105 LIST_PREPEND(same_devnode
, first
, s
);
107 return hashmap_replace(swaps
, first
->devnode
, first
);
113 static void swap_init(Unit
*u
) {
117 assert(UNIT(s
)->load_state
== UNIT_STUB
);
119 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
121 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
122 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
124 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
126 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
128 u
->ignore_on_isolate
= true;
131 static void swap_unwatch_control_pid(Swap
*s
) {
134 if (s
->control_pid
<= 0)
137 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
141 static void swap_done(Unit
*u
) {
146 swap_unset_proc_swaps(s
);
147 swap_set_devnode(s
, NULL
);
149 s
->what
= mfree(s
->what
);
150 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
151 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
153 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
154 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
155 s
->control_command
= NULL
;
157 swap_unwatch_control_pid(s
);
159 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
162 static int swap_arm_timer(Swap
*s
) {
167 if (s
->timeout_usec
<= 0) {
168 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
172 if (s
->timer_event_source
) {
173 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_usec
);
177 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
180 r
= sd_event_add_time(
181 UNIT(s
)->manager
->event
,
182 &s
->timer_event_source
,
184 now(CLOCK_MONOTONIC
) + s
->timeout_usec
, 0,
185 swap_dispatch_timer
, s
);
189 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
194 static int swap_add_device_links(Swap
*s
) {
200 if (!s
->from_fragment
)
203 if (is_device_path(s
->what
))
204 return unit_add_node_link(UNIT(s
), s
->what
, UNIT(s
)->manager
->running_as
== MANAGER_SYSTEM
);
206 /* File based swap devices need to be ordered after
207 * systemd-remount-fs.service, since they might need a
208 * writable file system. */
209 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
212 static int swap_add_default_dependencies(Swap
*s
) {
215 if (UNIT(s
)->manager
->running_as
!= MANAGER_SYSTEM
)
218 if (detect_container() > 0)
221 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
224 static int swap_verify(Swap
*s
) {
225 _cleanup_free_
char *e
= NULL
;
228 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
231 r
= unit_name_from_path(s
->what
, ".swap", &e
);
233 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
235 if (!unit_has_name(UNIT(s
), e
)) {
236 log_unit_error(UNIT(s
), "Value of What= and unit name do not match, not loading.");
240 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
241 log_unit_error(UNIT(s
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
248 static int swap_load_devnode(Swap
*s
) {
249 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
255 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
258 d
= udev_device_new_from_devnum(UNIT(s
)->manager
->udev
, 'b', st
.st_rdev
);
262 p
= udev_device_get_devnode(d
);
266 return swap_set_devnode(s
, p
);
269 static int swap_load(Unit
*u
) {
274 assert(u
->load_state
== UNIT_STUB
);
276 /* Load a .swap file */
277 r
= unit_load_fragment_and_dropin_optional(u
);
281 if (u
->load_state
== UNIT_LOADED
) {
283 if (UNIT(s
)->fragment_path
)
284 s
->from_fragment
= true;
287 if (s
->parameters_fragment
.what
)
288 s
->what
= strdup(s
->parameters_fragment
.what
);
289 else if (s
->parameters_proc_swaps
.what
)
290 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
292 r
= unit_name_to_path(u
->id
, &s
->what
);
301 path_kill_slashes(s
->what
);
303 if (!UNIT(s
)->description
) {
304 r
= unit_set_description(u
, s
->what
);
309 r
= unit_require_mounts_for(UNIT(s
), s
->what
);
313 r
= swap_add_device_links(s
);
317 r
= swap_load_devnode(s
);
321 r
= unit_patch_contexts(u
);
325 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
329 r
= unit_set_default_slice(u
);
333 if (UNIT(s
)->default_dependencies
) {
334 r
= swap_add_default_dependencies(s
);
340 return swap_verify(s
);
343 static int swap_setup_unit(
346 const char *what_proc_swaps
,
350 _cleanup_free_
char *e
= NULL
;
358 assert(what_proc_swaps
);
360 r
= unit_name_from_path(what
, ".swap", &e
);
362 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
364 u
= manager_get_unit(m
, e
);
367 SWAP(u
)->from_proc_swaps
&&
368 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
)) {
369 log_error("Swap %s appeared twice with different device paths %s and %s", e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
376 u
= unit_new(m
, sizeof(Swap
));
380 r
= unit_add_name(u
, e
);
384 SWAP(u
)->what
= strdup(what
);
385 if (!SWAP(u
)->what
) {
390 unit_add_to_load_queue(u
);
394 p
= &SWAP(u
)->parameters_proc_swaps
;
397 p
->what
= strdup(what_proc_swaps
);
405 SWAP(u
)->is_active
= true;
406 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
409 SWAP(u
)->from_proc_swaps
= true;
411 p
->priority
= priority
;
413 unit_add_to_dbus_queue(u
);
417 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
425 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
426 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
427 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
434 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
438 /* If this is a block device, then let's add duplicates for
439 * all other names of this block device */
440 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
443 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
447 /* Add the main device node */
448 dn
= udev_device_get_devnode(d
);
449 if (dn
&& !streq(dn
, device
))
450 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
452 /* Add additional units for all symlinks */
453 first
= udev_device_get_devlinks_list_entry(d
);
454 udev_list_entry_foreach(item
, first
) {
457 /* Don't bother with the /dev/block links */
458 p
= udev_list_entry_get_name(item
);
460 if (streq(p
, device
))
463 if (path_startswith(p
, "/dev/block/"))
466 if (stat(p
, &st
) >= 0)
467 if (!S_ISBLK(st
.st_mode
) ||
468 st
.st_rdev
!= udev_device_get_devnum(d
))
471 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
477 static void swap_set_state(Swap
*s
, SwapState state
) {
483 old_state
= s
->state
;
486 if (state
!= SWAP_ACTIVATING
&&
487 state
!= SWAP_ACTIVATING_SIGTERM
&&
488 state
!= SWAP_ACTIVATING_SIGKILL
&&
489 state
!= SWAP_ACTIVATING_DONE
&&
490 state
!= SWAP_DEACTIVATING
&&
491 state
!= SWAP_DEACTIVATING_SIGTERM
&&
492 state
!= SWAP_DEACTIVATING_SIGKILL
) {
493 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
494 swap_unwatch_control_pid(s
);
495 s
->control_command
= NULL
;
496 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
499 if (state
!= old_state
)
500 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
502 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
504 /* If there other units for the same device node have a job
505 queued it might be worth checking again if it is runnable
506 now. This is necessary, since swap_start() refuses
507 operation with EAGAIN if there's already another job for
508 the same device node queued. */
509 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
510 if (UNIT(other
)->job
)
511 job_add_to_run_queue(UNIT(other
)->job
);
514 static int swap_coldplug(Unit
*u
) {
516 SwapState new_state
= SWAP_DEAD
;
520 assert(s
->state
== SWAP_DEAD
);
522 if (s
->deserialized_state
!= s
->state
)
523 new_state
= s
->deserialized_state
;
524 else if (s
->from_proc_swaps
)
525 new_state
= SWAP_ACTIVE
;
527 if (new_state
== s
->state
)
530 if (new_state
== SWAP_ACTIVATING
||
531 new_state
== SWAP_ACTIVATING_SIGTERM
||
532 new_state
== SWAP_ACTIVATING_SIGKILL
||
533 new_state
== SWAP_ACTIVATING_DONE
||
534 new_state
== SWAP_DEACTIVATING
||
535 new_state
== SWAP_DEACTIVATING_SIGTERM
||
536 new_state
== SWAP_DEACTIVATING_SIGKILL
) {
538 if (s
->control_pid
<= 0)
541 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
545 r
= swap_arm_timer(s
);
550 swap_set_state(s
, new_state
);
554 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
561 if (s
->from_proc_swaps
)
562 p
= &s
->parameters_proc_swaps
;
563 else if (s
->from_fragment
)
564 p
= &s
->parameters_fragment
;
572 "%sFrom /proc/swaps: %s\n"
573 "%sFrom fragment: %s\n",
574 prefix
, swap_state_to_string(s
->state
),
575 prefix
, swap_result_to_string(s
->result
),
577 prefix
, yes_no(s
->from_proc_swaps
),
578 prefix
, yes_no(s
->from_fragment
));
581 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
588 prefix
, strempty(p
->options
));
590 if (s
->control_pid
> 0)
592 "%sControl PID: "PID_FMT
"\n",
593 prefix
, s
->control_pid
);
595 exec_context_dump(&s
->exec_context
, f
, prefix
);
596 kill_context_dump(&s
->kill_context
, f
, prefix
);
599 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
602 ExecParameters exec_params
= {
603 .apply_permissions
= true,
604 .apply_chroot
= true,
605 .apply_tty_stdin
= true,
606 .bus_endpoint_fd
= -1,
616 (void) unit_realize_cgroup(UNIT(s
));
617 if (s
->reset_cpu_usage
) {
618 (void) unit_reset_cpu_usage(UNIT(s
));
619 s
->reset_cpu_usage
= false;
622 r
= unit_setup_exec_runtime(UNIT(s
));
626 r
= swap_arm_timer(s
);
630 exec_params
.environment
= UNIT(s
)->manager
->environment
;
631 exec_params
.confirm_spawn
= UNIT(s
)->manager
->confirm_spawn
;
632 exec_params
.cgroup_supported
= UNIT(s
)->manager
->cgroup_supported
;
633 exec_params
.cgroup_path
= UNIT(s
)->cgroup_path
;
634 exec_params
.cgroup_delegate
= s
->cgroup_context
.delegate
;
635 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(s
)->manager
);
637 r
= exec_spawn(UNIT(s
),
646 r
= unit_watch_pid(UNIT(s
), pid
);
648 /* FIXME: we need to do something here */
656 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
660 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
663 if (f
!= SWAP_SUCCESS
)
666 exec_runtime_destroy(s
->exec_runtime
);
667 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
669 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
671 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
674 static void swap_enter_active(Swap
*s
, SwapResult f
) {
677 if (f
!= SWAP_SUCCESS
)
680 swap_set_state(s
, SWAP_ACTIVE
);
683 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
688 if (f
!= SWAP_SUCCESS
)
691 r
= unit_kill_context(
694 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
695 KILL_KILL
: KILL_TERMINATE
,
703 r
= swap_arm_timer(s
);
707 swap_set_state(s
, state
);
708 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
709 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
710 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
711 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
713 swap_enter_dead(s
, SWAP_SUCCESS
);
718 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
719 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
722 static void swap_enter_activating(Swap
*s
) {
723 _cleanup_free_
char *opts
= NULL
;
728 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
729 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
731 if (s
->from_fragment
) {
734 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
736 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
737 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
738 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
740 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
741 if (s
->parameters_fragment
.options
)
742 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
744 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
750 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
754 if (s
->parameters_fragment
.options
|| opts
) {
755 r
= exec_command_append(s
->control_command
, "-o",
756 opts
? : s
->parameters_fragment
.options
, NULL
);
761 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
765 swap_unwatch_control_pid(s
);
767 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
771 swap_set_state(s
, SWAP_ACTIVATING
);
776 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
777 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
780 static void swap_enter_deactivating(Swap
*s
) {
785 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
786 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
788 r
= exec_command_set(s
->control_command
,
795 swap_unwatch_control_pid(s
);
797 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
801 swap_set_state(s
, SWAP_DEACTIVATING
);
806 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
807 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
810 static int swap_start(Unit
*u
) {
811 Swap
*s
= SWAP(u
), *other
;
815 /* We cannot fulfill this request right now, try again later
818 if (s
->state
== SWAP_DEACTIVATING
||
819 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
820 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
821 s
->state
== SWAP_ACTIVATING_SIGTERM
||
822 s
->state
== SWAP_ACTIVATING_SIGKILL
)
825 if (s
->state
== SWAP_ACTIVATING
)
828 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
830 if (detect_container() > 0)
833 /* If there's a job for another swap unit for the same node
834 * running, then let's not dispatch this one for now, and wait
835 * until that other job has finished. */
836 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
837 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
840 s
->result
= SWAP_SUCCESS
;
841 s
->reset_cpu_usage
= true;
843 swap_enter_activating(s
);
847 static int swap_stop(Unit
*u
) {
852 if (s
->state
== SWAP_DEACTIVATING
||
853 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
854 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
855 s
->state
== SWAP_ACTIVATING_SIGTERM
||
856 s
->state
== SWAP_ACTIVATING_SIGKILL
)
859 assert(s
->state
== SWAP_ACTIVATING
||
860 s
->state
== SWAP_ACTIVATING_DONE
||
861 s
->state
== SWAP_ACTIVE
);
863 if (detect_container() > 0)
866 swap_enter_deactivating(s
);
870 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
877 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
878 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
880 if (s
->control_pid
> 0)
881 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
883 if (s
->control_command_id
>= 0)
884 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
889 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
895 if (streq(key
, "state")) {
898 state
= swap_state_from_string(value
);
900 log_unit_debug(u
, "Failed to parse state value: %s", value
);
902 s
->deserialized_state
= state
;
903 } else if (streq(key
, "result")) {
906 f
= swap_result_from_string(value
);
908 log_unit_debug(u
, "Failed to parse result value: %s", value
);
909 else if (f
!= SWAP_SUCCESS
)
911 } else if (streq(key
, "control-pid")) {
914 if (parse_pid(value
, &pid
) < 0)
915 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
917 s
->control_pid
= pid
;
919 } else if (streq(key
, "control-command")) {
922 id
= swap_exec_command_from_string(value
);
924 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
926 s
->control_command_id
= id
;
927 s
->control_command
= s
->exec_command
+ id
;
930 log_unit_debug(u
, "Unknown serialization key: %s", key
);
935 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
938 return state_translation_table
[SWAP(u
)->state
];
941 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
944 return swap_state_to_string(SWAP(u
)->state
);
947 _pure_
static bool swap_check_gc(Unit
*u
) {
952 return s
->from_proc_swaps
;
955 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
962 if (pid
!= s
->control_pid
)
967 if (is_clean_exit(code
, status
, NULL
))
969 else if (code
== CLD_EXITED
)
970 f
= SWAP_FAILURE_EXIT_CODE
;
971 else if (code
== CLD_KILLED
)
972 f
= SWAP_FAILURE_SIGNAL
;
973 else if (code
== CLD_DUMPED
)
974 f
= SWAP_FAILURE_CORE_DUMP
;
976 assert_not_reached("Unknown code");
978 if (f
!= SWAP_SUCCESS
)
981 if (s
->control_command
) {
982 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
984 s
->control_command
= NULL
;
985 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
988 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
989 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
993 case SWAP_ACTIVATING
:
994 case SWAP_ACTIVATING_DONE
:
995 case SWAP_ACTIVATING_SIGTERM
:
996 case SWAP_ACTIVATING_SIGKILL
:
998 if (f
== SWAP_SUCCESS
)
999 swap_enter_active(s
, f
);
1001 swap_enter_dead(s
, f
);
1004 case SWAP_DEACTIVATING
:
1005 case SWAP_DEACTIVATING_SIGKILL
:
1006 case SWAP_DEACTIVATING_SIGTERM
:
1008 swap_enter_dead(s
, f
);
1012 assert_not_reached("Uh, control process died at wrong time.");
1015 /* Notify clients about changed exit status */
1016 unit_add_to_dbus_queue(u
);
1019 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1020 Swap
*s
= SWAP(userdata
);
1023 assert(s
->timer_event_source
== source
);
1027 case SWAP_ACTIVATING
:
1028 case SWAP_ACTIVATING_DONE
:
1029 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1030 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1033 case SWAP_DEACTIVATING
:
1034 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1035 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1038 case SWAP_ACTIVATING_SIGTERM
:
1039 if (s
->kill_context
.send_sigkill
) {
1040 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1041 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1043 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1044 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1048 case SWAP_DEACTIVATING_SIGTERM
:
1049 if (s
->kill_context
.send_sigkill
) {
1050 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1051 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1053 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1054 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1058 case SWAP_ACTIVATING_SIGKILL
:
1059 case SWAP_DEACTIVATING_SIGKILL
:
1060 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1061 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1065 assert_not_reached("Timeout at wrong time.");
1071 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1077 rewind(m
->proc_swaps
);
1079 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1082 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1085 k
= fscanf(m
->proc_swaps
,
1086 "%ms " /* device/file */
1087 "%*s " /* type of swap */
1088 "%*s " /* swap size */
1090 "%i\n", /* priority */
1096 log_warning("Failed to parse /proc/swaps:%u.", i
);
1100 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1103 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1105 k
= swap_process_new(m
, d
, prio
, set_flags
);
1113 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1114 Manager
*m
= userdata
;
1119 assert(revents
& EPOLLPRI
);
1121 r
= swap_load_proc_swaps(m
, true);
1123 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1125 /* Reset flags, just in case, for late calls */
1126 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1127 Swap
*swap
= SWAP(u
);
1129 swap
->is_active
= swap
->just_activated
= false;
1135 manager_dispatch_load_queue(m
);
1137 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1138 Swap
*swap
= SWAP(u
);
1140 if (!swap
->is_active
) {
1141 /* This has just been deactivated */
1143 swap_unset_proc_swaps(swap
);
1145 switch (swap
->state
) {
1148 swap_enter_dead(swap
, SWAP_SUCCESS
);
1153 swap_set_state(swap
, swap
->state
);
1158 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1160 } else if (swap
->just_activated
) {
1162 /* New swap entry */
1164 switch (swap
->state
) {
1168 swap_enter_active(swap
, SWAP_SUCCESS
);
1171 case SWAP_ACTIVATING
:
1172 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1176 /* Nothing really changed, but let's
1177 * issue an notification call
1178 * nonetheless, in case somebody is
1179 * waiting for this. */
1180 swap_set_state(swap
, swap
->state
);
1185 /* Reset the flags for later calls */
1186 swap
->is_active
= swap
->just_activated
= false;
1192 static Unit
*swap_following(Unit
*u
) {
1194 Swap
*other
, *first
= NULL
;
1198 /* If the user configured the swap through /etc/fstab or
1199 * a device unit, follow that. */
1201 if (s
->from_fragment
)
1204 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1205 if (other
->from_fragment
)
1208 /* Otherwise make everybody follow the unit that's named after
1209 * the swap device in the kernel */
1211 if (streq_ptr(s
->what
, s
->devnode
))
1214 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1215 if (streq_ptr(other
->what
, other
->devnode
))
1218 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1219 if (streq_ptr(other
->what
, other
->devnode
))
1225 /* Fall back to the first on the list */
1229 static int swap_following_set(Unit
*u
, Set
**_set
) {
1230 Swap
*s
= SWAP(u
), *other
;
1237 if (LIST_JUST_US(same_devnode
, s
)) {
1242 set
= set_new(NULL
);
1246 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1247 r
= set_put(set
, other
);
1260 static void swap_shutdown(Manager
*m
) {
1263 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1265 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1267 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1270 static int swap_enumerate(Manager
*m
) {
1275 if (!m
->proc_swaps
) {
1276 m
->proc_swaps
= fopen("/proc/swaps", "re");
1278 return errno
== ENOENT
? 0 : -errno
;
1280 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1284 /* Dispatch this before we dispatch SIGCHLD, so that
1285 * we always get the events from /proc/swaps before
1286 * the SIGCHLD of /sbin/swapon. */
1287 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1291 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1294 r
= swap_load_proc_swaps(m
, false);
1305 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1306 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1307 _cleanup_free_
char *e
= NULL
;
1315 dn
= udev_device_get_devnode(dev
);
1319 r
= unit_name_from_path(dn
, ".swap", &e
);
1323 s
= hashmap_get(m
->units
, e
);
1325 r
= swap_set_devnode(s
, dn
);
1327 first
= udev_device_get_devlinks_list_entry(dev
);
1328 udev_list_entry_foreach(item
, first
) {
1329 _cleanup_free_
char *n
= NULL
;
1332 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1336 s
= hashmap_get(m
->units
, n
);
1338 q
= swap_set_devnode(s
, dn
);
1347 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1352 dn
= udev_device_get_devnode(dev
);
1356 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1359 q
= swap_set_devnode(s
, NULL
);
1367 static void swap_reset_failed(Unit
*u
) {
1372 if (s
->state
== SWAP_FAILED
)
1373 swap_set_state(s
, SWAP_DEAD
);
1375 s
->result
= SWAP_SUCCESS
;
1378 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1379 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1382 static int swap_get_timeout(Unit
*u
, uint64_t *timeout
) {
1386 if (!s
->timer_event_source
)
1389 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
1396 static bool swap_supported(void) {
1397 static int supported
= -1;
1399 /* If swap support is not available in the kernel, or we are
1400 * running in a container we don't support swap units, and any
1401 * attempts to starting one should fail immediately. */
1405 access("/proc/swaps", F_OK
) >= 0 &&
1406 detect_container() <= 0;
1411 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1412 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1413 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1416 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1418 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1419 [SWAP_SUCCESS
] = "success",
1420 [SWAP_FAILURE_RESOURCES
] = "resources",
1421 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1422 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1423 [SWAP_FAILURE_SIGNAL
] = "signal",
1424 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1427 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1429 const UnitVTable swap_vtable
= {
1430 .object_size
= sizeof(Swap
),
1431 .exec_context_offset
= offsetof(Swap
, exec_context
),
1432 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1433 .kill_context_offset
= offsetof(Swap
, kill_context
),
1434 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1440 .private_section
= "Swap",
1443 .no_instances
= true,
1449 .coldplug
= swap_coldplug
,
1453 .start
= swap_start
,
1458 .get_timeout
= swap_get_timeout
,
1460 .serialize
= swap_serialize
,
1461 .deserialize_item
= swap_deserialize_item
,
1463 .active_state
= swap_active_state
,
1464 .sub_state_to_string
= swap_sub_state_to_string
,
1466 .check_gc
= swap_check_gc
,
1468 .sigchld_event
= swap_sigchld_event
,
1470 .reset_failed
= swap_reset_failed
,
1472 .bus_vtable
= bus_swap_vtable
,
1473 .bus_set_property
= bus_swap_set_property
,
1474 .bus_commit_properties
= bus_swap_commit_properties
,
1476 .following
= swap_following
,
1477 .following_set
= swap_following_set
,
1479 .enumerate
= swap_enumerate
,
1480 .shutdown
= swap_shutdown
,
1481 .supported
= swap_supported
,
1483 .status_message_formats
= {
1484 .starting_stopping
= {
1485 [0] = "Activating swap %s...",
1486 [1] = "Deactivating swap %s...",
1488 .finished_start_job
= {
1489 [JOB_DONE
] = "Activated swap %s.",
1490 [JOB_FAILED
] = "Failed to activate swap %s.",
1491 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1493 .finished_stop_job
= {
1494 [JOB_DONE
] = "Deactivated swap %s.",
1495 [JOB_FAILED
] = "Failed deactivating swap %s.",
1496 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",