Patchwork [15/47] blkdebug: process all set_state rules in the old state

login
register
mail settings
Submitter Paolo Bonzini
Date July 24, 2012, 11:03 a.m.
Message ID <1343127865-16608-16-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/172842/
State New
Headers show

Comments

Paolo Bonzini - July 24, 2012, 11:03 a.m.
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 <pbonzini@redhat.com>
---
 block/blkdebug.c |   14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
Blue Swirl - July 24, 2012, 8:06 p.m.
On Tue, Jul 24, 2012 at 11:03 AM, Paolo Bonzini <pbonzini@redhat.com> 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 <pbonzini@redhat.com>
> ---
>  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
>
>
>

Patch

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);
     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);
     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)