Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 3160499aacb81f6735941eb4c372d87a > files > 588

kvm-83-164.el5_5.30.src.rpm

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

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <patch-10574-clone-for-rhel55-rhel55>
Patchwork-id: 10581
O-Subject: [RHEL-5.6 KVM PATCH 1/2] qemu-img check: Distinguish different kinds
	of errors
Bugzilla: 618206
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
RH-Acked-by: Christoph Hellwig <chellwig@redhat.com>
RH-Acked-by: Juan Quintela <quintela@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 395df1a..9ed7b91 100644
--- a/qemu/block.c
+++ b/qemu/block.c
@@ -589,15 +589,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 0c6d984..e571be6 100644
--- a/qemu/block.h
+++ b/qemu/block.h
@@ -72,7 +72,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,
@@ -92,6 +91,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 83d568b..d086cc7 100644
--- a/qemu/qemu-img.c
+++ b/qemu/qemu-img.c
@@ -321,12 +321,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(;;) {
@@ -359,25 +368,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