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