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