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 "dbus-swap.h"
31 #include "exit-status.h"
33 #include "formats-util.h"
34 #include "fstab-util.h"
35 #include "path-util.h"
37 #include "string-util.h"
39 #include "udev-util.h"
40 #include "unit-name.h"
44 static const UnitActiveState state_translation_table
[_SWAP_STATE_MAX
] = {
45 [SWAP_DEAD
] = UNIT_INACTIVE
,
46 [SWAP_ACTIVATING
] = UNIT_ACTIVATING
,
47 [SWAP_ACTIVATING_DONE
] = UNIT_ACTIVE
,
48 [SWAP_ACTIVE
] = UNIT_ACTIVE
,
49 [SWAP_DEACTIVATING
] = UNIT_DEACTIVATING
,
50 [SWAP_ACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
51 [SWAP_ACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
52 [SWAP_DEACTIVATING_SIGTERM
] = UNIT_DEACTIVATING
,
53 [SWAP_DEACTIVATING_SIGKILL
] = UNIT_DEACTIVATING
,
54 [SWAP_FAILED
] = UNIT_FAILED
57 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
58 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
60 static void swap_unset_proc_swaps(Swap
*s
) {
63 if (!s
->from_proc_swaps
)
66 s
->parameters_proc_swaps
.what
= mfree(s
->parameters_proc_swaps
.what
);
68 s
->from_proc_swaps
= false;
71 static int swap_set_devnode(Swap
*s
, const char *devnode
) {
78 r
= hashmap_ensure_allocated(&UNIT(s
)->manager
->swaps_by_devnode
, &string_hash_ops
);
82 swaps
= UNIT(s
)->manager
->swaps_by_devnode
;
85 first
= hashmap_get(swaps
, s
->devnode
);
87 LIST_REMOVE(same_devnode
, first
, s
);
89 hashmap_replace(swaps
, first
->devnode
, first
);
91 hashmap_remove(swaps
, s
->devnode
);
93 s
->devnode
= mfree(s
->devnode
);
97 s
->devnode
= strdup(devnode
);
101 first
= hashmap_get(swaps
, s
->devnode
);
102 LIST_PREPEND(same_devnode
, first
, s
);
104 return hashmap_replace(swaps
, first
->devnode
, first
);
110 static void swap_init(Unit
*u
) {
114 assert(UNIT(s
)->load_state
== UNIT_STUB
);
116 s
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
118 s
->exec_context
.std_output
= u
->manager
->default_std_output
;
119 s
->exec_context
.std_error
= u
->manager
->default_std_error
;
121 s
->parameters_proc_swaps
.priority
= s
->parameters_fragment
.priority
= -1;
123 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
125 u
->ignore_on_isolate
= true;
128 static void swap_unwatch_control_pid(Swap
*s
) {
131 if (s
->control_pid
<= 0)
134 unit_unwatch_pid(UNIT(s
), s
->control_pid
);
138 static void swap_done(Unit
*u
) {
143 swap_unset_proc_swaps(s
);
144 swap_set_devnode(s
, NULL
);
146 s
->what
= mfree(s
->what
);
147 s
->parameters_fragment
.what
= mfree(s
->parameters_fragment
.what
);
148 s
->parameters_fragment
.options
= mfree(s
->parameters_fragment
.options
);
150 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
151 exec_command_done_array(s
->exec_command
, _SWAP_EXEC_COMMAND_MAX
);
152 s
->control_command
= NULL
;
154 swap_unwatch_control_pid(s
);
156 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
159 static int swap_arm_timer(Swap
*s
) {
164 if (s
->timeout_usec
<= 0) {
165 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
169 if (s
->timer_event_source
) {
170 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_usec
);
174 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
177 r
= sd_event_add_time(
178 UNIT(s
)->manager
->event
,
179 &s
->timer_event_source
,
181 now(CLOCK_MONOTONIC
) + s
->timeout_usec
, 0,
182 swap_dispatch_timer
, s
);
186 (void) sd_event_source_set_description(s
->timer_event_source
, "swap-timer");
191 static int swap_add_device_links(Swap
*s
) {
197 if (!s
->from_fragment
)
200 if (is_device_path(s
->what
))
201 return unit_add_node_link(UNIT(s
), s
->what
, UNIT(s
)->manager
->running_as
== MANAGER_SYSTEM
);
203 /* File based swap devices need to be ordered after
204 * systemd-remount-fs.service, since they might need a
205 * writable file system. */
206 return unit_add_dependency_by_name(UNIT(s
), UNIT_AFTER
, SPECIAL_REMOUNT_FS_SERVICE
, NULL
, true);
209 static int swap_add_default_dependencies(Swap
*s
) {
212 if (UNIT(s
)->manager
->running_as
!= MANAGER_SYSTEM
)
215 if (detect_container() > 0)
218 return unit_add_two_dependencies_by_name(UNIT(s
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
221 static int swap_verify(Swap
*s
) {
222 _cleanup_free_
char *e
= NULL
;
225 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
228 r
= unit_name_from_path(s
->what
, ".swap", &e
);
230 return log_unit_error_errno(UNIT(s
), r
, "Failed to generate unit name from path: %m");
232 if (!unit_has_name(UNIT(s
), e
)) {
233 log_unit_error(UNIT(s
), "Value of What= and unit name do not match, not loading.");
237 if (s
->exec_context
.pam_name
&& s
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
238 log_unit_error(UNIT(s
), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
245 static int swap_load_devnode(Swap
*s
) {
246 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
252 if (stat(s
->what
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
255 d
= udev_device_new_from_devnum(UNIT(s
)->manager
->udev
, 'b', st
.st_rdev
);
259 p
= udev_device_get_devnode(d
);
263 return swap_set_devnode(s
, p
);
266 static int swap_load(Unit
*u
) {
271 assert(u
->load_state
== UNIT_STUB
);
273 /* Load a .swap file */
274 r
= unit_load_fragment_and_dropin_optional(u
);
278 if (u
->load_state
== UNIT_LOADED
) {
280 if (UNIT(s
)->fragment_path
)
281 s
->from_fragment
= true;
284 if (s
->parameters_fragment
.what
)
285 s
->what
= strdup(s
->parameters_fragment
.what
);
286 else if (s
->parameters_proc_swaps
.what
)
287 s
->what
= strdup(s
->parameters_proc_swaps
.what
);
289 r
= unit_name_to_path(u
->id
, &s
->what
);
298 path_kill_slashes(s
->what
);
300 if (!UNIT(s
)->description
) {
301 r
= unit_set_description(u
, s
->what
);
306 r
= unit_require_mounts_for(UNIT(s
), s
->what
);
310 r
= swap_add_device_links(s
);
314 r
= swap_load_devnode(s
);
318 r
= unit_patch_contexts(u
);
322 r
= unit_add_exec_dependencies(u
, &s
->exec_context
);
326 r
= unit_set_default_slice(u
);
330 if (UNIT(s
)->default_dependencies
) {
331 r
= swap_add_default_dependencies(s
);
337 return swap_verify(s
);
340 static int swap_setup_unit(
343 const char *what_proc_swaps
,
347 _cleanup_free_
char *e
= NULL
;
355 assert(what_proc_swaps
);
357 r
= unit_name_from_path(what
, ".swap", &e
);
359 return log_unit_error_errno(u
, r
, "Failed to generate unit name from path: %m");
361 u
= manager_get_unit(m
, e
);
364 SWAP(u
)->from_proc_swaps
&&
365 !path_equal(SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
)) {
366 log_error("Swap %s appeared twice with different device paths %s and %s", e
, SWAP(u
)->parameters_proc_swaps
.what
, what_proc_swaps
);
373 u
= unit_new(m
, sizeof(Swap
));
377 r
= unit_add_name(u
, e
);
381 SWAP(u
)->what
= strdup(what
);
382 if (!SWAP(u
)->what
) {
387 unit_add_to_load_queue(u
);
391 p
= &SWAP(u
)->parameters_proc_swaps
;
394 p
->what
= strdup(what_proc_swaps
);
402 SWAP(u
)->is_active
= true;
403 SWAP(u
)->just_activated
= !SWAP(u
)->from_proc_swaps
;
406 SWAP(u
)->from_proc_swaps
= true;
408 p
->priority
= priority
;
410 unit_add_to_dbus_queue(u
);
414 log_unit_warning_errno(u
, r
, "Failed to load swap unit: %m");
422 static int swap_process_new(Manager
*m
, const char *device
, int prio
, bool set_flags
) {
423 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
424 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
431 r
= swap_setup_unit(m
, device
, device
, prio
, set_flags
);
435 /* If this is a block device, then let's add duplicates for
436 * all other names of this block device */
437 if (stat(device
, &st
) < 0 || !S_ISBLK(st
.st_mode
))
440 d
= udev_device_new_from_devnum(m
->udev
, 'b', st
.st_rdev
);
444 /* Add the main device node */
445 dn
= udev_device_get_devnode(d
);
446 if (dn
&& !streq(dn
, device
))
447 swap_setup_unit(m
, dn
, device
, prio
, set_flags
);
449 /* Add additional units for all symlinks */
450 first
= udev_device_get_devlinks_list_entry(d
);
451 udev_list_entry_foreach(item
, first
) {
454 /* Don't bother with the /dev/block links */
455 p
= udev_list_entry_get_name(item
);
457 if (streq(p
, device
))
460 if (path_startswith(p
, "/dev/block/"))
463 if (stat(p
, &st
) >= 0)
464 if (!S_ISBLK(st
.st_mode
) ||
465 st
.st_rdev
!= udev_device_get_devnum(d
))
468 swap_setup_unit(m
, p
, device
, prio
, set_flags
);
474 static void swap_set_state(Swap
*s
, SwapState state
) {
480 old_state
= s
->state
;
483 if (state
!= SWAP_ACTIVATING
&&
484 state
!= SWAP_ACTIVATING_SIGTERM
&&
485 state
!= SWAP_ACTIVATING_SIGKILL
&&
486 state
!= SWAP_ACTIVATING_DONE
&&
487 state
!= SWAP_DEACTIVATING
&&
488 state
!= SWAP_DEACTIVATING_SIGTERM
&&
489 state
!= SWAP_DEACTIVATING_SIGKILL
) {
490 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
491 swap_unwatch_control_pid(s
);
492 s
->control_command
= NULL
;
493 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
496 if (state
!= old_state
)
497 log_unit_debug(UNIT(s
), "Changed %s -> %s", swap_state_to_string(old_state
), swap_state_to_string(state
));
499 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
501 /* If there other units for the same device node have a job
502 queued it might be worth checking again if it is runnable
503 now. This is necessary, since swap_start() refuses
504 operation with EAGAIN if there's already another job for
505 the same device node queued. */
506 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
507 if (UNIT(other
)->job
)
508 job_add_to_run_queue(UNIT(other
)->job
);
511 static int swap_coldplug(Unit
*u
) {
513 SwapState new_state
= SWAP_DEAD
;
517 assert(s
->state
== SWAP_DEAD
);
519 if (s
->deserialized_state
!= s
->state
)
520 new_state
= s
->deserialized_state
;
521 else if (s
->from_proc_swaps
)
522 new_state
= SWAP_ACTIVE
;
524 if (new_state
== s
->state
)
527 if (new_state
== SWAP_ACTIVATING
||
528 new_state
== SWAP_ACTIVATING_SIGTERM
||
529 new_state
== SWAP_ACTIVATING_SIGKILL
||
530 new_state
== SWAP_ACTIVATING_DONE
||
531 new_state
== SWAP_DEACTIVATING
||
532 new_state
== SWAP_DEACTIVATING_SIGTERM
||
533 new_state
== SWAP_DEACTIVATING_SIGKILL
) {
535 if (s
->control_pid
<= 0)
538 r
= unit_watch_pid(UNIT(s
), s
->control_pid
);
542 r
= swap_arm_timer(s
);
547 swap_set_state(s
, new_state
);
551 static void swap_dump(Unit
*u
, FILE *f
, const char *prefix
) {
558 if (s
->from_proc_swaps
)
559 p
= &s
->parameters_proc_swaps
;
560 else if (s
->from_fragment
)
561 p
= &s
->parameters_fragment
;
569 "%sFrom /proc/swaps: %s\n"
570 "%sFrom fragment: %s\n",
571 prefix
, swap_state_to_string(s
->state
),
572 prefix
, swap_result_to_string(s
->result
),
574 prefix
, yes_no(s
->from_proc_swaps
),
575 prefix
, yes_no(s
->from_fragment
));
578 fprintf(f
, "%sDevice Node: %s\n", prefix
, s
->devnode
);
585 prefix
, strempty(p
->options
));
587 if (s
->control_pid
> 0)
589 "%sControl PID: "PID_FMT
"\n",
590 prefix
, s
->control_pid
);
592 exec_context_dump(&s
->exec_context
, f
, prefix
);
593 kill_context_dump(&s
->kill_context
, f
, prefix
);
596 static int swap_spawn(Swap
*s
, ExecCommand
*c
, pid_t
*_pid
) {
599 ExecParameters exec_params
= {
600 .apply_permissions
= true,
601 .apply_chroot
= true,
602 .apply_tty_stdin
= true,
603 .bus_endpoint_fd
= -1,
613 (void) unit_realize_cgroup(UNIT(s
));
614 if (s
->reset_cpu_usage
) {
615 (void) unit_reset_cpu_usage(UNIT(s
));
616 s
->reset_cpu_usage
= false;
619 r
= unit_setup_exec_runtime(UNIT(s
));
623 r
= swap_arm_timer(s
);
627 exec_params
.environment
= UNIT(s
)->manager
->environment
;
628 exec_params
.confirm_spawn
= UNIT(s
)->manager
->confirm_spawn
;
629 exec_params
.cgroup_supported
= UNIT(s
)->manager
->cgroup_supported
;
630 exec_params
.cgroup_path
= UNIT(s
)->cgroup_path
;
631 exec_params
.cgroup_delegate
= s
->cgroup_context
.delegate
;
632 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(s
)->manager
);
634 r
= exec_spawn(UNIT(s
),
643 r
= unit_watch_pid(UNIT(s
), pid
);
645 /* FIXME: we need to do something here */
653 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
657 static void swap_enter_dead(Swap
*s
, SwapResult f
) {
660 if (f
!= SWAP_SUCCESS
)
663 exec_runtime_destroy(s
->exec_runtime
);
664 s
->exec_runtime
= exec_runtime_unref(s
->exec_runtime
);
666 exec_context_destroy_runtime_directory(&s
->exec_context
, manager_get_runtime_prefix(UNIT(s
)->manager
));
668 swap_set_state(s
, s
->result
!= SWAP_SUCCESS
? SWAP_FAILED
: SWAP_DEAD
);
671 static void swap_enter_active(Swap
*s
, SwapResult f
) {
674 if (f
!= SWAP_SUCCESS
)
677 swap_set_state(s
, SWAP_ACTIVE
);
680 static void swap_enter_signal(Swap
*s
, SwapState state
, SwapResult f
) {
685 if (f
!= SWAP_SUCCESS
)
688 r
= unit_kill_context(
691 (state
!= SWAP_ACTIVATING_SIGTERM
&& state
!= SWAP_DEACTIVATING_SIGTERM
) ?
692 KILL_KILL
: KILL_TERMINATE
,
700 r
= swap_arm_timer(s
);
704 swap_set_state(s
, state
);
705 } else if (state
== SWAP_ACTIVATING_SIGTERM
)
706 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_SUCCESS
);
707 else if (state
== SWAP_DEACTIVATING_SIGTERM
)
708 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_SUCCESS
);
710 swap_enter_dead(s
, SWAP_SUCCESS
);
715 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
716 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
719 static void swap_enter_activating(Swap
*s
) {
720 _cleanup_free_
char *opts
= NULL
;
725 s
->control_command_id
= SWAP_EXEC_ACTIVATE
;
726 s
->control_command
= s
->exec_command
+ SWAP_EXEC_ACTIVATE
;
728 if (s
->from_fragment
) {
731 r
= fstab_find_pri(s
->parameters_fragment
.options
, &priority
);
733 log_warning_errno(r
, "Failed to parse swap priority \"%s\", ignoring: %m", s
->parameters_fragment
.options
);
734 else if (r
== 1 && s
->parameters_fragment
.priority
>= 0)
735 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
737 if (r
<= 0 && s
->parameters_fragment
.priority
>= 0) {
738 if (s
->parameters_fragment
.options
)
739 r
= asprintf(&opts
, "%s,pri=%i", s
->parameters_fragment
.options
, s
->parameters_fragment
.priority
);
741 r
= asprintf(&opts
, "pri=%i", s
->parameters_fragment
.priority
);
747 r
= exec_command_set(s
->control_command
, "/sbin/swapon", NULL
);
751 if (s
->parameters_fragment
.options
|| opts
) {
752 r
= exec_command_append(s
->control_command
, "-o",
753 opts
? : s
->parameters_fragment
.options
, NULL
);
758 r
= exec_command_append(s
->control_command
, s
->what
, NULL
);
762 swap_unwatch_control_pid(s
);
764 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
768 swap_set_state(s
, SWAP_ACTIVATING
);
773 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapon' task: %m");
774 swap_enter_dead(s
, SWAP_FAILURE_RESOURCES
);
777 static void swap_enter_deactivating(Swap
*s
) {
782 s
->control_command_id
= SWAP_EXEC_DEACTIVATE
;
783 s
->control_command
= s
->exec_command
+ SWAP_EXEC_DEACTIVATE
;
785 r
= exec_command_set(s
->control_command
,
792 swap_unwatch_control_pid(s
);
794 r
= swap_spawn(s
, s
->control_command
, &s
->control_pid
);
798 swap_set_state(s
, SWAP_DEACTIVATING
);
803 log_unit_warning_errno(UNIT(s
), r
, "Failed to run 'swapoff' task: %m");
804 swap_enter_active(s
, SWAP_FAILURE_RESOURCES
);
807 static int swap_start(Unit
*u
) {
808 Swap
*s
= SWAP(u
), *other
;
812 /* We cannot fulfill this request right now, try again later
815 if (s
->state
== SWAP_DEACTIVATING
||
816 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
817 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
818 s
->state
== SWAP_ACTIVATING_SIGTERM
||
819 s
->state
== SWAP_ACTIVATING_SIGKILL
)
822 if (s
->state
== SWAP_ACTIVATING
)
825 assert(s
->state
== SWAP_DEAD
|| s
->state
== SWAP_FAILED
);
827 if (detect_container() > 0)
830 /* If there's a job for another swap unit for the same node
831 * running, then let's not dispatch this one for now, and wait
832 * until that other job has finished. */
833 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
834 if (UNIT(other
)->job
&& UNIT(other
)->job
->state
== JOB_RUNNING
)
837 s
->result
= SWAP_SUCCESS
;
838 s
->reset_cpu_usage
= true;
840 swap_enter_activating(s
);
844 static int swap_stop(Unit
*u
) {
849 if (s
->state
== SWAP_DEACTIVATING
||
850 s
->state
== SWAP_DEACTIVATING_SIGTERM
||
851 s
->state
== SWAP_DEACTIVATING_SIGKILL
||
852 s
->state
== SWAP_ACTIVATING_SIGTERM
||
853 s
->state
== SWAP_ACTIVATING_SIGKILL
)
856 assert(s
->state
== SWAP_ACTIVATING
||
857 s
->state
== SWAP_ACTIVATING_DONE
||
858 s
->state
== SWAP_ACTIVE
);
860 if (detect_container() > 0)
863 swap_enter_deactivating(s
);
867 static int swap_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
874 unit_serialize_item(u
, f
, "state", swap_state_to_string(s
->state
));
875 unit_serialize_item(u
, f
, "result", swap_result_to_string(s
->result
));
877 if (s
->control_pid
> 0)
878 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, s
->control_pid
);
880 if (s
->control_command_id
>= 0)
881 unit_serialize_item(u
, f
, "control-command", swap_exec_command_to_string(s
->control_command_id
));
886 static int swap_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
892 if (streq(key
, "state")) {
895 state
= swap_state_from_string(value
);
897 log_unit_debug(u
, "Failed to parse state value: %s", value
);
899 s
->deserialized_state
= state
;
900 } else if (streq(key
, "result")) {
903 f
= swap_result_from_string(value
);
905 log_unit_debug(u
, "Failed to parse result value: %s", value
);
906 else if (f
!= SWAP_SUCCESS
)
908 } else if (streq(key
, "control-pid")) {
911 if (parse_pid(value
, &pid
) < 0)
912 log_unit_debug(u
, "Failed to parse control-pid value: %s", value
);
914 s
->control_pid
= pid
;
916 } else if (streq(key
, "control-command")) {
919 id
= swap_exec_command_from_string(value
);
921 log_unit_debug(u
, "Failed to parse exec-command value: %s", value
);
923 s
->control_command_id
= id
;
924 s
->control_command
= s
->exec_command
+ id
;
927 log_unit_debug(u
, "Unknown serialization key: %s", key
);
932 _pure_
static UnitActiveState
swap_active_state(Unit
*u
) {
935 return state_translation_table
[SWAP(u
)->state
];
938 _pure_
static const char *swap_sub_state_to_string(Unit
*u
) {
941 return swap_state_to_string(SWAP(u
)->state
);
944 _pure_
static bool swap_check_gc(Unit
*u
) {
949 return s
->from_proc_swaps
;
952 static void swap_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
959 if (pid
!= s
->control_pid
)
964 if (is_clean_exit(code
, status
, NULL
))
966 else if (code
== CLD_EXITED
)
967 f
= SWAP_FAILURE_EXIT_CODE
;
968 else if (code
== CLD_KILLED
)
969 f
= SWAP_FAILURE_SIGNAL
;
970 else if (code
== CLD_DUMPED
)
971 f
= SWAP_FAILURE_CORE_DUMP
;
973 assert_not_reached("Unknown code");
975 if (f
!= SWAP_SUCCESS
)
978 if (s
->control_command
) {
979 exec_status_exit(&s
->control_command
->exec_status
, &s
->exec_context
, pid
, code
, status
);
981 s
->control_command
= NULL
;
982 s
->control_command_id
= _SWAP_EXEC_COMMAND_INVALID
;
985 log_unit_full(u
, f
== SWAP_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, 0,
986 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code
), status
);
990 case SWAP_ACTIVATING
:
991 case SWAP_ACTIVATING_DONE
:
992 case SWAP_ACTIVATING_SIGTERM
:
993 case SWAP_ACTIVATING_SIGKILL
:
995 if (f
== SWAP_SUCCESS
)
996 swap_enter_active(s
, f
);
998 swap_enter_dead(s
, f
);
1001 case SWAP_DEACTIVATING
:
1002 case SWAP_DEACTIVATING_SIGKILL
:
1003 case SWAP_DEACTIVATING_SIGTERM
:
1005 swap_enter_dead(s
, f
);
1009 assert_not_reached("Uh, control process died at wrong time.");
1012 /* Notify clients about changed exit status */
1013 unit_add_to_dbus_queue(u
);
1016 static int swap_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1017 Swap
*s
= SWAP(userdata
);
1020 assert(s
->timer_event_source
== source
);
1024 case SWAP_ACTIVATING
:
1025 case SWAP_ACTIVATING_DONE
:
1026 log_unit_warning(UNIT(s
), "Activation timed out. Stopping.");
1027 swap_enter_signal(s
, SWAP_ACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1030 case SWAP_DEACTIVATING
:
1031 log_unit_warning(UNIT(s
), "Deactivation timed out. Stopping.");
1032 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGTERM
, SWAP_FAILURE_TIMEOUT
);
1035 case SWAP_ACTIVATING_SIGTERM
:
1036 if (s
->kill_context
.send_sigkill
) {
1037 log_unit_warning(UNIT(s
), "Activation timed out. Killing.");
1038 swap_enter_signal(s
, SWAP_ACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1040 log_unit_warning(UNIT(s
), "Activation timed out. Skipping SIGKILL. Ignoring.");
1041 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1045 case SWAP_DEACTIVATING_SIGTERM
:
1046 if (s
->kill_context
.send_sigkill
) {
1047 log_unit_warning(UNIT(s
), "Deactivation timed out. Killing.");
1048 swap_enter_signal(s
, SWAP_DEACTIVATING_SIGKILL
, SWAP_FAILURE_TIMEOUT
);
1050 log_unit_warning(UNIT(s
), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1051 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1055 case SWAP_ACTIVATING_SIGKILL
:
1056 case SWAP_DEACTIVATING_SIGKILL
:
1057 log_unit_warning(UNIT(s
), "Swap process still around after SIGKILL. Ignoring.");
1058 swap_enter_dead(s
, SWAP_FAILURE_TIMEOUT
);
1062 assert_not_reached("Timeout at wrong time.");
1068 static int swap_load_proc_swaps(Manager
*m
, bool set_flags
) {
1074 rewind(m
->proc_swaps
);
1076 (void) fscanf(m
->proc_swaps
, "%*s %*s %*s %*s %*s\n");
1079 _cleanup_free_
char *dev
= NULL
, *d
= NULL
;
1082 k
= fscanf(m
->proc_swaps
,
1083 "%ms " /* device/file */
1084 "%*s " /* type of swap */
1085 "%*s " /* swap size */
1087 "%i\n", /* priority */
1093 log_warning("Failed to parse /proc/swaps:%u.", i
);
1097 if (cunescape(dev
, UNESCAPE_RELAX
, &d
) < 0)
1100 device_found_node(m
, d
, true, DEVICE_FOUND_SWAP
, set_flags
);
1102 k
= swap_process_new(m
, d
, prio
, set_flags
);
1110 static int swap_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1111 Manager
*m
= userdata
;
1116 assert(revents
& EPOLLPRI
);
1118 r
= swap_load_proc_swaps(m
, true);
1120 log_error_errno(r
, "Failed to reread /proc/swaps: %m");
1122 /* Reset flags, just in case, for late calls */
1123 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1124 Swap
*swap
= SWAP(u
);
1126 swap
->is_active
= swap
->just_activated
= false;
1132 manager_dispatch_load_queue(m
);
1134 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_SWAP
]) {
1135 Swap
*swap
= SWAP(u
);
1137 if (!swap
->is_active
) {
1138 /* This has just been deactivated */
1140 swap_unset_proc_swaps(swap
);
1142 switch (swap
->state
) {
1145 swap_enter_dead(swap
, SWAP_SUCCESS
);
1150 swap_set_state(swap
, swap
->state
);
1155 device_found_node(m
, swap
->what
, false, DEVICE_FOUND_SWAP
, true);
1157 } else if (swap
->just_activated
) {
1159 /* New swap entry */
1161 switch (swap
->state
) {
1165 swap_enter_active(swap
, SWAP_SUCCESS
);
1168 case SWAP_ACTIVATING
:
1169 swap_set_state(swap
, SWAP_ACTIVATING_DONE
);
1173 /* Nothing really changed, but let's
1174 * issue an notification call
1175 * nonetheless, in case somebody is
1176 * waiting for this. */
1177 swap_set_state(swap
, swap
->state
);
1182 /* Reset the flags for later calls */
1183 swap
->is_active
= swap
->just_activated
= false;
1189 static Unit
*swap_following(Unit
*u
) {
1191 Swap
*other
, *first
= NULL
;
1195 /* If the user configured the swap through /etc/fstab or
1196 * a device unit, follow that. */
1198 if (s
->from_fragment
)
1201 LIST_FOREACH_OTHERS(same_devnode
, other
, s
)
1202 if (other
->from_fragment
)
1205 /* Otherwise make everybody follow the unit that's named after
1206 * the swap device in the kernel */
1208 if (streq_ptr(s
->what
, s
->devnode
))
1211 LIST_FOREACH_AFTER(same_devnode
, other
, s
)
1212 if (streq_ptr(other
->what
, other
->devnode
))
1215 LIST_FOREACH_BEFORE(same_devnode
, other
, s
) {
1216 if (streq_ptr(other
->what
, other
->devnode
))
1222 /* Fall back to the first on the list */
1226 static int swap_following_set(Unit
*u
, Set
**_set
) {
1227 Swap
*s
= SWAP(u
), *other
;
1234 if (LIST_JUST_US(same_devnode
, s
)) {
1239 set
= set_new(NULL
);
1243 LIST_FOREACH_OTHERS(same_devnode
, other
, s
) {
1244 r
= set_put(set
, other
);
1257 static void swap_shutdown(Manager
*m
) {
1260 m
->swap_event_source
= sd_event_source_unref(m
->swap_event_source
);
1262 m
->proc_swaps
= safe_fclose(m
->proc_swaps
);
1264 m
->swaps_by_devnode
= hashmap_free(m
->swaps_by_devnode
);
1267 static int swap_enumerate(Manager
*m
) {
1272 if (!m
->proc_swaps
) {
1273 m
->proc_swaps
= fopen("/proc/swaps", "re");
1275 return errno
== ENOENT
? 0 : -errno
;
1277 r
= sd_event_add_io(m
->event
, &m
->swap_event_source
, fileno(m
->proc_swaps
), EPOLLPRI
, swap_dispatch_io
, m
);
1281 /* Dispatch this before we dispatch SIGCHLD, so that
1282 * we always get the events from /proc/swaps before
1283 * the SIGCHLD of /sbin/swapon. */
1284 r
= sd_event_source_set_priority(m
->swap_event_source
, -10);
1288 (void) sd_event_source_set_description(m
->swap_event_source
, "swap-proc");
1291 r
= swap_load_proc_swaps(m
, false);
1302 int swap_process_device_new(Manager
*m
, struct udev_device
*dev
) {
1303 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
1304 _cleanup_free_
char *e
= NULL
;
1312 dn
= udev_device_get_devnode(dev
);
1316 r
= unit_name_from_path(dn
, ".swap", &e
);
1320 s
= hashmap_get(m
->units
, e
);
1322 r
= swap_set_devnode(s
, dn
);
1324 first
= udev_device_get_devlinks_list_entry(dev
);
1325 udev_list_entry_foreach(item
, first
) {
1326 _cleanup_free_
char *n
= NULL
;
1329 q
= unit_name_from_path(udev_list_entry_get_name(item
), ".swap", &n
);
1333 s
= hashmap_get(m
->units
, n
);
1335 q
= swap_set_devnode(s
, dn
);
1344 int swap_process_device_remove(Manager
*m
, struct udev_device
*dev
) {
1349 dn
= udev_device_get_devnode(dev
);
1353 while ((s
= hashmap_get(m
->swaps_by_devnode
, dn
))) {
1356 q
= swap_set_devnode(s
, NULL
);
1364 static void swap_reset_failed(Unit
*u
) {
1369 if (s
->state
== SWAP_FAILED
)
1370 swap_set_state(s
, SWAP_DEAD
);
1372 s
->result
= SWAP_SUCCESS
;
1375 static int swap_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1376 return unit_kill_common(u
, who
, signo
, -1, SWAP(u
)->control_pid
, error
);
1379 static int swap_get_timeout(Unit
*u
, uint64_t *timeout
) {
1383 if (!s
->timer_event_source
)
1386 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
1393 static bool swap_supported(void) {
1394 static int supported
= -1;
1396 /* If swap support is not available in the kernel, or we are
1397 * running in a container we don't support swap units, and any
1398 * attempts to starting one should fail immediately. */
1402 access("/proc/swaps", F_OK
) >= 0 &&
1403 detect_container() <= 0;
1408 static const char* const swap_exec_command_table
[_SWAP_EXEC_COMMAND_MAX
] = {
1409 [SWAP_EXEC_ACTIVATE
] = "ExecActivate",
1410 [SWAP_EXEC_DEACTIVATE
] = "ExecDeactivate",
1413 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command
, SwapExecCommand
);
1415 static const char* const swap_result_table
[_SWAP_RESULT_MAX
] = {
1416 [SWAP_SUCCESS
] = "success",
1417 [SWAP_FAILURE_RESOURCES
] = "resources",
1418 [SWAP_FAILURE_TIMEOUT
] = "timeout",
1419 [SWAP_FAILURE_EXIT_CODE
] = "exit-code",
1420 [SWAP_FAILURE_SIGNAL
] = "signal",
1421 [SWAP_FAILURE_CORE_DUMP
] = "core-dump"
1424 DEFINE_STRING_TABLE_LOOKUP(swap_result
, SwapResult
);
1426 const UnitVTable swap_vtable
= {
1427 .object_size
= sizeof(Swap
),
1428 .exec_context_offset
= offsetof(Swap
, exec_context
),
1429 .cgroup_context_offset
= offsetof(Swap
, cgroup_context
),
1430 .kill_context_offset
= offsetof(Swap
, kill_context
),
1431 .exec_runtime_offset
= offsetof(Swap
, exec_runtime
),
1437 .private_section
= "Swap",
1440 .no_instances
= true,
1446 .coldplug
= swap_coldplug
,
1450 .start
= swap_start
,
1455 .get_timeout
= swap_get_timeout
,
1457 .serialize
= swap_serialize
,
1458 .deserialize_item
= swap_deserialize_item
,
1460 .active_state
= swap_active_state
,
1461 .sub_state_to_string
= swap_sub_state_to_string
,
1463 .check_gc
= swap_check_gc
,
1465 .sigchld_event
= swap_sigchld_event
,
1467 .reset_failed
= swap_reset_failed
,
1469 .bus_vtable
= bus_swap_vtable
,
1470 .bus_set_property
= bus_swap_set_property
,
1471 .bus_commit_properties
= bus_swap_commit_properties
,
1473 .following
= swap_following
,
1474 .following_set
= swap_following_set
,
1476 .enumerate
= swap_enumerate
,
1477 .shutdown
= swap_shutdown
,
1478 .supported
= swap_supported
,
1480 .status_message_formats
= {
1481 .starting_stopping
= {
1482 [0] = "Activating swap %s...",
1483 [1] = "Deactivating swap %s...",
1485 .finished_start_job
= {
1486 [JOB_DONE
] = "Activated swap %s.",
1487 [JOB_FAILED
] = "Failed to activate swap %s.",
1488 [JOB_TIMEOUT
] = "Timed out activating swap %s.",
1490 .finished_stop_job
= {
1491 [JOB_DONE
] = "Deactivated swap %s.",
1492 [JOB_FAILED
] = "Failed deactivating swap %s.",
1493 [JOB_TIMEOUT
] = "Timed out deactivating swap %s.",