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