diff --git a/include/libzutil.h b/include/libzutil.h index 839486fb62bf..d9a9a65753dd 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -26,6 +26,8 @@ #ifndef _LIBZUTIL_H #define _LIBZUTIL_H extern __attribute__((visibility("default"))) +#include +#include #include #include @@ -267,6 +269,14 @@ int for_each_vdev_in_nvlist(nvlist_t *nvroot, pool_vdev_iter_f func, void update_vdevs_config_dev_sysfs_path(nvlist_t *config); _LIBZUTIL_H void update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path, const char *key); + +/* + * Thread-safe strerror() for use in ZFS libraries + */ +static inline char *zfs_strerror(int errnum) { + return (strerror_l(errnum, uselocale(0))); +} + #ifdef __cplusplus } #endif diff --git a/lib/libshare/nfs.c b/lib/libshare/nfs.c index 3962c87453d4..77ed14f322ed 100644 --- a/lib/libshare/nfs.c +++ b/lib/libshare/nfs.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "nfs.h" @@ -45,7 +46,8 @@ nfs_exports_lock(const char *name, int *nfs_lock_fd) *nfs_lock_fd = open(name, O_RDWR | O_CREAT | O_CLOEXEC, 0600); if (*nfs_lock_fd == -1) { err = errno; - fprintf(stderr, "failed to lock %s: %s\n", name, strerror(err)); + fprintf(stderr, "failed to lock %s: %s\n", name, + zfs_strerror(err)); return (err); } @@ -53,7 +55,8 @@ nfs_exports_lock(const char *name, int *nfs_lock_fd) ; if (err != 0) { err = errno; - fprintf(stderr, "failed to lock %s: %s\n", name, strerror(err)); + fprintf(stderr, "failed to lock %s: %s\n", name, + zfs_strerror(err)); (void) close(*nfs_lock_fd); *nfs_lock_fd = -1; return (err); @@ -69,7 +72,7 @@ nfs_exports_unlock(const char *name, int *nfs_lock_fd) if (flock(*nfs_lock_fd, LOCK_UN) != 0) fprintf(stderr, "failed to unlock %s: %s\n", - name, strerror(errno)); + name, zfs_strerror(errno)); (void) close(*nfs_lock_fd); *nfs_lock_fd = -1; @@ -92,7 +95,7 @@ nfs_init_tmpfile(const char *prefix, const char *mdir, struct tmpfile *tmpf) errno != EEXIST) { fprintf(stderr, "failed to create %s: %s\n", // cppcheck-suppress uninitvar - mdir, strerror(errno)); + mdir, zfs_strerror(errno)); return (B_FALSE); } @@ -102,14 +105,14 @@ nfs_init_tmpfile(const char *prefix, const char *mdir, struct tmpfile *tmpf) int fd = mkostemp(tmpf->name, O_CLOEXEC); if (fd == -1) { fprintf(stderr, "Unable to create temporary file: %s", - strerror(errno)); + zfs_strerror(errno)); return (B_FALSE); } tmpf->fp = fdopen(fd, "w+"); if (tmpf->fp == NULL) { fprintf(stderr, "Unable to reopen temporary file: %s", - strerror(errno)); + zfs_strerror(errno)); close(fd); return (B_FALSE); } @@ -129,14 +132,14 @@ nfs_fini_tmpfile(const char *exports, struct tmpfile *tmpf) { if (fflush(tmpf->fp) != 0) { fprintf(stderr, "Failed to write to temporary file: %s\n", - strerror(errno)); + zfs_strerror(errno)); nfs_abort_tmpfile(tmpf); return (SA_SYSTEM_ERR); } if (rename(tmpf->name, exports) == -1) { fprintf(stderr, "Unable to rename %s -> %s: %s\n", - tmpf->name, exports, strerror(errno)); + tmpf->name, exports, zfs_strerror(errno)); nfs_abort_tmpfile(tmpf); return (SA_SYSTEM_ERR); } @@ -213,7 +216,7 @@ nfs_process_exports(const char *exports, const char *mountpoint, if (fclose(oldfp) != 0) { fprintf(stderr, "Unable to close file %s: %s\n", - exports, strerror(errno)); + exports, zfs_strerror(errno)); error = error != SA_OK ? error : SA_SYSTEM_ERR; } } diff --git a/lib/libspl/os/freebsd/getmntany.c b/lib/libspl/os/freebsd/getmntany.c index fc875fcb133f..fc1c9de6df81 100644 --- a/lib/libspl/os/freebsd/getmntany.c +++ b/lib/libspl/os/freebsd/getmntany.c @@ -36,6 +36,7 @@ #include #include #include +#include int getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf) @@ -49,13 +50,13 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf) if (stat64(path, statbuf) != 0) { (void) fprintf(stderr, "cannot open '%s': %s\n", - path, strerror(errno)); + path, zfs_strerror(errno)); return (-1); } if (statfs(path, &sfs) != 0) { (void) fprintf(stderr, "%s: %s\n", path, - strerror(errno)); + zfs_strerror(errno)); return (-1); } statfs2mnttab(&sfs, (struct mnttab *)entry); diff --git a/lib/libspl/os/linux/getmntany.c b/lib/libspl/os/linux/getmntany.c index 7e3722cd373e..a46c4e931719 100644 --- a/lib/libspl/os/linux/getmntany.c +++ b/lib/libspl/os/linux/getmntany.c @@ -38,6 +38,7 @@ #include #include #include +#include #define BUFSIZE (MNT_LINE_MAX + 2) @@ -122,7 +123,7 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf) */ if (stat64(path, statbuf) != 0) { (void) fprintf(stderr, "cannot open '%s': %s\n", - path, strerror(errno)); + path, zfs_strerror(errno)); return (-1); } diff --git a/lib/libzfs/libzfs_crypto.c b/lib/libzfs/libzfs_crypto.c index 8f2a50d55e87..93dfa9cbc2c0 100644 --- a/lib/libzfs/libzfs_crypto.c +++ b/lib/libzfs/libzfs_crypto.c @@ -37,6 +37,7 @@ #include #endif #include +#include #include "libzfs_impl.h" #include "zfeature_common.h" @@ -493,7 +494,7 @@ get_key_material_file(libzfs_handle_t *hdl, const char *uri, ret = errno; errno = 0; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "Failed to open key material file: %s"), strerror(ret)); + "Failed to open key material file: %s"), zfs_strerror(ret)); return (ret); } @@ -595,7 +596,7 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri, "%s/libzfs-XXXXXXXX.https", getenv("TMPDIR") ?: "/tmp") == -1) { ret = ENOMEM; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s"), - strerror(ret)); + zfs_strerror(ret)); goto end; } @@ -604,7 +605,7 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri, ret = errno; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Couldn't create temporary file %s: %s"), - path, strerror(ret)); + path, zfs_strerror(ret)); free(path); goto end; } @@ -616,7 +617,7 @@ get_key_material_https(libzfs_handle_t *hdl, const char *uri, ret = errno; (void) close(kfd); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "Couldn't reopen temporary file: %s"), strerror(ret)); + "Couldn't reopen temporary file: %s"), zfs_strerror(ret)); goto end; } diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index eaceabd23734..6f8773aed425 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -5225,7 +5225,7 @@ zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl) nvbuf = malloc(nvsz); if (nvbuf == NULL) { - err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno))); + err = (zfs_error(hdl, EZFS_NOMEM, zfs_strerror(errno))); goto out; } diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c index da2b26ef99ce..edf290c4d040 100644 --- a/lib/libzfs/libzfs_diff.c +++ b/lib/libzfs/libzfs_diff.c @@ -283,7 +283,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) fobjerr = get_stats_for_obj(di, di->fromsnap, dobj, fobjname, MAXPATHLEN, &fsb); if (fobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) { - zfs_error_aux(di->zhp->zfs_hdl, "%s", strerror(di->zerr)); + zfs_error_aux(di->zhp->zfs_hdl, "%s", zfs_strerror(di->zerr)); zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf); /* * Let's not print an error for the same object more than @@ -298,7 +298,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj) if (tobjerr && di->zerr != ENOTSUP && di->zerr != ENOENT) { if (!already_logged) { zfs_error_aux(di->zhp->zfs_hdl, - "%s", strerror(di->zerr)); + "%s", zfs_strerror(di->zerr)); zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf); } } @@ -445,7 +445,7 @@ differ(void *arg) if ((ofp = fdopen(di->outputfd, "w")) == NULL) { di->zerr = errno; - strlcpy(di->errbuf, strerror(errno), sizeof (di->errbuf)); + strlcpy(di->errbuf, zfs_strerror(errno), sizeof (di->errbuf)); (void) close(di->datafd); return ((void *)-1); } @@ -762,7 +762,7 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, } if (pipe2(pipefd, O_CLOEXEC)) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno)); teardown_differ_info(&di); return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, errbuf)); } @@ -776,7 +776,7 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, di.datafd = pipefd[0]; if (pthread_create(&tid, NULL, differ, &di)) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno)); (void) close(pipefd[0]); (void) close(pipefd[1]); teardown_differ_info(&di); @@ -802,14 +802,15 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "\n Not an earlier snapshot from the same fs")); } else if (errno != EPIPE || di.zerr == 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno)); } (void) close(pipefd[1]); (void) pthread_cancel(tid); (void) pthread_join(tid, NULL); teardown_differ_info(&di); if (di.zerr != 0 && di.zerr != EPIPE) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(di.zerr)); + zfs_error_aux(zhp->zfs_hdl, "%s", + zfs_strerror(di.zerr)); return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf)); } else { return (zfs_error(zhp->zfs_hdl, EZFS_DIFFDATA, errbuf)); @@ -820,7 +821,7 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap, (void) pthread_join(tid, NULL); if (di.zerr != 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(di.zerr)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(di.zerr)); return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf)); } teardown_differ_info(&di); diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index b38ad88096b2..ec6ebad2f180 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -74,6 +74,7 @@ #include #include +#include #include "libzfs_impl.h" #include @@ -466,7 +467,7 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint: %s"), - strerror(errno)); + zfs_strerror(errno)); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); @@ -524,7 +525,7 @@ zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); } else { - zfs_error_aux(hdl, "%s", strerror(rc)); + zfs_error_aux(hdl, "%s", zfs_strerror(rc)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index e9bc78aa8d39..d7b90ccb1cba 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -793,7 +793,7 @@ zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from, case EFAULT: case EROFS: case EINVAL: - zfs_error_aux(hdl, "%s", strerror(error)); + zfs_error_aux(hdl, "%s", zfs_strerror(error)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -876,7 +876,7 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj, case EFAULT: case EROFS: case EINVAL: - zfs_error_aux(hdl, "%s", strerror(errno)); + zfs_error_aux(hdl, "%s", zfs_strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -1632,7 +1632,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, err = pthread_create(&ptid, NULL, send_progress_thread, &pa); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno)); return (zfs_error(zhp->zfs_hdl, EZFS_THREADCREATEFAILED, errbuf)); } @@ -1651,7 +1651,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, return (err); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(err)); return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } @@ -1767,7 +1767,7 @@ find_redact_book(libzfs_handle_t *hdl, const char *path, "dataset to be sent no longer exists")); } else { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "unknown error: %s"), strerror(error)); + "unknown error: %s"), zfs_strerror(error)); } return (zfs_error(hdl, EZFS_BADPROP, errbuf)); } @@ -2004,7 +2004,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags, case ERANGE: case EFAULT: case EROFS: - zfs_error_aux(hdl, "%s", strerror(errno)); + zfs_error_aux(hdl, "%s", zfs_strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: @@ -2290,13 +2290,13 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd, err = dump_record(&drr, packbuf, buflen, &zc, fd); free(packbuf); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(err)); return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } err = send_conclusion_record(fd, &zc); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(err)); return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } @@ -2765,7 +2765,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd, err = pthread_create(&ptid, NULL, send_progress_thread, &pa); if (err != 0) { - zfs_error_aux(zhp->zfs_hdl, "%s", strerror(errno)); + zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno)); return (zfs_error(zhp->zfs_hdl, EZFS_THREADCREATEFAILED, errbuf)); } @@ -2823,7 +2823,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd, case EPIPE: case ERANGE: case EROFS: - zfs_error_aux(hdl, "%s", strerror(errno)); + zfs_error_aux(hdl, "%s", zfs_strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 778e511e0b32..d0a63a4daa8c 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -513,7 +513,7 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) zfs_verror(hdl, EZFS_NOT_USER_NAMESPACE, fmt, ap); break; default: - zfs_error_aux(hdl, "%s", strerror(error)); + zfs_error_aux(hdl, "%s", zfs_strerror(error)); zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); break; } @@ -769,7 +769,7 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) zfs_verror(hdl, EZFS_RAIDZ_EXPAND_IN_PROGRESS, fmt, ap); break; default: - zfs_error_aux(hdl, "%s", strerror(error)); + zfs_error_aux(hdl, "%s", zfs_strerror(error)); zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); } @@ -1968,7 +1968,7 @@ zfs_version_print(void) char *kver = zfs_version_kernel(); if (kver == NULL) { fprintf(stderr, "zfs_version_kernel() failed: %s\n", - strerror(errno)); + zfs_strerror(errno)); return (-1); } diff --git a/lib/libzfs/os/freebsd/libzfs_compat.c b/lib/libzfs/os/freebsd/libzfs_compat.c index aef2abf62568..2abf7755b518 100644 --- a/lib/libzfs/os/freebsd/libzfs_compat.c +++ b/lib/libzfs/os/freebsd/libzfs_compat.c @@ -212,7 +212,7 @@ libzfs_error_init(int error) msglen -= len; } - (void) snprintf(msg, msglen, "%s", strerror(error)); + (void) snprintf(msg, msglen, "%s", zfs_strerror(error)); return (errbuf); } diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index eb9131190458..06705ff4d9b4 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -1290,7 +1290,7 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock, if (error == ENOENT) return (0); - zutil_error_aux(hdl, "%s", strerror(error)); + zutil_error_aux(hdl, "%s", zfs_strerror(error)); (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN, "cannot resolve path '%s'"), dir); return (error); @@ -1299,7 +1299,7 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock, dirp = opendir(path); if (dirp == NULL) { error = errno; - zutil_error_aux(hdl, "%s", strerror(error)); + zutil_error_aux(hdl, "%s", zfs_strerror(error)); (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), path); return (error); @@ -1361,7 +1361,7 @@ zpool_find_import_scan_path(libpc_handle_t *hdl, pthread_mutex_t *lock, goto out; } - zutil_error_aux(hdl, "%s", strerror(error)); + zutil_error_aux(hdl, "%s", zfs_strerror(error)); (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext(TEXT_DOMAIN, "cannot resolve path '%s'"), dir); goto out; @@ -1399,7 +1399,7 @@ zpool_find_import_scan(libpc_handle_t *hdl, pthread_mutex_t *lock, if (error == ENOENT) continue; - zutil_error_aux(hdl, "%s", strerror(error)); + zutil_error_aux(hdl, "%s", zfs_strerror(error)); (void) zutil_error_fmt(hdl, LPC_BADPATH, dgettext( TEXT_DOMAIN, "cannot resolve path '%s'"), dir[i]); goto error; @@ -1629,14 +1629,14 @@ zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg) verify(iarg->poolname == NULL || iarg->guid == 0); if ((fd = open(iarg->cachefile, O_RDONLY | O_CLOEXEC)) < 0) { - zutil_error_aux(hdl, "%s", strerror(errno)); + zutil_error_aux(hdl, "%s", zfs_strerror(errno)); (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)); + zutil_error_aux(hdl, "%s", zfs_strerror(errno)); (void) close(fd); (void) zutil_error(hdl, LPC_BADCACHE, dgettext(TEXT_DOMAIN, "failed to get size of cache file"));