[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