blkdebug: add "remove_break" command
This adds "remove_break" command which is the reverse of blkdebug command "break": it removes all breakpoints with given tag and resumes all the requests. Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
							parent
							
								
									5b43dbb699
								
							
						
					
					
						commit
						4cc70e9337
					
				
							
								
								
									
										13
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								block.c
									
									
									
									
									
								
							| @ -3525,6 +3525,19 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, | ||||
|     return -ENOTSUP; | ||||
| } | ||||
| 
 | ||||
| int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag) | ||||
| { | ||||
|     while (bs && bs->drv && !bs->drv->bdrv_debug_remove_breakpoint) { | ||||
|         bs = bs->file; | ||||
|     } | ||||
| 
 | ||||
|     if (bs && bs->drv && bs->drv->bdrv_debug_remove_breakpoint) { | ||||
|         return bs->drv->bdrv_debug_remove_breakpoint(bs, tag); | ||||
|     } | ||||
| 
 | ||||
|     return -ENOTSUP; | ||||
| } | ||||
| 
 | ||||
| int bdrv_debug_resume(BlockDriverState *bs, const char *tag) | ||||
| { | ||||
|     while (bs && bs->drv && !bs->drv->bdrv_debug_resume) { | ||||
|  | ||||
| @ -605,6 +605,31 @@ static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag) | ||||
|     return -ENOENT; | ||||
| } | ||||
| 
 | ||||
| static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs, | ||||
|                                             const char *tag) | ||||
| { | ||||
|     BDRVBlkdebugState *s = bs->opaque; | ||||
|     BlkdebugSuspendedReq *r; | ||||
|     BlkdebugRule *rule, *next; | ||||
|     int i, ret = -ENOENT; | ||||
| 
 | ||||
|     for (i = 0; i < BLKDBG_EVENT_MAX; i++) { | ||||
|         QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { | ||||
|             if (rule->action == ACTION_SUSPEND && | ||||
|                 !strcmp(rule->options.suspend.tag, tag)) { | ||||
|                 remove_rule(rule); | ||||
|                 ret = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     QLIST_FOREACH(r, &s->suspended_reqs, next) { | ||||
|         if (!strcmp(r->tag, tag)) { | ||||
|             qemu_coroutine_enter(r->co, NULL); | ||||
|             ret = 0; | ||||
|         } | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag) | ||||
| { | ||||
| @ -639,6 +664,8 @@ static BlockDriver bdrv_blkdebug = { | ||||
| 
 | ||||
|     .bdrv_debug_event           = blkdebug_debug_event, | ||||
|     .bdrv_debug_breakpoint      = blkdebug_debug_breakpoint, | ||||
|     .bdrv_debug_remove_breakpoint | ||||
|                                 = blkdebug_debug_remove_breakpoint, | ||||
|     .bdrv_debug_resume          = blkdebug_debug_resume, | ||||
|     .bdrv_debug_is_suspended    = blkdebug_debug_is_suspended, | ||||
| }; | ||||
|  | ||||
| @ -519,6 +519,7 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event); | ||||
| 
 | ||||
| int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, | ||||
|                            const char *tag); | ||||
| int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag); | ||||
| int bdrv_debug_resume(BlockDriverState *bs, const char *tag); | ||||
| bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); | ||||
| 
 | ||||
|  | ||||
| @ -219,6 +219,8 @@ struct BlockDriver { | ||||
|     /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */ | ||||
|     int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event, | ||||
|         const char *tag); | ||||
|     int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs, | ||||
|         const char *tag); | ||||
|     int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag); | ||||
|     bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag); | ||||
| 
 | ||||
|  | ||||
| @ -1956,6 +1956,18 @@ static int break_f(BlockDriverState *bs, int argc, char **argv) | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int remove_break_f(BlockDriverState *bs, int argc, char **argv) | ||||
| { | ||||
|     int ret; | ||||
| 
 | ||||
|     ret = bdrv_debug_remove_breakpoint(bs, argv[1]); | ||||
|     if (ret < 0) { | ||||
|         printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret)); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static const cmdinfo_t break_cmd = { | ||||
|        .name           = "break", | ||||
|        .argmin         = 2, | ||||
| @ -1966,6 +1978,15 @@ static const cmdinfo_t break_cmd = { | ||||
|                          "request as tag", | ||||
| }; | ||||
| 
 | ||||
| static const cmdinfo_t remove_break_cmd = { | ||||
|        .name           = "remove_break", | ||||
|        .argmin         = 1, | ||||
|        .argmax         = 1, | ||||
|        .cfunc          = remove_break_f, | ||||
|        .args           = "tag", | ||||
|        .oneline        = "remove a breakpoint by tag", | ||||
| }; | ||||
| 
 | ||||
| static int resume_f(BlockDriverState *bs, int argc, char **argv) | ||||
| { | ||||
|     int ret; | ||||
| @ -2126,6 +2147,7 @@ static void __attribute((constructor)) init_qemuio_commands(void) | ||||
|     qemuio_add_command(&alloc_cmd); | ||||
|     qemuio_add_command(&map_cmd); | ||||
|     qemuio_add_command(&break_cmd); | ||||
|     qemuio_add_command(&remove_break_cmd); | ||||
|     qemuio_add_command(&resume_cmd); | ||||
|     qemuio_add_command(&wait_break_cmd); | ||||
|     qemuio_add_command(&abort_cmd); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Fam Zheng
						Fam Zheng