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