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