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