[systemd-commits] 10 commits - configure.ac Makefile.am README src/core src/udev .travis.yml

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Fri Nov 28 11:39:57 PST 2014


 .travis.yml             |    2 
 Makefile.am             |    4 -
 README                  |    1 
 configure.ac            |   10 +++
 src/core/manager.c      |    2 
 src/core/manager.h      |    2 
 src/core/mount.c        |  154 +++++++++++++++++++++++++++++++++---------------
 src/udev/udevadm-hwdb.c |    4 +
 8 files changed, 130 insertions(+), 49 deletions(-)

New commits:
commit 36afca67b67984520c5c9a6ce14af51a68c7c8cf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Nov 27 15:19:44 2014 +1000

    udevadm hwdb: discard extra leading whitespaces in hwdb
    
    Currently a property in the form of
      FOO=bar
    is stored as " FOO=bar", i.e. the property name contains a leading space.
    That's quite hard to spot.
    
    This patch discards all extra whitespaces but the first one which is required
    by libudev's hwdb_add_property.
    
    [zj: modify the check a bit]
    
    https://bugs.freedesktop.org/show_bug.cgi?id=82311

diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index fa137c1..a5870d1 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -428,6 +428,10 @@ static int insert_data(struct trie *trie, struct udev_list *match_list,
         value[0] = '\0';
         value++;
 
+        /* libudev requires properties to start with a space */
+        while (isblank(line[0]) && isblank(line[1]))
+                line++;
+
         if (line[0] == '\0' || value[0] == '\0') {
                 log_error("Error, empty key or value '%s' in '%s':", line, filename);
                 return -EINVAL;

commit e6a7b9f45553fe0f73ba1f6134f4829b1d519658
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Nov 28 14:22:47 2014 -0500

    mount: constify MountParameters

diff --git a/src/core/mount.c b/src/core/mount.c
index fc160b6..812d57d 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -74,13 +74,13 @@ static bool mount_needs_network(const char *options, const char *fstype) {
         return false;
 }
 
-static bool mount_is_network(MountParameters *p) {
+static bool mount_is_network(const MountParameters *p) {
         assert(p);
 
         return mount_needs_network(p->options, p->fstype);
 }
 
-static bool mount_is_bind(MountParameters *p) {
+static bool mount_is_bind(const MountParameters *p) {
         assert(p);
 
         if (mount_test_option(p->options, "bind"))
@@ -98,13 +98,13 @@ static bool mount_is_bind(MountParameters *p) {
         return false;
 }
 
-static bool mount_is_auto(MountParameters *p) {
+static bool mount_is_auto(const MountParameters *p) {
         assert(p);
 
         return !mount_test_option(p->options, "noauto");
 }
 
-static bool needs_quota(MountParameters *p) {
+static bool needs_quota(const MountParameters *p) {
         assert(p);
 
         if (mount_is_network(p))

commit fddf1a3189aa6e2ea641e0a9f995344c14e8d1e0
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Nov 28 14:19:03 2014 -0500

    mount: deal with inotify queue overflow
    
    Overflow is very unlikely, since we are watching a privileged directory,
    but could be triggered if thousands of mounts are suddently executed.

diff --git a/src/core/mount.c b/src/core/mount.c
index 61bc3e3..fc160b6 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1662,8 +1662,8 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
 
         /* The manager calls this for every fd event happening on the
          * /proc/self/mountinfo file, which informs us about mounting
-         * table changes
-         * This may also be called for /run/mount events */
+         * table changes, and for /run/mount events which we watch
+         * for mount options. */
 
         if (fd == m->utab_inotify_fd) {
                 char inotify_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
@@ -1671,18 +1671,18 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
                 char *p;
                 int rescan = 0;
 
-                while ((r = read(fd, inotify_buffer, sizeof(inotify_buffer))) > 0) {
+                while ((r = read(fd, inotify_buffer, sizeof(inotify_buffer))) > 0)
                         for (p = inotify_buffer; p < inotify_buffer + r; ) {
                                 event = (struct inotify_event *) p;
                                 /* only care about changes to utab, but we have
                                  * to monitor the directory to reliably get
                                  * notifications about when utab is replaced
                                  * using rename(2) */
-                                if (strcmp(event->name, "utab") == 0)
+                                if ((event->mask & IN_Q_OVERFLOW) || streq(event->name, "utab"))
                                         rescan = 1;
                                 p += sizeof(struct inotify_event) + event->len;
                         }
-                }
+
                 if (!rescan)
                         return 0;
         }

commit 90598531b0bb79626ae5471f7c7c9e82954050c9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Nov 28 13:43:09 2014 -0500

    mount: create directory before adding watches on it

diff --git a/src/core/mount.c b/src/core/mount.c
index 679d15c..61bc3e3 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1624,6 +1624,8 @@ static int mount_enumerate(Manager *m) {
                 if (m->utab_inotify_fd < 0)
                         goto fail_with_errno;
 
+                (void) mkdir_p_label("/run/mount", 0755);
+
                 r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
                 if (r < 0)
                         goto fail_with_errno;

commit 5cca8defd2717669c69d13c479c0885af5b534bd
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Nov 28 13:02:15 2014 -0500

    mount: be more careful about errors when parsing mtab
    
    Fixup for 4a3a9ef610.

diff --git a/src/core/mount.c b/src/core/mount.c
index bccf6c5..679d15c 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1535,15 +1535,22 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
         if (!tb || !itr)
                 return log_oom();
 
-        mnt_table_parse_mtab(tb, NULL);
-        if (r)
+        r = mnt_table_parse_mtab(tb, NULL);
+        if (r < 0)
                 return r;
 
-        while (mnt_table_next_fs(tb, itr, &fs) == 0) {
+        r = 0;
+        for (;;) {
                 const char *device, *path, *options, *fstype;
                 _cleanup_free_ const char *d = NULL, *p = NULL;
                 int k;
 
+                k = mnt_table_next_fs(tb, itr, &fs);
+                if (k == 1)
+                        break;
+                else if (k < 0)
+                        return log_error_errno(k, "Failed to get next entry from /etc/fstab: %m");
+
                 device = mnt_fs_get_source(fs);
                 path = mnt_fs_get_target(fs);
                 options = mnt_fs_get_options(fs);
@@ -1555,7 +1562,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
                         return log_oom();
 
                 k = mount_add_one(m, d, p, options, fstype, set_flags);
-                if (k < 0)
+                if (r == 0 && k < 0)
                         r = k;
         }
 

commit 9d05dd2e1ef814a714214004f927ce82c9890fa6
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Nov 28 01:50:05 2014 -0500

    mount: simplify mount_needs_network check

diff --git a/src/core/mount.c b/src/core/mount.c
index 5f2de64..bccf6c5 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1441,17 +1441,13 @@ static int mount_add_one(
                         }
                 }
 
-                if (m->running_as == SYSTEMD_SYSTEM) {
-                        const char* target;
-
-                        target = mount_needs_network(options, fstype) ?  SPECIAL_REMOTE_FS_TARGET : NULL;
+                if (m->running_as == SYSTEMD_SYSTEM &&
+                    mount_needs_network(options, fstype)) {
                         /* _netdev option may have shown up late, or on a
                          * remount. Add remote-fs dependencies, even though
-                         * local-fs ones may already be there */
-                        if (target) {
-                                unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
-                                load_extras = true;
-                        }
+                         * local-fs ones may already be there. */
+                        unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
+                        load_extras = true;
                 }
 
                 if (u->load_state == UNIT_NOT_FOUND) {

commit affc3d834347076e8616948978e70ed1fca84db4
Author: Chris Leech <cleech at redhat.com>
Date:   Sun Nov 23 20:33:38 2014 -0800

    mount: check options as well as fstype for network mounts
    
    When creating a new mount unit after an event on /proc/self/mountinfo,
    check the mount options as well as the fstype to determine if this is a
    remote mount that requires network access.

diff --git a/src/core/mount.c b/src/core/mount.c
index e62a5f1..5f2de64 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -64,18 +64,22 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 
-static bool mount_is_network(MountParameters *p) {
-        assert(p);
-
-        if (mount_test_option(p->options, "_netdev"))
+static bool mount_needs_network(const char *options, const char *fstype) {
+        if (mount_test_option(options, "_netdev"))
                 return true;
 
-        if (p->fstype && fstype_is_network(p->fstype))
+        if (fstype && fstype_is_network(fstype))
                 return true;
 
         return false;
 }
 
+static bool mount_is_network(MountParameters *p) {
+        assert(p);
+
+        return mount_needs_network(p->options, p->fstype);
+}
+
 static bool mount_is_bind(MountParameters *p) {
         assert(p);
 
@@ -1412,8 +1416,7 @@ static int mount_add_one(
                 if (m->running_as == SYSTEMD_SYSTEM) {
                         const char* target;
 
-                        target = fstype_is_network(fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
-
+                        target = mount_needs_network(options, fstype) ?  SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
                         r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
                         if (r < 0)
                                 goto fail;

commit a6d305f91d722e136c29222070efed5c5d8b120b
Author: Chris Leech <cleech at redhat.com>
Date:   Sun Nov 23 20:33:40 2014 -0800

    mount: add remote-fs dependencies if needed after change
    
    This is an attempt to add it the remote-fs dependencies to a mount unit
    if the options change, like when the utab options are picked up after
    mountinfo has already been processed.  It just adds the remote-fs
    dependencies, leaving the local-fs ones in place.
    
    With this change I always get mount units with proper remote-fs
    dependencies when mounted with the _netdev option.

diff --git a/src/core/mount.c b/src/core/mount.c
index c961677..e62a5f1 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1438,6 +1438,19 @@ static int mount_add_one(
                         }
                 }
 
+                if (m->running_as == SYSTEMD_SYSTEM) {
+                        const char* target;
+
+                        target = mount_needs_network(options, fstype) ?  SPECIAL_REMOTE_FS_TARGET : NULL;
+                        /* _netdev option may have shown up late, or on a
+                         * remount. Add remote-fs dependencies, even though
+                         * local-fs ones may already be there */
+                        if (target) {
+                                unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
+                                load_extras = true;
+                        }
+                }
+
                 if (u->load_state == UNIT_NOT_FOUND) {
                         u->load_state = UNIT_LOADED;
                         u->load_error = 0;

commit befb6d54948480f836d53d633bef27e3505818c1
Author: Chris Leech <cleech at redhat.com>
Date:   Sun Nov 23 20:33:39 2014 -0800

    mount: monitor for utab changes with inotify
    
    Parsing the mount table with libmount races against the mount command,
    which will handle the actual mounting before updating utab.  This means
    the poll event on /proc/self/mountinfo can kick of a reparse in systemd
    before the utab information is available.
    
    This change adds in an additional event source using inotify to watch
    for changes to utab.  It only watches for IN_MOVED_TO events, matching
    libmount behavior of always overwriting this file using rename(2).
    
    This does add a second pass through the mount table parsing when utab is
    updated.

diff --git a/src/core/manager.c b/src/core/manager.c
index 3e1728f..7b25500 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -540,7 +540,7 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
 
         m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
 
-        m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = -1;
+        m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = m->utab_inotify_fd = -1;
         m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
 
         m->ask_password_inotify_fd = -1;
diff --git a/src/core/manager.h b/src/core/manager.h
index 0253502..ab75f90 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -182,6 +182,8 @@ struct Manager {
         /* Data specific to the mount subsystem */
         FILE *proc_self_mountinfo;
         sd_event_source *mount_event_source;
+        int utab_inotify_fd;
+        sd_event_source *mount_utab_event_source;
 
         /* Data specific to the swap filesystem */
         FILE *proc_swaps;
diff --git a/src/core/mount.c b/src/core/mount.c
index d257925..c961677 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -25,6 +25,7 @@
 #include <sys/epoll.h>
 #include <signal.h>
 #include <libmount.h>
+#include <sys/inotify.h>
 
 #include "manager.h"
 #include "unit.h"
@@ -1553,11 +1554,13 @@ static void mount_shutdown(Manager *m) {
         assert(m);
 
         m->mount_event_source = sd_event_source_unref(m->mount_event_source);
+        m->mount_utab_event_source = sd_event_source_unref(m->mount_utab_event_source);
 
         if (m->proc_self_mountinfo) {
                 fclose(m->proc_self_mountinfo);
                 m->proc_self_mountinfo = NULL;
         }
+        m->utab_inotify_fd = safe_close(m->utab_inotify_fd);
 }
 
 static int mount_get_timeout(Unit *u, uint64_t *timeout) {
@@ -1597,12 +1600,32 @@ static int mount_enumerate(Manager *m) {
                         goto fail;
         }
 
+        if (m->utab_inotify_fd < 0) {
+                m->utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+                if (m->utab_inotify_fd < 0)
+                        goto fail_with_errno;
+
+                r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
+                if (r < 0)
+                        goto fail_with_errno;
+
+                r = sd_event_add_io(m->event, &m->mount_utab_event_source, m->utab_inotify_fd, EPOLLIN, mount_dispatch_io, m);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_event_source_set_priority(m->mount_utab_event_source, -10);
+                if (r < 0)
+                        goto fail;
+        }
+
         r = mount_load_proc_self_mountinfo(m, false);
         if (r < 0)
                 goto fail;
 
         return 0;
 
+fail_with_errno:
+        r = -errno;
 fail:
         mount_shutdown(m);
         return r;
@@ -1614,11 +1637,34 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
         int r;
 
         assert(m);
-        assert(revents & EPOLLPRI);
+        assert(revents & (EPOLLPRI | EPOLLIN));
 
         /* The manager calls this for every fd event happening on the
          * /proc/self/mountinfo file, which informs us about mounting
-         * table changes */
+         * table changes
+         * This may also be called for /run/mount events */
+
+        if (fd == m->utab_inotify_fd) {
+                char inotify_buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
+                struct inotify_event *event;
+                char *p;
+                int rescan = 0;
+
+                while ((r = read(fd, inotify_buffer, sizeof(inotify_buffer))) > 0) {
+                        for (p = inotify_buffer; p < inotify_buffer + r; ) {
+                                event = (struct inotify_event *) p;
+                                /* only care about changes to utab, but we have
+                                 * to monitor the directory to reliably get
+                                 * notifications about when utab is replaced
+                                 * using rename(2) */
+                                if (strcmp(event->name, "utab") == 0)
+                                        rescan = 1;
+                                p += sizeof(struct inotify_event) + event->len;
+                        }
+                }
+                if (!rescan)
+                        return 0;
+        }
 
         r = mount_load_proc_self_mountinfo(m, true);
         if (r < 0) {

commit 8d3ae2bd4c9bf9fc2e57f7b3776325a1c750ca30
Author: Chris Leech <cleech at redhat.com>
Date:   Sun Nov 23 20:33:37 2014 -0800

    mount: use libmount to enumerate /proc/self/mountinfo
    
    This lets libmount add in user options from /run/mount/utab, like
    _netdev which is needed to get proper ordering against remote-fs.target

diff --git a/.travis.yml b/.travis.yml
index 7e5251c..4ea2bc2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@ compiler:
   - gcc
 before_install:
  - sudo apt-get update -qq
- - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev
+ - sudo apt-get install autotools-dev automake autoconf libtool libdbus-1-dev libcap-dev libblkid-dev libmount-dev libpam-dev libcryptsetup-dev libaudit-dev libacl1-dev libattr1-dev libselinux-dev liblzma-dev libgcrypt-dev libqrencode-dev libmicrohttpd-dev gtk-doc-tools gperf python2.7-dev
 script: ./autogen.sh && ./configure --enable-gtk-doc --enable-gtk-doc-pdf && make V=1 && sudo ./systemd-machine-id-setup && make check && make distcheck
 after_failure: cat test-suite.log
 notifications:
diff --git a/Makefile.am b/Makefile.am
index 7ab1dea..791508b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1149,6 +1149,7 @@ libsystemd_core_la_CFLAGS = \
 	$(KMOD_CFLAGS) \
 	$(APPARMOR_CFLAGS) \
 	$(SECCOMP_CFLAGS) \
+	$(MOUNT_CFLAGS) \
 	-pthread
 
 libsystemd_core_la_LIBADD = \
@@ -1161,7 +1162,8 @@ libsystemd_core_la_LIBADD = \
 	$(AUDIT_LIBS) \
 	$(KMOD_LIBS) \
 	$(APPARMOR_LIBS) \
-	$(SECCOMP_LIBS)
+	$(SECCOMP_LIBS) \
+	$(MOUNT_LIBS)
 
 if HAVE_SECCOMP
 libsystemd_core_la_LIBADD += \
diff --git a/README b/README
index aefb349..84c6ed4 100644
--- a/README
+++ b/README
@@ -106,6 +106,7 @@ REQUIREMENTS:
 
         glibc >= 2.14
         libcap
+        libmount >= 2.20 (from util-linux)
         libseccomp >= 1.0.0 (optional)
         libblkid >= 2.20 (from util-linux) (optional)
         libkmod >= 15 (optional)
diff --git a/configure.ac b/configure.ac
index a4e91e3..928ac2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -439,6 +439,15 @@ fi
 AM_CONDITIONAL(HAVE_BLKID, [test "$have_blkid" = "yes"])
 
 # ------------------------------------------------------------------------------
+have_libmount=no
+PKG_CHECK_MODULES(MOUNT, [ mount >= 2.20 ],
+        [AC_DEFINE(HAVE_LIBMOUNT, 1, [Define if libmount is available]) have_libmount=yes], have_libmount=no)
+if test "x$have_libmount" = xno; then
+        AC_MSG_ERROR([*** libmount support required but libraries not found])
+fi
+AM_CONDITIONAL(HAVE_LIBMOUNT, [test "$have_libmount" = "yes"])
+
+# ------------------------------------------------------------------------------
 have_seccomp=no
 AC_ARG_ENABLE(seccomp, AS_HELP_STRING([--disable-seccomp], [Disable optional SECCOMP support]))
 if test "x$enable_seccomp" != "xno"; then
@@ -1388,6 +1397,7 @@ AC_MSG_RESULT([
         kmod:                    ${have_kmod}
         xkbcommon:               ${have_xkbcommon}
         blkid:                   ${have_blkid}
+        libmount:                ${have_libmount}
         dbus:                    ${have_dbus}
         nss-myhostname:          ${have_myhostname}
         gudev:                   ${enable_gudev}
diff --git a/src/core/mount.c b/src/core/mount.c
index e6f0a8a..d257925 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -24,6 +24,7 @@
 #include <mntent.h>
 #include <sys/epoll.h>
 #include <signal.h>
+#include <libmount.h>
 
 #include "manager.h"
 #include "unit.h"
@@ -1500,55 +1501,47 @@ fail:
         return r;
 }
 
+static inline void mnt_free_table_p(struct libmnt_table **tb) {
+        mnt_free_table(*tb);
+}
+
+static inline void mnt_free_iter_p(struct libmnt_iter **itr) {
+        mnt_free_iter(*itr);
+}
+
 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
+        _cleanup_(mnt_free_table_p) struct libmnt_table *tb = NULL;
+        _cleanup_(mnt_free_iter_p) struct libmnt_iter *itr = NULL;
+        struct libmnt_fs *fs;
         int r = 0;
-        unsigned i;
 
         assert(m);
 
-        rewind(m->proc_self_mountinfo);
+        tb = mnt_new_table();
+        itr = mnt_new_iter(MNT_ITER_FORWARD);
+        if (!tb || !itr)
+                return log_oom();
 
-        for (i = 1;; i++) {
-                _cleanup_free_ char *device = NULL, *path = NULL, *options = NULL, *options2 = NULL, *fstype = NULL, *d = NULL, *p = NULL, *o = NULL;
-                int k;
+        mnt_table_parse_mtab(tb, NULL);
+        if (r)
+                return r;
 
-                k = fscanf(m->proc_self_mountinfo,
-                           "%*s "       /* (1) mount id */
-                           "%*s "       /* (2) parent id */
-                           "%*s "       /* (3) major:minor */
-                           "%*s "       /* (4) root */
-                           "%ms "       /* (5) mount point */
-                           "%ms"        /* (6) mount options */
-                           "%*[^-]"     /* (7) optional fields */
-                           "- "         /* (8) separator */
-                           "%ms "       /* (9) file system type */
-                           "%ms"        /* (10) mount source */
-                           "%ms"        /* (11) mount options 2 */
-                           "%*[^\n]",   /* some rubbish at the end */
-                           &path,
-                           &options,
-                           &fstype,
-                           &device,
-                           &options2);
-
-                if (k == EOF)
-                        break;
-
-                if (k != 5) {
-                        log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
-                        continue;
-                }
+        while (mnt_table_next_fs(tb, itr, &fs) == 0) {
+                const char *device, *path, *options, *fstype;
+                _cleanup_free_ const char *d = NULL, *p = NULL;
+                int k;
 
-                o = strjoin(options, ",", options2, NULL);
-                if (!o)
-                        return log_oom();
+                device = mnt_fs_get_source(fs);
+                path = mnt_fs_get_target(fs);
+                options = mnt_fs_get_options(fs);
+                fstype = mnt_fs_get_fstype(fs);
 
                 d = cunescape(device);
                 p = cunescape(path);
                 if (!d || !p)
                         return log_oom();
 
-                k = mount_add_one(m, d, p, o, fstype, set_flags);
+                k = mount_add_one(m, d, p, options, fstype, set_flags);
                 if (k < 0)
                         r = k;
         }
@@ -1585,6 +1578,8 @@ static int mount_enumerate(Manager *m) {
         int r;
         assert(m);
 
+        mnt_init_debug(0);
+
         if (!m->proc_self_mountinfo) {
                 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
                 if (!m->proc_self_mountinfo)



More information about the systemd-commits mailing list