Revision e076f338
b/block.c | ||
---|---|---|
710 | 710 |
/* |
711 | 711 |
* Run consistency checks on an image |
712 | 712 |
* |
713 |
* Returns the number of errors or -errno when an internal error occurs |
|
713 |
* Returns 0 if the check could be completed (it doesn't mean that the image is |
|
714 |
* free of errors) or -errno when an internal error occured. The results of the |
|
715 |
* check are stored in res. |
|
714 | 716 |
*/ |
715 |
int bdrv_check(BlockDriverState *bs) |
|
717 |
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
|
|
716 | 718 |
{ |
717 | 719 |
if (bs->drv->bdrv_check == NULL) { |
718 | 720 |
return -ENOTSUP; |
719 | 721 |
} |
720 | 722 |
|
721 |
return bs->drv->bdrv_check(bs); |
|
723 |
memset(res, 0, sizeof(*res)); |
|
724 |
res->corruptions = bs->drv->bdrv_check(bs); |
|
725 |
return res->corruptions < 0 ? res->corruptions : 0; |
|
722 | 726 |
} |
723 | 727 |
|
724 | 728 |
/* commit COW file into the raw image */ |
b/block.h | ||
---|---|---|
74 | 74 |
int bdrv_attach(BlockDriverState *bs, DeviceState *qdev); |
75 | 75 |
void bdrv_detach(BlockDriverState *bs, DeviceState *qdev); |
76 | 76 |
DeviceState *bdrv_get_attached(BlockDriverState *bs); |
77 |
int bdrv_check(BlockDriverState *bs); |
|
78 | 77 |
int bdrv_read(BlockDriverState *bs, int64_t sector_num, |
79 | 78 |
uint8_t *buf, int nb_sectors); |
80 | 79 |
int bdrv_write(BlockDriverState *bs, int64_t sector_num, |
... | ... | |
97 | 96 |
const char *backing_file, const char *backing_fmt); |
98 | 97 |
void bdrv_register(BlockDriver *bdrv); |
99 | 98 |
|
99 |
|
|
100 |
typedef struct BdrvCheckResult { |
|
101 |
int corruptions; |
|
102 |
int leaks; |
|
103 |
int check_errors; |
|
104 |
} BdrvCheckResult; |
|
105 |
|
|
106 |
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res); |
|
107 |
|
|
100 | 108 |
/* async block I/O */ |
101 | 109 |
typedef struct BlockDriverAIOCB BlockDriverAIOCB; |
102 | 110 |
typedef void BlockDriverCompletionFunc(void *opaque, int ret); |
b/qemu-img.c | ||
---|---|---|
425 | 425 |
return 0; |
426 | 426 |
} |
427 | 427 |
|
428 |
/* |
|
429 |
* Checks an image for consistency. Exit codes: |
|
430 |
* |
|
431 |
* 0 - Check completed, image is good |
|
432 |
* 1 - Check not completed because of internal errors |
|
433 |
* 2 - Check completed, image is corrupted |
|
434 |
* 3 - Check completed, image has leaked clusters, but is good otherwise |
|
435 |
*/ |
|
428 | 436 |
static int img_check(int argc, char **argv) |
429 | 437 |
{ |
430 | 438 |
int c, ret; |
431 | 439 |
const char *filename, *fmt; |
432 | 440 |
BlockDriverState *bs; |
441 |
BdrvCheckResult result; |
|
433 | 442 |
|
434 | 443 |
fmt = NULL; |
435 | 444 |
for(;;) { |
... | ... | |
453 | 462 |
if (!bs) { |
454 | 463 |
return 1; |
455 | 464 |
} |
456 |
ret = bdrv_check(bs); |
|
457 |
switch(ret) { |
|
458 |
case 0: |
|
459 |
printf("No errors were found on the image.\n"); |
|
460 |
break; |
|
461 |
case -ENOTSUP: |
|
465 |
ret = bdrv_check(bs, &result); |
|
466 |
|
|
467 |
if (ret == -ENOTSUP) { |
|
462 | 468 |
error("This image format does not support checks"); |
463 |
break; |
|
464 |
default: |
|
465 |
if (ret < 0) { |
|
466 |
error("An error occurred during the check"); |
|
467 |
} else { |
|
468 |
printf("%d errors were found on the image.\n", ret); |
|
469 |
bdrv_delete(bs); |
|
470 |
return 1; |
|
471 |
} |
|
472 |
|
|
473 |
if (!(result.corruptions || result.leaks || result.check_errors)) { |
|
474 |
printf("No errors were found on the image.\n"); |
|
475 |
} else { |
|
476 |
if (result.corruptions) { |
|
477 |
printf("\n%d errors were found on the image.\n" |
|
478 |
"Data may be corrupted, or further writes to the image " |
|
479 |
"may corrupt it.\n", |
|
480 |
result.corruptions); |
|
481 |
} |
|
482 |
|
|
483 |
if (result.leaks) { |
|
484 |
printf("\n%d leaked clusters were found on the image.\n" |
|
485 |
"This means waste of disk space, but no harm to data.\n", |
|
486 |
result.leaks); |
|
487 |
} |
|
488 |
|
|
489 |
if (result.check_errors) { |
|
490 |
printf("\n%d internal errors have occurred during the check.\n", |
|
491 |
result.check_errors); |
|
469 | 492 |
} |
470 |
break; |
|
471 | 493 |
} |
472 | 494 |
|
473 | 495 |
bdrv_delete(bs); |
474 |
if (ret) { |
|
496 |
|
|
497 |
if (ret < 0 || result.check_errors) { |
|
498 |
printf("\nAn error has occurred during the check: %s\n" |
|
499 |
"The check is not complete and may have missed error.\n", |
|
500 |
strerror(-ret)); |
|
475 | 501 |
return 1; |
476 | 502 |
} |
477 |
return 0; |
|
503 |
|
|
504 |
if (result.corruptions) { |
|
505 |
return 2; |
|
506 |
} else if (result.leaks) { |
|
507 |
return 3; |
|
508 |
} else { |
|
509 |
return 0; |
|
510 |
} |
|
478 | 511 |
} |
479 | 512 |
|
480 | 513 |
static int img_commit(int argc, char **argv) |
Also available in: Unified diff