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