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