[systemd-commits] 5 commits - rules/78-sound-card.rules src/core src/libsystemd src/shared src/test

Lennart Poettering lennart at kemper.freedesktop.org
Thu Apr 23 04:53:29 PDT 2015


 rules/78-sound-card.rules          |   13 ++-
 src/core/device.c                  |    2 
 src/libsystemd/sd-bus/bus-socket.c |    4 -
 src/shared/path-util.c             |  135 +++++++++++++++++++++++++++++--------
 src/test/test-path-util.c          |    9 ++
 5 files changed, 127 insertions(+), 36 deletions(-)

New commits:
commit 5259bcf6a638d8d489db1ddefd55327aa15f3e51
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 23 13:50:01 2015 +0200

    core: downgrade warning about duplicate device names
    
    http://lists.freedesktop.org/archives/systemd-devel/2015-April/031094.html

diff --git a/src/core/device.c b/src/core/device.c
index dca2a82..43c4c67 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -282,7 +282,7 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
         if (u &&
             DEVICE(u)->sysfs &&
             !path_equal(DEVICE(u)->sysfs, sysfs)) {
-                log_unit_error(u->id, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
+                log_unit_debug(u->id, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
                 return -EEXIST;
         }
 

commit 5c0b72de3a092bff272640ae27cd960e660a3a3d
Author: Adam Goode <agoode at google.com>
Date:   Wed Apr 22 21:05:39 2015 -0400

    rules: Add more firewire properties for sound, to be closer to USB and PCI
    
    USB and PCI soundcards have a nice set of ID_* properties. It would
    be handy for firewire soundcards to have the same.
    
    Note that this removes the explicit setting of ID_ID in the firewire
    conditional. Because we are now setting ID_SERIAL, ID_ID will come
    from later in the file.

diff --git a/rules/78-sound-card.rules b/rules/78-sound-card.rules
index bd7a994..04740e8 100644
--- a/rules/78-sound-card.rules
+++ b/rules/78-sound-card.rules
@@ -41,14 +41,17 @@ IMPORT{builtin}="hwdb"
 SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
 SUBSYSTEMS=="usb", GOTO="skip_pci"
 
-SUBSYSTEMS=="firewire", ATTRS{vendor_name}=="?*", ATTRS{model_name}=="?*", \
-  ENV{ID_BUS}="firewire", ENV{ID_VENDOR}="$attr{vendor_name}", ENV{ID_MODEL}="$attr{model_name}"
-SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", ENV{ID_ID}="firewire-$attr{guid}"
+SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", \
+  ENV{ID_BUS}="firewire", ENV{ID_SERIAL}="$attr{guid}", ENV{ID_SERIAL_SHORT}="$attr{guid}", \
+  ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{model}", \
+  ENV{ID_VENDOR}="$attr{vendor_name}", ENV{ID_MODEL}="$attr{model_name}"
 SUBSYSTEMS=="firewire", GOTO="skip_pci"
 
 SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
 LABEL="skip_pci"
 
+# Define ID_ID if ID_BUS and ID_SERIAL are set. This will work for both
+# USB and firewire.
 ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}"
 ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}"
 

commit 0414af1dfe99fe7bd58a7d93427cb6762895729d
Author: Adam Goode <agoode at google.com>
Date:   Wed Apr 22 21:05:38 2015 -0400

    rules: Don't use ALSA card id in ID_ID
    
    The ALSA id sysattr is generated by the sound subsystem and is not
    a stable identifier. It is generated though some string manipulation
    then made unique if there is a conflict. This means that it is
    enumeration-dependent and shouldn't be used for ID_ID.
    
    If ID_ID is supposed to be system-unique, it is not already since
    for firewire it is generated from the guid and there are broken
    firewire devices that have duplicate guids across devices.
    
    This is tracked for PulseAudio at
    https://bugs.freedesktop.org/show_bug.cgi?id=90129.
    
    This is essentially a revert of systemd
    ed1b2d9fc7d5c5bfe2a67b0b8ff9e5ea8694268e.

diff --git a/rules/78-sound-card.rules b/rules/78-sound-card.rules
index 295f490..bd7a994 100644
--- a/rules/78-sound-card.rules
+++ b/rules/78-sound-card.rules
@@ -49,8 +49,8 @@ SUBSYSTEMS=="firewire", GOTO="skip_pci"
 SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
 LABEL="skip_pci"
 
-ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}-$attr{id}"
-ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$attr{id}"
+ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}"
+ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}"
 
 IMPORT{builtin}="path_id"
 

commit 038f9863e22295d0e22b3b79a6d54f7086525ba2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 23 13:37:03 2015 +0200

    sd-bus: don't inherit connection creds into message creds when we have a direct connection
    
    It's never a good idea, let's just not do it, not even on dierct
    connections.

diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 6a55f9b..94a5c04 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -915,8 +915,8 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
         r = bus_message_from_malloc(bus,
                                     bus->rbuffer, size,
                                     bus->fds, bus->n_fds,
-                                    !bus->bus_client && bus->ucred_valid ? &bus->ucred : NULL,
-                                    !bus->bus_client && !isempty(bus->label) ? bus->label : NULL,
+                                    NULL,
+                                    NULL,
                                     &t);
         if (r < 0) {
                 free(b);

commit 3f72b427b44f39a1aec6806dad6f6b57103ae9ed
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 23 13:23:03 2015 +0200

    path-util: make use of "mnt_id" field exported in /proc/self/fdinfo/<fd> to test for mount points
    
    It's a very recent kernel addition, but certainly makes sense to
    support.

diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index a01475a..925bb28 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -33,6 +33,7 @@
 #include "strv.h"
 #include "path-util.h"
 #include "missing.h"
+#include "fileio.h"
 
 bool path_is_absolute(const char *p) {
         return p[0] == '/';
@@ -470,25 +471,82 @@ char* path_join(const char *root, const char *path, const char *rest) {
                                NULL);
 }
 
+static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id) {
+        char path[strlen("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)];
+        _cleanup_free_ char *fdinfo = NULL;
+        _cleanup_close_ int subfd = -1;
+        char *p;
+        int r;
+
+        if ((flags & AT_EMPTY_PATH) && isempty(filename))
+                xsprintf(path, "/proc/self/fdinfo/%i", fd);
+        else {
+                subfd = openat(fd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
+                if (subfd < 0)
+                        return -errno;
+
+                xsprintf(path, "/proc/self/fdinfo/%i", subfd);
+        }
+
+        r = read_full_file(path, &fdinfo, NULL);
+        if (r == -ENOENT) /* The fdinfo directory is a relatively new addition */
+                return -EOPNOTSUPP;
+        if (r < 0)
+                return -errno;
+
+        p = startswith(fdinfo, "mnt_id:");
+        if (!p) {
+                p = strstr(fdinfo, "\nmnt_id:");
+                if (!p) /* The mnt_id field is a relatively new addition */
+                        return -EOPNOTSUPP;
+
+                p += 8;
+        }
+
+        p += strspn(p, WHITESPACE);
+        p[strcspn(p, WHITESPACE)] = 0;
+
+        return safe_atoi(p, mnt_id);
+}
+
 int fd_is_mount_point(int fd) {
         union file_handle_union h = FILE_HANDLE_INIT, h_parent = FILE_HANDLE_INIT;
         int mount_id = -1, mount_id_parent = -1;
-        bool nosupp = false;
+        bool nosupp = false, check_st_dev = false;
         struct stat a, b;
         int r;
 
         assert(fd >= 0);
 
-        /* We are not actually interested in the file handles, but
-         * name_to_handle_at() also passes us the mount ID, hence use
-         * it but throw the handle away */
+        /* First we will try the name_to_handle_at() syscall, which
+         * tells us the mount id and an opaque file "handle". It is
+         * not supported everywhere though (kernel compile-time
+         * option, not all file systems are hooked up). If it works
+         * the mount id is usually good enough to tell us whether
+         * something is a mount point.
+         *
+         * If that didn't work we will try to read the mount id from
+         * /proc/self/fdinfo/<fd>. This is almost as good as
+         * name_to_handle_at(), however, does not return the the
+         * opaque file handle. The opaque file handle is pretty useful
+         * to detect the root directory, which we should always
+         * consider a mount point. Hence we use this only as
+         * fallback. Exporting the mnt_id in fdinfo is a pretty recent
+         * kernel addition.
+         *
+         * As last fallback we do traditional fstat() based st_dev
+         * comparisons. This is how things were traditionally done,
+         * but unionfs breaks breaks this since it exposes file
+         * systems with a variety of st_dev reported. Also, btrfs
+         * subvolumes have different st_dev, even though they aren't
+         * real mounts of their own. */
 
         r = name_to_handle_at(fd, "", &h.handle, &mount_id, AT_EMPTY_PATH);
         if (r < 0) {
                 if (errno == ENOSYS)
                         /* This kernel does not support name_to_handle_at()
-                         * fall back to the traditional stat() logic. */
-                        goto fallback;
+                         * fall back to simpler logic. */
+                        goto fallback_fdinfo;
                 else if (errno == EOPNOTSUPP)
                         /* This kernel or file system does not support
                          * name_to_handle_at(), hence let's see if the
@@ -506,7 +564,7 @@ int fd_is_mount_point(int fd) {
                         if (nosupp)
                                 /* Neither parent nor child do name_to_handle_at()?
                                    We have no choice but to fall back. */
-                                goto fallback;
+                                goto fallback_fdinfo;
                         else
                                 /* The parent can't do name_to_handle_at() but the
                                  * directory we are interested in can?
@@ -514,32 +572,53 @@ int fd_is_mount_point(int fd) {
                                 return 1;
                 } else
                         return -errno;
-        } else if (nosupp)
-                /* The parent can do name_to_handle_at() but the
-                 * directory we are interested in can't? If so, it
-                 * must be a mount point. */
+        }
+
+        /* The parent can do name_to_handle_at() but the
+         * directory we are interested in can't? If so, it
+         * must be a mount point. */
+        if (nosupp)
                 return 1;
-        else {
-                /* If the file handle for the directory we are
-                 * interested in and its parent are identical, we
-                 * assume this is the root directory, which is a mount
-                 * point. */
-
-                if (h.handle.handle_bytes == h_parent.handle.handle_bytes &&
-                    h.handle.handle_type == h_parent.handle.handle_type &&
-                    memcmp(h.handle.f_handle, h_parent.handle.f_handle, h.handle.handle_bytes) == 0)
-                        return 1;
 
-                return mount_id != mount_id_parent;
-        }
+        /* If the file handle for the directory we are
+         * interested in and its parent are identical, we
+         * assume this is the root directory, which is a mount
+         * point. */
+
+        if (h.handle.handle_bytes == h_parent.handle.handle_bytes &&
+            h.handle.handle_type == h_parent.handle.handle_type &&
+            memcmp(h.handle.f_handle, h_parent.handle.f_handle, h.handle.handle_bytes) == 0)
+                return 1;
+
+        return mount_id != mount_id_parent;
 
-fallback:
-        r = fstatat(fd, "", &a, AT_EMPTY_PATH);
+fallback_fdinfo:
+        r = fd_fdinfo_mnt_id(fd, "", AT_EMPTY_PATH, &mount_id);
+        if (r == -EOPNOTSUPP)
+                goto fallback_fstat;
         if (r < 0)
-                return -errno;
+                return r;
 
-        r = fstatat(fd, "..", &b, 0);
+        r = fd_fdinfo_mnt_id(fd, "..", 0, &mount_id_parent);
         if (r < 0)
+                return r;
+
+        if (mount_id != mount_id_parent)
+                return 1;
+
+        /* Hmm, so, the mount ids are the same. This leaves one
+         * special case though for the root file system. For that,
+         * let's see if the parent directory has the same inode as we
+         * are interested in. Hence, let's also do fstat() checks now,
+         * too, but avoid the st_dev comparisons, since they aren't
+         * that useful on unionfs mounts. */
+        check_st_dev = false;
+
+fallback_fstat:
+        if (fstatat(fd, "", &a, AT_EMPTY_PATH) < 0)
+                return -errno;
+
+        if (fstatat(fd, "..", &b, 0) < 0)
                 return -errno;
 
         /* A directory with same device and inode as its parent? Must
@@ -548,7 +627,7 @@ fallback:
             a.st_ino == b.st_ino)
                 return 1;
 
-        return a.st_dev != b.st_dev;
+        return check_st_dev && (a.st_dev != b.st_dev);
 }
 
 int path_is_mount_point(const char *t, bool allow_symlink) {
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index 55d75ae..e5b9c28 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -36,6 +36,8 @@
         }
 
 static void test_path(void) {
+        _cleanup_close_ int fd = -1;
+
         test_path_compare("/goo", "/goo", 0);
         test_path_compare("/goo", "/goo", 0);
         test_path_compare("//goo", "/goo", 0);
@@ -89,9 +91,16 @@ static void test_path(void) {
         assert_se(path_is_mount_point("/", true) > 0);
         assert_se(path_is_mount_point("/", false) > 0);
 
+        fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
+        assert_se(fd >= 0);
+        assert_se(fd_is_mount_point(fd) > 0);
+
         assert_se(path_is_mount_point("/proc", true) > 0);
         assert_se(path_is_mount_point("/proc", false) > 0);
 
+        assert_se(path_is_mount_point("/proc/1", true) == 0);
+        assert_se(path_is_mount_point("/proc/1", false) == 0);
+
         assert_se(path_is_mount_point("/sys", true) > 0);
         assert_se(path_is_mount_point("/sys", false) > 0);
 



More information about the systemd-commits mailing list