aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorнаб <[email protected]>2021-04-29 22:21:41 +0200
committerBrian Behlendorf <[email protected]>2021-05-08 09:16:26 -0700
commit8bc357ba9285f0a151d458409d23916b3062d6dc (patch)
treebc287e6c2d38445d62e7f2690af573149ba58400
parent36e8abee95576de588802afadd2c44c674e00acb (diff)
libzfs: zpool_load_compat(): open feature file cloexec
As a bonus, this also passes the open flags into the open flags instead of the mode (it worked by accident because O_RDONLY is 0), correctly detects a failed map, and prefaults the entire file since we're always writing to every page Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ahelenia Ziemiańska <[email protected]> Closes #11993
-rw-r--r--lib/libzfs/libzfs_pool.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
index b4c9d7df9..d4849ee5b 100644
--- a/lib/libzfs/libzfs_pool.c
+++ b/lib/libzfs/libzfs_pool.c
@@ -4812,14 +4812,14 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
file != NULL;
file = strtok_r(NULL, ",", &ps)) {
- boolean_t l_features[SPA_FEATURES];
+ boolean_t l_features[SPA_FEATURES] = {B_FALSE};
enum { Z_SYSCONF, Z_DATA } source;
/* try sysconfdir first, then datadir */
source = Z_SYSCONF;
- if ((featfd = openat(sdirfd, file, 0, O_RDONLY)) < 0) {
- featfd = openat(ddirfd, file, 0, O_RDONLY);
+ if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) {
+ featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC);
source = Z_DATA;
}
@@ -4835,13 +4835,18 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
continue;
}
+#if !defined(MAP_POPULATE) && defined(MAP_PREFAULT_READ)
+#define MAP_POPULATE MAP_PREFAULT_READ
+#elif !defined(MAP_POPULATE)
+#define MAP_POPULATE 0
+#endif
/* private mmap() so we can strtok safely */
fc = (char *)mmap(NULL, fs.st_size,
- PROT_READ|PROT_WRITE, MAP_PRIVATE, featfd, 0);
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_POPULATE, featfd, 0);
(void) close(featfd);
/* map ok, and last character == newline? */
- if (fc < 0 || fc[fs.st_size - 1] != '\n') {
+ if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') {
(void) munmap((void *) fc, fs.st_size);
strlcat(err_badfile, file, ZFS_MAXPROPLEN);
strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
@@ -4851,9 +4856,6 @@ zpool_load_compat(const char *compat, boolean_t *features, char *report,
ret_nofiles = B_FALSE;
- for (uint_t i = 0; i < SPA_FEATURES; i++)
- l_features[i] = B_FALSE;
-
/* replace last char with NUL to ensure we have a delimiter */
fc[fs.st_size - 1] = '\0';