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