chiark / gitweb /
mount: Don't stop the mountinfo parser if one line can't be read
[elogind.git] / src / mount.c
index 64c67909437c2d36752d93533d1ee7c5860203ca..dcf0a434744483a6a9944a22a7347c711c646d0d 100644 (file)
@@ -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;
                 }
         }
 
@@ -226,7 +260,7 @@ static char* mount_test_option(const char *haystack, const char *needle) {
 }
 
 static int mount_add_target_links(Mount *m) {
-        const char *target;
+        const char *target, *after = NULL;
         MountParameters *p;
         Unit *tu;
         int r;
@@ -248,14 +282,21 @@ static int mount_add_target_links(Mount *m) {
         automount = !!mount_test_option(p->options, "comment=systemd.automount");
 
         if (mount_test_option(p->options, "_netdev") ||
-            fstype_is_network(p->fstype))
+            fstype_is_network(p->fstype)) {
                 target = SPECIAL_REMOTE_FS_TARGET;
-        else
+
+                if (m->meta.manager->running_as == MANAGER_SYSTEM)
+                        after = SPECIAL_NETWORK_TARGET;
+        } else
                 target = SPECIAL_LOCAL_FS_TARGET;
 
         if ((r = manager_load_unit(m->meta.manager, target, NULL, NULL, &tu)) < 0)
                 return r;
 
+        if (after)
+                if ((r = unit_add_dependency_by_name(tu, UNIT_AFTER, after, NULL, true)) < 0)
+                        return r;
+
         if (automount && m->meta.manager->running_as == MANAGER_SYSTEM) {
                 Unit *am;
 
@@ -278,6 +319,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 +347,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");
 
@@ -1352,13 +1408,14 @@ finish:
 
 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
         int r;
+        unsigned i;
         char *device, *path, *options, *options2, *fstype, *d, *p, *o;
 
         assert(m);
 
         rewind(m->proc_self_mountinfo);
 
-        for (;;) {
+        for (i = 1;; i++) {
                 int k;
 
                 device = path = options = options2 = fstype = d = p = o = NULL;
@@ -1371,7 +1428,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
                                 "%ms "       /* (5) mount point */
                                 "%ms"        /* (6) mount options */
                                 "%*[^-]"     /* (7) optional fields */
-                                "- "         /* (8) seperator */
+                                "- "         /* (8) separator */
                                 "%ms "       /* (9) file system type */
                                 "%ms"        /* (10) mount source */
                                 "%ms"        /* (11) mount options 2 */
@@ -1385,8 +1442,8 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
                         if (k == EOF)
                                 break;
 
-                        r = -EBADMSG;
-                        goto finish;
+                        log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
+                        goto clean_up;
                 }
 
                 if (asprintf(&o, "%s,%s", options, options2) < 0) {
@@ -1403,6 +1460,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
                 if ((r = mount_add_one(m, d, p, o, fstype, true, set_flags)) < 0)
                         goto finish;
 
+clean_up:
                 free(device);
                 free(path);
                 free(options);