diff --git a/qemu/qmp.go b/qemu/qmp.go index 186f3fadd1..473ce4afaa 100644 --- a/qemu/qmp.go +++ b/qemu/qmp.go @@ -251,6 +251,13 @@ type SchemaInfo struct { Name string `json:"name"` } +// StatusInfo represents guest running status +type StatusInfo struct { + Running bool `json:"running"` + SingleStep bool `json:"singlestep"` + Status string `json:"status"` +} + func (q *QMP) readLoop(fromVMCh chan<- []byte) { scanner := bufio.NewScanner(q.conn) if q.cfg.MaxCapacity > 0 { @@ -1545,3 +1552,23 @@ func (q *QMP) ExecQueryQmpSchema(ctx context.Context) ([]SchemaInfo, error) { return schemaInfo, nil } + +// ExecuteQueryStatus queries guest status +func (q *QMP) ExecuteQueryStatus(ctx context.Context) (StatusInfo, error) { + response, err := q.executeCommandWithResponse(ctx, "query-status", nil, nil, nil) + if err != nil { + return StatusInfo{}, err + } + + data, err := json.Marshal(response) + if err != nil { + return StatusInfo{}, fmt.Errorf("unable to extract migrate status information: %v", err) + } + + var status StatusInfo + if err = json.Unmarshal(data, &status); err != nil { + return StatusInfo{}, fmt.Errorf("unable to convert migrate status information: %v", err) + } + + return status, nil +} diff --git a/qemu/qmp_test.go b/qemu/qmp_test.go index 067665371f..bfad9d0dd6 100644 --- a/qemu/qmp_test.go +++ b/qemu/qmp_test.go @@ -1623,3 +1623,30 @@ func TestQMPExecQueryQmpSchema(t *testing.T) { q.Shutdown() <-disconnectedCh } + +func TestQMPExecQueryQmpStatus(t *testing.T) { + connectedCh := make(chan *QMPVersion) + disconnectedCh := make(chan struct{}) + buf := newQMPTestCommandBuffer(t) + statusInfo := StatusInfo{ + Running: true, + SingleStep: false, + Status: "running", + } + buf.AddCommand("query-status", nil, "return", statusInfo) + cfg := QMPConfig{ + Logger: qmpTestLogger{}, + MaxCapacity: 1024, + } + q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) + checkVersion(t, connectedCh) + info, err := q.ExecuteQueryStatus(context.Background()) + if err != nil { + t.Fatalf("Unexpected error: %v\n", err) + } + if reflect.DeepEqual(info, statusInfo) == false { + t.Fatalf("Expected %v equals to %v\n", info, statusInfo) + } + q.Shutdown() + <-disconnectedCh +}