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