2 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "toolcontext.h"
20 #include "lvm-string.h"
27 #include <stddef.h> /* offsetof() */
29 struct lvm_report_object {
30 struct volume_group *vg;
31 struct logical_volume *lv;
32 struct physical_volume *pv;
33 struct lv_segment *seg;
34 struct pv_segment *pvseg;
37 static const uint64_t _minusone64 = UINT64_C(-1);
38 static const int32_t _minusone32 = INT32_C(-1);
41 * Data-munging functions to prepare each data type for display and sorting
43 static int _string_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
44 struct dm_report_field *field,
45 const void *data, void *private __attribute__((unused)))
47 return dm_report_field_string(rh, field, (const char **) data);
50 static int _dev_name_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
51 struct dm_report_field *field,
52 const void *data, void *private __attribute__((unused)))
54 const char *name = dev_name(*(const struct device * const *) data);
56 return dm_report_field_string(rh, field, &name);
59 static int _format_pvsegs(struct dm_pool *mem, struct dm_report_field *field,
60 const void *data, int range_format)
62 const struct lv_segment *seg = (const struct lv_segment *) data;
64 const char *name = NULL;
68 if (!dm_pool_begin_object(mem, 256)) {
69 log_error("dm_pool_begin_object failed");
73 for (s = 0; s < seg->area_count; s++) {
74 switch (seg_type(seg, s)) {
76 name = seg_lv(seg, s)->name;
77 extent = seg_le(seg, s);
80 name = dev_name(seg_dev(seg, s));
81 extent = seg_pe(seg, s);
88 if (!dm_pool_grow_object(mem, name, strlen(name))) {
89 log_error("dm_pool_grow_object failed");
93 if (dm_snprintf(extent_str, sizeof(extent_str),
95 range_format ? ":" : "(", extent,
96 range_format ? "-" : ")") < 0) {
97 log_error("Extent number dm_snprintf failed");
100 if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
101 log_error("dm_pool_grow_object failed");
106 if (dm_snprintf(extent_str, sizeof(extent_str),
107 "%" PRIu32, extent + seg->area_len - 1) < 0) {
108 log_error("Extent number dm_snprintf failed");
111 if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
112 log_error("dm_pool_grow_object failed");
117 if ((s != seg->area_count - 1) &&
118 !dm_pool_grow_object(mem, range_format ? " " : ",", 1)) {
119 log_error("dm_pool_grow_object failed");
124 if (!dm_pool_grow_object(mem, "\0", 1)) {
125 log_error("dm_pool_grow_object failed");
129 dm_report_field_set_value(field, dm_pool_end_object(mem), NULL);
134 static int _devices_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
135 struct dm_report_field *field,
136 const void *data, void *private __attribute__((unused)))
138 return _format_pvsegs(mem, field, data, 0);
141 static int _peranges_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
142 struct dm_report_field *field,
143 const void *data, void *private __attribute__((unused)))
145 return _format_pvsegs(mem, field, data, 1);
148 static int _tags_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
149 struct dm_report_field *field,
150 const void *data, void *private __attribute__((unused)))
152 const struct dm_list *tags = (const struct dm_list *) data;
155 if (!(tags_str = tags_format_and_copy(mem, tags)))
158 dm_report_field_set_value(field, tags_str, NULL);
163 static int _modules_disp(struct dm_report *rh, struct dm_pool *mem,
164 struct dm_report_field *field,
165 const void *data, void *private)
167 const struct logical_volume *lv = (const struct logical_volume *) data;
170 if (!(modules_str = lv_modules_dup(mem, lv)))
173 dm_report_field_set_value(field, modules_str, NULL);
177 static int _vgfmt_disp(struct dm_report *rh, struct dm_pool *mem,
178 struct dm_report_field *field,
179 const void *data, void *private)
181 const struct volume_group *vg = (const struct volume_group *) data;
184 dm_report_field_set_value(field, "", NULL);
188 return _string_disp(rh, mem, field, &vg->fid->fmt->name, private);
191 static int _pvfmt_disp(struct dm_report *rh, struct dm_pool *mem,
192 struct dm_report_field *field,
193 const void *data, void *private)
195 const struct physical_volume *pv =
196 (const struct physical_volume *) data;
199 dm_report_field_set_value(field, "", NULL);
203 return _string_disp(rh, mem, field, &pv->fmt->name, private);
206 static int _lvkmaj_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
207 struct dm_report_field *field,
208 const void *data, void *private __attribute__((unused)))
210 const struct logical_volume *lv = (const struct logical_volume *) data;
213 if ((major = lv_kernel_major(lv)) >= 0)
214 return dm_report_field_int(rh, field, &major);
216 return dm_report_field_int32(rh, field, &_minusone32);
219 static int _lvkmin_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
220 struct dm_report_field *field,
221 const void *data, void *private __attribute__((unused)))
223 const struct logical_volume *lv = (const struct logical_volume *) data;
226 if ((minor = lv_kernel_minor(lv)) >= 0)
227 return dm_report_field_int(rh, field, &minor);
229 return dm_report_field_int32(rh, field, &_minusone32);
232 static int _lvstatus_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
233 struct dm_report_field *field,
234 const void *data, void *private __attribute__((unused)))
236 const struct logical_volume *lv = (const struct logical_volume *) data;
239 if (!(repstr = lv_attr_dup(mem, lv)))
242 dm_report_field_set_value(field, repstr, NULL);
246 static int _pvstatus_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
247 struct dm_report_field *field,
248 const void *data, void *private __attribute__((unused)))
250 const struct physical_volume *pv =
251 (const struct physical_volume *) data;
254 if (!(repstr = pv_attr_dup(mem, pv)))
257 dm_report_field_set_value(field, repstr, NULL);
261 static int _vgstatus_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
262 struct dm_report_field *field,
263 const void *data, void *private __attribute__((unused)))
265 const struct volume_group *vg = (const struct volume_group *) data;
268 if (!(repstr = vg_attr_dup(mem, vg)))
271 dm_report_field_set_value(field, repstr, NULL);
275 static int _segtype_disp(struct dm_report *rh __attribute__((unused)),
276 struct dm_pool *mem __attribute__((unused)),
277 struct dm_report_field *field,
278 const void *data, void *private __attribute__((unused)))
280 const struct lv_segment *seg = (const struct lv_segment *) data;
283 name = lvseg_segtype_dup(seg);
284 dm_report_field_set_value(field, name, NULL);
288 static int _loglv_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
289 struct dm_report_field *field,
290 const void *data, void *private __attribute__((unused)))
292 const struct logical_volume *lv = (const struct logical_volume *) data;
295 if ((name = lv_mirror_log_dup(mem, lv)))
296 return dm_report_field_string(rh, field, &name);
298 dm_report_field_set_value(field, "", NULL);
302 static int _lvname_disp(struct dm_report *rh, struct dm_pool *mem,
303 struct dm_report_field *field,
304 const void *data, void *private __attribute__((unused)))
306 const struct logical_volume *lv = (const struct logical_volume *) data;
307 char *repstr, *lvname;
310 if (lv_is_visible(lv)) {
312 return dm_report_field_string(rh, field, (const char **) &repstr);
315 len = strlen(lv->name) + 3;
316 if (!(repstr = dm_pool_zalloc(mem, len))) {
317 log_error("dm_pool_alloc failed");
321 if (dm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
322 log_error("lvname snprintf failed");
326 if (!(lvname = dm_pool_strdup(mem, lv->name))) {
327 log_error("dm_pool_strdup failed");
331 dm_report_field_set_value(field, repstr, lvname);
336 static int _lvpath_disp(struct dm_report *rh, struct dm_pool *mem,
337 struct dm_report_field *field,
338 const void *data, void *private __attribute__((unused)))
340 const struct logical_volume *lv = (const struct logical_volume *) data;
343 if (!(repstr = lv_path_dup(mem, lv)))
346 dm_report_field_set_value(field, repstr, NULL);
351 static int _origin_disp(struct dm_report *rh, struct dm_pool *mem,
352 struct dm_report_field *field,
353 const void *data, void *private)
355 const struct logical_volume *lv = (const struct logical_volume *) data;
358 return _lvname_disp(rh, mem, field, origin_from_cow(lv), private);
360 dm_report_field_set_value(field, "", NULL);
364 static int _movepv_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
365 struct dm_report_field *field,
366 const void *data, void *private __attribute__((unused)))
368 const struct logical_volume *lv = (const struct logical_volume *) data;
371 if (!(name = lv_move_pv_dup(mem, lv)))
372 dm_report_field_set_value(field, "", NULL);
374 return dm_report_field_string(rh, field, &name);
378 static int _convertlv_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
379 struct dm_report_field *field,
380 const void *data, void *private __attribute__((unused)))
382 const struct logical_volume *lv = (const struct logical_volume *) data;
383 const char *name = NULL;
385 name = lv_convert_lv_dup(mem, lv);
387 return dm_report_field_string(rh, field, &name);
389 dm_report_field_set_value(field, "", NULL);
393 static int _size32_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
394 struct dm_report_field *field,
395 const void *data, void *private)
397 const uint32_t size = *(const uint32_t *) data;
398 const char *disp, *repstr;
401 if (!*(disp = display_size_units(private, (uint64_t) size)))
404 if (!(repstr = dm_pool_strdup(mem, disp))) {
405 log_error("dm_pool_strdup failed");
409 if (!(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
410 log_error("dm_pool_alloc failed");
414 *sortval = (const uint64_t) size;
416 dm_report_field_set_value(field, repstr, sortval);
421 static int _size64_disp(struct dm_report *rh __attribute__((unused)),
423 struct dm_report_field *field,
424 const void *data, void *private)
426 const uint64_t size = *(const uint64_t *) data;
427 const char *disp, *repstr;
430 if (!*(disp = display_size_units(private, size)))
433 if (!(repstr = dm_pool_strdup(mem, disp))) {
434 log_error("dm_pool_strdup failed");
438 if (!(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
439 log_error("dm_pool_alloc failed");
444 dm_report_field_set_value(field, repstr, sortval);
449 static int _lvreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
450 struct dm_report_field *field,
451 const void *data, void *private __attribute__((unused)))
453 const struct logical_volume *lv = (const struct logical_volume *) data;
455 if (lv->read_ahead == DM_READ_AHEAD_AUTO) {
456 dm_report_field_set_value(field, "auto", &_minusone64);
460 return _size32_disp(rh, mem, field, &lv->read_ahead, private);
463 static int _lvkreadahead_disp(struct dm_report *rh, struct dm_pool *mem,
464 struct dm_report_field *field,
468 const struct logical_volume *lv = (const struct logical_volume *) data;
471 if ((read_ahead = lv_kernel_read_ahead(lv)) == UINT32_MAX)
472 return dm_report_field_int32(rh, field, &_minusone32);
474 return _size32_disp(rh, mem, field, &read_ahead, private);
477 static int _vgsize_disp(struct dm_report *rh, struct dm_pool *mem,
478 struct dm_report_field *field,
479 const void *data, void *private)
481 const struct volume_group *vg = (const struct volume_group *) data;
484 size = (uint64_t) vg_size(vg);
486 return _size64_disp(rh, mem, field, &size, private);
489 static int _segstart_disp(struct dm_report *rh, struct dm_pool *mem,
490 struct dm_report_field *field,
491 const void *data, void *private)
493 const struct lv_segment *seg = (const struct lv_segment *) data;
496 start = lvseg_start(seg);
498 return _size64_disp(rh, mem, field, &start, private);
501 static int _segstartpe_disp(struct dm_report *rh,
502 struct dm_pool *mem __attribute__((unused)),
503 struct dm_report_field *field,
505 void *private __attribute__((unused)))
507 const struct lv_segment *seg = (const struct lv_segment *) data;
509 return dm_report_field_uint32(rh, field, &seg->le);
512 static int _segsize_disp(struct dm_report *rh, struct dm_pool *mem,
513 struct dm_report_field *field,
514 const void *data, void *private)
516 const struct lv_segment *seg = (const struct lv_segment *) data;
519 size = lvseg_size(seg);
521 return _size64_disp(rh, mem, field, &size, private);
524 static int _chunksize_disp(struct dm_report *rh, struct dm_pool *mem,
525 struct dm_report_field *field,
526 const void *data, void *private)
528 const struct lv_segment *seg = (const struct lv_segment *) data;
531 size = lvseg_chunksize(seg);
533 return _size64_disp(rh, mem, field, &size, private);
536 static int _originsize_disp(struct dm_report *rh, struct dm_pool *mem,
537 struct dm_report_field *field,
538 const void *data, void *private)
540 const struct logical_volume *lv = (const struct logical_volume *) data;
543 size = lv_origin_size(lv);
545 return _size64_disp(rh, mem, field, &size, private);
548 static int _pvused_disp(struct dm_report *rh, struct dm_pool *mem,
549 struct dm_report_field *field,
550 const void *data, void *private)
552 const struct physical_volume *pv =
553 (const struct physical_volume *) data;
558 return _size64_disp(rh, mem, field, &used, private);
561 static int _pvfree_disp(struct dm_report *rh, struct dm_pool *mem,
562 struct dm_report_field *field,
563 const void *data, void *private)
565 const struct physical_volume *pv =
566 (const struct physical_volume *) data;
569 freespace = pv_free(pv);
571 return _size64_disp(rh, mem, field, &freespace, private);
574 static int _pvsize_disp(struct dm_report *rh, struct dm_pool *mem,
575 struct dm_report_field *field,
576 const void *data, void *private)
578 const struct physical_volume *pv =
579 (const struct physical_volume *) data;
582 size = pv_size_field(pv);
584 return _size64_disp(rh, mem, field, &size, private);
587 static int _devsize_disp(struct dm_report *rh, struct dm_pool *mem,
588 struct dm_report_field *field,
589 const void *data, void *private)
591 const struct physical_volume *pv =
592 (const struct physical_volume *) data;
595 size = pv_dev_size(pv);
597 return _size64_disp(rh, mem, field, &size, private);
600 static int _vgfree_disp(struct dm_report *rh, struct dm_pool *mem,
601 struct dm_report_field *field,
602 const void *data, void *private)
604 const struct volume_group *vg = (const struct volume_group *) data;
607 freespace = (uint64_t) vg_free(vg);
609 return _size64_disp(rh, mem, field, &freespace, private);
612 static int _uuid_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
613 struct dm_report_field *field,
614 const void *data, void *private __attribute__((unused)))
618 if (!(repstr = id_format_and_copy(mem, (struct id *)data)))
621 dm_report_field_set_value(field, repstr, NULL);
625 static int _uint32_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
626 struct dm_report_field *field,
627 const void *data, void *private __attribute__((unused)))
629 return dm_report_field_uint32(rh, field, data);
632 static int _int32_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)),
633 struct dm_report_field *field,
634 const void *data, void *private __attribute__((unused)))
636 return dm_report_field_int32(rh, field, data);
639 static int _pvmdas_disp(struct dm_report *rh, struct dm_pool *mem,
640 struct dm_report_field *field,
641 const void *data, void *private)
644 const struct physical_volume *pv =
645 (const struct physical_volume *) data;
647 count = pv_mda_count(pv);
649 return _uint32_disp(rh, mem, field, &count, private);
652 static int _pvmdasused_disp(struct dm_report *rh, struct dm_pool *mem,
653 struct dm_report_field *field,
654 const void *data, void *private)
657 const struct physical_volume *pv =
658 (const struct physical_volume *) data;
660 count = pv_mda_used_count(pv);
662 return _uint32_disp(rh, mem, field, &count, private);
665 static int _vgmdas_disp(struct dm_report *rh, struct dm_pool *mem,
666 struct dm_report_field *field,
667 const void *data, void *private)
669 const struct volume_group *vg = (const struct volume_group *) data;
672 count = vg_mda_count(vg);
674 return _uint32_disp(rh, mem, field, &count, private);
677 static int _vgmdasused_disp(struct dm_report *rh, struct dm_pool *mem,
678 struct dm_report_field *field,
679 const void *data, void *private)
681 const struct volume_group *vg = (const struct volume_group *) data;
684 count = vg_mda_used_count(vg);
686 return _uint32_disp(rh, mem, field, &count, private);
689 static int _vgmdacopies_disp(struct dm_report *rh, struct dm_pool *mem,
690 struct dm_report_field *field,
691 const void *data, void *private)
693 const struct volume_group *vg = (const struct volume_group *) data;
696 count = vg_mda_copies(vg);
698 if (count == VGMETADATACOPIES_UNMANAGED) {
699 dm_report_field_set_value(field, "unmanaged", &_minusone64);
703 return _uint32_disp(rh, mem, field, &count, private);
706 static int _pvmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
707 struct dm_report_field *field,
708 const void *data, void *private)
710 const struct physical_volume *pv =
711 (const struct physical_volume *) data;
714 freespace = pv_mda_free(pv);
716 return _size64_disp(rh, mem, field, &freespace, private);
719 static int _pvmdasize_disp(struct dm_report *rh, struct dm_pool *mem,
720 struct dm_report_field *field,
721 const void *data, void *private)
723 const struct physical_volume *pv =
724 (const struct physical_volume *) data;
725 uint64_t min_mda_size;
727 min_mda_size = pv_mda_size(pv);
729 return _size64_disp(rh, mem, field, &min_mda_size, private);
732 static int _vgmdasize_disp(struct dm_report *rh, struct dm_pool *mem,
733 struct dm_report_field *field,
734 const void *data, void *private)
736 const struct volume_group *vg = (const struct volume_group *) data;
737 uint64_t min_mda_size;
739 min_mda_size = vg_mda_size(vg);
741 return _size64_disp(rh, mem, field, &min_mda_size, private);
744 static int _vgmdafree_disp(struct dm_report *rh, struct dm_pool *mem,
745 struct dm_report_field *field,
746 const void *data, void *private)
748 const struct volume_group *vg = (const struct volume_group *) data;
751 freespace = vg_mda_free(vg);
753 return _size64_disp(rh, mem, field, &freespace, private);
756 static int _lvcount_disp(struct dm_report *rh, struct dm_pool *mem,
757 struct dm_report_field *field,
758 const void *data, void *private)
760 const struct volume_group *vg = (const struct volume_group *) data;
763 count = vg_visible_lvs(vg);
765 return _uint32_disp(rh, mem, field, &count, private);
768 static int _lvsegcount_disp(struct dm_report *rh, struct dm_pool *mem,
769 struct dm_report_field *field,
770 const void *data, void *private)
772 const struct logical_volume *lv = (const struct logical_volume *) data;
775 count = dm_list_size(&lv->segments);
777 return _uint32_disp(rh, mem, field, &count, private);
780 static int _snapcount_disp(struct dm_report *rh, struct dm_pool *mem,
781 struct dm_report_field *field,
782 const void *data, void *private)
784 const struct volume_group *vg = (const struct volume_group *) data;
787 count = snapshot_count(vg);
789 return _uint32_disp(rh, mem, field, &count, private);
792 static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
793 struct dm_report_field *field,
794 const void *data, void *private __attribute__((unused)))
796 const struct logical_volume *lv = (const struct logical_volume *) data;
798 percent_t snap_percent;
802 /* Suppress snapshot percentage if not using driver */
804 dm_report_field_set_value(field, "", NULL);
808 if (!(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
809 log_error("dm_pool_alloc failed");
813 if ((!lv_is_cow(lv) && !lv_is_merging_origin(lv)) ||
814 !lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) || !info.exists) {
815 *sortval = UINT64_C(0);
816 dm_report_field_set_value(field, "", sortval);
820 if (!lv_snapshot_percent(lv, &snap_percent) ||
821 (snap_percent == PERCENT_INVALID)) {
822 if (!lv_is_merging_origin(lv)) {
823 *sortval = UINT64_C(100);
824 dm_report_field_set_value(field, "100.00", sortval);
826 /* onactivate merge that hasn't started yet would
827 * otherwise display incorrect snap% in origin
829 *sortval = UINT64_C(0);
830 dm_report_field_set_value(field, "", sortval);
835 if (!(repstr = dm_pool_zalloc(mem, 8))) {
836 log_error("dm_pool_alloc failed");
840 if (dm_snprintf(repstr, 7, "%.2f", percent_to_float(snap_percent)) < 0) {
841 log_error("snapshot percentage too large");
845 *sortval = (uint64_t)(snap_percent * 1000.f);
846 dm_report_field_set_value(field, repstr, sortval);
851 static int _copypercent_disp(struct dm_report *rh __attribute__((unused)),
853 struct dm_report_field *field,
854 const void *data, void *private __attribute__((unused)))
856 struct logical_volume *lv = (struct logical_volume *) data;
861 if (!(sortval = dm_pool_alloc(mem, sizeof(uint64_t)))) {
862 log_error("dm_pool_alloc failed");
866 if ((!(lv->status & PVMOVE) && !(lv->status & MIRRORED)) ||
867 !lv_mirror_percent(lv->vg->cmd, lv, 0, &percent,
868 NULL) || (percent == PERCENT_INVALID)) {
869 *sortval = UINT64_C(0);
870 dm_report_field_set_value(field, "", sortval);
874 percent = copy_percent(lv);
876 if (!(repstr = dm_pool_zalloc(mem, 8))) {
877 log_error("dm_pool_alloc failed");
881 if (dm_snprintf(repstr, 7, "%.2f", percent_to_float(percent)) < 0) {
882 log_error("copy percentage too large");
886 *sortval = (uint64_t)(percent * 1000.f);
887 dm_report_field_set_value(field, repstr, sortval);
892 /* Report object types */
894 /* necessary for displaying something for PVs not belonging to VG */
895 static struct format_instance _dummy_fid = {
896 .metadata_areas_in_use = { &(_dummy_fid.metadata_areas_in_use), &(_dummy_fid.metadata_areas_in_use) },
897 .metadata_areas_ignored = { &(_dummy_fid.metadata_areas_ignored), &(_dummy_fid.metadata_areas_ignored) },
900 static struct volume_group _dummy_vg = {
903 .system_id = (char *) "",
904 .pvs = { &(_dummy_vg.pvs), &(_dummy_vg.pvs) },
905 .lvs = { &(_dummy_vg.lvs), &(_dummy_vg.lvs) },
906 .tags = { &(_dummy_vg.tags), &(_dummy_vg.tags) },
909 static void *_obj_get_vg(void *obj)
911 struct volume_group *vg = ((struct lvm_report_object *)obj)->vg;
913 return vg ? vg : &_dummy_vg;
916 static void *_obj_get_lv(void *obj)
918 return ((struct lvm_report_object *)obj)->lv;
921 static void *_obj_get_pv(void *obj)
923 return ((struct lvm_report_object *)obj)->pv;
926 static void *_obj_get_seg(void *obj)
928 return ((struct lvm_report_object *)obj)->seg;
931 static void *_obj_get_pvseg(void *obj)
933 return ((struct lvm_report_object *)obj)->pvseg;
936 static const struct dm_report_object_type _report_types[] = {
937 { VGS, "Volume Group", "vg_", _obj_get_vg },
938 { LVS, "Logical Volume", "lv_", _obj_get_lv },
939 { PVS, "Physical Volume", "pv_", _obj_get_pv },
940 { LABEL, "Physical Volume Label", "pv_", _obj_get_pv },
941 { SEGS, "Logical Volume Segment", "seg_", _obj_get_seg },
942 { PVSEGS, "Physical Volume Segment", "pvseg_", _obj_get_pvseg },
947 * Import column definitions
950 #define STR DM_REPORT_FIELD_TYPE_STRING
951 #define NUM DM_REPORT_FIELD_TYPE_NUMBER
952 #define FIELD(type, strct, sorttype, head, field, width, func, id, desc, writeable) \
953 {type, sorttype, offsetof(type_ ## strct, field), width, \
954 #id, head, &_ ## func ## _disp, desc},
956 typedef struct physical_volume type_pv;
957 typedef struct logical_volume type_lv;
958 typedef struct volume_group type_vg;
959 typedef struct lv_segment type_seg;
960 typedef struct pv_segment type_pvseg;
962 static const struct dm_report_field_type _fields[] = {
964 {0, 0, 0, 0, "", "", NULL, NULL},
971 void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
972 report_type_t *report_type, const char *separator,
973 int aligned, int buffered, int headings, int field_prefixes,
974 int quoted, int columns_as_rows)
976 uint32_t report_flags = 0;
980 report_flags |= DM_REPORT_OUTPUT_ALIGNED;
983 report_flags |= DM_REPORT_OUTPUT_BUFFERED;
986 report_flags |= DM_REPORT_OUTPUT_HEADINGS;
989 report_flags |= DM_REPORT_OUTPUT_FIELD_NAME_PREFIX;
992 report_flags |= DM_REPORT_OUTPUT_FIELD_UNQUOTED;
995 report_flags |= DM_REPORT_OUTPUT_COLUMNS_AS_ROWS;
997 rh = dm_report_init(report_type, _report_types, _fields, format,
998 separator, report_flags, keys, cmd);
1000 if (rh && field_prefixes)
1001 dm_report_set_output_field_name_prefix(rh, "lvm2_");
1007 * Create a row of data for an object
1009 int report_object(void *handle, struct volume_group *vg,
1010 struct logical_volume *lv, struct physical_volume *pv,
1011 struct lv_segment *seg, struct pv_segment *pvseg)
1013 struct lvm_report_object obj;
1015 /* The two format fields might as well match. */
1017 _dummy_fid.fmt = pv->fmt;
1025 return dm_report_object(handle, &obj);