Skip to content

Commit 9d81146

Browse files
dechampsbehlendorf
authored andcommitted
Use dynamic file descriptor numbers in ztest.
Currently, ztest expects to get 3 and 4 as the file descriptors for data and random files, respectively. This is quite fragile and breaks easily if ztest is run with these file descriptors already opened (e.g. in a complex shell script). This patch fixes the issue by removing the assumptions on the file descriptor numbers that open() returns. For the random file (/dev/urandom), the new code doesn't rely on a shared file descriptor; instead, it reopens the file in the child. For the data file, the new code writes the file descriptor number into a "ZTEST_FD_DATA" environment variable so that it can be recovered after the execv() call. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
1 parent 22257dc commit 9d81146

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

cmd/ztest/ztest.c

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@
121121
#include <sys/fs/zfs.h>
122122
#include <libnvpair.h>
123123

124-
#define ZTEST_FD_DATA 3
125-
#define ZTEST_FD_RAND 4
124+
static int ztest_fd_data = -1;
125+
static int ztest_fd_rand = -1;
126126

127127
typedef struct ztest_shared_hdr {
128128
uint64_t zh_hdr_size;
@@ -783,10 +783,12 @@ ztest_random(uint64_t range)
783783
{
784784
uint64_t r;
785785

786+
ASSERT3S(ztest_fd_rand, >=, 0);
787+
786788
if (range == 0)
787789
return (0);
788790

789-
if (read(ZTEST_FD_RAND, &r, sizeof (r)) != sizeof (r))
791+
if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
790792
fatal(1, "short read from /dev/urandom");
791793

792794
return (r % range);
@@ -5815,26 +5817,13 @@ ztest_init(ztest_shared_t *zs)
58155817
}
58165818

58175819
static void
5818-
setup_fds(void)
5820+
setup_data_fd(void)
58195821
{
5820-
int fd;
5821-
58225822
char *tmp = tempnam(NULL, NULL);
5823-
fd = open(tmp, O_RDWR | O_CREAT, 0700);
5824-
ASSERT3S(fd, >=, 0);
5825-
if (fd != ZTEST_FD_DATA) {
5826-
VERIFY3S(dup2(fd, ZTEST_FD_DATA), ==, ZTEST_FD_DATA);
5827-
close(fd);
5828-
}
5823+
ztest_fd_data = open(tmp, O_RDWR | O_CREAT, 0700);
5824+
ASSERT3S(ztest_fd_data, >=, 0);
58295825
(void) unlink(tmp);
58305826
free(tmp);
5831-
5832-
fd = open("/dev/urandom", O_RDONLY);
5833-
ASSERT3S(fd, >=, 0);
5834-
if (fd != ZTEST_FD_RAND) {
5835-
VERIFY3S(dup2(fd, ZTEST_FD_RAND), ==, ZTEST_FD_RAND);
5836-
close(fd);
5837-
}
58385827
}
58395828

58405829
static int
@@ -5858,10 +5847,10 @@ setup_hdr(void)
58585847
ztest_shared_hdr_t *hdr;
58595848

58605849
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
5861-
PROT_READ | PROT_WRITE, MAP_SHARED, ZTEST_FD_DATA, 0);
5850+
PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
58625851
ASSERT(hdr != MAP_FAILED);
58635852

5864-
VERIFY3U(0, ==, ftruncate(ZTEST_FD_DATA, sizeof (ztest_shared_hdr_t)));
5853+
VERIFY3U(0, ==, ftruncate(ztest_fd_data, sizeof (ztest_shared_hdr_t)));
58655854

58665855
hdr->zh_hdr_size = sizeof (ztest_shared_hdr_t);
58675856
hdr->zh_opts_size = sizeof (ztest_shared_opts_t);
@@ -5872,7 +5861,7 @@ setup_hdr(void)
58725861
hdr->zh_ds_count = ztest_opts.zo_datasets;
58735862

58745863
size = shared_data_size(hdr);
5875-
VERIFY3U(0, ==, ftruncate(ZTEST_FD_DATA, size));
5864+
VERIFY3U(0, ==, ftruncate(ztest_fd_data, size));
58765865

58775866
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
58785867
}
@@ -5885,14 +5874,14 @@ setup_data(void)
58855874
uint8_t *buf;
58865875

58875876
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
5888-
PROT_READ, MAP_SHARED, ZTEST_FD_DATA, 0);
5877+
PROT_READ, MAP_SHARED, ztest_fd_data, 0);
58895878
ASSERT(hdr != MAP_FAILED);
58905879

58915880
size = shared_data_size(hdr);
58925881

58935882
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
58945883
hdr = ztest_shared_hdr = (void *)mmap(0, P2ROUNDUP(size, getpagesize()),
5895-
PROT_READ | PROT_WRITE, MAP_SHARED, ZTEST_FD_DATA, 0);
5884+
PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
58965885
ASSERT(hdr != MAP_FAILED);
58975886
buf = (uint8_t *)hdr;
58985887

@@ -5925,9 +5914,15 @@ exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
59255914

59265915
if (pid == 0) { /* child */
59275916
char *emptyargv[2] = { cmd, NULL };
5917+
char fd_data_str[12];
59285918

59295919
struct rlimit rl = { 1024, 1024 };
59305920
(void) setrlimit(RLIMIT_NOFILE, &rl);
5921+
5922+
(void) close(ztest_fd_rand);
5923+
VERIFY(11 >= snprintf(fd_data_str, 12, "%d", ztest_fd_data));
5924+
VERIFY(0 == setenv("ZTEST_FD_DATA", fd_data_str, 1));
5925+
59315926
(void) enable_extended_FILE_stdio(-1, -1);
59325927
if (libpath != NULL)
59335928
VERIFY(0 == setenv("LD_LIBRARY_PATH", libpath, 1));
@@ -6005,22 +6000,24 @@ main(int argc, char **argv)
60056000
char cmd[MAXNAMELEN];
60066001
boolean_t hasalt;
60076002
int f;
6008-
boolean_t ischild = (0 == lseek(ZTEST_FD_DATA, 0, SEEK_CUR));
6009-
6010-
ASSERT(ischild || errno == EBADF || errno == ESPIPE);
6003+
char *fd_data_str = getenv("ZTEST_FD_DATA");
60116004

60126005
(void) setvbuf(stdout, NULL, _IOLBF, 0);
60136006

6014-
if (!ischild) {
6007+
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
6008+
ASSERT3S(ztest_fd_rand, >=, 0);
6009+
6010+
if (!fd_data_str) {
60156011
dprintf_setup(&argc, argv);
60166012
process_options(argc, argv);
60176013

6018-
setup_fds();
6014+
setup_data_fd();
60196015
setup_hdr();
60206016
setup_data();
60216017
bcopy(&ztest_opts, ztest_shared_opts,
60226018
sizeof (*ztest_shared_opts));
60236019
} else {
6020+
ztest_fd_data = atoi(fd_data_str);
60246021
setup_data();
60256022
bcopy(ztest_shared_opts, &ztest_opts, sizeof (ztest_opts));
60266023
}
@@ -6029,12 +6026,12 @@ main(int argc, char **argv)
60296026
/* Override location of zpool.cache */
60306027
(void) asprintf((char **)&spa_config_path, "%s/zpool.cache",
60316028
ztest_opts.zo_dir);
6032-
6029+
60336030
ztest_ds = umem_alloc(ztest_opts.zo_datasets * sizeof (ztest_ds_t),
60346031
UMEM_NOFAIL);
60356032
zs = ztest_shared;
60366033

6037-
if (ischild) {
6034+
if (fd_data_str) {
60386035
metaslab_gang_bang = ztest_opts.zo_metaslab_gang_bang;
60396036
metaslab_df_alloc_threshold =
60406037
zs->zs_metaslab_df_alloc_threshold;

0 commit comments

Comments
 (0)