]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/automount.c
automount: add expire support
[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 free(a->where);
131 a->where = NULL;
132
133 set_free(a->tokens);
134 a->tokens = NULL;
135 set_free(a->expire_tokens);
136 a->expire_tokens = NULL;
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 != SYSTEMD_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 bool b;
171 _cleanup_free_ char *e = NULL;
172 assert(a);
173
174 if (UNIT(a)->load_state != UNIT_LOADED)
175 return 0;
176
177 if (path_equal(a->where, "/")) {
178 log_unit_error(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
179 return -EINVAL;
180 }
181
182 e = unit_name_from_path(a->where, ".automount");
183 if (!e)
184 return -ENOMEM;
185
186 b = unit_has_name(UNIT(a), e);
187
188 if (!b) {
189 log_unit_error(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
190 return -EINVAL;
191 }
192
193 return 0;
194 }
195
196 static int automount_load(Unit *u) {
197 Automount *a = AUTOMOUNT(u);
198 int r;
199
200 assert(u);
201 assert(u->load_state == UNIT_STUB);
202
203 /* Load a .automount file */
204 r = unit_load_fragment_and_dropin_optional(u);
205 if (r < 0)
206 return r;
207
208 if (u->load_state == UNIT_LOADED) {
209 Unit *x;
210
211 if (!a->where) {
212 a->where = unit_name_to_path(u->id);
213 if (!a->where)
214 return -ENOMEM;
215 }
216
217 path_kill_slashes(a->where);
218
219 r = unit_load_related_unit(u, ".mount", &x);
220 if (r < 0)
221 return r;
222
223 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
224 if (r < 0)
225 return r;
226
227 r = automount_add_mount_links(a);
228 if (r < 0)
229 return r;
230
231 if (UNIT(a)->default_dependencies) {
232 r = automount_add_default_dependencies(a);
233 if (r < 0)
234 return r;
235 }
236 }
237
238 return automount_verify(a);
239 }
240
241 static void automount_set_state(Automount *a, AutomountState state) {
242 AutomountState old_state;
243 assert(a);
244
245 old_state = a->state;
246 a->state = state;
247
248 if (state != AUTOMOUNT_WAITING &&
249 state != AUTOMOUNT_RUNNING)
250 unmount_autofs(a);
251
252 if (state != old_state)
253 log_unit_debug(UNIT(a)->id,
254 "%s changed %s -> %s",
255 UNIT(a)->id,
256 automount_state_to_string(old_state),
257 automount_state_to_string(state));
258
259 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
260 }
261
262 static int automount_coldplug(Unit *u, Hashmap *deferred_work) {
263 Automount *a = AUTOMOUNT(u);
264 int r;
265
266 assert(a);
267 assert(a->state == AUTOMOUNT_DEAD);
268
269 if (a->deserialized_state != a->state) {
270
271 r = open_dev_autofs(u->manager);
272 if (r < 0)
273 return r;
274
275 if (a->deserialized_state == AUTOMOUNT_WAITING ||
276 a->deserialized_state == AUTOMOUNT_RUNNING) {
277
278 assert(a->pipe_fd >= 0);
279
280 r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
281 if (r < 0)
282 return r;
283 }
284
285 automount_set_state(a, a->deserialized_state);
286 }
287
288 return 0;
289 }
290
291 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
292 char time_string[FORMAT_TIMESPAN_MAX];
293 Automount *a = AUTOMOUNT(u);
294
295 assert(a);
296
297 fprintf(f,
298 "%sAutomount State: %s\n"
299 "%sResult: %s\n"
300 "%sWhere: %s\n"
301 "%sDirectoryMode: %04o\n"
302 "%sTimeoutIdleUSec: %s\n",
303 prefix, automount_state_to_string(a->state),
304 prefix, automount_result_to_string(a->result),
305 prefix, a->where,
306 prefix, a->directory_mode,
307 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, a->timeout_idle_usec, USEC_PER_SEC));
308 }
309
310 static void automount_enter_dead(Automount *a, AutomountResult f) {
311 assert(a);
312
313 if (f != AUTOMOUNT_SUCCESS)
314 a->result = f;
315
316 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
317 }
318
319 static int open_dev_autofs(Manager *m) {
320 struct autofs_dev_ioctl param;
321
322 assert(m);
323
324 if (m->dev_autofs_fd >= 0)
325 return m->dev_autofs_fd;
326
327 label_fix("/dev/autofs", false, false);
328
329 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
330 if (m->dev_autofs_fd < 0)
331 return log_error_errno(errno, "Failed to open /dev/autofs: %m");
332
333 init_autofs_dev_ioctl(&param);
334 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
335 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
336 return -errno;
337 }
338
339 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
340
341 return m->dev_autofs_fd;
342 }
343
344 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
345 struct autofs_dev_ioctl *param;
346 size_t l;
347
348 assert(dev_autofs_fd >= 0);
349 assert(where);
350
351 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
352 param = alloca(l);
353
354 init_autofs_dev_ioctl(param);
355 param->size = l;
356 param->ioctlfd = -1;
357 param->openmount.devid = devid;
358 strcpy(param->path, where);
359
360 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
361 return -errno;
362
363 if (param->ioctlfd < 0)
364 return -EIO;
365
366 fd_cloexec(param->ioctlfd, true);
367 return param->ioctlfd;
368 }
369
370 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
371 uint32_t major, minor;
372 struct autofs_dev_ioctl param;
373
374 assert(dev_autofs_fd >= 0);
375 assert(ioctl_fd >= 0);
376
377 init_autofs_dev_ioctl(&param);
378 param.ioctlfd = ioctl_fd;
379
380 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
381 return -errno;
382
383 major = param.protover.version;
384
385 init_autofs_dev_ioctl(&param);
386 param.ioctlfd = ioctl_fd;
387
388 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
389 return -errno;
390
391 minor = param.protosubver.sub_version;
392
393 log_debug("Autofs protocol version %i.%i", major, minor);
394 return 0;
395 }
396
397 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, usec_t usec) {
398 struct autofs_dev_ioctl param;
399
400 assert(dev_autofs_fd >= 0);
401 assert(ioctl_fd >= 0);
402
403 init_autofs_dev_ioctl(&param);
404 param.ioctlfd = ioctl_fd;
405
406 /* Convert to seconds, rounding up. */
407 param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
408
409 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
410 return -errno;
411
412 return 0;
413 }
414
415 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
416 struct autofs_dev_ioctl param;
417
418 assert(dev_autofs_fd >= 0);
419 assert(ioctl_fd >= 0);
420
421 init_autofs_dev_ioctl(&param);
422 param.ioctlfd = ioctl_fd;
423
424 if (status) {
425 param.fail.token = token;
426 param.fail.status = status;
427 } else
428 param.ready.token = token;
429
430 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
431 return -errno;
432
433 return 0;
434 }
435
436 static int automount_send_ready(Automount *a, Set *tokens, int status) {
437 _cleanup_close_ int ioctl_fd = -1;
438 unsigned token;
439 int r;
440
441 assert(a);
442 assert(status <= 0);
443
444 if (set_isempty(tokens))
445 return 0;
446
447 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
448 if (ioctl_fd < 0)
449 return ioctl_fd;
450
451 if (status)
452 log_unit_debug_errno(UNIT(a)->id, status, "Sending failure: %m");
453 else
454 log_unit_debug(UNIT(a)->id, "Sending success.");
455
456 r = 0;
457
458 /* Autofs thankfully does not hand out 0 as a token */
459 while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
460 int k;
461
462 /* Autofs fun fact II:
463 *
464 * if you pass a positive status code here, the kernel will
465 * freeze! Yay! */
466
467 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
468 ioctl_fd,
469 token,
470 status);
471 if (k < 0)
472 r = k;
473 }
474
475 return r;
476 }
477
478 int automount_update_mount(Automount *a, MountState old_state, MountState state) {
479 _cleanup_close_ int ioctl_fd = -1;
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 break;
488 case MOUNT_DEAD:
489 case MOUNT_UNMOUNTING:
490 case MOUNT_MOUNTING_SIGTERM:
491 case MOUNT_MOUNTING_SIGKILL:
492 case MOUNT_REMOUNTING_SIGTERM:
493 case MOUNT_REMOUNTING_SIGKILL:
494 case MOUNT_UNMOUNTING_SIGTERM:
495 case MOUNT_UNMOUNTING_SIGKILL:
496 case MOUNT_FAILED:
497 if (old_state != state)
498 automount_send_ready(a, a->tokens, -ENODEV);
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 if (a->tokens)
542 set_clear(a->tokens);
543
544 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
545 if (dev_autofs_fd < 0) {
546 r = dev_autofs_fd;
547 goto fail;
548 }
549
550 /* We knowingly ignore the results of this call */
551 mkdir_p_label(a->where, 0555);
552
553 warn_if_dir_nonempty(a->meta.id, a->where);
554
555 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
556 r = -errno;
557 goto fail;
558 }
559
560 xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
561 xsprintf(name, "systemd-"PID_FMT, getpid());
562 if (mount(name, a->where, "autofs", 0, options) < 0) {
563 r = -errno;
564 goto fail;
565 }
566
567 mounted = true;
568
569 p[1] = safe_close(p[1]);
570
571 if (stat(a->where, &st) < 0) {
572 r = -errno;
573 goto fail;
574 }
575
576 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
577 if (ioctl_fd < 0) {
578 r = ioctl_fd;
579 goto fail;
580 }
581
582 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
583 if (r < 0)
584 goto fail;
585
586 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, a->timeout_idle_usec);
587 if (r < 0)
588 goto fail;
589
590 /* Autofs fun fact:
591 *
592 * Unless we close the ioctl fd here, for some weird reason
593 * the direct mount will not receive events from the
594 * kernel. */
595
596 r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
597 if (r < 0)
598 goto fail;
599
600 a->pipe_fd = p[0];
601 a->dev_id = st.st_dev;
602
603 automount_set_state(a, AUTOMOUNT_WAITING);
604
605 return;
606
607 fail:
608 safe_close_pair(p);
609
610 if (mounted)
611 repeat_unmount(a->where);
612
613 log_unit_error(UNIT(a)->id,
614 "Failed to initialize automounter: %s", strerror(-r));
615 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
616 }
617
618 static void *expire_thread(void *p) {
619 struct autofs_dev_ioctl param;
620 _cleanup_(expire_data_freep) struct expire_data *data = (struct expire_data*)p;
621 int r;
622
623 assert(data->dev_autofs_fd >= 0);
624 assert(data->ioctl_fd >= 0);
625
626 init_autofs_dev_ioctl(&param);
627 param.ioctlfd = data->ioctl_fd;
628
629 do {
630 r = ioctl(data->dev_autofs_fd, AUTOFS_DEV_IOCTL_EXPIRE, &param);
631 } while (r >= 0);
632
633 if (errno != EAGAIN)
634 log_warning_errno(errno, "Failed to expire automount, ignoring: %m");
635
636 return NULL;
637 }
638
639 static int automount_start_expire(Automount *a);
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)->id, 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)->id, 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)->id, 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 timeout = now(CLOCK_MONOTONIC) + MAX(a->timeout_idle_usec/10, USEC_PER_SEC);
679
680 if (a->expire_event_source) {
681 r = sd_event_source_set_time(a->expire_event_source, timeout);
682 if (r < 0)
683 return r;
684
685 return sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_ONESHOT);
686 }
687
688 return sd_event_add_time(
689 UNIT(a)->manager->event,
690 &a->expire_event_source,
691 CLOCK_MONOTONIC, timeout, 0,
692 automount_dispatch_expire, a);
693 }
694
695 static void automount_enter_runnning(Automount *a) {
696 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
697 struct stat st;
698 int r;
699
700 assert(a);
701
702 /* We don't take mount requests anymore if we are supposed to
703 * shut down anyway */
704 if (unit_stop_pending(UNIT(a))) {
705 log_unit_debug(UNIT(a)->id,
706 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
707 automount_send_ready(a, a->tokens, -EHOSTDOWN);
708 automount_send_ready(a, a->expire_tokens, -EHOSTDOWN);
709 return;
710 }
711
712 mkdir_p_label(a->where, a->directory_mode);
713
714 /* Before we do anything, let's see if somebody is playing games with us? */
715 if (lstat(a->where, &st) < 0) {
716 log_unit_warning(UNIT(a)->id,
717 "%s failed to stat automount point: %m", UNIT(a)->id);
718 goto fail;
719 }
720
721 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
722 log_unit_info(UNIT(a)->id,
723 "%s's automount point already active?", UNIT(a)->id);
724 else {
725 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
726 JOB_REPLACE, true, &error, NULL);
727 if (r < 0) {
728 log_unit_warning(UNIT(a)->id,
729 "%s failed to queue mount startup job: %s",
730 UNIT(a)->id, bus_error_message(&error, r));
731 goto fail;
732 }
733 }
734
735 r = automount_start_expire(a);
736 if (r < 0)
737 log_unit_warning_errno(UNIT(a)->id, r, "Failed to start expiration timer, ignoring: %m");
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, false) > 0) {
753 log_unit_error(u->id, "Path %s is already a mount point, refusing start for %s", a->where, u->id);
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 void *p;
778 Iterator i;
779
780 assert(a);
781 assert(f);
782 assert(fds);
783
784 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
785 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
786 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
787
788 SET_FOREACH(p, a->tokens, i)
789 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
790 SET_FOREACH(p, a->expire_tokens, i)
791 unit_serialize_item_format(u, f, "expire-token", "%u", PTR_TO_UINT(p));
792
793 if (a->pipe_fd >= 0) {
794 int copy;
795
796 copy = fdset_put_dup(fds, a->pipe_fd);
797 if (copy < 0)
798 return copy;
799
800 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
801 }
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->id, "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->id, "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->id, "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->id, "Failed to parse token value %s", value);
842 else {
843 if (!a->tokens)
844 if (!(a->tokens = set_new(NULL)))
845 return -ENOMEM;
846
847 r = set_put(a->tokens, UINT_TO_PTR(token));
848 if (r < 0)
849 return r;
850 }
851 } else if (streq(key, "expire-token")) {
852 unsigned token;
853
854 if (safe_atou(value, &token) < 0)
855 log_unit_debug(u->id, "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->id, 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->id, "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->id, "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 int r;
908
909 assert(a);
910 assert(fd == a->pipe_fd);
911
912 if (events != EPOLLIN) {
913 log_unit_error(UNIT(a)->id, "%s: got invalid poll event %"PRIu32" on pipe (fd=%d)",
914 UNIT(a)->id, 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)->id, 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)->id,
933 "Got automount request for %s, triggered by %"PRIu32" (%s)",
934 a->where, packet.v5_packet.pid, strna(p));
935 } else
936 log_unit_debug(UNIT(a)->id, "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)->id, "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)->id, 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)->id, "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)->id, "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)->id, r, "Failed to remember token: %m");
967 goto fail;
968 }
969 r = manager_add_job(UNIT(a)->manager, JOB_STOP, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, true, &error, NULL);
970 if (r < 0) {
971 log_unit_warning(UNIT(a)->id,
972 "%s failed to queue umount startup job: %s",
973 UNIT(a)->id, bus_error_message(&error, r));
974 goto fail;
975 }
976 break;
977
978 default:
979 log_unit_error(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
980 break;
981 }
982
983 return 0;
984
985 fail:
986 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
987 return 0;
988 }
989
990 static void automount_shutdown(Manager *m) {
991 assert(m);
992
993 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
994 }
995
996 static void automount_reset_failed(Unit *u) {
997 Automount *a = AUTOMOUNT(u);
998
999 assert(a);
1000
1001 if (a->state == AUTOMOUNT_FAILED)
1002 automount_set_state(a, AUTOMOUNT_DEAD);
1003
1004 a->result = AUTOMOUNT_SUCCESS;
1005 }
1006
1007 static bool automount_supported(Manager *m) {
1008 static int supported = -1;
1009
1010 assert(m);
1011
1012 if (supported < 0)
1013 supported = access("/dev/autofs", F_OK) >= 0;
1014
1015 return supported;
1016 }
1017
1018 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
1019 [AUTOMOUNT_DEAD] = "dead",
1020 [AUTOMOUNT_WAITING] = "waiting",
1021 [AUTOMOUNT_RUNNING] = "running",
1022 [AUTOMOUNT_FAILED] = "failed"
1023 };
1024
1025 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
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_interface = "org.freedesktop.systemd1.Automount",
1067 .bus_vtable = bus_automount_vtable,
1068
1069 .shutdown = automount_shutdown,
1070 .supported = automount_supported,
1071
1072 .status_message_formats = {
1073 .finished_start_job = {
1074 [JOB_DONE] = "Set up automount %s.",
1075 [JOB_FAILED] = "Failed to set up automount %s.",
1076 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1077 },
1078 .finished_stop_job = {
1079 [JOB_DONE] = "Unset automount %s.",
1080 [JOB_FAILED] = "Failed to unset automount %s.",
1081 },
1082 },
1083 };