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