qemu-io: Add AIO debugging commands
This makes the blkdebug suspend/resume functionality available in qemu-io. Use it like this: $ ./qemu-io blkdebug::/tmp/test.qcow2 qemu-io> break write_aio req_a qemu-io> aio_write 0 4k qemu-io> blkdebug: Suspended request 'req_a' qemu-io> resume req_a blkdebug: Resuming request 'req_a' qemu-io> wrote 4096/4096 bytes at offset 0 4 KiB, 1 ops; 0:00:30.71 (133.359788 bytes/sec and 0.0326 ops/sec) Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									3c90c65d7a
								
							
						
					
					
						commit
						41c695c749
					
				
							
								
								
									
										39
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								block.c
									
									
									
									
									
								
							| @ -3045,7 +3045,46 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) | ||||
|     } | ||||
| 
 | ||||
|     drv->bdrv_debug_event(bs, event); | ||||
| } | ||||
| 
 | ||||
| int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, | ||||
|                           const char *tag) | ||||
| { | ||||
|     while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) { | ||||
|         bs = bs->file; | ||||
|     } | ||||
| 
 | ||||
|     if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) { | ||||
|         return bs->drv->bdrv_debug_breakpoint(bs, event, tag); | ||||
|     } | ||||
| 
 | ||||
|     return -ENOTSUP; | ||||
| } | ||||
| 
 | ||||
| int bdrv_debug_resume(BlockDriverState *bs, const char *tag) | ||||
| { | ||||
|     while (bs && bs->drv && !bs->drv->bdrv_debug_resume) { | ||||
|         bs = bs->file; | ||||
|     } | ||||
| 
 | ||||
|     if (bs && bs->drv && bs->drv->bdrv_debug_resume) { | ||||
|         return bs->drv->bdrv_debug_resume(bs, tag); | ||||
|     } | ||||
| 
 | ||||
|     return -ENOTSUP; | ||||
| } | ||||
| 
 | ||||
| bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag) | ||||
| { | ||||
|     while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) { | ||||
|         bs = bs->file; | ||||
|     } | ||||
| 
 | ||||
|     if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) { | ||||
|         return bs->drv->bdrv_debug_is_suspended(bs, tag); | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| /**************************************************************/ | ||||
|  | ||||
							
								
								
									
										5
									
								
								block.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								block.h
									
									
									
									
									
								
							| @ -431,4 +431,9 @@ typedef enum { | ||||
| #define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt) | ||||
| void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event); | ||||
| 
 | ||||
| int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, | ||||
|                            const char *tag); | ||||
| int bdrv_debug_resume(BlockDriverState *bs, const char *tag); | ||||
| bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag); | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -190,6 +190,12 @@ struct BlockDriver { | ||||
| 
 | ||||
|     void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event); | ||||
| 
 | ||||
|     /* 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_resume)(BlockDriverState *bs, const char *tag); | ||||
|     bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag); | ||||
| 
 | ||||
|     /*
 | ||||
|      * Returns 1 if newly created images are guaranteed to contain only | ||||
|      * zeros, 0 otherwise. | ||||
|  | ||||
							
								
								
									
										64
									
								
								qemu-io.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								qemu-io.c
									
									
									
									
									
								
							| @ -1671,6 +1671,67 @@ static const cmdinfo_t map_cmd = { | ||||
|        .oneline        = "prints the allocated areas of a file", | ||||
| }; | ||||
| 
 | ||||
| static int break_f(int argc, char **argv) | ||||
| { | ||||
|     int ret; | ||||
| 
 | ||||
|     ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]); | ||||
|     if (ret < 0) { | ||||
|         printf("Could not set breakpoint: %s\n", strerror(-ret)); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static const cmdinfo_t break_cmd = { | ||||
|        .name           = "break", | ||||
|        .argmin         = 2, | ||||
|        .argmax         = 2, | ||||
|        .cfunc          = break_f, | ||||
|        .args           = "event tag", | ||||
|        .oneline        = "sets a breakpoint on event and tags the stopped " | ||||
|                          "request as tag", | ||||
| }; | ||||
| 
 | ||||
| static int resume_f(int argc, char **argv) | ||||
| { | ||||
|     int ret; | ||||
| 
 | ||||
|     ret = bdrv_debug_resume(bs, argv[1]); | ||||
|     if (ret < 0) { | ||||
|         printf("Could not resume request: %s\n", strerror(-ret)); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static const cmdinfo_t resume_cmd = { | ||||
|        .name           = "resume", | ||||
|        .argmin         = 1, | ||||
|        .argmax         = 1, | ||||
|        .cfunc          = resume_f, | ||||
|        .args           = "tag", | ||||
|        .oneline        = "resumes the request tagged as tag", | ||||
| }; | ||||
| 
 | ||||
| static int wait_break_f(int argc, char **argv) | ||||
| { | ||||
|     while (!bdrv_debug_is_suspended(bs, argv[1])) { | ||||
|         qemu_aio_wait(); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static const cmdinfo_t wait_break_cmd = { | ||||
|        .name           = "wait_break", | ||||
|        .argmin         = 1, | ||||
|        .argmax         = 1, | ||||
|        .cfunc          = wait_break_f, | ||||
|        .args           = "tag", | ||||
|        .oneline        = "waits for the suspension of a request", | ||||
| }; | ||||
| 
 | ||||
| static int abort_f(int argc, char **argv) | ||||
| { | ||||
|     abort(); | ||||
| @ -1934,6 +1995,9 @@ int main(int argc, char **argv) | ||||
|     add_command(&discard_cmd); | ||||
|     add_command(&alloc_cmd); | ||||
|     add_command(&map_cmd); | ||||
|     add_command(&break_cmd); | ||||
|     add_command(&resume_cmd); | ||||
|     add_command(&wait_break_cmd); | ||||
|     add_command(&abort_cmd); | ||||
| 
 | ||||
|     add_args_command(init_args_command); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Kevin Wolf
						Kevin Wolf