[systemd-devel] [PATCH] libudev: replace name_to_handle_at with normal sscanf
Zbigniew Jędrzejewski-Szmek
zbyszek at in.waw.pl
Sat Apr 19 20:36:02 PDT 2014
This has the advantage that we use the same sscanf
pattern as in other places where /proc/self/mountinfo is parsed,
and we avoid bugreports from people who are confused about missing
CONFIG_FHANDLE.
An alternate solution would be to warn when (at runtime) name_to_handle_at
is detected to be missing, but this is used in early boot, and seems
less useful overall.
https://bugzilla.redhat.com/show_bug.cgi?id=1072966
---
Hi Kay,
it seems that handles are not crucial, and the simplified version below
works too. Is there something I'm missing?
Zbyszek
README | 2 +-
src/libudev/libudev-monitor.c | 49 ++++++++++++++++++++++++-------------------
src/shared/path-util.c | 6 +-----
3 files changed, 30 insertions(+), 27 deletions(-)
diff --git a/README b/README
index cecbcbf..983f02f 100644
--- a/README
+++ b/README
@@ -51,7 +51,6 @@ REQUIREMENTS:
CONFIG_NET
CONFIG_SYSFS
CONFIG_PROC_FS
- CONFIG_FHANDLE (libudev, mount and bind mount handling)
Udev will fail to work with the legacy layout:
CONFIG_SYSFS_DEPRECATED=n
@@ -79,6 +78,7 @@ REQUIREMENTS:
CONFIG_TMPFS_POSIX_ACL
CONFIG_TMPFS_XATTR
CONFIG_SECCOMP
+ CONFIG_FHANDLE (libudev, mount and bind mount handling)
For systemd-bootchart, several proc debug interfaces are required:
CONFIG_SCHEDSTATS
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index 3f7436b..0590002 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -108,39 +108,46 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev)
/* we consider udev running when /dev is on devtmpfs */
static bool udev_has_devtmpfs(struct udev *udev) {
- struct file_handle *h;
- int mount_id;
_cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX], *e;
- int r;
-
- h = alloca(MAX_HANDLE_SZ);
- h->handle_bytes = MAX_HANDLE_SZ;
- r = name_to_handle_at(AT_FDCWD, "/dev", h, &mount_id, 0);
- if (r < 0)
- return false;
-
+ int i;
f = fopen("/proc/self/mountinfo", "re");
if (!f)
return false;
- FOREACH_LINE(line, f, return false) {
- int mid;
-
- if (sscanf(line, "%i", &mid) != 1)
- continue;
+ for (i = 1;; i++) {
+ _cleanup_free_ char *where = NULL, *fstype = NULL;
+ int k;
+
+ k = fscanf(f,
+ "%*s " /* (1) mount id */
+ "%*s " /* (2) parent id */
+ "%*s " /* (3) major:minor */
+ "%*s " /* (4) root */
+ "%ms " /* (5) mount point */
+ "%*s" /* (6) mount options */
+ "%*[^-]" /* (7) optional fields */
+ "- " /* (8) separator */
+ "%ms " /* (9) file system type */
+ "%*s" /* (10) mount source */
+ "%*s" /* (11) mount options 2 */
+ "%*[^\n]", /* some rubbish at the end */
+ &where,
+ &fstype);
+
+ if (k == EOF)
+ break;
- if (mid != mount_id)
+ if (k != 2) {
+ log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
continue;
+ }
- e = strstr(line, " - ");
- if (!e)
+ if (!streq(where, "/dev"))
continue;
/* accept any name that starts with the currently expected type */
- if (startswith(e + 3, "devtmpfs"))
- return true;
+ return streq(fstype, "devtmpfs");
}
return false;
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index e35d7f8..5beb5f8 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -324,7 +324,7 @@ bool path_equal(const char *a, const char *b) {
}
int path_is_mount_point(const char *t, bool allow_symlink) {
- char *parent;
+ _cleanup_free_ char *parent = NULL;
int r;
struct file_handle *h;
int mount_id, mount_id_parent;
@@ -360,8 +360,6 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
h->handle_bytes = MAX_HANDLE_SZ;
r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0);
- free(parent);
-
if (r < 0) {
/* The parent can't do name_to_handle_at() but the
* directory we are interested in can? If so, it must
@@ -392,8 +390,6 @@ fallback:
return r;
r = lstat(parent, &b);
- free(parent);
-
if (r < 0)
return -errno;
--
1.8.5.2
More information about the systemd-devel
mailing list