Current reporting infrastructure handles only single report, that is the simple sequence: dm_report_init -> dm_report_object [-> dm_report_object ...] -> dm_report_output -> dm_report_free (or with dm_report_output integrated into dm_report_object if report is unbuffered). Enhance reporting code to support grouping several reports into one whole. When reports are in a group, they follow the same discipline on output - that means the output format is the same for each of the reports in a group and the code also checks whether lines from each report are properly ordered and whether they're not interleaved with each other so the group as whole conforms to the format used. Grouping also allows for adding any necessary opening and closing lines on output as well as delimiters between reports depending on format used. Also, it should be possible to change the format of the output for the whole group by simply changing type of report group, without a need to modify any of existing calls to reporting functions.
The flow of the code is following: - create report group - push report(report1) - push report(report2) - ... - push report(reportN) - dm_report_output(reportN) - pop report(reportN) - ... - dm_report_output(report2) - pop report(report2) - dm_report_output(report1) - pop report(report1) - destroy report group This sequence is also valid: - create report group - push report(report1) - dm_report_output(report1) - pop report(report1) - push report(report2) - dm_report_output(report2) - pop report(report2) ... - push report(reportN) - dm_report_output(reportN) - pop report(reportN) - destroy report group So the rule is - only the report on top of the stack can be generating output - this controls the flow of output from different reports in a group. More concretely, there are 4 new libdevmapper functions to support this feature: struct dm_report_group *dm_report_group_create(dm_report_group_type_t type, void *data) --> Creates a new group of type "type" with any additional "data" that the group type needs (this is any type-specific additional data that can be attached to the group or which are needed for initialization). int dm_report_group_push(struct dm_report_group *group, struct dm_report *report, void *data) --> Pushes report to group's stack with any type-specific additional "data". If report is NULL, this is just an item that wraps several reports on output under one object, but the item itself is not a report. int dm_report_group_pop(struct dm_report_group *group) --> Pops report from group's stack, adding any closing stanzas based on group type used. int dm_report_group_destroy(struct dm_report_group *group) --> Destroys whole report group. If any of the reports has not been reported on output yet by direct dm_report_output call, it is reported on output now automatically.
device-mapper library (libdevmapper) adds support for grouping reports together since version 1.02.128 and it contains these functions to support the feature: - dm_report_group_create to create report group - dm_report_group_push to add report to report group - dm_report_group_pop to remove last report from report group - dm_report_group_destroy to destroy report group