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