mirror of https://github.com/xqemu/xqemu.git
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;
|
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)
|
int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
|
||||||
{
|
{
|
||||||
while (bs && bs->drv && !bs->drv->bdrv_debug_resume) {
|
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;
|
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)
|
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_event = blkdebug_debug_event,
|
||||||
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
|
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
|
||||||
|
.bdrv_debug_remove_breakpoint
|
||||||
|
= blkdebug_debug_remove_breakpoint,
|
||||||
.bdrv_debug_resume = blkdebug_debug_resume,
|
.bdrv_debug_resume = blkdebug_debug_resume,
|
||||||
.bdrv_debug_is_suspended = blkdebug_debug_is_suspended,
|
.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,
|
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||||
const char *tag);
|
const char *tag);
|
||||||
|
int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
|
||||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
|
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
|
||||||
bool bdrv_debug_is_suspended(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? */
|
/* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
|
||||||
int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
|
int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
|
||||||
const char *tag);
|
const char *tag);
|
||||||
|
int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs,
|
||||||
|
const char *tag);
|
||||||
int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
|
int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
|
||||||
bool (*bdrv_debug_is_suspended)(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;
|
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 = {
|
static const cmdinfo_t break_cmd = {
|
||||||
.name = "break",
|
.name = "break",
|
||||||
.argmin = 2,
|
.argmin = 2,
|
||||||
|
@ -1966,6 +1978,15 @@ static const cmdinfo_t break_cmd = {
|
||||||
"request as tag",
|
"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)
|
static int resume_f(BlockDriverState *bs, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2126,6 +2147,7 @@ static void __attribute((constructor)) init_qemuio_commands(void)
|
||||||
qemuio_add_command(&alloc_cmd);
|
qemuio_add_command(&alloc_cmd);
|
||||||
qemuio_add_command(&map_cmd);
|
qemuio_add_command(&map_cmd);
|
||||||
qemuio_add_command(&break_cmd);
|
qemuio_add_command(&break_cmd);
|
||||||
|
qemuio_add_command(&remove_break_cmd);
|
||||||
qemuio_add_command(&resume_cmd);
|
qemuio_add_command(&resume_cmd);
|
||||||
qemuio_add_command(&wait_break_cmd);
|
qemuio_add_command(&wait_break_cmd);
|
||||||
qemuio_add_command(&abort_cmd);
|
qemuio_add_command(&abort_cmd);
|
||||||
|
|
Loading…
Reference in New Issue