]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/automount.c
Merge pull request #1880 from fsateler/sysctl-doc
[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)->default_dependencies)
152 return 0;
153
154 if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
155 return 0;
156
157 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
158 if (r < 0)
159 return r;
160
161 return 0;
162 }
163
164 static int automount_verify(Automount *a) {
165 _cleanup_free_ char *e = NULL;
166 int r;
167
168 assert(a);
169
170 if (UNIT(a)->load_state != UNIT_LOADED)
171 return 0;
172
173 if (path_equal(a->where, "/")) {
174 log_unit_error(UNIT(a), "Cannot have an automount unit for the root directory. Refusing.");
175 return -EINVAL;
176 }
177
178 r = unit_name_from_path(a->where, ".automount", &e);
179 if (r < 0)
180 return log_unit_error(UNIT(a), "Failed to generate unit name from path: %m");
181
182 if (!unit_has_name(UNIT(a), e)) {
183 log_unit_error(UNIT(a), "Where= setting doesn't match unit name. Refusing.");
184 return -EINVAL;
185 }
186
187 return 0;
188 }
189
190 static int automount_load(Unit *u) {
191 Automount *a = AUTOMOUNT(u);
192 int r;
193
194 assert(u);
195 assert(u->load_state == UNIT_STUB);
196
197 /* Load a .automount file */
198 r = unit_load_fragment_and_dropin_optional(u);
199 if (r < 0)
200 return r;
201
202 if (u->load_state == UNIT_LOADED) {
203 Unit *x;
204
205 if (!a->where) {
206 r = unit_name_to_path(u->id, &a->where);
207 if (r < 0)
208 return r;
209 }
210
211 path_kill_slashes(a->where);
212
213 r = unit_load_related_unit(u, ".mount", &x);
214 if (r < 0)
215 return r;
216
217 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
218 if (r < 0)
219 return r;
220
221 r = automount_add_mount_links(a);
222 if (r < 0)
223 return r;
224
225 r = automount_add_default_dependencies(a);
226 if (r < 0)
227 return r;
228 }
229
230 return automount_verify(a);
231 }
232
233 static void automount_set_state(Automount *a, AutomountState state) {
234 AutomountState old_state;
235 assert(a);
236
237 old_state = a->state;
238 a->state = state;
239
240 if (state != AUTOMOUNT_WAITING &&
241 state != AUTOMOUNT_RUNNING)
242 unmount_autofs(a);
243
244 if (state != old_state)
245 log_unit_debug(UNIT(a), "Changed %s -> %s", automount_state_to_string(old_state), automount_state_to_string(state));
246
247 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
248 }
249
250 static int automount_coldplug(Unit *u) {
251 Automount *a = AUTOMOUNT(u);
252 int r;
253
254 assert(a);
255 assert(a->state == AUTOMOUNT_DEAD);
256
257 if (a->deserialized_state != a->state) {
258
259 r = open_dev_autofs(u->manager);
260 if (r < 0)
261 return r;
262
263 if (a->deserialized_state == AUTOMOUNT_WAITING ||
264 a->deserialized_state == AUTOMOUNT_RUNNING) {
265 assert(a->pipe_fd >= 0);
266
267 r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
268 if (r < 0)
269 return r;
270
271 (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
272 }
273
274 automount_set_state(a, a->deserialized_state);
275 }
276
277 return 0;
278 }
279
280 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
281 char time_string[FORMAT_TIMESPAN_MAX];
282 Automount *a = AUTOMOUNT(u);
283
284 assert(a);
285
286 fprintf(f,
287 "%sAutomount State: %s\n"
288 "%sResult: %s\n"
289 "%sWhere: %s\n"
290 "%sDirectoryMode: %04o\n"
291 "%sTimeoutIdleUSec: %s\n",
292 prefix, automount_state_to_string(a->state),
293 prefix, automount_result_to_string(a->result),
294 prefix, a->where,
295 prefix, a->directory_mode,
296 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, a->timeout_idle_usec, USEC_PER_SEC));
297 }
298
299 static void automount_enter_dead(Automount *a, AutomountResult f) {
300 assert(a);
301
302 if (f != AUTOMOUNT_SUCCESS)
303 a->result = f;
304
305 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
306 }
307
308 static int open_dev_autofs(Manager *m) {
309 struct autofs_dev_ioctl param;
310
311 assert(m);
312
313 if (m->dev_autofs_fd >= 0)
314 return m->dev_autofs_fd;
315
316 label_fix("/dev/autofs", false, false);
317
318 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
319 if (m->dev_autofs_fd < 0)
320 return log_error_errno(errno, "Failed to open /dev/autofs: %m");
321
322 init_autofs_dev_ioctl(&param);
323 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
324 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
325 return -errno;
326 }
327
328 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
329
330 return m->dev_autofs_fd;
331 }
332
333 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
334 struct autofs_dev_ioctl *param;
335 size_t l;
336
337 assert(dev_autofs_fd >= 0);
338 assert(where);
339
340 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
341 param = alloca(l);
342
343 init_autofs_dev_ioctl(param);
344 param->size = l;
345 param->ioctlfd = -1;
346 param->openmount.devid = devid;
347 strcpy(param->path, where);
348
349 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
350 return -errno;
351
352 if (param->ioctlfd < 0)
353 return -EIO;
354
355 (void) fd_cloexec(param->ioctlfd, true);
356 return param->ioctlfd;
357 }
358
359 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
360 uint32_t major, minor;
361 struct autofs_dev_ioctl param;
362
363 assert(dev_autofs_fd >= 0);
364 assert(ioctl_fd >= 0);
365
366 init_autofs_dev_ioctl(&param);
367 param.ioctlfd = ioctl_fd;
368
369 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
370 return -errno;
371
372 major = param.protover.version;
373
374 init_autofs_dev_ioctl(&param);
375 param.ioctlfd = ioctl_fd;
376
377 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
378 return -errno;
379
380 minor = param.protosubver.sub_version;
381
382 log_debug("Autofs protocol version %i.%i", major, minor);
383 return 0;
384 }
385
386 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, usec_t usec) {
387 struct autofs_dev_ioctl param;
388
389 assert(dev_autofs_fd >= 0);
390 assert(ioctl_fd >= 0);
391
392 init_autofs_dev_ioctl(&param);
393 param.ioctlfd = ioctl_fd;
394
395 /* Convert to seconds, rounding up. */
396 param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
397
398 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
399 return -errno;
400
401 return 0;
402 }
403
404 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
405 struct autofs_dev_ioctl param;
406
407 assert(dev_autofs_fd >= 0);
408 assert(ioctl_fd >= 0);
409
410 init_autofs_dev_ioctl(&param);
411 param.ioctlfd = ioctl_fd;
412
413 if (status) {
414 param.fail.token = token;
415 param.fail.status = status;
416 } else
417 param.ready.token = token;
418
419 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
420 return -errno;
421
422 return 0;
423 }
424
425 static int automount_send_ready(Automount *a, Set *tokens, int status) {
426 _cleanup_close_ int ioctl_fd = -1;
427 unsigned token;
428 int r;
429
430 assert(a);
431 assert(status <= 0);
432
433 if (set_isempty(tokens))
434 return 0;
435
436 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
437 if (ioctl_fd < 0)
438 return ioctl_fd;
439
440 if (status)
441 log_unit_debug_errno(UNIT(a), status, "Sending failure: %m");
442 else
443 log_unit_debug(UNIT(a), "Sending success.");
444
445 r = 0;
446
447 /* Autofs thankfully does not hand out 0 as a token */
448 while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
449 int k;
450
451 /* Autofs fun fact II:
452 *
453 * if you pass a positive status code here, the kernel will
454 * freeze! Yay! */
455
456 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
457 ioctl_fd,
458 token,
459 status);
460 if (k < 0)
461 r = k;
462 }
463
464 return r;
465 }
466
467 static int automount_start_expire(Automount *a);
468
469 int automount_update_mount(Automount *a, MountState old_state, MountState state) {
470 int r;
471
472 assert(a);
473
474 switch (state) {
475 case MOUNT_MOUNTED:
476 case MOUNT_REMOUNTING:
477 automount_send_ready(a, a->tokens, 0);
478 r = automount_start_expire(a);
479 if (r < 0)
480 log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m");
481 break;
482 case MOUNT_DEAD:
483 case MOUNT_UNMOUNTING:
484 case MOUNT_MOUNTING_SIGTERM:
485 case MOUNT_MOUNTING_SIGKILL:
486 case MOUNT_REMOUNTING_SIGTERM:
487 case MOUNT_REMOUNTING_SIGKILL:
488 case MOUNT_UNMOUNTING_SIGTERM:
489 case MOUNT_UNMOUNTING_SIGKILL:
490 case MOUNT_FAILED:
491 if (old_state != state)
492 automount_send_ready(a, a->tokens, -ENODEV);
493 (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
494 break;
495 default:
496 break;
497 }
498
499 switch (state) {
500 case MOUNT_DEAD:
501 automount_send_ready(a, a->expire_tokens, 0);
502 break;
503 case MOUNT_MOUNTING:
504 case MOUNT_MOUNTING_DONE:
505 case MOUNT_MOUNTING_SIGTERM:
506 case MOUNT_MOUNTING_SIGKILL:
507 case MOUNT_REMOUNTING_SIGTERM:
508 case MOUNT_REMOUNTING_SIGKILL:
509 case MOUNT_UNMOUNTING_SIGTERM:
510 case MOUNT_UNMOUNTING_SIGKILL:
511 case MOUNT_FAILED:
512 if (old_state != state)
513 automount_send_ready(a, a->expire_tokens, -ENODEV);
514 break;
515 default:
516 break;
517 }
518
519 return 0;
520 }
521
522 static void automount_enter_waiting(Automount *a) {
523 _cleanup_close_ int ioctl_fd = -1;
524 int p[2] = { -1, -1 };
525 char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1];
526 char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
527 + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1];
528 bool mounted = false;
529 int r, dev_autofs_fd;
530 struct stat st;
531
532 assert(a);
533 assert(a->pipe_fd < 0);
534 assert(a->where);
535
536 set_clear(a->tokens);
537
538 r = unit_fail_if_symlink(UNIT(a), a->where);
539 if (r < 0)
540 goto fail;
541
542 (void) mkdir_p_label(a->where, 0555);
543
544 unit_warn_if_dir_nonempty(UNIT(a), a->where);
545
546 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
547 if (dev_autofs_fd < 0) {
548 r = dev_autofs_fd;
549 goto fail;
550 }
551
552 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
553 r = -errno;
554 goto fail;
555 }
556
557 xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
558 xsprintf(name, "systemd-"PID_FMT, getpid());
559 if (mount(name, a->where, "autofs", 0, options) < 0) {
560 r = -errno;
561 goto fail;
562 }
563
564 mounted = true;
565
566 p[1] = safe_close(p[1]);
567
568 if (stat(a->where, &st) < 0) {
569 r = -errno;
570 goto fail;
571 }
572
573 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
574 if (ioctl_fd < 0) {
575 r = ioctl_fd;
576 goto fail;
577 }
578
579 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
580 if (r < 0)
581 goto fail;
582
583 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, a->timeout_idle_usec);
584 if (r < 0)
585 goto fail;
586
587 /* Autofs fun fact:
588 *
589 * Unless we close the ioctl fd here, for some weird reason
590 * the direct mount will not receive events from the
591 * kernel. */
592
593 r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
594 if (r < 0)
595 goto fail;
596
597 (void) sd_event_source_set_description(a->pipe_event_source, "automount-io");
598
599 a->pipe_fd = p[0];
600 a->dev_id = st.st_dev;
601
602 automount_set_state(a, AUTOMOUNT_WAITING);
603
604 return;
605
606 fail:
607 log_unit_error_errno(UNIT(a), r, "Failed to initialize automounter: %m");
608
609 safe_close_pair(p);
610
611 if (mounted) {
612 r = repeat_unmount(a->where, MNT_DETACH);
613 if (r < 0)
614 log_error_errno(r, "Failed to unmount, ignoring: %m");
615 }
616
617 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
618 }
619
620 static void *expire_thread(void *p) {
621 struct autofs_dev_ioctl param;
622 _cleanup_(expire_data_freep) struct expire_data *data = (struct expire_data*)p;
623 int r;
624
625 assert(data->dev_autofs_fd >= 0);
626 assert(data->ioctl_fd >= 0);
627
628 init_autofs_dev_ioctl(&param);
629 param.ioctlfd = data->ioctl_fd;
630
631 do {
632 r = ioctl(data->dev_autofs_fd, AUTOFS_DEV_IOCTL_EXPIRE, &param);
633 } while (r >= 0);
634
635 if (errno != EAGAIN)
636 log_warning_errno(errno, "Failed to expire automount, ignoring: %m");
637
638 return NULL;
639 }
640
641 static int automount_dispatch_expire(sd_event_source *source, usec_t usec, void *userdata) {
642 Automount *a = AUTOMOUNT(userdata);
643 _cleanup_(expire_data_freep) struct expire_data *data = NULL;
644 int r;
645
646 assert(a);
647 assert(source == a->expire_event_source);
648
649 data = new0(struct expire_data, 1);
650 if (!data)
651 return log_oom();
652
653 data->ioctl_fd = -1;
654
655 data->dev_autofs_fd = fcntl(UNIT(a)->manager->dev_autofs_fd, F_DUPFD_CLOEXEC, 3);
656 if (data->dev_autofs_fd < 0)
657 return log_unit_error_errno(UNIT(a), errno, "Failed to duplicate autofs fd: %m");
658
659 data->ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
660 if (data->ioctl_fd < 0)
661 return log_unit_error_errno(UNIT(a), data->ioctl_fd, "Couldn't open autofs ioctl fd: %m");
662
663 r = asynchronous_job(expire_thread, data);
664 if (r < 0)
665 return log_unit_error_errno(UNIT(a), r, "Failed to start expire job: %m");
666
667 data = NULL;
668
669 return automount_start_expire(a);
670 }
671
672 static int automount_start_expire(Automount *a) {
673 int r;
674 usec_t timeout;
675
676 assert(a);
677
678 if (a->timeout_idle_usec == 0)
679 return 0;
680
681 timeout = now(CLOCK_MONOTONIC) + MAX(a->timeout_idle_usec/3, USEC_PER_SEC);
682
683 if (a->expire_event_source) {
684 r = sd_event_source_set_time(a->expire_event_source, timeout);
685 if (r < 0)
686 return r;
687
688 return sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_ONESHOT);
689 }
690
691 r = sd_event_add_time(
692 UNIT(a)->manager->event,
693 &a->expire_event_source,
694 CLOCK_MONOTONIC, timeout, 0,
695 automount_dispatch_expire, a);
696 if (r < 0)
697 return r;
698
699 (void) sd_event_source_set_description(a->expire_event_source, "automount-expire");
700
701 return 0;
702 }
703
704 static void automount_enter_runnning(Automount *a) {
705 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
706 struct stat st;
707 int r;
708
709 assert(a);
710
711 /* We don't take mount requests anymore if we are supposed to
712 * shut down anyway */
713 if (unit_stop_pending(UNIT(a))) {
714 log_unit_debug(UNIT(a), "Suppressing automount request since unit stop is scheduled.");
715 automount_send_ready(a, a->tokens, -EHOSTDOWN);
716 automount_send_ready(a, a->expire_tokens, -EHOSTDOWN);
717 return;
718 }
719
720 mkdir_p_label(a->where, a->directory_mode);
721
722 /* Before we do anything, let's see if somebody is playing games with us? */
723 if (lstat(a->where, &st) < 0) {
724 log_unit_warning_errno(UNIT(a), errno, "Failed to stat automount point: %m");
725 goto fail;
726 }
727
728 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
729 log_unit_info(UNIT(a), "Automount point already active?");
730 else {
731 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, &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, &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 };