chiark / gitweb /
Make sure that keys are properly removed from hashmap
[elogind.git] / src / core / automount.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 <sys/mount.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/epoll.h>
28 #include <sys/stat.h>
29 #include <linux/auto_fs4.h>
30 #include <linux/auto_dev-ioctl.h>
31
32 #include "unit.h"
33 #include "automount.h"
34 #include "mount.h"
35 #include "load-fragment.h"
36 #include "load-dropin.h"
37 #include "unit-name.h"
38 #include "special.h"
39 #include "label.h"
40 #include "mkdir.h"
41 #include "path-util.h"
42 #include "dbus-automount.h"
43 #include "bus-util.h"
44 #include "bus-error.h"
45
46 static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
47         [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
48         [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
49         [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
50         [AUTOMOUNT_FAILED] = UNIT_FAILED
51 };
52
53 static int open_dev_autofs(Manager *m);
54 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
55
56 static void automount_init(Unit *u) {
57         Automount *a = AUTOMOUNT(u);
58
59         assert(u);
60         assert(u->load_state == UNIT_STUB);
61
62         a->pipe_fd = -1;
63         a->directory_mode = 0755;
64         UNIT(a)->ignore_on_isolate = true;
65 }
66
67 static void repeat_unmount(const char *path) {
68         assert(path);
69
70         for (;;) {
71                 /* If there are multiple mounts on a mount point, this
72                  * removes them all */
73
74                 if (umount2(path, MNT_DETACH) >= 0)
75                         continue;
76
77                 if (errno != EINVAL)
78                         log_error("Failed to unmount: %m");
79
80                 break;
81         }
82 }
83
84 static void unmount_autofs(Automount *a) {
85         assert(a);
86
87         if (a->pipe_fd < 0)
88                 return;
89
90         automount_send_ready(a, -EHOSTDOWN);
91
92         a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
93         a->pipe_fd = safe_close(a->pipe_fd);
94
95         /* If we reload/reexecute things we keep the mount point
96          * around */
97         if (a->where &&
98             (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
99              UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
100                 repeat_unmount(a->where);
101 }
102
103 static void automount_done(Unit *u) {
104         Automount *a = AUTOMOUNT(u);
105
106         assert(a);
107
108         unmount_autofs(a);
109
110         free(a->where);
111         a->where = NULL;
112
113         set_free(a->tokens);
114         a->tokens = NULL;
115 }
116
117 static int automount_add_mount_links(Automount *a) {
118         _cleanup_free_ char *parent = NULL;
119         int r;
120
121         assert(a);
122
123         r = path_get_parent(a->where, &parent);
124         if (r < 0)
125                 return r;
126
127         return unit_require_mounts_for(UNIT(a), parent);
128 }
129
130 static int automount_add_default_dependencies(Automount *a) {
131         int r;
132
133         assert(a);
134
135         if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
136                 return 0;
137
138         r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
139         if (r < 0)
140                 return r;
141
142         return 0;
143 }
144
145 static int automount_verify(Automount *a) {
146         bool b;
147         char *e;
148         assert(a);
149
150         if (UNIT(a)->load_state != UNIT_LOADED)
151                 return 0;
152
153         if (path_equal(a->where, "/")) {
154                 log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
155                 return -EINVAL;
156         }
157
158         e = unit_name_from_path(a->where, ".automount");
159         if (!e)
160                 return -ENOMEM;
161
162         b = unit_has_name(UNIT(a), e);
163         free(e);
164
165         if (!b) {
166                 log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
167                 return -EINVAL;
168         }
169
170         return 0;
171 }
172
173 static int automount_load(Unit *u) {
174         Automount *a = AUTOMOUNT(u);
175         int r;
176
177         assert(u);
178         assert(u->load_state == UNIT_STUB);
179
180         /* Load a .automount file */
181         r = unit_load_fragment_and_dropin_optional(u);
182         if (r < 0)
183                 return r;
184
185         if (u->load_state == UNIT_LOADED) {
186                 Unit *x;
187
188                 if (!a->where) {
189                         a->where = unit_name_to_path(u->id);
190                         if (!a->where)
191                                 return -ENOMEM;
192                 }
193
194                 path_kill_slashes(a->where);
195
196                 r = unit_load_related_unit(u, ".mount", &x);
197                 if (r < 0)
198                         return r;
199
200                 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
201                 if (r < 0)
202                         return r;
203
204                 r = automount_add_mount_links(a);
205                 if (r < 0)
206                         return r;
207
208                 if (UNIT(a)->default_dependencies) {
209                         r = automount_add_default_dependencies(a);
210                         if (r < 0)
211                                 return r;
212                 }
213         }
214
215         return automount_verify(a);
216 }
217
218 static void automount_set_state(Automount *a, AutomountState state) {
219         AutomountState old_state;
220         assert(a);
221
222         old_state = a->state;
223         a->state = state;
224
225         if (state != AUTOMOUNT_WAITING &&
226             state != AUTOMOUNT_RUNNING)
227                 unmount_autofs(a);
228
229         if (state != old_state)
230                 log_debug_unit(UNIT(a)->id,
231                                "%s changed %s -> %s",
232                                UNIT(a)->id,
233                                automount_state_to_string(old_state),
234                                automount_state_to_string(state));
235
236         unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
237 }
238
239 static int automount_coldplug(Unit *u) {
240         Automount *a = AUTOMOUNT(u);
241         int r;
242
243         assert(a);
244         assert(a->state == AUTOMOUNT_DEAD);
245
246         if (a->deserialized_state != a->state) {
247
248                 r = open_dev_autofs(u->manager);
249                 if (r < 0)
250                         return r;
251
252                 if (a->deserialized_state == AUTOMOUNT_WAITING ||
253                     a->deserialized_state == AUTOMOUNT_RUNNING) {
254
255                         assert(a->pipe_fd >= 0);
256
257                         r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
258                         if (r < 0)
259                                 return r;
260                 }
261
262                 automount_set_state(a, a->deserialized_state);
263         }
264
265         return 0;
266 }
267
268 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
269         Automount *a = AUTOMOUNT(u);
270
271         assert(a);
272
273         fprintf(f,
274                 "%sAutomount State: %s\n"
275                 "%sResult: %s\n"
276                 "%sWhere: %s\n"
277                 "%sDirectoryMode: %04o\n",
278                 prefix, automount_state_to_string(a->state),
279                 prefix, automount_result_to_string(a->result),
280                 prefix, a->where,
281                 prefix, a->directory_mode);
282 }
283
284 static void automount_enter_dead(Automount *a, AutomountResult f) {
285         assert(a);
286
287         if (f != AUTOMOUNT_SUCCESS)
288                 a->result = f;
289
290         automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
291 }
292
293 static int open_dev_autofs(Manager *m) {
294         struct autofs_dev_ioctl param;
295
296         assert(m);
297
298         if (m->dev_autofs_fd >= 0)
299                 return m->dev_autofs_fd;
300
301         label_fix("/dev/autofs", false, false);
302
303         m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
304         if (m->dev_autofs_fd < 0) {
305                 log_error("Failed to open /dev/autofs: %m");
306                 return -errno;
307         }
308
309         init_autofs_dev_ioctl(&param);
310         if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
311                 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
312                 return -errno;
313         }
314
315         log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
316
317         return m->dev_autofs_fd;
318 }
319
320 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
321         struct autofs_dev_ioctl *param;
322         size_t l;
323
324         assert(dev_autofs_fd >= 0);
325         assert(where);
326
327         l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
328         param = alloca(l);
329
330         init_autofs_dev_ioctl(param);
331         param->size = l;
332         param->ioctlfd = -1;
333         param->openmount.devid = devid;
334         strcpy(param->path, where);
335
336         if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
337                 return -errno;
338
339         if (param->ioctlfd < 0)
340                 return -EIO;
341
342         fd_cloexec(param->ioctlfd, true);
343         return param->ioctlfd;
344 }
345
346 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
347         uint32_t major, minor;
348         struct autofs_dev_ioctl param;
349
350         assert(dev_autofs_fd >= 0);
351         assert(ioctl_fd >= 0);
352
353         init_autofs_dev_ioctl(&param);
354         param.ioctlfd = ioctl_fd;
355
356         if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
357                 return -errno;
358
359         major = param.protover.version;
360
361         init_autofs_dev_ioctl(&param);
362         param.ioctlfd = ioctl_fd;
363
364         if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
365                 return -errno;
366
367         minor = param.protosubver.sub_version;
368
369         log_debug("Autofs protocol version %i.%i", major, minor);
370         return 0;
371 }
372
373 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
374         struct autofs_dev_ioctl param;
375
376         assert(dev_autofs_fd >= 0);
377         assert(ioctl_fd >= 0);
378
379         init_autofs_dev_ioctl(&param);
380         param.ioctlfd = ioctl_fd;
381         param.timeout.timeout = sec;
382
383         if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
384                 return -errno;
385
386         return 0;
387 }
388
389 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
390         struct autofs_dev_ioctl param;
391
392         assert(dev_autofs_fd >= 0);
393         assert(ioctl_fd >= 0);
394
395         init_autofs_dev_ioctl(&param);
396         param.ioctlfd = ioctl_fd;
397
398         if (status) {
399                 param.fail.token = token;
400                 param.fail.status = status;
401         } else
402                 param.ready.token = token;
403
404         if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
405                 return -errno;
406
407         return 0;
408 }
409
410 int automount_send_ready(Automount *a, int status) {
411         _cleanup_close_ int ioctl_fd = -1;
412         unsigned token;
413         int r;
414
415         assert(a);
416         assert(status <= 0);
417
418         if (set_isempty(a->tokens))
419                 return 0;
420
421         ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
422         if (ioctl_fd < 0)
423                 return ioctl_fd;
424
425         if (status)
426                 log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
427         else
428                 log_debug_unit(UNIT(a)->id, "Sending success.");
429
430         r = 0;
431
432         /* Autofs thankfully does not hand out 0 as a token */
433         while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
434                 int k;
435
436                 /* Autofs fun fact II:
437                  *
438                  * if you pass a positive status code here, the kernel will
439                  * freeze! Yay! */
440
441                 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
442                                       ioctl_fd,
443                                       token,
444                                       status);
445                 if (k < 0)
446                         r = k;
447         }
448
449         return r;
450 }
451
452 static void automount_enter_waiting(Automount *a) {
453         _cleanup_close_ int ioctl_fd = -1;
454         int p[2] = { -1, -1 };
455         char name[32], options[128];
456         bool mounted = false;
457         int r, dev_autofs_fd;
458         struct stat st;
459
460         assert(a);
461         assert(a->pipe_fd < 0);
462         assert(a->where);
463
464         if (a->tokens)
465                 set_clear(a->tokens);
466
467         dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
468         if (dev_autofs_fd < 0) {
469                 r = dev_autofs_fd;
470                 goto fail;
471         }
472
473         /* We knowingly ignore the results of this call */
474         mkdir_p_label(a->where, 0555);
475
476         warn_if_dir_nonempty(a->meta.id, a->where);
477
478         if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
479                 r = -errno;
480                 goto fail;
481         }
482
483         snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
484         char_array_0(options);
485
486         snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
487         char_array_0(name);
488
489         if (mount(name, a->where, "autofs", 0, options) < 0) {
490                 r = -errno;
491                 goto fail;
492         }
493
494         mounted = true;
495
496         p[1] = safe_close(p[1]);
497
498         if (stat(a->where, &st) < 0) {
499                 r = -errno;
500                 goto fail;
501         }
502
503         ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
504         if (ioctl_fd < 0) {
505                 r = ioctl_fd;
506                 goto fail;
507         }
508
509         r = autofs_protocol(dev_autofs_fd, ioctl_fd);
510         if (r < 0)
511                 goto fail;
512
513         r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
514         if (r < 0)
515                 goto fail;
516
517         /* Autofs fun fact:
518          *
519          * Unless we close the ioctl fd here, for some weird reason
520          * the direct mount will not receive events from the
521          * kernel. */
522
523         r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
524         if (r < 0)
525                 goto fail;
526
527         a->pipe_fd = p[0];
528         a->dev_id = st.st_dev;
529
530         automount_set_state(a, AUTOMOUNT_WAITING);
531
532         return;
533
534 fail:
535         safe_close_pair(p);
536
537         if (mounted)
538                 repeat_unmount(a->where);
539
540         log_error_unit(UNIT(a)->id,
541                        "Failed to initialize automounter: %s", strerror(-r));
542         automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
543 }
544
545 static void automount_enter_runnning(Automount *a) {
546         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
547         struct stat st;
548         int r;
549
550         assert(a);
551
552         /* We don't take mount requests anymore if we are supposed to
553          * shut down anyway */
554         if (unit_stop_pending(UNIT(a))) {
555                 log_debug_unit(UNIT(a)->id,
556                                "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
557                 automount_send_ready(a, -EHOSTDOWN);
558                 return;
559         }
560
561         mkdir_p_label(a->where, a->directory_mode);
562
563         /* Before we do anything, let's see if somebody is playing games with us? */
564         if (lstat(a->where, &st) < 0) {
565                 log_warning_unit(UNIT(a)->id,
566                                  "%s failed to stat automount point: %m", UNIT(a)->id);
567                 goto fail;
568         }
569
570         if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
571                 log_info_unit(UNIT(a)->id,
572                               "%s's automount point already active?", UNIT(a)->id);
573         else {
574                 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
575                                     JOB_REPLACE, true, &error, NULL);
576                 if (r < 0) {
577                         log_warning_unit(UNIT(a)->id,
578                                          "%s failed to queue mount startup job: %s",
579                                          UNIT(a)->id, bus_error_message(&error, r));
580                         goto fail;
581                 }
582         }
583
584         automount_set_state(a, AUTOMOUNT_RUNNING);
585         return;
586
587 fail:
588         automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
589 }
590
591 static int automount_start(Unit *u) {
592         Automount *a = AUTOMOUNT(u);
593
594         assert(a);
595         assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
596
597         if (path_is_mount_point(a->where, false)) {
598                 log_error_unit(u->id,
599                                "Path %s is already a mount point, refusing start for %s",
600                                a->where, u->id);
601                 return -EEXIST;
602         }
603
604         if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
605                 return -ENOENT;
606
607         a->result = AUTOMOUNT_SUCCESS;
608         automount_enter_waiting(a);
609         return 0;
610 }
611
612 static int automount_stop(Unit *u) {
613         Automount *a = AUTOMOUNT(u);
614
615         assert(a);
616         assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
617
618         automount_enter_dead(a, AUTOMOUNT_SUCCESS);
619         return 0;
620 }
621
622 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
623         Automount *a = AUTOMOUNT(u);
624         void *p;
625         Iterator i;
626
627         assert(a);
628         assert(f);
629         assert(fds);
630
631         unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
632         unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
633         unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
634
635         SET_FOREACH(p, a->tokens, i)
636                 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
637
638         if (a->pipe_fd >= 0) {
639                 int copy;
640
641                 copy = fdset_put_dup(fds, a->pipe_fd);
642                 if (copy < 0)
643                         return copy;
644
645                 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
646         }
647
648         return 0;
649 }
650
651 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
652         Automount *a = AUTOMOUNT(u);
653         int r;
654
655         assert(a);
656         assert(fds);
657
658         if (streq(key, "state")) {
659                 AutomountState state;
660
661                 state = automount_state_from_string(value);
662                 if (state < 0)
663                         log_debug_unit(u->id, "Failed to parse state value %s", value);
664                 else
665                         a->deserialized_state = state;
666         } else if (streq(key, "result")) {
667                 AutomountResult f;
668
669                 f = automount_result_from_string(value);
670                 if (f < 0)
671                         log_debug_unit(u->id, "Failed to parse result value %s", value);
672                 else if (f != AUTOMOUNT_SUCCESS)
673                         a->result = f;
674
675         } else if (streq(key, "dev-id")) {
676                 unsigned d;
677
678                 if (safe_atou(value, &d) < 0)
679                         log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
680                 else
681                         a->dev_id = (unsigned) d;
682         } else if (streq(key, "token")) {
683                 unsigned token;
684
685                 if (safe_atou(value, &token) < 0)
686                         log_debug_unit(u->id, "Failed to parse token value %s", value);
687                 else {
688                         if (!a->tokens)
689                                 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
690                                         return -ENOMEM;
691
692                         r = set_put(a->tokens, UINT_TO_PTR(token));
693                         if (r < 0)
694                                 return r;
695                 }
696         } else if (streq(key, "pipe-fd")) {
697                 int fd;
698
699                 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
700                         log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
701                 else {
702                         safe_close(a->pipe_fd);
703                         a->pipe_fd = fdset_remove(fds, fd);
704                 }
705         } else
706                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
707
708         return 0;
709 }
710
711 static UnitActiveState automount_active_state(Unit *u) {
712         assert(u);
713
714         return state_translation_table[AUTOMOUNT(u)->state];
715 }
716
717 static const char *automount_sub_state_to_string(Unit *u) {
718         assert(u);
719
720         return automount_state_to_string(AUTOMOUNT(u)->state);
721 }
722
723 static bool automount_check_gc(Unit *u) {
724         assert(u);
725
726         if (!UNIT_TRIGGER(u))
727                 return false;
728
729         return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
730 }
731
732 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
733         union autofs_v5_packet_union packet;
734         Automount *a = AUTOMOUNT(userdata);
735         ssize_t l;
736         int r;
737
738         assert(a);
739         assert(fd == a->pipe_fd);
740
741         if (events != EPOLLIN) {
742                 log_error_unit(UNIT(a)->id, "Got invalid poll event on pipe.");
743                 goto fail;
744         }
745
746         l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
747         if (l != sizeof(packet)) {
748                 log_error_unit(UNIT(a)->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
749                 goto fail;
750         }
751
752         switch (packet.hdr.type) {
753
754         case autofs_ptype_missing_direct:
755
756                 if (packet.v5_packet.pid > 0) {
757                         _cleanup_free_ char *p = NULL;
758
759                         get_process_comm(packet.v5_packet.pid, &p);
760                         log_info_unit(UNIT(a)->id,
761                                        "Got automount request for %s, triggered by "PID_FMT" (%s)",
762                                        a->where, packet.v5_packet.pid, strna(p));
763                 } else
764                         log_debug_unit(UNIT(a)->id, "Got direct mount request on %s", a->where);
765
766                 r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func);
767                 if (r < 0) {
768                         log_error_unit(UNIT(a)->id, "Failed to allocate token set.");
769                         goto fail;
770                 }
771
772                 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
773                 if (r < 0) {
774                         log_error_unit(UNIT(a)->id, "Failed to remember token: %s", strerror(-r));
775                         goto fail;
776                 }
777
778                 automount_enter_runnning(a);
779                 break;
780
781         default:
782                 log_error_unit(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
783                 break;
784         }
785
786         return 0;
787
788 fail:
789         automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
790         return 0;
791 }
792
793 static void automount_shutdown(Manager *m) {
794         assert(m);
795
796         m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
797 }
798
799 static void automount_reset_failed(Unit *u) {
800         Automount *a = AUTOMOUNT(u);
801
802         assert(a);
803
804         if (a->state == AUTOMOUNT_FAILED)
805                 automount_set_state(a, AUTOMOUNT_DEAD);
806
807         a->result = AUTOMOUNT_SUCCESS;
808 }
809
810 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
811         [AUTOMOUNT_DEAD] = "dead",
812         [AUTOMOUNT_WAITING] = "waiting",
813         [AUTOMOUNT_RUNNING] = "running",
814         [AUTOMOUNT_FAILED] = "failed"
815 };
816
817 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
818
819 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
820         [AUTOMOUNT_SUCCESS] = "success",
821         [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
822 };
823
824 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
825
826 const UnitVTable automount_vtable = {
827         .object_size = sizeof(Automount),
828
829         .sections =
830                 "Unit\0"
831                 "Automount\0"
832                 "Install\0",
833
834         .no_alias = true,
835         .no_instances = true,
836
837         .init = automount_init,
838         .load = automount_load,
839         .done = automount_done,
840
841         .coldplug = automount_coldplug,
842
843         .dump = automount_dump,
844
845         .start = automount_start,
846         .stop = automount_stop,
847
848         .serialize = automount_serialize,
849         .deserialize_item = automount_deserialize_item,
850
851         .active_state = automount_active_state,
852         .sub_state_to_string = automount_sub_state_to_string,
853
854         .check_gc = automount_check_gc,
855
856         .reset_failed = automount_reset_failed,
857
858         .bus_interface = "org.freedesktop.systemd1.Automount",
859         .bus_vtable = bus_automount_vtable,
860
861         .shutdown = automount_shutdown,
862
863         .status_message_formats = {
864                 .finished_start_job = {
865                         [JOB_DONE]       = "Set up automount %s.",
866                         [JOB_FAILED]     = "Failed to set up automount %s.",
867                         [JOB_DEPENDENCY] = "Dependency failed for %s.",
868                 },
869                 .finished_stop_job = {
870                         [JOB_DONE]       = "Unset automount %s.",
871                         [JOB_FAILED]     = "Failed to unset automount %s.",
872                 },
873         },
874 };