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/multisnapshot/multisnapshot.c | 28 ++++++++++++++++++++++++++-- lib/report/report.c | 22 ++++++++++++++++++++-- 3 files changed, 48 insertions(+), 5 deletions(-) Index: LVM2.2.02.73/lib/activate/dev_manager.c =================================================================== --- LVM2.2.02.73.orig/lib/activate/dev_manager.c 2010-09-10 18:54:49.000000000 +0200 +++ LVM2.2.02.73/lib/activate/dev_manager.c 2010-09-10 18:54:58.000000000 +0200 @@ -704,7 +704,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, percent_range, NULL, fail_if_percent_unsupported))) return_0; Index: LVM2.2.02.73/lib/multisnapshot/multisnapshot.c =================================================================== --- LVM2.2.02.73.orig/lib/multisnapshot/multisnapshot.c 2010-09-10 18:54:39.000000000 +0200 +++ LVM2.2.02.73/lib/multisnapshot/multisnapshot.c 2010-09-10 18:54:58.000000000 +0200 @@ -168,8 +168,32 @@ static int _multisnapshot_target_percent 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_range = PERCENT_INVALID; + return 1; + } + + *percent_range = allocated == metadata ? PERCENT_0 : allocated == total ? PERCENT_100 : PERCENT_0_TO_100; + *total_numerator += allocated; + *total_denominator += total; + return 1; } static int _multisnap_target_present(struct cmd_context *cmd, Index: LVM2.2.02.73/lib/report/report.c =================================================================== --- LVM2.2.02.73.orig/lib/report/report.c 2010-09-10 18:54:52.000000000 +0200 +++ LVM2.2.02.73/lib/report/report.c 2010-09-10 18:59:13.000000000 +0200 @@ -383,6 +383,18 @@ static int _lvstatus_disp(struct dm_repo 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, &percent_range) && percent_range == PERCENT_INVALID) { + repstr[0] = toupper(repstr[0]); + repstr[4] = 'I'; + } + out: dm_report_field_set_value(field, repstr, NULL); return 1; @@ -1091,13 +1103,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, &percent_range) || (percent_range == PERCENT_INVALID)) { if (!lv_is_merging_origin(lv)) {