qemu: conf: Add support for memory device cold(un)plug

Add a few helpers that allow to operate with memory device definitions
on the domain config and use them to implement memory device coldplug in
the qemu driver.
This commit is contained in:
Peter Krempa 2015-01-21 15:49:44 +01:00
parent 8b54bffbab
commit 96094fb28d
4 changed files with 127 additions and 2 deletions

View File

@ -12812,6 +12812,106 @@ virDomainRNGRemove(virDomainDefPtr def,
}
static int
virDomainMemoryFindByDefInternal(virDomainDefPtr def,
virDomainMemoryDefPtr mem,
bool allowAddressFallback)
{
size_t i;
for (i = 0; i < def->nmems; i++) {
virDomainMemoryDefPtr tmp = def->mems[i];
/* address, if present */
if (allowAddressFallback) {
if (tmp->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
continue;
} else {
if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
!virDomainDeviceInfoAddressIsEqual(&tmp->info, &mem->info))
continue;
}
/* alias, if present */
if (mem->info.alias &&
STRNEQ_NULLABLE(tmp->info.alias, mem->info.alias))
continue;
/* target info -> always present */
if (tmp->model != mem->model ||
tmp->targetNode != mem->targetNode ||
tmp->size != mem->size)
continue;
/* source stuff -> match with device */
if (tmp->pagesize != mem->pagesize)
continue;
if (!virBitmapEqual(tmp->sourceNodes, mem->sourceNodes))
continue;
break;
}
if (i == def->nmems)
return -1;
return i;
}
int
virDomainMemoryFindByDef(virDomainDefPtr def,
virDomainMemoryDefPtr mem)
{
return virDomainMemoryFindByDefInternal(def, mem, false);
}
int
virDomainMemoryFindInactiveByDef(virDomainDefPtr def,
virDomainMemoryDefPtr mem)
{
int ret;
if ((ret = virDomainMemoryFindByDefInternal(def, mem, false)) < 0)
ret = virDomainMemoryFindByDefInternal(def, mem, true);
return ret;
}
int
virDomainMemoryInsert(virDomainDefPtr def,
virDomainMemoryDefPtr mem)
{
int id = def->nmems;
if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
virDomainDefHasDeviceAddress(def, &mem->info)) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain already contains a device with the same "
"address"));
return -1;
}
if (VIR_APPEND_ELEMENT(def->mems, def->nmems, mem) < 0)
return -1;
return id;
}
virDomainMemoryDefPtr
virDomainMemoryRemove(virDomainDefPtr def,
int idx)
{
virDomainMemoryDefPtr ret = def->mems[idx];
VIR_DELETE_ELEMENT(def->mems, idx, def->nmems);
return ret;
}
char *
virDomainDefGetDefaultEmulator(virDomainDefPtr def,
virCapsPtr caps)

View File

@ -2859,6 +2859,16 @@ virDomainChrDefGetSecurityLabelDef(virDomainChrDefPtr def, const char *model);
typedef const char* (*virEventActionToStringFunc)(int type);
typedef int (*virEventActionFromStringFunc)(const char *type);
int virDomainMemoryInsert(virDomainDefPtr def, virDomainMemoryDefPtr mem)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
virDomainMemoryDefPtr virDomainMemoryRemove(virDomainDefPtr def, int idx)
ATTRIBUTE_NONNULL(1);
int virDomainMemoryFindByDef(virDomainDefPtr def, virDomainMemoryDefPtr mem)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virDomainMemoryFindInactiveByDef(virDomainDefPtr def,
virDomainMemoryDefPtr mem)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
VIR_ENUM_DECL(virDomainTaint)
VIR_ENUM_DECL(virDomainVirt)
VIR_ENUM_DECL(virDomainBoot)

View File

@ -335,6 +335,10 @@ virDomainLockFailureTypeToString;
virDomainMemballoonModelTypeFromString;
virDomainMemballoonModelTypeToString;
virDomainMemoryDefFree;
virDomainMemoryFindByDef;
virDomainMemoryFindInactiveByDef;
virDomainMemoryInsert;
virDomainMemoryRemove;
virDomainNetAppendIpAddress;
virDomainNetDefFormat;
virDomainNetDefFree;

View File

@ -7999,7 +7999,10 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps,
break;
case VIR_DOMAIN_DEVICE_MEMORY:
/* TODO: implement later */
if (virDomainMemoryInsert(vmdef, dev->data.memory) < 0)
return -1;
dev->data.memory = NULL;
break;
case VIR_DOMAIN_DEVICE_INPUT:
case VIR_DOMAIN_DEVICE_SOUND:
@ -8127,7 +8130,15 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
break;
case VIR_DOMAIN_DEVICE_MEMORY:
/* TODO: implement later */
if ((idx = virDomainMemoryFindInactiveByDef(vmdef,
dev->data.memory)) < 0) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("matching memory device was not found"));
return -1;
}
virDomainMemoryDefFree(virDomainMemoryRemove(vmdef, idx));
break;
case VIR_DOMAIN_DEVICE_INPUT:
case VIR_DOMAIN_DEVICE_SOUND: