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