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