mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-02-10 09:21:09 +03:00
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>
This commit is contained in:
parent
22257dc0d5
commit
9d81146b01
@ -121,8 +121,8 @@
|
|||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
|
|
||||||
#define ZTEST_FD_DATA 3
|
static int ztest_fd_data = -1;
|
||||||
#define ZTEST_FD_RAND 4
|
static int ztest_fd_rand = -1;
|
||||||
|
|
||||||
typedef struct ztest_shared_hdr {
|
typedef struct ztest_shared_hdr {
|
||||||
uint64_t zh_hdr_size;
|
uint64_t zh_hdr_size;
|
||||||
@ -783,10 +783,12 @@ ztest_random(uint64_t range)
|
|||||||
{
|
{
|
||||||
uint64_t r;
|
uint64_t r;
|
||||||
|
|
||||||
|
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||||
|
|
||||||
if (range == 0)
|
if (range == 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (read(ZTEST_FD_RAND, &r, sizeof (r)) != sizeof (r))
|
if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
|
||||||
fatal(1, "short read from /dev/urandom");
|
fatal(1, "short read from /dev/urandom");
|
||||||
|
|
||||||
return (r % range);
|
return (r % range);
|
||||||
@ -5815,26 +5817,13 @@ ztest_init(ztest_shared_t *zs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_fds(void)
|
setup_data_fd(void)
|
||||||
{
|
{
|
||||||
int fd;
|
|
||||||
|
|
||||||
char *tmp = tempnam(NULL, NULL);
|
char *tmp = tempnam(NULL, NULL);
|
||||||
fd = open(tmp, O_RDWR | O_CREAT, 0700);
|
ztest_fd_data = open(tmp, O_RDWR | O_CREAT, 0700);
|
||||||
ASSERT3S(fd, >=, 0);
|
ASSERT3S(ztest_fd_data, >=, 0);
|
||||||
if (fd != ZTEST_FD_DATA) {
|
|
||||||
VERIFY3S(dup2(fd, ZTEST_FD_DATA), ==, ZTEST_FD_DATA);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
(void) unlink(tmp);
|
(void) unlink(tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
|
||||||
ASSERT3S(fd, >=, 0);
|
|
||||||
if (fd != ZTEST_FD_RAND) {
|
|
||||||
VERIFY3S(dup2(fd, ZTEST_FD_RAND), ==, ZTEST_FD_RAND);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -5858,10 +5847,10 @@ setup_hdr(void)
|
|||||||
ztest_shared_hdr_t *hdr;
|
ztest_shared_hdr_t *hdr;
|
||||||
|
|
||||||
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
|
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, ZTEST_FD_DATA, 0);
|
PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
|
||||||
ASSERT(hdr != MAP_FAILED);
|
ASSERT(hdr != MAP_FAILED);
|
||||||
|
|
||||||
VERIFY3U(0, ==, ftruncate(ZTEST_FD_DATA, sizeof (ztest_shared_hdr_t)));
|
VERIFY3U(0, ==, ftruncate(ztest_fd_data, sizeof (ztest_shared_hdr_t)));
|
||||||
|
|
||||||
hdr->zh_hdr_size = sizeof (ztest_shared_hdr_t);
|
hdr->zh_hdr_size = sizeof (ztest_shared_hdr_t);
|
||||||
hdr->zh_opts_size = sizeof (ztest_shared_opts_t);
|
hdr->zh_opts_size = sizeof (ztest_shared_opts_t);
|
||||||
@ -5872,7 +5861,7 @@ setup_hdr(void)
|
|||||||
hdr->zh_ds_count = ztest_opts.zo_datasets;
|
hdr->zh_ds_count = ztest_opts.zo_datasets;
|
||||||
|
|
||||||
size = shared_data_size(hdr);
|
size = shared_data_size(hdr);
|
||||||
VERIFY3U(0, ==, ftruncate(ZTEST_FD_DATA, size));
|
VERIFY3U(0, ==, ftruncate(ztest_fd_data, size));
|
||||||
|
|
||||||
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
|
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
|
||||||
}
|
}
|
||||||
@ -5885,14 +5874,14 @@ setup_data(void)
|
|||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
|
|
||||||
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
|
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
|
||||||
PROT_READ, MAP_SHARED, ZTEST_FD_DATA, 0);
|
PROT_READ, MAP_SHARED, ztest_fd_data, 0);
|
||||||
ASSERT(hdr != MAP_FAILED);
|
ASSERT(hdr != MAP_FAILED);
|
||||||
|
|
||||||
size = shared_data_size(hdr);
|
size = shared_data_size(hdr);
|
||||||
|
|
||||||
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
|
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
|
||||||
hdr = ztest_shared_hdr = (void *)mmap(0, P2ROUNDUP(size, getpagesize()),
|
hdr = ztest_shared_hdr = (void *)mmap(0, P2ROUNDUP(size, getpagesize()),
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, ZTEST_FD_DATA, 0);
|
PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
|
||||||
ASSERT(hdr != MAP_FAILED);
|
ASSERT(hdr != MAP_FAILED);
|
||||||
buf = (uint8_t *)hdr;
|
buf = (uint8_t *)hdr;
|
||||||
|
|
||||||
@ -5925,9 +5914,15 @@ exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
|
|||||||
|
|
||||||
if (pid == 0) { /* child */
|
if (pid == 0) { /* child */
|
||||||
char *emptyargv[2] = { cmd, NULL };
|
char *emptyargv[2] = { cmd, NULL };
|
||||||
|
char fd_data_str[12];
|
||||||
|
|
||||||
struct rlimit rl = { 1024, 1024 };
|
struct rlimit rl = { 1024, 1024 };
|
||||||
(void) setrlimit(RLIMIT_NOFILE, &rl);
|
(void) setrlimit(RLIMIT_NOFILE, &rl);
|
||||||
|
|
||||||
|
(void) close(ztest_fd_rand);
|
||||||
|
VERIFY(11 >= snprintf(fd_data_str, 12, "%d", ztest_fd_data));
|
||||||
|
VERIFY(0 == setenv("ZTEST_FD_DATA", fd_data_str, 1));
|
||||||
|
|
||||||
(void) enable_extended_FILE_stdio(-1, -1);
|
(void) enable_extended_FILE_stdio(-1, -1);
|
||||||
if (libpath != NULL)
|
if (libpath != NULL)
|
||||||
VERIFY(0 == setenv("LD_LIBRARY_PATH", libpath, 1));
|
VERIFY(0 == setenv("LD_LIBRARY_PATH", libpath, 1));
|
||||||
@ -6005,22 +6000,24 @@ main(int argc, char **argv)
|
|||||||
char cmd[MAXNAMELEN];
|
char cmd[MAXNAMELEN];
|
||||||
boolean_t hasalt;
|
boolean_t hasalt;
|
||||||
int f;
|
int f;
|
||||||
boolean_t ischild = (0 == lseek(ZTEST_FD_DATA, 0, SEEK_CUR));
|
char *fd_data_str = getenv("ZTEST_FD_DATA");
|
||||||
|
|
||||||
ASSERT(ischild || errno == EBADF || errno == ESPIPE);
|
|
||||||
|
|
||||||
(void) setvbuf(stdout, NULL, _IOLBF, 0);
|
(void) setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
if (!ischild) {
|
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
|
||||||
|
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||||
|
|
||||||
|
if (!fd_data_str) {
|
||||||
dprintf_setup(&argc, argv);
|
dprintf_setup(&argc, argv);
|
||||||
process_options(argc, argv);
|
process_options(argc, argv);
|
||||||
|
|
||||||
setup_fds();
|
setup_data_fd();
|
||||||
setup_hdr();
|
setup_hdr();
|
||||||
setup_data();
|
setup_data();
|
||||||
bcopy(&ztest_opts, ztest_shared_opts,
|
bcopy(&ztest_opts, ztest_shared_opts,
|
||||||
sizeof (*ztest_shared_opts));
|
sizeof (*ztest_shared_opts));
|
||||||
} else {
|
} else {
|
||||||
|
ztest_fd_data = atoi(fd_data_str);
|
||||||
setup_data();
|
setup_data();
|
||||||
bcopy(ztest_shared_opts, &ztest_opts, sizeof (ztest_opts));
|
bcopy(ztest_shared_opts, &ztest_opts, sizeof (ztest_opts));
|
||||||
}
|
}
|
||||||
@ -6034,7 +6031,7 @@ main(int argc, char **argv)
|
|||||||
UMEM_NOFAIL);
|
UMEM_NOFAIL);
|
||||||
zs = ztest_shared;
|
zs = ztest_shared;
|
||||||
|
|
||||||
if (ischild) {
|
if (fd_data_str) {
|
||||||
metaslab_gang_bang = ztest_opts.zo_metaslab_gang_bang;
|
metaslab_gang_bang = ztest_opts.zo_metaslab_gang_bang;
|
||||||
metaslab_df_alloc_threshold =
|
metaslab_df_alloc_threshold =
|
||||||
zs->zs_metaslab_df_alloc_threshold;
|
zs->zs_metaslab_df_alloc_threshold;
|
||||||
|
Loading…
Reference in New Issue
Block a user