Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make userspace libs more threadsafe #15793

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/libzutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifndef _LIBZUTIL_H
#define _LIBZUTIL_H extern __attribute__((visibility("default")))

#include <string.h>
#include <locale.h>
#include <sys/nvpair.h>
#include <sys/fs/zfs.h>

Expand Down Expand Up @@ -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
Expand Down
21 changes: 12 additions & 9 deletions lib/libshare/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <errno.h>
#include <libshare.h>
#include <unistd.h>
#include <libzutil.h>
#include "nfs.h"


Expand All @@ -45,15 +46,17 @@ 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);
}

while ((err = flock(*nfs_lock_fd, LOCK_EX)) != 0 && errno == EINTR)
;
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);
Expand All @@ -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;
Expand All @@ -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);
}

Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/libspl/os/freebsd/getmntany.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libzutil.h>

int
getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion lib/libspl/os/linux/getmntany.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libzutil.h>

#define BUFSIZE (MNT_LINE_MAX + 2)

Expand Down Expand Up @@ -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);
}

Expand Down
9 changes: 5 additions & 4 deletions lib/libzfs/libzfs_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <curl/curl.h>
#endif
#include <libzfs.h>
#include <libzutil.h>
#include "libzfs_impl.h"
#include "zfeature_common.h"

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand All @@ -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;
}

Expand Down
14 changes: 11 additions & 3 deletions lib/libzfs/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
#include "libzfs_impl.h"
#include "zfs_deleg.h"

static __thread struct passwd gpwd;
static __thread struct group ggrp;
static __thread char rpbuf[2048];

static int userquota_propname_decode(const char *propname, boolean_t zoned,
zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);

Expand Down Expand Up @@ -3195,11 +3199,15 @@ userquota_propname_decode(const char *propname, boolean_t zoned,

cp = strchr(propname, '@') + 1;

if (isuser && (pw = getpwnam(cp)) != NULL) {
if (isuser &&
getpwnam_r(cp, &gpwd, rpbuf, sizeof (rpbuf), &pw) == 0 &&
pw != NULL) {
if (zoned && getzoneid() == GLOBAL_ZONEID)
return (ENOENT);
*ridp = pw->pw_uid;
} else if (isgroup && (gr = getgrnam(cp)) != NULL) {
} else if (isgroup &&
getgrnam_r(cp, &ggrp, rpbuf, sizeof (rpbuf), &gr) == 0 &&
gr != NULL) {
if (zoned && getzoneid() == GLOBAL_ZONEID)
return (ENOENT);
*ridp = gr->gr_gid;
Expand Down Expand Up @@ -5217,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;
}

Expand Down
17 changes: 9 additions & 8 deletions lib/libzfs/libzfs_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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));
}
Expand All @@ -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);
Expand All @@ -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));
Expand All @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions lib/libzfs/libzfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#include <sys/dsl_crypt.h>

#include <libzfs.h>
#include <libzutil.h>

#include "libzfs_impl.h"
#include <thread_pool.h>
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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'"),
Expand Down
Loading
Loading