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