The Friday 05 Sep 2014 à 16:07:16 (+0200), Max Reitz wrote : > Add a helper function for easily marking an image corrupt (on fatal > corruptions) while outputting an informative message to stderr and via > QAPI. > > Signed-off-by: Max Reitz <mre...@redhat.com> > --- > block/qcow2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ > block/qcow2.h | 5 +++++ > 2 files changed, 53 insertions(+) > > diff --git a/block/qcow2.c b/block/qcow2.c > index f9e045f..fc4217b 100644 > --- a/block/qcow2.c > +++ b/block/qcow2.c > @@ -30,6 +30,8 @@ > #include "qemu/error-report.h" > #include "qapi/qmp/qerror.h" > #include "qapi/qmp/qbool.h" > +#include "qapi/qmp/types.h" > +#include "qapi-event.h" > #include "trace.h" > #include "qemu/option_int.h" > > @@ -2478,6 +2480,52 @@ static int qcow2_amend_options(BlockDriverState *bs, > QemuOpts *opts) > return 0; > } > > +/* > + * If offset or size are negative, respectively, they will not be included in > + * the BLOCK_IMAGE_CORRUPTED event emitted. > + * fatal will be ignored for read-only BDS; corruptions found there will > always > + * be considered non-fatal. > + */ > +void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t > offset, > + int64_t size, const char *message_format, ...) > +{ > + BDRVQcowState *s = bs->opaque; > + char *message; > + va_list ap; > + > + fatal = fatal && !bs->read_only; > + > + if (s->signaled_corruption && > + (!fatal || (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT))) > + { > + return; > + } > + > + va_start(ap, message_format); > + message = g_strdup_vprintf(message_format, ap); > + va_end(ap); > + > + if (fatal) { > + fprintf(stderr, "qcow2: Marking image as corrupt: %s; further " > + "corruption events will be suppressed\n", message); > + } else { > + fprintf(stderr, "qcow2: Image is corrupt: %s; further non-fatal " > + "corruption events will be suppressed\n", message); > + } > + > + qapi_event_send_block_image_corrupted(bdrv_get_device_name(bs), message, > + offset >= 0, offset, size >= 0, > size, > + fatal, &error_abort); > + g_free(message); > + > + if (fatal) { > + qcow2_mark_corrupt(bs); > + bs->drv = NULL; /* make BDS unusable */ > + } > + > + s->signaled_corruption = true; > +} > + > static QemuOptsList qcow2_create_opts = { > .name = "qcow2-create-opts", > .head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head), > diff --git a/block/qcow2.h b/block/qcow2.h > index 6aeb7ea..7b7b6a6 100644 > --- a/block/qcow2.h > +++ b/block/qcow2.h > @@ -261,6 +261,7 @@ typedef struct BDRVQcowState { > bool discard_passthrough[QCOW2_DISCARD_MAX]; > > int overlap_check; /* bitmask of Qcow2MetadataOverlap values */ > + bool signaled_corruption; > > uint64_t incompatible_features; > uint64_t compatible_features; > @@ -477,6 +478,10 @@ int qcow2_mark_corrupt(BlockDriverState *bs); > int qcow2_mark_consistent(BlockDriverState *bs); > int qcow2_update_header(BlockDriverState *bs); > > +void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t > offset, > + int64_t size, const char *message_format, ...) > + GCC_FMT_ATTR(5, 6); > + > /* qcow2-refcount.c functions */ > int qcow2_refcount_init(BlockDriverState *bs); > void qcow2_refcount_close(BlockDriverState *bs); > -- > 2.1.0 > > Reviewed-by: Benoît Canet <benoit.ca...@nodalink.com>