--- src/libudev/libudev-monitor.c +++ src/libudev/libudev-monitor.c @@ -108,43 +108,45 @@ /* we consider udev running when /dev is on devtmpfs */ static bool udev_has_devtmpfs(struct udev *udev) { - - union file_handle_union h = { - .handle.handle_bytes = MAX_HANDLE_SZ - }; - - _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX], *e; - int mount_id; - int r; - - r = name_to_handle_at(AT_FDCWD, "/dev", &h.handle, &mount_id, 0); - if (r < 0) { - if (errno != EOPNOTSUPP) - udev_err(udev, "name_to_handle_at on /dev: %m\n"); - return false; - } + int i; f = fopen("/proc/self/mountinfo", "re"); if (!f) return false; - FOREACH_LINE(line, f, return false) { - int mid; + 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 (sscanf(line, "%i", &mid) != 1) - continue; + 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; --- src/shared/path-util.c +++ src/shared/path-util.c @@ -436,15 +436,11 @@ } int path_is_mount_point(const char *t, bool allow_symlink) { - - union file_handle_union h = { - .handle.handle_bytes = MAX_HANDLE_SZ - }; - + _cleanup_free_ char *parent = NULL; + int r; + struct file_handle *h; int mount_id, mount_id_parent; - char *parent; struct stat a, b; - int r; /* We are not actually interested in the file handles, but * name_to_handle_at() also passes us the mount ID, hence use @@ -453,9 +449,12 @@ if (path_equal(t, "/")) return 1; - r = name_to_handle_at(AT_FDCWD, t, &h.handle, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0); + h = alloca(MAX_HANDLE_SZ); + h->handle_bytes = MAX_HANDLE_SZ; + + r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0); if (r < 0) { - if (IN_SET(errno, ENOSYS, EOPNOTSUPP)) + if (errno == ENOSYS || errno == ENOTSUP) /* This kernel or file system does not support * name_to_handle_at(), hence fallback to the * traditional stat() logic */ @@ -471,14 +470,14 @@ if (r < 0) return r; - h.handle.handle_bytes = MAX_HANDLE_SZ; - r = name_to_handle_at(AT_FDCWD, parent, &h.handle, &mount_id_parent, 0); - free(parent); + h->handle_bytes = MAX_HANDLE_SZ; + r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0); + if (r < 0) { /* The parent can't do name_to_handle_at() but the * directory we are interested in can? If so, it must * be a mount point */ - if (errno == EOPNOTSUPP) + if (errno == ENOTSUP) return 1; return -errno; @@ -504,7 +503,7 @@ return r; r = lstat(parent, &b); - free(parent); + if (r < 0) return -errno;