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