1
0
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:
Peter Rajnoha 2023-10-23 13:56:55 +02:00
parent d019c41f7a
commit c36e012926
No known key found for this signature in database
GPG Key ID: E776664036DF84AB
3 changed files with 55 additions and 6 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;