]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/swap.c
b6e4372fc0fbd15a2f92f51baaa852ff88a92503
[thirdparty/systemd.git] / src / core / swap.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <errno.h>
23 #include <sys/epoll.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26
27 #include "libudev.h"
28
29 #include "alloc-util.h"
30 #include "dbus-swap.h"
31 #include "escape.h"
32 #include "exit-status.h"
33 #include "fd-util.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"
39 #include "special.h"
40 #include "string-table.h"
41 #include "string-util.h"
42 #include "swap.h"
43 #include "udev-util.h"
44 #include "unit-name.h"
45 #include "unit.h"
46 #include "virt.h"
47
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
59 };
60
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);
63
64 static void swap_unset_proc_swaps(Swap *s) {
65 assert(s);
66
67 if (!s->from_proc_swaps)
68 return;
69
70 s->parameters_proc_swaps.what = mfree(s->parameters_proc_swaps.what);
71
72 s->from_proc_swaps = false;
73 }
74
75 static int swap_set_devnode(Swap *s, const char *devnode) {
76 Hashmap *swaps;
77 Swap *first;
78 int r;
79
80 assert(s);
81
82 r = hashmap_ensure_allocated(&UNIT(s)->manager->swaps_by_devnode, &string_hash_ops);
83 if (r < 0)
84 return r;
85
86 swaps = UNIT(s)->manager->swaps_by_devnode;
87
88 if (s->devnode) {
89 first = hashmap_get(swaps, s->devnode);
90
91 LIST_REMOVE(same_devnode, first, s);
92 if (first)
93 hashmap_replace(swaps, first->devnode, first);
94 else
95 hashmap_remove(swaps, s->devnode);
96
97 s->devnode = mfree(s->devnode);
98 }
99
100 if (devnode) {
101 s->devnode = strdup(devnode);
102 if (!s->devnode)
103 return -ENOMEM;
104
105 first = hashmap_get(swaps, s->devnode);
106 LIST_PREPEND(same_devnode, first, s);
107
108 return hashmap_replace(swaps, first->devnode, first);
109 }
110
111 return 0;
112 }
113
114 static void swap_init(Unit *u) {
115 Swap *s = SWAP(u);
116
117 assert(s);
118 assert(UNIT(s)->load_state == UNIT_STUB);
119
120 s->timeout_usec = u->manager->default_timeout_start_usec;
121
122 s->exec_context.std_output = u->manager->default_std_output;
123 s->exec_context.std_error = u->manager->default_std_error;
124
125 s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
126
127 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
128
129 u->ignore_on_isolate = true;
130 }
131
132 static void swap_unwatch_control_pid(Swap *s) {
133 assert(s);
134
135 if (s->control_pid <= 0)
136 return;
137
138 unit_unwatch_pid(UNIT(s), s->control_pid);
139 s->control_pid = 0;
140 }
141
142 static void swap_done(Unit *u) {
143 Swap *s = SWAP(u);
144
145 assert(s);
146
147 swap_unset_proc_swaps(s);
148 swap_set_devnode(s, NULL);
149
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);
153
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;
157
158 swap_unwatch_control_pid(s);
159
160 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
161 }
162
163 static int swap_arm_timer(Swap *s) {
164 int r;
165
166 assert(s);
167
168 if (s->timeout_usec <= 0) {
169 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
170 return 0;
171 }
172
173 if (s->timer_event_source) {
174 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec);
175 if (r < 0)
176 return r;
177
178 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
179 }
180
181 r = sd_event_add_time(
182 UNIT(s)->manager->event,
183 &s->timer_event_source,
184 CLOCK_MONOTONIC,
185 now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
186 swap_dispatch_timer, s);
187 if (r < 0)
188 return r;
189
190 (void) sd_event_source_set_description(s->timer_event_source, "swap-timer");
191
192 return 0;
193 }
194
195 static int swap_add_device_links(Swap *s) {
196 assert(s);
197
198 if (!s->what)
199 return 0;
200
201 if (!s->from_fragment)
202 return 0;
203
204 if (is_device_path(s->what))
205 return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == MANAGER_SYSTEM);
206 else
207 /* File based swap devices need to be ordered after
208 * systemd-remount-fs.service, since they might need a
209 * writable file system. */
210 return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_FS_SERVICE, NULL, true);
211 }
212
213 static int swap_add_default_dependencies(Swap *s) {
214 int r;
215
216 assert(s);
217
218 if (!UNIT(s)->default_dependencies)
219 return 0;
220
221 if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
222 return 0;
223
224 if (detect_container() > 0)
225 return 0;
226
227 /* swap units generated for the swap dev links are missing the
228 * ordering dep against the swap target. */
229 r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SWAP_TARGET, NULL, true);
230 if (r < 0)
231 return r;
232
233 return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
234 }
235
236 static int swap_verify(Swap *s) {
237 _cleanup_free_ char *e = NULL;
238 int r;
239
240 if (UNIT(s)->load_state != UNIT_LOADED)
241 return 0;
242
243 r = unit_name_from_path(s->what, ".swap", &e);
244 if (r < 0)
245 return log_unit_error_errno(UNIT(s), r, "Failed to generate unit name from path: %m");
246
247 if (!unit_has_name(UNIT(s), e)) {
248 log_unit_error(UNIT(s), "Value of What= and unit name do not match, not loading.");
249 return -EINVAL;
250 }
251
252 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
253 log_unit_error(UNIT(s), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing to load.");
254 return -EINVAL;
255 }
256
257 return 0;
258 }
259
260 static int swap_load_devnode(Swap *s) {
261 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
262 struct stat st;
263 const char *p;
264
265 assert(s);
266
267 if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
268 return 0;
269
270 d = udev_device_new_from_devnum(UNIT(s)->manager->udev, 'b', st.st_rdev);
271 if (!d)
272 return 0;
273
274 p = udev_device_get_devnode(d);
275 if (!p)
276 return 0;
277
278 return swap_set_devnode(s, p);
279 }
280
281 static int swap_load(Unit *u) {
282 int r;
283 Swap *s = SWAP(u);
284
285 assert(s);
286 assert(u->load_state == UNIT_STUB);
287
288 /* Load a .swap file */
289 r = unit_load_fragment_and_dropin_optional(u);
290 if (r < 0)
291 return r;
292
293 if (u->load_state == UNIT_LOADED) {
294
295 if (UNIT(s)->fragment_path)
296 s->from_fragment = true;
297
298 if (!s->what) {
299 if (s->parameters_fragment.what)
300 s->what = strdup(s->parameters_fragment.what);
301 else if (s->parameters_proc_swaps.what)
302 s->what = strdup(s->parameters_proc_swaps.what);
303 else {
304 r = unit_name_to_path(u->id, &s->what);
305 if (r < 0)
306 return r;
307 }
308
309 if (!s->what)
310 return -ENOMEM;
311 }
312
313 path_kill_slashes(s->what);
314
315 if (!UNIT(s)->description) {
316 r = unit_set_description(u, s->what);
317 if (r < 0)
318 return r;
319 }
320
321 r = unit_require_mounts_for(UNIT(s), s->what);
322 if (r < 0)
323 return r;
324
325 r = swap_add_device_links(s);
326 if (r < 0)
327 return r;
328
329 r = swap_load_devnode(s);
330 if (r < 0)
331 return r;
332
333 r = unit_patch_contexts(u);
334 if (r < 0)
335 return r;
336
337 r = unit_add_exec_dependencies(u, &s->exec_context);
338 if (r < 0)
339 return r;
340
341 r = unit_set_default_slice(u);
342 if (r < 0)
343 return r;
344
345 r = swap_add_default_dependencies(s);
346 if (r < 0)
347 return r;
348 }
349
350 return swap_verify(s);
351 }
352
353 static int swap_setup_unit(
354 Manager *m,
355 const char *what,
356 const char *what_proc_swaps,
357 int priority,
358 bool set_flags) {
359
360 _cleanup_free_ char *e = NULL;
361 bool delete = false;
362 Unit *u = NULL;
363 int r;
364 SwapParameters *p;
365
366 assert(m);
367 assert(what);
368 assert(what_proc_swaps);
369
370 r = unit_name_from_path(what, ".swap", &e);
371 if (r < 0)
372 return log_unit_error_errno(u, r, "Failed to generate unit name from path: %m");
373
374 u = manager_get_unit(m, e);
375
376 if (u &&
377 SWAP(u)->from_proc_swaps &&
378 !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps)) {
379 log_error("Swap %s appeared twice with different device paths %s and %s", e, SWAP(u)->parameters_proc_swaps.what, what_proc_swaps);
380 return -EEXIST;
381 }
382
383 if (!u) {
384 delete = true;
385
386 u = unit_new(m, sizeof(Swap));
387 if (!u)
388 return log_oom();
389
390 r = unit_add_name(u, e);
391 if (r < 0)
392 goto fail;
393
394 SWAP(u)->what = strdup(what);
395 if (!SWAP(u)->what) {
396 r = -ENOMEM;
397 goto fail;
398 }
399
400 unit_add_to_load_queue(u);
401 } else
402 delete = false;
403
404 p = &SWAP(u)->parameters_proc_swaps;
405
406 if (!p->what) {
407 p->what = strdup(what_proc_swaps);
408 if (!p->what) {
409 r = -ENOMEM;
410 goto fail;
411 }
412 }
413
414 if (set_flags) {
415 SWAP(u)->is_active = true;
416 SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps;
417 }
418
419 SWAP(u)->from_proc_swaps = true;
420
421 p->priority = priority;
422
423 unit_add_to_dbus_queue(u);
424 return 0;
425
426 fail:
427 log_unit_warning_errno(u, r, "Failed to load swap unit: %m");
428
429 if (delete && u)
430 unit_free(u);
431
432 return r;
433 }
434
435 static int swap_process_new(Manager *m, const char *device, int prio, bool set_flags) {
436 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
437 struct udev_list_entry *item = NULL, *first = NULL;
438 const char *dn;
439 struct stat st;
440 int r;
441
442 assert(m);
443
444 r = swap_setup_unit(m, device, device, prio, set_flags);
445 if (r < 0)
446 return r;
447
448 /* If this is a block device, then let's add duplicates for
449 * all other names of this block device */
450 if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
451 return 0;
452
453 d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev);
454 if (!d)
455 return 0;
456
457 /* Add the main device node */
458 dn = udev_device_get_devnode(d);
459 if (dn && !streq(dn, device))
460 swap_setup_unit(m, dn, device, prio, set_flags);
461
462 /* Add additional units for all symlinks */
463 first = udev_device_get_devlinks_list_entry(d);
464 udev_list_entry_foreach(item, first) {
465 const char *p;
466
467 /* Don't bother with the /dev/block links */
468 p = udev_list_entry_get_name(item);
469
470 if (streq(p, device))
471 continue;
472
473 if (path_startswith(p, "/dev/block/"))
474 continue;
475
476 if (stat(p, &st) >= 0)
477 if (!S_ISBLK(st.st_mode) ||
478 st.st_rdev != udev_device_get_devnum(d))
479 continue;
480
481 swap_setup_unit(m, p, device, prio, set_flags);
482 }
483
484 return r;
485 }
486
487 static void swap_set_state(Swap *s, SwapState state) {
488 SwapState old_state;
489 Swap *other;
490
491 assert(s);
492
493 old_state = s->state;
494 s->state = state;
495
496 if (state != SWAP_ACTIVATING &&
497 state != SWAP_ACTIVATING_SIGTERM &&
498 state != SWAP_ACTIVATING_SIGKILL &&
499 state != SWAP_ACTIVATING_DONE &&
500 state != SWAP_DEACTIVATING &&
501 state != SWAP_DEACTIVATING_SIGTERM &&
502 state != SWAP_DEACTIVATING_SIGKILL) {
503 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
504 swap_unwatch_control_pid(s);
505 s->control_command = NULL;
506 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
507 }
508
509 if (state != old_state)
510 log_unit_debug(UNIT(s), "Changed %s -> %s", swap_state_to_string(old_state), swap_state_to_string(state));
511
512 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
513
514 /* If there other units for the same device node have a job
515 queued it might be worth checking again if it is runnable
516 now. This is necessary, since swap_start() refuses
517 operation with EAGAIN if there's already another job for
518 the same device node queued. */
519 LIST_FOREACH_OTHERS(same_devnode, other, s)
520 if (UNIT(other)->job)
521 job_add_to_run_queue(UNIT(other)->job);
522 }
523
524 static int swap_coldplug(Unit *u) {
525 Swap *s = SWAP(u);
526 SwapState new_state = SWAP_DEAD;
527 int r;
528
529 assert(s);
530 assert(s->state == SWAP_DEAD);
531
532 if (s->deserialized_state != s->state)
533 new_state = s->deserialized_state;
534 else if (s->from_proc_swaps)
535 new_state = SWAP_ACTIVE;
536
537 if (new_state == s->state)
538 return 0;
539
540 if (s->control_pid > 0 &&
541 pid_is_unwaited(s->control_pid) &&
542 IN_SET(new_state,
543 SWAP_ACTIVATING,
544 SWAP_ACTIVATING_SIGTERM,
545 SWAP_ACTIVATING_SIGKILL,
546 SWAP_ACTIVATING_DONE,
547 SWAP_DEACTIVATING,
548 SWAP_DEACTIVATING_SIGTERM,
549 SWAP_DEACTIVATING_SIGKILL)) {
550
551 r = unit_watch_pid(UNIT(s), s->control_pid);
552 if (r < 0)
553 return r;
554
555 r = swap_arm_timer(s);
556 if (r < 0)
557 return r;
558 }
559
560 swap_set_state(s, new_state);
561 return 0;
562 }
563
564 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
565 Swap *s = SWAP(u);
566 SwapParameters *p;
567
568 assert(s);
569 assert(f);
570
571 if (s->from_proc_swaps)
572 p = &s->parameters_proc_swaps;
573 else if (s->from_fragment)
574 p = &s->parameters_fragment;
575 else
576 p = NULL;
577
578 fprintf(f,
579 "%sSwap State: %s\n"
580 "%sResult: %s\n"
581 "%sWhat: %s\n"
582 "%sFrom /proc/swaps: %s\n"
583 "%sFrom fragment: %s\n",
584 prefix, swap_state_to_string(s->state),
585 prefix, swap_result_to_string(s->result),
586 prefix, s->what,
587 prefix, yes_no(s->from_proc_swaps),
588 prefix, yes_no(s->from_fragment));
589
590 if (s->devnode)
591 fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
592
593 if (p)
594 fprintf(f,
595 "%sPriority: %i\n"
596 "%sOptions: %s\n",
597 prefix, p->priority,
598 prefix, strempty(p->options));
599
600 if (s->control_pid > 0)
601 fprintf(f,
602 "%sControl PID: "PID_FMT"\n",
603 prefix, s->control_pid);
604
605 exec_context_dump(&s->exec_context, f, prefix);
606 kill_context_dump(&s->kill_context, f, prefix);
607 }
608
609 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
610 pid_t pid;
611 int r;
612 ExecParameters exec_params = {
613 .apply_permissions = true,
614 .apply_chroot = true,
615 .apply_tty_stdin = true,
616 .bus_endpoint_fd = -1,
617 .stdin_fd = -1,
618 .stdout_fd = -1,
619 .stderr_fd = -1,
620 };
621
622 assert(s);
623 assert(c);
624 assert(_pid);
625
626 (void) unit_realize_cgroup(UNIT(s));
627 if (s->reset_cpu_usage) {
628 (void) unit_reset_cpu_usage(UNIT(s));
629 s->reset_cpu_usage = false;
630 }
631
632 r = unit_setup_exec_runtime(UNIT(s));
633 if (r < 0)
634 goto fail;
635
636 r = swap_arm_timer(s);
637 if (r < 0)
638 goto fail;
639
640 exec_params.environment = UNIT(s)->manager->environment;
641 exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
642 exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
643 exec_params.cgroup_path = UNIT(s)->cgroup_path;
644 exec_params.cgroup_delegate = s->cgroup_context.delegate;
645 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
646
647 r = exec_spawn(UNIT(s),
648 c,
649 &s->exec_context,
650 &exec_params,
651 s->exec_runtime,
652 &pid);
653 if (r < 0)
654 goto fail;
655
656 r = unit_watch_pid(UNIT(s), pid);
657 if (r < 0)
658 /* FIXME: we need to do something here */
659 goto fail;
660
661 *_pid = pid;
662
663 return 0;
664
665 fail:
666 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
667 return r;
668 }
669
670 static void swap_enter_dead(Swap *s, SwapResult f) {
671 assert(s);
672
673 if (f != SWAP_SUCCESS)
674 s->result = f;
675
676 exec_runtime_destroy(s->exec_runtime);
677 s->exec_runtime = exec_runtime_unref(s->exec_runtime);
678
679 exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
680
681 swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
682 }
683
684 static void swap_enter_active(Swap *s, SwapResult f) {
685 assert(s);
686
687 if (f != SWAP_SUCCESS)
688 s->result = f;
689
690 swap_set_state(s, SWAP_ACTIVE);
691 }
692
693 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
694 int r;
695
696 assert(s);
697
698 if (f != SWAP_SUCCESS)
699 s->result = f;
700
701 r = unit_kill_context(
702 UNIT(s),
703 &s->kill_context,
704 (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
705 KILL_KILL : KILL_TERMINATE,
706 -1,
707 s->control_pid,
708 false);
709 if (r < 0)
710 goto fail;
711
712 if (r > 0) {
713 r = swap_arm_timer(s);
714 if (r < 0)
715 goto fail;
716
717 swap_set_state(s, state);
718 } else if (state == SWAP_ACTIVATING_SIGTERM)
719 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_SUCCESS);
720 else if (state == SWAP_DEACTIVATING_SIGTERM)
721 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_SUCCESS);
722 else
723 swap_enter_dead(s, SWAP_SUCCESS);
724
725 return;
726
727 fail:
728 log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
729 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
730 }
731
732 static void swap_enter_activating(Swap *s) {
733 _cleanup_free_ char *opts = NULL;
734 int r;
735
736 assert(s);
737
738 s->control_command_id = SWAP_EXEC_ACTIVATE;
739 s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
740
741 if (s->from_fragment) {
742 int priority = -1;
743
744 r = fstab_find_pri(s->parameters_fragment.options, &priority);
745 if (r < 0)
746 log_warning_errno(r, "Failed to parse swap priority \"%s\", ignoring: %m", s->parameters_fragment.options);
747 else if (r == 1 && s->parameters_fragment.priority >= 0)
748 log_warning("Duplicate swap priority configuration by Priority and Options fields.");
749
750 if (r <= 0 && s->parameters_fragment.priority >= 0) {
751 if (s->parameters_fragment.options)
752 r = asprintf(&opts, "%s,pri=%i", s->parameters_fragment.options, s->parameters_fragment.priority);
753 else
754 r = asprintf(&opts, "pri=%i", s->parameters_fragment.priority);
755 if (r < 0)
756 goto fail;
757 }
758 }
759
760 r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
761 if (r < 0)
762 goto fail;
763
764 if (s->parameters_fragment.options || opts) {
765 r = exec_command_append(s->control_command, "-o",
766 opts ? : s->parameters_fragment.options, NULL);
767 if (r < 0)
768 goto fail;
769 }
770
771 r = exec_command_append(s->control_command, s->what, NULL);
772 if (r < 0)
773 goto fail;
774
775 swap_unwatch_control_pid(s);
776
777 r = swap_spawn(s, s->control_command, &s->control_pid);
778 if (r < 0)
779 goto fail;
780
781 swap_set_state(s, SWAP_ACTIVATING);
782
783 return;
784
785 fail:
786 log_unit_warning_errno(UNIT(s), r, "Failed to run 'swapon' task: %m");
787 swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
788 }
789
790 static void swap_enter_deactivating(Swap *s) {
791 int r;
792
793 assert(s);
794
795 s->control_command_id = SWAP_EXEC_DEACTIVATE;
796 s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
797
798 r = exec_command_set(s->control_command,
799 "/sbin/swapoff",
800 s->what,
801 NULL);
802 if (r < 0)
803 goto fail;
804
805 swap_unwatch_control_pid(s);
806
807 r = swap_spawn(s, s->control_command, &s->control_pid);
808 if (r < 0)
809 goto fail;
810
811 swap_set_state(s, SWAP_DEACTIVATING);
812
813 return;
814
815 fail:
816 log_unit_warning_errno(UNIT(s), r, "Failed to run 'swapoff' task: %m");
817 swap_enter_active(s, SWAP_FAILURE_RESOURCES);
818 }
819
820 static int swap_start(Unit *u) {
821 Swap *s = SWAP(u), *other;
822
823 assert(s);
824
825 /* We cannot fulfill this request right now, try again later
826 * please! */
827
828 if (s->state == SWAP_DEACTIVATING ||
829 s->state == SWAP_DEACTIVATING_SIGTERM ||
830 s->state == SWAP_DEACTIVATING_SIGKILL ||
831 s->state == SWAP_ACTIVATING_SIGTERM ||
832 s->state == SWAP_ACTIVATING_SIGKILL)
833 return -EAGAIN;
834
835 if (s->state == SWAP_ACTIVATING)
836 return 0;
837
838 assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
839
840 if (detect_container() > 0)
841 return -EPERM;
842
843 /* If there's a job for another swap unit for the same node
844 * running, then let's not dispatch this one for now, and wait
845 * until that other job has finished. */
846 LIST_FOREACH_OTHERS(same_devnode, other, s)
847 if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
848 return -EAGAIN;
849
850 s->result = SWAP_SUCCESS;
851 s->reset_cpu_usage = true;
852
853 swap_enter_activating(s);
854 return 1;
855 }
856
857 static int swap_stop(Unit *u) {
858 Swap *s = SWAP(u);
859
860 assert(s);
861
862 if (s->state == SWAP_DEACTIVATING ||
863 s->state == SWAP_DEACTIVATING_SIGTERM ||
864 s->state == SWAP_DEACTIVATING_SIGKILL ||
865 s->state == SWAP_ACTIVATING_SIGTERM ||
866 s->state == SWAP_ACTIVATING_SIGKILL)
867 return 0;
868
869 assert(s->state == SWAP_ACTIVATING ||
870 s->state == SWAP_ACTIVATING_DONE ||
871 s->state == SWAP_ACTIVE);
872
873 if (detect_container() > 0)
874 return -EPERM;
875
876 swap_enter_deactivating(s);
877 return 1;
878 }
879
880 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
881 Swap *s = SWAP(u);
882
883 assert(s);
884 assert(f);
885 assert(fds);
886
887 unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
888 unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
889
890 if (s->control_pid > 0)
891 unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
892
893 if (s->control_command_id >= 0)
894 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
895
896 return 0;
897 }
898
899 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
900 Swap *s = SWAP(u);
901
902 assert(s);
903 assert(fds);
904
905 if (streq(key, "state")) {
906 SwapState state;
907
908 state = swap_state_from_string(value);
909 if (state < 0)
910 log_unit_debug(u, "Failed to parse state value: %s", value);
911 else
912 s->deserialized_state = state;
913 } else if (streq(key, "result")) {
914 SwapResult f;
915
916 f = swap_result_from_string(value);
917 if (f < 0)
918 log_unit_debug(u, "Failed to parse result value: %s", value);
919 else if (f != SWAP_SUCCESS)
920 s->result = f;
921 } else if (streq(key, "control-pid")) {
922 pid_t pid;
923
924 if (parse_pid(value, &pid) < 0)
925 log_unit_debug(u, "Failed to parse control-pid value: %s", value);
926 else
927 s->control_pid = pid;
928
929 } else if (streq(key, "control-command")) {
930 SwapExecCommand id;
931
932 id = swap_exec_command_from_string(value);
933 if (id < 0)
934 log_unit_debug(u, "Failed to parse exec-command value: %s", value);
935 else {
936 s->control_command_id = id;
937 s->control_command = s->exec_command + id;
938 }
939 } else
940 log_unit_debug(u, "Unknown serialization key: %s", key);
941
942 return 0;
943 }
944
945 _pure_ static UnitActiveState swap_active_state(Unit *u) {
946 assert(u);
947
948 return state_translation_table[SWAP(u)->state];
949 }
950
951 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
952 assert(u);
953
954 return swap_state_to_string(SWAP(u)->state);
955 }
956
957 _pure_ static bool swap_check_gc(Unit *u) {
958 Swap *s = SWAP(u);
959
960 assert(s);
961
962 return s->from_proc_swaps;
963 }
964
965 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
966 Swap *s = SWAP(u);
967 SwapResult f;
968
969 assert(s);
970 assert(pid >= 0);
971
972 if (pid != s->control_pid)
973 return;
974
975 s->control_pid = 0;
976
977 if (is_clean_exit(code, status, NULL))
978 f = SWAP_SUCCESS;
979 else if (code == CLD_EXITED)
980 f = SWAP_FAILURE_EXIT_CODE;
981 else if (code == CLD_KILLED)
982 f = SWAP_FAILURE_SIGNAL;
983 else if (code == CLD_DUMPED)
984 f = SWAP_FAILURE_CORE_DUMP;
985 else
986 assert_not_reached("Unknown code");
987
988 if (f != SWAP_SUCCESS)
989 s->result = f;
990
991 if (s->control_command) {
992 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
993
994 s->control_command = NULL;
995 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
996 }
997
998 log_unit_full(u, f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0,
999 "Swap process exited, code=%s status=%i", sigchld_code_to_string(code), status);
1000
1001 switch (s->state) {
1002
1003 case SWAP_ACTIVATING:
1004 case SWAP_ACTIVATING_DONE:
1005 case SWAP_ACTIVATING_SIGTERM:
1006 case SWAP_ACTIVATING_SIGKILL:
1007
1008 if (f == SWAP_SUCCESS)
1009 swap_enter_active(s, f);
1010 else
1011 swap_enter_dead(s, f);
1012 break;
1013
1014 case SWAP_DEACTIVATING:
1015 case SWAP_DEACTIVATING_SIGKILL:
1016 case SWAP_DEACTIVATING_SIGTERM:
1017
1018 swap_enter_dead(s, f);
1019 break;
1020
1021 default:
1022 assert_not_reached("Uh, control process died at wrong time.");
1023 }
1024
1025 /* Notify clients about changed exit status */
1026 unit_add_to_dbus_queue(u);
1027 }
1028
1029 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1030 Swap *s = SWAP(userdata);
1031
1032 assert(s);
1033 assert(s->timer_event_source == source);
1034
1035 switch (s->state) {
1036
1037 case SWAP_ACTIVATING:
1038 case SWAP_ACTIVATING_DONE:
1039 log_unit_warning(UNIT(s), "Activation timed out. Stopping.");
1040 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1041 break;
1042
1043 case SWAP_DEACTIVATING:
1044 log_unit_warning(UNIT(s), "Deactivation timed out. Stopping.");
1045 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1046 break;
1047
1048 case SWAP_ACTIVATING_SIGTERM:
1049 if (s->kill_context.send_sigkill) {
1050 log_unit_warning(UNIT(s), "Activation timed out. Killing.");
1051 swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1052 } else {
1053 log_unit_warning(UNIT(s), "Activation timed out. Skipping SIGKILL. Ignoring.");
1054 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1055 }
1056 break;
1057
1058 case SWAP_DEACTIVATING_SIGTERM:
1059 if (s->kill_context.send_sigkill) {
1060 log_unit_warning(UNIT(s), "Deactivation timed out. Killing.");
1061 swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1062 } else {
1063 log_unit_warning(UNIT(s), "Deactivation timed out. Skipping SIGKILL. Ignoring.");
1064 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1065 }
1066 break;
1067
1068 case SWAP_ACTIVATING_SIGKILL:
1069 case SWAP_DEACTIVATING_SIGKILL:
1070 log_unit_warning(UNIT(s), "Swap process still around after SIGKILL. Ignoring.");
1071 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1072 break;
1073
1074 default:
1075 assert_not_reached("Timeout at wrong time.");
1076 }
1077
1078 return 0;
1079 }
1080
1081 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1082 unsigned i;
1083 int r = 0;
1084
1085 assert(m);
1086
1087 rewind(m->proc_swaps);
1088
1089 (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1090
1091 for (i = 1;; i++) {
1092 _cleanup_free_ char *dev = NULL, *d = NULL;
1093 int prio = 0, k;
1094
1095 k = fscanf(m->proc_swaps,
1096 "%ms " /* device/file */
1097 "%*s " /* type of swap */
1098 "%*s " /* swap size */
1099 "%*s " /* used */
1100 "%i\n", /* priority */
1101 &dev, &prio);
1102 if (k != 2) {
1103 if (k == EOF)
1104 break;
1105
1106 log_warning("Failed to parse /proc/swaps:%u.", i);
1107 continue;
1108 }
1109
1110 if (cunescape(dev, UNESCAPE_RELAX, &d) < 0)
1111 return log_oom();
1112
1113 device_found_node(m, d, true, DEVICE_FOUND_SWAP, set_flags);
1114
1115 k = swap_process_new(m, d, prio, set_flags);
1116 if (k < 0)
1117 r = k;
1118 }
1119
1120 return r;
1121 }
1122
1123 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1124 Manager *m = userdata;
1125 Unit *u;
1126 int r;
1127
1128 assert(m);
1129 assert(revents & EPOLLPRI);
1130
1131 r = swap_load_proc_swaps(m, true);
1132 if (r < 0) {
1133 log_error_errno(r, "Failed to reread /proc/swaps: %m");
1134
1135 /* Reset flags, just in case, for late calls */
1136 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1137 Swap *swap = SWAP(u);
1138
1139 swap->is_active = swap->just_activated = false;
1140 }
1141
1142 return 0;
1143 }
1144
1145 manager_dispatch_load_queue(m);
1146
1147 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1148 Swap *swap = SWAP(u);
1149
1150 if (!swap->is_active) {
1151 /* This has just been deactivated */
1152
1153 swap_unset_proc_swaps(swap);
1154
1155 switch (swap->state) {
1156
1157 case SWAP_ACTIVE:
1158 swap_enter_dead(swap, SWAP_SUCCESS);
1159 break;
1160
1161 default:
1162 /* Fire again */
1163 swap_set_state(swap, swap->state);
1164 break;
1165 }
1166
1167 if (swap->what)
1168 device_found_node(m, swap->what, false, DEVICE_FOUND_SWAP, true);
1169
1170 } else if (swap->just_activated) {
1171
1172 /* New swap entry */
1173
1174 switch (swap->state) {
1175
1176 case SWAP_DEAD:
1177 case SWAP_FAILED:
1178 swap_enter_active(swap, SWAP_SUCCESS);
1179 break;
1180
1181 case SWAP_ACTIVATING:
1182 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1183 break;
1184
1185 default:
1186 /* Nothing really changed, but let's
1187 * issue an notification call
1188 * nonetheless, in case somebody is
1189 * waiting for this. */
1190 swap_set_state(swap, swap->state);
1191 break;
1192 }
1193 }
1194
1195 /* Reset the flags for later calls */
1196 swap->is_active = swap->just_activated = false;
1197 }
1198
1199 return 1;
1200 }
1201
1202 static Unit *swap_following(Unit *u) {
1203 Swap *s = SWAP(u);
1204 Swap *other, *first = NULL;
1205
1206 assert(s);
1207
1208 /* If the user configured the swap through /etc/fstab or
1209 * a device unit, follow that. */
1210
1211 if (s->from_fragment)
1212 return NULL;
1213
1214 LIST_FOREACH_OTHERS(same_devnode, other, s)
1215 if (other->from_fragment)
1216 return UNIT(other);
1217
1218 /* Otherwise, make everybody follow the unit that's named after
1219 * the swap device in the kernel */
1220
1221 if (streq_ptr(s->what, s->devnode))
1222 return NULL;
1223
1224 LIST_FOREACH_AFTER(same_devnode, other, s)
1225 if (streq_ptr(other->what, other->devnode))
1226 return UNIT(other);
1227
1228 LIST_FOREACH_BEFORE(same_devnode, other, s) {
1229 if (streq_ptr(other->what, other->devnode))
1230 return UNIT(other);
1231
1232 first = other;
1233 }
1234
1235 /* Fall back to the first on the list */
1236 return UNIT(first);
1237 }
1238
1239 static int swap_following_set(Unit *u, Set **_set) {
1240 Swap *s = SWAP(u), *other;
1241 Set *set;
1242 int r;
1243
1244 assert(s);
1245 assert(_set);
1246
1247 if (LIST_JUST_US(same_devnode, s)) {
1248 *_set = NULL;
1249 return 0;
1250 }
1251
1252 set = set_new(NULL);
1253 if (!set)
1254 return -ENOMEM;
1255
1256 LIST_FOREACH_OTHERS(same_devnode, other, s) {
1257 r = set_put(set, other);
1258 if (r < 0)
1259 goto fail;
1260 }
1261
1262 *_set = set;
1263 return 1;
1264
1265 fail:
1266 set_free(set);
1267 return r;
1268 }
1269
1270 static void swap_shutdown(Manager *m) {
1271 assert(m);
1272
1273 m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1274
1275 m->proc_swaps = safe_fclose(m->proc_swaps);
1276
1277 m->swaps_by_devnode = hashmap_free(m->swaps_by_devnode);
1278 }
1279
1280 static void swap_enumerate(Manager *m) {
1281 int r;
1282
1283 assert(m);
1284
1285 if (!m->proc_swaps) {
1286 m->proc_swaps = fopen("/proc/swaps", "re");
1287 if (!m->proc_swaps) {
1288 if (errno == ENOENT)
1289 log_debug("Not swap enabled, skipping enumeration");
1290 else
1291 log_error_errno(errno, "Failed to open /proc/swaps: %m");
1292
1293 return;
1294 }
1295
1296 r = sd_event_add_io(m->event, &m->swap_event_source, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m);
1297 if (r < 0) {
1298 log_error_errno(r, "Failed to watch /proc/swaps: %m");
1299 goto fail;
1300 }
1301
1302 /* Dispatch this before we dispatch SIGCHLD, so that
1303 * we always get the events from /proc/swaps before
1304 * the SIGCHLD of /sbin/swapon. */
1305 r = sd_event_source_set_priority(m->swap_event_source, -10);
1306 if (r < 0) {
1307 log_error_errno(r, "Failed to change /proc/swaps priority: %m");
1308 goto fail;
1309 }
1310
1311 (void) sd_event_source_set_description(m->swap_event_source, "swap-proc");
1312 }
1313
1314 r = swap_load_proc_swaps(m, false);
1315 if (r < 0)
1316 goto fail;
1317
1318 return;
1319
1320 fail:
1321 swap_shutdown(m);
1322 }
1323
1324 int swap_process_device_new(Manager *m, struct udev_device *dev) {
1325 struct udev_list_entry *item = NULL, *first = NULL;
1326 _cleanup_free_ char *e = NULL;
1327 const char *dn;
1328 Swap *s;
1329 int r = 0;
1330
1331 assert(m);
1332 assert(dev);
1333
1334 dn = udev_device_get_devnode(dev);
1335 if (!dn)
1336 return 0;
1337
1338 r = unit_name_from_path(dn, ".swap", &e);
1339 if (r < 0)
1340 return r;
1341
1342 s = hashmap_get(m->units, e);
1343 if (s)
1344 r = swap_set_devnode(s, dn);
1345
1346 first = udev_device_get_devlinks_list_entry(dev);
1347 udev_list_entry_foreach(item, first) {
1348 _cleanup_free_ char *n = NULL;
1349 int q;
1350
1351 q = unit_name_from_path(udev_list_entry_get_name(item), ".swap", &n);
1352 if (q < 0)
1353 return q;
1354
1355 s = hashmap_get(m->units, n);
1356 if (s) {
1357 q = swap_set_devnode(s, dn);
1358 if (q < 0)
1359 r = q;
1360 }
1361 }
1362
1363 return r;
1364 }
1365
1366 int swap_process_device_remove(Manager *m, struct udev_device *dev) {
1367 const char *dn;
1368 int r = 0;
1369 Swap *s;
1370
1371 dn = udev_device_get_devnode(dev);
1372 if (!dn)
1373 return 0;
1374
1375 while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1376 int q;
1377
1378 q = swap_set_devnode(s, NULL);
1379 if (q < 0)
1380 r = q;
1381 }
1382
1383 return r;
1384 }
1385
1386 static void swap_reset_failed(Unit *u) {
1387 Swap *s = SWAP(u);
1388
1389 assert(s);
1390
1391 if (s->state == SWAP_FAILED)
1392 swap_set_state(s, SWAP_DEAD);
1393
1394 s->result = SWAP_SUCCESS;
1395 }
1396
1397 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1398 return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1399 }
1400
1401 static int swap_get_timeout(Unit *u, uint64_t *timeout) {
1402 Swap *s = SWAP(u);
1403 int r;
1404
1405 if (!s->timer_event_source)
1406 return 0;
1407
1408 r = sd_event_source_get_time(s->timer_event_source, timeout);
1409 if (r < 0)
1410 return r;
1411
1412 return 1;
1413 }
1414
1415 static bool swap_supported(void) {
1416 static int supported = -1;
1417
1418 /* If swap support is not available in the kernel, or we are
1419 * running in a container we don't support swap units, and any
1420 * attempts to starting one should fail immediately. */
1421
1422 if (supported < 0)
1423 supported =
1424 access("/proc/swaps", F_OK) >= 0 &&
1425 detect_container() <= 0;
1426
1427 return supported;
1428 }
1429
1430 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1431 [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1432 [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1433 };
1434
1435 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1436
1437 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1438 [SWAP_SUCCESS] = "success",
1439 [SWAP_FAILURE_RESOURCES] = "resources",
1440 [SWAP_FAILURE_TIMEOUT] = "timeout",
1441 [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1442 [SWAP_FAILURE_SIGNAL] = "signal",
1443 [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1444 };
1445
1446 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1447
1448 const UnitVTable swap_vtable = {
1449 .object_size = sizeof(Swap),
1450 .exec_context_offset = offsetof(Swap, exec_context),
1451 .cgroup_context_offset = offsetof(Swap, cgroup_context),
1452 .kill_context_offset = offsetof(Swap, kill_context),
1453 .exec_runtime_offset = offsetof(Swap, exec_runtime),
1454
1455 .sections =
1456 "Unit\0"
1457 "Swap\0"
1458 "Install\0",
1459 .private_section = "Swap",
1460
1461 .no_alias = true,
1462 .no_instances = true,
1463
1464 .init = swap_init,
1465 .load = swap_load,
1466 .done = swap_done,
1467
1468 .coldplug = swap_coldplug,
1469
1470 .dump = swap_dump,
1471
1472 .start = swap_start,
1473 .stop = swap_stop,
1474
1475 .kill = swap_kill,
1476
1477 .get_timeout = swap_get_timeout,
1478
1479 .serialize = swap_serialize,
1480 .deserialize_item = swap_deserialize_item,
1481
1482 .active_state = swap_active_state,
1483 .sub_state_to_string = swap_sub_state_to_string,
1484
1485 .check_gc = swap_check_gc,
1486
1487 .sigchld_event = swap_sigchld_event,
1488
1489 .reset_failed = swap_reset_failed,
1490
1491 .bus_vtable = bus_swap_vtable,
1492 .bus_set_property = bus_swap_set_property,
1493 .bus_commit_properties = bus_swap_commit_properties,
1494
1495 .following = swap_following,
1496 .following_set = swap_following_set,
1497
1498 .enumerate = swap_enumerate,
1499 .shutdown = swap_shutdown,
1500 .supported = swap_supported,
1501
1502 .status_message_formats = {
1503 .starting_stopping = {
1504 [0] = "Activating swap %s...",
1505 [1] = "Deactivating swap %s...",
1506 },
1507 .finished_start_job = {
1508 [JOB_DONE] = "Activated swap %s.",
1509 [JOB_FAILED] = "Failed to activate swap %s.",
1510 [JOB_TIMEOUT] = "Timed out activating swap %s.",
1511 },
1512 .finished_stop_job = {
1513 [JOB_DONE] = "Deactivated swap %s.",
1514 [JOB_FAILED] = "Failed deactivating swap %s.",
1515 [JOB_TIMEOUT] = "Timed out deactivating swap %s.",
1516 },
1517 },
1518 };