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