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