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