libdm: compute percentage of snapshot-merge

Computes the merge completion percentage from the sector information.

Provided test for the function.

Change-Id: I64d83baa0478f9e6969636ee067174910d9b8e03
Bug: N/A
Test: dm_test
Signed-off-by: Alessio Balsini <balsini@google.com>
This commit is contained in:
Alessio Balsini 2019-07-31 21:21:15 +01:00
parent 4560856e33
commit 3565e31b42
3 changed files with 74 additions and 0 deletions

View file

@ -150,6 +150,25 @@ std::string DmTargetSnapshot::GetParameterString() const {
return base_device_ + " " + cow_device_ + " " + mode + " " + std::to_string(chunk_size_);
}
// Computes the percentage of complition for snapshot status.
// @sectors_initial is the number of sectors_allocated stored right before
// starting the merge.
double DmTargetSnapshot::MergePercent(const DmTargetSnapshot::Status& status,
uint64_t sectors_initial) {
uint64_t s = status.sectors_allocated;
uint64_t t = status.total_sectors;
uint64_t m = status.metadata_sectors;
uint64_t i = sectors_initial == 0 ? t : sectors_initial;
if (t <= s || i <= s) {
return 0.0;
}
if (s == 0 || t == 0 || s <= m) {
return 100.0;
}
return 100.0 / (i - m) * (i - s);
}
bool DmTargetSnapshot::ReportsOverflow(const std::string& target_type) {
DeviceMapper& dm = DeviceMapper::Instance();
DmTargetTypeInfo info;

View file

@ -483,6 +483,60 @@ TEST(libdm, ParseStatusText) {
EXPECT_TRUE(DmTargetSnapshot::ParseStatusText("Overflow", &status));
}
TEST(libdm, DmSnapshotMergePercent) {
DmTargetSnapshot::Status status;
// Correct input
status.sectors_allocated = 1000;
status.total_sectors = 1000;
status.metadata_sectors = 0;
EXPECT_LE(DmTargetSnapshot::MergePercent(status), 1.0);
status.sectors_allocated = 500;
status.total_sectors = 1000;
status.metadata_sectors = 0;
EXPECT_GE(DmTargetSnapshot::MergePercent(status), 49.0);
EXPECT_LE(DmTargetSnapshot::MergePercent(status), 51.0);
status.sectors_allocated = 0;
status.total_sectors = 1000;
status.metadata_sectors = 0;
EXPECT_GE(DmTargetSnapshot::MergePercent(status), 99.0);
status.sectors_allocated = 500;
status.total_sectors = 1000;
status.metadata_sectors = 500;
EXPECT_GE(DmTargetSnapshot::MergePercent(status), 99.0);
status.sectors_allocated = 500;
status.total_sectors = 1000;
status.metadata_sectors = 0;
EXPECT_LE(DmTargetSnapshot::MergePercent(status, 500), 1.0);
EXPECT_LE(DmTargetSnapshot::MergePercent(status, 1000), 51.0);
EXPECT_GE(DmTargetSnapshot::MergePercent(status, 1000), 49.0);
// Robustness
status.sectors_allocated = 2000;
status.total_sectors = 1000;
status.metadata_sectors = 0;
EXPECT_LE(DmTargetSnapshot::MergePercent(status), 0.0);
status.sectors_allocated = 2000;
status.total_sectors = 1000;
status.metadata_sectors = 2000;
EXPECT_LE(DmTargetSnapshot::MergePercent(status), 0.0);
status.sectors_allocated = 2000;
status.total_sectors = 0;
status.metadata_sectors = 2000;
EXPECT_LE(DmTargetSnapshot::MergePercent(status), 0.0);
status.sectors_allocated = 1000;
status.total_sectors = 0;
status.metadata_sectors = 1000;
EXPECT_LE(DmTargetSnapshot::MergePercent(status, 0), 0.0);
}
TEST(libdm, CryptArgs) {
DmTargetCrypt target1(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
ASSERT_EQ(target1.name(), "crypt");

View file

@ -216,6 +216,7 @@ class DmTargetSnapshot final : public DmTarget {
std::string error;
};
static double MergePercent(const Status& status, uint64_t sectors_initial = 0);
static bool ParseStatusText(const std::string& text, Status* status);
static bool ReportsOverflow(const std::string& target_type);