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