Display status percentage. Display percentage of space usage for shared snapshots. Display 'I' and 'S' for invalidated snapshots. Signed-off-by: Mikulas Patocka --- lib/activate/dev_manager.c | 3 ++- lib/metadata/lv.c | 13 +++++++++++++ lib/multisnapshot/multisnapshot.c | 37 ++++++++++++++++++++++++++++++++++--- lib/report/report.c | 10 ++++++++-- 4 files changed, 57 insertions(+), 6 deletions(-) Index: LVM2.2.02.85/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.85.orig/lib/activate/dev_manager.c 2011-05-23 16:07:44.000000000 +0200 +++ LVM2.2.02.85/lib/activate/dev_manager.c 2011-05-23 16:07:51.000000000 +0200 @@ -727,7 +727,8 @@ int dev_manager_snapshot_percent(struct * Try and get some info on this device. */ log_debug("Getting device status percentage for %s", name); - if (!(_percent(dm, name, dlid, "snapshot", 0, NULL, percent, + if (!(_percent(dm, name, dlid, lv_is_multisnap_origin(lv) ? + "multisnapshot" : "snapshot", 0, NULL, percent, NULL, fail_if_percent_unsupported))) return_0; Index: LVM2.2.02.85/lib/multisnapshot/multisnapshot.c =================================================================== --- LVM2.2.02.85.orig/lib/multisnapshot/multisnapshot.c 2011-05-23 16:00:12.000000000 +0200 +++ LVM2.2.02.85/lib/multisnapshot/multisnapshot.c 2011-05-23 16:07:51.000000000 +0200 @@ -161,15 +161,46 @@ static int _multisnap_snap_text_export(c #ifdef DEVMAPPER_SUPPORT static int _multisnapshot_target_percent(void **target_state __attribute((unused)), - percent_range_t *percent_range, + percent_t *percent, struct dm_pool *mem __attribute((unused)), struct cmd_context *cmd __attribute((unused)), struct lv_segment *seg __attribute((unused)), char *params, uint64_t *total_numerator, uint64_t *total_denominator) { - *percent_range = PERCENT_INVALID; - return 0; + int m; + unsigned nargs; + int error; + char *snapid; + uint64_t total, allocated, metadata; + + snapid = dm_pool_alloc(mem, strlen(params) + 1); + if (!snapid) { + log_error("Out of memory."); + return 0; + } + + m = sscanf(params, "%u %d %s %"SCNu64" %"SCNu64" %"SCNu64"", &nargs, &error, snapid, &total, &allocated, &metadata); + if (m != 6) { + log_error("_multisnapshot_target_percent: matched only %d entries of '%s'", m, params); + return 0; + } + if (error < 0) { + *percent = PERCENT_INVALID; + return 1; + } + + *total_numerator += allocated; + *total_denominator += total; + + if (allocated == metadata) + *percent = PERCENT_0; + else if (allocated == total) + *percent = PERCENT_100; + else + *percent = make_percent(*total_numerator, *total_denominator); + + return 1; } static int _multisnap_target_present(struct cmd_context *cmd, Index: LVM2.2.02.85/lib/report/report.c =================================================================== --- LVM2.2.02.85.orig/lib/report/report.c 2011-05-23 16:07:48.000000000 +0200 +++ LVM2.2.02.85/lib/report/report.c 2011-05-23 16:07:51.000000000 +0200 @@ -754,13 +754,19 @@ static int _snpercent_disp(struct dm_rep return 0; } - if ((!lv_is_cow(lv) && !lv_is_merging_origin(lv)) || - !lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) || !info.exists) { + if ((!lv_is_cow(lv) && !lv_is_merging_origin(lv))) { +report_empty: *sortval = UINT64_C(0); dm_report_field_set_value(field, "", sortval); return 1; } + if (lv->snapshot->status & SNAPSHOT_SHARED) + lv = lv->snapshot->origin; + + if (!lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) || !info.exists) + goto report_empty; + if (!lv_snapshot_percent(lv, &snap_percent) || (snap_percent == PERCENT_INVALID)) { if (!lv_is_merging_origin(lv)) { Index: LVM2.2.02.85/lib/metadata/lv.c =================================================================== --- LVM2.2.02.85.orig/lib/metadata/lv.c 2011-05-23 16:07:48.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/lv.c 2011-05-23 16:07:51.000000000 +0200 @@ -372,6 +372,19 @@ char *lv_attr_dup(struct dm_pool *mem, c repstr[4] = '-'; repstr[5] = '-'; } + + if (lv_is_cow(lv) && lv->snapshot->status & SNAPSHOT_SHARED) + lv = lv->snapshot->origin; + else if (lv_is_multisnap_cow(lv)) + lv = first_seg(lv)->origin; + else + lv = NULL; + + if (lv && lv_snapshot_percent(lv, &snap_percent) && snap_percent == PERCENT_INVALID) { + repstr[0] = toupper(repstr[0]); + repstr[4] = 'I'; + } + out: return repstr; }