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