mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 11:06:21 +00:00
qemu: Add functions to process QMP response
Some QMP commands like ```query-hotpluggable-cpus``` returns a response that needs to be processed and returned to the client as a struct. This patch adds the function ```executeCommandWithResponse``` that returns the response of a QMP command. Signed-off-by: Julio Montes <julio.montes@intel.com>
This commit is contained in:
parent
e39da6ca47
commit
24b14059b3
30
qmp.go
30
qmp.go
@ -107,7 +107,8 @@ type QMPEvent struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type qmpResult struct {
|
type qmpResult struct {
|
||||||
err error
|
response interface{}
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
type qmpCommand struct {
|
type qmpCommand struct {
|
||||||
@ -203,14 +204,14 @@ func (q *QMP) processQMPEvent(cmdQueue *list.List, name interface{}, data interf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *QMP) finaliseCommand(cmdEl *list.Element, cmdQueue *list.List, succeeded bool) {
|
func (q *QMP) finaliseCommandWithResponse(cmdEl *list.Element, cmdQueue *list.List, succeeded bool, response interface{}) {
|
||||||
cmd := cmdEl.Value.(*qmpCommand)
|
cmd := cmdEl.Value.(*qmpCommand)
|
||||||
cmdQueue.Remove(cmdEl)
|
cmdQueue.Remove(cmdEl)
|
||||||
select {
|
select {
|
||||||
case <-cmd.ctx.Done():
|
case <-cmd.ctx.Done():
|
||||||
default:
|
default:
|
||||||
if succeeded {
|
if succeeded {
|
||||||
cmd.res <- qmpResult{}
|
cmd.res <- qmpResult{response: response}
|
||||||
} else {
|
} else {
|
||||||
cmd.res <- qmpResult{err: fmt.Errorf("QMP command failed")}
|
cmd.res <- qmpResult{err: fmt.Errorf("QMP command failed")}
|
||||||
}
|
}
|
||||||
@ -220,6 +221,10 @@ func (q *QMP) finaliseCommand(cmdEl *list.Element, cmdQueue *list.List, succeede
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *QMP) finaliseCommand(cmdEl *list.Element, cmdQueue *list.List, succeeded bool) {
|
||||||
|
q.finaliseCommandWithResponse(cmdEl, cmdQueue, succeeded, nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
|
func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
|
||||||
var vmData map[string]interface{}
|
var vmData map[string]interface{}
|
||||||
err := json.Unmarshal(line, &vmData)
|
err := json.Unmarshal(line, &vmData)
|
||||||
@ -233,7 +238,7 @@ func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, succeeded := vmData["return"]
|
response, succeeded := vmData["return"]
|
||||||
_, failed := vmData["error"]
|
_, failed := vmData["error"]
|
||||||
|
|
||||||
if !succeeded && !failed {
|
if !succeeded && !failed {
|
||||||
@ -248,7 +253,7 @@ func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
|
|||||||
}
|
}
|
||||||
cmd := cmdEl.Value.(*qmpCommand)
|
cmd := cmdEl.Value.(*qmpCommand)
|
||||||
if failed || cmd.filter == nil {
|
if failed || cmd.filter == nil {
|
||||||
q.finaliseCommand(cmdEl, cmdQueue, succeeded)
|
q.finaliseCommandWithResponse(cmdEl, cmdQueue, succeeded, response)
|
||||||
} else {
|
} else {
|
||||||
cmd.resultReceived = true
|
cmd.resultReceived = true
|
||||||
}
|
}
|
||||||
@ -463,9 +468,10 @@ func startQMPLoop(conn io.ReadWriteCloser, cfg QMPConfig,
|
|||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *QMP) executeCommand(ctx context.Context, name string, args map[string]interface{},
|
func (q *QMP) executeCommandWithResponse(ctx context.Context, name string, args map[string]interface{},
|
||||||
filter *qmpEventFilter) error {
|
filter *qmpEventFilter) (interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
|
var response interface{}
|
||||||
resCh := make(chan qmpResult)
|
resCh := make(chan qmpResult)
|
||||||
select {
|
select {
|
||||||
case <-q.disconnectedCh:
|
case <-q.disconnectedCh:
|
||||||
@ -480,16 +486,24 @@ func (q *QMP) executeCommand(ctx context.Context, name string, args map[string]i
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case res := <-resCh:
|
case res := <-resCh:
|
||||||
err = res.err
|
err = res.err
|
||||||
|
response = res.response
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
err = ctx.Err()
|
err = ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QMP) executeCommand(ctx context.Context, name string, args map[string]interface{},
|
||||||
|
filter *qmpEventFilter) error {
|
||||||
|
|
||||||
|
_, err := q.executeCommandWithResponse(ctx, name, args, filter)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user