From f262d114ddfe11bad7b2f109cb965873f132f74e Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Sat, 13 Jun 2015 16:22:02 +0200 Subject: [PATCH 08/42] qcow2: Add qcow2_signal_corruption() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-id: <1434212556-3927-9-git-send-email-mreitz@redhat.com> Patchwork-id: 66027 O-Subject: [RHEL-7.2 qemu-kvm PATCH 08/42] qcow2: Add qcow2_signal_corruption() Bugzilla: 1129893 RH-Acked-by: Jeffrey Cody RH-Acked-by: Fam Zheng RH-Acked-by: Stefan Hajnoczi BZ: 1129893 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 Reviewed-by: Eric Blake Reviewed-by: BenoƮt Canet Message-id: 1409926039-29044-3-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi (cherry picked from commit 85186ebdac7e183242deaa55d5049988de832be1) Signed-off-by: Miroslav Rezanina Conflicts: block/qcow2.c No qapi_event_send_*() downstream. Signed-off-by: Max Reitz --- block/qcow2.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2.h | 5 +++++ 2 files changed, 67 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c index 6026f8a..be7e8e8 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -31,6 +31,8 @@ #include "qapi/qmp/qerror.h" #include "qapi/qmp/qbool.h" #include "qapi/util.h" +#include "qapi/qmp/types.h" +#include "monitor/monitor.h" #include "trace.h" /* @@ -2329,6 +2331,66 @@ static int qcow2_amend_options(BlockDriverState *bs, 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; + QObject *data; + 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); + } + + assert((offset >= 0) == (size >= 0)); + + if (offset >= 0) { + data = qobject_from_jsonf("{ 'device': %s, 'msg': %s, 'offset': %" + PRId64 ", 'size': %" PRId64 ", 'fatal': %s }", + bdrv_get_device_name(bs), message, + offset, size, fatal ? "true" : "false"); + } else { + data = qobject_from_jsonf("{ 'device': %s, 'msg': %s, 'fatal': %s }", + bdrv_get_device_name(bs), message, + fatal ? "true" : "false"); + } + + monitor_protocol_event(QEVENT_BLOCK_IMAGE_CORRUPTED, data); + qobject_decref(data); + + g_free(message); + + if (fatal) { + qcow2_mark_corrupt(bs); + bs->drv = NULL; /* make BDS unusable */ + } + + s->signaled_corruption = true; +} + static QEMUOptionParameter qcow2_create_options[] = { { .name = BLOCK_OPT_SIZE, diff --git a/block/qcow2.h b/block/qcow2.h index e958ab4..2138462 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -252,6 +252,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; @@ -468,6 +469,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); -- 1.8.3.1