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