]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/automount.c
11c217beb9f10abfbf90bf82f0cfe081b3c2f528
[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 "load-fragment.h"
35 #include "load-dropin.h"
36 #include "unit-name.h"
37 #include "dbus-automount.h"
38 #include "bus-errors.h"
39 #include "special.h"
40 #include "label.h"
41 #include "mkdir.h"
42
43 static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
44 [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
45 [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
46 [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
47 [AUTOMOUNT_FAILED] = UNIT_FAILED
48 };
49
50 static int open_dev_autofs(Manager *m);
51
52 static void automount_init(Unit *u) {
53 Automount *a = AUTOMOUNT(u);
54
55 assert(u);
56 assert(u->load_state == UNIT_STUB);
57
58 a->pipe_watch.fd = a->pipe_fd = -1;
59 a->pipe_watch.type = WATCH_INVALID;
60
61 a->directory_mode = 0755;
62
63 UNIT(a)->ignore_on_isolate = true;
64 }
65
66 static void repeat_unmout(const char *path) {
67 assert(path);
68
69 for (;;) {
70 /* If there are multiple mounts on a mount point, this
71 * removes them all */
72
73 if (umount2(path, MNT_DETACH) >= 0)
74 continue;
75
76 if (errno != EINVAL)
77 log_error("Failed to unmount: %m");
78
79 break;
80 }
81 }
82
83 static void unmount_autofs(Automount *a) {
84 assert(a);
85
86 if (a->pipe_fd < 0)
87 return;
88
89 automount_send_ready(a, -EHOSTDOWN);
90
91 unit_unwatch_fd(UNIT(a), &a->pipe_watch);
92 close_nointr_nofail(a->pipe_fd);
93 a->pipe_fd = -1;
94
95 /* If we reload/reexecute things we keep the mount point
96 * around */
97 if (a->where &&
98 (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
99 UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
100 repeat_unmout(a->where);
101 }
102
103 static void automount_done(Unit *u) {
104 Automount *a = AUTOMOUNT(u);
105
106 assert(a);
107
108 unmount_autofs(a);
109 unit_ref_unset(&a->mount);
110
111 free(a->where);
112 a->where = NULL;
113
114 set_free(a->tokens);
115 a->tokens = NULL;
116 }
117
118 int automount_add_one_mount_link(Automount *a, Mount *m) {
119 int r;
120
121 assert(a);
122 assert(m);
123
124 if (UNIT(a)->load_state != UNIT_LOADED ||
125 UNIT(m)->load_state != UNIT_LOADED)
126 return 0;
127
128 if (!path_startswith(a->where, m->where))
129 return 0;
130
131 if (path_equal(a->where, m->where))
132 return 0;
133
134 if ((r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
135 return r;
136
137 return 0;
138 }
139
140 static int automount_add_mount_links(Automount *a) {
141 Unit *other;
142 int r;
143
144 assert(a);
145
146 LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT])
147 if ((r = automount_add_one_mount_link(a, MOUNT(other))) < 0)
148 return r;
149
150 return 0;
151 }
152
153 static int automount_add_default_dependencies(Automount *a) {
154 int r;
155
156 assert(a);
157
158 if (UNIT(a)->manager->running_as == MANAGER_SYSTEM) {
159
160 if ((r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
161 return r;
162
163 if ((r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
164 return r;
165 }
166
167 return 0;
168 }
169
170 static int automount_verify(Automount *a) {
171 bool b;
172 char *e;
173 assert(a);
174
175 if (UNIT(a)->load_state != UNIT_LOADED)
176 return 0;
177
178 if (path_equal(a->where, "/")) {
179 log_error("Cannot have an automount unit for the root directory. Refusing.");
180 return -EINVAL;
181 }
182
183 if (!(e = unit_name_from_path(a->where, ".automount")))
184 return -ENOMEM;
185
186 b = unit_has_name(UNIT(a), e);
187 free(e);
188
189 if (!b) {
190 log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
191 return -EINVAL;
192 }
193
194 return 0;
195 }
196
197 static int automount_load(Unit *u) {
198 int r;
199 Automount *a = AUTOMOUNT(u);
200
201 assert(u);
202 assert(u->load_state == UNIT_STUB);
203
204 /* Load a .automount file */
205 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
206 return r;
207
208 if (u->load_state == UNIT_LOADED) {
209 Unit *x;
210
211 if (!a->where)
212 if (!(a->where = unit_name_to_path(u->id)))
213 return -ENOMEM;
214
215 path_kill_slashes(a->where);
216
217 if ((r = automount_add_mount_links(a)) < 0)
218 return r;
219
220 r = unit_load_related_unit(u, ".mount", &x);
221 if (r < 0)
222 return r;
223
224 unit_ref_set(&a->mount, x);
225
226 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
227 if (r < 0)
228 return r;
229
230 if (UNIT(a)->default_dependencies)
231 if ((r = automount_add_default_dependencies(a)) < 0)
232 return r;
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_debug("%s changed %s -> %s",
251 UNIT(a)->id,
252 automount_state_to_string(old_state),
253 automount_state_to_string(state));
254
255 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
256 }
257
258 static int automount_coldplug(Unit *u) {
259 Automount *a = AUTOMOUNT(u);
260 int r;
261
262 assert(a);
263 assert(a->state == AUTOMOUNT_DEAD);
264
265 if (a->deserialized_state != a->state) {
266
267 if ((r = open_dev_autofs(u->manager)) < 0)
268 return r;
269
270 if (a->deserialized_state == AUTOMOUNT_WAITING ||
271 a->deserialized_state == AUTOMOUNT_RUNNING) {
272
273 assert(a->pipe_fd >= 0);
274
275 if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 0)
276 return r;
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 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 prefix, automount_state_to_string(a->state),
296 prefix, automount_result_to_string(a->result),
297 prefix, a->where,
298 prefix, a->directory_mode);
299 }
300
301 static void automount_enter_dead(Automount *a, AutomountResult f) {
302 assert(a);
303
304 if (f != AUTOMOUNT_SUCCESS)
305 a->result = f;
306
307 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
308 }
309
310 static int open_dev_autofs(Manager *m) {
311 struct autofs_dev_ioctl param;
312
313 assert(m);
314
315 if (m->dev_autofs_fd >= 0)
316 return m->dev_autofs_fd;
317
318 label_fix("/dev/autofs", false);
319
320 if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) {
321 log_error("Failed to open /dev/autofs: %s", strerror(errno));
322 return -errno;
323 }
324
325 init_autofs_dev_ioctl(&param);
326 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
327 close_nointr_nofail(m->dev_autofs_fd);
328 m->dev_autofs_fd = -1;
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 int r;
341
342 assert(dev_autofs_fd >= 0);
343 assert(where);
344
345 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
346
347 if (!(param = malloc(l)))
348 return -ENOMEM;
349
350 init_autofs_dev_ioctl(param);
351 param->size = l;
352 param->ioctlfd = -1;
353 param->openmount.devid = devid;
354 strcpy(param->path, where);
355
356 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) {
357 r = -errno;
358 goto finish;
359 }
360
361 if (param->ioctlfd < 0) {
362 r = -EIO;
363 goto finish;
364 }
365
366 fd_cloexec(param->ioctlfd, true);
367 r = param->ioctlfd;
368
369 finish:
370 free(param);
371 return r;
372 }
373
374 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
375 uint32_t major, minor;
376 struct autofs_dev_ioctl param;
377
378 assert(dev_autofs_fd >= 0);
379 assert(ioctl_fd >= 0);
380
381 init_autofs_dev_ioctl(&param);
382 param.ioctlfd = ioctl_fd;
383
384 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, &param) < 0)
385 return -errno;
386
387 major = param.protover.version;
388
389 init_autofs_dev_ioctl(&param);
390 param.ioctlfd = ioctl_fd;
391
392 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, &param) < 0)
393 return -errno;
394
395 minor = param.protosubver.sub_version;
396
397 log_debug("Autofs protocol version %i.%i", major, minor);
398 return 0;
399 }
400
401 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
402 struct autofs_dev_ioctl param;
403
404 assert(dev_autofs_fd >= 0);
405 assert(ioctl_fd >= 0);
406
407 init_autofs_dev_ioctl(&param);
408 param.ioctlfd = ioctl_fd;
409 param.timeout.timeout = sec;
410
411 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) < 0)
412 return -errno;
413
414 return 0;
415 }
416
417 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
418 struct autofs_dev_ioctl param;
419
420 assert(dev_autofs_fd >= 0);
421 assert(ioctl_fd >= 0);
422
423 init_autofs_dev_ioctl(&param);
424 param.ioctlfd = ioctl_fd;
425
426 if (status) {
427 param.fail.token = token;
428 param.fail.status = status;
429 } else
430 param.ready.token = token;
431
432 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, &param) < 0)
433 return -errno;
434
435 return 0;
436 }
437
438 int automount_send_ready(Automount *a, int status) {
439 int ioctl_fd, r;
440 unsigned token;
441
442 assert(a);
443 assert(status <= 0);
444
445 if (set_isempty(a->tokens))
446 return 0;
447
448 if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) {
449 r = ioctl_fd;
450 goto fail;
451 }
452
453 if (status)
454 log_debug("Sending failure: %s", strerror(-status));
455 else
456 log_debug("Sending success.");
457
458 r = 0;
459
460 /* Autofs thankfully does not hand out 0 as a token */
461 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
462 int k;
463
464 /* Autofs fun fact II:
465 *
466 * if you pass a positive status code here, the kernel will
467 * freeze! Yay! */
468
469 if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
470 ioctl_fd,
471 token,
472 status)) < 0)
473 r = k;
474 }
475
476 fail:
477 if (ioctl_fd >= 0)
478 close_nointr_nofail(ioctl_fd);
479
480 return r;
481 }
482
483 static void automount_enter_waiting(Automount *a) {
484 int p[2] = { -1, -1 };
485 char name[32], options[128];
486 bool mounted = false;
487 int r, ioctl_fd = -1, dev_autofs_fd;
488 struct stat st;
489
490 assert(a);
491 assert(a->pipe_fd < 0);
492 assert(a->where);
493
494 if (a->tokens)
495 set_clear(a->tokens);
496
497 if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) {
498 r = dev_autofs_fd;
499 goto fail;
500 }
501
502 /* We knowingly ignore the results of this call */
503 mkdir_p(a->where, 0555);
504
505 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
506 r = -errno;
507 goto fail;
508 }
509
510 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
511 char_array_0(options);
512
513 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
514 char_array_0(name);
515
516 if (mount(name, a->where, "autofs", 0, options) < 0) {
517 r = -errno;
518 goto fail;
519 }
520
521 mounted = true;
522
523 close_nointr_nofail(p[1]);
524 p[1] = -1;
525
526 if (stat(a->where, &st) < 0) {
527 r = -errno;
528 goto fail;
529 }
530
531 if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) {
532 r = ioctl_fd;
533 goto fail;
534 }
535
536 if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0)
537 goto fail;
538
539 if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0)
540 goto fail;
541
542 /* Autofs fun fact:
543 *
544 * Unless we close the ioctl fd here, for some weird reason
545 * the direct mount will not receive events from the
546 * kernel. */
547
548 close_nointr_nofail(ioctl_fd);
549 ioctl_fd = -1;
550
551 if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0)
552 goto fail;
553
554 a->pipe_fd = p[0];
555 a->dev_id = st.st_dev;
556
557 automount_set_state(a, AUTOMOUNT_WAITING);
558
559 return;
560
561 fail:
562 assert_se(close_pipe(p) == 0);
563
564 if (ioctl_fd >= 0)
565 close_nointr_nofail(ioctl_fd);
566
567 if (mounted)
568 repeat_unmout(a->where);
569
570 log_error("Failed to initialize automounter: %s", strerror(-r));
571 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
572 }
573
574 static void automount_enter_runnning(Automount *a) {
575 int r;
576 struct stat st;
577 DBusError error;
578
579 assert(a);
580 assert(UNIT_DEREF(a->mount));
581
582 dbus_error_init(&error);
583
584 /* We don't take mount requests anymore if we are supposed to
585 * shut down anyway */
586 if (unit_pending_inactive(UNIT(a))) {
587 log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
588 automount_send_ready(a, -EHOSTDOWN);
589 return;
590 }
591
592 mkdir_p(a->where, a->directory_mode);
593
594 /* Before we do anything, let's see if somebody is playing games with us? */
595 if (lstat(a->where, &st) < 0) {
596 log_warning("%s failed to stat automount point: %m", UNIT(a)->id);
597 goto fail;
598 }
599
600 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
601 log_info("%s's automount point already active?", UNIT(a)->id);
602 else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
603 log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r));
604 goto fail;
605 }
606
607 automount_set_state(a, AUTOMOUNT_RUNNING);
608 return;
609
610 fail:
611 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
612 dbus_error_free(&error);
613 }
614
615 static int automount_start(Unit *u) {
616 Automount *a = AUTOMOUNT(u);
617
618 assert(a);
619
620 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
621
622 if (path_is_mount_point(a->where, false)) {
623 log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id);
624 return -EEXIST;
625 }
626
627 if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
628 return -ENOENT;
629
630 a->result = AUTOMOUNT_SUCCESS;
631 automount_enter_waiting(a);
632 return 0;
633 }
634
635 static int automount_stop(Unit *u) {
636 Automount *a = AUTOMOUNT(u);
637
638 assert(a);
639
640 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
641
642 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
643 return 0;
644 }
645
646 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
647 Automount *a = AUTOMOUNT(u);
648 void *p;
649 Iterator i;
650
651 assert(a);
652 assert(f);
653 assert(fds);
654
655 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
656 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
657 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
658
659 SET_FOREACH(p, a->tokens, i)
660 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
661
662 if (a->pipe_fd >= 0) {
663 int copy;
664
665 if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0)
666 return copy;
667
668 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
669 }
670
671 return 0;
672 }
673
674 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
675 Automount *a = AUTOMOUNT(u);
676 int r;
677
678 assert(a);
679 assert(fds);
680
681 if (streq(key, "state")) {
682 AutomountState state;
683
684 if ((state = automount_state_from_string(value)) < 0)
685 log_debug("Failed to parse state value %s", value);
686 else
687 a->deserialized_state = state;
688 } else if (streq(key, "result")) {
689 AutomountResult f;
690
691 f = automount_result_from_string(value);
692 if (f < 0)
693 log_debug("Failed to parse result value %s", value);
694 else if (f != AUTOMOUNT_SUCCESS)
695 a->result = f;
696
697 } else if (streq(key, "dev-id")) {
698 unsigned d;
699
700 if (safe_atou(value, &d) < 0)
701 log_debug("Failed to parse dev-id value %s", value);
702 else
703 a->dev_id = (unsigned) d;
704 } else if (streq(key, "token")) {
705 unsigned token;
706
707 if (safe_atou(value, &token) < 0)
708 log_debug("Failed to parse token value %s", value);
709 else {
710 if (!a->tokens)
711 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
712 return -ENOMEM;
713
714 if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0)
715 return r;
716 }
717 } else if (streq(key, "pipe-fd")) {
718 int fd;
719
720 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
721 log_debug("Failed to parse pipe-fd value %s", value);
722 else {
723 if (a->pipe_fd >= 0)
724 close_nointr_nofail(a->pipe_fd);
725
726 a->pipe_fd = fdset_remove(fds, fd);
727 }
728 } else
729 log_debug("Unknown serialization key '%s'", key);
730
731 return 0;
732 }
733
734 static UnitActiveState automount_active_state(Unit *u) {
735 assert(u);
736
737 return state_translation_table[AUTOMOUNT(u)->state];
738 }
739
740 static const char *automount_sub_state_to_string(Unit *u) {
741 assert(u);
742
743 return automount_state_to_string(AUTOMOUNT(u)->state);
744 }
745
746 static bool automount_check_gc(Unit *u) {
747 Automount *a = AUTOMOUNT(u);
748
749 assert(a);
750
751 if (!UNIT_DEREF(a->mount))
752 return false;
753
754 return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
755 }
756
757 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
758 Automount *a = AUTOMOUNT(u);
759 union autofs_v5_packet_union packet;
760 ssize_t l;
761 int r;
762
763 assert(a);
764 assert(fd == a->pipe_fd);
765
766 if (events != EPOLLIN) {
767 log_error("Got invalid poll event on pipe.");
768 goto fail;
769 }
770
771 if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
772 log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
773 goto fail;
774 }
775
776 switch (packet.hdr.type) {
777
778 case autofs_ptype_missing_direct:
779
780 if (packet.v5_packet.pid > 0) {
781 char *p = NULL;
782
783 get_process_comm(packet.v5_packet.pid, &p);
784 log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p));
785 free(p);
786
787 } else
788 log_debug("Got direct mount request for %s", packet.v5_packet.name);
789
790 if (!a->tokens)
791 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) {
792 log_error("Failed to allocate token set.");
793 goto fail;
794 }
795
796 if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) {
797 log_error("Failed to remember token: %s", strerror(-r));
798 goto fail;
799 }
800
801 automount_enter_runnning(a);
802 break;
803
804 default:
805 log_error("Received unknown automount request %i", packet.hdr.type);
806 break;
807 }
808
809 return;
810
811 fail:
812 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
813 }
814
815 static void automount_shutdown(Manager *m) {
816 assert(m);
817
818 if (m->dev_autofs_fd >= 0)
819 close_nointr_nofail(m->dev_autofs_fd);
820 }
821
822 static void automount_reset_failed(Unit *u) {
823 Automount *a = AUTOMOUNT(u);
824
825 assert(a);
826
827 if (a->state == AUTOMOUNT_FAILED)
828 automount_set_state(a, AUTOMOUNT_DEAD);
829
830 a->result = AUTOMOUNT_SUCCESS;
831 }
832
833 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
834 [AUTOMOUNT_DEAD] = "dead",
835 [AUTOMOUNT_WAITING] = "waiting",
836 [AUTOMOUNT_RUNNING] = "running",
837 [AUTOMOUNT_FAILED] = "failed"
838 };
839
840 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
841
842 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
843 [AUTOMOUNT_SUCCESS] = "success",
844 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
845 };
846
847 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
848
849 const UnitVTable automount_vtable = {
850 .suffix = ".automount",
851 .object_size = sizeof(Automount),
852 .sections =
853 "Unit\0"
854 "Automount\0"
855 "Install\0",
856
857 .no_alias = true,
858 .no_instances = true,
859
860 .init = automount_init,
861 .load = automount_load,
862 .done = automount_done,
863
864 .coldplug = automount_coldplug,
865
866 .dump = automount_dump,
867
868 .start = automount_start,
869 .stop = automount_stop,
870
871 .serialize = automount_serialize,
872 .deserialize_item = automount_deserialize_item,
873
874 .active_state = automount_active_state,
875 .sub_state_to_string = automount_sub_state_to_string,
876
877 .check_gc = automount_check_gc,
878
879 .fd_event = automount_fd_event,
880
881 .reset_failed = automount_reset_failed,
882
883 .bus_interface = "org.freedesktop.systemd1.Automount",
884 .bus_message_handler = bus_automount_message_handler,
885 .bus_invalidating_properties = bus_automount_invalidating_properties,
886
887 .shutdown = automount_shutdown
888 };