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