]> git.proxmox.com Git - pve-qemu-kvm.git/commitdiff
add vma verify command
authorDietmar Maurer <dietmar@proxmox.com>
Mon, 11 Mar 2013 10:12:09 +0000 (11:12 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Mon, 11 Mar 2013 10:12:09 +0000 (11:12 +0100)
Makefile
debian/changelog
debian/patches/0007-vma-add-verify-command.patch [new file with mode: 0644]
debian/patches/series

index 4f15e79f51703c68c9c9b540400c68cd19ccef15..d34589db865d812ec7f68c8631204c303021455d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ RELEASE=2.3
 
 # also update debian/changelog
 KVMVER=1.4
-KVMPKGREL=7
+KVMPKGREL=8
 
 KVMPACKAGE=pve-qemu-kvm
 KVMDIR=qemu-kvm
index eeaa8e947ba9cd530b43c8a9b273d66f5ee4d7f0..dda159c4e38019653140b466b357bcc7a7025e51 100644 (file)
@@ -1,3 +1,9 @@
+pve-qemu-kvm (1.4-8) unstable; urgency=low
+
+  * vma: add 'vma verify' command to verify vma archives
+
+ -- Proxmox Support Team <support@proxmox.com>  Mon, 11 Mar 2013 11:10:34 +0100
+
 pve-qemu-kvm (1.4-7) unstable; urgency=low
 
   * update seabios to 1.7.2.1 (fix freebsd boot)
diff --git a/debian/patches/0007-vma-add-verify-command.patch b/debian/patches/0007-vma-add-verify-command.patch
new file mode 100644 (file)
index 0000000..2feba4f
--- /dev/null
@@ -0,0 +1,320 @@
+From acdcd483ac6977e096ef7cde746d22bbf82e04d3 Mon Sep 17 00:00:00 2001
+From: Dietmar Maurer <dietmar@proxmox.com>
+Date: Mon, 11 Mar 2013 07:07:46 +0100
+Subject: [PATCH v5 7/7] vma: add verify command
+
+Users wants to verify the archive after backup.
+
+Examples:
+
+ # vma verify -v test.vma
+
+ # lzop -d -c test.vma.lzo |vma verify -
+
+Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
+---
+ vma-reader.c |  118 +++++++++++++++++++++++++++++++++++++++++++---------------
+ vma.c        |   57 +++++++++++++++++++++++++++-
+ vma.h        |    1 +
+ 3 files changed, 145 insertions(+), 31 deletions(-)
+
+diff --git a/vma-reader.c b/vma-reader.c
+index bc36cba..a740f04 100644
+--- a/vma-reader.c
++++ b/vma-reader.c
+@@ -53,6 +53,8 @@ struct VmaReader {
+     time_t start_time;
+     int64_t cluster_count;
+     int64_t clusters_read;
++    int64_t zero_cluster_data;
++    int64_t partial_zero_cluster_data;
+     int clusters_read_per;
+ };
+@@ -433,6 +435,27 @@ VmaDeviceInfo *vma_reader_get_device_info(VmaReader *vmar, guint8 dev_id)
+     return NULL;
+ }
++static void allocate_rstate(VmaReader *vmar,  guint8 dev_id, 
++                            BlockDriverState *bs, bool write_zeroes)
++{
++    assert(vmar);
++    assert(dev_id);
++
++    vmar->rstate[dev_id].bs = bs;
++    vmar->rstate[dev_id].write_zeroes = write_zeroes;
++
++    int64_t size = vmar->devinfo[dev_id].size;
++
++    int64_t bitmap_size = (size/BDRV_SECTOR_SIZE) +
++        (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG - 1;
++    bitmap_size /= (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG;
++
++    vmar->rstate[dev_id].bitmap_size = bitmap_size;
++    vmar->rstate[dev_id].bitmap = g_new0(unsigned long, bitmap_size);
++
++    vmar->cluster_count += size/VMA_CLUSTER_SIZE;
++}
++
+ int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockDriverState *bs,
+                            bool write_zeroes, Error **errp)
+ {
+@@ -449,17 +472,7 @@ int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id, BlockDriverState *bs,
+         return -1;
+     }
+-    vmar->rstate[dev_id].bs = bs;
+-    vmar->rstate[dev_id].write_zeroes = write_zeroes;
+-
+-    int64_t bitmap_size = (size/BDRV_SECTOR_SIZE) +
+-        (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG - 1;
+-    bitmap_size /= (VMA_CLUSTER_SIZE/BDRV_SECTOR_SIZE) * BITS_PER_LONG;
+-
+-    vmar->rstate[dev_id].bitmap_size = bitmap_size;
+-    vmar->rstate[dev_id].bitmap = g_new0(unsigned long, bitmap_size);
+-
+-    vmar->cluster_count += size/VMA_CLUSTER_SIZE;
++    allocate_rstate(vmar, dev_id, bs, write_zeroes);
+     return 0;
+ }
+@@ -526,9 +539,10 @@ static int restore_write_data(VmaReader *vmar, guint8 dev_id,
+     }
+     return 0;
+ }
++
+ static int restore_extent(VmaReader *vmar, unsigned char *buf,
+                           int extent_size, int vmstate_fd,
+-                          bool verbose, Error **errp)
++                          bool verbose, bool verify, Error **errp)
+ {
+     assert(vmar);
+     assert(buf);
+@@ -553,7 +567,7 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
+         if (dev_id != vmar->vmstate_stream) {
+             bs = rstate->bs;
+-            if (!bs) {
++            if (!verify && !bs) {
+                 error_setg(errp, "got wrong dev id %d", dev_id);
+                 return -1;
+             }
+@@ -609,10 +623,13 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
+                 return -1;
+             }
+-            int nb_sectors = end_sector - sector_num;
+-            if (restore_write_data(vmar, dev_id, bs, vmstate_fd, buf + start,
+-                                   sector_num, nb_sectors, errp) < 0) {
+-                return -1;
++            if (!verify) {
++                int nb_sectors = end_sector - sector_num;
++                if (restore_write_data(vmar, dev_id, bs, vmstate_fd, 
++                                       buf + start, sector_num, nb_sectors, 
++                                       errp) < 0) {
++                    return -1;
++                }
+             }
+             start += VMA_CLUSTER_SIZE;
+@@ -642,26 +659,37 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
+                         return -1;
+                     }
+-                    int nb_sectors = end_sector - sector_num;
+-                    if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
+-                                           buf + start, sector_num,
+-                                           nb_sectors, errp) < 0) {
+-                        return -1;
++                    if (!verify) {
++                        int nb_sectors = end_sector - sector_num;
++                        if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
++                                               buf + start, sector_num,
++                                               nb_sectors, errp) < 0) {
++                            return -1;
++                        }
+                     }
+                     start += VMA_BLOCK_SIZE;
+                 } else {
+-                    if (rstate->write_zeroes && (end_sector > sector_num)) {
++ 
++                    if (end_sector > sector_num) {
+                         /* Todo: use bdrv_co_write_zeroes (but that need to
+                          * be run inside coroutine?)
+                          */
+                         int nb_sectors = end_sector - sector_num;
+-                        if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
+-                                              zero_vma_block, sector_num,
+-                                               nb_sectors, errp) < 0) {
+-                            return -1;
++                        int zero_size = BDRV_SECTOR_SIZE*nb_sectors;
++                        vmar->zero_cluster_data += zero_size;
++                        if (mask != 0) {
++                            vmar->partial_zero_cluster_data += zero_size;
++                        }
++
++                        if (rstate->write_zeroes && !verify) {
++                            if (restore_write_data(vmar, dev_id, bs, vmstate_fd,
++                                                   zero_vma_block, sector_num,
++                                                   nb_sectors, errp) < 0) {
++                                return -1;
++                            }
+                         }
+                     }
+                 }
+@@ -679,8 +707,9 @@ static int restore_extent(VmaReader *vmar, unsigned char *buf,
+     return 0;
+ }
+-int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
+-                       Error **errp)
++static int vma_reader_restore_full(VmaReader *vmar, int vmstate_fd, 
++                                   bool verbose, bool verify,
++                                   Error **errp)
+ {
+     assert(vmar);
+     assert(vmar->head_data);
+@@ -747,7 +776,7 @@ int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
+         }
+         if (restore_extent(vmar, buf, extent_size, vmstate_fd, verbose,
+-                           errp) < 0) {
++                           verify, errp) < 0) {
+             return -1;
+         }
+@@ -794,6 +823,35 @@ int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
+         }
+     }
++    if (verbose) {
++        printf("total bytes read %zd, sparse bytes %zd (%.3g%%)\n",
++               vmar->clusters_read*VMA_CLUSTER_SIZE,
++               vmar->zero_cluster_data,
++               (double)(100.0*vmar->zero_cluster_data)/
++               (vmar->clusters_read*VMA_CLUSTER_SIZE));
++        printf("space reduction due to 4K zero bocks %.3g%%\n",
++               (double)(100.0*vmar->partial_zero_cluster_data) /
++               (vmar->clusters_read*VMA_CLUSTER_SIZE-vmar->zero_cluster_data));
++    }
+     return ret;
+ }
++int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
++                       Error **errp)
++{
++    return vma_reader_restore_full(vmar, vmstate_fd, verbose, false, errp);
++}
++
++int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp)
++{
++    guint8 dev_id;
++
++    for (dev_id = 1; dev_id < 255; dev_id++) {
++        if (vma_reader_get_device_info(vmar, dev_id)) {
++            allocate_rstate(vmar, dev_id, NULL, false);
++        }
++    }
++
++    return vma_reader_restore_full(vmar, -1, verbose, true, errp);
++}
++
+diff --git a/vma.c b/vma.c
+index 6633aa5..bcde379 100644
+--- a/vma.c
++++ b/vma.c
+@@ -33,7 +33,8 @@ static void help(void)
+         "\n"
+         "vma list <filename>\n"
+         "vma create <filename> [-c config] <archive> pathname ...\n"
+-        "vma extract <filename> [-r] <targetdir>\n"
++        "vma extract <filename> [-v] [-r] <targetdir>\n"
++        "vma verify <filename> [-v]\n"
+         ;
+     printf("%s", help_msg);
+@@ -337,6 +338,58 @@ static int extract_content(int argc, char **argv)
+     return ret;
+ }
++static int verify_content(int argc, char **argv)
++{
++    int c, ret = 0;
++    int verbose = 0;
++    const char *filename;
++
++    for (;;) {
++        c = getopt(argc, argv, "hv");
++        if (c == -1) {
++            break;
++        }
++        switch (c) {
++        case '?':
++        case 'h':
++            help();
++            break;
++        case 'v':
++            verbose = 1;
++            break;
++        default:
++            help();
++        }
++    }
++
++    /* Get the filename */
++    if ((optind + 1) != argc) {
++        help();
++    }
++    filename = argv[optind++];
++
++    Error *errp = NULL;
++    VmaReader *vmar = vma_reader_create(filename, &errp);
++
++    if (!vmar) {
++        g_error("%s", error_get_pretty(errp));
++    }
++
++    if (verbose) {
++        print_content(vmar);
++    }
++
++    if (vma_reader_verify(vmar, verbose, &errp) < 0) {
++        g_error("verify failed - %s", error_get_pretty(errp));
++    }
++
++    vma_reader_destroy(vmar);
++
++    bdrv_close_all();
++
++    return ret;
++}
++
+ typedef struct BackupCB {
+     VmaWriter *vmaw;
+     uint8_t dev_id;
+@@ -554,6 +607,8 @@ int main(int argc, char **argv)
+         return create_archive(argc, argv);
+     } else if (!strcmp(cmdname, "extract")) {
+         return extract_content(argc, argv);
++    } else if (!strcmp(cmdname, "verify")) {
++        return verify_content(argc, argv);
+     }
+     help();
+diff --git a/vma.h b/vma.h
+index 76d0dc8..ebd96c1 100644
+--- a/vma.h
++++ b/vma.h
+@@ -141,5 +141,6 @@ int vma_reader_register_bs(VmaReader *vmar, guint8 dev_id,
+                            Error **errp);
+ int vma_reader_restore(VmaReader *vmar, int vmstate_fd, bool verbose,
+                        Error **errp);
++int vma_reader_verify(VmaReader *vmar, bool verbose, Error **errp);
+ #endif /* BACKUP_VMA_H */
+-- 
+1.7.2.5
+
index 50721ad631d61a08a083c6d81bc595fd34051be7..01a5affdbb45113b0ae2c38519f691fee72d14dd 100644 (file)
@@ -16,6 +16,7 @@ enable-kvm-by-default.patch
 0004-introduce-new-vma-archive-format.patch
 0005-add-regression-tests-for-backup.patch
 0006-add-vm-state-to-backups.patch
+0007-vma-add-verify-command.patch
 # always-update-expected-downtime.patch
 virtio-balloon-fix-query.patch
 set-cpu-model-to-kvm64.patch