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