Illumos 5116 - zpool history -i goes into infinite loop
5116 zpool history -i goes into infinite loop Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Richard Elling <richard.elling@gmail.com> Reviewed by: Boris Protopopov <boris.protopopov@me.com> Approved by: Dan McDonald <danmcd@omniti.com> References: https://www.illumos.org/issues/5116 https://github.com/illumos/illumos-gate/commit/3339867 Ported by: Turbo Fredriksson <turbo@bayour.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2715
This commit is contained in:
parent
ab2894e66f
commit
1f6f97f304
|
@ -3760,22 +3760,24 @@ zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HIS_BUF_LEN (128*1024)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the command history of a pool.
|
* Retrieve the command history of a pool.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
|
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
|
||||||
{
|
{
|
||||||
char buf[HIS_BUF_LEN];
|
char *buf;
|
||||||
|
int buflen = 128 * 1024;
|
||||||
uint64_t off = 0;
|
uint64_t off = 0;
|
||||||
nvlist_t **records = NULL;
|
nvlist_t **records = NULL;
|
||||||
uint_t numrecords = 0;
|
uint_t numrecords = 0;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
|
buf = malloc(buflen);
|
||||||
|
if (buf == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
do {
|
do {
|
||||||
uint64_t bytes_read = sizeof (buf);
|
uint64_t bytes_read = buflen;
|
||||||
uint64_t leftover;
|
uint64_t leftover;
|
||||||
|
|
||||||
if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
|
if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
|
||||||
|
@ -3789,10 +3791,23 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
|
||||||
&leftover, &records, &numrecords)) != 0)
|
&leftover, &records, &numrecords)) != 0)
|
||||||
break;
|
break;
|
||||||
off -= leftover;
|
off -= leftover;
|
||||||
|
if (leftover == bytes_read) {
|
||||||
|
/*
|
||||||
|
* no progress made, because buffer is not big enough
|
||||||
|
* to hold this record; resize and retry.
|
||||||
|
*/
|
||||||
|
buflen *= 2;
|
||||||
|
free(buf);
|
||||||
|
buf = malloc(buflen);
|
||||||
|
if (buf == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
/* CONSTCOND */
|
/* CONSTCOND */
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
|
verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
|
||||||
verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
|
verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
|
||||||
|
|
Loading…
Reference in New Issue