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