]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/mount.c
build-sys: move source files to subdirectory
[thirdparty/systemd.git] / src / mount.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
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 General Public License as published by
10 the Free Software Foundation; either version 2 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 General Public License for more details.
17
18 You should have received a copy of the GNU 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 "mount-setup.h"
35 #include "unit-name.h"
36 #include "mount.h"
37 #include "dbus-mount.h"
38
39 static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
40 [MOUNT_DEAD] = UNIT_INACTIVE,
41 [MOUNT_MOUNTING] = UNIT_ACTIVATING,
42 [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
43 [MOUNT_MOUNTED] = UNIT_ACTIVE,
44 [MOUNT_REMOUNTING] = UNIT_ACTIVE_RELOADING,
45 [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
46 [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
47 [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
48 [MOUNT_REMOUNTING_SIGTERM] = UNIT_ACTIVE_RELOADING,
49 [MOUNT_REMOUNTING_SIGKILL] = UNIT_ACTIVE_RELOADING,
50 [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
51 [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
52 [MOUNT_MAINTAINANCE] = UNIT_INACTIVE,
53 };
54
55 static void mount_init(Unit *u) {
56 Mount *m = MOUNT(u);
57
58 assert(u);
59 assert(u->meta.load_state == UNIT_STUB);
60
61 m->timeout_usec = DEFAULT_TIMEOUT_USEC;
62 exec_context_init(&m->exec_context);
63
64 /* We need to make sure that /bin/mount is always called in
65 * the same process group as us, so that the autofs kernel
66 * side doesn't send us another mount request while we are
67 * already trying to comply its last one. */
68 m->exec_context.no_setsid = true;
69
70 m->timer_watch.type = WATCH_INVALID;
71
72 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
73 }
74
75 static void mount_unwatch_control_pid(Mount *m) {
76 assert(m);
77
78 if (m->control_pid <= 0)
79 return;
80
81 unit_unwatch_pid(UNIT(m), m->control_pid);
82 m->control_pid = 0;
83 }
84
85 static void mount_parameters_done(MountParameters *p) {
86 assert(p);
87
88 free(p->what);
89 free(p->options);
90 free(p->fstype);
91
92 p->what = p->options = p->fstype = NULL;
93 }
94
95 static void mount_done(Unit *u) {
96 Mount *m = MOUNT(u);
97
98 assert(m);
99
100 free(m->where);
101 m->where = NULL;
102
103 mount_parameters_done(&m->parameters_etc_fstab);
104 mount_parameters_done(&m->parameters_proc_self_mountinfo);
105 mount_parameters_done(&m->parameters_fragment);
106
107 exec_context_done(&m->exec_context);
108 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
109 m->control_command = NULL;
110
111 mount_unwatch_control_pid(m);
112
113 unit_unwatch_timer(u, &m->timer_watch);
114 }
115
116 static int mount_add_mount_links(Mount *m) {
117 Meta *other;
118 int r;
119
120 assert(m);
121
122 /* Adds in links to other mount points that might lie below or
123 * above us in the hierarchy */
124
125 LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_MOUNT]) {
126 Mount *n = (Mount*) other;
127
128 if (n == m)
129 continue;
130
131 if (n->meta.load_state != UNIT_LOADED)
132 continue;
133
134 if (path_startswith(m->where, n->where)) {
135
136 if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
137 return r;
138
139 if (n->from_etc_fstab || n->from_fragment)
140 if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
141 return r;
142
143 } else if (path_startswith(n->where, m->where)) {
144
145 if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(n), true)) < 0)
146 return r;
147
148 if (m->from_etc_fstab || m->from_fragment)
149 if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
150 return r;
151 }
152 }
153
154 return 0;
155 }
156
157 static int mount_add_swap_links(Mount *m) {
158 Meta *other;
159 int r;
160
161 assert(m);
162
163 LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_SWAP])
164 if ((r = swap_add_one_mount_link((Swap*) other, m)) < 0)
165 return r;
166
167 return 0;
168 }
169
170 static int mount_add_automount_links(Mount *m) {
171 Meta *other;
172 int r;
173
174 assert(m);
175
176 LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_AUTOMOUNT])
177 if ((r = automount_add_one_mount_link((Automount*) other, m)) < 0)
178 return r;
179
180 return 0;
181 }
182
183 static int mount_add_socket_links(Mount *m) {
184 Meta *other;
185 int r;
186
187 assert(m);
188
189 LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_SOCKET])
190 if ((r = socket_add_one_mount_link((Socket*) other, m)) < 0)
191 return r;
192
193 return 0;
194 }
195
196 static char* mount_test_option(const char *haystack, const char *needle) {
197 struct mntent me;
198
199 assert(needle);
200
201 /* Like glibc's hasmntopt(), but works on a string, not a
202 * struct mntent */
203
204 if (!haystack)
205 return false;
206
207 zero(me);
208 me.mnt_opts = (char*) haystack;
209
210 return hasmntopt(&me, needle);
211 }
212
213 static int mount_add_target_links(Mount *m) {
214 const char *target;
215 MountParameters *p;
216 Unit *tu;
217 int r;
218 bool noauto, handle, automount;
219
220 assert(m);
221
222 if (m->from_fragment)
223 p = &m->parameters_fragment;
224 else if (m->from_etc_fstab)
225 p = &m->parameters_etc_fstab;
226 else
227 return 0;
228
229 noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO);
230 handle = !!mount_test_option(p->options, "comment=systemd.mount");
231 automount = !!mount_test_option(p->options, "comment=systemd.automount");
232
233 if (mount_test_option(p->options, "_netdev") ||
234 fstype_is_network(p->fstype))
235 target = SPECIAL_REMOTE_FS_TARGET;
236 else
237 target = SPECIAL_LOCAL_FS_TARGET;
238
239 if ((r = manager_load_unit(UNIT(m)->meta.manager, target, NULL, &tu)) < 0)
240 return r;
241
242 if (automount) {
243 Unit *am;
244
245 if ((r = unit_load_related_unit(UNIT(m), ".automount", &am)) < 0)
246 return r;
247
248 if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(am), true)) < 0)
249 return r;
250
251 return unit_add_dependency(UNIT(am), UNIT_BEFORE, tu, true);
252
253 } else {
254
255 if (!noauto && handle)
256 if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0)
257 return r;
258
259 return unit_add_dependency(UNIT(m), UNIT_BEFORE, tu, true);
260 }
261 }
262
263 static int mount_verify(Mount *m) {
264 bool b;
265 char *e;
266 assert(m);
267
268 if (UNIT(m)->meta.load_state != UNIT_LOADED)
269 return 0;
270
271 if (!(e = unit_name_from_path(m->where, ".mount")))
272 return -ENOMEM;
273
274 b = unit_has_name(UNIT(m), e);
275 free(e);
276
277 if (!b) {
278 log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(m)->meta.id);
279 return -EINVAL;
280 }
281
282 if (m->meta.fragment_path && !m->parameters_fragment.what) {
283 log_error("%s's What setting is missing. Refusing.", UNIT(m)->meta.id);
284 return -EBADMSG;
285 }
286
287 return 0;
288 }
289
290 static int mount_load(Unit *u) {
291 Mount *m = MOUNT(u);
292 int r;
293
294 assert(u);
295 assert(u->meta.load_state == UNIT_STUB);
296
297 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
298 return r;
299
300 /* This is a new unit? Then let's add in some extras */
301 if (u->meta.load_state == UNIT_LOADED) {
302 const char *what = NULL;
303
304 if (m->meta.fragment_path)
305 m->from_fragment = true;
306
307 if (!m->where)
308 if (!(m->where = unit_name_to_path(u->meta.id)))
309 return -ENOMEM;
310
311 path_kill_slashes(m->where);
312
313 if (!m->meta.description)
314 if ((r = unit_set_description(u, m->where)) < 0)
315 return r;
316
317 if (m->from_fragment && m->parameters_fragment.what)
318 what = m->parameters_fragment.what;
319 else if (m->from_etc_fstab && m->parameters_etc_fstab.what)
320 what = m->parameters_etc_fstab.what;
321 else if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
322 what = m->parameters_proc_self_mountinfo.what;
323
324 if (what)
325 if ((r = unit_add_node_link(u, what,
326 (u->meta.manager->running_as == MANAGER_INIT ||
327 u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
328 return r;
329
330 if ((r = mount_add_mount_links(m)) < 0)
331 return r;
332
333 if ((r = mount_add_socket_links(m)) < 0)
334 return r;
335
336 if ((r = mount_add_swap_links(m)) < 0)
337 return r;
338
339 if ((r = mount_add_automount_links(m)) < 0)
340 return r;
341
342 if ((r = mount_add_target_links(m)) < 0)
343 return r;
344
345 if ((r = unit_add_default_cgroup(u)) < 0)
346 return r;
347 }
348
349 return mount_verify(m);
350 }
351
352 static int mount_notify_automount(Mount *m, int status) {
353 Unit *p;
354 int r;
355
356 assert(m);
357
358 if ((r = unit_get_related_unit(UNIT(m), ".automount", &p)) < 0)
359 return r == -ENOENT ? 0 : r;
360
361 return automount_send_ready(AUTOMOUNT(p), status);
362 }
363
364 static void mount_set_state(Mount *m, MountState state) {
365 MountState old_state;
366 assert(m);
367
368 old_state = m->state;
369 m->state = state;
370
371 if (state != MOUNT_MOUNTING &&
372 state != MOUNT_MOUNTING_DONE &&
373 state != MOUNT_REMOUNTING &&
374 state != MOUNT_UNMOUNTING &&
375 state != MOUNT_MOUNTING_SIGTERM &&
376 state != MOUNT_MOUNTING_SIGKILL &&
377 state != MOUNT_UNMOUNTING_SIGTERM &&
378 state != MOUNT_UNMOUNTING_SIGKILL &&
379 state != MOUNT_REMOUNTING_SIGTERM &&
380 state != MOUNT_REMOUNTING_SIGKILL) {
381 unit_unwatch_timer(UNIT(m), &m->timer_watch);
382 mount_unwatch_control_pid(m);
383 m->control_command = NULL;
384 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
385 }
386
387 if (state == MOUNT_MOUNTED ||
388 state == MOUNT_REMOUNTING)
389 mount_notify_automount(m, 0);
390 else if (state == MOUNT_DEAD ||
391 state == MOUNT_UNMOUNTING ||
392 state == MOUNT_MOUNTING_SIGTERM ||
393 state == MOUNT_MOUNTING_SIGKILL ||
394 state == MOUNT_REMOUNTING_SIGTERM ||
395 state == MOUNT_REMOUNTING_SIGKILL ||
396 state == MOUNT_UNMOUNTING_SIGTERM ||
397 state == MOUNT_UNMOUNTING_SIGKILL ||
398 state == MOUNT_MAINTAINANCE)
399 mount_notify_automount(m, -ENODEV);
400
401 if (state != old_state)
402 log_debug("%s changed %s -> %s",
403 UNIT(m)->meta.id,
404 mount_state_to_string(old_state),
405 mount_state_to_string(state));
406
407 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state]);
408 }
409
410 static int mount_coldplug(Unit *u) {
411 Mount *m = MOUNT(u);
412 MountState new_state = MOUNT_DEAD;
413 int r;
414
415 assert(m);
416 assert(m->state == MOUNT_DEAD);
417
418 if (m->deserialized_state != m->state)
419 new_state = m->deserialized_state;
420 else if (m->from_proc_self_mountinfo)
421 new_state = MOUNT_MOUNTED;
422
423 if (new_state != m->state) {
424
425 if (new_state == MOUNT_MOUNTING ||
426 new_state == MOUNT_MOUNTING_DONE ||
427 new_state == MOUNT_REMOUNTING ||
428 new_state == MOUNT_UNMOUNTING ||
429 new_state == MOUNT_MOUNTING_SIGTERM ||
430 new_state == MOUNT_MOUNTING_SIGKILL ||
431 new_state == MOUNT_UNMOUNTING_SIGTERM ||
432 new_state == MOUNT_UNMOUNTING_SIGKILL ||
433 new_state == MOUNT_REMOUNTING_SIGTERM ||
434 new_state == MOUNT_REMOUNTING_SIGKILL) {
435
436 if (m->control_pid <= 0)
437 return -EBADMSG;
438
439 if ((r = unit_watch_pid(UNIT(m), m->control_pid)) < 0)
440 return r;
441
442 if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
443 return r;
444 }
445
446 mount_set_state(m, new_state);
447 }
448
449 return 0;
450 }
451
452 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
453 Mount *m = MOUNT(u);
454 MountParameters *p;
455
456 assert(m);
457 assert(f);
458
459 if (m->from_proc_self_mountinfo)
460 p = &m->parameters_proc_self_mountinfo;
461 else if (m->from_fragment)
462 p = &m->parameters_fragment;
463 else
464 p = &m->parameters_etc_fstab;
465
466 fprintf(f,
467 "%sMount State: %s\n"
468 "%sWhere: %s\n"
469 "%sWhat: %s\n"
470 "%sFile System Type: %s\n"
471 "%sOptions: %s\n"
472 "%sFrom /etc/fstab: %s\n"
473 "%sFrom /proc/self/mountinfo: %s\n"
474 "%sFrom fragment: %s\n"
475 "%sKillMode: %s\n",
476 prefix, mount_state_to_string(m->state),
477 prefix, m->where,
478 prefix, strna(p->what),
479 prefix, strna(p->fstype),
480 prefix, strna(p->options),
481 prefix, yes_no(m->from_etc_fstab),
482 prefix, yes_no(m->from_proc_self_mountinfo),
483 prefix, yes_no(m->from_fragment),
484 prefix, kill_mode_to_string(m->kill_mode));
485
486 if (m->control_pid > 0)
487 fprintf(f,
488 "%sControl PID: %llu\n",
489 prefix, (unsigned long long) m->control_pid);
490
491 exec_context_dump(&m->exec_context, f, prefix);
492 }
493
494 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
495 pid_t pid;
496 int r;
497
498 assert(m);
499 assert(c);
500 assert(_pid);
501
502 if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
503 goto fail;
504
505 if ((r = exec_spawn(c,
506 NULL,
507 &m->exec_context,
508 NULL, 0,
509 m->meta.manager->environment,
510 true,
511 true,
512 UNIT(m)->meta.manager->confirm_spawn,
513 UNIT(m)->meta.cgroup_bondings,
514 &pid)) < 0)
515 goto fail;
516
517 if ((r = unit_watch_pid(UNIT(m), pid)) < 0)
518 /* FIXME: we need to do something here */
519 goto fail;
520
521 *_pid = pid;
522
523 return 0;
524
525 fail:
526 unit_unwatch_timer(UNIT(m), &m->timer_watch);
527
528 return r;
529 }
530
531 static void mount_enter_dead(Mount *m, bool success) {
532 assert(m);
533
534 if (!success)
535 m->failure = true;
536
537 mount_set_state(m, m->failure ? MOUNT_MAINTAINANCE : MOUNT_DEAD);
538 }
539
540 static void mount_enter_mounted(Mount *m, bool success) {
541 assert(m);
542
543 if (!success)
544 m->failure = true;
545
546 mount_set_state(m, MOUNT_MOUNTED);
547 }
548
549 static void mount_enter_signal(Mount *m, MountState state, bool success) {
550 int r;
551 bool sent = false;
552
553 assert(m);
554
555 if (!success)
556 m->failure = true;
557
558 if (m->kill_mode != KILL_NONE) {
559 int sig = (state == MOUNT_MOUNTING_SIGTERM ||
560 state == MOUNT_UNMOUNTING_SIGTERM ||
561 state == MOUNT_REMOUNTING_SIGTERM) ? SIGTERM : SIGKILL;
562
563 if (m->kill_mode == KILL_CONTROL_GROUP) {
564
565 if ((r = cgroup_bonding_kill_list(UNIT(m)->meta.cgroup_bondings, sig)) < 0) {
566 if (r != -EAGAIN && r != -ESRCH)
567 goto fail;
568 } else
569 sent = true;
570 }
571
572 if (!sent && m->control_pid > 0)
573 if (kill(m->kill_mode == KILL_PROCESS ? m->control_pid : -m->control_pid, sig) < 0 && errno != ESRCH) {
574 r = -errno;
575 goto fail;
576 }
577 }
578
579 if (sent) {
580 if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
581 goto fail;
582
583 mount_set_state(m, state);
584 } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
585 mount_enter_mounted(m, true);
586 else
587 mount_enter_dead(m, true);
588
589 return;
590
591 fail:
592 log_warning("%s failed to kill processes: %s", UNIT(m)->meta.id, strerror(-r));
593
594 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
595 mount_enter_mounted(m, false);
596 else
597 mount_enter_dead(m, false);
598 }
599
600 static void mount_enter_unmounting(Mount *m, bool success) {
601 int r;
602
603 assert(m);
604
605 if (!success)
606 m->failure = true;
607
608 m->control_command_id = MOUNT_EXEC_UNMOUNT;
609 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
610
611 if ((r = exec_command_set(
612 m->control_command,
613 "/bin/umount",
614 m->where,
615 NULL)) < 0)
616 goto fail;
617
618 mount_unwatch_control_pid(m);
619
620 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
621 goto fail;
622
623 mount_set_state(m, MOUNT_UNMOUNTING);
624
625 return;
626
627 fail:
628 log_warning("%s failed to run umount exectuable: %s", UNIT(m)->meta.id, strerror(-r));
629 mount_enter_mounted(m, false);
630 }
631
632 static void mount_enter_mounting(Mount *m) {
633 int r;
634
635 assert(m);
636
637 m->control_command_id = MOUNT_EXEC_MOUNT;
638 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
639
640 if (m->from_fragment)
641 r = exec_command_set(
642 m->control_command,
643 "/bin/mount",
644 m->parameters_fragment.what,
645 m->where,
646 "-t", m->parameters_fragment.fstype,
647 m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
648 NULL);
649 else if (m->from_etc_fstab)
650 r = exec_command_set(
651 m->control_command,
652 "/bin/mount",
653 m->where,
654 NULL);
655 else
656 r = -ENOENT;
657
658 if (r < 0)
659 goto fail;
660
661 mount_unwatch_control_pid(m);
662
663 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
664 goto fail;
665
666 mount_set_state(m, MOUNT_MOUNTING);
667
668 return;
669
670 fail:
671 log_warning("%s failed to run mount exectuable: %s", UNIT(m)->meta.id, strerror(-r));
672 mount_enter_dead(m, false);
673 }
674
675 static void mount_enter_mounting_done(Mount *m) {
676 assert(m);
677
678 mount_set_state(m, MOUNT_MOUNTING_DONE);
679 }
680
681 static void mount_enter_remounting(Mount *m, bool success) {
682 int r;
683
684 assert(m);
685
686 if (!success)
687 m->failure = true;
688
689 m->control_command_id = MOUNT_EXEC_REMOUNT;
690 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
691
692 if (m->from_fragment) {
693 char *buf = NULL;
694 const char *o;
695
696 if (m->parameters_fragment.options) {
697 if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
698 r = -ENOMEM;
699 goto fail;
700 }
701
702 o = buf;
703 } else
704 o = "remount";
705
706 r = exec_command_set(
707 m->control_command,
708 "/bin/mount",
709 m->parameters_fragment.what,
710 m->where,
711 "-t", m->parameters_fragment.fstype,
712 "-o", o,
713 NULL);
714
715 free(buf);
716 } else if (m->from_etc_fstab)
717 r = exec_command_set(
718 m->control_command,
719 "/bin/mount",
720 m->where,
721 "-o", "remount",
722 NULL);
723 else
724 r = -ENOENT;
725
726 if (r < 0) {
727 r = -ENOMEM;
728 goto fail;
729 }
730
731 mount_unwatch_control_pid(m);
732
733 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
734 goto fail;
735
736 mount_set_state(m, MOUNT_REMOUNTING);
737
738 return;
739
740 fail:
741 mount_enter_mounted(m, false);
742 }
743
744 static int mount_start(Unit *u) {
745 Mount *m = MOUNT(u);
746
747 assert(m);
748
749 /* We cannot fulfill this request right now, try again later
750 * please! */
751 if (m->state == MOUNT_UNMOUNTING ||
752 m->state == MOUNT_UNMOUNTING_SIGTERM ||
753 m->state == MOUNT_UNMOUNTING_SIGKILL)
754 return -EAGAIN;
755
756 /* Already on it! */
757 if (m->state == MOUNT_MOUNTING ||
758 m->state == MOUNT_MOUNTING_SIGTERM ||
759 m->state == MOUNT_MOUNTING_SIGKILL)
760 return 0;
761
762 assert(m->state == MOUNT_DEAD || m->state == MOUNT_MAINTAINANCE);
763
764 m->failure = false;
765 mount_enter_mounting(m);
766 return 0;
767 }
768
769 static int mount_stop(Unit *u) {
770 Mount *m = MOUNT(u);
771
772 assert(m);
773
774 /* Cann't do this right now. */
775 if (m->state == MOUNT_MOUNTING ||
776 m->state == MOUNT_MOUNTING_DONE ||
777 m->state == MOUNT_MOUNTING_SIGTERM ||
778 m->state == MOUNT_MOUNTING_SIGKILL ||
779 m->state == MOUNT_REMOUNTING ||
780 m->state == MOUNT_REMOUNTING_SIGTERM ||
781 m->state == MOUNT_REMOUNTING_SIGKILL)
782 return -EAGAIN;
783
784 /* Already on it */
785 if (m->state == MOUNT_UNMOUNTING ||
786 m->state == MOUNT_UNMOUNTING_SIGKILL ||
787 m->state == MOUNT_UNMOUNTING_SIGTERM)
788 return 0;
789
790 assert(m->state == MOUNT_MOUNTED);
791
792 mount_enter_unmounting(m, true);
793 return 0;
794 }
795
796 static int mount_reload(Unit *u) {
797 Mount *m = MOUNT(u);
798
799 assert(m);
800
801 if (m->state == MOUNT_MOUNTING_DONE)
802 return -EAGAIN;
803
804 assert(m->state == MOUNT_MOUNTED);
805
806 mount_enter_remounting(m, true);
807 return 0;
808 }
809
810 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
811 Mount *m = MOUNT(u);
812
813 assert(m);
814 assert(f);
815 assert(fds);
816
817 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
818 unit_serialize_item(u, f, "failure", yes_no(m->failure));
819
820 if (m->control_pid > 0)
821 unit_serialize_item_format(u, f, "control-pid", "%u", (unsigned) m->control_pid);
822
823 if (m->control_command_id >= 0)
824 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
825
826 return 0;
827 }
828
829 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
830 Mount *m = MOUNT(u);
831 int r;
832
833 assert(u);
834 assert(key);
835 assert(value);
836 assert(fds);
837
838 if (streq(key, "state")) {
839 MountState state;
840
841 if ((state = mount_state_from_string(value)) < 0)
842 log_debug("Failed to parse state value %s", value);
843 else
844 m->deserialized_state = state;
845 } else if (streq(key, "failure")) {
846 int b;
847
848 if ((b = parse_boolean(value)) < 0)
849 log_debug("Failed to parse failure value %s", value);
850 else
851 m->failure = b || m->failure;
852
853 } else if (streq(key, "control-pid")) {
854 unsigned pid;
855
856 if ((r = safe_atou(value, &pid)) < 0 || pid <= 0)
857 log_debug("Failed to parse control-pid value %s", value);
858 else
859 m->control_pid = (pid_t) pid;
860 } else if (streq(key, "control-command")) {
861 MountExecCommand id;
862
863 if ((id = mount_exec_command_from_string(value)) < 0)
864 log_debug("Failed to parse exec-command value %s", value);
865 else {
866 m->control_command_id = id;
867 m->control_command = m->exec_command + id;
868 }
869
870 } else
871 log_debug("Unknown serialization key '%s'", key);
872
873 return 0;
874 }
875
876 static UnitActiveState mount_active_state(Unit *u) {
877 assert(u);
878
879 return state_translation_table[MOUNT(u)->state];
880 }
881
882 static const char *mount_sub_state_to_string(Unit *u) {
883 assert(u);
884
885 return mount_state_to_string(MOUNT(u)->state);
886 }
887
888 static bool mount_check_gc(Unit *u) {
889 Mount *m = MOUNT(u);
890
891 assert(m);
892
893 return m->from_etc_fstab || m->from_proc_self_mountinfo;
894 }
895
896 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
897 Mount *m = MOUNT(u);
898 bool success;
899
900 assert(m);
901 assert(pid >= 0);
902
903 success = is_clean_exit(code, status);
904 m->failure = m->failure || !success;
905
906 assert(m->control_pid == pid);
907 m->control_pid = 0;
908
909 if (m->control_command) {
910 exec_status_fill(&m->control_command->exec_status, pid, code, status);
911 m->control_command = NULL;
912 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
913 }
914
915 log_debug("%s control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
916
917 /* Note that mount(8) returning and the kernel sending us a
918 * mount table change event might happen out-of-order. If an
919 * operation succeed we assume the kernel will follow soon too
920 * and already change into the resulting state. If it fails
921 * we check if the kernel still knows about the mount. and
922 * change state accordingly. */
923
924 switch (m->state) {
925
926 case MOUNT_MOUNTING:
927 case MOUNT_MOUNTING_DONE:
928 case MOUNT_MOUNTING_SIGKILL:
929 case MOUNT_MOUNTING_SIGTERM:
930 case MOUNT_REMOUNTING:
931 case MOUNT_REMOUNTING_SIGKILL:
932 case MOUNT_REMOUNTING_SIGTERM:
933
934 if (success && m->from_proc_self_mountinfo)
935 mount_enter_mounted(m, true);
936 else if (m->from_proc_self_mountinfo)
937 mount_enter_mounted(m, false);
938 else
939 mount_enter_dead(m, false);
940 break;
941
942 case MOUNT_UNMOUNTING:
943 case MOUNT_UNMOUNTING_SIGKILL:
944 case MOUNT_UNMOUNTING_SIGTERM:
945
946 if (success)
947 mount_enter_dead(m, true);
948 else if (m->from_proc_self_mountinfo)
949 mount_enter_mounted(m, false);
950 else
951 mount_enter_dead(m, false);
952 break;
953
954 default:
955 assert_not_reached("Uh, control process died at wrong time.");
956 }
957 }
958
959 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
960 Mount *m = MOUNT(u);
961
962 assert(m);
963 assert(elapsed == 1);
964 assert(w == &m->timer_watch);
965
966 switch (m->state) {
967
968 case MOUNT_MOUNTING:
969 case MOUNT_MOUNTING_DONE:
970 log_warning("%s mounting timed out. Stopping.", u->meta.id);
971 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, false);
972 break;
973
974 case MOUNT_REMOUNTING:
975 log_warning("%s remounting timed out. Stopping.", u->meta.id);
976 mount_enter_signal(m, MOUNT_REMOUNTING_SIGTERM, false);
977 break;
978
979 case MOUNT_UNMOUNTING:
980 log_warning("%s unmounting timed out. Stopping.", u->meta.id);
981 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, false);
982 break;
983
984 case MOUNT_MOUNTING_SIGTERM:
985 log_warning("%s mounting timed out. Killing.", u->meta.id);
986 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
987 break;
988
989 case MOUNT_REMOUNTING_SIGTERM:
990 log_warning("%s remounting timed out. Killing.", u->meta.id);
991 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
992 break;
993
994 case MOUNT_UNMOUNTING_SIGTERM:
995 log_warning("%s unmounting timed out. Killing.", u->meta.id);
996 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
997 break;
998
999 case MOUNT_MOUNTING_SIGKILL:
1000 case MOUNT_REMOUNTING_SIGKILL:
1001 case MOUNT_UNMOUNTING_SIGKILL:
1002 log_warning("%s mount process still around after SIGKILL. Ignoring.", u->meta.id);
1003
1004 if (m->from_proc_self_mountinfo)
1005 mount_enter_mounted(m, false);
1006 else
1007 mount_enter_dead(m, false);
1008 break;
1009
1010 default:
1011 assert_not_reached("Timeout at wrong time.");
1012 }
1013 }
1014
1015 static int mount_add_one(
1016 Manager *m,
1017 const char *what,
1018 const char *where,
1019 const char *options,
1020 const char *fstype,
1021 bool from_proc_self_mountinfo,
1022 bool set_flags) {
1023 int r;
1024 Unit *u;
1025 bool delete;
1026 char *e, *w = NULL, *o = NULL, *f = NULL;
1027 MountParameters *p;
1028
1029 assert(m);
1030 assert(what);
1031 assert(where);
1032 assert(options);
1033 assert(fstype);
1034
1035 assert(!set_flags || from_proc_self_mountinfo);
1036
1037 /* Ignore API mount points. They should never be referenced in
1038 * dependencies ever. */
1039 if (mount_point_is_api(where))
1040 return 0;
1041
1042 if (streq(fstype, "autofs"))
1043 return 0;
1044
1045 /* probably some kind of swap, ignore */
1046 if (!is_path(where))
1047 return 0;
1048
1049 if (!(e = unit_name_from_path(where, ".mount")))
1050 return -ENOMEM;
1051
1052 if (!(u = manager_get_unit(m, e))) {
1053 delete = true;
1054
1055 if (!(u = unit_new(m))) {
1056 free(e);
1057 return -ENOMEM;
1058 }
1059
1060 r = unit_add_name(u, e);
1061 free(e);
1062
1063 if (r < 0)
1064 goto fail;
1065
1066 if (!(MOUNT(u)->where = strdup(where))) {
1067 r = -ENOMEM;
1068 goto fail;
1069 }
1070
1071 unit_add_to_load_queue(u);
1072 } else {
1073 delete = false;
1074 free(e);
1075 }
1076
1077 if (!(w = strdup(what)) ||
1078 !(o = strdup(options)) ||
1079 !(f = strdup(fstype))) {
1080 r = -ENOMEM;
1081 goto fail;
1082 }
1083
1084 if (from_proc_self_mountinfo) {
1085 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1086
1087 if (set_flags) {
1088 MOUNT(u)->is_mounted = true;
1089 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1090 MOUNT(u)->just_changed = !streq_ptr(p->options, o);
1091 }
1092
1093 MOUNT(u)->from_proc_self_mountinfo = true;
1094 } else {
1095 p = &MOUNT(u)->parameters_etc_fstab;
1096 MOUNT(u)->from_etc_fstab = true;
1097 }
1098
1099 free(p->what);
1100 p->what = w;
1101
1102 free(p->options);
1103 p->options = o;
1104
1105 free(p->fstype);
1106 p->fstype = f;
1107
1108 unit_add_to_dbus_queue(u);
1109
1110 return 0;
1111
1112 fail:
1113 free(w);
1114 free(o);
1115 free(f);
1116
1117 if (delete && u)
1118 unit_free(u);
1119
1120 return r;
1121 }
1122
1123 static char *fstab_node_to_udev_node(char *p) {
1124 char *dn, *t;
1125 int r;
1126
1127 /* FIXME: to follow udev's logic 100% we need to leave valid
1128 * UTF8 chars unescaped */
1129
1130 if (startswith(p, "LABEL=")) {
1131
1132 if (!(t = xescape(p+6, "/ ")))
1133 return NULL;
1134
1135 r = asprintf(&dn, "/dev/disk/by-label/%s", t);
1136 free(t);
1137
1138 if (r < 0)
1139 return NULL;
1140
1141 return dn;
1142 }
1143
1144 if (startswith(p, "UUID=")) {
1145
1146 if (!(t = xescape(p+5, "/ ")))
1147 return NULL;
1148
1149 r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(t));
1150 free(t);
1151
1152 if (r < 0)
1153 return NULL;
1154
1155 return dn;
1156 }
1157
1158 return strdup(p);
1159 }
1160
1161 static int mount_find_pri(char *options) {
1162 char *end, *pri;
1163 unsigned long r;
1164
1165 if (!(pri = mount_test_option(options, "pri=")))
1166 return 0;
1167
1168 pri += 4;
1169
1170 errno = 0;
1171 r = strtoul(pri, &end, 10);
1172
1173 if (errno != 0)
1174 return -errno;
1175
1176 if (end == pri || (*end != ',' && *end != 0))
1177 return -EINVAL;
1178
1179 return (int) r;
1180 }
1181
1182 static int mount_load_etc_fstab(Manager *m) {
1183 FILE *f;
1184 int r;
1185 struct mntent* me;
1186
1187 assert(m);
1188
1189 errno = 0;
1190 if (!(f = setmntent("/etc/fstab", "r")))
1191 return -errno;
1192
1193 while ((me = getmntent(f))) {
1194 char *where, *what;
1195
1196 if (!(what = fstab_node_to_udev_node(me->mnt_fsname))) {
1197 r = -ENOMEM;
1198 goto finish;
1199 }
1200
1201 if (!(where = strdup(me->mnt_dir))) {
1202 free(what);
1203 r = -ENOMEM;
1204 goto finish;
1205 }
1206
1207 if (what[0] == '/')
1208 path_kill_slashes(what);
1209
1210 if (where[0] == '/')
1211 path_kill_slashes(where);
1212
1213 if (streq(me->mnt_type, "swap")) {
1214 int pri;
1215
1216 if ((pri = mount_find_pri(me->mnt_opts)) < 0)
1217 r = pri;
1218 else
1219 r = swap_add_one(m,
1220 what,
1221 pri,
1222 !!mount_test_option(me->mnt_opts, MNTOPT_NOAUTO),
1223 !!mount_test_option(me->mnt_opts, "comment=systemd.swapon"),
1224 false);
1225 } else
1226 r = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, false, false);
1227
1228 free(what);
1229 free(where);
1230
1231 if (r < 0)
1232 goto finish;
1233 }
1234
1235 r = 0;
1236 finish:
1237
1238 endmntent(f);
1239 return r;
1240 }
1241
1242 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1243 int r;
1244 char *device, *path, *options, *fstype, *d, *p;
1245
1246 assert(m);
1247
1248 rewind(m->proc_self_mountinfo);
1249
1250 for (;;) {
1251 int k;
1252
1253 device = path = options = fstype = d = p = NULL;
1254
1255 if ((k = fscanf(m->proc_self_mountinfo,
1256 "%*s " /* (1) mount id */
1257 "%*s " /* (2) parent id */
1258 "%*s " /* (3) major:minor */
1259 "%*s " /* (4) root */
1260 "%ms " /* (5) mount point */
1261 "%ms" /* (6) mount options */
1262 "%*[^-]" /* (7) optional fields */
1263 "- " /* (8) seperator */
1264 "%ms " /* (9) file system type */
1265 "%ms" /* (10) mount source */
1266 "%*[^\n]", /* some rubbish at the end */
1267 &path,
1268 &options,
1269 &fstype,
1270 &device)) != 4) {
1271
1272 if (k == EOF)
1273 break;
1274
1275 r = -EBADMSG;
1276 goto finish;
1277 }
1278
1279 if (!(d = cunescape(device)) ||
1280 !(p = cunescape(path))) {
1281 r = -ENOMEM;
1282 goto finish;
1283 }
1284
1285 if ((r = mount_add_one(m, d, p, options, fstype, true, set_flags)) < 0)
1286 goto finish;
1287
1288 free(device);
1289 free(path);
1290 free(options);
1291 free(fstype);
1292 free(d);
1293 free(p);
1294 }
1295
1296 r = 0;
1297
1298 finish:
1299 free(device);
1300 free(path);
1301 free(options);
1302 free(fstype);
1303 free(d);
1304 free(p);
1305
1306 return r;
1307 }
1308
1309 static void mount_shutdown(Manager *m) {
1310 assert(m);
1311
1312 if (m->proc_self_mountinfo) {
1313 fclose(m->proc_self_mountinfo);
1314 m->proc_self_mountinfo = NULL;
1315 }
1316 }
1317
1318 static int mount_enumerate(Manager *m) {
1319 int r;
1320 struct epoll_event ev;
1321 assert(m);
1322
1323 if (!m->proc_self_mountinfo) {
1324 if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
1325 return -errno;
1326
1327 m->mount_watch.type = WATCH_MOUNT;
1328 m->mount_watch.fd = fileno(m->proc_self_mountinfo);
1329
1330 zero(ev);
1331 ev.events = EPOLLERR;
1332 ev.data.ptr = &m->mount_watch;
1333
1334 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
1335 return -errno;
1336 }
1337
1338 if ((r = mount_load_etc_fstab(m)) < 0)
1339 goto fail;
1340
1341 if ((r = mount_load_proc_self_mountinfo(m, false)) < 0)
1342 goto fail;
1343
1344 return 0;
1345
1346 fail:
1347 mount_shutdown(m);
1348 return r;
1349 }
1350
1351 void mount_fd_event(Manager *m, int events) {
1352 Meta *meta;
1353 int r;
1354
1355 assert(m);
1356 assert(events == EPOLLERR);
1357
1358 /* The manager calls this for every fd event happening on the
1359 * /proc/self/mountinfo file, which informs us about mounting
1360 * table changes */
1361
1362 if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) {
1363 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(errno));
1364
1365 /* Reset flags, just in case, for later calls */
1366 LIST_FOREACH(units_per_type, meta, m->units_per_type[UNIT_MOUNT]) {
1367 Mount *mount = (Mount*) meta;
1368
1369 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1370 }
1371
1372 return;
1373 }
1374
1375 manager_dispatch_load_queue(m);
1376
1377 LIST_FOREACH(units_per_type, meta, m->units_per_type[UNIT_MOUNT]) {
1378 Mount *mount = (Mount*) meta;
1379
1380 if (!mount->is_mounted) {
1381 /* This has just been unmounted. */
1382
1383 mount->from_proc_self_mountinfo = false;
1384
1385 switch (mount->state) {
1386
1387 case MOUNT_MOUNTED:
1388 mount_enter_dead(mount, true);
1389 break;
1390
1391 default:
1392 mount_set_state(mount, mount->state);
1393 break;
1394
1395 }
1396
1397 } else if (mount->just_mounted || mount->just_changed) {
1398
1399 /* New or changed entrymount */
1400
1401 switch (mount->state) {
1402
1403 case MOUNT_DEAD:
1404 case MOUNT_MAINTAINANCE:
1405 mount_enter_mounted(mount, true);
1406 break;
1407
1408 case MOUNT_MOUNTING:
1409 mount_enter_mounting_done(mount);
1410 break;
1411
1412 default:
1413 /* Nothing really changed, but let's
1414 * issue an notification call
1415 * nonetheless, in case somebody is
1416 * waiting for this. (e.g. file system
1417 * ro/rw remounts.) */
1418 mount_set_state(mount, mount->state);
1419 break;
1420 }
1421 }
1422
1423 /* Reset the flags for later calls */
1424 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1425 }
1426 }
1427
1428 int mount_path_is_mounted(Manager *m, const char* path) {
1429 char *t;
1430 int r;
1431
1432 assert(m);
1433 assert(path);
1434
1435 if (path[0] != '/')
1436 return 1;
1437
1438 if (!(t = strdup(path)))
1439 return -ENOMEM;
1440
1441 path_kill_slashes(t);
1442
1443 for (;;) {
1444 char *e, *slash;
1445 Unit *u;
1446
1447 if (!(e = unit_name_from_path(t, ".mount"))) {
1448 r = -ENOMEM;
1449 goto finish;
1450 }
1451
1452 u = manager_get_unit(m, e);
1453 free(e);
1454
1455 if (u &&
1456 (MOUNT(u)->from_etc_fstab || MOUNT(u)->from_fragment) &&
1457 MOUNT(u)->state != MOUNT_MOUNTED) {
1458 r = 0;
1459 goto finish;
1460 }
1461
1462 assert_se(slash = strrchr(t, '/'));
1463
1464 if (slash == t) {
1465 r = 1;
1466 goto finish;
1467 }
1468
1469 *slash = 0;
1470 }
1471
1472 r = 1;
1473
1474 finish:
1475 free(t);
1476 return r;
1477 }
1478
1479 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1480 [MOUNT_DEAD] = "dead",
1481 [MOUNT_MOUNTING] = "mounting",
1482 [MOUNT_MOUNTING_DONE] = "mounting-done",
1483 [MOUNT_MOUNTED] = "mounted",
1484 [MOUNT_REMOUNTING] = "remounting",
1485 [MOUNT_UNMOUNTING] = "unmounting",
1486 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1487 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1488 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1489 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1490 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1491 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1492 [MOUNT_MAINTAINANCE] = "maintainance"
1493 };
1494
1495 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1496
1497 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1498 [MOUNT_EXEC_MOUNT] = "ExecMount",
1499 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1500 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1501 };
1502
1503 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1504
1505 const UnitVTable mount_vtable = {
1506 .suffix = ".mount",
1507
1508 .no_alias = true,
1509 .no_instances = true,
1510 .no_isolate = true,
1511
1512 .init = mount_init,
1513 .load = mount_load,
1514 .done = mount_done,
1515
1516 .coldplug = mount_coldplug,
1517
1518 .dump = mount_dump,
1519
1520 .start = mount_start,
1521 .stop = mount_stop,
1522 .reload = mount_reload,
1523
1524 .serialize = mount_serialize,
1525 .deserialize_item = mount_deserialize_item,
1526
1527 .active_state = mount_active_state,
1528 .sub_state_to_string = mount_sub_state_to_string,
1529
1530 .check_gc = mount_check_gc,
1531
1532 .sigchld_event = mount_sigchld_event,
1533 .timer_event = mount_timer_event,
1534
1535 .bus_message_handler = bus_mount_message_handler,
1536
1537 .enumerate = mount_enumerate,
1538 .shutdown = mount_shutdown
1539 };