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 <behlendorf1@llnl.gov> Reviewed-by: Damian Szuberski <szuberskidamian@gmail.com> Signed-off-by: WHR <msl0000023508@gmail.com> Issue #13322 Closes #13320
This commit is contained in:
parent
0dd34a1955
commit
4dced31b98
|
@ -4439,17 +4439,17 @@ int
|
||||||
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
|
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
|
||||||
boolean_t *eof)
|
boolean_t *eof)
|
||||||
{
|
{
|
||||||
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
char *buf;
|
char *buf;
|
||||||
int buflen = 128 * 1024;
|
int buflen = 128 * 1024;
|
||||||
nvlist_t **records = NULL;
|
nvlist_t **records = NULL;
|
||||||
uint_t numrecords = 0;
|
uint_t numrecords = 0;
|
||||||
int err, i;
|
int err = 0, i;
|
||||||
uint64_t start = *off;
|
uint64_t start = *off;
|
||||||
|
|
||||||
buf = malloc(buflen);
|
buf = zfs_alloc(hdl, buflen);
|
||||||
if (buf == NULL)
|
|
||||||
return (ENOMEM);
|
/* process about 1MiB a time */
|
||||||
/* process about 1MB a time */
|
|
||||||
while (*off - start < 1024 * 1024) {
|
while (*off - start < 1024 * 1024) {
|
||||||
uint64_t bytes_read = buflen;
|
uint64_t bytes_read = buflen;
|
||||||
uint64_t leftover;
|
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,
|
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;
|
break;
|
||||||
|
}
|
||||||
*off -= leftover;
|
*off -= leftover;
|
||||||
if (leftover == bytes_read) {
|
if (leftover == bytes_read) {
|
||||||
/*
|
/*
|
||||||
|
@ -4474,9 +4478,7 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
|
||||||
*/
|
*/
|
||||||
buflen *= 2;
|
buflen *= 2;
|
||||||
free(buf);
|
free(buf);
|
||||||
buf = malloc(buflen);
|
buf = zfs_alloc(hdl, buflen);
|
||||||
if (buf == NULL)
|
|
||||||
return (ENOMEM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue