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