Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 709

kvm-83-270.el5_11.src.rpm

From a05ea85357cb28cad77a605ccf5e70c30203a252 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 8 Jul 2010 15:34:07 -0300
Subject: [PATCH 4/5] qemu-img check: Distinguish different kinds of errors

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1278603248-15580-2-git-send-email-kwolf@redhat.com>
Patchwork-id: 10574
O-Subject: [RHEL-5.6 KVM PATCH 1/2] qemu-img check: Distinguish different kinds
	of errors
Bugzilla: 606651
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Christoph Hellwig <chellwig@redhat.com>
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>

Bugzilla: 606651
Upstream commit: e076f3383b08a563d76c8beb9a716788a3987df9

People think that their images are corrupted when in fact there are just some
leaked clusters. Differentiating several error cases should make the messages
more comprehensible.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu/block.c    |   10 ++++++--
 qemu/block.h    |   10 +++++++-
 qemu/qemu-img.c |   63 ++++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 65 insertions(+), 18 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/block.c    |   10 ++++++--
 qemu/block.h    |   10 +++++++-
 qemu/qemu-img.c |   63 ++++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/qemu/block.c b/qemu/block.c
index 73c5952..845ca9f 100644
--- a/qemu/block.c
+++ b/qemu/block.c
@@ -596,15 +596,19 @@ void bdrv_delete(BlockDriverState *bs)
 /*
  * Run consistency checks on an image
  *
- * Returns the number of errors or -errno when an internal error occurs
+ * Returns 0 if the check could be completed (it doesn't mean that the image is
+ * free of errors) or -errno when an internal error occured. The results of the
+ * check are stored in res.
  */
-int bdrv_check(BlockDriverState *bs)
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
 {
     if (bs->drv->bdrv_check == NULL) {
         return -ENOTSUP;
     }
 
-    return bs->drv->bdrv_check(bs);
+    memset(res, 0, sizeof(*res));
+    res->corruptions = bs->drv->bdrv_check(bs);
+    return res->corruptions < 0 ? res->corruptions : 0;
 }
 
 /* commit COW file into the raw image */
diff --git a/qemu/block.h b/qemu/block.h
index 16a6baf..0858935 100644
--- a/qemu/block.h
+++ b/qemu/block.h
@@ -70,7 +70,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags);
 int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
                BlockDriver *drv);
 void bdrv_close(BlockDriverState *bs);
-int bdrv_check(BlockDriverState *bs);
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors);
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
@@ -90,6 +89,15 @@ void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *pse
 int bdrv_commit(BlockDriverState *bs);
 int bdrv_change_backing_file(BlockDriverState *bs,
     const char *backing_file, const char *backing_fmt);
+
+typedef struct BdrvCheckResult {
+    int corruptions;
+    int leaks;
+    int check_errors;
+} BdrvCheckResult;
+
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
+
 /* async block I/O */
 typedef struct BlockDriverAIOCB BlockDriverAIOCB;
 typedef void BlockDriverCompletionFunc(void *opaque, int ret);
diff --git a/qemu/qemu-img.c b/qemu/qemu-img.c
index 2b9c3ad..58cd23c 100644
--- a/qemu/qemu-img.c
+++ b/qemu/qemu-img.c
@@ -326,12 +326,21 @@ static int img_create(int argc, char **argv)
     return 0;
 }
 
+/*
+ * Checks an image for consistency. Exit codes:
+ *
+ * 0 - Check completed, image is good
+ * 1 - Check not completed because of internal errors
+ * 2 - Check completed, image is corrupted
+ * 3 - Check completed, image has leaked clusters, but is good otherwise
+ */
 static int img_check(int argc, char **argv)
 {
     int c, ret;
     const char *filename, *fmt;
     BlockDriver *drv;
     BlockDriverState *bs;
+    BdrvCheckResult result;
 
     fmt = NULL;
     for(;;) {
@@ -364,25 +373,51 @@ static int img_check(int argc, char **argv)
     if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
         error("Could not open '%s'", filename);
     }
-    ret = bdrv_check(bs);
-    switch(ret) {
-    case 0:
-        printf("No errors were found on the image.\n");
-        break;
-    case -ENOTSUP:
+    ret = bdrv_check(bs, &result);
+
+    if (ret == -ENOTSUP) {
         error("This image format does not support checks");
-        break;
-    default:
-        if (ret < 0) {
-            error("An error occurred during the check");
-        } else {
-            printf("%d errors were found on the image.\n", ret);
+        bdrv_delete(bs);
+        return 1;
+    }
+
+    if (!(result.corruptions || result.leaks || result.check_errors)) {
+        printf("No errors were found on the image.\n");
+    } else {
+        if (result.corruptions) {
+            printf("\n%d errors were found on the image.\n"
+                "Data may be corrupted, or further writes to the image "
+                "may corrupt it.\n",
+                result.corruptions);
+        }
+
+        if (result.leaks) {
+            printf("\n%d leaked clusters were found on the image.\n"
+                "This means waste of disk space, but no harm to data.\n",
+                result.leaks);
+        }
+
+        if (result.check_errors) {
+            printf("\n%d internal errors have occurred during the check.\n",
+                result.check_errors);
         }
-        break;
     }
 
     bdrv_delete(bs);
-    return 0;
+
+    if (ret < 0 || result.check_errors) {
+        printf("\nAn error has occurred during the check: %s\n"
+            "The check is not complete and may have missed error.\n",
+            strerror(-ret));
+    }
+
+    if (result.corruptions) {
+        return 2;
+    } else if (result.leaks) {
+        return 3;
+    } else {
+        return 0;
+    }
 }
 
 static int img_commit(int argc, char **argv)
-- 
1.7.0.3