mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
libdm: report: fix invalid JSON if using DM_REPORT_OUTPUT_MULTIPLE_TIMES and selection
When reporting in JSON format, we need to be able to find the 'last displayed row', not just 'last row' as we did before. This is used to decide whether to put the JSON_SEPARATOR (the ',' character) between the lines when reporting in JSON format. This is mainly important in case we use a combination of JSON format and a report marked with DM_REPORT_OUTPUT_MULTIPLE_TIMES flag. Such report may be reused several times with different selection criteria each time. In that case, the report always contains all lines in memory, even though some of them do not need to pass the selection criteria that are currently used. Without DM_REPORT_OUTPUT_MULTIPLE_TIMES flag, the report only contains the lines that have passed the selection criteria, so the this wasn't an issue in this case. Fix suggested by Lars Ellenberg and reported here: https://github.com/lvmteam/lvm2/issues/130
This commit is contained in:
parent
d019c41f7a
commit
c36e012926
@ -1,5 +1,6 @@
|
||||
Version 1.02.197 -
|
||||
===================================
|
||||
Fix invalid JSON report if using DM_REPORT_OUTPUT_MULTIPLE_TIMES and selection.
|
||||
Propagate ioctl errno from dm_task_run when creating new table line.
|
||||
Add support for group aliases in dmstats.
|
||||
Add support for exit-on file for dmeventd to reduce shutdown delays.
|
||||
|
@ -4811,12 +4811,36 @@ static int _output_as_rows(struct dm_report *rh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_list *_get_last_displayed_rowh(struct dm_report *rh)
|
||||
{
|
||||
struct dm_list *rowh;
|
||||
struct row *row;
|
||||
|
||||
/*
|
||||
* We need to find 'last displayed row', not just 'last row'.
|
||||
*
|
||||
* This is because the report may be marked with
|
||||
* DM_REPORT_OUTPUT_MULTIPLE_TIMES flag. In that case, the report
|
||||
* may be used more than once and with different selection
|
||||
* criteria each time. Therefore, such report may also contain
|
||||
* rows which we do not display on output with current selection
|
||||
* criteria.
|
||||
*/
|
||||
for (rowh = dm_list_last(&rh->rows); rowh; rowh = dm_list_prev(&rh->rows, rowh)) {
|
||||
row = dm_list_item(rowh, struct row);
|
||||
if (_should_display_row(row))
|
||||
return rowh;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _output_as_columns(struct dm_report *rh)
|
||||
{
|
||||
struct dm_list *fh, *rowh, *ftmp, *rtmp;
|
||||
struct row *row = NULL;
|
||||
struct dm_report_field *field;
|
||||
struct dm_list *last_row;
|
||||
struct dm_list *last_rowh;
|
||||
int do_field_delim;
|
||||
char *line;
|
||||
|
||||
@ -4825,7 +4849,7 @@ static int _output_as_columns(struct dm_report *rh)
|
||||
_report_headings(rh);
|
||||
|
||||
/* Print and clear buffer */
|
||||
last_row = dm_list_last(&rh->rows);
|
||||
last_rowh = _get_last_displayed_rowh(rh);
|
||||
dm_list_iterate_safe(rowh, rtmp, &rh->rows) {
|
||||
row = dm_list_item(rowh, struct row);
|
||||
|
||||
@ -4879,7 +4903,7 @@ static int _output_as_columns(struct dm_report *rh)
|
||||
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
|
||||
goto bad;
|
||||
}
|
||||
if (rowh != last_row &&
|
||||
if (rowh != last_rowh &&
|
||||
!dm_pool_grow_object(rh->mem, JSON_SEPARATOR, 0)) {
|
||||
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
|
||||
goto bad;
|
||||
|
@ -4810,12 +4810,36 @@ static int _output_as_rows(struct dm_report *rh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_list *_get_last_displayed_rowh(struct dm_report *rh)
|
||||
{
|
||||
struct dm_list *rowh;
|
||||
struct row *row;
|
||||
|
||||
/*
|
||||
* We need to find 'last displayed row', not just 'last row'.
|
||||
*
|
||||
* This is because the report may be marked with
|
||||
* DM_REPORT_OUTPUT_MULTIPLE_TIMES flag. In that case, the report
|
||||
* may be used more than once and with different selection
|
||||
* criteria each time. Therefore, such report may also contain
|
||||
* rows which we do not display on output with current selection
|
||||
* criteria.
|
||||
*/
|
||||
for (rowh = dm_list_last(&rh->rows); rowh; rowh = dm_list_prev(&rh->rows, rowh)) {
|
||||
row = dm_list_item(rowh, struct row);
|
||||
if (_should_display_row(row))
|
||||
return rowh;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _output_as_columns(struct dm_report *rh)
|
||||
{
|
||||
struct dm_list *fh, *rowh, *ftmp, *rtmp;
|
||||
struct row *row = NULL;
|
||||
struct dm_report_field *field;
|
||||
struct dm_list *last_row;
|
||||
struct dm_list *last_rowh;
|
||||
int do_field_delim;
|
||||
char *line;
|
||||
|
||||
@ -4824,7 +4848,7 @@ static int _output_as_columns(struct dm_report *rh)
|
||||
_report_headings(rh);
|
||||
|
||||
/* Print and clear buffer */
|
||||
last_row = dm_list_last(&rh->rows);
|
||||
last_rowh = _get_last_displayed_rowh(rh);
|
||||
dm_list_iterate_safe(rowh, rtmp, &rh->rows) {
|
||||
row = dm_list_item(rowh, struct row);
|
||||
|
||||
@ -4878,7 +4902,7 @@ static int _output_as_columns(struct dm_report *rh)
|
||||
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
|
||||
goto bad;
|
||||
}
|
||||
if (rowh != last_row &&
|
||||
if (rowh != last_rowh &&
|
||||
!dm_pool_grow_object(rh->mem, JSON_SEPARATOR, 0)) {
|
||||
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
|
||||
goto bad;
|
||||
|
Loading…
Reference in New Issue
Block a user