1 From acdcd483ac6977e096ef7cde746d22bbf82e04d3 Mon Sep 17 00:00:00 2001
2 From: Dietmar Maurer <dietmar@proxmox.com>
3 Date: Mon, 11 Mar 2013 07:07:46 +0100
4 Subject: [PATCH v5 7/7] vma: add verify command
6 Users wants to verify the archive after backup.
10 # vma verify -v test.vma
12 # lzop -d -c test.vma.lzo |vma verify -
14 Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
16 vma-reader.c | 118 +++++++++++++++++++++++++++++++++++++++++++---------------
17 vma.c | 57 +++++++++++++++++++++++++++-
19 3 files changed, 145 insertions(+), 31 deletions(-)
21 Index: new/vma-reader.c
22 ===================================================================
23 --- new.orig/vma-reader.c 2014-11-20 08:15:12.000000000 +0100
24 +++ new/vma-reader.c 2014-11-20 08:47:30.000000000 +0100
27 int64_t cluster_count;
28 int64_t clusters_read;
29 + int64_t zero_cluster_data;
30 + int64_t partial_zero_cluster_data;
31 int clusters_read_per;
38 +static void allocate_rstate(VmaReader *vmar, guint8 dev_id,
39 + BlockDriverState *bs, bool write_zeroes)
44 + vmar->rstate[dev_id].bs = bs;
45 + vmar->rstate[dev_id].write_zeroes = write_zeroes;
47 + int64_t size = vmar->devinfo[dev_id].size;
49 + int64_t bitmap_size = (size/BDRV_SECTOR_SIZE) +
50 + (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG - 1;
51 + bitmap_size /= (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG;
53 + vmar->rstate[dev_id].bitmap_size = bitmap_size;
54 + vmar->rstate[dev_id].bitmap = g_new0(unsigned long, bitmap_size);
56 + vmar->cluster_count += size/VMA_CLUSTER_SIZE;
59 int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockDriverState *bs,
60 bool write_zeroes, Error **errp)
66 - vmar->rstate[dev_id].bs = bs;
67 - vmar->rstate[dev_id].write_zeroes = write_zeroes;
69 - int64_t bitmap_size = (size/BDRV_SECTOR_SIZE) +
70 - (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG - 1;
71 - bitmap_size /= (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG;
73 - vmar->rstate[dev_id].bitmap_size = bitmap_size;
74 - vmar->rstate[dev_id].bitmap = g_new0(unsigned long, bitmap_size);
76 - vmar->cluster_count += size/VMA_CLUSTER_SIZE;
77 + allocate_rstate(vmar, dev_id, bs, write_zeroes);
86 static int restore_extent(VmaReader *vmar, unsigned char *buf,
87 int extent_size, int vmstate_fd,
88 - bool verbose, Error **errp)
89 + bool verbose, bool verify, Error **errp)
95 if (dev_id != vmar->vmstate_stream) {
98 + if (!verify && !bs) {
99 error_setg(errp, "got wrong dev id %d", dev_id);
102 @@ -609,10 +623,13 @@
106 - int nb_sectors = end_sector - sector_num;
107 - if (restore_write_data(vmar, dev_id, bs, vmstate_fd, buf + start,
108 - sector_num, nb_sectors, errp) < 0) {
111 + int nb_sectors = end_sector - sector_num;
112 + if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
113 + buf + start, sector_num, nb_sectors,
119 start += VMA_CLUSTER_SIZE;
120 @@ -642,26 +659,37 @@
124 - int nb_sectors = end_sector - sector_num;
125 - if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
126 - buf + start, sector_num,
127 - nb_sectors, errp) < 0) {
130 + int nb_sectors = end_sector - sector_num;
131 + if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
132 + buf + start, sector_num,
133 + nb_sectors, errp) < 0) {
138 start += VMA_BLOCK_SIZE;
142 - if (rstate->write_zeroes && (end_sector > sector_num)) {
144 + if (end_sector > sector_num) {
145 /* Todo: use bdrv_co_write_zeroes (but that need to
146 * be run inside coroutine?)
148 int nb_sectors = end_sector - sector_num;
149 - if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
150 - zero_vma_block, sector_num,
151 - nb_sectors, errp) < 0) {
153 + int zero_size = BDRV_SECTOR_SIZE*nb_sectors;
154 + vmar->zero_cluster_data += zero_size;
156 + vmar->partial_zero_cluster_data += zero_size;
159 + if (rstate->write_zeroes && !verify) {
160 + if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
161 + zero_vma_block, sector_num,
162 + nb_sectors, errp) < 0) {
172 -int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
174 +static int vma_reader_restore_full(VmaReader *vmar, int vmstate_fd,
175 + bool verbose, bool verify,
179 assert(vmar->head_data);
183 if (restore_extent(vmar, buf, extent_size, vmstate_fd, verbose,
185 + verify, errp) < 0) {
194 + printf("total bytes read %zd, sparse bytes %zd (%.3g%%)\n",
195 + vmar->clusters_read*VMA_CLUSTER_SIZE,
196 + vmar->zero_cluster_data,
197 + (double)(100.0*vmar->zero_cluster_data)/
198 + (vmar->clusters_read*VMA_CLUSTER_SIZE));
200 + int64_t datasize = vmar->clusters_read*VMA_CLUSTER_SIZE-vmar->zero_cluster_data;
201 + if (datasize) { // this does not make sense for empty files
202 + printf("space reduction due to 4K zero blocks %.3g%%\n",
203 + (double)(100.0*vmar->partial_zero_cluster_data) / datasize);
209 +int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
212 + return vma_reader_restore_full(vmar, vmstate_fd, verbose, false, errp);
215 +int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp)
219 + for (dev_id = 1; dev_id < 255; dev_id++) {
220 + if (vma_reader_get_device_info(vmar, dev_id)) {
221 + allocate_rstate(vmar, dev_id, NULL, false);
225 + return vma_reader_restore_full(vmar, -1, verbose, true, errp);
229 ===================================================================
230 --- new.orig/vma.c 2014-11-20 08:47:23.000000000 +0100
231 +++ new/vma.c 2014-11-20 08:47:30.000000000 +0100
233 "vma list <filename>\n"
234 "vma create <filename> [-c config] <archive> pathname ...\n"
235 "vma extract <filename> [-r <fifo>] <targetdir>\n"
236 + "vma verify <filename> [-v]\n"
239 printf("%s", help_msg);
244 +static int verify_content(int argc, char **argv)
248 + const char *filename;
251 + c = getopt(argc, argv, "hv");
268 + /* Get the filename */
269 + if ((optind + 1) != argc) {
272 + filename = argv[optind++];
274 + Error *errp = NULL;
275 + VmaReader *vmar = vma_reader_create(filename, &errp);
278 + g_error("%s", error_get_pretty(errp));
282 + print_content(vmar);
285 + if (vma_reader_verify(vmar, verbose, &errp) < 0) {
286 + g_error("verify failed - %s", error_get_pretty(errp));
289 + vma_reader_destroy(vmar);
296 typedef struct BackupJob {
297 BlockDriverState *bs;
300 return create_archive(argc, argv);
301 } else if (!strcmp(cmdname, "extract")) {
302 return extract_content(argc, argv);
303 + } else if (!strcmp(cmdname, "verify")) {
304 + return verify_content(argc, argv);
309 ===================================================================
310 --- new.orig/vma.h 2014-11-20 08:15:12.000000000 +0100
311 +++ new/vma.h 2014-11-20 08:47:30.000000000 +0100
314 int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
316 +int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp);
318 #endif /* BACKUP_VMA_H */