提交 0feebab2 编写于 作者: P Peter Krempa

qemu: block: Add code to detect node names when necessary

Detect the node names when setting block threshold and when reconnecting
or when they are cleared when a block job finishes. This operation will
become a no-op once we fully support node names.
上级 2780bcd9
...@@ -278,3 +278,105 @@ qemuBlockNodeNameGetBackingChain(virJSONValuePtr json) ...@@ -278,3 +278,105 @@ qemuBlockNodeNameGetBackingChain(virJSONValuePtr json)
return ret; return ret;
} }
static void
qemuBlockDiskClearDetectedNodes(virDomainDiskDefPtr disk)
{
virStorageSourcePtr next = disk->src;
while (next) {
VIR_FREE(next->nodeformat);
VIR_FREE(next->nodebacking);
next = next->backingStore;
}
}
static int
qemuBlockDiskDetectNodes(virDomainDiskDefPtr disk,
const char *parentnode,
virHashTablePtr table)
{
qemuBlockNodeNameBackingChainDataPtr entry = NULL;
virStorageSourcePtr src = disk->src;
/* don't attempt the detection if the top level already has node names */
if (!parentnode || src->nodeformat || src->nodebacking)
return 0;
while (src && parentnode) {
if (!(entry = virHashLookup(table, parentnode)))
break;
if (src->nodeformat || src->nodebacking) {
if (STRNEQ_NULLABLE(src->nodeformat, entry->nodeformat) ||
STRNEQ_NULLABLE(src->nodebacking, entry->nodestorage))
goto error;
break;
} else {
if (VIR_STRDUP(src->nodeformat, entry->nodeformat) < 0 ||
VIR_STRDUP(src->nodebacking, entry->nodestorage) < 0)
goto error;
}
parentnode = entry->nodebacking;
src = src->backingStore;
}
return 0;
error:
qemuBlockDiskClearDetectedNodes(disk);
return -1;
}
int
qemuBlockNodeNamesDetect(virQEMUDriverPtr driver,
virDomainObjPtr vm)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
virHashTablePtr disktable = NULL;
virHashTablePtr nodenametable = NULL;
virJSONValuePtr data = NULL;
virDomainDiskDefPtr disk;
struct qemuDomainDiskInfo *info;
size_t i;
int ret = -1;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_NAMED_BLOCK_NODES))
return 0;
qemuDomainObjEnterMonitor(driver, vm);
disktable = qemuMonitorGetBlockInfo(qemuDomainGetMonitor(vm));
data = qemuMonitorQueryNamedBlockNodes(qemuDomainGetMonitor(vm));
if (qemuDomainObjExitMonitor(driver, vm) < 0 || !data || !disktable)
goto cleanup;
if (!(nodenametable = qemuBlockNodeNameGetBackingChain(data)))
goto cleanup;
for (i = 0; i < vm->def->ndisks; i++) {
disk = vm->def->disks[i];
if (!(info = virHashLookup(disktable, disk->info.alias)))
continue;
if (qemuBlockDiskDetectNodes(disk, info->nodename, nodenametable) < 0)
goto cleanup;
}
ret = 0;
cleanup:
virJSONValueFree(data);
virHashFree(nodenametable);
virHashFree(disktable);
return ret;
}
...@@ -44,4 +44,8 @@ struct qemuBlockNodeNameBackingChainData { ...@@ -44,4 +44,8 @@ struct qemuBlockNodeNameBackingChainData {
virHashTablePtr virHashTablePtr
qemuBlockNodeNameGetBackingChain(virJSONValuePtr data); qemuBlockNodeNameGetBackingChain(virJSONValuePtr data);
int
qemuBlockNodeNamesDetect(virQEMUDriverPtr driver,
virDomainObjPtr vm);
#endif /* __QEMU_BLOCK_H__ */ #endif /* __QEMU_BLOCK_H__ */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "internal.h" #include "internal.h"
#include "qemu_blockjob.h" #include "qemu_blockjob.h"
#include "qemu_block.h"
#include "qemu_domain.h" #include "qemu_domain.h"
#include "conf/domain_conf.h" #include "conf/domain_conf.h"
...@@ -166,6 +167,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, ...@@ -166,6 +167,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN; disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
true, true)); true, true));
ignore_value(qemuBlockNodeNamesDetect(driver, vm));
diskPriv->blockjob = false; diskPriv->blockjob = false;
break; break;
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "qemu_driver.h" #include "qemu_driver.h"
#include "qemu_agent.h" #include "qemu_agent.h"
#include "qemu_alias.h" #include "qemu_alias.h"
#include "qemu_block.h"
#include "qemu_conf.h" #include "qemu_conf.h"
#include "qemu_capabilities.h" #include "qemu_capabilities.h"
#include "qemu_command.h" #include "qemu_command.h"
...@@ -20354,6 +20355,10 @@ qemuDomainSetBlockThreshold(virDomainPtr dom, ...@@ -20354,6 +20355,10 @@ qemuDomainSetBlockThreshold(virDomainPtr dom,
if (!(src = qemuDomainGetStorageSourceByDevstr(dev, vm->def))) if (!(src = qemuDomainGetStorageSourceByDevstr(dev, vm->def)))
goto endjob; goto endjob;
if (!src->nodebacking &&
qemuBlockNodeNamesDetect(driver, vm) < 0)
goto endjob;
if (!src->nodebacking) { if (!src->nodebacking) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("threshold currently can't be set for block device '%s'"), _("threshold currently can't be set for block device '%s'"),
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "qemu_process.h" #include "qemu_process.h"
#include "qemu_processpriv.h" #include "qemu_processpriv.h"
#include "qemu_alias.h" #include "qemu_alias.h"
#include "qemu_block.h"
#include "qemu_domain.h" #include "qemu_domain.h"
#include "qemu_domain_address.h" #include "qemu_domain_address.h"
#include "qemu_cgroup.h" #include "qemu_cgroup.h"
...@@ -3486,6 +3487,9 @@ qemuProcessReconnect(void *opaque) ...@@ -3486,6 +3487,9 @@ qemuProcessReconnect(void *opaque)
if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0) if (qemuProcessRefreshDisks(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error; goto error;
if (qemuBlockNodeNamesDetect(driver, obj) < 0)
goto error;
if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0) if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
goto error; goto error;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册