ztest: take -B ./path/to/ztest, LD_LIBRARY_PATH=./path/lib:$L_L_P

This changes the behaviour of -B from the illumos one which would,
in the example in the manual, take just ./chroots/lenny;
this, however, is more versatile, and scales much better for systems
with ZFS in /usr/local, for example

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #13411
Closes #1770
This commit is contained in:
наб 2022-05-03 16:55:14 +02:00 committed by Brian Behlendorf
parent 951a3889d1
commit 888914486e
2 changed files with 48 additions and 53 deletions

View File

@ -929,8 +929,7 @@ process_options(int argc, char **argv)
int opt; int opt;
uint64_t value; uint64_t value;
char altdir[MAXNAMELEN] = { 0 }; const char *raid_kind = "random";
char raid_kind[8] = "random";
memcpy(zo, &ztest_opts_defaults, sizeof (*zo)); memcpy(zo, &ztest_opts_defaults, sizeof (*zo));
@ -978,7 +977,7 @@ process_options(int argc, char **argv)
zo->zo_raid_parity = MIN(MAX(value, 1), 3); zo->zo_raid_parity = MIN(MAX(value, 1), 3);
break; break;
case 'K': case 'K':
(void) strlcpy(raid_kind, optarg, sizeof (raid_kind)); raid_kind = optarg;
break; break;
case 'D': case 'D':
zo->zo_draid_data = MAX(1, value); zo->zo_draid_data = MAX(1, value);
@ -1037,7 +1036,8 @@ process_options(int argc, char **argv)
zo->zo_maxloops = MAX(1, value); zo->zo_maxloops = MAX(1, value);
break; break;
case 'B': case 'B':
(void) strlcpy(altdir, optarg, sizeof (altdir)); (void) strlcpy(zo->zo_alt_ztest, optarg,
sizeof (zo->zo_alt_ztest));
break; break;
case 'C': case 'C':
ztest_parse_name_value(optarg, zo); ztest_parse_name_value(optarg, zo);
@ -1076,8 +1076,7 @@ process_options(int argc, char **argv)
/* When raid choice is 'random' add a draid pool 50% of the time */ /* When raid choice is 'random' add a draid pool 50% of the time */
if (strcmp(raid_kind, "random") == 0) { if (strcmp(raid_kind, "random") == 0) {
(void) strlcpy(raid_kind, (ztest_random(2) == 0) ? raid_kind = (ztest_random(2) == 0) ? "draid" : "raidz";
"draid" : "raidz", sizeof (raid_kind));
if (ztest_opts.zo_verbose >= 3) if (ztest_opts.zo_verbose >= 3)
(void) printf("choosing RAID type '%s'\n", raid_kind); (void) printf("choosing RAID type '%s'\n", raid_kind);
@ -1127,51 +1126,28 @@ process_options(int argc, char **argv)
(zo->zo_vdevs > 0 ? zo->zo_time * NANOSEC / zo->zo_vdevs : (zo->zo_vdevs > 0 ? zo->zo_time * NANOSEC / zo->zo_vdevs :
UINT64_MAX >> 2); UINT64_MAX >> 2);
if (strlen(altdir) > 0) { if (*zo->zo_alt_ztest) {
char *cmd; const char *invalid_what = "ztest";
char *realaltdir; char *val = zo->zo_alt_ztest;
char *bin; if (0 != access(val, X_OK) ||
char *ztest; (strrchr(val, '/') == NULL && (errno = EINVAL)))
char *isa; goto invalid;
int isalen;
cmd = umem_alloc(MAXPATHLEN, UMEM_NOFAIL); int dirlen = strrchr(val, '/') - val;
realaltdir = umem_alloc(MAXPATHLEN, UMEM_NOFAIL); strncpy(zo->zo_alt_libpath, val, dirlen);
invalid_what = "library path", val = zo->zo_alt_libpath;
if (strrchr(val, '/') == NULL && (errno = EINVAL))
goto invalid;
*strrchr(val, '/') = '\0';
strlcat(val, "/lib", sizeof (zo->zo_alt_libpath));
VERIFY3P(NULL, !=, realpath(getexecname(), cmd)); if (0 != access(zo->zo_alt_libpath, X_OK))
if (0 != access(altdir, F_OK)) { goto invalid;
return;
invalid:
ztest_dump_core = B_FALSE; ztest_dump_core = B_FALSE;
fatal(B_TRUE, "invalid alternate ztest path: %s", fatal(B_TRUE, "invalid alternate %s %s", invalid_what, val);
altdir);
}
VERIFY3P(NULL, !=, realpath(altdir, realaltdir));
/*
* 'cmd' should be of the form "<anything>/usr/bin/<isa>/ztest".
* We want to extract <isa> to determine if we should use
* 32 or 64 bit binaries.
*/
bin = strstr(cmd, "/usr/bin/");
ztest = strstr(bin, "/ztest");
isa = bin + 9;
isalen = ztest - isa;
(void) snprintf(zo->zo_alt_ztest, sizeof (zo->zo_alt_ztest),
"%s/usr/bin/%.*s/ztest", realaltdir, isalen, isa);
(void) snprintf(zo->zo_alt_libpath, sizeof (zo->zo_alt_libpath),
"%s/usr/lib/%.*s", realaltdir, isalen, isa);
if (0 != access(zo->zo_alt_ztest, X_OK)) {
ztest_dump_core = B_FALSE;
fatal(B_TRUE, "invalid alternate ztest: %s",
zo->zo_alt_ztest);
} else if (0 != access(zo->zo_alt_libpath, X_OK)) {
ztest_dump_core = B_FALSE;
fatal(B_TRUE, "invalid alternate lib directory %s",
zo->zo_alt_libpath);
}
umem_free(cmd, MAXPATHLEN);
umem_free(realaltdir, MAXPATHLEN);
} }
} }
@ -1182,14 +1158,14 @@ ztest_kill(ztest_shared_t *zs)
zs->zs_space = metaslab_class_get_space(spa_normal_class(ztest_spa)); zs->zs_space = metaslab_class_get_space(spa_normal_class(ztest_spa));
/* /*
* Before we kill off ztest, make sure that the config is updated. * Before we kill ourselves, make sure that the config is updated.
* See comment above spa_write_cachefile(). * See comment above spa_write_cachefile().
*/ */
mutex_enter(&spa_namespace_lock); mutex_enter(&spa_namespace_lock);
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE); spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE);
mutex_exit(&spa_namespace_lock); mutex_exit(&spa_namespace_lock);
(void) kill(getpid(), SIGKILL); (void) raise(SIGKILL);
} }
static void static void
@ -7895,8 +7871,17 @@ exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
snprintf(fd_data_str, 12, "%d", ztest_fd_data)); snprintf(fd_data_str, 12, "%d", ztest_fd_data));
VERIFY0(setenv("ZTEST_FD_DATA", fd_data_str, 1)); VERIFY0(setenv("ZTEST_FD_DATA", fd_data_str, 1));
if (libpath != NULL) if (libpath != NULL) {
const char *curlp = getenv("LD_LIBRARY_PATH");
if (curlp == NULL)
VERIFY0(setenv("LD_LIBRARY_PATH", libpath, 1)); VERIFY0(setenv("LD_LIBRARY_PATH", libpath, 1));
else {
char *newlp = NULL;
VERIFY3S(-1, !=,
asprintf(&newlp, "%s:%s", libpath, curlp));
VERIFY0(setenv("LD_LIBRARY_PATH", newlp, 1));
}
}
(void) execl(cmd, cmd, (char *)NULL); (void) execl(cmd, cmd, (char *)NULL);
ztest_dump_core = B_FALSE; ztest_dump_core = B_FALSE;
fatal(B_TRUE, "exec failed: %s", cmd); fatal(B_TRUE, "exec failed: %s", cmd);

View File

@ -157,7 +157,17 @@ Time per pass.
Max loops in Max loops in
.Fn spa_freeze . .Fn spa_freeze .
.It Fl B , -alt-ztest Ns = .It Fl B , -alt-ztest Ns =
Alternate ztest path. Path to alternate ("older")
.Nm ztest
to drive, which will be used to initialise the pool, and, a stochastic half the time, to run the tests.
The parallel
.Pa lib
directory is prepended to
.Ev LD_LIBRARY_PATH ;
i.e. given
.Fl B Pa ./chroots/lenny/usr/bin/ Ns Nm ,
.Pa ./chroots/lenny/usr/lib
will be loaded.
.It Fl C , -vdev-class-state Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy random No (default: Sy random ) .It Fl C , -vdev-class-state Ns = Ns Sy on Ns | Ns Sy off Ns | Ns Sy random No (default: Sy random )
The vdev allocation class state. The vdev allocation class state.
.It Fl o , -option Ns = Ns Ar variable Ns = Ns Ar value .It Fl o , -option Ns = Ns Ar variable Ns = Ns Ar value