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