aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLow-power <[email protected]>2022-04-16 05:16:07 +0800
committerGitHub <[email protected]>2022-04-15 14:16:07 -0700
commit4dced31b98228f2fedbbe32de60ffcf8cc8f4fb3 (patch)
treeaa2b16e43ceea8c7edf69582e2d6bd4d8221d63a
parent0dd34a1955b06cdea460f2f1711b72536a5a511b (diff)
Fix 'zpool history' sometimes fails without reporting any error
The corresponding function 'zpool_get_history' in libzfs would printing an error messages only when the ioctl call failed. Add missing error reporting, specifically memory allocation failures and error from 'zpool_history_unpack'. Also avoid possibly reading of uninitialized 'err' variable in case the requested offset pasts EOF. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Damian Szuberski <[email protected]> Signed-off-by: WHR <[email protected]> Issue #13322 Closes #13320
-rw-r--r--lib/libzfs/libzfs_pool.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
index a923995f2..cd7062a88 100644
--- a/lib/libzfs/libzfs_pool.c
+++ b/lib/libzfs/libzfs_pool.c
@@ -4439,17 +4439,17 @@ int
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
boolean_t *eof)
{
+ libzfs_handle_t *hdl = zhp->zpool_hdl;
char *buf;
int buflen = 128 * 1024;
nvlist_t **records = NULL;
uint_t numrecords = 0;
- int err, i;
+ int err = 0, i;
uint64_t start = *off;
- buf = malloc(buflen);
- if (buf == NULL)
- return (ENOMEM);
- /* process about 1MB a time */
+ buf = zfs_alloc(hdl, buflen);
+
+ /* process about 1MiB a time */
while (*off - start < 1024 * 1024) {
uint64_t bytes_read = buflen;
uint64_t leftover;
@@ -4464,8 +4464,12 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
}
if ((err = zpool_history_unpack(buf, bytes_read,
- &leftover, &records, &numrecords)) != 0)
+ &leftover, &records, &numrecords)) != 0) {
+ zpool_standard_error_fmt(hdl, err,
+ dgettext(TEXT_DOMAIN,
+ "cannot get history for '%s'"), zhp->zpool_name);
break;
+ }
*off -= leftover;
if (leftover == bytes_read) {
/*
@@ -4474,9 +4478,7 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
*/
buflen *= 2;
free(buf);
- buf = malloc(buflen);
- if (buf == NULL)
- return (ENOMEM);
+ buf = zfs_alloc(hdl, buflen);
}
}