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