提交 e17e3ed6 编写于 作者: J Jiri Denemark

qemu: Implement virDomainGetDiskErrors

上级 342fc56f
...@@ -175,6 +175,7 @@ struct qemuDomainDiskInfo { ...@@ -175,6 +175,7 @@ struct qemuDomainDiskInfo {
bool removable; bool removable;
bool locked; bool locked;
bool tray_open; bool tray_open;
int io_status;
}; };
#endif /* __QEMUD_CONF_H */ #endif /* __QEMUD_CONF_H */
...@@ -11728,6 +11728,91 @@ cleanup: ...@@ -11728,6 +11728,91 @@ cleanup:
return ret; return ret;
} }
static int
qemuDomainGetDiskErrors(virDomainPtr dom,
virDomainDiskErrorPtr errors,
unsigned int nerrors,
unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm = NULL;
qemuDomainObjPrivatePtr priv;
char uuidstr[VIR_UUID_STRING_BUFLEN];
virHashTablePtr table = NULL;
int ret = -1;
int i;
int n = 0;
virCheckFlags(0, -1);
qemuDriverLock(driver);
virUUIDFormat(dom->uuid, uuidstr);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
if (!vm) {
qemuReportError(VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
priv = vm->privateData;
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
}
if (!errors) {
ret = vm->def->ndisks;
goto endjob;
}
qemuDomainObjEnterMonitor(driver, vm);
table = qemuMonitorGetBlockInfo(priv->mon);
qemuDomainObjExitMonitor(driver, vm);
if (!table)
goto endjob;
for (i = n = 0; i < vm->def->ndisks; i++) {
struct qemuDomainDiskInfo *info;
virDomainDiskDefPtr disk = vm->def->disks[i];
if ((info = virHashLookup(table, disk->info.alias)) &&
info->io_status != VIR_DOMAIN_DISK_ERROR_NONE) {
if (n == nerrors)
break;
if (!(errors[n].disk = strdup(disk->dst))) {
virReportOOMError();
goto endjob;
}
errors[n].error = info->io_status;
n++;
}
}
ret = n;
endjob:
if (qemuDomainObjEndJob(driver, vm) == 0)
vm = NULL;
cleanup:
if (vm)
virDomainObjUnlock(vm);
virHashFree(table);
if (ret < 0) {
for (i = 0; i < n; i++)
VIR_FREE(errors[i].disk);
}
return ret;
}
static virDriver qemuDriver = { static virDriver qemuDriver = {
.no = VIR_DRV_QEMU, .no = VIR_DRV_QEMU,
.name = "QEMU", .name = "QEMU",
...@@ -11881,6 +11966,7 @@ static virDriver qemuDriver = { ...@@ -11881,6 +11966,7 @@ static virDriver qemuDriver = {
.domainGetNumaParameters = qemuDomainGetNumaParameters, /* 0.9.9 */ .domainGetNumaParameters = qemuDomainGetNumaParameters, /* 0.9.9 */
.domainGetInterfaceParameters = qemuDomainGetInterfaceParameters, /* 0.9.9 */ .domainGetInterfaceParameters = qemuDomainGetInterfaceParameters, /* 0.9.9 */
.domainSetInterfaceParameters = qemuDomainSetInterfaceParameters, /* 0.9.9 */ .domainSetInterfaceParameters = qemuDomainSetInterfaceParameters, /* 0.9.9 */
.domainGetDiskErrors = qemuDomainGetDiskErrors, /* 0.9.10 */
}; };
......
...@@ -87,6 +87,20 @@ VIR_ENUM_IMPL(qemuMonitorVMStatus, ...@@ -87,6 +87,20 @@ VIR_ENUM_IMPL(qemuMonitorVMStatus,
"postmigrate", "prelaunch", "finish-migrate", "restore-vm", "postmigrate", "prelaunch", "finish-migrate", "restore-vm",
"running", "save-vm", "shutdown", "watchdog") "running", "save-vm", "shutdown", "watchdog")
typedef enum {
QEMU_MONITOR_BLOCK_IO_STATUS_OK,
QEMU_MONITOR_BLOCK_IO_STATUS_FAILED,
QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE,
QEMU_MONITOR_BLOCK_IO_STATUS_LAST
} qemuMonitorBlockIOStatus;
VIR_ENUM_DECL(qemuMonitorBlockIOStatus)
VIR_ENUM_IMPL(qemuMonitorBlockIOStatus,
QEMU_MONITOR_BLOCK_IO_STATUS_LAST,
"ok", "failed", "nospace")
char *qemuMonitorEscapeArg(const char *in) char *qemuMonitorEscapeArg(const char *in)
{ {
int len = 0; int len = 0;
...@@ -1227,6 +1241,32 @@ int qemuMonitorGetMemoryStats(qemuMonitorPtr mon, ...@@ -1227,6 +1241,32 @@ int qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
return ret; return ret;
} }
int
qemuMonitorBlockIOStatusToError(const char *status)
{
int st = qemuMonitorBlockIOStatusTypeFromString(status);
if (st < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown block IO status: %s"), status);
return -1;
}
switch ((qemuMonitorBlockIOStatus) st) {
case QEMU_MONITOR_BLOCK_IO_STATUS_OK:
return VIR_DOMAIN_DISK_ERROR_NONE;
case QEMU_MONITOR_BLOCK_IO_STATUS_FAILED:
return VIR_DOMAIN_DISK_ERROR_UNSPEC;
case QEMU_MONITOR_BLOCK_IO_STATUS_NOSPACE:
return VIR_DOMAIN_DISK_ERROR_NO_SPACE;
/* unreachable */
case QEMU_MONITOR_BLOCK_IO_STATUS_LAST:
break;
}
return -1;
}
virHashTablePtr virHashTablePtr
qemuMonitorGetBlockInfo(qemuMonitorPtr mon) qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
{ {
......
...@@ -236,6 +236,7 @@ int qemuMonitorGetMemoryStats(qemuMonitorPtr mon, ...@@ -236,6 +236,7 @@ int qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
virDomainMemoryStatPtr stats, virDomainMemoryStatPtr stats,
unsigned int nr_stats); unsigned int nr_stats);
int qemuMonitorBlockIOStatusToError(const char *status);
virHashTablePtr qemuMonitorGetBlockInfo(qemuMonitorPtr mon); virHashTablePtr qemuMonitorGetBlockInfo(qemuMonitorPtr mon);
struct qemuDomainDiskInfo * struct qemuDomainDiskInfo *
qemuMonitorBlockInfoLookup(virHashTablePtr blockInfo, qemuMonitorBlockInfoLookup(virHashTablePtr blockInfo,
......
...@@ -1389,6 +1389,7 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon, ...@@ -1389,6 +1389,7 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
virJSONValuePtr dev = virJSONValueArrayGet(devices, i); virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
struct qemuDomainDiskInfo *info; struct qemuDomainDiskInfo *info;
const char *thisdev; const char *thisdev;
const char *status;
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) { if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
...@@ -1434,6 +1435,13 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon, ...@@ -1434,6 +1435,13 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
*/ */
ignore_value(virJSONValueObjectGetBoolean(dev, "tray-open", ignore_value(virJSONValueObjectGetBoolean(dev, "tray-open",
&info->tray_open)); &info->tray_open));
/* Missing io-status indicates no error */
if ((status = virJSONValueObjectGetString(dev, "io-status"))) {
info->io_status = qemuMonitorBlockIOStatusToError(status);
if (info->io_status < 0)
goto cleanup;
}
} }
ret = 0; ret = 0;
......
...@@ -839,6 +839,21 @@ int qemuMonitorTextGetBlockInfo(qemuMonitorPtr mon, ...@@ -839,6 +839,21 @@ int qemuMonitorTextGetBlockInfo(qemuMonitorPtr mon,
VIR_DEBUG("error reading tray_open: %s", p); VIR_DEBUG("error reading tray_open: %s", p);
else else
info->tray_open = (tmp != 0); info->tray_open = (tmp != 0);
} else if (STRPREFIX(p, "io-status=")) {
char *end;
char c;
p += strlen("io-status=");
end = strchr(p, ' ');
if (!end || end > eol)
end = eol;
c = *end;
*end = '\0';
info->io_status = qemuMonitorBlockIOStatusToError(p);
*end = c;
if (info->io_status < 0)
goto cleanup;
} else { } else {
/* ignore because we don't parse all options */ /* ignore because we don't parse all options */
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册