Split out CCW address allocation

Just code movement and rename.
This commit is contained in:
Ján Tomko 2014-06-17 16:17:41 +02:00
parent c1bc06e2d7
commit b2626755d3
9 changed files with 205 additions and 181 deletions

View File

@ -564,3 +564,156 @@ virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
addrs->lastFlags = flags;
return 0;
}
static char*
virDomainCCWAddressAsString(virDomainDeviceCCWAddressPtr addr)
{
char *addrstr = NULL;
ignore_value(virAsprintf(&addrstr, "%x.%x.%04x",
addr->cssid,
addr->ssid,
addr->devno));
return addrstr;
}
static int
virDomainCCWAddressIncrement(virDomainDeviceCCWAddressPtr addr)
{
virDomainDeviceCCWAddress ccwaddr = *addr;
/* We are not touching subchannel sets and channel subsystems */
if (++ccwaddr.devno > VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO)
return -1;
*addr = ccwaddr;
return 0;
}
int
virDomainCCWAddressAssign(virDomainDeviceInfoPtr dev,
virDomainCCWAddressSetPtr addrs,
bool autoassign)
{
int ret = -1;
char *addr = NULL;
if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
return 0;
if (!autoassign && dev->addr.ccw.assigned) {
if (!(addr = virDomainCCWAddressAsString(&dev->addr.ccw)))
goto cleanup;
if (virHashLookup(addrs->defined, addr)) {
virReportError(VIR_ERR_XML_ERROR,
_("The CCW devno '%s' is in use already "),
addr);
goto cleanup;
}
} else if (autoassign && !dev->addr.ccw.assigned) {
if (!(addr = virDomainCCWAddressAsString(&addrs->next)) < 0)
goto cleanup;
while (virHashLookup(addrs->defined, addr)) {
if (virDomainCCWAddressIncrement(&addrs->next) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("There are no more free CCW devnos."));
goto cleanup;
}
VIR_FREE(addr);
addr = virDomainCCWAddressAsString(&addrs->next);
}
dev->addr.ccw = addrs->next;
dev->addr.ccw.assigned = true;
} else {
return 0;
}
if (virHashAddEntry(addrs->defined, addr, addr) < 0)
goto cleanup;
else
addr = NULL; /* memory will be freed by hash table */
ret = 0;
cleanup:
VIR_FREE(addr);
return ret;
}
int
virDomainCCWAddressAllocate(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
virDomainDeviceInfoPtr info,
void *data)
{
return virDomainCCWAddressAssign(info, data, true);
}
int
virDomainCCWAddressValidate(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
virDomainDeviceInfoPtr info,
void *data)
{
return virDomainCCWAddressAssign(info, data, false);
}
int
virDomainCCWAddressReleaseAddr(virDomainCCWAddressSetPtr addrs,
virDomainDeviceInfoPtr dev)
{
char *addr;
int ret;
addr = virDomainCCWAddressAsString(&(dev->addr.ccw));
if (!addr)
return -1;
if ((ret = virHashRemoveEntry(addrs->defined, addr)) == 0 &&
dev->addr.ccw.cssid == addrs->next.cssid &&
dev->addr.ccw.ssid == addrs->next.ssid &&
dev->addr.ccw.devno < addrs->next.devno) {
addrs->next.devno = dev->addr.ccw.devno;
addrs->next.assigned = false;
}
VIR_FREE(addr);
return ret;
}
void virDomainCCWAddressSetFree(virDomainCCWAddressSetPtr addrs)
{
if (!addrs)
return;
virHashFree(addrs->defined);
VIR_FREE(addrs);
}
virDomainCCWAddressSetPtr
virDomainCCWAddressSetCreate(void)
{
virDomainCCWAddressSetPtr addrs = NULL;
if (VIR_ALLOC(addrs) < 0)
goto error;
if (!(addrs->defined = virHashCreate(10, virHashValueFree)))
goto error;
/* must use cssid = 0xfe (254) for virtio-ccw devices */
addrs->next.cssid = 254;
addrs->next.ssid = 0;
addrs->next.devno = 0;
addrs->next.assigned = 0;
return addrs;
error:
virDomainCCWAddressSetFree(addrs);
return NULL;
}

View File

@ -146,4 +146,31 @@ int virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
virDomainPCIConnectFlags flags)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
struct _virDomainCCWAddressSet {
virHashTablePtr defined;
virDomainDeviceCCWAddress next;
};
typedef struct _virDomainCCWAddressSet virDomainCCWAddressSet;
typedef virDomainCCWAddressSet *virDomainCCWAddressSetPtr;
int virDomainCCWAddressAssign(virDomainDeviceInfoPtr dev,
virDomainCCWAddressSetPtr addrs,
bool autoassign)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virDomainCCWAddressSetFree(virDomainCCWAddressSetPtr addrs);
int virDomainCCWAddressAllocate(virDomainDefPtr def,
virDomainDeviceDefPtr dev,
virDomainDeviceInfoPtr info,
void *data)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
int virDomainCCWAddressValidate(virDomainDefPtr def,
virDomainDeviceDefPtr dev,
virDomainDeviceInfoPtr info,
void *data)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
int virDomainCCWAddressReleaseAddr(virDomainCCWAddressSetPtr addrs,
virDomainDeviceInfoPtr dev)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
virDomainCCWAddressSetPtr virDomainCCWAddressSetCreate(void);
#endif /* __DOMAIN_ADDR_H__ */

View File

@ -90,6 +90,12 @@ virInterfaceStateTypeToString;
# conf/domain_addr.h
virDomainCCWAddressAllocate;
virDomainCCWAddressAssign;
virDomainCCWAddressReleaseAddr;
virDomainCCWAddressSetCreate;
virDomainCCWAddressSetFree;
virDomainCCWAddressValidate;
virDomainPCIAddressAsString;
virDomainPCIAddressBusSetModel;
virDomainPCIAddressEnsureAddr;

View File

@ -1058,89 +1058,6 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
return 0;
}
/* S390 ccw bus support */
struct _qemuDomainCCWAddressSet {
virHashTablePtr defined;
virDomainDeviceCCWAddress next;
};
static char*
qemuCCWAddressAsString(virDomainDeviceCCWAddressPtr addr)
{
char *addrstr = NULL;
ignore_value(virAsprintf(&addrstr, "%x.%x.%04x",
addr->cssid,
addr->ssid,
addr->devno));
return addrstr;
}
static int
qemuCCWAdressIncrement(virDomainDeviceCCWAddressPtr addr)
{
virDomainDeviceCCWAddress ccwaddr = *addr;
/* We are not touching subchannel sets and channel subsystems */
if (++ccwaddr.devno > VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO)
return -1;
*addr = ccwaddr;
return 0;
}
int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev,
qemuDomainCCWAddressSetPtr addrs,
bool autoassign)
{
int ret = -1;
char *addr = NULL;
if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
return 0;
if (!autoassign && dev->addr.ccw.assigned) {
if (!(addr = qemuCCWAddressAsString(&dev->addr.ccw)))
goto cleanup;
if (virHashLookup(addrs->defined, addr)) {
virReportError(VIR_ERR_XML_ERROR,
_("The CCW devno '%s' is in use already "),
addr);
goto cleanup;
}
} else if (autoassign && !dev->addr.ccw.assigned) {
if (!(addr = qemuCCWAddressAsString(&addrs->next)) < 0)
goto cleanup;
while (virHashLookup(addrs->defined, addr)) {
if (qemuCCWAdressIncrement(&addrs->next) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("There are no more free CCW devnos."));
goto cleanup;
}
VIR_FREE(addr);
addr = qemuCCWAddressAsString(&addrs->next);
}
dev->addr.ccw = addrs->next;
dev->addr.ccw.assigned = true;
} else {
return 0;
}
if (virHashAddEntry(addrs->defined, addr, addr) < 0)
goto cleanup;
else
addr = NULL; /* memory will be freed by hash table */
ret = 0;
cleanup:
VIR_FREE(addr);
return ret;
}
static void
qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
@ -1187,79 +1104,6 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
def->rng->info.type = type;
}
static int
qemuDomainCCWAddressAllocate(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
virDomainDeviceInfoPtr info,
void *data)
{
return qemuDomainCCWAddressAssign(info, data, true);
}
static int
qemuDomainCCWAddressValidate(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
virDomainDeviceInfoPtr info,
void *data)
{
return qemuDomainCCWAddressAssign(info, data, false);
}
static int
qemuDomainCCWAddressReleaseAddr(qemuDomainCCWAddressSetPtr addrs,
virDomainDeviceInfoPtr dev)
{
char *addr;
int ret;
addr = qemuCCWAddressAsString(&(dev->addr.ccw));
if (!addr)
return -1;
if ((ret = virHashRemoveEntry(addrs->defined, addr)) == 0 &&
dev->addr.ccw.cssid == addrs->next.cssid &&
dev->addr.ccw.ssid == addrs->next.ssid &&
dev->addr.ccw.devno < addrs->next.devno) {
addrs->next.devno = dev->addr.ccw.devno;
addrs->next.assigned = false;
}
VIR_FREE(addr);
return ret;
}
void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs)
{
if (!addrs)
return;
virHashFree(addrs->defined);
VIR_FREE(addrs);
}
static qemuDomainCCWAddressSetPtr
qemuDomainCCWAddressSetCreate(void)
{
qemuDomainCCWAddressSetPtr addrs = NULL;
if (VIR_ALLOC(addrs) < 0)
goto error;
if (!(addrs->defined = virHashCreate(10, virHashValueFree)))
goto error;
/* must use cssid = 0xfe (254) for virtio-ccw devices */
addrs->next.cssid = 254;
addrs->next.ssid = 0;
addrs->next.devno = 0;
addrs->next.assigned = 0;
return addrs;
error:
qemuDomainCCWAddressSetFree(addrs);
return NULL;
}
/*
* Three steps populating CCW devnos
@ -1273,7 +1117,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
virDomainObjPtr obj)
{
int ret = -1;
qemuDomainCCWAddressSetPtr addrs = NULL;
virDomainCCWAddressSetPtr addrs = NULL;
qemuDomainObjPrivatePtr priv = NULL;
if (STREQLEN(def->os.machine, "s390-ccw", 8) &&
@ -1281,14 +1125,14 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
qemuDomainPrimeVirtioDeviceAddresses(
def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);
if (!(addrs = qemuDomainCCWAddressSetCreate()))
if (!(addrs = virDomainCCWAddressSetCreate()))
goto cleanup;
if (virDomainDeviceInfoIterate(def, qemuDomainCCWAddressValidate,
if (virDomainDeviceInfoIterate(def, virDomainCCWAddressValidate,
addrs) < 0)
goto cleanup;
if (virDomainDeviceInfoIterate(def, qemuDomainCCWAddressAllocate,
if (virDomainDeviceInfoIterate(def, virDomainCCWAddressAllocate,
addrs) < 0)
goto cleanup;
} else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
@ -1301,7 +1145,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
priv = obj->privateData;
if (addrs) {
/* if this is the live domain object, we persist the CCW addresses*/
qemuDomainCCWAddressSetFree(priv->ccwaddrs);
virDomainCCWAddressSetFree(priv->ccwaddrs);
priv->persistentAddrs = 1;
priv->ccwaddrs = addrs;
addrs = NULL;
@ -1312,7 +1156,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
ret = 0;
cleanup:
qemuDomainCCWAddressSetFree(addrs);
virDomainCCWAddressSetFree(addrs);
return ret;
}
@ -1796,7 +1640,7 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) &&
qemuDomainCCWAddressReleaseAddr(priv->ccwaddrs, info) < 0)
virDomainCCWAddressReleaseAddr(priv->ccwaddrs, info) < 0)
VIR_WARN("Unable to release CCW address on %s",
NULLSTR(devstr));
else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&

View File

@ -243,13 +243,9 @@ virDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
unsigned int nbuses,
bool dryRun);
int qemuAssignDevicePCISlots(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
virDomainPCIAddressSetPtr addrs);
int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, qemuDomainCCWAddressSetPtr addrs,
bool autoassign);
void qemuDomainCCWAddressSetFree(qemuDomainCCWAddressSetPtr addrs);
int qemuAssignDevicePCISlots(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
virDomainPCIAddressSetPtr addrs);
int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps);
int qemuDomainNetVLAN(virDomainNetDefPtr def);

View File

@ -249,7 +249,7 @@ qemuDomainObjPrivateFree(void *data)
virCgroupFree(&priv->cgroup);
virDomainPCIAddressSetFree(priv->pciaddrs);
qemuDomainCCWAddressSetFree(priv->ccwaddrs);
virDomainCCWAddressSetFree(priv->ccwaddrs);
virDomainChrSourceDefFree(priv->monConfig);
qemuDomainObjFreeJob(priv);
VIR_FREE(priv->vcpupids);

View File

@ -119,8 +119,6 @@ struct qemuDomainJobObj {
typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver,
virDomainObjPtr vm);
typedef struct _qemuDomainCCWAddressSet qemuDomainCCWAddressSet;
typedef qemuDomainCCWAddressSet *qemuDomainCCWAddressSetPtr;
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
@ -145,7 +143,7 @@ struct _qemuDomainObjPrivate {
int *vcpupids;
virDomainPCIAddressSetPtr pciaddrs;
qemuDomainCCWAddressSetPtr ccwaddrs;
virDomainCCWAddressSetPtr ccwaddrs;
int persistentAddrs;
virQEMUCapsPtr qemuCaps;

View File

@ -279,8 +279,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
if (qemuDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
!disk->info.addr.ccw.assigned) < 0)
if (virDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
!disk->info.addr.ccw.assigned) < 0)
goto error;
} else if (!disk->info.type ||
disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
@ -389,8 +389,8 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
goto cleanup;
} else if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
if (qemuDomainCCWAddressAssign(&controller->info, priv->ccwaddrs,
!controller->info.addr.ccw.assigned) < 0)
if (virDomainCCWAddressAssign(&controller->info, priv->ccwaddrs,
!controller->info.addr.ccw.assigned) < 0)
goto cleanup;
}
releaseaddr = true;
@ -933,8 +933,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
if (qemuDomainCCWAddressAssign(&net->info, priv->ccwaddrs,
!net->info.addr.ccw.assigned) < 0)
if (virDomainCCWAddressAssign(&net->info, priv->ccwaddrs,
!net->info.addr.ccw.assigned) < 0)
goto cleanup;
} else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",

View File

@ -4448,7 +4448,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
virDomainPCIAddressSetFree(priv->pciaddrs);
priv->pciaddrs = NULL;
virDomainDefClearCCWAddresses(vm->def);
qemuDomainCCWAddressSetFree(priv->ccwaddrs);
virDomainCCWAddressSetFree(priv->ccwaddrs);
priv->ccwaddrs = NULL;
}