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