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