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