]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/automount.c
Merge pull request #1690 from evverx/run-runtime-directory
[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 <fcntl.h>
24 #include <limits.h>
25 #include <linux/auto_dev-ioctl.h>
26 #include <linux/auto_fs4.h>
27 #include <sys/epoll.h>
28 #include <sys/mount.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #include "alloc-util.h"
33 #include "async.h"
34 #include "automount.h"
35 #include "bus-error.h"
36 #include "bus-util.h"
37 #include "dbus-automount.h"
38 #include "fd-util.h"
39 #include "formats-util.h"
40 #include "io-util.h"
41 #include "label.h"
42 #include "mkdir.h"
43 #include "mount-util.h"
44 #include "mount.h"
45 #include "parse-util.h"
46 #include "path-util.h"
47 #include "process-util.h"
48 #include "special.h"
49 #include "stdio-util.h"
50 #include "string-table.h"
51 #include "string-util.h"
52 #include "unit-name.h"
53 #include "unit.h"
54
55 static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
56 [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
57 [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
58 [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
59 [AUTOMOUNT_FAILED] = UNIT_FAILED
60 };
61
62 struct expire_data {
63 int dev_autofs_fd;
64 int ioctl_fd;
65 };
66
67 static inline void expire_data_free(struct expire_data *data) {
68 if (!data)
69 return;
70
71 safe_close(data->dev_autofs_fd);
72 safe_close(data->ioctl_fd);
73 free(data);
74 }
75
76 DEFINE_TRIVIAL_CLEANUP_FUNC(struct expire_data*, expire_data_free);
77
78 static int open_dev_autofs(Manager *m);
79 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
80
81 static void automount_init(Unit *u) {
82 Automount *a = AUTOMOUNT(u);
83
84 assert(u);
85 assert(u->load_state == UNIT_STUB);
86
87 a->pipe_fd = -1;
88 a->directory_mode = 0755;
89 UNIT(a)->ignore_on_isolate = true;
90 }
91
92 static int automount_send_ready(Automount *a, Set *tokens, int status);
93
94 static void unmount_autofs(Automount *a) {
95 int r;
96
97 assert(a);
98
99 if (a->pipe_fd < 0)
100 return;
101
102 automount_send_ready(a, a->tokens, -EHOSTDOWN);
103 automount_send_ready(a, a->expire_tokens, -EHOSTDOWN);
104
105 a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
106 a->pipe_fd = safe_close(a->pipe_fd);
107
108 /* If we reload/reexecute things we keep the mount point
109 * around */
110 if (a->where &&
111 (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
112 UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) {
113 r = repeat_unmount(a->where, MNT_DETACH);
114 if (r < 0)
115 log_error_errno(r, "Failed to unmount: %m");
116 }
117 }
118
119 static void automount_done(Unit *u) {
120 Automount *a = AUTOMOUNT(u);
121
122 assert(a);
123
124 unmount_autofs(a);
125
126 a->where = mfree(a->where);
127
128 a->tokens = set_free(a->tokens);
129 a->expire_tokens = set_free(a->expire_tokens);
130
131 a->expire_event_source = sd_event_source_unref(a->expire_event_source);
132 }
133
134 static int automount_add_mount_links(Automount *a) {
135 _cleanup_free_ char *parent = NULL;
136
137 assert(a);
138
139 parent = dirname_malloc(a->where);
140 if (!parent)
141 return -ENOMEM;
142
143 return unit_require_mounts_for(UNIT(a), parent);
144 }
145
146 static int automount_add_default_dependencies(Automount *a) {
147 int r;
148
149 assert(a);
150
151 if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
152 return 0;
153
154 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
155 if (r < 0)
156 return r;
157
158 return 0;
159 }
160
161 static int automount_verify(Automount *a) {
162 _cleanup_free_ char *e = NULL;
163 int r;
164
165 assert(a);
166
167 if (UNIT(a)->load_state != UNIT_LOADED)
168 return 0;
169
170 if (path_equal(a->where, "/")) {
171 log_unit_error(UNIT(a), "Cannot have an automount unit for the root directory. Refusing.");
172 return -EINVAL;
173 }
174
175 r = unit_name_from_path(a->where, ".automount", &e);
176 if (r < 0)
177 return log_unit_error(UNIT(a), "Failed to generate unit name from path: %m");
178
179 if (!unit_has_name(UNIT(a), e)) {
180 log_unit_error(UNIT(a), "Where= setting doesn't match unit name. Refusing.");
181 return -EINVAL;
182 }
183
184 return 0;
185 }
186
187 static int automount_load(Unit *u) {
188 Automount *a = AUTOMOUNT(u);
189 int r;
190
191 assert(u);
192 assert(u->load_state == UNIT_STUB);
193
194 /* Load a .automount file */
195 r = unit_load_fragment_and_dropin_optional(u);
196 if (r < 0)
197 return r;
198
199 if (u->load_state == UNIT_LOADED) {
200 Unit *x;
201
202 if (!a->where) {
203 r = unit_name_to_path(u->id, &a->where);
204 if (r < 0)
205 return r;
206 }
207
208 path_kill_slashes(a->where);
209
210 r = unit_load_related_unit(u, ".mount", &x);
211 if (r < 0)
212 return r;
213
214 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
215 if (r < 0)
216 return r;
217
218 r = automount_add_mount_links(a);
219 if (r < 0)
220 return r;
221
222 if (UNIT(a)->default_dependencies) {
223 r = automount_add_default_dependencies(a);
224 if (r < 0)
225 return r;
226 }
227 }
228
229 return automount_verify(a);
230 }
231
232 static void automount_set_state(Automount *a, AutomountState state) {
233 AutomountState old_state;
234 assert(a);
235
236 old_state = a->state;
237 a->state = state;
238
239 if (state != AUTOMOUNT_WAITING &&
240 state != AUTOMOUNT_RUNNING)
241 unmount_autofs(a);
242
243 if (state != old_state)
244 log_unit_debug(UNIT(a), "Changed %s -> %s", automount_state_to_string(old_state), automount_state_to_string(state));
245
246 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
247 }
248
249 static int automount_coldplug(Unit *u) {
250 Automount *a = AUTOMOUNT(u);
251 int r;
252
253 assert(a);
254 assert(a->state == AUTOMOUNT_DEAD);
255
256 if (a->deserialized_state != a->state) {
257
258 r = open_dev_autofs(u->manager);
259 if (r < 0)
260 return r;
261
262 if (a->deserialized_state == AUTOMOUNT_WAITING ||
263 a->deserialized_state == AUTOMOUNT_RUNNING) {
264 assert(a->pipe_fd >= 0);
265
266 r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
267 if (r < 0)
268 return r;
269
270 (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
271 }
272
273 automount_set_state(a, a->deserialized_state);
274 }
275
276 return 0;
277 }
278
279 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
280 char time_string[FORMAT_TIMESPAN_MAX];
281 Automount *a = AUTOMOUNT(u);
282
283 assert(a);
284
285 fprintf(f,
286 "%sAutomount State: %s\n"
287 "%sResult: %s\n"
288 "%sWhere: %s\n"
289 "%sDirectoryMode: %04o\n"
290 "%sTimeoutIdleUSec: %s\n",
291 prefix, automount_state_to_string(a->state),
292 prefix, automount_result_to_string(a->result),
293 prefix, a->where,
294 prefix, a->directory_mode,
295 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, a->timeout_idle_usec, USEC_PER_SEC));
296 }
297
298 static void automount_enter_dead(Automount *a, AutomountResult f) {
299 assert(a);
300
301 if (f != AUTOMOUNT_SUCCESS)
302 a->result = f;
303
304 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
305 }
306
307 static int open_dev_autofs(Manager *m) {
308 struct autofs_dev_ioctl param;
309
310 assert(m);
311
312 if (m->dev_autofs_fd >= 0)
313 return m->dev_autofs_fd;
314
315 label_fix("/dev/autofs", false, false);
316
317 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
318 if (m->dev_autofs_fd < 0)
319 return log_error_errno(errno, "Failed to open /dev/autofs: %m");
320
321 init_autofs_dev_ioctl(&param);
322 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
323 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
324 return -errno;
325 }
326
327 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
328
329 return m->dev_autofs_fd;
330 }
331
332 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
333 struct autofs_dev_ioctl *param;
334 size_t l;
335
336 assert(dev_autofs_fd >= 0);
337 assert(where);
338
339 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
340 param = alloca(l);
341
342 init_autofs_dev_ioctl(param);
343 param->size = l;
344 param->ioctlfd = -1;
345 param->openmount.devid = devid;
346 strcpy(param->path, where);
347
348 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
349 return -errno;
350
351 if (param->ioctlfd < 0)
352 return -EIO;
353
354 (void) fd_cloexec(param->ioctlfd, true);
355 return param->ioctlfd;
356 }
357
358 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
359 uint32_t major, minor;
360 struct autofs_dev_ioctl param;
361
362 assert(dev_autofs_fd >= 0);
363 assert(ioctl_fd >= 0);
364
365 init_autofs_dev_ioctl(&param);
366 param.ioctlfd = ioctl_fd;
367
368 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
369 return -errno;
370
371 major = param.protover.version;
372
373 init_autofs_dev_ioctl(&param);
374 param.ioctlfd = ioctl_fd;
375
376 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
377 return -errno;
378
379 minor = param.protosubver.sub_version;
380
381 log_debug("Autofs protocol version %i.%i", major, minor);
382 return 0;
383 }
384
385 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, usec_t usec) {
386 struct autofs_dev_ioctl param;
387
388 assert(dev_autofs_fd >= 0);
389 assert(ioctl_fd >= 0);
390
391 init_autofs_dev_ioctl(&param);
392 param.ioctlfd = ioctl_fd;
393
394 /* Convert to seconds, rounding up. */
395 param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
396
397 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
398 return -errno;
399
400 return 0;
401 }
402
403 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
404 struct autofs_dev_ioctl param;
405
406 assert(dev_autofs_fd >= 0);
407 assert(ioctl_fd >= 0);
408
409 init_autofs_dev_ioctl(&param);
410 param.ioctlfd = ioctl_fd;
411
412 if (status) {
413 param.fail.token = token;
414 param.fail.status = status;
415 } else
416 param.ready.token = token;
417
418 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
419 return -errno;
420
421 return 0;
422 }
423
424 static int automount_send_ready(Automount *a, Set *tokens, int status) {
425 _cleanup_close_ int ioctl_fd = -1;
426 unsigned token;
427 int r;
428
429 assert(a);
430 assert(status <= 0);
431
432 if (set_isempty(tokens))
433 return 0;
434
435 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
436 if (ioctl_fd < 0)
437 return ioctl_fd;
438
439 if (status)
440 log_unit_debug_errno(UNIT(a), status, "Sending failure: %m");
441 else
442 log_unit_debug(UNIT(a), "Sending success.");
443
444 r = 0;
445
446 /* Autofs thankfully does not hand out 0 as a token */
447 while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
448 int k;
449
450 /* Autofs fun fact II:
451 *
452 * if you pass a positive status code here, the kernel will
453 * freeze! Yay! */
454
455 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
456 ioctl_fd,
457 token,
458 status);
459 if (k < 0)
460 r = k;
461 }
462
463 return r;
464 }
465
466 static int automount_start_expire(Automount *a);
467
468 int automount_update_mount(Automount *a, MountState old_state, MountState state) {
469 int r;
470
471 assert(a);
472
473 switch (state) {
474 case MOUNT_MOUNTED:
475 case MOUNT_REMOUNTING:
476 automount_send_ready(a, a->tokens, 0);
477 r = automount_start_expire(a);
478 if (r < 0)
479 log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m");
480 break;
481 case MOUNT_DEAD:
482 case MOUNT_UNMOUNTING:
483 case MOUNT_MOUNTING_SIGTERM:
484 case MOUNT_MOUNTING_SIGKILL:
485 case MOUNT_REMOUNTING_SIGTERM:
486 case MOUNT_REMOUNTING_SIGKILL:
487 case MOUNT_UNMOUNTING_SIGTERM:
488 case MOUNT_UNMOUNTING_SIGKILL:
489 case MOUNT_FAILED:
490 if (old_state != state)
491 automount_send_ready(a, a->tokens, -ENODEV);
492 (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
493 break;
494 default:
495 break;
496 }
497
498 switch (state) {
499 case MOUNT_DEAD:
500 automount_send_ready(a, a->expire_tokens, 0);
501 break;
502 case MOUNT_MOUNTING:
503 case MOUNT_MOUNTING_DONE:
504 case MOUNT_MOUNTING_SIGTERM:
505 case MOUNT_MOUNTING_SIGKILL:
506 case MOUNT_REMOUNTING_SIGTERM:
507 case MOUNT_REMOUNTING_SIGKILL:
508 case MOUNT_UNMOUNTING_SIGTERM:
509 case MOUNT_UNMOUNTING_SIGKILL:
510 case MOUNT_FAILED:
511 if (old_state != state)
512 automount_send_ready(a, a->expire_tokens, -ENODEV);
513 break;
514 default:
515 break;
516 }
517
518 return 0;
519 }
520
521 static void automount_enter_waiting(Automount *a) {
522 _cleanup_close_ int ioctl_fd = -1;
523 int p[2] = { -1, -1 };
524 char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1];
525 char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
526 + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1];
527 bool mounted = false;
528 int r, dev_autofs_fd;
529 struct stat st;
530
531 assert(a);
532 assert(a->pipe_fd < 0);
533 assert(a->where);
534
535 set_clear(a->tokens);
536
537 r = unit_fail_if_symlink(UNIT(a), a->where);
538 if (r < 0)
539 goto fail;
540
541 (void) mkdir_p_label(a->where, 0555);
542
543 unit_warn_if_dir_nonempty(UNIT(a), a->where);
544
545 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
546 if (dev_autofs_fd < 0) {
547 r = dev_autofs_fd;
548 goto fail;
549 }
550
551 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
552 r = -errno;
553 goto fail;
554 }
555
556 xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
557 xsprintf(name, "systemd-"PID_FMT, getpid());
558 if (mount(name, a->where, "autofs", 0, options) < 0) {
559 r = -errno;
560 goto fail;
561 }
562
563 mounted = true;
564
565 p[1] = safe_close(p[1]);
566
567 if (stat(a->where, &st) < 0) {
568 r = -errno;
569 goto fail;
570 }
571
572 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
573 if (ioctl_fd < 0) {
574 r = ioctl_fd;
575 goto fail;
576 }
577
578 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
579 if (r < 0)
580 goto fail;
581
582 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, a->timeout_idle_usec);
583 if (r < 0)
584 goto fail;
585
586 /* Autofs fun fact:
587 *
588 * Unless we close the ioctl fd here, for some weird reason
589 * the direct mount will not receive events from the
590 * kernel. */
591
592 r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
593 if (r < 0)
594 goto fail;
595
596 (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
597
598 a->pipe_fd = p[0];
599 a->dev_id = st.st_dev;
600
601 automount_set_state(a, AUTOMOUNT_WAITING);
602
603 return;
604
605 fail:
606 log_unit_error_errno(UNIT(a), r, "Failed to initialize automounter: %m");
607
608 safe_close_pair(p);
609
610 if (mounted) {
611 r = repeat_unmount(a->where, MNT_DETACH);
612 if (r < 0)
613 log_error_errno(r, "Failed to unmount, ignoring: %m");
614 }
615
616 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
617 }
618
619 static void *expire_thread(void *p) {
620 struct autofs_dev_ioctl param;
621 _cleanup_(expire_data_freep) struct expire_data *data = (struct expire_data*)p;
622 int r;
623
624 assert(data->dev_autofs_fd >= 0);
625 assert(data->ioctl_fd >= 0);
626
627 init_autofs_dev_ioctl(&param);
628 param.ioctlfd = data->ioctl_fd;
629
630 do {
631 r = ioctl(data->dev_autofs_fd, AUTOFS_DEV_IOCTL_EXPIRE, &param);
632 } while (r >= 0);
633
634 if (errno != EAGAIN)
635 log_warning_errno(errno, "Failed to expire automount, ignoring: %m");
636
637 return NULL;
638 }
639
640 static int automount_dispatch_expire(sd_event_source *source, usec_t usec, void *userdata) {
641 Automount *a = AUTOMOUNT(userdata);
642 _cleanup_(expire_data_freep) struct expire_data *data = NULL;
643 int r;
644
645 assert(a);
646 assert(source == a->expire_event_source);
647
648 data = new0(struct expire_data, 1);
649 if (!data)
650 return log_oom();
651
652 data->ioctl_fd = -1;
653
654 data->dev_autofs_fd = fcntl(UNIT(a)->manager->dev_autofs_fd, F_DUPFD_CLOEXEC, 3);
655 if (data->dev_autofs_fd < 0)
656 return log_unit_error_errno(UNIT(a), errno, "Failed to duplicate autofs fd: %m");
657
658 data->ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
659 if (data->ioctl_fd < 0)
660 return log_unit_error_errno(UNIT(a), data->ioctl_fd, "Couldn't open autofs ioctl fd: %m");
661
662 r = asynchronous_job(expire_thread, data);
663 if (r < 0)
664 return log_unit_error_errno(UNIT(a), r, "Failed to start expire job: %m");
665
666 data = NULL;
667
668 return automount_start_expire(a);
669 }
670
671 static int automount_start_expire(Automount *a) {
672 int r;
673 usec_t timeout;
674
675 assert(a);
676
677 if (a->timeout_idle_usec == 0)
678 return 0;
679
680 timeout = now(CLOCK_MONOTONIC) + MAX(a->timeout_idle_usec/3, USEC_PER_SEC);
681
682 if (a->expire_event_source) {
683 r = sd_event_source_set_time(a->expire_event_source, timeout);
684 if (r < 0)
685 return r;
686
687 return sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_ONESHOT);
688 }
689
690 r = sd_event_add_time(
691 UNIT(a)->manager->event,
692 &a->expire_event_source,
693 CLOCK_MONOTONIC, timeout, 0,
694 automount_dispatch_expire, a);
695 if (r < 0)
696 return r;
697
698 (void) sd_event_source_set_description(a->expire_event_source, "automount-expire");
699
700 return 0;
701 }
702
703 static void automount_enter_runnning(Automount *a) {
704 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
705 struct stat st;
706 int r;
707
708 assert(a);
709
710 /* We don't take mount requests anymore if we are supposed to
711 * shut down anyway */
712 if (unit_stop_pending(UNIT(a))) {
713 log_unit_debug(UNIT(a), "Suppressing automount request since unit stop is scheduled.");
714 automount_send_ready(a, a->tokens, -EHOSTDOWN);
715 automount_send_ready(a, a->expire_tokens, -EHOSTDOWN);
716 return;
717 }
718
719 mkdir_p_label(a->where, a->directory_mode);
720
721 /* Before we do anything, let's see if somebody is playing games with us? */
722 if (lstat(a->where, &st) < 0) {
723 log_unit_warning_errno(UNIT(a), errno, "Failed to stat automount point: %m");
724 goto fail;
725 }
726
727 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
728 log_unit_info(UNIT(a), "Automount point already active?");
729 else {
730 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
731 JOB_REPLACE, true, &error, NULL);
732 if (r < 0) {
733 log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r));
734 goto fail;
735 }
736 }
737
738 automount_set_state(a, AUTOMOUNT_RUNNING);
739 return;
740
741 fail:
742 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
743 }
744
745 static int automount_start(Unit *u) {
746 Automount *a = AUTOMOUNT(u);
747
748 assert(a);
749 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
750
751 if (path_is_mount_point(a->where, 0) > 0) {
752 log_unit_error(u, "Path %s is already a mount point, refusing start.", a->where);
753 return -EEXIST;
754 }
755
756 if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
757 return -ENOENT;
758
759 a->result = AUTOMOUNT_SUCCESS;
760 automount_enter_waiting(a);
761 return 1;
762 }
763
764 static int automount_stop(Unit *u) {
765 Automount *a = AUTOMOUNT(u);
766
767 assert(a);
768 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
769
770 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
771 return 1;
772 }
773
774 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
775 Automount *a = AUTOMOUNT(u);
776 Iterator i;
777 void *p;
778 int r;
779
780 assert(a);
781 assert(f);
782 assert(fds);
783
784 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
785 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
786 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
787
788 SET_FOREACH(p, a->tokens, i)
789 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
790 SET_FOREACH(p, a->expire_tokens, i)
791 unit_serialize_item_format(u, f, "expire-token", "%u", PTR_TO_UINT(p));
792
793 r = unit_serialize_item_fd(u, f, fds, "pipe-fd", a->pipe_fd);
794 if (r < 0)
795 return r;
796
797 return 0;
798 }
799
800 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
801 Automount *a = AUTOMOUNT(u);
802 int r;
803
804 assert(a);
805 assert(fds);
806
807 if (streq(key, "state")) {
808 AutomountState state;
809
810 state = automount_state_from_string(value);
811 if (state < 0)
812 log_unit_debug(u, "Failed to parse state value: %s", value);
813 else
814 a->deserialized_state = state;
815 } else if (streq(key, "result")) {
816 AutomountResult f;
817
818 f = automount_result_from_string(value);
819 if (f < 0)
820 log_unit_debug(u, "Failed to parse result value: %s", value);
821 else if (f != AUTOMOUNT_SUCCESS)
822 a->result = f;
823
824 } else if (streq(key, "dev-id")) {
825 unsigned d;
826
827 if (safe_atou(value, &d) < 0)
828 log_unit_debug(u, "Failed to parse dev-id value: %s", value);
829 else
830 a->dev_id = (unsigned) d;
831 } else if (streq(key, "token")) {
832 unsigned token;
833
834 if (safe_atou(value, &token) < 0)
835 log_unit_debug(u, "Failed to parse token value: %s", value);
836 else {
837 r = set_ensure_allocated(&a->tokens, NULL);
838 if (r < 0) {
839 log_oom();
840 return 0;
841 }
842
843 r = set_put(a->tokens, UINT_TO_PTR(token));
844 if (r < 0)
845 log_unit_error_errno(u, r, "Failed to add token to set: %m");
846 }
847 } else if (streq(key, "expire-token")) {
848 unsigned token;
849
850 if (safe_atou(value, &token) < 0)
851 log_unit_debug(u, "Failed to parse token value: %s", value);
852 else {
853 r = set_ensure_allocated(&a->expire_tokens, NULL);
854 if (r < 0) {
855 log_oom();
856 return 0;
857 }
858
859 r = set_put(a->expire_tokens, UINT_TO_PTR(token));
860 if (r < 0)
861 log_unit_error_errno(u, r, "Failed to add expire token to set: %m");
862 }
863 } else if (streq(key, "pipe-fd")) {
864 int fd;
865
866 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
867 log_unit_debug(u, "Failed to parse pipe-fd value: %s", value);
868 else {
869 safe_close(a->pipe_fd);
870 a->pipe_fd = fdset_remove(fds, fd);
871 }
872 } else
873 log_unit_debug(u, "Unknown serialization key: %s", key);
874
875 return 0;
876 }
877
878 static UnitActiveState automount_active_state(Unit *u) {
879 assert(u);
880
881 return state_translation_table[AUTOMOUNT(u)->state];
882 }
883
884 static const char *automount_sub_state_to_string(Unit *u) {
885 assert(u);
886
887 return automount_state_to_string(AUTOMOUNT(u)->state);
888 }
889
890 static bool automount_check_gc(Unit *u) {
891 assert(u);
892
893 if (!UNIT_TRIGGER(u))
894 return false;
895
896 return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
897 }
898
899 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
900 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
901 union autofs_v5_packet_union packet;
902 Automount *a = AUTOMOUNT(userdata);
903 struct stat st;
904 int r;
905
906 assert(a);
907 assert(fd == a->pipe_fd);
908
909 if (events != EPOLLIN) {
910 log_unit_error(UNIT(a), "Got invalid poll event %"PRIu32" on pipe (fd=%d)", events, fd);
911 goto fail;
912 }
913
914 r = loop_read_exact(a->pipe_fd, &packet, sizeof(packet), true);
915 if (r < 0) {
916 log_unit_error_errno(UNIT(a), r, "Invalid read from pipe: %m");
917 goto fail;
918 }
919
920 switch (packet.hdr.type) {
921
922 case autofs_ptype_missing_direct:
923
924 if (packet.v5_packet.pid > 0) {
925 _cleanup_free_ char *p = NULL;
926
927 get_process_comm(packet.v5_packet.pid, &p);
928 log_unit_info(UNIT(a), "Got automount request for %s, triggered by %"PRIu32" (%s)", a->where, packet.v5_packet.pid, strna(p));
929 } else
930 log_unit_debug(UNIT(a), "Got direct mount request on %s", a->where);
931
932 r = set_ensure_allocated(&a->tokens, NULL);
933 if (r < 0) {
934 log_unit_error(UNIT(a), "Failed to allocate token set.");
935 goto fail;
936 }
937
938 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
939 if (r < 0) {
940 log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m");
941 goto fail;
942 }
943
944 automount_enter_runnning(a);
945 break;
946
947 case autofs_ptype_expire_direct:
948 log_unit_debug(UNIT(a), "Got direct umount request on %s", a->where);
949
950 (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
951
952 r = set_ensure_allocated(&a->expire_tokens, NULL);
953 if (r < 0) {
954 log_unit_error(UNIT(a), "Failed to allocate token set.");
955 goto fail;
956 }
957
958 r = set_put(a->expire_tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
959 if (r < 0) {
960 log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m");
961 goto fail;
962 }
963
964 /* Before we do anything, let's see if somebody is playing games with us? */
965 if (lstat(a->where, &st) < 0) {
966 log_unit_warning_errno(UNIT(a), errno, "Failed to stat automount point: %m");
967 goto fail;
968 }
969
970 if (!S_ISDIR(st.st_mode) || st.st_dev == a->dev_id) {
971 log_unit_info(UNIT(a), "Automount point already unmounted?");
972 automount_send_ready(a, a->expire_tokens, 0);
973 break;
974 }
975
976 r = manager_add_job(UNIT(a)->manager, JOB_STOP, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, true, &error, NULL);
977 if (r < 0) {
978 log_unit_warning(UNIT(a), "Failed to queue umount startup job: %s", bus_error_message(&error, r));
979 goto fail;
980 }
981 break;
982
983 default:
984 log_unit_error(UNIT(a), "Received unknown automount request %i", packet.hdr.type);
985 break;
986 }
987
988 return 0;
989
990 fail:
991 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
992 return 0;
993 }
994
995 static void automount_shutdown(Manager *m) {
996 assert(m);
997
998 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
999 }
1000
1001 static void automount_reset_failed(Unit *u) {
1002 Automount *a = AUTOMOUNT(u);
1003
1004 assert(a);
1005
1006 if (a->state == AUTOMOUNT_FAILED)
1007 automount_set_state(a, AUTOMOUNT_DEAD);
1008
1009 a->result = AUTOMOUNT_SUCCESS;
1010 }
1011
1012 static bool automount_supported(void) {
1013 static int supported = -1;
1014
1015 if (supported < 0)
1016 supported = access("/dev/autofs", F_OK) >= 0;
1017
1018 return supported;
1019 }
1020
1021 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
1022 [AUTOMOUNT_SUCCESS] = "success",
1023 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
1024 };
1025
1026 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
1027
1028 const UnitVTable automount_vtable = {
1029 .object_size = sizeof(Automount),
1030
1031 .sections =
1032 "Unit\0"
1033 "Automount\0"
1034 "Install\0",
1035
1036 .no_alias = true,
1037 .no_instances = true,
1038
1039 .init = automount_init,
1040 .load = automount_load,
1041 .done = automount_done,
1042
1043 .coldplug = automount_coldplug,
1044
1045 .dump = automount_dump,
1046
1047 .start = automount_start,
1048 .stop = automount_stop,
1049
1050 .serialize = automount_serialize,
1051 .deserialize_item = automount_deserialize_item,
1052
1053 .active_state = automount_active_state,
1054 .sub_state_to_string = automount_sub_state_to_string,
1055
1056 .check_gc = automount_check_gc,
1057
1058 .reset_failed = automount_reset_failed,
1059
1060 .bus_vtable = bus_automount_vtable,
1061
1062 .shutdown = automount_shutdown,
1063 .supported = automount_supported,
1064
1065 .status_message_formats = {
1066 .finished_start_job = {
1067 [JOB_DONE] = "Set up automount %s.",
1068 [JOB_FAILED] = "Failed to set up automount %s.",
1069 },
1070 .finished_stop_job = {
1071 [JOB_DONE] = "Unset automount %s.",
1072 [JOB_FAILED] = "Failed to unset automount %s.",
1073 },
1074 },
1075 };