On 23/06/16 09:45, Ján Tomko wrote:
In preparation to tracking which USB addresses are occupied.
Introduce two helper functions for printing the port path
as a string and appending it to a virBuffer.
---
src/conf/device_conf.h | 2 +-
src/conf/domain_addr.c | 26 ++++++++++++++++++++++++++
src/conf/domain_addr.h | 8 ++++++++
src/conf/domain_conf.c | 21 +++++++++------------
src/libvirt_private.syms | 2 ++
src/qemu/qemu_command.c | 3 ++-
6 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
index 934afd4..478060a 100644
--- a/src/conf/device_conf.h
+++ b/src/conf/device_conf.h
@@ -122,7 +122,7 @@ typedef struct _virDomainDeviceCcidAddress {
typedef struct _virDomainDeviceUSBAddress {
unsigned int bus;
- char *port;
+ unsigned int port[VIR_DOMAIN_DEVICE_USB_MAX_PORT_DEPTH];
} virDomainDeviceUSBAddress, *virDomainDeviceUSBAddressPtr;
typedef struct _virDomainDeviceSpaprVioAddress {
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 794270d..1f5193c 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -1251,3 +1251,29 @@ virDomainVirtioSerialAddrRelease(virDomainVirtioSerialAddrSetPtr
addrs,
VIR_FREE(str);
return ret;
}
+
+
+void
+virDomainUSBAddressPortFormatBuf(virBufferPtr buf,
+ unsigned int *port)
+{
+ size_t i;
+
+ for (i = 0; i < VIR_DOMAIN_DEVICE_USB_MAX_PORT_DEPTH; i++) {
+ if (port[i] == 0)
+ break;
+ virBufferAsprintf(buf, "%u.", port[i]);
+ }
+ virBufferTrim(buf, ".", -1);
+}
+
+
+char *
+virDomainUSBAddressPortFormat(unsigned int *port)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virDomainUSBAddressPortFormatBuf(&buf, port);
+ if (virBufferCheckError(&buf) < 0)
+ return NULL;
+ return virBufferContentAndReset(&buf);
+}
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
index f3eda89..8efd512 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -237,4 +237,12 @@ virDomainVirtioSerialAddrRelease(virDomainVirtioSerialAddrSetPtr
addrs,
virDomainDeviceInfoPtr info)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+void
+virDomainUSBAddressPortFormatBuf(virBufferPtr buf,
+ unsigned int *port)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+char *
+virDomainUSBAddressPortFormat(unsigned int *port)
+ ATTRIBUTE_NONNULL(1);
+
#endif /* __DOMAIN_ADDR_H__ */
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9443281..780d705 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32,6 +32,7 @@
#include "internal.h"
#include "virerror.h"
#include "datatypes.h"
+#include "domain_addr.h"
#include "domain_conf.h"
#include "snapshot_conf.h"
#include "viralloc.h"
@@ -3321,8 +3322,6 @@ virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst,
void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info)
{
VIR_FREE(info->alias);
- if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB)
- VIR_FREE(info->addr.usb.port);
memset(&info->addr, 0, sizeof(info->addr));
info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE;
VIR_FREE(info->romfile);
@@ -4867,9 +4866,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB:
- virBufferAsprintf(buf, " bus='%d' port='%s'",
- info->addr.usb.bus,
- info->addr.usb.port);
+ virBufferAsprintf(buf, " bus='%d' port='",
+ info->addr.usb.bus);
+ virDomainUSBAddressPortFormatBuf(buf, info->addr.usb.port);
+ virBufferAddLit(buf, "'");
break;
The empty string that could be formatted into the buffer if the port
wasn't originally specified was the only thing that had caught my eye. I
tried to define a domain with the port attribute omitted, since
according to virDomainDeviceUSBAddressParseXML port is optional. I hit
the RNG validation failure but once I bypassed it, the domain was
defined just fine. However, once I started it, I got an error: "Cannot
parse <address> 'port' attribute". I suspect it's due to
virDomainObjSetDefTransient running the xml parser again, which then
fails on the empty string because we formatted it back. I got the same
behavior with 1.3.5 as well with the only difference being that we
format the port back as '(null)', so imho we should not format the port
back if it would lead to '' or '(null)'.
Again, your patch did not break the functionality (as described above),
it *was* already broken, so that issue should be fixed first.
Erik