era block size is in 512b sectors; support calculating diff size

master
Vitaliy Filippov 2019-02-19 02:58:39 +03:00
parent f69f7a88cb
commit 6787050f95
1 changed files with 39 additions and 19 deletions

View File

@ -45,7 +45,7 @@ void read_era_invalidate_and_copy(FILE *fp, int src, int era_block_size)
// read input XML
char buf[XML_BUFSIZE] = { 0 };
char c = 0;
long long start = 0, length = 0;
long long start = 0, length = 0, total = 0;
if (fgets(buf, XML_BUFSIZE, fp) == NULL)
{
fprintf(stderr, "Input block list is empty\n");
@ -70,47 +70,67 @@ void read_era_invalidate_and_copy(FILE *fp, int src, int era_block_size)
{
break;
}
start = start*era_block_size;
length = length*era_block_size;
// write a very simple binary format: SIGNATURE, start, length, data, ...
write(1, SIGNATURE, 8);
write(1, &start, 8);
write(1, &length, 8);
copy_blocks(src, 1, start, length);
start = start*era_block_size*512;
length = length*era_block_size*512;
if (src >= 0)
{
// write a very simple binary format: SIGNATURE, start, length, data, ...
write(1, SIGNATURE, 8);
write(1, &start, 8);
write(1, &length, 8);
copy_blocks(src, 1, start, length);
}
else
{
// calculate diff size
total += length;
}
}
if (sscanf(buf, " </blocks > %c", &c) == 0 || c != 0)
{
fprintf(stderr, "</blocks> expected, but \"%s\" found\n", buf);
exit(1);
}
if (src < 0)
{
printf("%lld bytes\n", total);
}
}
void era_copy(char *src_path, int era_block_size)
{
int src;
src = open(src_path, O_RDONLY|O_LARGEFILE);
if (src < 0)
int src = -1;
if (src_path != NULL)
{
fprintf(stderr, "Failed to open %s for reading: %s\n", src_path, strerror(errno));
exit(1);
src = open(src_path, O_RDONLY|O_LARGEFILE);
if (src < 0)
{
fprintf(stderr, "Failed to open %s for reading: %s\n", src_path, strerror(errno));
exit(1);
}
}
read_era_invalidate_and_copy(stdin, src, era_block_size);
close(src);
if (src_path != NULL)
{
close(src);
}
}
int main(int narg, char *args[])
{
if (narg < 3)
if (narg < 2)
{
fprintf(stderr,
"era_copy - parses era_invalidate output and saves changed blocks to a stream\n"
"(c) Vitaliy Filippov, 2019+, distributed under the terms of GNU GPLv3.0 or later license\n"
"\n"
"USAGE:\nera_invalidate --metadata-snapshot --written-since <ERA> <META_DEVICE> |\\\n"
" era_copy <ERA_BLOCK_SIZE> <DATA_DEVICE> > era_copy.bin\n"
" era_copy <ERA_BLOCK_SIZE> [<DATA_DEVICE>] > era_copy.bin\n"
"\n"
"ERA_BLOCK_SIZE is the block size you used when creating dm-era device\n"
"You can take it from `dmsetup table <DATA_DEVICE>`: it's the last number in the table\n"
"When invoked without <DATA_DEVICE>, era_copy only calculates the future diff size and prints it\n"
"\n"
"ERA_BLOCK_SIZE is dm-era's granularity in 512-byte sectors you used when creating dm-era device\n"
"You can take it from `dmsetup table <DATA_DEVICE>`: it's the last number in DM table\n"
"For example, in `0 3625546496 era 259:3 259:2 65536` it's 65536\n"
);
exit(1);
@ -121,6 +141,6 @@ int main(int narg, char *args[])
fprintf(stderr, "Incorrect era_block_size = %d\n", bs);
exit(1);
}
era_copy(args[2], bs);
era_copy(narg == 2 ? NULL : args[2], bs);
return 0;
}