qmp: Output error detail when execute QMP command failed

Only get 'QMP command failed' error message now when execute QMP
command by 'executeCommandWithResponse' failed. This patch will
output more error detail.

Signed-off-by: NingBo <ning.bo9@zte.com.cn>
This commit is contained in:
NingBo 2018-11-29 16:20:03 +08:00
parent 99e0358ba9
commit f30fd1354a

View File

@ -313,7 +313,7 @@ func (q *QMP) finaliseCommandWithResponse(cmdEl *list.Element, cmdQueue *list.Li
if succeeded {
cmd.res <- qmpResult{response: response}
} else {
cmd.res <- qmpResult{err: fmt.Errorf("QMP command failed")}
cmd.res <- qmpResult{err: fmt.Errorf("QMP command failed: %v", response)}
}
}
if cmdQueue.Len() > 0 {
@ -325,6 +325,23 @@ func (q *QMP) finaliseCommand(cmdEl *list.Element, cmdQueue *list.List, succeede
q.finaliseCommandWithResponse(cmdEl, cmdQueue, succeeded, nil)
}
func (q *QMP) errorDesc(errorData interface{}) (string, error) {
// convert error to json
data, err := json.Marshal(errorData)
if err != nil {
return "", fmt.Errorf("Unable to extract error information: %v", err)
}
// see: https://github.com/qemu/qemu/blob/stable-2.12/qapi/qmp-dispatch.c#L125
var qmpErr map[string]string
// convert json to qmpError
if err = json.Unmarshal(data, &qmpErr); err != nil {
return "", fmt.Errorf("Unable to convert json to qmpError: %v", err)
}
return qmpErr["desc"], nil
}
func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
var vmData map[string]interface{}
err := json.Unmarshal(line, &vmData)
@ -339,7 +356,7 @@ func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
}
response, succeeded := vmData["return"]
_, failed := vmData["error"]
errData, failed := vmData["error"]
if !succeeded && !failed {
return
@ -353,6 +370,14 @@ func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
}
cmd := cmdEl.Value.(*qmpCommand)
if failed || cmd.filter == nil {
if errData != nil {
desc, err := q.errorDesc(errData)
if err != nil {
q.cfg.Logger.Infof("Get error description failed: %v", err)
} else {
response = desc
}
}
q.finaliseCommandWithResponse(cmdEl, cmdQueue, succeeded, response)
} else {
cmd.resultReceived = true