]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/mount.c
core: do not add "what" to RequiresMountsFor for network mounts
[thirdparty/systemd.git] / src / core / mount.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 <stdio.h>
24 #include <mntent.h>
25 #include <sys/epoll.h>
26 #include <signal.h>
27
28 #include "manager.h"
29 #include "unit.h"
30 #include "mount.h"
31 #include "load-fragment.h"
32 #include "load-dropin.h"
33 #include "log.h"
34 #include "sd-messages.h"
35 #include "strv.h"
36 #include "mkdir.h"
37 #include "path-util.h"
38 #include "mount-setup.h"
39 #include "unit-name.h"
40 #include "dbus-mount.h"
41 #include "special.h"
42 #include "bus-errors.h"
43 #include "exit-status.h"
44 #include "def.h"
45
46 static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
47 [MOUNT_DEAD] = UNIT_INACTIVE,
48 [MOUNT_MOUNTING] = UNIT_ACTIVATING,
49 [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
50 [MOUNT_MOUNTED] = UNIT_ACTIVE,
51 [MOUNT_REMOUNTING] = UNIT_RELOADING,
52 [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
53 [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
54 [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
55 [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
56 [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
57 [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
58 [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
59 [MOUNT_FAILED] = UNIT_FAILED
60 };
61
62 static char* mount_test_option(const char *haystack, const char *needle) {
63 struct mntent me = { .mnt_opts = (char*) haystack };
64
65 assert(needle);
66
67 /* Like glibc's hasmntopt(), but works on a string, not a
68 * struct mntent */
69
70 if (!haystack)
71 return NULL;
72
73 return hasmntopt(&me, needle);
74 }
75
76 static bool mount_is_network(MountParameters *p) {
77 assert(p);
78
79 if (mount_test_option(p->options, "_netdev"))
80 return true;
81
82 if (p->fstype && fstype_is_network(p->fstype))
83 return true;
84
85 return false;
86 }
87
88 static bool mount_is_bind(MountParameters *p) {
89 assert(p);
90
91 if (mount_test_option(p->options, "bind"))
92 return true;
93
94 if (p->fstype && streq(p->fstype, "bind"))
95 return true;
96
97 if (mount_test_option(p->options, "rbind"))
98 return true;
99
100 if (p->fstype && streq(p->fstype, "rbind"))
101 return true;
102
103 return false;
104 }
105
106 static bool mount_is_auto(MountParameters *p) {
107 assert(p);
108
109 return !mount_test_option(p->options, "noauto");
110 }
111
112 static bool needs_quota(MountParameters *p) {
113 assert(p);
114
115 if (mount_is_network(p))
116 return false;
117
118 if (mount_is_bind(p))
119 return false;
120
121 return mount_test_option(p->options, "usrquota") ||
122 mount_test_option(p->options, "grpquota") ||
123 mount_test_option(p->options, "quota") ||
124 mount_test_option(p->options, "usrjquota") ||
125 mount_test_option(p->options, "grpjquota");
126 }
127
128 static void mount_init(Unit *u) {
129 Mount *m = MOUNT(u);
130
131 assert(u);
132 assert(u->load_state == UNIT_STUB);
133
134 m->timeout_usec = DEFAULT_TIMEOUT_USEC;
135 m->directory_mode = 0755;
136
137 exec_context_init(&m->exec_context);
138
139 if (unit_has_name(u, "-.mount")) {
140 /* Don't allow start/stop for root directory */
141 UNIT(m)->refuse_manual_start = true;
142 UNIT(m)->refuse_manual_stop = true;
143 } else {
144 /* The stdio/kmsg bridge socket is on /, in order to avoid a
145 * dep loop, don't use kmsg logging for -.mount */
146 m->exec_context.std_output = u->manager->default_std_output;
147 m->exec_context.std_error = u->manager->default_std_error;
148 }
149
150 kill_context_init(&m->kill_context);
151 cgroup_context_init(&m->cgroup_context);
152
153 /* We need to make sure that /bin/mount is always called in
154 * the same process group as us, so that the autofs kernel
155 * side doesn't send us another mount request while we are
156 * already trying to comply its last one. */
157 m->exec_context.same_pgrp = true;
158
159 m->timer_watch.type = WATCH_INVALID;
160
161 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
162
163 UNIT(m)->ignore_on_isolate = true;
164 }
165
166 static void mount_unwatch_control_pid(Mount *m) {
167 assert(m);
168
169 if (m->control_pid <= 0)
170 return;
171
172 unit_unwatch_pid(UNIT(m), m->control_pid);
173 m->control_pid = 0;
174 }
175
176 static void mount_parameters_done(MountParameters *p) {
177 assert(p);
178
179 free(p->what);
180 free(p->options);
181 free(p->fstype);
182
183 p->what = p->options = p->fstype = NULL;
184 }
185
186 static void mount_done(Unit *u) {
187 Mount *m = MOUNT(u);
188
189 assert(m);
190
191 free(m->where);
192 m->where = NULL;
193
194 mount_parameters_done(&m->parameters_proc_self_mountinfo);
195 mount_parameters_done(&m->parameters_fragment);
196
197 cgroup_context_done(&m->cgroup_context);
198 exec_context_done(&m->exec_context, manager_is_reloading_or_reexecuting(u->manager));
199 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
200 m->control_command = NULL;
201
202 mount_unwatch_control_pid(m);
203
204 unit_unwatch_timer(u, &m->timer_watch);
205 }
206
207 _pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
208 assert(m);
209
210 if (m->from_fragment)
211 return &m->parameters_fragment;
212
213 return NULL;
214 }
215
216 _pure_ static MountParameters* get_mount_parameters(Mount *m) {
217 assert(m);
218
219 if (m->from_proc_self_mountinfo)
220 return &m->parameters_proc_self_mountinfo;
221
222 return get_mount_parameters_fragment(m);
223 }
224
225 static int mount_add_mount_links(Mount *m) {
226 _cleanup_free_ char *parent = NULL;
227 MountParameters *pm;
228 Unit *other;
229 Iterator i;
230 Set *s;
231 int r;
232
233 assert(m);
234
235 if (!path_equal(m->where, "/")) {
236 /* Adds in links to other mount points that might lie further
237 * up in the hierarchy */
238 r = path_get_parent(m->where, &parent);
239 if (r < 0)
240 return r;
241
242 r = unit_require_mounts_for(UNIT(m), parent);
243 if (r < 0)
244 return r;
245 }
246
247 /* Adds in links to other mount points that might be needed
248 * for the source path (if this is a bind mount) to be
249 * available. */
250 pm = get_mount_parameters_fragment(m);
251 if (pm && pm->what &&
252 path_is_absolute(pm->what) &&
253 !mount_is_network(pm)) {
254
255 r = unit_require_mounts_for(UNIT(m), pm->what);
256 if (r < 0)
257 return r;
258 }
259
260 /* Adds in links to other units that use this path or paths
261 * further down in the hierarchy */
262 s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
263 SET_FOREACH(other, s, i) {
264
265 if (other->load_state != UNIT_LOADED)
266 continue;
267
268 if (other == UNIT(m))
269 continue;
270
271 r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true);
272 if (r < 0)
273 return r;
274
275 if (UNIT(m)->fragment_path) {
276 /* If we have fragment configuration, then make this dependency required */
277 r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true);
278 if (r < 0)
279 return r;
280 }
281 }
282
283 return 0;
284 }
285
286 static int mount_add_device_links(Mount *m) {
287 MountParameters *p;
288 bool device_wants_mount = false;
289 int r;
290
291 assert(m);
292
293 p = get_mount_parameters_fragment(m);
294 if (!p)
295 return 0;
296
297 if (!p->what)
298 return 0;
299
300 if (mount_is_bind(p))
301 return 0;
302
303 if (!is_device_path(p->what))
304 return 0;
305
306 if (path_equal(m->where, "/"))
307 return 0;
308
309 if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
310 device_wants_mount = true;
311
312 r = unit_add_node_link(UNIT(m), p->what, device_wants_mount);
313 if (r < 0)
314 return r;
315
316 if (p->passno > 0 &&
317 UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
318 char *name;
319 Unit *fsck;
320 /* Let's add in the fsck service */
321
322 /* aka SPECIAL_FSCK_SERVICE */
323 name = unit_name_from_path_instance("systemd-fsck", p->what, ".service");
324 if (!name)
325 return -ENOMEM;
326
327 r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
328 if (r < 0) {
329 log_warning_unit(name,
330 "Failed to prepare unit %s: %s", name, strerror(-r));
331 free(name);
332 return r;
333 }
334 free(name);
335
336 SERVICE(fsck)->fsck_passno = p->passno;
337
338 r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true);
339 if (r < 0)
340 return r;
341 }
342
343 return 0;
344 }
345
346 static int mount_add_quota_links(Mount *m) {
347 int r;
348 MountParameters *p;
349
350 assert(m);
351
352 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
353 return 0;
354
355 p = get_mount_parameters_fragment(m);
356 if (!p)
357 return 0;
358
359 if (!needs_quota(p))
360 return 0;
361
362 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
363 if (r < 0)
364 return r;
365
366 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
367 if (r < 0)
368 return r;
369
370 return 0;
371 }
372
373 static bool should_umount(Mount *m) {
374 MountParameters *p;
375
376 if (path_equal(m->where, "/") ||
377 path_equal(m->where, "/usr"))
378 return false;
379
380 p = get_mount_parameters(m);
381 if (p && mount_test_option(p->options, "x-initrd.mount") &&
382 !in_initrd())
383 return false;
384
385 return true;
386 }
387
388 static int mount_add_default_dependencies(Mount *m) {
389 const char *after, *after2, *online;
390 MountParameters *p;
391 int r;
392
393 assert(m);
394
395 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
396 return 0;
397
398 p = get_mount_parameters(m);
399
400 if (!p)
401 return 0;
402
403 if (path_equal(m->where, "/"))
404 return 0;
405
406 if (mount_is_network(p)) {
407 after = SPECIAL_REMOTE_FS_PRE_TARGET;
408 after2 = SPECIAL_NETWORK_TARGET;
409 online = SPECIAL_NETWORK_ONLINE_TARGET;
410 } else {
411 after = SPECIAL_LOCAL_FS_PRE_TARGET;
412 after2 = NULL;
413 online = NULL;
414 }
415
416 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
417 if (r < 0)
418 return r;
419
420 if (after2) {
421 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
422 if (r < 0)
423 return r;
424 }
425
426 if (online) {
427 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
428 if (r < 0)
429 return r;
430 }
431
432 if (should_umount(m)) {
433 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
434 if (r < 0)
435 return r;
436 }
437
438 return 0;
439 }
440
441 static int mount_fix_timeouts(Mount *m) {
442 MountParameters *p;
443 const char *timeout = NULL;
444 Unit *other;
445 Iterator i;
446 usec_t u;
447 char *t;
448 int r;
449
450 assert(m);
451
452 p = get_mount_parameters_fragment(m);
453 if (!p)
454 return 0;
455
456 /* Allow configuration how long we wait for a device that
457 * backs a mount point to show up. This is useful to support
458 * endless device timeouts for devices that show up only after
459 * user input, like crypto devices. */
460
461 if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
462 timeout += 31;
463 else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
464 timeout += 25;
465 else
466 return 0;
467
468 t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
469 if (!t)
470 return -ENOMEM;
471
472 r = parse_sec(t, &u);
473 free(t);
474
475 if (r < 0) {
476 log_warning_unit(UNIT(m)->id,
477 "Failed to parse timeout for %s, ignoring: %s",
478 m->where, timeout);
479 return r;
480 }
481
482 SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
483 if (other->type != UNIT_DEVICE)
484 continue;
485
486 other->job_timeout = u;
487 }
488
489 return 0;
490 }
491
492 static int mount_verify(Mount *m) {
493 _cleanup_free_ char *e = NULL;
494 bool b;
495
496 assert(m);
497
498 if (UNIT(m)->load_state != UNIT_LOADED)
499 return 0;
500
501 if (!m->from_fragment && !m->from_proc_self_mountinfo)
502 return -ENOENT;
503
504 e = unit_name_from_path(m->where, ".mount");
505 if (!e)
506 return -ENOMEM;
507
508 b = unit_has_name(UNIT(m), e);
509 if (!b) {
510 log_error_unit(UNIT(m)->id,
511 "%s's Where setting doesn't match unit name. Refusing.",
512 UNIT(m)->id);
513 return -EINVAL;
514 }
515
516 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
517 log_error_unit(UNIT(m)->id,
518 "Cannot create mount unit for API file system %s. Refusing.",
519 m->where);
520 return -EINVAL;
521 }
522
523 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
524 log_error_unit(UNIT(m)->id,
525 "%s's What setting is missing. Refusing.", UNIT(m)->id);
526 return -EBADMSG;
527 }
528
529 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
530 log_error_unit(UNIT(m)->id,
531 "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",
532 UNIT(m)->id);
533 return -EINVAL;
534 }
535
536 return 0;
537 }
538
539 static int mount_add_extras(Mount *m) {
540 Unit *u = UNIT(m);
541 int r;
542
543 if (UNIT(m)->fragment_path)
544 m->from_fragment = true;
545
546 if (!m->where) {
547 m->where = unit_name_to_path(u->id);
548 if (!m->where)
549 return -ENOMEM;
550 }
551
552 path_kill_slashes(m->where);
553
554 r = unit_add_exec_dependencies(u, &m->exec_context);
555 if (r < 0)
556 return r;
557
558 if (!UNIT(m)->description) {
559 r = unit_set_description(u, m->where);
560 if (r < 0)
561 return r;
562 }
563
564 r = mount_add_device_links(m);
565 if (r < 0)
566 return r;
567
568 r = mount_add_mount_links(m);
569 if (r < 0)
570 return r;
571
572 r = mount_add_quota_links(m);
573 if (r < 0)
574 return r;
575
576 if (UNIT(m)->default_dependencies) {
577 r = mount_add_default_dependencies(m);
578 if (r < 0)
579 return r;
580 }
581
582 r = unit_add_default_slice(u);
583 if (r < 0)
584 return r;
585
586 r = mount_fix_timeouts(m);
587 if (r < 0)
588 return r;
589
590 return 0;
591 }
592
593 static int mount_load(Unit *u) {
594 Mount *m = MOUNT(u);
595 int r;
596
597 assert(u);
598 assert(u->load_state == UNIT_STUB);
599
600 if (m->from_proc_self_mountinfo)
601 r = unit_load_fragment_and_dropin_optional(u);
602 else
603 r = unit_load_fragment_and_dropin(u);
604
605 if (r < 0)
606 return r;
607
608 /* This is a new unit? Then let's add in some extras */
609 if (u->load_state == UNIT_LOADED) {
610 r = mount_add_extras(m);
611 if (r < 0)
612 return r;
613
614 r = unit_exec_context_defaults(u, &m->exec_context);
615 if (r < 0)
616 return r;
617 }
618
619 return mount_verify(m);
620 }
621
622 static int mount_notify_automount(Mount *m, int status) {
623 Unit *p;
624 int r;
625 Iterator i;
626
627 assert(m);
628
629 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
630 if (p->type == UNIT_AUTOMOUNT) {
631 r = automount_send_ready(AUTOMOUNT(p), status);
632 if (r < 0)
633 return r;
634 }
635
636 return 0;
637 }
638
639 static void mount_set_state(Mount *m, MountState state) {
640 MountState old_state;
641 assert(m);
642
643 old_state = m->state;
644 m->state = state;
645
646 if (state != MOUNT_MOUNTING &&
647 state != MOUNT_MOUNTING_DONE &&
648 state != MOUNT_REMOUNTING &&
649 state != MOUNT_UNMOUNTING &&
650 state != MOUNT_MOUNTING_SIGTERM &&
651 state != MOUNT_MOUNTING_SIGKILL &&
652 state != MOUNT_UNMOUNTING_SIGTERM &&
653 state != MOUNT_UNMOUNTING_SIGKILL &&
654 state != MOUNT_REMOUNTING_SIGTERM &&
655 state != MOUNT_REMOUNTING_SIGKILL) {
656 unit_unwatch_timer(UNIT(m), &m->timer_watch);
657 mount_unwatch_control_pid(m);
658 m->control_command = NULL;
659 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
660 }
661
662 if (state == MOUNT_MOUNTED ||
663 state == MOUNT_REMOUNTING)
664 mount_notify_automount(m, 0);
665 else if (state == MOUNT_DEAD ||
666 state == MOUNT_UNMOUNTING ||
667 state == MOUNT_MOUNTING_SIGTERM ||
668 state == MOUNT_MOUNTING_SIGKILL ||
669 state == MOUNT_REMOUNTING_SIGTERM ||
670 state == MOUNT_REMOUNTING_SIGKILL ||
671 state == MOUNT_UNMOUNTING_SIGTERM ||
672 state == MOUNT_UNMOUNTING_SIGKILL ||
673 state == MOUNT_FAILED) {
674 if (state != old_state)
675 mount_notify_automount(m, -ENODEV);
676 }
677
678 if (state != old_state)
679 log_debug_unit(UNIT(m)->id,
680 "%s changed %s -> %s",
681 UNIT(m)->id,
682 mount_state_to_string(old_state),
683 mount_state_to_string(state));
684
685 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
686 m->reload_result = MOUNT_SUCCESS;
687 }
688
689 static int mount_coldplug(Unit *u) {
690 Mount *m = MOUNT(u);
691 MountState new_state = MOUNT_DEAD;
692 int r;
693
694 assert(m);
695 assert(m->state == MOUNT_DEAD);
696
697 if (m->deserialized_state != m->state)
698 new_state = m->deserialized_state;
699 else if (m->from_proc_self_mountinfo)
700 new_state = MOUNT_MOUNTED;
701
702 if (new_state != m->state) {
703
704 if (new_state == MOUNT_MOUNTING ||
705 new_state == MOUNT_MOUNTING_DONE ||
706 new_state == MOUNT_REMOUNTING ||
707 new_state == MOUNT_UNMOUNTING ||
708 new_state == MOUNT_MOUNTING_SIGTERM ||
709 new_state == MOUNT_MOUNTING_SIGKILL ||
710 new_state == MOUNT_UNMOUNTING_SIGTERM ||
711 new_state == MOUNT_UNMOUNTING_SIGKILL ||
712 new_state == MOUNT_REMOUNTING_SIGTERM ||
713 new_state == MOUNT_REMOUNTING_SIGKILL) {
714
715 if (m->control_pid <= 0)
716 return -EBADMSG;
717
718 r = unit_watch_pid(UNIT(m), m->control_pid);
719 if (r < 0)
720 return r;
721
722 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
723 if (r < 0)
724 return r;
725 }
726
727 mount_set_state(m, new_state);
728 }
729
730 return 0;
731 }
732
733 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
734 Mount *m = MOUNT(u);
735 MountParameters *p;
736
737 assert(m);
738 assert(f);
739
740 p = get_mount_parameters(m);
741
742 fprintf(f,
743 "%sMount State: %s\n"
744 "%sResult: %s\n"
745 "%sWhere: %s\n"
746 "%sWhat: %s\n"
747 "%sFile System Type: %s\n"
748 "%sOptions: %s\n"
749 "%sFrom /proc/self/mountinfo: %s\n"
750 "%sFrom fragment: %s\n"
751 "%sDirectoryMode: %04o\n",
752 prefix, mount_state_to_string(m->state),
753 prefix, mount_result_to_string(m->result),
754 prefix, m->where,
755 prefix, p ? strna(p->what) : "n/a",
756 prefix, p ? strna(p->fstype) : "n/a",
757 prefix, p ? strna(p->options) : "n/a",
758 prefix, yes_no(m->from_proc_self_mountinfo),
759 prefix, yes_no(m->from_fragment),
760 prefix, m->directory_mode);
761
762 if (m->control_pid > 0)
763 fprintf(f,
764 "%sControl PID: %lu\n",
765 prefix, (unsigned long) m->control_pid);
766
767 exec_context_dump(&m->exec_context, f, prefix);
768 kill_context_dump(&m->kill_context, f, prefix);
769 }
770
771 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
772 pid_t pid;
773 int r;
774
775 assert(m);
776 assert(c);
777 assert(_pid);
778
779 unit_realize_cgroup(UNIT(m));
780
781 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
782 if (r < 0)
783 goto fail;
784
785 r = exec_spawn(c,
786 NULL,
787 &m->exec_context,
788 NULL, 0,
789 UNIT(m)->manager->environment,
790 true,
791 true,
792 true,
793 UNIT(m)->manager->confirm_spawn,
794 UNIT(m)->manager->cgroup_supported,
795 UNIT(m)->cgroup_path,
796 UNIT(m)->id,
797 NULL,
798 &pid);
799 if (r < 0)
800 goto fail;
801
802 r = unit_watch_pid(UNIT(m), pid);
803 if (r < 0)
804 /* FIXME: we need to do something here */
805 goto fail;
806
807 *_pid = pid;
808
809 return 0;
810
811 fail:
812 unit_unwatch_timer(UNIT(m), &m->timer_watch);
813
814 return r;
815 }
816
817 static void mount_enter_dead(Mount *m, MountResult f) {
818 assert(m);
819
820 if (f != MOUNT_SUCCESS)
821 m->result = f;
822
823 exec_context_tmp_dirs_done(&m->exec_context);
824 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
825 }
826
827 static void mount_enter_mounted(Mount *m, MountResult f) {
828 assert(m);
829
830 if (f != MOUNT_SUCCESS)
831 m->result = f;
832
833 mount_set_state(m, MOUNT_MOUNTED);
834 }
835
836 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
837 int r;
838
839 assert(m);
840
841 if (f != MOUNT_SUCCESS)
842 m->result = f;
843
844 r = unit_kill_context(
845 UNIT(m),
846 &m->kill_context,
847 state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM,
848 -1,
849 m->control_pid,
850 false);
851 if (r < 0)
852 goto fail;
853
854 if (r > 0) {
855 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
856 if (r < 0)
857 goto fail;
858
859 mount_set_state(m, state);
860 } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
861 mount_enter_mounted(m, MOUNT_SUCCESS);
862 else
863 mount_enter_dead(m, MOUNT_SUCCESS);
864
865 return;
866
867 fail:
868 log_warning_unit(UNIT(m)->id,
869 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
870
871 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
872 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
873 else
874 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
875 }
876
877 void warn_if_dir_nonempty(const char *unit, const char* where) {
878 assert(unit);
879 assert(where);
880
881 if (dir_is_empty(where) > 0)
882 return;
883
884 log_struct_unit(LOG_NOTICE,
885 unit,
886 "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
887 unit, where,
888 "WHERE=%s", where,
889 MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
890 NULL);
891 }
892
893 static void mount_enter_unmounting(Mount *m) {
894 int r;
895
896 assert(m);
897
898 m->control_command_id = MOUNT_EXEC_UNMOUNT;
899 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
900
901 if ((r = exec_command_set(
902 m->control_command,
903 "/bin/umount",
904 m->where,
905 NULL)) < 0)
906 goto fail;
907
908 mount_unwatch_control_pid(m);
909
910 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
911 goto fail;
912
913 mount_set_state(m, MOUNT_UNMOUNTING);
914
915 return;
916
917 fail:
918 log_warning_unit(UNIT(m)->id,
919 "%s failed to run 'umount' task: %s",
920 UNIT(m)->id, strerror(-r));
921 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
922 }
923
924 static void mount_enter_mounting(Mount *m) {
925 int r;
926 MountParameters *p;
927
928 assert(m);
929
930 m->control_command_id = MOUNT_EXEC_MOUNT;
931 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
932
933 mkdir_p_label(m->where, m->directory_mode);
934
935 warn_if_dir_nonempty(m->meta.id, m->where);
936
937 /* Create the source directory for bind-mounts if needed */
938 p = get_mount_parameters_fragment(m);
939 if (p && mount_is_bind(p))
940 mkdir_p_label(p->what, m->directory_mode);
941
942 if (m->from_fragment)
943 r = exec_command_set(
944 m->control_command,
945 "/bin/mount",
946 m->parameters_fragment.what,
947 m->where,
948 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
949 m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
950 NULL);
951 else
952 r = -ENOENT;
953
954 if (r < 0)
955 goto fail;
956
957 mount_unwatch_control_pid(m);
958
959 r = mount_spawn(m, m->control_command, &m->control_pid);
960 if (r < 0)
961 goto fail;
962
963 mount_set_state(m, MOUNT_MOUNTING);
964
965 return;
966
967 fail:
968 log_warning_unit(UNIT(m)->id,
969 "%s failed to run 'mount' task: %s",
970 UNIT(m)->id, strerror(-r));
971 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
972 }
973
974 static void mount_enter_mounting_done(Mount *m) {
975 assert(m);
976
977 mount_set_state(m, MOUNT_MOUNTING_DONE);
978 }
979
980 static void mount_enter_remounting(Mount *m) {
981 int r;
982
983 assert(m);
984
985 m->control_command_id = MOUNT_EXEC_REMOUNT;
986 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
987
988 if (m->from_fragment) {
989 char *buf = NULL;
990 const char *o;
991
992 if (m->parameters_fragment.options) {
993 if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
994 r = -ENOMEM;
995 goto fail;
996 }
997
998 o = buf;
999 } else
1000 o = "remount";
1001
1002 r = exec_command_set(
1003 m->control_command,
1004 "/bin/mount",
1005 m->parameters_fragment.what,
1006 m->where,
1007 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1008 "-o", o,
1009 NULL);
1010
1011 free(buf);
1012 } else
1013 r = -ENOENT;
1014
1015 if (r < 0)
1016 goto fail;
1017
1018 mount_unwatch_control_pid(m);
1019
1020 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
1021 goto fail;
1022
1023 mount_set_state(m, MOUNT_REMOUNTING);
1024
1025 return;
1026
1027 fail:
1028 log_warning_unit(UNIT(m)->id,
1029 "%s failed to run 'remount' task: %s",
1030 UNIT(m)->id, strerror(-r));
1031 m->reload_result = MOUNT_FAILURE_RESOURCES;
1032 mount_enter_mounted(m, MOUNT_SUCCESS);
1033 }
1034
1035 static int mount_start(Unit *u) {
1036 Mount *m = MOUNT(u);
1037
1038 assert(m);
1039
1040 /* We cannot fulfill this request right now, try again later
1041 * please! */
1042 if (m->state == MOUNT_UNMOUNTING ||
1043 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1044 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1045 m->state == MOUNT_MOUNTING_SIGTERM ||
1046 m->state == MOUNT_MOUNTING_SIGKILL)
1047 return -EAGAIN;
1048
1049 /* Already on it! */
1050 if (m->state == MOUNT_MOUNTING)
1051 return 0;
1052
1053 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1054
1055 m->result = MOUNT_SUCCESS;
1056 m->reload_result = MOUNT_SUCCESS;
1057
1058 mount_enter_mounting(m);
1059 return 0;
1060 }
1061
1062 static int mount_stop(Unit *u) {
1063 Mount *m = MOUNT(u);
1064
1065 assert(m);
1066
1067 /* Already on it */
1068 if (m->state == MOUNT_UNMOUNTING ||
1069 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1070 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1071 m->state == MOUNT_MOUNTING_SIGTERM ||
1072 m->state == MOUNT_MOUNTING_SIGKILL)
1073 return 0;
1074
1075 assert(m->state == MOUNT_MOUNTING ||
1076 m->state == MOUNT_MOUNTING_DONE ||
1077 m->state == MOUNT_MOUNTED ||
1078 m->state == MOUNT_REMOUNTING ||
1079 m->state == MOUNT_REMOUNTING_SIGTERM ||
1080 m->state == MOUNT_REMOUNTING_SIGKILL);
1081
1082 mount_enter_unmounting(m);
1083 return 0;
1084 }
1085
1086 static int mount_reload(Unit *u) {
1087 Mount *m = MOUNT(u);
1088
1089 assert(m);
1090
1091 if (m->state == MOUNT_MOUNTING_DONE)
1092 return -EAGAIN;
1093
1094 assert(m->state == MOUNT_MOUNTED);
1095
1096 mount_enter_remounting(m);
1097 return 0;
1098 }
1099
1100 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1101 Mount *m = MOUNT(u);
1102
1103 assert(m);
1104 assert(f);
1105 assert(fds);
1106
1107 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1108 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1109 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1110
1111 if (m->control_pid > 0)
1112 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid);
1113
1114 if (m->control_command_id >= 0)
1115 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1116
1117 exec_context_serialize(&m->exec_context, UNIT(m), f);
1118
1119 return 0;
1120 }
1121
1122 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1123 Mount *m = MOUNT(u);
1124
1125 assert(u);
1126 assert(key);
1127 assert(value);
1128 assert(fds);
1129
1130 if (streq(key, "state")) {
1131 MountState state;
1132
1133 if ((state = mount_state_from_string(value)) < 0)
1134 log_debug_unit(u->id, "Failed to parse state value %s", value);
1135 else
1136 m->deserialized_state = state;
1137 } else if (streq(key, "result")) {
1138 MountResult f;
1139
1140 f = mount_result_from_string(value);
1141 if (f < 0)
1142 log_debug_unit(UNIT(m)->id,
1143 "Failed to parse result value %s", value);
1144 else if (f != MOUNT_SUCCESS)
1145 m->result = f;
1146
1147 } else if (streq(key, "reload-result")) {
1148 MountResult f;
1149
1150 f = mount_result_from_string(value);
1151 if (f < 0)
1152 log_debug_unit(UNIT(m)->id,
1153 "Failed to parse reload result value %s", value);
1154 else if (f != MOUNT_SUCCESS)
1155 m->reload_result = f;
1156
1157 } else if (streq(key, "control-pid")) {
1158 pid_t pid;
1159
1160 if (parse_pid(value, &pid) < 0)
1161 log_debug_unit(UNIT(m)->id,
1162 "Failed to parse control-pid value %s", value);
1163 else
1164 m->control_pid = pid;
1165 } else if (streq(key, "control-command")) {
1166 MountExecCommand id;
1167
1168 if ((id = mount_exec_command_from_string(value)) < 0)
1169 log_debug_unit(UNIT(m)->id,
1170 "Failed to parse exec-command value %s", value);
1171 else {
1172 m->control_command_id = id;
1173 m->control_command = m->exec_command + id;
1174 }
1175 } else if (streq(key, "tmp-dir")) {
1176 char *t;
1177
1178 t = strdup(value);
1179 if (!t)
1180 return log_oom();
1181
1182 m->exec_context.tmp_dir = t;
1183 } else if (streq(key, "var-tmp-dir")) {
1184 char *t;
1185
1186 t = strdup(value);
1187 if (!t)
1188 return log_oom();
1189
1190 m->exec_context.var_tmp_dir = t;
1191 } else
1192 log_debug_unit(UNIT(m)->id,
1193 "Unknown serialization key '%s'", key);
1194
1195 return 0;
1196 }
1197
1198 _pure_ static UnitActiveState mount_active_state(Unit *u) {
1199 assert(u);
1200
1201 return state_translation_table[MOUNT(u)->state];
1202 }
1203
1204 _pure_ static const char *mount_sub_state_to_string(Unit *u) {
1205 assert(u);
1206
1207 return mount_state_to_string(MOUNT(u)->state);
1208 }
1209
1210 _pure_ static bool mount_check_gc(Unit *u) {
1211 Mount *m = MOUNT(u);
1212
1213 assert(m);
1214
1215 return m->from_proc_self_mountinfo;
1216 }
1217
1218 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1219 Mount *m = MOUNT(u);
1220 MountResult f;
1221
1222 assert(m);
1223 assert(pid >= 0);
1224
1225 if (pid != m->control_pid)
1226 return;
1227
1228 m->control_pid = 0;
1229
1230 if (is_clean_exit(code, status, NULL))
1231 f = MOUNT_SUCCESS;
1232 else if (code == CLD_EXITED)
1233 f = MOUNT_FAILURE_EXIT_CODE;
1234 else if (code == CLD_KILLED)
1235 f = MOUNT_FAILURE_SIGNAL;
1236 else if (code == CLD_DUMPED)
1237 f = MOUNT_FAILURE_CORE_DUMP;
1238 else
1239 assert_not_reached("Unknown code");
1240
1241 if (f != MOUNT_SUCCESS)
1242 m->result = f;
1243
1244 if (m->control_command) {
1245 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1246
1247 m->control_command = NULL;
1248 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1249 }
1250
1251 log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
1252 "%s mount process exited, code=%s status=%i",
1253 u->id, sigchld_code_to_string(code), status);
1254
1255 /* Note that mount(8) returning and the kernel sending us a
1256 * mount table change event might happen out-of-order. If an
1257 * operation succeed we assume the kernel will follow soon too
1258 * and already change into the resulting state. If it fails
1259 * we check if the kernel still knows about the mount. and
1260 * change state accordingly. */
1261
1262 switch (m->state) {
1263
1264 case MOUNT_MOUNTING:
1265 case MOUNT_MOUNTING_DONE:
1266 case MOUNT_MOUNTING_SIGKILL:
1267 case MOUNT_MOUNTING_SIGTERM:
1268
1269 if (f == MOUNT_SUCCESS)
1270 mount_enter_mounted(m, f);
1271 else if (m->from_proc_self_mountinfo)
1272 mount_enter_mounted(m, f);
1273 else
1274 mount_enter_dead(m, f);
1275 break;
1276
1277 case MOUNT_REMOUNTING:
1278 case MOUNT_REMOUNTING_SIGKILL:
1279 case MOUNT_REMOUNTING_SIGTERM:
1280
1281 m->reload_result = f;
1282 if (m->from_proc_self_mountinfo)
1283 mount_enter_mounted(m, MOUNT_SUCCESS);
1284 else
1285 mount_enter_dead(m, MOUNT_SUCCESS);
1286
1287 break;
1288
1289 case MOUNT_UNMOUNTING:
1290 case MOUNT_UNMOUNTING_SIGKILL:
1291 case MOUNT_UNMOUNTING_SIGTERM:
1292
1293 if (f == MOUNT_SUCCESS)
1294 mount_enter_dead(m, f);
1295 else if (m->from_proc_self_mountinfo)
1296 mount_enter_mounted(m, f);
1297 else
1298 mount_enter_dead(m, f);
1299 break;
1300
1301 default:
1302 assert_not_reached("Uh, control process died at wrong time.");
1303 }
1304
1305 /* Notify clients about changed exit status */
1306 unit_add_to_dbus_queue(u);
1307 }
1308
1309 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1310 Mount *m = MOUNT(u);
1311
1312 assert(m);
1313 assert(elapsed == 1);
1314 assert(w == &m->timer_watch);
1315
1316 switch (m->state) {
1317
1318 case MOUNT_MOUNTING:
1319 case MOUNT_MOUNTING_DONE:
1320 log_warning_unit(u->id,
1321 "%s mounting timed out. Stopping.", u->id);
1322 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1323 break;
1324
1325 case MOUNT_REMOUNTING:
1326 log_warning_unit(u->id,
1327 "%s remounting timed out. Stopping.", u->id);
1328 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1329 mount_enter_mounted(m, MOUNT_SUCCESS);
1330 break;
1331
1332 case MOUNT_UNMOUNTING:
1333 log_warning_unit(u->id,
1334 "%s unmounting timed out. Stopping.", u->id);
1335 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1336 break;
1337
1338 case MOUNT_MOUNTING_SIGTERM:
1339 if (m->kill_context.send_sigkill) {
1340 log_warning_unit(u->id,
1341 "%s mounting timed out. Killing.", u->id);
1342 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1343 } else {
1344 log_warning_unit(u->id,
1345 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1346 u->id);
1347
1348 if (m->from_proc_self_mountinfo)
1349 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1350 else
1351 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1352 }
1353 break;
1354
1355 case MOUNT_REMOUNTING_SIGTERM:
1356 if (m->kill_context.send_sigkill) {
1357 log_warning_unit(u->id,
1358 "%s remounting timed out. Killing.", u->id);
1359 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1360 } else {
1361 log_warning_unit(u->id,
1362 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1363 u->id);
1364
1365 if (m->from_proc_self_mountinfo)
1366 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1367 else
1368 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1369 }
1370 break;
1371
1372 case MOUNT_UNMOUNTING_SIGTERM:
1373 if (m->kill_context.send_sigkill) {
1374 log_warning_unit(u->id,
1375 "%s unmounting timed out. Killing.", u->id);
1376 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1377 } else {
1378 log_warning_unit(u->id,
1379 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1380 u->id);
1381
1382 if (m->from_proc_self_mountinfo)
1383 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1384 else
1385 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1386 }
1387 break;
1388
1389 case MOUNT_MOUNTING_SIGKILL:
1390 case MOUNT_REMOUNTING_SIGKILL:
1391 case MOUNT_UNMOUNTING_SIGKILL:
1392 log_warning_unit(u->id,
1393 "%s mount process still around after SIGKILL. Ignoring.",
1394 u->id);
1395
1396 if (m->from_proc_self_mountinfo)
1397 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1398 else
1399 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1400 break;
1401
1402 default:
1403 assert_not_reached("Timeout at wrong time.");
1404 }
1405 }
1406
1407 static int mount_add_one(
1408 Manager *m,
1409 const char *what,
1410 const char *where,
1411 const char *options,
1412 const char *fstype,
1413 int passno,
1414 bool set_flags) {
1415 int r;
1416 Unit *u;
1417 bool delete;
1418 char *e, *w = NULL, *o = NULL, *f = NULL;
1419 MountParameters *p;
1420 bool load_extras = false;
1421
1422 assert(m);
1423 assert(what);
1424 assert(where);
1425 assert(options);
1426 assert(fstype);
1427
1428 /* Ignore API mount points. They should never be referenced in
1429 * dependencies ever. */
1430 if (mount_point_is_api(where) || mount_point_ignore(where))
1431 return 0;
1432
1433 if (streq(fstype, "autofs"))
1434 return 0;
1435
1436 /* probably some kind of swap, ignore */
1437 if (!is_path(where))
1438 return 0;
1439
1440 e = unit_name_from_path(where, ".mount");
1441 if (!e)
1442 return -ENOMEM;
1443
1444 u = manager_get_unit(m, e);
1445 if (!u) {
1446 const char* const target =
1447 fstype_is_network(fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
1448
1449 delete = true;
1450
1451 u = unit_new(m, sizeof(Mount));
1452 if (!u) {
1453 free(e);
1454 return -ENOMEM;
1455 }
1456
1457 r = unit_add_name(u, e);
1458 free(e);
1459
1460 if (r < 0)
1461 goto fail;
1462
1463 MOUNT(u)->where = strdup(where);
1464 if (!MOUNT(u)->where) {
1465 r = -ENOMEM;
1466 goto fail;
1467 }
1468
1469 u->source_path = strdup("/proc/self/mountinfo");
1470 if (!u->source_path) {
1471 r = -ENOMEM;
1472 goto fail;
1473 }
1474
1475 r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
1476 if (r < 0)
1477 goto fail;
1478
1479 if (should_umount(MOUNT(u))) {
1480 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1481 if (r < 0)
1482 goto fail;
1483 }
1484
1485 unit_add_to_load_queue(u);
1486 } else {
1487 delete = false;
1488 free(e);
1489
1490 if (!MOUNT(u)->where) {
1491 MOUNT(u)->where = strdup(where);
1492 if (!MOUNT(u)->where) {
1493 r = -ENOMEM;
1494 goto fail;
1495 }
1496 }
1497
1498 if (u->load_state == UNIT_NOT_FOUND) {
1499 u->load_state = UNIT_LOADED;
1500 u->load_error = 0;
1501
1502 /* Load in the extras later on, after we
1503 * finished initialization of the unit */
1504 load_extras = true;
1505 }
1506 }
1507
1508 if (!(w = strdup(what)) ||
1509 !(o = strdup(options)) ||
1510 !(f = strdup(fstype))) {
1511 r = -ENOMEM;
1512 goto fail;
1513 }
1514
1515 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1516 if (set_flags) {
1517 MOUNT(u)->is_mounted = true;
1518 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1519 MOUNT(u)->just_changed = !streq_ptr(p->options, o);
1520 }
1521
1522 MOUNT(u)->from_proc_self_mountinfo = true;
1523
1524 free(p->what);
1525 p->what = w;
1526
1527 free(p->options);
1528 p->options = o;
1529
1530 free(p->fstype);
1531 p->fstype = f;
1532
1533 p->passno = passno;
1534
1535 if (load_extras) {
1536 r = mount_add_extras(MOUNT(u));
1537 if (r < 0)
1538 goto fail;
1539 }
1540
1541 unit_add_to_dbus_queue(u);
1542
1543 return 0;
1544
1545 fail:
1546 free(w);
1547 free(o);
1548 free(f);
1549
1550 if (delete && u)
1551 unit_free(u);
1552
1553 return r;
1554 }
1555
1556 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1557 int r = 0;
1558 unsigned i;
1559
1560 assert(m);
1561
1562 rewind(m->proc_self_mountinfo);
1563
1564 for (i = 1;; i++) {
1565 _cleanup_free_ char *device = NULL, *path = NULL, *options = NULL, *options2 = NULL, *fstype = NULL, *d = NULL, *p = NULL, *o = NULL;
1566 int k;
1567
1568 k = fscanf(m->proc_self_mountinfo,
1569 "%*s " /* (1) mount id */
1570 "%*s " /* (2) parent id */
1571 "%*s " /* (3) major:minor */
1572 "%*s " /* (4) root */
1573 "%ms " /* (5) mount point */
1574 "%ms" /* (6) mount options */
1575 "%*[^-]" /* (7) optional fields */
1576 "- " /* (8) separator */
1577 "%ms " /* (9) file system type */
1578 "%ms" /* (10) mount source */
1579 "%ms" /* (11) mount options 2 */
1580 "%*[^\n]", /* some rubbish at the end */
1581 &path,
1582 &options,
1583 &fstype,
1584 &device,
1585 &options2);
1586
1587 if (k == EOF)
1588 break;
1589
1590 if (k != 5) {
1591 log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
1592 continue;
1593 }
1594
1595 o = strjoin(options, ",", options2, NULL);
1596 if (!o)
1597 return log_oom();
1598
1599 d = cunescape(device);
1600 p = cunescape(path);
1601 if (!d || !p)
1602 return log_oom();
1603
1604 k = mount_add_one(m, d, p, o, fstype, 0, set_flags);
1605 if (k < 0)
1606 r = k;
1607 }
1608
1609 return r;
1610 }
1611
1612 static void mount_shutdown(Manager *m) {
1613 assert(m);
1614
1615 if (m->proc_self_mountinfo) {
1616 fclose(m->proc_self_mountinfo);
1617 m->proc_self_mountinfo = NULL;
1618 }
1619 }
1620
1621 static int mount_enumerate(Manager *m) {
1622 int r;
1623 assert(m);
1624
1625 if (!m->proc_self_mountinfo) {
1626 struct epoll_event ev = {
1627 .events = EPOLLPRI,
1628 .data.ptr = &m->mount_watch,
1629 };
1630
1631 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1632 if (!m->proc_self_mountinfo)
1633 return -errno;
1634
1635 m->mount_watch.type = WATCH_MOUNT;
1636 m->mount_watch.fd = fileno(m->proc_self_mountinfo);
1637
1638 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
1639 return -errno;
1640 }
1641
1642 r = mount_load_proc_self_mountinfo(m, false);
1643 if (r < 0)
1644 goto fail;
1645
1646 return 0;
1647
1648 fail:
1649 mount_shutdown(m);
1650 return r;
1651 }
1652
1653 void mount_fd_event(Manager *m, int events) {
1654 Unit *u;
1655 int r;
1656
1657 assert(m);
1658 assert(events & EPOLLPRI);
1659
1660 /* The manager calls this for every fd event happening on the
1661 * /proc/self/mountinfo file, which informs us about mounting
1662 * table changes */
1663
1664 r = mount_load_proc_self_mountinfo(m, true);
1665 if (r < 0) {
1666 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
1667
1668 /* Reset flags, just in case, for later calls */
1669 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1670 Mount *mount = MOUNT(u);
1671
1672 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1673 }
1674
1675 return;
1676 }
1677
1678 manager_dispatch_load_queue(m);
1679
1680 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1681 Mount *mount = MOUNT(u);
1682
1683 if (!mount->is_mounted) {
1684 /* This has just been unmounted. */
1685
1686 mount->from_proc_self_mountinfo = false;
1687
1688 switch (mount->state) {
1689
1690 case MOUNT_MOUNTED:
1691 mount_enter_dead(mount, MOUNT_SUCCESS);
1692 break;
1693
1694 default:
1695 mount_set_state(mount, mount->state);
1696 break;
1697
1698 }
1699
1700 } else if (mount->just_mounted || mount->just_changed) {
1701
1702 /* New or changed mount entry */
1703
1704 switch (mount->state) {
1705
1706 case MOUNT_DEAD:
1707 case MOUNT_FAILED:
1708 mount_enter_mounted(mount, MOUNT_SUCCESS);
1709 break;
1710
1711 case MOUNT_MOUNTING:
1712 mount_enter_mounting_done(mount);
1713 break;
1714
1715 default:
1716 /* Nothing really changed, but let's
1717 * issue an notification call
1718 * nonetheless, in case somebody is
1719 * waiting for this. (e.g. file system
1720 * ro/rw remounts.) */
1721 mount_set_state(mount, mount->state);
1722 break;
1723 }
1724 }
1725
1726 /* Reset the flags for later calls */
1727 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1728 }
1729 }
1730
1731 static void mount_reset_failed(Unit *u) {
1732 Mount *m = MOUNT(u);
1733
1734 assert(m);
1735
1736 if (m->state == MOUNT_FAILED)
1737 mount_set_state(m, MOUNT_DEAD);
1738
1739 m->result = MOUNT_SUCCESS;
1740 m->reload_result = MOUNT_SUCCESS;
1741 }
1742
1743 static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1744 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
1745 }
1746
1747 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1748 [MOUNT_DEAD] = "dead",
1749 [MOUNT_MOUNTING] = "mounting",
1750 [MOUNT_MOUNTING_DONE] = "mounting-done",
1751 [MOUNT_MOUNTED] = "mounted",
1752 [MOUNT_REMOUNTING] = "remounting",
1753 [MOUNT_UNMOUNTING] = "unmounting",
1754 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1755 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1756 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1757 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1758 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1759 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1760 [MOUNT_FAILED] = "failed"
1761 };
1762
1763 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1764
1765 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1766 [MOUNT_EXEC_MOUNT] = "ExecMount",
1767 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1768 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1769 };
1770
1771 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1772
1773 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1774 [MOUNT_SUCCESS] = "success",
1775 [MOUNT_FAILURE_RESOURCES] = "resources",
1776 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1777 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1778 [MOUNT_FAILURE_SIGNAL] = "signal",
1779 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1780 };
1781
1782 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1783
1784 const UnitVTable mount_vtable = {
1785 .object_size = sizeof(Mount),
1786
1787 .sections =
1788 "Unit\0"
1789 "Mount\0"
1790 "Install\0",
1791
1792 .private_section = "Mount",
1793 .exec_context_offset = offsetof(Mount, exec_context),
1794 .cgroup_context_offset = offsetof(Mount, cgroup_context),
1795
1796 .no_alias = true,
1797 .no_instances = true,
1798
1799 .init = mount_init,
1800 .load = mount_load,
1801 .done = mount_done,
1802
1803 .coldplug = mount_coldplug,
1804
1805 .dump = mount_dump,
1806
1807 .start = mount_start,
1808 .stop = mount_stop,
1809 .reload = mount_reload,
1810
1811 .kill = mount_kill,
1812
1813 .serialize = mount_serialize,
1814 .deserialize_item = mount_deserialize_item,
1815
1816 .active_state = mount_active_state,
1817 .sub_state_to_string = mount_sub_state_to_string,
1818
1819 .check_gc = mount_check_gc,
1820
1821 .sigchld_event = mount_sigchld_event,
1822 .timer_event = mount_timer_event,
1823
1824 .reset_failed = mount_reset_failed,
1825
1826 .bus_interface = "org.freedesktop.systemd1.Mount",
1827 .bus_message_handler = bus_mount_message_handler,
1828 .bus_invalidating_properties = bus_mount_invalidating_properties,
1829 .bus_set_property = bus_mount_set_property,
1830 .bus_commit_properties = bus_mount_commit_properties,
1831
1832 .enumerate = mount_enumerate,
1833 .shutdown = mount_shutdown,
1834
1835 .status_message_formats = {
1836 .starting_stopping = {
1837 [0] = "Mounting %s...",
1838 [1] = "Unmounting %s...",
1839 },
1840 .finished_start_job = {
1841 [JOB_DONE] = "Mounted %s.",
1842 [JOB_FAILED] = "Failed to mount %s.",
1843 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1844 [JOB_TIMEOUT] = "Timed out mounting %s.",
1845 },
1846 .finished_stop_job = {
1847 [JOB_DONE] = "Unmounted %s.",
1848 [JOB_FAILED] = "Failed unmounting %s.",
1849 [JOB_TIMEOUT] = "Timed out unmounting %s.",
1850 },
1851 },
1852 };