diff options
author | Low-power <[email protected]> | 2022-04-16 05:16:07 +0800 |
---|---|---|
committer | GitHub <[email protected]> | 2022-04-15 14:16:07 -0700 |
commit | 4dced31b98228f2fedbbe32de60ffcf8cc8f4fb3 (patch) | |
tree | aa2b16e43ceea8c7edf69582e2d6bd4d8221d63a | |
parent | 0dd34a1955b06cdea460f2f1711b72536a5a511b (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.c | 20 |
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); } } |