FreeBSD: Improve libzfs_error_init messages

It is a common mistake to have failed to autoload the module due to
permission issues when running a ZFS command as a user.  "Operation
not permitted" is an unhelpfully vague error message.

Use a thread-local message buffer to format a nicer error message.
We can infer that loading the kernel module failed if the module is
not loaded.  This can be extended with heuristics for other errors
in the future.

While looking at this stuff, remove an unused thread-local message
buffer found in libspl and remove some inaccurate verbiage from the
comment on libzfs_load_module.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <ryan@iXsystems.com>
Closes #11033
This commit is contained in:
Ryan Moeller 2020-10-13 12:38:40 -04:00 committed by GitHub
parent 7dfc56d866
commit e191b60ddc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 11 deletions

View File

@ -37,10 +37,6 @@
#include <sys/stat.h>
#include <unistd.h>
#define BUFSIZE (MNT_LINE_MAX + 2)
__thread char buf[BUFSIZE];
int
getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
{

View File

@ -1010,8 +1010,7 @@ libzfs_init(void)
int error;
char *env;
error = libzfs_load_module();
if (error) {
if ((error = libzfs_load_module()) != 0) {
errno = error;
return (NULL);
}

View File

@ -176,11 +176,26 @@ execvpe(const char *name, char * const argv[], char * const envp[])
return (execvPe(name, path, argv, envp));
}
#define ERRBUFLEN 256
__thread static char errbuf[ERRBUFLEN];
const char *
libzfs_error_init(int error)
{
char *msg = errbuf;
size_t len, msglen = ERRBUFLEN;
return (strerror(error));
if (modfind("zfs") < 0) {
len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN,
"Failed to load %s module: "), ZFS_KMOD);
msg += len;
msglen -= len;
}
(void) snprintf(msg, msglen, "%s", strerror(error));
return (errbuf);
}
int
@ -193,10 +208,6 @@ zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
* Verify the required ZFS_DEV device is available and optionally attempt
* to load the ZFS modules. Under normal circumstances the modules
* should already have been loaded by some external mechanism.
*
* Environment variables:
* - ZFS_MODULE_LOADING="YES|yes|ON|on" - Attempt to load modules.
* - ZFS_MODULE_TIMEOUT="<seconds>" - Seconds to wait for ZFS_DEV
*/
int
libzfs_load_module(void)