summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-09-28 01:03:19 +0200
committerLennart Poettering <lennart@poettering.net>2010-09-28 01:03:19 +0200
commit5c78d8e24289e8a88e355345192f6a416c1ebfc3 (patch)
tree5b4499992dca17747878cf619ccaae3dabeb8627
parentcaca31b57621d4c5632e1fbf9ffa4259f05a13e5 (diff)
mount: properly handle bind mounts
-rw-r--r--fixme2
-rw-r--r--src/mount.c51
2 files changed, 50 insertions, 3 deletions
diff --git a/fixme b/fixme
index f11d0e0156..68a64890e2 100644
--- a/fixme
+++ b/fixme
@@ -89,8 +89,6 @@
* ask-password tty timeout
-* properly handle bind mounts in /etc/fstab
-
* readahead() vs. fadvise() vs. ioprio
* properly handle multiple inotify events per read() in path.c and util.c
diff --git a/src/mount.c b/src/mount.c
index 64c6790943..3c08baf5cb 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -118,14 +118,23 @@ static void mount_done(Unit *u) {
static int mount_add_mount_links(Mount *m) {
Meta *other;
int r;
+ MountParameters *pm;
assert(m);
+ if (m->from_fragment)
+ pm = &m->parameters_fragment;
+ else if (m->from_etc_fstab)
+ pm = &m->parameters_etc_fstab;
+ else
+ pm = NULL;
+
/* Adds in links to other mount points that might lie below or
* above us in the hierarchy */
LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_MOUNT]) {
Mount *n = (Mount*) other;
+ MountParameters *pn;
if (n == m)
continue;
@@ -133,6 +142,13 @@ static int mount_add_mount_links(Mount *m) {
if (n->meta.load_state != UNIT_LOADED)
continue;
+ if (n->from_fragment)
+ pn = &n->parameters_fragment;
+ else if (n->from_etc_fstab)
+ pn = &n->parameters_etc_fstab;
+ else
+ pn = NULL;
+
if (path_startswith(m->where, n->where)) {
if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
@@ -144,12 +160,30 @@ static int mount_add_mount_links(Mount *m) {
} else if (path_startswith(n->where, m->where)) {
- if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(n), true)) < 0)
+ if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
return r;
if (m->from_etc_fstab || m->from_fragment)
if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
return r;
+
+ } else if (pm && path_startswith(pm->what, n->where)) {
+
+ if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
+ return r;
+
+ if (m->from_etc_fstab || m->from_fragment)
+ if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
+ return r;
+
+ } else if (pn && path_startswith(pn->what, m->where)) {
+
+ if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
+ return r;
+
+ if (n->from_etc_fstab || n->from_fragment)
+ if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
}
}
@@ -278,6 +312,18 @@ static int mount_add_target_links(Mount *m) {
}
}
+static bool mount_is_bind(MountParameters *p) {
+ assert(p);
+
+ if (p->fstype && streq(p->fstype, "bind"))
+ return true;
+
+ if (mount_test_option(p->options, "bind"))
+ return true;
+
+ return false;
+}
+
static int mount_add_device_links(Mount *m) {
MountParameters *p;
bool nofail, noauto;
@@ -294,6 +340,9 @@ static int mount_add_device_links(Mount *m) {
if (!p->what || path_equal(m->where, "/"))
return 0;
+ if (mount_is_bind(p))
+ return 0;
+
noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO);
nofail = !!mount_test_option(p->options, "nofail");