chiark / gitweb /
bus: include connection name in credentials structure
[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                        0,
649                        NULL,
650                        s->exec_runtime,
651                        &pid);
652         if (r < 0)
653                 goto fail;
654
655         r = unit_watch_pid(UNIT(s), pid);
656         if (r < 0)
657                 /* FIXME: we need to do something here */
658                 goto fail;
659
660         *_pid = pid;
661
662         return 0;
663
664 fail:
665         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
666
667         return r;
668 }
669
670 static void swap_enter_dead(Swap *s, SwapResult f) {
671         assert(s);
672
673         if (f != SWAP_SUCCESS)
674                 s->result = f;
675
676         exec_runtime_destroy(s->exec_runtime);
677         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
678
679         swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
680 }
681
682 static void swap_enter_active(Swap *s, SwapResult f) {
683         assert(s);
684
685         if (f != SWAP_SUCCESS)
686                 s->result = f;
687
688         swap_set_state(s, SWAP_ACTIVE);
689 }
690
691 static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
692         int r;
693
694         assert(s);
695
696         if (f != SWAP_SUCCESS)
697                 s->result = f;
698
699         r = unit_kill_context(
700                         UNIT(s),
701                         &s->kill_context,
702                         state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM,
703                         -1,
704                         s->control_pid,
705                         false);
706         if (r < 0)
707                 goto fail;
708
709         if (r > 0) {
710                 r = swap_arm_timer(s);
711                 if (r < 0)
712                         goto fail;
713
714                 swap_set_state(s, state);
715         } else
716                 swap_enter_dead(s, SWAP_SUCCESS);
717
718         return;
719
720 fail:
721         log_warning_unit(UNIT(s)->id,
722                          "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
723
724         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
725 }
726
727 static void swap_enter_activating(Swap *s) {
728         int r, priority;
729
730         assert(s);
731
732         s->control_command_id = SWAP_EXEC_ACTIVATE;
733         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
734
735         if (s->from_fragment)
736                 priority = s->parameters_fragment.priority;
737         else
738                 priority = -1;
739
740         if (priority >= 0) {
741                 char p[DECIMAL_STR_MAX(int)];
742
743                 sprintf(p, "%i", priority);
744
745                 r = exec_command_set(
746                                 s->control_command,
747                                 "/sbin/swapon",
748                                 "-p",
749                                 p,
750                                 s->what,
751                                 NULL);
752         } else
753                 r = exec_command_set(
754                                 s->control_command,
755                                 "/sbin/swapon",
756                                 s->what,
757                                 NULL);
758
759         if (r < 0)
760                 goto fail;
761
762         swap_unwatch_control_pid(s);
763
764         r = swap_spawn(s, s->control_command, &s->control_pid);
765         if (r < 0)
766                 goto fail;
767
768         swap_set_state(s, SWAP_ACTIVATING);
769
770         return;
771
772 fail:
773         log_warning_unit(UNIT(s)->id,
774                          "%s failed to run 'swapon' task: %s",
775                          UNIT(s)->id, strerror(-r));
776         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
777 }
778
779 static void swap_enter_deactivating(Swap *s) {
780         int r;
781
782         assert(s);
783
784         s->control_command_id = SWAP_EXEC_DEACTIVATE;
785         s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE;
786
787         r = exec_command_set(s->control_command,
788                              "/sbin/swapoff",
789                              s->what,
790                              NULL);
791         if (r < 0)
792                 goto fail;
793
794         swap_unwatch_control_pid(s);
795
796         r = swap_spawn(s, s->control_command, &s->control_pid);
797         if (r < 0)
798                 goto fail;
799
800         swap_set_state(s, SWAP_DEACTIVATING);
801
802         return;
803
804 fail:
805         log_warning_unit(UNIT(s)->id,
806                          "%s failed to run 'swapoff' task: %s",
807                          UNIT(s)->id, strerror(-r));
808         swap_enter_active(s, SWAP_FAILURE_RESOURCES);
809 }
810
811 static int swap_start(Unit *u) {
812         Swap *s = SWAP(u);
813
814         assert(s);
815
816         /* We cannot fulfill this request right now, try again later
817          * please! */
818
819         if (s->state == SWAP_DEACTIVATING ||
820             s->state == SWAP_DEACTIVATING_SIGTERM ||
821             s->state == SWAP_DEACTIVATING_SIGKILL ||
822             s->state == SWAP_ACTIVATING_SIGTERM ||
823             s->state == SWAP_ACTIVATING_SIGKILL)
824                 return -EAGAIN;
825
826         if (s->state == SWAP_ACTIVATING)
827                 return 0;
828
829         assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
830
831         if (detect_container(NULL) > 0)
832                 return -EPERM;
833
834         s->result = SWAP_SUCCESS;
835         swap_enter_activating(s);
836         return 0;
837 }
838
839 static int swap_stop(Unit *u) {
840         Swap *s = SWAP(u);
841
842         assert(s);
843
844         if (s->state == SWAP_DEACTIVATING ||
845             s->state == SWAP_DEACTIVATING_SIGTERM ||
846             s->state == SWAP_DEACTIVATING_SIGKILL ||
847             s->state == SWAP_ACTIVATING_SIGTERM ||
848             s->state == SWAP_ACTIVATING_SIGKILL)
849                 return 0;
850
851         assert(s->state == SWAP_ACTIVATING ||
852                s->state == SWAP_ACTIVATING_DONE ||
853                s->state == SWAP_ACTIVE);
854
855         if (detect_container(NULL) > 0)
856                 return -EPERM;
857
858         swap_enter_deactivating(s);
859         return 0;
860 }
861
862 static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
863         Swap *s = SWAP(u);
864
865         assert(s);
866         assert(f);
867         assert(fds);
868
869         unit_serialize_item(u, f, "state", swap_state_to_string(s->state));
870         unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
871
872         if (s->control_pid > 0)
873                 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
874
875         if (s->control_command_id >= 0)
876                 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
877
878         return 0;
879 }
880
881 static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
882         Swap *s = SWAP(u);
883
884         assert(s);
885         assert(fds);
886
887         if (streq(key, "state")) {
888                 SwapState state;
889
890                 state = swap_state_from_string(value);
891                 if (state < 0)
892                         log_debug_unit(u->id, "Failed to parse state value %s", value);
893                 else
894                         s->deserialized_state = state;
895         } else if (streq(key, "result")) {
896                 SwapResult f;
897
898                 f = swap_result_from_string(value);
899                 if (f < 0)
900                         log_debug_unit(u->id, "Failed to parse result value %s", value);
901                 else if (f != SWAP_SUCCESS)
902                         s->result = f;
903         } else if (streq(key, "control-pid")) {
904                 pid_t pid;
905
906                 if (parse_pid(value, &pid) < 0)
907                         log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
908                 else
909                         s->control_pid = pid;
910
911         } else if (streq(key, "control-command")) {
912                 SwapExecCommand id;
913
914                 id = swap_exec_command_from_string(value);
915                 if (id < 0)
916                         log_debug_unit(u->id, "Failed to parse exec-command value %s", value);
917                 else {
918                         s->control_command_id = id;
919                         s->control_command = s->exec_command + id;
920                 }
921         } else
922                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
923
924         return 0;
925 }
926
927 _pure_ static UnitActiveState swap_active_state(Unit *u) {
928         assert(u);
929
930         return state_translation_table[SWAP(u)->state];
931 }
932
933 _pure_ static const char *swap_sub_state_to_string(Unit *u) {
934         assert(u);
935
936         return swap_state_to_string(SWAP(u)->state);
937 }
938
939 _pure_ static bool swap_check_gc(Unit *u) {
940         Swap *s = SWAP(u);
941
942         assert(s);
943
944         return s->from_proc_swaps;
945 }
946
947 static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
948         Swap *s = SWAP(u);
949         SwapResult f;
950
951         assert(s);
952         assert(pid >= 0);
953
954         if (pid != s->control_pid)
955                 return;
956
957         s->control_pid = 0;
958
959         if (is_clean_exit(code, status, NULL))
960                 f = SWAP_SUCCESS;
961         else if (code == CLD_EXITED)
962                 f = SWAP_FAILURE_EXIT_CODE;
963         else if (code == CLD_KILLED)
964                 f = SWAP_FAILURE_SIGNAL;
965         else if (code == CLD_DUMPED)
966                 f = SWAP_FAILURE_CORE_DUMP;
967         else
968                 assert_not_reached("Unknown code");
969
970         if (f != SWAP_SUCCESS)
971                 s->result = f;
972
973         if (s->control_command) {
974                 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
975
976                 s->control_command = NULL;
977                 s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
978         }
979
980         log_full_unit(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
981                       u->id,
982                       "%s swap process exited, code=%s status=%i",
983                       u->id, sigchld_code_to_string(code), status);
984
985         switch (s->state) {
986
987         case SWAP_ACTIVATING:
988         case SWAP_ACTIVATING_DONE:
989         case SWAP_ACTIVATING_SIGTERM:
990         case SWAP_ACTIVATING_SIGKILL:
991
992                 if (f == SWAP_SUCCESS)
993                         swap_enter_active(s, f);
994                 else
995                         swap_enter_dead(s, f);
996                 break;
997
998         case SWAP_DEACTIVATING:
999         case SWAP_DEACTIVATING_SIGKILL:
1000         case SWAP_DEACTIVATING_SIGTERM:
1001
1002                 swap_enter_dead(s, f);
1003                 break;
1004
1005         default:
1006                 assert_not_reached("Uh, control process died at wrong time.");
1007         }
1008
1009         /* Notify clients about changed exit status */
1010         unit_add_to_dbus_queue(u);
1011 }
1012
1013 static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1014         Swap *s = SWAP(userdata);
1015
1016         assert(s);
1017         assert(s->timer_event_source == source);
1018
1019         switch (s->state) {
1020
1021         case SWAP_ACTIVATING:
1022         case SWAP_ACTIVATING_DONE:
1023                 log_warning_unit(UNIT(s)->id, "%s activation timed out. Stopping.", UNIT(s)->id);
1024                 swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1025                 break;
1026
1027         case SWAP_DEACTIVATING:
1028                 log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Stopping.", UNIT(s)->id);
1029                 swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT);
1030                 break;
1031
1032         case SWAP_ACTIVATING_SIGTERM:
1033                 if (s->kill_context.send_sigkill) {
1034                         log_warning_unit(UNIT(s)->id, "%s activation timed out. Killing.", UNIT(s)->id);
1035                         swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1036                 } else {
1037                         log_warning_unit(UNIT(s)->id, "%s activation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1038                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1039                 }
1040                 break;
1041
1042         case SWAP_DEACTIVATING_SIGTERM:
1043                 if (s->kill_context.send_sigkill) {
1044                         log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Killing.", UNIT(s)->id);
1045                         swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT);
1046                 } else {
1047                         log_warning_unit(UNIT(s)->id, "%s deactivation timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
1048                         swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1049                 }
1050                 break;
1051
1052         case SWAP_ACTIVATING_SIGKILL:
1053         case SWAP_DEACTIVATING_SIGKILL:
1054                 log_warning_unit(UNIT(s)->id, "%s swap process still around after SIGKILL. Ignoring.", UNIT(s)->id);
1055                 swap_enter_dead(s, SWAP_FAILURE_TIMEOUT);
1056                 break;
1057
1058         default:
1059                 assert_not_reached("Timeout at wrong time.");
1060         }
1061
1062         return 0;
1063 }
1064
1065 static int swap_load_proc_swaps(Manager *m, bool set_flags) {
1066         unsigned i;
1067         int r = 0;
1068
1069         assert(m);
1070
1071         rewind(m->proc_swaps);
1072
1073         (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n");
1074
1075         for (i = 1;; i++) {
1076                 _cleanup_free_ char *dev = NULL, *d = NULL;
1077                 int prio = 0, k;
1078
1079                 k = fscanf(m->proc_swaps,
1080                            "%ms "  /* device/file */
1081                            "%*s "  /* type of swap */
1082                            "%*s "  /* swap size */
1083                            "%*s "  /* used */
1084                            "%i\n", /* priority */
1085                            &dev, &prio);
1086                 if (k != 2) {
1087                         if (k == EOF)
1088                                 break;
1089
1090                         log_warning("Failed to parse /proc/swaps:%u", i);
1091                         continue;
1092                 }
1093
1094                 d = cunescape(dev);
1095                 if (!d)
1096                         return -ENOMEM;
1097
1098                 k = swap_process_new_swap(m, d, prio, set_flags);
1099                 if (k < 0)
1100                         r = k;
1101         }
1102
1103         return r;
1104 }
1105
1106 static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1107         Manager *m = userdata;
1108         Unit *u;
1109         int r;
1110
1111         assert(m);
1112         assert(revents & EPOLLPRI);
1113
1114         r = swap_load_proc_swaps(m, true);
1115         if (r < 0) {
1116                 log_error("Failed to reread /proc/swaps: %s", strerror(-r));
1117
1118                 /* Reset flags, just in case, for late calls */
1119                 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1120                         Swap *swap = SWAP(u);
1121
1122                         swap->is_active = swap->just_activated = false;
1123                 }
1124
1125                 return 0;
1126         }
1127
1128         manager_dispatch_load_queue(m);
1129
1130         LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) {
1131                 Swap *swap = SWAP(u);
1132
1133                 if (!swap->is_active) {
1134                         /* This has just been deactivated */
1135
1136                         swap_unset_proc_swaps(swap);
1137
1138                         switch (swap->state) {
1139
1140                         case SWAP_ACTIVE:
1141                                 swap_enter_dead(swap, SWAP_SUCCESS);
1142                                 break;
1143
1144                         default:
1145                                 /* Fire again */
1146                                 swap_set_state(swap, swap->state);
1147                                 break;
1148                         }
1149
1150                 } else if (swap->just_activated) {
1151
1152                         /* New swap entry */
1153
1154                         switch (swap->state) {
1155
1156                         case SWAP_DEAD:
1157                         case SWAP_FAILED:
1158                                 swap_enter_active(swap, SWAP_SUCCESS);
1159                                 break;
1160
1161                         case SWAP_ACTIVATING:
1162                                 swap_set_state(swap, SWAP_ACTIVATING_DONE);
1163                                 break;
1164
1165                         default:
1166                                 /* Nothing really changed, but let's
1167                                  * issue an notification call
1168                                  * nonetheless, in case somebody is
1169                                  * waiting for this. */
1170                                 swap_set_state(swap, swap->state);
1171                                 break;
1172                         }
1173                 }
1174
1175                 /* Reset the flags for later calls */
1176                 swap->is_active = swap->just_activated = false;
1177         }
1178
1179         return 1;
1180 }
1181
1182 static Unit *swap_following(Unit *u) {
1183         Swap *s = SWAP(u);
1184         Swap *other, *first = NULL;
1185
1186         assert(s);
1187
1188         if (streq_ptr(s->what, s->devnode))
1189                 return NULL;
1190
1191         /* Make everybody follow the unit that's named after the swap
1192          * device in the kernel */
1193
1194         LIST_FOREACH_AFTER(same_devnode, other, s)
1195                 if (streq_ptr(other->what, other->devnode))
1196                         return UNIT(other);
1197
1198         LIST_FOREACH_BEFORE(same_devnode, other, s) {
1199                 if (streq_ptr(other->what, other->devnode))
1200                         return UNIT(other);
1201
1202                 first = other;
1203         }
1204
1205         return UNIT(first);
1206 }
1207
1208 static int swap_following_set(Unit *u, Set **_set) {
1209         Swap *s = SWAP(u), *other;
1210         Set *set;
1211         int r;
1212
1213         assert(s);
1214         assert(_set);
1215
1216         if (LIST_JUST_US(same_devnode, s)) {
1217                 *_set = NULL;
1218                 return 0;
1219         }
1220
1221         set = set_new(NULL, NULL);
1222         if (!set)
1223                 return -ENOMEM;
1224
1225         LIST_FOREACH_AFTER(same_devnode, other, s) {
1226                 r = set_put(set, other);
1227                 if (r < 0)
1228                         goto fail;
1229         }
1230
1231         LIST_FOREACH_BEFORE(same_devnode, other, s) {
1232                 r = set_put(set, other);
1233                 if (r < 0)
1234                         goto fail;
1235         }
1236
1237         *_set = set;
1238         return 1;
1239
1240 fail:
1241         set_free(set);
1242         return r;
1243 }
1244
1245 static void swap_shutdown(Manager *m) {
1246         assert(m);
1247
1248         m->swap_event_source = sd_event_source_unref(m->swap_event_source);
1249
1250         if (m->proc_swaps) {
1251                 fclose(m->proc_swaps);
1252                 m->proc_swaps = NULL;
1253         }
1254
1255         hashmap_free(m->swaps_by_devnode);
1256         m->swaps_by_devnode = NULL;
1257 }
1258
1259 static int swap_enumerate(Manager *m) {
1260         int r;
1261
1262         assert(m);
1263
1264         if (!m->proc_swaps) {
1265                 m->proc_swaps = fopen("/proc/swaps", "re");
1266                 if (!m->proc_swaps)
1267                         return errno == ENOENT ? 0 : -errno;
1268
1269                 r = sd_event_add_io(m->event, fileno(m->proc_swaps), EPOLLPRI, swap_dispatch_io, m, &m->swap_event_source);
1270                 if (r < 0)
1271                         goto fail;
1272
1273                 /* Dispatch this before we dispatch SIGCHLD, so that
1274                  * we always get the events from /proc/swaps before
1275                  * the SIGCHLD of /sbin/swapon. */
1276                 r = sd_event_source_set_priority(m->swap_event_source, -10);
1277                 if (r < 0)
1278                         goto fail;
1279         }
1280
1281         r = swap_load_proc_swaps(m, false);
1282         if (r < 0)
1283                 goto fail;
1284
1285         return 0;
1286
1287 fail:
1288         swap_shutdown(m);
1289         return r;
1290 }
1291
1292 int swap_process_new_device(Manager *m, struct udev_device *dev) {
1293         struct udev_list_entry *item = NULL, *first = NULL;
1294         _cleanup_free_ char *e = NULL;
1295         const char *dn;
1296         Swap *s;
1297         int r = 0;
1298
1299         assert(m);
1300         assert(dev);
1301
1302         dn = udev_device_get_devnode(dev);
1303         if (!dn)
1304                 return 0;
1305
1306         e = unit_name_from_path(dn, ".swap");
1307         if (!e)
1308                 return -ENOMEM;
1309
1310         s = hashmap_get(m->units, e);
1311         if (s)
1312                 r = swap_set_devnode(s, dn);
1313
1314         first = udev_device_get_devlinks_list_entry(dev);
1315         udev_list_entry_foreach(item, first) {
1316                 _cleanup_free_ char *n = NULL;
1317
1318                 n = unit_name_from_path(udev_list_entry_get_name(item), ".swap");
1319                 if (!n)
1320                         return -ENOMEM;
1321
1322                 s = hashmap_get(m->units, n);
1323                 if (s) {
1324                         int q;
1325
1326                         q = swap_set_devnode(s, dn);
1327                         if (q < 0)
1328                                 r = q;
1329                 }
1330         }
1331
1332         return r;
1333 }
1334
1335 int swap_process_removed_device(Manager *m, struct udev_device *dev) {
1336         const char *dn;
1337         int r = 0;
1338         Swap *s;
1339
1340         dn = udev_device_get_devnode(dev);
1341         if (!dn)
1342                 return 0;
1343
1344         while ((s = hashmap_get(m->swaps_by_devnode, dn))) {
1345                 int q;
1346
1347                 q = swap_set_devnode(s, NULL);
1348                 if (q < 0)
1349                         r = q;
1350         }
1351
1352         return r;
1353 }
1354
1355 static void swap_reset_failed(Unit *u) {
1356         Swap *s = SWAP(u);
1357
1358         assert(s);
1359
1360         if (s->state == SWAP_FAILED)
1361                 swap_set_state(s, SWAP_DEAD);
1362
1363         s->result = SWAP_SUCCESS;
1364 }
1365
1366 static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1367         return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
1368 }
1369
1370 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
1371         [SWAP_DEAD] = "dead",
1372         [SWAP_ACTIVATING] = "activating",
1373         [SWAP_ACTIVATING_DONE] = "activating-done",
1374         [SWAP_ACTIVE] = "active",
1375         [SWAP_DEACTIVATING] = "deactivating",
1376         [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm",
1377         [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill",
1378         [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm",
1379         [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill",
1380         [SWAP_FAILED] = "failed"
1381 };
1382
1383 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
1384
1385 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
1386         [SWAP_EXEC_ACTIVATE] = "ExecActivate",
1387         [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
1388 };
1389
1390 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
1391
1392 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
1393         [SWAP_SUCCESS] = "success",
1394         [SWAP_FAILURE_RESOURCES] = "resources",
1395         [SWAP_FAILURE_TIMEOUT] = "timeout",
1396         [SWAP_FAILURE_EXIT_CODE] = "exit-code",
1397         [SWAP_FAILURE_SIGNAL] = "signal",
1398         [SWAP_FAILURE_CORE_DUMP] = "core-dump"
1399 };
1400
1401 DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult);
1402
1403 const UnitVTable swap_vtable = {
1404         .object_size = sizeof(Swap),
1405         .exec_context_offset = offsetof(Swap, exec_context),
1406         .cgroup_context_offset = offsetof(Swap, cgroup_context),
1407         .kill_context_offset = offsetof(Swap, kill_context),
1408         .exec_runtime_offset = offsetof(Swap, exec_runtime),
1409
1410         .sections =
1411                 "Unit\0"
1412                 "Swap\0"
1413                 "Install\0",
1414         .private_section = "Swap",
1415
1416         .no_alias = true,
1417         .no_instances = true,
1418
1419         .init = swap_init,
1420         .load = swap_load,
1421         .done = swap_done,
1422
1423         .coldplug = swap_coldplug,
1424
1425         .dump = swap_dump,
1426
1427         .start = swap_start,
1428         .stop = swap_stop,
1429
1430         .kill = swap_kill,
1431
1432         .serialize = swap_serialize,
1433         .deserialize_item = swap_deserialize_item,
1434
1435         .active_state = swap_active_state,
1436         .sub_state_to_string = swap_sub_state_to_string,
1437
1438         .check_gc = swap_check_gc,
1439
1440         .sigchld_event = swap_sigchld_event,
1441
1442         .reset_failed = swap_reset_failed,
1443
1444         .bus_interface = "org.freedesktop.systemd1.Swap",
1445         .bus_vtable = bus_swap_vtable,
1446         .bus_set_property = bus_swap_set_property,
1447         .bus_commit_properties = bus_swap_commit_properties,
1448
1449         .following = swap_following,
1450         .following_set = swap_following_set,
1451
1452         .enumerate = swap_enumerate,
1453         .shutdown = swap_shutdown,
1454
1455         .status_message_formats = {
1456                 .starting_stopping = {
1457                         [0] = "Activating swap %s...",
1458                         [1] = "Deactivating swap %s...",
1459                 },
1460                 .finished_start_job = {
1461                         [JOB_DONE]       = "Activated swap %s.",
1462                         [JOB_FAILED]     = "Failed to activate swap %s.",
1463                         [JOB_DEPENDENCY] = "Dependency failed for %s.",
1464                         [JOB_TIMEOUT]    = "Timed out activating swap %s.",
1465                 },
1466                 .finished_stop_job = {
1467                         [JOB_DONE]       = "Deactivated swap %s.",
1468                         [JOB_FAILED]     = "Failed deactivating swap %s.",
1469                         [JOB_TIMEOUT]    = "Timed out deactivating swap %s.",
1470                 },
1471         },
1472 };