chiark / gitweb /
load-fragment: a few modernizations
[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                             UNIT(s)->id,
594                             NULL,
595                             &pid)) < 0)
596                 goto fail;
597
598         if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
599                 /* FIXME: we need to do something here */
600                 goto fail;
601
602         *_pid = pid;
603
604         return 0;
605
606 fail:
607         unit_unwatch_timer(UNIT(s), &s->timer_watch);
608
609         return r;
610 }
611
612 static void swap_enter_dead(Swap *s, SwapResult f) {
613         assert(s);
614
615         if (f != SWAP_SUCCESS)
616                 s->result = f;
617
618         swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
619 }
620
621 static void swap_enter_active(Swap *s, SwapResult f) {
622         assert(s);
623
624         if (f != SWAP_SUCCESS)
625                 s->result = f;
626
627         swap_set_state(s, SWAP_ACTIVE);
628 }
629
630 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
631         int r;
632         Set *pid_set = NULL;
633         bool wait_for_exit = false;
634
635         assert(s);
636
637         if (f != SWAP_SUCCESS)
638                 s->result = f;
639
640         if (s->exec_context.kill_mode != KILL_NONE) {
641                 int sig = (state == SWAP_ACTIVATING_SIGTERM ||
642                            state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
643
644                 if (s->control_pid > 0) {
645                         if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH)
646
647                                 log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
648                         else
649                                 wait_for_exit = true;
650                 }
651
652                 if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
653
654                         if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
655                                 r = -ENOMEM;
656                                 goto fail;
657                         }
658
659                         /* Exclude the control pid from being killed via the cgroup */
660                         if (s->control_pid > 0)
661                                 if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
662                                         goto fail;
663
664                         r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, false, pid_set, NULL);
665                         if (r < 0) {
666                                 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
667                                         log_warning("Failed to kill control group: %s", strerror(-r));
668                         } else if (r > 0)
669                                 wait_for_exit = true;
670
671                         set_free(pid_set);
672                         pid_set = NULL;
673                 }
674         }
675
676         if (wait_for_exit) {
677                 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
678                         goto fail;
679
680                 swap_set_state(s, state);
681         } else
682                 swap_enter_dead(s, SWAP_SUCCESS);
683
684         return;
685
686 fail:
687         log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
688
689         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
690
691         if (pid_set)
692                 set_free(pid_set);
693 }
694
695 static void swap_enter_activating(Swap *s) {
696         int r, priority;
697
698         assert(s);
699
700         s->control_command_id = SWAP_EXEC_ACTIVATE;
701         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
702
703         if (s->from_fragment)
704                 priority = s->parameters_fragment.priority;
705         else
706                 priority = -1;
707
708         if (priority >= 0) {
709                 char p[LINE_MAX];
710
711                 snprintf(p, sizeof(p), "%i", priority);
712                 char_array_0(p);
713
714                 r = exec_command_set(
715                                 s->control_command,
716                                 "/sbin/swapon",
717                                 "-p",
718                                 p,
719                                 s->what,
720                                 NULL);
721         } else
722                 r = exec_command_set(
723                                 s->control_command,
724                                 "/sbin/swapon",
725                                 s->what,
726                                 NULL);
727
728         if (r < 0)
729                 goto fail;
730
731         swap_unwatch_control_pid(s);
732
733         if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
734                 goto fail;
735
736         swap_set_state(s, SWAP_ACTIVATING);
737
738         return;
739
740 fail:
741         log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r));
742         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
743 }
744
745 static void swap_enter_deactivating(Swap *s) {
746         int r;
747
748         assert(s);
749
750         s->control_command_id = SWAP_EXEC_DEACTIVATE;
751         s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
752
753         if ((r = exec_command_set(
754                              s->control_command,
755                              "/sbin/swapoff",
756                              s->what,
757                              NULL)) < 0)
758                 goto fail;
759
760         swap_unwatch_control_pid(s);
761
762         if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0)
763                 goto fail;
764
765         swap_set_state(s, SWAP_DEACTIVATING);
766
767         return;
768
769 fail:
770         log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r));
771         swap_enter_active(s, SWAP_FAILURE_RESOURCES);
772 }
773
774 static int swap_start(Unit *u) {
775         Swap *s = SWAP(u);
776
777         assert(s);
778
779         /* We cannot fulfill this request right now, try again later
780          * please! */
781
782         if (s->state == SWAP_DEACTIVATING ||
783             s->state == SWAP_DEACTIVATING_SIGTERM ||
784             s->state == SWAP_DEACTIVATING_SIGKILL ||
785             s->state == SWAP_ACTIVATING_SIGTERM ||
786             s->state == SWAP_ACTIVATING_SIGKILL)
787                 return -EAGAIN;
788
789         if (s->state == SWAP_ACTIVATING)
790                 return 0;
791
792         assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
793
794         s->result = SWAP_SUCCESS;
795         swap_enter_activating(s);
796         return 0;
797 }
798
799 static int swap_stop(Unit *u) {
800         Swap *s = SWAP(u);
801
802         assert(s);
803
804         if (s->state == SWAP_DEACTIVATING ||
805             s->state == SWAP_DEACTIVATING_SIGTERM ||
806             s->state == SWAP_DEACTIVATING_SIGKILL ||
807             s->state == SWAP_ACTIVATING_SIGTERM ||
808             s->state == SWAP_ACTIVATING_SIGKILL)
809                 return 0;
810
811         assert(s->state == SWAP_ACTIVATING ||
812                s->state == SWAP_ACTIVE);
813
814         swap_enter_deactivating(s);
815         return 0;
816 }
817
818 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
819         Swap *s = SWAP(u);
820
821         assert(s);
822         assert(f);
823         assert(fds);
824
825         unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
826         unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
827
828         if (s->control_pid > 0)
829                 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
830
831         if (s->control_command_id >= 0)
832                 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
833
834         return 0;
835 }
836
837 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
838         Swap *s = SWAP(u);
839
840         assert(s);
841         assert(fds);
842
843         if (streq(key, "state")) {
844                 SwapState state;
845
846                 if ((state = swap_state_from_string(value)) < 0)
847                         log_debug("Failed to parse state value %s", value);
848                 else
849                         s->deserialized_state = state;
850         } else if (streq(key, "result")) {
851                 SwapResult f;
852
853                 f = swap_result_from_string(value);
854                 if (f < 0)
855                         log_debug("Failed to parse result value %s", value);
856                 else if (f != SWAP_SUCCESS)
857                         s->result = f;
858         } else if (streq(key, "control-pid")) {
859                 pid_t pid;
860
861                 if (parse_pid(value, &pid) < 0)
862                         log_debug("Failed to parse control-pid value %s", value);
863                 else
864                         s->control_pid = pid;
865
866         } else if (streq(key, "control-command")) {
867                 SwapExecCommand id;
868
869                 if ((id = swap_exec_command_from_string(value)) < 0)
870                         log_debug("Failed to parse exec-command value %s", value);
871                 else {
872                         s->control_command_id = id;
873                         s->control_command = s->exec_command + id;
874                 }
875
876         } else
877                 log_debug("Unknown serialization key '%s'", key);
878
879         return 0;
880 }
881
882 static UnitActiveState swap_active_state(Unit *u) {
883         assert(u);
884
885         return state_translation_table[SWAP(u)->state];
886 }
887
888 static const char *swap_sub_state_to_string(Unit *u) {
889         assert(u);
890
891         return swap_state_to_string(SWAP(u)->state);
892 }
893
894 static bool swap_check_gc(Unit *u) {
895         Swap *s = SWAP(u);
896
897         assert(s);
898
899         return s->from_proc_swaps;
900 }
901
902 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
903         Swap *s = SWAP(u);
904         SwapResult f;
905
906         assert(s);
907         assert(pid >= 0);
908
909         if (pid != s->control_pid)
910                 return;
911
912         s->control_pid = 0;
913
914         if (is_clean_exit(code, status))
915                 f = SWAP_SUCCESS;
916         else if (code == CLD_EXITED)
917                 f = SWAP_FAILURE_EXIT_CODE;
918         else if (code == CLD_KILLED)
919                 f = SWAP_FAILURE_SIGNAL;
920         else if (code == CLD_DUMPED)
921                 f = SWAP_FAILURE_CORE_DUMP;
922         else
923                 assert_not_reached("Unknown code");
924
925         if (f != SWAP_SUCCESS)
926                 s->result = f;
927
928         if (s->control_command) {
929                 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
930
931                 s->control_command = NULL;
932                 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
933         }
934
935         log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
936                  "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
937
938         switch (s->state) {
939
940         case SWAP_ACTIVATING:
941         case SWAP_ACTIVATING_SIGTERM:
942         case SWAP_ACTIVATING_SIGKILL:
943
944                 if (f == SWAP_SUCCESS)
945                         swap_enter_active(s, f);
946                 else
947                         swap_enter_dead(s, f);
948                 break;
949
950         case SWAP_DEACTIVATING:
951         case SWAP_DEACTIVATING_SIGKILL:
952         case SWAP_DEACTIVATING_SIGTERM:
953
954                 if (f == SWAP_SUCCESS)
955                         swap_enter_dead(s, f);
956                 else
957                         swap_enter_dead(s, f);
958                 break;
959
960         default:
961                 assert_not_reached("Uh, control process died at wrong time.");
962         }
963
964         /* Notify clients about changed exit status */
965         unit_add_to_dbus_queue(u);
966
967         /* Request a reload of /proc/swaps, so that following units
968          * can follow our state change */
969         u->manager->request_reload = true;
970 }
971
972 static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
973         Swap *s = SWAP(u);
974
975         assert(s);
976         assert(elapsed == 1);
977         assert(w == &s->timer_watch);
978
979         switch (s->state) {
980
981         case SWAP_ACTIVATING:
982                 log_warning("%s activation timed out. Stopping.", u->id);
983                 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
984                 break;
985
986         case SWAP_DEACTIVATING:
987                 log_warning("%s deactivation timed out. Stopping.", u->id);
988                 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
989                 break;
990
991         case SWAP_ACTIVATING_SIGTERM:
992                 if (s->exec_context.send_sigkill) {
993                         log_warning("%s activation timed out. Killing.", u->id);
994                         swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
995                 } else {
996                         log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id);
997                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
998                 }
999                 break;
1000
1001         case SWAP_DEACTIVATING_SIGTERM:
1002                 if (s->exec_context.send_sigkill) {
1003                         log_warning("%s deactivation timed out. Killing.", u->id);
1004                         swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1005                 } else {
1006                         log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id);
1007                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1008                 }
1009                 break;
1010
1011         case SWAP_ACTIVATING_SIGKILL:
1012         case SWAP_DEACTIVATING_SIGKILL:
1013                 log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id);
1014                 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1015                 break;
1016
1017         default:
1018                 assert_not_reached("Timeout at wrong time.");
1019         }
1020 }
1021
1022 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1023         unsigned i;
1024         int r = 0;
1025
1026         assert(m);
1027
1028         rewind(m->proc_swaps);
1029
1030         (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1031
1032         for (i = 1;; i++) {
1033                 char *dev = NULL, *d;
1034                 int prio = 0, k;
1035
1036                 if ((k = fscanf(m->proc_swaps,
1037                                 "%ms "  /* device/file */
1038                                 "%*s "  /* type of swap */
1039                                 "%*s "  /* swap size */
1040                                 "%*s "  /* used */
1041                                 "%i\n", /* priority */
1042                                 &dev, &prio)) != 2) {
1043
1044                         if (k == EOF)
1045                                 break;
1046
1047                         log_warning("Failed to parse /proc/swaps:%u.", i);
1048                         free(dev);
1049                         continue;
1050                 }
1051
1052                 d = cunescape(dev);
1053                 free(dev);
1054
1055                 if (!d)
1056                         return -ENOMEM;
1057
1058                 k = swap_process_new_swap(m, d, prio, set_flags);
1059                 free(d);
1060
1061                 if (k < 0)
1062                         r = k;
1063         }
1064
1065         return r;
1066 }
1067
1068 int swap_dispatch_reload(Manager *m) {
1069         /* This function should go as soon as the kernel properly notifies us */
1070
1071         if (_likely_(!m->request_reload))
1072                 return 0;
1073
1074         m->request_reload = false;
1075
1076         return swap_fd_event(m, EPOLLPRI);
1077 }
1078
1079 int swap_fd_event(Manager *m, int events) {
1080         Unit *u;
1081         int r;
1082
1083         assert(m);
1084         assert(events & EPOLLPRI);
1085
1086         if ((r = swap_load_proc_swaps(m, true)) < 0) {
1087                 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1088
1089                 /* Reset flags, just in case, for late calls */
1090                 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1091                         Swap *swap = SWAP(u);
1092
1093                         swap->is_active = swap->just_activated = false;
1094                 }
1095
1096                 return 0;
1097         }
1098
1099         manager_dispatch_load_queue(m);
1100
1101         LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1102                 Swap *swap = SWAP(u);
1103
1104                 if (!swap->is_active) {
1105                         /* This has just been deactivated */
1106
1107                         swap->from_proc_swaps = false;
1108                         swap_unset_proc_swaps(swap);
1109
1110                         switch (swap->state) {
1111
1112                         case SWAP_ACTIVE:
1113                                 swap_enter_dead(swap, SWAP_SUCCESS);
1114                                 break;
1115
1116                         default:
1117                                 swap_set_state(swap, swap->state);
1118                                 break;
1119                         }
1120
1121                 } else if (swap->just_activated) {
1122
1123                         /* New swap entry */
1124
1125                         switch (swap->state) {
1126
1127                         case SWAP_DEAD:
1128                         case SWAP_FAILED:
1129                                 swap_enter_active(swap, SWAP_SUCCESS);
1130                                 break;
1131
1132                         default:
1133                                 /* Nothing really changed, but let's
1134                                  * issue an notification call
1135                                  * nonetheless, in case somebody is
1136                                  * waiting for this. */
1137                                 swap_set_state(swap, swap->state);
1138                                 break;
1139                         }
1140                 }
1141
1142                 /* Reset the flags for later calls */
1143                 swap->is_active = swap->just_activated = false;
1144         }
1145
1146         return 1;
1147 }
1148
1149 static Unit *swap_following(Unit *u) {
1150         Swap *s = SWAP(u);
1151         Swap *other, *first = NULL;
1152
1153         assert(s);
1154
1155         if (streq_ptr(s->what, s->parameters_proc_swaps.what))
1156                 return NULL;
1157
1158         /* Make everybody follow the unit that's named after the swap
1159          * device in the kernel */
1160
1161         LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1162                 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1163                         return UNIT(other);
1164
1165         LIST_FOREACH_BEFORE(same_proc_swaps, other, s) {
1166                 if (streq_ptr(other->what, other->parameters_proc_swaps.what))
1167                         return UNIT(other);
1168
1169                 first = other;
1170         }
1171
1172         return UNIT(first);
1173 }
1174
1175 static int swap_following_set(Unit *u, Set **_set) {
1176         Swap *s = SWAP(u);
1177         Swap *other;
1178         Set *set;
1179         int r;
1180
1181         assert(s);
1182         assert(_set);
1183
1184         if (LIST_JUST_US(same_proc_swaps, s)) {
1185                 *_set = NULL;
1186                 return 0;
1187         }
1188
1189         if (!(set = set_new(NULL, NULL)))
1190                 return -ENOMEM;
1191
1192         LIST_FOREACH_AFTER(same_proc_swaps, other, s)
1193                 if ((r = set_put(set, other)) < 0)
1194                         goto fail;
1195
1196         LIST_FOREACH_BEFORE(same_proc_swaps, other, s)
1197                 if ((r = set_put(set, other)) < 0)
1198                         goto fail;
1199
1200         *_set = set;
1201         return 1;
1202
1203 fail:
1204         set_free(set);
1205         return r;
1206 }
1207
1208 static void swap_shutdown(Manager *m) {
1209         assert(m);
1210
1211         if (m->proc_swaps) {
1212                 fclose(m->proc_swaps);
1213                 m->proc_swaps = NULL;
1214         }
1215
1216         hashmap_free(m->swaps_by_proc_swaps);
1217         m->swaps_by_proc_swaps = NULL;
1218 }
1219
1220 static int swap_enumerate(Manager *m) {
1221         int r;
1222         struct epoll_event ev;
1223         assert(m);
1224
1225         if (!m->proc_swaps) {
1226                 if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
1227                         return (errno == ENOENT) ? 0 : -errno;
1228
1229                 m->swap_watch.type = WATCH_SWAP;
1230                 m->swap_watch.fd = fileno(m->proc_swaps);
1231
1232                 zero(ev);
1233                 ev.events = EPOLLPRI;
1234                 ev.data.ptr = &m->swap_watch;
1235
1236                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
1237                         return -errno;
1238         }
1239
1240         if ((r = swap_load_proc_swaps(m, false)) < 0)
1241                 swap_shutdown(m);
1242
1243         return r;
1244 }
1245
1246 static void swap_reset_failed(Unit *u) {
1247         Swap *s = SWAP(u);
1248
1249         assert(s);
1250
1251         if (s->state == SWAP_FAILED)
1252                 swap_set_state(s, SWAP_DEAD);
1253
1254         s->result = SWAP_SUCCESS;
1255 }
1256
1257 static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
1258         Swap *s = SWAP(u);
1259         int r = 0;
1260         Set *pid_set = NULL;
1261
1262         assert(s);
1263
1264         if (who == KILL_MAIN) {
1265                 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
1266                 return -ESRCH;
1267         }
1268
1269         if (s->control_pid <= 0 && who == KILL_CONTROL) {
1270                 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1271                 return -ESRCH;
1272         }
1273
1274         if (who == KILL_CONTROL || who == KILL_ALL)
1275                 if (s->control_pid > 0)
1276                         if (kill(s->control_pid, signo) < 0)
1277                                 r = -errno;
1278
1279         if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) {
1280                 int q;
1281
1282                 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func)))
1283                         return -ENOMEM;
1284
1285                 /* Exclude the control pid from being killed via the cgroup */
1286                 if (s->control_pid > 0)
1287                         if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) {
1288                                 r = q;
1289                                 goto finish;
1290                         }
1291
1292                 q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
1293                 if (q < 0)
1294                         if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1295                                 r = q;
1296         }
1297
1298 finish:
1299         if (pid_set)
1300                 set_free(pid_set);
1301
1302         return r;
1303 }
1304
1305 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1306         [SWAP_DEAD] = "dead",
1307         [SWAP_ACTIVATING] = "activating",
1308         [SWAP_ACTIVE] = "active",
1309         [SWAP_DEACTIVATING] = "deactivating",
1310         [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1311         [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1312         [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1313         [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1314         [SWAP_FAILED] = "failed"
1315 };
1316
1317 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1318
1319 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1320         [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1321         [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1322 };
1323
1324 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1325
1326 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1327         [SWAP_SUCCESS] = "success",
1328         [SWAP_FAILURE_RESOURCES] = "resources",
1329         [SWAP_FAILURE_TIMEOUT] = "timeout",
1330         [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1331         [SWAP_FAILURE_SIGNAL] = "signal",
1332         [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1333 };
1334
1335 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1336
1337 const UnitVTable swap_vtable = {
1338         .suffix = ".swap",
1339         .object_size = sizeof(Swap),
1340         .sections =
1341                 "Unit\0"
1342                 "Swap\0"
1343                 "Install\0",
1344
1345         .no_alias = true,
1346         .no_instances = true,
1347
1348         .init = swap_init,
1349         .load = swap_load,
1350         .done = swap_done,
1351
1352         .coldplug = swap_coldplug,
1353
1354         .dump = swap_dump,
1355
1356         .start = swap_start,
1357         .stop = swap_stop,
1358
1359         .kill = swap_kill,
1360
1361         .serialize = swap_serialize,
1362         .deserialize_item = swap_deserialize_item,
1363
1364         .active_state = swap_active_state,
1365         .sub_state_to_string = swap_sub_state_to_string,
1366
1367         .check_gc = swap_check_gc,
1368
1369         .sigchld_event = swap_sigchld_event,
1370         .timer_event = swap_timer_event,
1371
1372         .reset_failed = swap_reset_failed,
1373
1374         .bus_interface = "org.freedesktop.systemd1.Swap",
1375         .bus_message_handler = bus_swap_message_handler,
1376         .bus_invalidating_properties =  bus_swap_invalidating_properties,
1377
1378         .following = swap_following,
1379         .following_set = swap_following_set,
1380
1381         .enumerate = swap_enumerate,
1382         .shutdown = swap_shutdown,
1383
1384         .status_message_formats = {
1385                 .starting_stopping = {
1386                         [0] = "Activating swap %s...",
1387                         [1] = "Deactivating swap %s...",
1388                 },
1389                 .finished_start_job = {
1390                         [JOB_DONE]       = "Activated swap %s.",
1391                         [JOB_FAILED]     = "Failed to activate swap %s.",
1392                         [JOB_DEPENDENCY] = "Dependency failed for %s.",
1393                         [JOB_TIMEOUT]    = "Timed out activating swap %s.",
1394                 },
1395                 .finished_stop_job = {
1396                         [JOB_DONE]       = "Deactivated swap %s.",
1397                         [JOB_FAILED]     = "Failed deactivating swap %s.",
1398                         [JOB_TIMEOUT]    = "Timed out deactivating swap %s.",
1399                 },
1400         },
1401 };