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