diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 96db9c4b9..18a94da1f 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -8778,8 +8778,12 @@ main(int argc, char **argv) args.path = searchdirs; args.can_be_active = B_TRUE; - error = zpool_find_config(NULL, target_pool, &cfg, &args, - &libzpool_config_ops); + libpc_handle_t lpch = { + .lpc_lib_handle = NULL, + .lpc_ops = &libzpool_config_ops, + .lpc_printerr = B_TRUE + }; + error = zpool_find_config(&lpch, target_pool, &cfg, &args); if (error == 0) { diff --git a/cmd/zhack.c b/cmd/zhack.c index 8797a53e4..a1063ab14 100644 --- a/cmd/zhack.c +++ b/cmd/zhack.c @@ -140,8 +140,12 @@ zhack_import(char *target, boolean_t readonly) g_importargs.can_be_active = readonly; g_pool = strdup(target); - error = zpool_find_config(NULL, target, &config, &g_importargs, - &libzpool_config_ops); + libpc_handle_t lpch = { + .lpc_lib_handle = NULL, + .lpc_ops = &libzpool_config_ops, + .lpc_printerr = B_TRUE + }; + error = zpool_find_config(&lpch, target, &config, &g_importargs); if (error) fatal(NULL, FTAG, "cannot import '%s'", target); diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 39ea615f6..8a4f3dd16 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -3773,7 +3773,12 @@ zpool_do_import(int argc, char **argv) idata.scan = do_scan; idata.policy = policy; - pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops); + libpc_handle_t lpch = { + .lpc_lib_handle = g_zfs, + .lpc_ops = &libzfs_config_ops, + .lpc_printerr = B_TRUE + }; + pools = zpool_search_import(&lpch, &idata); if (pools != NULL && pool_exists && (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { @@ -3829,7 +3834,7 @@ zpool_do_import(int argc, char **argv) */ idata.scan = B_TRUE; nvlist_free(pools); - pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops); + pools = zpool_search_import(&lpch, &idata); err = import_pools(pools, props, mntopts, flags, argc >= 1 ? argv[0] : NULL, diff --git a/cmd/ztest.c b/cmd/ztest.c index e630d3353..668a267b6 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -7471,8 +7471,12 @@ ztest_import_impl(void) args.path = searchdirs; args.can_be_active = B_FALSE; - VERIFY0(zpool_find_config(NULL, ztest_opts.zo_pool, &cfg, &args, - &libzpool_config_ops)); + libpc_handle_t lpch = { + .lpc_lib_handle = NULL, + .lpc_ops = &libzpool_config_ops, + .lpc_printerr = B_TRUE + }; + VERIFY0(zpool_find_config(&lpch, ztest_opts.zo_pool, &cfg, &args)); VERIFY0(spa_import(ztest_opts.zo_pool, cfg, NULL, flags)); fnvlist_free(cfg); } diff --git a/include/libzutil.h b/include/libzutil.h index 0b4075c16..617dd0cd1 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -59,6 +59,15 @@ typedef const struct pool_config_ops { _LIBZUTIL_H pool_config_ops_t libzfs_config_ops; _LIBZUTIL_H pool_config_ops_t libzpool_config_ops; +typedef enum lpc_error { + LPC_SUCCESS = 0, /* no error -- success */ + LPC_BADCACHE = 2000, /* out of memory */ + LPC_BADPATH, /* must be an absolute path */ + LPC_NOMEM, /* out of memory */ + LPC_EACCESS, /* some devices require root privileges */ + LPC_UNKNOWN +} lpc_error_t; + typedef struct importargs { char **path; /* a list of paths to search */ int paths; /* number of paths to search */ @@ -70,10 +79,20 @@ typedef struct importargs { nvlist_t *policy; /* load policy (max txg, rewind, etc.) */ } importargs_t; -_LIBZUTIL_H nvlist_t *zpool_search_import(void *, importargs_t *, - pool_config_ops_t *); -_LIBZUTIL_H int zpool_find_config(void *, const char *, nvlist_t **, - importargs_t *, pool_config_ops_t *); +typedef struct libpc_handle { + int lpc_error; + boolean_t lpc_printerr; + boolean_t lpc_open_access_error; + boolean_t lpc_desc_active; + char lpc_desc[1024]; + pool_config_ops_t *lpc_ops; + void *lpc_lib_handle; +} libpc_handle_t; + +_LIBZUTIL_H const char *libpc_error_description(libpc_handle_t *); +_LIBZUTIL_H nvlist_t *zpool_search_import(libpc_handle_t *, importargs_t *); +_LIBZUTIL_H int zpool_find_config(libpc_handle_t *, const char *, nvlist_t **, + importargs_t *); _LIBZUTIL_H const char * const * zpool_default_search_paths(size_t *count); _LIBZUTIL_H int zpool_read_label(int, nvlist_t **, int *); diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index 3471bcac9..87b65a4cf 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -191,6 +191,7 @@ + @@ -4569,7 +4570,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4578,17 +4604,15 @@ - + - - + - diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index e3f1c8942..fbf390587 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -71,6 +71,30 @@ #include "zutil_import.h" +const char * +libpc_error_description(libpc_handle_t *hdl) +{ + if (hdl->lpc_desc[0] != '\0') + return (hdl->lpc_desc); + + switch (hdl->lpc_error) { + case LPC_BADCACHE: + return (dgettext(TEXT_DOMAIN, "invalid or missing cache file")); + case LPC_BADPATH: + return (dgettext(TEXT_DOMAIN, "must be an absolute path")); + case LPC_NOMEM: + return (dgettext(TEXT_DOMAIN, "out of memory")); + case LPC_EACCESS: + return (dgettext(TEXT_DOMAIN, "some devices require root " + "privileges")); + case LPC_UNKNOWN: + return (dgettext(TEXT_DOMAIN, "unknown error")); + default: + assert(hdl->lpc_error == 0); + return (dgettext(TEXT_DOMAIN, "no error")); + } +} + static __attribute__((format(printf, 2, 3))) void zutil_error_aux(libpc_handle_t *hdl, const char *fmt, ...) { @@ -85,28 +109,27 @@ zutil_error_aux(libpc_handle_t *hdl, const char *fmt, ...) } static void -zutil_verror(libpc_handle_t *hdl, const char *error, const char *fmt, +zutil_verror(libpc_handle_t *hdl, lpc_error_t error, const char *fmt, va_list ap) { char action[1024]; (void) vsnprintf(action, sizeof (action), fmt, ap); + hdl->lpc_error = error; if (hdl->lpc_desc_active) hdl->lpc_desc_active = B_FALSE; else hdl->lpc_desc[0] = '\0'; - if (hdl->lpc_printerr) { - if (hdl->lpc_desc[0] != '\0') - error = hdl->lpc_desc; - - (void) fprintf(stderr, "%s: %s\n", action, error); - } + if (hdl->lpc_printerr) + (void) fprintf(stderr, "%s: %s\n", action, + libpc_error_description(hdl)); } static __attribute__((format(printf, 3, 4))) int -zutil_error_fmt(libpc_handle_t *hdl, const char *error, const char *fmt, ...) +zutil_error_fmt(libpc_handle_t *hdl, lpc_error_t error, + const char *fmt, ...) { va_list ap; @@ -120,7 +143,7 @@ zutil_error_fmt(libpc_handle_t *hdl, const char *error, const char *fmt, ...) } static int -zutil_error(libpc_handle_t *hdl, const char *error, const char *msg) +zutil_error(libpc_handle_t *hdl, lpc_error_t error, const char *msg) { return (zutil_error_fmt(hdl, error, "%s", msg)); } @@ -128,7 +151,7 @@ zutil_error(libpc_handle_t *hdl, const char *error, const char *msg) static int zutil_no_memory(libpc_handle_t *hdl) { - zutil_error(hdl, EZFS_NOMEM, "internal error"); + zutil_error(hdl, LPC_NOMEM, "internal error"); exit(1); } @@ -1244,8 +1267,8 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock, return (0); zutil_error_aux(hdl, "%s", strerror(error)); - (void) zutil_error_fmt(hdl, EZFS_BADPATH, dgettext( - TEXT_DOMAIN, "cannot resolve path '%s'"), dir); + (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN, + "cannot resolve path '%s'"), dir); return (error); } @@ -1253,8 +1276,8 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock, if (dirp == NULL) { error = errno; zutil_error_aux(hdl, "%s", strerror(error)); - (void) zutil_error_fmt(hdl, EZFS_BADPATH, - dgettext(TEXT_DOMAIN, "cannot open '%s'"), path); + (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN, + "cannot open '%s'"), path); return (error); } @@ -1315,8 +1338,8 @@ zpool_find_import_scan_path(libpc_handle_t *hdl, pthread_mutex_t *lock, } zutil_error_aux(hdl, "%s", strerror(error)); - (void) zutil_error_fmt(hdl, EZFS_BADPATH, dgettext( - TEXT_DOMAIN, "cannot resolve path '%s'"), dir); + (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN, + "cannot resolve path '%s'"), dir); goto out; } @@ -1353,7 +1376,7 @@ zpool_find_import_scan(libpc_handle_t *hdl, pthread_mutex_t *lock, continue; zutil_error_aux(hdl, "%s", strerror(error)); - (void) zutil_error_fmt(hdl, EZFS_BADPATH, dgettext( + (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext( TEXT_DOMAIN, "cannot resolve path '%s'"), dir[i]); goto error; } @@ -1574,16 +1597,16 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg) if ((fd = open(iarg->cachefile, O_RDONLY | O_CLOEXEC)) < 0) { zutil_error_aux(hdl, "%s", strerror(errno)); - (void) zutil_error(hdl, EZFS_BADCACHE, - dgettext(TEXT_DOMAIN, "failed to open cache file")); + (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN, + "failed to open cache file")); return (NULL); } if (fstat64(fd, &statbuf) != 0) { zutil_error_aux(hdl, "%s", strerror(errno)); (void) close(fd); - (void) zutil_error(hdl, EZFS_BADCACHE, - dgettext(TEXT_DOMAIN, "failed to get size of cache file")); + (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN, + "failed to get size of cache file")); return (NULL); } @@ -1595,8 +1618,7 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg) if (read(fd, buf, statbuf.st_size) != statbuf.st_size) { (void) close(fd); free(buf); - (void) zutil_error(hdl, EZFS_BADCACHE, - dgettext(TEXT_DOMAIN, + (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN, "failed to read cache file contents")); return (NULL); } @@ -1605,8 +1627,7 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg) if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) { free(buf); - (void) zutil_error(hdl, EZFS_BADCACHE, - dgettext(TEXT_DOMAIN, + (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN, "invalid or corrupt cache file contents")); return (NULL); } @@ -1777,25 +1798,20 @@ zpool_find_import(libpc_handle_t *hdl, importargs_t *iarg) nvlist_t * -zpool_search_import(void *hdl, importargs_t *import, pool_config_ops_t *pco) +zpool_search_import(libpc_handle_t *hdl, importargs_t *import) { - libpc_handle_t handle = { 0 }; nvlist_t *pools = NULL; - handle.lpc_lib_handle = hdl; - handle.lpc_ops = pco; - handle.lpc_printerr = B_TRUE; - verify(import->poolname == NULL || import->guid == 0); if (import->cachefile != NULL) - pools = zpool_find_import_cached(&handle, import); + pools = zpool_find_import_cached(hdl, import); else - pools = zpool_find_import(&handle, import); + pools = zpool_find_import(hdl, import); if ((pools == NULL || nvlist_empty(pools)) && - handle.lpc_open_access_error && geteuid() != 0) { - (void) zutil_error(&handle, EZFS_EACESS, dgettext(TEXT_DOMAIN, + hdl->lpc_open_access_error && geteuid() != 0) { + (void) zutil_error(hdl, LPC_EACCESS, dgettext(TEXT_DOMAIN, "no pools found")); } @@ -1819,8 +1835,8 @@ pool_match(nvlist_t *cfg, char *tgt) } int -zpool_find_config(void *hdl, const char *target, nvlist_t **configp, - importargs_t *args, pool_config_ops_t *pco) +zpool_find_config(libpc_handle_t *hdl, const char *target, nvlist_t **configp, + importargs_t *args) { nvlist_t *pools; nvlist_t *match = NULL; @@ -1834,7 +1850,7 @@ zpool_find_config(void *hdl, const char *target, nvlist_t **configp, if ((sepp = strpbrk(targetdup, "/@")) != NULL) *sepp = '\0'; - pools = zpool_search_import(hdl, args, pco); + pools = zpool_search_import(hdl, args); if (pools != NULL) { nvpair_t *elem = NULL; diff --git a/lib/libzutil/zutil_import.h b/lib/libzutil/zutil_import.h index 482315e44..f851a9113 100644 --- a/lib/libzutil/zutil_import.h +++ b/lib/libzutil/zutil_import.h @@ -28,26 +28,11 @@ #ifndef _LIBZUTIL_ZUTIL_IMPORT_H_ #define _LIBZUTIL_ZUTIL_IMPORT_H_ -#define EZFS_BADCACHE "invalid or missing cache file" -#define EZFS_BADPATH "must be an absolute path" -#define EZFS_NOMEM "out of memory" -#define EZFS_EACESS "some devices require root privileges" - #define IMPORT_ORDER_PREFERRED_1 1 #define IMPORT_ORDER_PREFERRED_2 2 #define IMPORT_ORDER_SCAN_OFFSET 10 #define IMPORT_ORDER_DEFAULT 100 -typedef struct libpc_handle { - boolean_t lpc_printerr; - boolean_t lpc_open_access_error; - boolean_t lpc_desc_active; - char lpc_desc[1024]; - pool_config_ops_t *lpc_ops; - void *lpc_lib_handle; -} libpc_handle_t; - - int label_paths(libpc_handle_t *hdl, nvlist_t *label, char **path, char **devid); int zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,