qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@gmail.com>
To: Miroslav Rezanina <mrezanin@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v3] Add compare subcommand for qemu-img
Date: Thu, 22 Nov 2012 10:18:15 +0100	[thread overview]
Message-ID: <20121122091815.GD7598@stefanha-thinkpad.redhat.com> (raw)
In-Reply-To: <1090097436.3721567.1353491414263.JavaMail.root@redhat.com>

On Wed, Nov 21, 2012 at 04:50:14AM -0500, Miroslav Rezanina wrote:
> diff --git a/qemu-img.c b/qemu-img.c
> index e29e01b..6294b11 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -101,7 +101,12 @@ static void help(void)
>             "  '-a' applies a snapshot (revert disk to saved state)\n"
>             "  '-c' creates a snapshot\n"
>             "  '-d' deletes a snapshot\n"
> -           "  '-l' lists all snapshots in the given image\n";
> +           "  '-l' lists all snapshots in the given image\n"

Please add "\n" to separate like the other parameter docs for
subcommands.

> +           "Parameters to compare subcommand:\n"
> +           "  '-f' First image format\n"
> +           "  '-F' Second image format\n"
> +           "  '-q' Quiet mode - do not print any output (except errors)\n"
> +           "  '-s' Strict mode - fail on different image size or sector allocation\n";
>  
>      printf("%s\nSupported formats:", help_msg);
>      bdrv_iterate_format(format_print, NULL);
> @@ -657,6 +662,277 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
>  }
>  
>  #define IO_BUF_SIZE (2 * 1024 * 1024)
> +#define sector_to_bytes(sector) ((sector) << BDRV_SECTOR_BITS)

No macros, please.  Hiding the sector conversion isn't consistent anyway
since further down in your patch you explicitly use >> BDRV_SECTOR_BITS.

Either open code or define static inline functions so we have type
information.

> +
> +/*
> + * Get number of sectors that can be stored in IO buffer.
> + */
> +
> +static int64_t sectors_to_process(int64_t total, int64_t from)

Doc comments fit snuggly against the function definition, no newline
please.  QEMU code isn't very consistent in doc comment formatting in
general but it does not use a newline here.

> +    for (;;) {
> +        c = getopt(argc, argv, "pf:F:sq");
> +        if (c == -1) {
> +            break;
> +        }
> +        switch (c) {
> +        case 'f':
> +            fmt1 = optarg;
> +            break;
> +        case 'F':
> +            fmt2 = optarg;
> +            break;
> +        case 'p':
> +            progress = (quiet == 0) ? 1 : 0;
> +            break;
> +        case 'q':
> +            quiet = 1;
> +            if (progress == 1) {
> +                progress = 0;
> +            }
> +            break;

It's cleaner to silence progress after all options have been parsed than
to duplicate the quiet/progress checking.

/* -q overrides -p */
if (quiet) {
    progress = 0;
}

> +        case 's':
> +            strict = 1;
> +            break;
> +        }

case 'h':
case '?':
    help();
    break;

> +    }
> +    if (optind >= argc) {

This subcommand takes two filenames, so check the number of arguments is
correct:

if (optind + 1 >= argc) {

> +        help();
> +        goto out3;
> +    }
> +    filename1 = argv[optind++];
> +    filename2 = argv[optind++];
> +
> +    /* Initialize before goto out */
> +    qemu_progress_init(progress, 2.0);
> +
> +    bs1 = bdrv_new_open(filename1, fmt1, flags, true);
> +    if (!bs1) {
> +        error_report("Can't open file %s", filename1);
> +        ret = 2;
> +        goto out3;
> +    }
> +
> +    bs2 = bdrv_new_open(filename2, fmt2, flags, true);
> +    if (!bs2) {
> +        error_report("Can't open file %s:", filename2);

Stray ':'?

> +        ret = 2;
> +        goto out2;
> +    }
> +
> +    buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
> +    buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
> +    bdrv_get_geometry(bs1, &bs_sectors);
> +    total_sectors1 = bs_sectors;
> +    bdrv_get_geometry(bs2, &bs_sectors);
> +    total_sectors2 = bs_sectors;
> +    total_sectors = total_sectors1;
> +    progress_base = total_sectors;
> +
> +    qemu_progress_print(0, 100);
> +
> +    if (total_sectors1 != total_sectors2) {
> +        BlockDriverState *bsover;
> +        int64_t lo_total_sectors, lo_sector_num;
> +        const char *filename_over;
> +
> +        if (strict) {
> +            ret = 1;
> +            if (!quiet) {
> +                printf("Strict mode: Image size mismatch!\n");
> +            }
> +            goto out;
> +        } else {
> +            error_report("Image size mismatch!");
> +        }
> +
> +        if (total_sectors1 > total_sectors2) {
> +            total_sectors = total_sectors2;
> +            lo_total_sectors = total_sectors1;
> +            lo_sector_num = total_sectors2;
> +            bsover = bs1;
> +            filename_over = filename1;
> +        } else {
> +            total_sectors = total_sectors1;
> +            lo_total_sectors = total_sectors2;
> +            lo_sector_num = total_sectors1;
> +            bsover = bs2;
> +            filename_over = filename2;
> +        }
> +
> +        progress_base = lo_total_sectors;
> +
> +        for (;;) {
> +            nb_sectors = sectors_to_process(lo_total_sectors, lo_sector_num);
> +            if (nb_sectors <= 0) {
> +                break;
> +            }
> +            rv = bdrv_is_allocated(bsover, lo_sector_num, nb_sectors, &pnum);

We should error out if a backing image has non-zero data:

rv = bdrv_is_allocated_above(bsover, NULL, lo_sector_num, nb_sectors &pnum);

> +            nb_sectors = pnum;
> +            if (rv) {
> +                rv = bdrv_read(bsover, lo_sector_num, buf1, nb_sectors);
> +                if (rv < 0) {
> +                    error_report("error while reading data offset %" PRId64
> +                                 " of %s: %s", sector_to_bytes(lo_sector_num),
> +                                 filename_over, strerror(-rv));
> +                    ret = 2;
> +                    goto out;
> +                }
> +                rv = is_allocated_sectors(buf1, nb_sectors, &pnum);
> +                if (rv || pnum != nb_sectors) {
> +                    ret = 1;
> +                    if (!quiet) {
> +                        printf("Content mismatch - offset %" PRId64
> +                               " not available in both images!\n",
> +                               sector_to_bytes(
> +                                   rv ? lo_sector_num : lo_sector_num + pnum));
> +                    }
> +                    goto out;
> +                }

This is duplicated from the code below.

Please split this function up into helper functions.  It will make some
of the temporary variables go away too.

  reply	other threads:[~2012-11-22  9:18 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1736118218.6697488.1343814369561.JavaMail.root@redhat.com>
2012-08-01 10:03 ` [Qemu-devel] [PATCH][RFC] Add compare subcommand for qemu-img Miroslav Rezanina
2012-08-01 10:22   ` Paolo Bonzini
2012-08-01 10:44     ` Miroslav Rezanina
2012-08-01 10:52       ` Paolo Bonzini
2012-08-02 10:06     ` Miroslav Rezanina
2012-08-02 11:11       ` Paolo Bonzini
2012-08-01 12:22   ` Stefan Hajnoczi
2012-08-01 13:21   ` Eric Blake
2012-08-01 13:23     ` Paolo Bonzini
2012-08-02  5:19     ` Miroslav Rezanina
2012-08-03  6:45   ` [Qemu-devel] [PATCH v2][RFC] " Miroslav Rezanina
2012-08-03 15:23     ` Eric Blake
2012-11-20 12:36     ` Kevin Wolf
2012-11-20 13:04       ` Miroslav Rezanina
2012-11-21  9:50     ` [Qemu-devel] [PATCH v3] " Miroslav Rezanina
2012-11-22  9:18       ` Stefan Hajnoczi [this message]
2012-11-27  8:03       ` [Qemu-devel] [PATCH v4] " Miroslav Rezanina
2012-11-30 14:22         ` Stefan Hajnoczi
2012-12-04 11:06         ` [Qemu-devel] [PATCH v5] " Miroslav Rezanina
2012-12-04 15:22           ` Stefan Hajnoczi
2012-12-06 12:24           ` [Qemu-devel] [PATCH v6] " Miroslav Rezanina
2012-12-11  9:16             ` Stefan Hajnoczi
2012-12-11 12:27             ` Kevin Wolf
2012-12-11 13:09               ` Miroslav Rezanina

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121122091815.GD7598@stefanha-thinkpad.redhat.com \
    --to=stefanha@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=mrezanin@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).