• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修訂16789db3de64147c7271d30a9d379b2a8aa2b81e (tree)
時間2019-06-14 21:16:57
作者Max Reitz <mreitz@redh...>
CommiterMax Reitz

Log Message

blkdebug: Add @iotype error option

This new error option allows users of blkdebug to inject errors only on
certain kinds of I/O operations. Users usually want to make a very
specific operation fail, not just any; but right now they simply hope
that the event that triggers the error injection is followed up with
that very operation. That may not be true, however, because the block
layer is changing (including blkdebug, which may increase the number of
types of I/O operations on which to inject errors).

The new option's default has been chosen to keep backwards
compatibility.

Note that similar to the internal representation, we could choose to
expose this option as a list of I/O types. But there is no practical
use for this, because as described above, users usually know exactly
which kind of operation they want to make fail, so there is no need to
specify multiple I/O types at once. In addition, exposing this option
as a list would require non-trivial changes to qemu_opts_absorb_qdict().

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190507203508.18026-4-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>

Change Summary

差異

--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -75,6 +75,7 @@ typedef struct BlkdebugRule {
7575 int state;
7676 union {
7777 struct {
78+ uint64_t iotype_mask;
7879 int error;
7980 int immediately;
8081 int once;
@@ -91,6 +92,9 @@ typedef struct BlkdebugRule {
9192 QSIMPLEQ_ENTRY(BlkdebugRule) active_next;
9293 } BlkdebugRule;
9394
95+QEMU_BUILD_BUG_MSG(BLKDEBUG_IO_TYPE__MAX > 64,
96+ "BlkdebugIOType mask does not fit into an uint64_t");
97+
9498 static QemuOptsList inject_error_opts = {
9599 .name = "inject-error",
96100 .head = QTAILQ_HEAD_INITIALIZER(inject_error_opts.head),
@@ -104,6 +108,10 @@ static QemuOptsList inject_error_opts = {
104108 .type = QEMU_OPT_NUMBER,
105109 },
106110 {
111+ .name = "iotype",
112+ .type = QEMU_OPT_STRING,
113+ },
114+ {
107115 .name = "errno",
108116 .type = QEMU_OPT_NUMBER,
109117 },
@@ -162,6 +170,8 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
162170 int event;
163171 struct BlkdebugRule *rule;
164172 int64_t sector;
173+ BlkdebugIOType iotype;
174+ Error *local_error = NULL;
165175
166176 /* Find the right event for the rule */
167177 event_name = qemu_opt_get(opts, "event");
@@ -192,6 +202,26 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
192202 sector = qemu_opt_get_number(opts, "sector", -1);
193203 rule->options.inject.offset =
194204 sector == -1 ? -1 : sector * BDRV_SECTOR_SIZE;
205+
206+ iotype = qapi_enum_parse(&BlkdebugIOType_lookup,
207+ qemu_opt_get(opts, "iotype"),
208+ BLKDEBUG_IO_TYPE__MAX, &local_error);
209+ if (local_error) {
210+ error_propagate(errp, local_error);
211+ return -1;
212+ }
213+ if (iotype != BLKDEBUG_IO_TYPE__MAX) {
214+ rule->options.inject.iotype_mask = (1ull << iotype);
215+ } else {
216+ /* Apply the default */
217+ rule->options.inject.iotype_mask =
218+ (1ull << BLKDEBUG_IO_TYPE_READ)
219+ | (1ull << BLKDEBUG_IO_TYPE_WRITE)
220+ | (1ull << BLKDEBUG_IO_TYPE_WRITE_ZEROES)
221+ | (1ull << BLKDEBUG_IO_TYPE_DISCARD)
222+ | (1ull << BLKDEBUG_IO_TYPE_FLUSH);
223+ }
224+
195225 break;
196226
197227 case ACTION_SET_STATE:
@@ -470,7 +500,8 @@ out:
470500 return ret;
471501 }
472502
473-static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes)
503+static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
504+ BlkdebugIOType iotype)
474505 {
475506 BDRVBlkdebugState *s = bs->opaque;
476507 BlkdebugRule *rule = NULL;
@@ -480,9 +511,10 @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes)
480511 QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
481512 uint64_t inject_offset = rule->options.inject.offset;
482513
483- if (inject_offset == -1 ||
484- (bytes && inject_offset >= offset &&
485- inject_offset < offset + bytes))
514+ if ((inject_offset == -1 ||
515+ (bytes && inject_offset >= offset &&
516+ inject_offset < offset + bytes)) &&
517+ (rule->options.inject.iotype_mask & (1ull << iotype)))
486518 {
487519 break;
488520 }
@@ -521,7 +553,7 @@ blkdebug_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
521553 assert(bytes <= bs->bl.max_transfer);
522554 }
523555
524- err = rule_check(bs, offset, bytes);
556+ err = rule_check(bs, offset, bytes, BLKDEBUG_IO_TYPE_READ);
525557 if (err) {
526558 return err;
527559 }
@@ -542,7 +574,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
542574 assert(bytes <= bs->bl.max_transfer);
543575 }
544576
545- err = rule_check(bs, offset, bytes);
577+ err = rule_check(bs, offset, bytes, BLKDEBUG_IO_TYPE_WRITE);
546578 if (err) {
547579 return err;
548580 }
@@ -552,7 +584,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
552584
553585 static int blkdebug_co_flush(BlockDriverState *bs)
554586 {
555- int err = rule_check(bs, 0, 0);
587+ int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
556588
557589 if (err) {
558590 return err;
@@ -586,7 +618,7 @@ static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
586618 assert(bytes <= bs->bl.max_pwrite_zeroes);
587619 }
588620
589- err = rule_check(bs, offset, bytes);
621+ err = rule_check(bs, offset, bytes, BLKDEBUG_IO_TYPE_WRITE_ZEROES);
590622 if (err) {
591623 return err;
592624 }
@@ -620,7 +652,7 @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
620652 assert(bytes <= bs->bl.max_pdiscard);
621653 }
622654
623- err = rule_check(bs, offset, bytes);
655+ err = rule_check(bs, offset, bytes, BLKDEBUG_IO_TYPE_DISCARD);
624656 if (err) {
625657 return err;
626658 }
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3265,6 +3265,26 @@
32653265 'cor_write', 'cluster_alloc_space'] }
32663266
32673267 ##
3268+# @BlkdebugIOType:
3269+#
3270+# Kinds of I/O that blkdebug can inject errors in.
3271+#
3272+# @read: .bdrv_co_preadv()
3273+#
3274+# @write: .bdrv_co_pwritev()
3275+#
3276+# @write-zeroes: .bdrv_co_pwrite_zeroes()
3277+#
3278+# @discard: .bdrv_co_pdiscard()
3279+#
3280+# @flush: .bdrv_co_flush_to_disk()
3281+#
3282+# Since: 4.1
3283+##
3284+{ 'enum': 'BlkdebugIOType', 'prefix': 'BLKDEBUG_IO_TYPE',
3285+ 'data': [ 'read', 'write', 'write-zeroes', 'discard', 'flush' ] }
3286+
3287+##
32683288 # @BlkdebugInjectErrorOptions:
32693289 #
32703290 # Describes a single error injection for blkdebug.
@@ -3274,6 +3294,11 @@
32743294 # @state: the state identifier blkdebug needs to be in to
32753295 # actually trigger the event; defaults to "any"
32763296 #
3297+# @iotype: the type of I/O operations on which this error should
3298+# be injected; defaults to "all read, write,
3299+# write-zeroes, discard, and flush operations"
3300+# (since: 4.1)
3301+#
32773302 # @errno: error identifier (errno) to be returned; defaults to
32783303 # EIO
32793304 #
@@ -3291,6 +3316,7 @@
32913316 { 'struct': 'BlkdebugInjectErrorOptions',
32923317 'data': { 'event': 'BlkdebugEvent',
32933318 '*state': 'int',
3319+ '*iotype': 'BlkdebugIOType',
32943320 '*errno': 'int',
32953321 '*sector': 'int',
32963322 '*once': 'bool',