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