libzfs: return (allocated) strings instead of filling buffers

This also expands the zfs version output from 127 characters to However
Many Are Actually Set

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #13330
This commit is contained in:
наб 2022-04-15 00:00:02 +02:00 committed by Brian Behlendorf
parent 38f4d99f76
commit 2b4f2fc93c
7 changed files with 1427 additions and 1442 deletions

View File

@ -8577,11 +8577,7 @@ static int
zfs_do_version(int argc, char **argv) zfs_do_version(int argc, char **argv)
{ {
(void) argc, (void) argv; (void) argc, (void) argv;
return (zfs_version_print() != 0);
if (zfs_version_print() == -1)
return (1);
return (0);
} }
int int

View File

@ -10818,11 +10818,7 @@ static int
zpool_do_version(int argc, char **argv) zpool_do_version(int argc, char **argv)
{ {
(void) argc, (void) argv; (void) argc, (void) argv;
return (zfs_version_print() != 0);
if (zfs_version_print() == -1)
return (1);
return (0);
} }
/* /*

View File

@ -914,8 +914,8 @@ _LIBZFS_H int libzfs_envvar_is_set(char *);
/* /*
* Utility functions for zfs version * Utility functions for zfs version
*/ */
_LIBZFS_H void zfs_version_userland(char *, int); _LIBZFS_H const char *zfs_version_userland(void);
_LIBZFS_H int zfs_version_kernel(char *, int); _LIBZFS_H char *zfs_version_kernel(void);
_LIBZFS_H int zfs_version_print(void); _LIBZFS_H int zfs_version_print(void);
/* /*

File diff suppressed because it is too large Load Diff

View File

@ -1910,37 +1910,30 @@ zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
return (zprop_iter_common(func, cb, show_all, ordered, type)); return (zprop_iter_common(func, cb, show_all, ordered, type));
} }
/* const char *
* Fill given version buffer with zfs userland version zfs_version_userland(void)
*/
void
zfs_version_userland(char *version, int len)
{ {
(void) strlcpy(version, ZFS_META_ALIAS, len); return (ZFS_META_ALIAS);
} }
/* /*
* Prints both zfs userland and kernel versions * Prints both zfs userland and kernel versions
* Returns 0 on success, and -1 on error (with errno set) * Returns 0 on success, and -1 on error
*/ */
int int
zfs_version_print(void) zfs_version_print(void)
{ {
char zver_userland[128]; (void) puts(ZFS_META_ALIAS);
char zver_kernel[128];
zfs_version_userland(zver_userland, sizeof (zver_userland)); char *kver = zfs_version_kernel();
if (kver == NULL) {
(void) printf("%s\n", zver_userland);
if (zfs_version_kernel(zver_kernel, sizeof (zver_kernel)) == -1) {
fprintf(stderr, "zfs_version_kernel() failed: %s\n", fprintf(stderr, "zfs_version_kernel() failed: %s\n",
strerror(errno)); strerror(errno));
return (-1); return (-1);
} }
(void) printf("zfs-kmod-%s\n", zver_kernel); (void) printf("zfs-kmod-%s\n", kver);
free(kver);
return (0); return (0);
} }

View File

@ -351,14 +351,22 @@ zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
} }
/* /*
* Fill given version buffer with zfs kernel version. * Return allocated loaded module version, or NULL on error (with errno set)
* Returns 0 on success, and -1 on error (with errno set)
*/ */
int char *
zfs_version_kernel(char *version, int len) zfs_version_kernel(void)
{ {
size_t l = len; size_t l;
if (sysctlbyname("vfs.zfs.version.module",
return (sysctlbyname("vfs.zfs.version.module", NULL, &l, NULL, 0) == -1)
version, &l, NULL, 0)); return (NULL);
char *version = malloc(l);
if (version == NULL)
return (NULL);
if (sysctlbyname("vfs.zfs.version.module",
version, &l, NULL, 0) == -1) {
free(version);
return (NULL);
}
return (version);
} }

View File

@ -183,31 +183,27 @@ zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps)
} }
/* /*
* Fill given version buffer with zfs kernel version read from ZFS_SYSFS_DIR * Return allocated loaded module version, or NULL on error (with errno set)
* Returns 0 on success, and -1 on error (with errno set)
*/ */
int char *
zfs_version_kernel(char *version, int len) zfs_version_kernel(void)
{ {
int _errno; FILE *f = fopen(ZFS_SYSFS_DIR "/version", "re");
int fd; if (f == NULL)
int rlen; return (NULL);
if ((fd = open(ZFS_SYSFS_DIR "/version", O_RDONLY | O_CLOEXEC)) == -1) char *ret = NULL;
return (-1); size_t l;
ssize_t read;
if ((rlen = read(fd, version, len)) == -1) { if ((read = getline(&ret, &l, f)) == -1) {
version[0] = '\0'; int err = errno;
_errno = errno; fclose(f);
(void) close(fd); errno = err;
errno = _errno; return (NULL);
return (-1);
} }
version[rlen-1] = '\0'; /* discard '\n' */ fclose(f);
if (ret[read - 1] == '\n')
if (close(fd) == -1) ret[read - 1] = '\0';
return (-1); return (ret);
return (0);
} }