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