From 845ac4781cad8630bd75de08857b8e81198d3554 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 8 Jul 2024 09:09:08 +0200 Subject: [PATCH] vm/qemu: better handle qmp errors Sometimes qemu just returns an "Error: ..." string in reply instead of returning an error. Handle these cases. Also log all qmp commands in debug mode. --- vm/qemu/qmp.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/vm/qemu/qmp.go b/vm/qemu/qmp.go index e7e3b69e2f83..217158e864c0 100644 --- a/vm/qemu/qmp.go +++ b/vm/qemu/qmp.go @@ -5,8 +5,10 @@ package qemu import ( "encoding/json" + "errors" "fmt" "net" + "strings" "github.com/google/syzkaller/pkg/log" ) @@ -109,15 +111,22 @@ func (inst *instance) qmp(cmd *qmpCommand) (interface{}, error) { return nil, err } if resp.Error.Desc != "" { - return nil, fmt.Errorf("error %v", resp.Error) + return nil, fmt.Errorf("%v", resp.Error) } if resp.Return == nil { return nil, fmt.Errorf(`no "return" nor "error" in [%v]`, resp) } + if output, _ := resp.Return.(string); strings.HasPrefix(output, "Error:") || + strings.HasPrefix(output, "unknown command:") { + return nil, errors.New(output) + } return resp.Return, nil } func (inst *instance) hmp(cmd string, cpu int) (string, error) { + if inst.debug { + log.Logf(0, "qemu: running hmp command: %v", cmd) + } req := &qmpCommand{ Execute: "human-monitor-command", Arguments: &hmpCommand{ @@ -126,8 +135,11 @@ func (inst *instance) hmp(cmd string, cpu int) (string, error) { }, } resp, err := inst.qmp(req) + if inst.debug { + log.Logf(0, "qemu: reply: %v\n%v", err, resp) + } if err != nil { - return "", err + return "", fmt.Errorf("qemu hmp command '%s': %w", cmd, err) } return resp.(string), nil }