aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2015-11-20 15:50:06 -0800
committerBrian Behlendorf <[email protected]>2015-12-02 14:50:36 -0800
commit90aa094d6d77bf6f17a671ff76a84ae8232267d8 (patch)
treee5860ffa2cf16611b71e174edd04092628f918f6
parentb0fe1adeb1f24192c9a3358a4c9a29a34b9537fe (diff)
Fix zdb calling behavior in ztest
The current zdb calling behaviour is really fragile, and is guaranteed to segfault if ztest is not installed in either /sbin or /usr/sbin. With this patch, the ztest will try to call zdb in the following order. 1. Use environmental variable ZDB_PATH if provided. 2. If ztest resides in build tree, guess the in tree zdb path. 3. Just pass zdb to popen and let it search it in PATH. Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #3126
-rw-r--r--cmd/ztest/ztest.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index afe6faab0..1dc9eff77 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -5371,6 +5371,41 @@ ztest_spa_rename(ztest_ds_t *zd, uint64_t id)
(void) rw_unlock(&ztest_name_lock);
}
+static int
+ztest_check_path(char *path)
+{
+ struct stat s;
+ /* return true on success */
+ return (!stat(path, &s));
+}
+
+static void
+ztest_get_zdb_bin(char *bin, int len)
+{
+ char *zdb_path;
+ /*
+ * Try to use ZDB_PATH and in-tree zdb path. If not successful, just
+ * let popen to search through PATH.
+ */
+ if ((zdb_path = getenv("ZDB_PATH"))) {
+ strlcpy(bin, zdb_path, len); /* In env */
+ if (!ztest_check_path(bin)) {
+ ztest_dump_core = 0;
+ fatal(1, "invalid ZDB_PATH '%s'", bin);
+ }
+ return;
+ }
+
+ VERIFY(realpath(getexecname(), bin) != NULL);
+ if (strstr(bin, "/ztest/")) {
+ strstr(bin, "/ztest/")[0] = '\0'; /* In-tree */
+ strcat(bin, "/zdb/zdb");
+ if (ztest_check_path(bin))
+ return;
+ }
+ strcpy(bin, "zdb");
+}
+
/*
* Verify pool integrity by running zdb.
*/
@@ -5381,21 +5416,14 @@ ztest_run_zdb(char *pool)
char *bin;
char *zdb;
char *zbuf;
+ const int len = MAXPATHLEN + MAXNAMELEN + 20;
FILE *fp;
- bin = umem_alloc(MAXPATHLEN + MAXNAMELEN + 20, UMEM_NOFAIL);
- zdb = umem_alloc(MAXPATHLEN + MAXNAMELEN + 20, UMEM_NOFAIL);
+ bin = umem_alloc(len, UMEM_NOFAIL);
+ zdb = umem_alloc(len, UMEM_NOFAIL);
zbuf = umem_alloc(1024, UMEM_NOFAIL);
- VERIFY(realpath(getexecname(), bin) != NULL);
- if (strncmp(bin, "/usr/sbin/ztest", 15) == 0) {
- strcpy(bin, "/usr/sbin/zdb"); /* Installed */
- } else if (strncmp(bin, "/sbin/ztest", 11) == 0) {
- strcpy(bin, "/sbin/zdb"); /* Installed */
- } else {
- strstr(bin, "/ztest/")[0] = '\0'; /* In-tree */
- strcat(bin, "/zdb/zdb");
- }
+ ztest_get_zdb_bin(bin, len);
(void) sprintf(zdb,
"%s -bcc%s%s -d -U %s %s",
@@ -5425,8 +5453,8 @@ ztest_run_zdb(char *pool)
else
fatal(0, "'%s' died with signal %d", zdb, WTERMSIG(status));
out:
- umem_free(bin, MAXPATHLEN + MAXNAMELEN + 20);
- umem_free(zdb, MAXPATHLEN + MAXNAMELEN + 20);
+ umem_free(bin, len);
+ umem_free(zdb, len);
umem_free(zbuf, 1024);
}