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