On Tue, Jul 24, 2012 at 11:03 AM, Paolo Bonzini <[email protected]> wrote:
> Currently it is impossible to write a blkdebug script that ping-pongs
> between two states, because the second set-state rule will use the
> state that is set in the first. If you have
>
> [set-state]
> event = "..."
> state = "1"
> new_state = "2"
>
> [set-state]
> event = "..."
> state = "2"
> new_state = "1"
>
> for example the state will remain locked at 1. This can be fixed
> by first processing all rules, and then setting the state.
>
> Signed-off-by: Paolo Bonzini <[email protected]>
> ---
> block/blkdebug.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/block/blkdebug.c b/block/blkdebug.c
> index 59dcea0..0f12145 100644
> --- a/block/blkdebug.c
> +++ b/block/blkdebug.c
> @@ -28,6 +28,7 @@
>
> typedef struct BDRVBlkdebugState {
> int state;
> + int new_state;
> QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX];
> QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
> } BDRVBlkdebugState;
> @@ -351,6 +352,7 @@ static BlockDriverAIOCB
> *blkdebug_aio_readv(BlockDriverState *bs,
> BDRVBlkdebugState *s = bs->opaque;
> BlkdebugRule *rule = NULL;
>
> + printf("read %ld\n", sector_num);
Leftover debugging?
> QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
> if (rule->options.inject.sector == -1 ||
> (rule->options.inject.sector >= sector_num &&
> @@ -403,12 +405,12 @@ static void blkdebug_close(BlockDriverState *bs)
> }
>
> static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
> - int old_state, bool injected)
> + bool injected)
> {
> BDRVBlkdebugState *s = bs->opaque;
>
> /* Only process rules for the current state */
> - if (rule->state && rule->state != old_state) {
> + if (rule->state && rule->state != s->state) {
> return injected;
> }
>
> @@ -423,7 +425,7 @@ static bool process_rule(BlockDriverState *bs, struct
> BlkdebugRule *rule,
> break;
>
> case ACTION_SET_STATE:
> - s->state = rule->options.set_state.new_state;
> + s->new_state = rule->options.set_state.new_state;
> break;
> }
> return injected;
> @@ -433,15 +435,17 @@ static void blkdebug_debug_event(BlockDriverState *bs,
> BlkDebugEvent event)
> {
> BDRVBlkdebugState *s = bs->opaque;
> struct BlkdebugRule *rule;
> - int old_state = s->state;
> bool injected;
>
> assert((int)event >= 0 && event < BLKDBG_EVENT_MAX);
>
> + printf("state %d\n", s->state);
Here too?
> injected = false;
> + s->new_state = s->state;
> QLIST_FOREACH(rule, &s->rules[event], next) {
> - injected = process_rule(bs, rule, old_state, injected);
> + injected = process_rule(bs, rule, injected);
> }
> + s->state = s->new_state;
> }
>
> static int64_t blkdebug_getlength(BlockDriverState *bs)
> --
> 1.7.10.4
>
>
>