Line
Link Here
|
0 |
-- src/libudev/libudev-monitor.c |
0 |
++ src/libudev/libudev-monitor.c |
Lines 108-150
Link Here
|
108 |
|
108 |
|
109 |
/* we consider udev running when /dev is on devtmpfs */ |
109 |
/* we consider udev running when /dev is on devtmpfs */ |
110 |
static bool udev_has_devtmpfs(struct udev *udev) { |
110 |
static bool udev_has_devtmpfs(struct udev *udev) { |
111 |
|
111 |
int i; |
112 |
union file_handle_union h = { |
|
|
113 |
.handle.handle_bytes = MAX_HANDLE_SZ |
114 |
}; |
115 |
|
116 |
_cleanup_fclose_ FILE *f = NULL; |
117 |
char line[LINE_MAX], *e; |
118 |
int mount_id; |
119 |
int r; |
120 |
|
121 |
r = name_to_handle_at(AT_FDCWD, "/dev", &h.handle, &mount_id, 0); |
122 |
if (r < 0) { |
123 |
if (errno != EOPNOTSUPP) |
124 |
udev_err(udev, "name_to_handle_at on /dev: %m\n"); |
125 |
return false; |
126 |
} |
127 |
|
112 |
|
128 |
f = fopen("/proc/self/mountinfo", "re"); |
113 |
f = fopen("/proc/self/mountinfo", "re"); |
129 |
if (!f) |
114 |
if (!f) |
130 |
return false; |
115 |
return false; |
131 |
|
116 |
|
132 |
FOREACH_LINE(line, f, return false) { |
117 |
for (i = 1;; i++) { |
133 |
int mid; |
118 |
_cleanup_free_ char *where = NULL, *fstype = NULL; |
|
|
119 |
int k; |
120 |
|
121 |
k = fscanf(f, |
122 |
"%*s " /* (1) mount id */ |
123 |
"%*s " /* (2) parent id */ |
124 |
"%*s " /* (3) major:minor */ |
125 |
"%*s " /* (4) root */ |
126 |
"%ms " /* (5) mount point */ |
127 |
"%*s" /* (6) mount options */ |
128 |
"%*[^-]" /* (7) optional fields */ |
129 |
"- " /* (8) separator */ |
130 |
"%ms " /* (9) file system type */ |
131 |
"%*s" /* (10) mount source */ |
132 |
"%*s" /* (11) mount options 2 */ |
133 |
"%*[^\n]", /* some rubbish at the end */ |
134 |
&where, |
135 |
&fstype); |
134 |
|
136 |
|
135 |
if (sscanf(line, "%i", &mid) != 1) |
137 |
if (k == EOF) |
136 |
continue; |
138 |
break; |
137 |
|
139 |
|
138 |
if (mid != mount_id) |
140 |
if (k != 2) { |
|
|
141 |
log_warning("Failed to parse /proc/self/mountinfo:%u.", i); |
139 |
continue; |
142 |
continue; |
|
|
143 |
} |
140 |
|
144 |
|
141 |
e = strstr(line, " - "); |
145 |
if (!streq(where, "/dev")) |
142 |
if (!e) |
|
|
143 |
continue; |
146 |
continue; |
144 |
|
147 |
|
145 |
/* accept any name that starts with the currently expected type */ |
148 |
/* accept any name that starts with the currently expected type */ |
146 |
if (startswith(e + 3, "devtmpfs")) |
149 |
return streq(fstype, "devtmpfs"); |
147 |
return true; |
|
|
148 |
} |
150 |
} |
149 |
|
151 |
|
150 |
return false; |
152 |
return false; |
151 |
-- src/shared/path-util.c |
153 |
++ src/shared/path-util.c |
Lines 436-450
Link Here
|
436 |
} |
436 |
} |
437 |
|
437 |
|
438 |
int path_is_mount_point(const char *t, bool allow_symlink) { |
438 |
int path_is_mount_point(const char *t, bool allow_symlink) { |
439 |
|
439 |
_cleanup_free_ char *parent = NULL; |
440 |
union file_handle_union h = { |
440 |
int r; |
441 |
.handle.handle_bytes = MAX_HANDLE_SZ |
441 |
struct file_handle *h; |
442 |
}; |
|
|
443 |
|
444 |
int mount_id, mount_id_parent; |
442 |
int mount_id, mount_id_parent; |
445 |
char *parent; |
|
|
446 |
struct stat a, b; |
443 |
struct stat a, b; |
447 |
int r; |
|
|
448 |
|
444 |
|
449 |
/* We are not actually interested in the file handles, but |
445 |
/* We are not actually interested in the file handles, but |
450 |
* name_to_handle_at() also passes us the mount ID, hence use |
446 |
* name_to_handle_at() also passes us the mount ID, hence use |
Lines 453-461
Link Here
|
453 |
if (path_equal(t, "/")) |
449 |
if (path_equal(t, "/")) |
454 |
return 1; |
450 |
return 1; |
455 |
|
451 |
|
456 |
r = name_to_handle_at(AT_FDCWD, t, &h.handle, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0); |
452 |
h = alloca(MAX_HANDLE_SZ); |
|
|
453 |
h->handle_bytes = MAX_HANDLE_SZ; |
454 |
|
455 |
r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0); |
457 |
if (r < 0) { |
456 |
if (r < 0) { |
458 |
if (IN_SET(errno, ENOSYS, EOPNOTSUPP)) |
457 |
if (errno == ENOSYS || errno == ENOTSUP) |
459 |
/* This kernel or file system does not support |
458 |
/* This kernel or file system does not support |
460 |
* name_to_handle_at(), hence fallback to the |
459 |
* name_to_handle_at(), hence fallback to the |
461 |
* traditional stat() logic */ |
460 |
* traditional stat() logic */ |
Lines 471-484
Link Here
|
471 |
if (r < 0) |
470 |
if (r < 0) |
472 |
return r; |
471 |
return r; |
473 |
|
472 |
|
474 |
h.handle.handle_bytes = MAX_HANDLE_SZ; |
473 |
h->handle_bytes = MAX_HANDLE_SZ; |
475 |
r = name_to_handle_at(AT_FDCWD, parent, &h.handle, &mount_id_parent, 0); |
474 |
r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0); |
476 |
free(parent); |
475 |
|
477 |
if (r < 0) { |
476 |
if (r < 0) { |
478 |
/* The parent can't do name_to_handle_at() but the |
477 |
/* The parent can't do name_to_handle_at() but the |
479 |
* directory we are interested in can? If so, it must |
478 |
* directory we are interested in can? If so, it must |
480 |
* be a mount point */ |
479 |
* be a mount point */ |
481 |
if (errno == EOPNOTSUPP) |
480 |
if (errno == ENOTSUP) |
482 |
return 1; |
481 |
return 1; |
483 |
|
482 |
|
484 |
return -errno; |
483 |
return -errno; |
Lines 504-510
Link Here
|
504 |
return r; |
503 |
return r; |
505 |
|
504 |
|
506 |
r = lstat(parent, &b); |
505 |
r = lstat(parent, &b); |
507 |
free(parent); |
506 |
|
508 |
if (r < 0) |
507 |
if (r < 0) |
509 |
return -errno; |
508 |
return -errno; |
510 |
|
509 |
|