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