qemu: Report error if qemu monitor command not found for BlockJob

* src/qemu/qemu_monitor_json.c: Handle error "CommandNotFound" and
  report the error.

* src/qemu/qemu_monitor_text.c: If a sub info command is not found,
  it prints the output of "help info", for other commands,
  "unknown command" is printed.

Without this patch, libvirt always report:

  An error occurred, but the cause is unknown

This patch was adapted from a patch by Osier Yang <jyang@redhat.com> to
break out detection of unrecognized text monitor commands into a separate
function.

Signed-off-by: Adam Litke <agl@us.ibm.com>
This commit is contained in:
Osier Yang 2011-08-24 14:39:42 +08:00
parent 678cd0f04b
commit 10b100240f
2 changed files with 59 additions and 21 deletions

View File

@ -2909,20 +2909,25 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
int ret = -1; int ret = -1;
virJSONValuePtr cmd = NULL; virJSONValuePtr cmd = NULL;
virJSONValuePtr reply = NULL; virJSONValuePtr reply = NULL;
const char *cmd_name = NULL;
if (mode == BLOCK_JOB_ABORT) if (mode == BLOCK_JOB_ABORT) {
cmd = qemuMonitorJSONMakeCommand("block_job_cancel", cmd_name = "block_job_cancel";
"s:device", device, NULL); cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device, NULL);
else if (mode == BLOCK_JOB_INFO) } else if (mode == BLOCK_JOB_INFO) {
cmd = qemuMonitorJSONMakeCommand("query-block-jobs", NULL); cmd_name = "query-block-jobs";
else if (mode == BLOCK_JOB_SPEED) cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL);
cmd = qemuMonitorJSONMakeCommand("block_job_set_speed", } else if (mode == BLOCK_JOB_SPEED) {
"s:device", device, cmd_name = "block_job_set_speed";
"U:value", bandwidth * 1024ULL * 1024ULL, cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device",
device, "U:value",
bandwidth * 1024ULL * 1024ULL,
NULL); NULL);
else if (mode == BLOCK_JOB_PULL) } else if (mode == BLOCK_JOB_PULL) {
cmd = qemuMonitorJSONMakeCommand("block_stream", cmd_name = "block_stream";
"s:device", device, NULL); cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device",
device, NULL);
}
if (!cmd) if (!cmd)
return -1; return -1;
@ -2939,6 +2944,9 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
else if (qemuMonitorJSONHasError(reply, "NotSupported")) else if (qemuMonitorJSONHasError(reply, "NotSupported"))
qemuReportError(VIR_ERR_OPERATION_INVALID, qemuReportError(VIR_ERR_OPERATION_INVALID,
_("Operation is not supported for device: %s"), device); _("Operation is not supported for device: %s"), device);
else if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
qemuReportError(VIR_ERR_OPERATION_INVALID,
_("Command '%s' is not found"), cmd_name);
else else
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpected error")); _("Unexpected error"));

View File

@ -271,6 +271,23 @@ qemuMonitorTextCommandWithFd(qemuMonitorPtr mon,
scm_fd, reply); scm_fd, reply);
} }
/* Check monitor output for evidence that the command was not recognized.
* For 'info' commands, qemu returns help text. For other commands, qemu
* returns 'unknown command:'.
*/
static int
qemuMonitorTextCommandNotFound(const char *cmd, const char *reply)
{
if (STRPREFIX(cmd, "info ")) {
if (strstr(reply, "info version"))
return 1;
} else {
if (strstr(reply, "unknown command:"))
return 1;
}
return 0;
}
static int static int
qemuMonitorSendDiskPassphrase(qemuMonitorPtr mon, qemuMonitorSendDiskPassphrase(qemuMonitorPtr mon,
@ -3031,18 +3048,24 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
char *cmd = NULL; char *cmd = NULL;
char *reply = NULL; char *reply = NULL;
int ret; int ret;
const char *cmd_name = NULL;
if (mode == BLOCK_JOB_ABORT) if (mode == BLOCK_JOB_ABORT) {
ret = virAsprintf(&cmd, "block_job_cancel %s", device); cmd_name = "block_job_cancel";
else if (mode == BLOCK_JOB_INFO) ret = virAsprintf(&cmd, "%s %s", cmd_name, device);
ret = virAsprintf(&cmd, "info block-jobs"); } else if (mode == BLOCK_JOB_INFO) {
else if (mode == BLOCK_JOB_SPEED) cmd_name = "info block-jobs";
ret = virAsprintf(&cmd, "block_job_set_speed %s %llu", device, ret = virAsprintf(&cmd, "%s", cmd_name);
} else if (mode == BLOCK_JOB_SPEED) {
cmd_name = "block_job_set_speed";
ret = virAsprintf(&cmd, "%s %s %llu", cmd_name, device,
bandwidth * 1024ULL * 1024ULL); bandwidth * 1024ULL * 1024ULL);
else if (mode == BLOCK_JOB_PULL) } else if (mode == BLOCK_JOB_PULL) {
ret = virAsprintf(&cmd, "block_stream %s", device); cmd_name = "block_stream";
else ret = virAsprintf(&cmd, "%s %s", cmd_name, device);
} else {
return -1; return -1;
}
if (ret < 0) { if (ret < 0) {
virReportOOMError(); virReportOOMError();
@ -3056,6 +3079,13 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
goto cleanup; goto cleanup;
} }
if (qemuMonitorTextCommandNotFound(cmd_name, reply)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
_("Command '%s' is not found"), cmd_name);
ret = -1;
goto cleanup;
}
ret = qemuMonitorTextParseBlockJob(reply, device, info); ret = qemuMonitorTextParseBlockJob(reply, device, info);
cleanup: cleanup: