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;
virJSONValuePtr cmd = NULL;
virJSONValuePtr reply = NULL;
const char *cmd_name = NULL;
if (mode == BLOCK_JOB_ABORT)
cmd = qemuMonitorJSONMakeCommand("block_job_cancel",
"s:device", device, NULL);
else if (mode == BLOCK_JOB_INFO)
cmd = qemuMonitorJSONMakeCommand("query-block-jobs", NULL);
else if (mode == BLOCK_JOB_SPEED)
cmd = qemuMonitorJSONMakeCommand("block_job_set_speed",
"s:device", device,
"U:value", bandwidth * 1024ULL * 1024ULL,
if (mode == BLOCK_JOB_ABORT) {
cmd_name = "block_job_cancel";
cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device, NULL);
} else if (mode == BLOCK_JOB_INFO) {
cmd_name = "query-block-jobs";
cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL);
} else if (mode == BLOCK_JOB_SPEED) {
cmd_name = "block_job_set_speed";
cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device",
device, "U:value",
bandwidth * 1024ULL * 1024ULL,
NULL);
else if (mode == BLOCK_JOB_PULL)
cmd = qemuMonitorJSONMakeCommand("block_stream",
"s:device", device, NULL);
} else if (mode == BLOCK_JOB_PULL) {
cmd_name = "block_stream";
cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device",
device, NULL);
}
if (!cmd)
return -1;
@ -2939,6 +2944,9 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
else if (qemuMonitorJSONHasError(reply, "NotSupported"))
qemuReportError(VIR_ERR_OPERATION_INVALID,
_("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
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpected error"));

View File

@ -271,6 +271,23 @@ qemuMonitorTextCommandWithFd(qemuMonitorPtr mon,
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
qemuMonitorSendDiskPassphrase(qemuMonitorPtr mon,
@ -3031,18 +3048,24 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
char *cmd = NULL;
char *reply = NULL;
int ret;
const char *cmd_name = NULL;
if (mode == BLOCK_JOB_ABORT)
ret = virAsprintf(&cmd, "block_job_cancel %s", device);
else if (mode == BLOCK_JOB_INFO)
ret = virAsprintf(&cmd, "info block-jobs");
else if (mode == BLOCK_JOB_SPEED)
ret = virAsprintf(&cmd, "block_job_set_speed %s %llu", device,
if (mode == BLOCK_JOB_ABORT) {
cmd_name = "block_job_cancel";
ret = virAsprintf(&cmd, "%s %s", cmd_name, device);
} else if (mode == BLOCK_JOB_INFO) {
cmd_name = "info block-jobs";
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);
else if (mode == BLOCK_JOB_PULL)
ret = virAsprintf(&cmd, "block_stream %s", device);
else
} else if (mode == BLOCK_JOB_PULL) {
cmd_name = "block_stream";
ret = virAsprintf(&cmd, "%s %s", cmd_name, device);
} else {
return -1;
}
if (ret < 0) {
virReportOOMError();
@ -3056,6 +3079,13 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
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);
cleanup: