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