[libvirt] The problem of CPU index
by Li Zhang
Hi all,
In the function qemuMonitorJSONExtractCPUInfo(),
it assumes that CPU indexes should be contiguous.
As the following:
if (cpu != i) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected cpu index %d expecting %d"),
i, cpu);
goto cleanup;
}
For x86, in what kind of situation will cause this error?
Actually, on ppc64, the CPU indexes always are not contiguous,
because smt is always disabled because of hardware's limitation for KVM.
For example, smt=4, CPUs=64, cores=16.
If with SMT enabled, 0~3 will run on core 0, 4~7 will run on core 1, ....
If SMT is disabled, only one thread is active. It should be 0, 4, 8,....
CPU information on my machine is as the following:
Architecture: ppc64
Byte Order: Big Endian
CPU(s): 64
On-line CPU(s) list: 0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60
Off-line CPU(s) list:
1-3,5-7,9-11,13-15,17-19,21-23,25-27,29-31,33-35,37-39,41-43,45-47,49-51,53-55,57-59,61-63
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 16
NUMA node(s): 2
Model: 8246-L2C
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 4096K
L4 cache: 4096K
NUMA node0 CPU(s): 0,36,40,44,48,52,56,60
NUMA node1 CPU(s): 4,8,12,16,20,24,28,32
Actually, only 16 CPUs are online.
All we get CPUs are 0,4,8,...,60.
If possible, could this assumption be removed?
Thanks
--Li
11 years, 10 months
[libvirt] [PATCH 1/1] Add NVRAM device
by Li Zhang
From: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
For pSeries guest in QEMU, NVRAM is one kind of spapr-vio device.
Users are allowed to specify spapr-vio devices'address.
But NVRAM is not supported in libvirt. So this patch is to
add NVRAM device to allow users to specify its address.
In QEMU, NVRAM device's address is specified by
"-global spapr-nvram.reg=xxxxx".
In libvirt, XML file is defined as the following:
<nvram>
<address type='spapr-vio' reg='0x3000'/>
</nvram>
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 10 ++++++
src/qemu/qemu_command.c | 31 ++++++++++++++++++
src/qemu/qemu_command.h | 2 ++
4 files changed, 125 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 10f361c..8c1e8ae 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -175,7 +175,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"redirdev",
"smartcard",
"chr",
- "memballoon")
+ "memballoon",
+ "nvram")
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
@@ -1442,6 +1443,16 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def)
VIR_FREE(def);
}
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def)
+{
+ if (!def)
+ return;
+
+ virDomainDeviceInfoClear(&def->info);
+
+ VIR_FREE(def);
+}
+
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def)
{
if (!def)
@@ -1602,6 +1613,7 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
+ case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
break;
}
@@ -1791,6 +1803,7 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainWatchdogDefFree(def->watchdog);
virDomainMemballoonDefFree(def->memballoon);
+ virDomainNVRAMDefFree(def->nvram);
for (i = 0; i < def->nseclabels; i++)
virSecurityLabelDefFree(def->seclabels[i]);
@@ -2342,6 +2355,12 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
if (cb(def, &device, &def->memballoon->info, opaque) < 0)
return -1;
}
+ if (def->nvram) {
+ device.type = VIR_DOMAIN_DEVICE_NVRAM;
+ device.data.nvram = def->nvram;
+ if (cb(def, &device, &def->nvram->info, opaque) < 0)
+ return -1;
+ }
device.type = VIR_DOMAIN_DEVICE_HUB;
for (i = 0; i < def->nhubs ; i++) {
device.data.hub = def->hubs[i];
@@ -7461,6 +7480,23 @@ error:
goto cleanup;
}
+static virDomainNVRAMDefPtr
+virDomainNVRAMDefParseXML(const xmlNodePtr node,
+ unsigned int flags)
+{
+ virDomainNVRAMDefPtr def;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if ( virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0 )
+ return NULL;
+
+ return def;
+}
+
static virSysinfoDefPtr
virSysinfoParseXML(const xmlNodePtr node,
xmlXPathContextPtr ctxt)
@@ -10572,6 +10608,32 @@ virDomainDefParseXML(virCapsPtr caps,
}
}
+ def->nvram = NULL;
+ if ((n = virXPathNodeSet("./devices/nvram", ctxt, &nodes)) < 0) {
+ goto error;
+ }
+
+ if (n > 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("only a single nvram device is supported"));
+ goto error;
+ }
+
+ if (n > 0) {
+ virDomainNVRAMDefPtr nvram =
+ virDomainNVRAMDefParseXML(nodes[0], flags);
+ if (!nvram)
+ goto error;
+ def->nvram = nvram;
+ VIR_FREE(nodes);
+ } else {
+ virDomainNVRAMDefPtr nvram;
+ if (VIR_ALLOC(nvram) < 0)
+ goto no_memory;
+ nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE;
+ def->nvram = nvram;
+ }
+
/* analysis of the hub devices */
if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
goto error;
@@ -13547,6 +13609,21 @@ virDomainMemballoonDefFormat(virBufferPtr buf,
}
static int
+virDomainNVRAMDefFormat(virBufferPtr buf,
+ virDomainNVRAMDefPtr def,
+ unsigned int flags)
+{
+ virBufferAsprintf(buf, " <nvram>\n");
+ if (virDomainDeviceInfoIsSet(&def->info, flags))
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+
+ virBufferAddLit(buf, " </nvram>\n");
+
+ return 0;
+}
+
+static int
virDomainSysinfoDefFormat(virBufferPtr buf,
virSysinfoDefPtr def)
{
@@ -14787,6 +14864,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->memballoon)
virDomainMemballoonDefFormat(buf, def->memballoon, flags);
+ if (def->nvram)
+ virDomainNVRAMDefFormat(buf, def->nvram, flags);
+
virBufferAddLit(buf, " </devices>\n");
virBufferAdjustIndent(buf, 2);
@@ -16061,6 +16141,7 @@ virDomainDeviceDefCopy(virCapsPtr caps,
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
+ case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Copying definition of '%d' type "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 4ffa4aa..8e5f1d8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -108,6 +108,9 @@ typedef virDomainChrDef *virDomainChrDefPtr;
typedef struct _virDomainMemballoonDef virDomainMemballoonDef;
typedef virDomainMemballoonDef *virDomainMemballoonDefPtr;
+typedef struct _virDomainNVRAMDef virDomainNVRAMDef;
+typedef virDomainNVRAMDef *virDomainNVRAMDefPtr;
+
typedef struct _virDomainSnapshotObj virDomainSnapshotObj;
typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
@@ -133,6 +136,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_SMARTCARD,
VIR_DOMAIN_DEVICE_CHR,
VIR_DOMAIN_DEVICE_MEMBALLOON,
+ VIR_DOMAIN_DEVICE_NVRAM,
VIR_DOMAIN_DEVICE_LAST
} virDomainDeviceType;
@@ -158,6 +162,7 @@ struct _virDomainDeviceDef {
virDomainSmartcardDefPtr smartcard;
virDomainChrDefPtr chr;
virDomainMemballoonDefPtr memballoon;
+ virDomainNVRAMDefPtr nvram;
} data;
};
@@ -1418,6 +1423,9 @@ struct _virDomainMemballoonDef {
virDomainDeviceInfo info;
};
+struct _virDomainNVRAMDef {
+ virDomainDeviceInfo info;
+};
enum virDomainSmbiosMode {
VIR_DOMAIN_SMBIOS_NONE,
@@ -1849,6 +1857,7 @@ struct _virDomainDef {
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
+ virDomainNVRAMDefPtr nvram;
virCPUDefPtr cpu;
virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter;
@@ -1951,6 +1960,7 @@ int virDomainChrSourceDefCopy(virDomainChrSourceDefPtr src,
void virDomainSoundCodecDefFree(virDomainSoundCodecDefPtr def);
void virDomainSoundDefFree(virDomainSoundDefPtr def);
void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def);
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def);
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
void virDomainVideoDefFree(virDomainVideoDefPtr def);
virDomainHostdevDefPtr virDomainHostdevDefAlloc(void);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index dee493f..6e1e0e6 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -941,6 +941,13 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
goto cleanup;
}
+ if (def->os.arch == VIR_ARCH_PPC64 &&
+ STREQ(def->os.machine, "pseries"))
+ def->nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
+ if (qemuAssignSpaprVIOAddress(def, &def->nvram->info,
+ 0x3000ul) < 0)
+ goto cleanup;
+
/* No other devices are currently supported on spapr-vio */
ret = 0;
@@ -3406,6 +3413,17 @@ error:
return NULL;
}
+char *
+qemuBuildNVRAMDevStr(virDomainNVRAMDefPtr dev)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
+ dev->info.addr.spaprvio.has_reg)
+ virBufferAsprintf(&buf, "spapr-nvram.reg=0x%llx",
+ dev->info.addr.spaprvio.reg);
+
+ return virBufferContentAndReset(&buf);
+}
char *
qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
@@ -7006,6 +7024,19 @@ qemuBuildCommandLine(virConnectPtr conn,
}
}
+ if (def->nvram &&
+ def->os.arch == VIR_ARCH_PPC64 &&
+ STREQ(def->os.machine, "pseries")) {
+ char *optstr;
+ virCommandAddArg(cmd, "-global");
+ optstr = qemuBuildNVRAMDevStr(def->nvram);
+ if (!optstr)
+ goto error;
+ if (optstr)
+ virCommandAddArg(cmd, optstr);
+ VIR_FREE(optstr);
+ }
+
if (snapshot)
virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index e4db000..7a0fe17 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -118,6 +118,8 @@ char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev,
char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
virQEMUCapsPtr qemuCaps);
+char * qemuBuildNVRAMDevStr(virDomainNVRAMDefPtr dev);
+
char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
virQEMUCapsPtr qemuCaps);
--
1.7.10.1
11 years, 10 months
[libvirt] [PATCH v2 1/1] Add NVRAM device
by Li Zhang
From: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
For pSeries guest in QEMU, NVRAM is one kind of spapr-vio device.
Users are allowed to specify spapr-vio devices'address.
But NVRAM is not supported in libvirt. So this patch is to
add NVRAM device to allow users to specify its address.
In QEMU, NVRAM device's address is specified by
"-global spapr-nvram.reg=xxxxx".
In libvirt, XML file is defined as the following:
<nvram>
<address type='spapr-vio' reg='0x3000'/>
</nvram>
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
* v2 -> v1:
Add NVRAM parameters parsing in qemuParseCommandLine.
src/conf/domain_conf.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 10 ++++++
src/qemu/qemu_command.c | 48 +++++++++++++++++++++++++++
src/qemu/qemu_command.h | 2 ++
4 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 10f361c..8c1e8ae 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -175,7 +175,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"redirdev",
"smartcard",
"chr",
- "memballoon")
+ "memballoon",
+ "nvram")
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
@@ -1442,6 +1443,16 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def)
VIR_FREE(def);
}
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def)
+{
+ if (!def)
+ return;
+
+ virDomainDeviceInfoClear(&def->info);
+
+ VIR_FREE(def);
+}
+
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def)
{
if (!def)
@@ -1602,6 +1613,7 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
+ case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
break;
}
@@ -1791,6 +1803,7 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainWatchdogDefFree(def->watchdog);
virDomainMemballoonDefFree(def->memballoon);
+ virDomainNVRAMDefFree(def->nvram);
for (i = 0; i < def->nseclabels; i++)
virSecurityLabelDefFree(def->seclabels[i]);
@@ -2342,6 +2355,12 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
if (cb(def, &device, &def->memballoon->info, opaque) < 0)
return -1;
}
+ if (def->nvram) {
+ device.type = VIR_DOMAIN_DEVICE_NVRAM;
+ device.data.nvram = def->nvram;
+ if (cb(def, &device, &def->nvram->info, opaque) < 0)
+ return -1;
+ }
device.type = VIR_DOMAIN_DEVICE_HUB;
for (i = 0; i < def->nhubs ; i++) {
device.data.hub = def->hubs[i];
@@ -7461,6 +7480,23 @@ error:
goto cleanup;
}
+static virDomainNVRAMDefPtr
+virDomainNVRAMDefParseXML(const xmlNodePtr node,
+ unsigned int flags)
+{
+ virDomainNVRAMDefPtr def;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if ( virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0 )
+ return NULL;
+
+ return def;
+}
+
static virSysinfoDefPtr
virSysinfoParseXML(const xmlNodePtr node,
xmlXPathContextPtr ctxt)
@@ -10572,6 +10608,32 @@ virDomainDefParseXML(virCapsPtr caps,
}
}
+ def->nvram = NULL;
+ if ((n = virXPathNodeSet("./devices/nvram", ctxt, &nodes)) < 0) {
+ goto error;
+ }
+
+ if (n > 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("only a single nvram device is supported"));
+ goto error;
+ }
+
+ if (n > 0) {
+ virDomainNVRAMDefPtr nvram =
+ virDomainNVRAMDefParseXML(nodes[0], flags);
+ if (!nvram)
+ goto error;
+ def->nvram = nvram;
+ VIR_FREE(nodes);
+ } else {
+ virDomainNVRAMDefPtr nvram;
+ if (VIR_ALLOC(nvram) < 0)
+ goto no_memory;
+ nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE;
+ def->nvram = nvram;
+ }
+
/* analysis of the hub devices */
if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
goto error;
@@ -13547,6 +13609,21 @@ virDomainMemballoonDefFormat(virBufferPtr buf,
}
static int
+virDomainNVRAMDefFormat(virBufferPtr buf,
+ virDomainNVRAMDefPtr def,
+ unsigned int flags)
+{
+ virBufferAsprintf(buf, " <nvram>\n");
+ if (virDomainDeviceInfoIsSet(&def->info, flags))
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+
+ virBufferAddLit(buf, " </nvram>\n");
+
+ return 0;
+}
+
+static int
virDomainSysinfoDefFormat(virBufferPtr buf,
virSysinfoDefPtr def)
{
@@ -14787,6 +14864,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->memballoon)
virDomainMemballoonDefFormat(buf, def->memballoon, flags);
+ if (def->nvram)
+ virDomainNVRAMDefFormat(buf, def->nvram, flags);
+
virBufferAddLit(buf, " </devices>\n");
virBufferAdjustIndent(buf, 2);
@@ -16061,6 +16141,7 @@ virDomainDeviceDefCopy(virCapsPtr caps,
case VIR_DOMAIN_DEVICE_SMARTCARD:
case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
+ case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Copying definition of '%d' type "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 4ffa4aa..8e5f1d8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -108,6 +108,9 @@ typedef virDomainChrDef *virDomainChrDefPtr;
typedef struct _virDomainMemballoonDef virDomainMemballoonDef;
typedef virDomainMemballoonDef *virDomainMemballoonDefPtr;
+typedef struct _virDomainNVRAMDef virDomainNVRAMDef;
+typedef virDomainNVRAMDef *virDomainNVRAMDefPtr;
+
typedef struct _virDomainSnapshotObj virDomainSnapshotObj;
typedef virDomainSnapshotObj *virDomainSnapshotObjPtr;
@@ -133,6 +136,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_SMARTCARD,
VIR_DOMAIN_DEVICE_CHR,
VIR_DOMAIN_DEVICE_MEMBALLOON,
+ VIR_DOMAIN_DEVICE_NVRAM,
VIR_DOMAIN_DEVICE_LAST
} virDomainDeviceType;
@@ -158,6 +162,7 @@ struct _virDomainDeviceDef {
virDomainSmartcardDefPtr smartcard;
virDomainChrDefPtr chr;
virDomainMemballoonDefPtr memballoon;
+ virDomainNVRAMDefPtr nvram;
} data;
};
@@ -1418,6 +1423,9 @@ struct _virDomainMemballoonDef {
virDomainDeviceInfo info;
};
+struct _virDomainNVRAMDef {
+ virDomainDeviceInfo info;
+};
enum virDomainSmbiosMode {
VIR_DOMAIN_SMBIOS_NONE,
@@ -1849,6 +1857,7 @@ struct _virDomainDef {
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
+ virDomainNVRAMDefPtr nvram;
virCPUDefPtr cpu;
virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter;
@@ -1951,6 +1960,7 @@ int virDomainChrSourceDefCopy(virDomainChrSourceDefPtr src,
void virDomainSoundCodecDefFree(virDomainSoundCodecDefPtr def);
void virDomainSoundDefFree(virDomainSoundDefPtr def);
void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def);
+void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def);
void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
void virDomainVideoDefFree(virDomainVideoDefPtr def);
virDomainHostdevDefPtr virDomainHostdevDefAlloc(void);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index dee493f..30694d6 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -941,6 +941,13 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
goto cleanup;
}
+ if (def->os.arch == VIR_ARCH_PPC64 &&
+ STREQ(def->os.machine, "pseries"))
+ def->nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
+ if (qemuAssignSpaprVIOAddress(def, &def->nvram->info,
+ 0x3000ul) < 0)
+ goto cleanup;
+
/* No other devices are currently supported on spapr-vio */
ret = 0;
@@ -3406,6 +3413,17 @@ error:
return NULL;
}
+char *
+qemuBuildNVRAMDevStr(virDomainNVRAMDefPtr dev)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
+ dev->info.addr.spaprvio.has_reg)
+ virBufferAsprintf(&buf, "spapr-nvram.reg=0x%llx",
+ dev->info.addr.spaprvio.reg);
+
+ return virBufferContentAndReset(&buf);
+}
char *
qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
@@ -7006,6 +7024,19 @@ qemuBuildCommandLine(virConnectPtr conn,
}
}
+ if (def->nvram &&
+ def->os.arch == VIR_ARCH_PPC64 &&
+ STREQ(def->os.machine, "pseries")) {
+ char *optstr;
+ virCommandAddArg(cmd, "-global");
+ optstr = qemuBuildNVRAMDevStr(def->nvram);
+ if (!optstr)
+ goto error;
+ if (optstr)
+ virCommandAddArg(cmd, optstr);
+ VIR_FREE(optstr);
+ }
+
if (snapshot)
virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
@@ -9139,6 +9170,23 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
goto error;
}
+ } else if (STREQ(arg, "-global") &&
+ STRPREFIX(progargv[i + 1], "spapr-nvram.reg=")) {
+
+ WANT_VALUE();
+
+ if (VIR_ALLOC(def->nvram) < 0)
+ goto no_memory;
+
+ val += strlen("spapr-nvram.reg=");
+ if (virStrToLong_ull(val, NULL, 16,
+ &def->nvram->info.addr.spaprvio.reg) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid value for spapr-nvram.reg :"
+ "'%s'"), val);
+ goto error;
+ }
+
} else if (STREQ(arg, "-S")) {
/* ignore, always added by libvirt */
} else {
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index e4db000..7a0fe17 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -118,6 +118,8 @@ char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev,
char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev,
virQEMUCapsPtr qemuCaps);
+char * qemuBuildNVRAMDevStr(virDomainNVRAMDefPtr dev);
+
char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev,
virQEMUCapsPtr qemuCaps);
--
1.7.10.1
11 years, 10 months
[libvirt] [PATCH] wrap some long lines
by liguang
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_command.c | 71 ++++++++++++++++++++++++++++++----------------
1 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9ad3c77..ad62120 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -611,7 +611,8 @@ qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx)
}
if ((thisidx = qemuDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Unable to determine device index for network device"));
+ _("Unable to determine device index for "
+ "network device"));
return -1;
}
if (thisidx >= idx)
@@ -638,7 +639,8 @@ qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev
int thisidx;
if ((thisidx = qemuDomainDeviceAliasIndex(def->hostdevs[i]->info, "hostdev")) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Unable to determine device index for hostdev device"));
+ _("Unable to determine device index for "
+ "hostdev device"));
return -1;
}
if (thisidx >= idx)
@@ -665,7 +667,8 @@ qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redir
int thisidx;
if ((thisidx = qemuDomainDeviceAliasIndex(&def->redirdevs[i]->info, "redir")) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Unable to determine device index for redirected device"));
+ _("Unable to determine device index for"
+ " redirected device"));
return -1;
}
if (thisidx >= idx)
@@ -1001,8 +1004,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
if (info->addr.pci.function != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("Attempted double use of PCI Address '%s' "
- "(may need \"multifunction='on'\" for device on function 0)"),
- addr);
+ "(may need \"multifunction='on'\" for "
+ "device on function 0)"), addr);
} else {
virReportError(VIR_ERR_XML_ERROR,
_("Attempted double use of PCI Address '%s'"), addr);
@@ -1036,7 +1039,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
goto cleanup;
}
- VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", addr);
+ VIR_DEBUG("Remembering PCI addr %s (multifunction=off"
+ " for function 0)", addr);
if (virHashAddEntry(addrs->used, addr, addr))
goto cleanup;
addr = NULL;
@@ -1468,7 +1472,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
def->controllers[i]->info.addr.pci.slot != 1 ||
def->controllers[i]->info.addr.pci.function != 2) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("PIIX3 USB controller must have PCI address 0:0:1.2"));
+ _("PIIX3 USB controller must have"
+ " PCI address 0:0:1.2"));
goto error;
}
reservedUSB = true;
@@ -1524,7 +1529,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
primaryVideo->info.addr.pci.slot != 2 ||
primaryVideo->info.addr.pci.function != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Primary video card must have PCI address 0:0:2.0"));
+ _("Primary video card must have "
+ "PCI address 0:0:2.0"));
goto error;
}
/* If TYPE==PCI, then qemuCollectPCIAddress() function
@@ -1814,12 +1820,14 @@ qemuBuildRomStr(virBufferPtr buf,
if (info->rombar || info->romfile) {
if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("rombar and romfile are supported only for PCI devices"));
+ "%s", _("rombar and romfile are supported "
+ "only for PCI devices"));
return -1;
}
if (!qemuCapsGet(caps, QEMU_CAPS_PCI_ROMBAR)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("rombar and romfile not supported in this QEMU binary"));
+ "%s", _("rombar and romfile not supported "
+ "in this QEMU binary"));
return -1;
}
@@ -1900,8 +1908,8 @@ qemuBuildRBDString(virConnectPtr conn,
VIR_SECRET_GET_VALUE_INTERNAL_CALL);
if (secret == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not get the value of the secret for username %s"),
- disk->auth.username);
+ _("could not get the value of the secret for "
+ "username %s"), disk->auth.username);
goto error;
}
/* qemu/librbd wants it base64 encoded */
@@ -2330,7 +2338,8 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
}
if (!disk->readonly) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot create virtual FAT disks in read-write mode"));
+ _("cannot create virtual FAT disks "
+ "in read-write mode"));
goto error;
}
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
@@ -3231,7 +3240,8 @@ qemuBuildNicDevStr(virDomainNetDefPtr net,
}
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("virtio-net-pci 'tx' option not supported in this QEMU binary"));
+ _("virtio-net-pci 'tx' option not supported "
+ "in this QEMU binary"));
goto error;
}
}
@@ -3538,7 +3548,8 @@ qemuBuildSoundCodecStr(virDomainSoundDefPtr sound,
}
virBufferAsprintf(&buf, "%s,id=%s-codec%d,bus=%s.0,cad=%d",
- stype, sound->info.alias, codec->cad, sound->info.alias, codec->cad);
+ stype, sound->info.alias, codec->cad,
+ sound->info.alias, codec->cad);
return virBufferContentAndReset(&buf);
@@ -4978,7 +4989,9 @@ qemuBuildGraphicsCommandLine(virQEMUDriverPtr driver,
case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
if (!driver->spiceTLS) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("spice secure channels set in XML configuration, but TLS is disabled in qemu.conf"));
+ _("spice secure channels set in XML "
+ "configuration, but TLS is disabled "
+ "in qemu.conf"));
goto error;
}
virBufferAsprintf(&opt, ",tls-channel=%s",
@@ -5218,7 +5231,8 @@ qemuBuildCommandLine(virConnectPtr conn,
}
if (!driver->hugepage_path) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("hugepages are disabled by administrator config"));
+ "%s", _("hugepages are disabled by "
+ "administrator config"));
goto error;
}
if (!qemuCapsGet(caps, QEMU_CAPS_MEM_PATH)) {
@@ -5268,7 +5282,8 @@ qemuBuildCommandLine(virConnectPtr conn,
if (!qemuCapsGet(caps, QEMU_CAPS_SMBIOS_TYPE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("the QEMU binary %s does not support smbios settings"),
+ _("the QEMU binary %s does not support "
+ "smbios settings"),
emulator);
goto error;
}
@@ -6386,7 +6401,8 @@ qemuBuildCommandLine(virConnectPtr conn,
if (!qemuCapsGet(caps, QEMU_CAPS_CHARDEV) ||
!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("guestfwd requires QEMU to support -chardev & -device"));
+ "%s", _("guestfwd requires QEMU to support "
+ "-chardev & -device"));
goto error;
}
@@ -6405,8 +6421,9 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, "-netdev");
virCommandAddArgFormat(cmd,
- "user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s",
- addr, port, channel->info.alias,
+ "user,guestfwd=tcp:%s:%i,chardev=char%s, "
+ "id=user-%s", addr, port,
+ channel->info.alias,
channel->info.alias);
VIR_FREE(addr);
break;
@@ -6414,7 +6431,8 @@ qemuBuildCommandLine(virConnectPtr conn,
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("virtio channel requires QEMU to support -device"));
+ _("virtio channel requires QEMU to support "
+ "-device"));
goto error;
}
@@ -6643,7 +6661,8 @@ qemuBuildCommandLine(virConnectPtr conn,
char *str;
if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("video type %s is only valid as primary video card"),
+ _("video type %s is only valid as "
+ "primary video card"),
virDomainVideoTypeToString(def->videos[0]->type));
goto error;
}
@@ -6930,7 +6949,8 @@ qemuBuildCommandLine(virConnectPtr conn,
VIR_FREE(devstr);
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("PCI device assignment is not supported by this version of qemu"));
+ _("PCI device assignment is not supported by "
+ "this version of qemu"));
goto error;
}
}
@@ -7010,7 +7030,8 @@ qemuBuildCommandLine(virConnectPtr conn,
def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {
if (def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Memory balloon device type '%s' is not supported by this version of qemu"),
+ _("Memory balloon device type '%s' is not supported "
+ "by this version of qemu"),
virDomainMemballoonModelTypeToString(def->memballoon->model));
goto error;
}
--
1.7.2.5
11 years, 10 months
[libvirt] [PATCH 0/5] fix qemumonitorjsontest
by Eric Blake
I hit a segv in qemumonitorjsontest on a new machine, and
traced it to through several layers of issues, including not
having yajl-devel installed on my end. This series fixes
the test failure, and several incidental things that I found
along the way.
Eric Blake (5):
qemu: don't override earlier json error
qemu: minor monitor lock cleanups
tests: avoid segfault if json monitor not present
tests: don't test json when not compiled in
tests: uniformly report test failures
cfg.mk | 7 +++++++
src/qemu/qemu_agent.c | 13 ++++++-------
src/qemu/qemu_monitor.c | 12 ++++--------
src/qemu/qemu_monitor_json.c | 8 +++-----
tests/commandhelper.c | 7 +++----
tests/qemumonitorjsontest.c | 14 ++++++++------
tests/qemumonitortestutils.c | 4 ++++
tests/seclabeltest.c | 8 ++++----
tests/securityselinuxlabeltest.c | 6 +++---
tests/securityselinuxtest.c | 6 +++---
tests/testutils.c | 8 ++++----
tests/testutils.h | 4 ++--
12 files changed, 51 insertions(+), 46 deletions(-)
--
1.8.1.2
11 years, 10 months
[libvirt] [PATCH] ESX: Add AnyType_Serialize routine to esx_vi_types.c
by Ata E Husain Bohra
Add esxVI_AnyType_Serialize routine to allow serialization
of objects containing variables of type "AnyType". The routine
attempts to determine the type of the object that covers:
boolean, long, int, string, short, byte.
If variables does not fall under any above mentioned types
then it is added as "anyType".
---
src/esx/esx_vi_types.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
src/esx/esx_vi_types.h | 3 ++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index d1f91ff..2076ce4 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -1130,6 +1130,54 @@ esxVI_AnyType_Deserialize(xmlNodePtr node, esxVI_AnyType **anyType)
+int
+esxVI_AnyType_Serialize(esxVI_AnyType *anyType, const char *element,
+ virBufferPtr output)
+{
+ if (element == NULL || output == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Invalid argument"));
+ return -1;
+ }
+
+ if (anyType == NULL || anyType->value == NULL) {
+ return 0;
+ }
+
+ switch (anyType->type) {
+ case esxVI_Type_Boolean:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:boolean");
+ break;
+ case esxVI_Type_String:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:string");
+ break;
+ case esxVI_Type_Short:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:short");
+ break;
+ case esxVI_Type_Byte:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:byte");
+ break;
+ case esxVI_Type_Int:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:int");
+ break;
+ case esxVI_Type_Long:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:long");
+ break;
+ case esxVI_Type_Undefined:
+ case esxVI_Type_Other:
+ default:
+ ESV_VI__XML_TAG__OPEN(output, element, "xsd:anyType");
+ break;
+ }
+
+ virBufferAdd(output, anyType->value, -1);
+
+ ESV_VI__XML_TAG__CLOSE(output, element);
+
+ return 0;
+}
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* XSD: String
*/
diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h
index 92dc16f..5150377 100644
--- a/src/esx/esx_vi_types.h
+++ b/src/esx/esx_vi_types.h
@@ -161,7 +161,8 @@ const char *esxVI_AnyType_TypeToString(esxVI_AnyType *anyType);
int esxVI_AnyType_ExpectType(esxVI_AnyType *anyType, esxVI_Type type);
int esxVI_AnyType_DeepCopy(esxVI_AnyType **dest, esxVI_AnyType *src);
int esxVI_AnyType_Deserialize(xmlNodePtr node, esxVI_AnyType **anyType);
-
+int esxVI_AnyType_Serialize(esxVI_AnyType *anyType, const char *element,
+ virBufferPtr output);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
--
1.7.9.5
11 years, 10 months
[libvirt] [PATCHv2 0/8] VirtIO RNG device support
by Peter Krempa
Version 2 fixes comments by John and several improvements I noticed.
There's 1 new patch in this series. See patch notes for more info.
Peter Krempa (8):
conf: Add fake switch statement to warn for new device types
doc: schema: Add basic documentation for the virtual RNG device
support
conf: Add support for RNG device configuration in XML
conf: Add RNG device ABI compatibility check
qemu: Implement support for default 'random' backend for virtio-rng
qemu: Implement support for EGD backend for virtio-rng
tests: Add tests for virtio-rng device handling
virtio-rng: Add rate limiting options for virtio-RNG
docs/formatdomain.html.in | 78 ++++++
docs/schemas/domaincommon.rng | 48 ++++
src/conf/domain_conf.c | 293 ++++++++++++++++++++-
src/conf/domain_conf.h | 39 +++
src/libvirt_private.syms | 2 +
src/qemu/qemu_capabilities.c | 6 +
src/qemu/qemu_capabilities.h | 4 +
src/qemu/qemu_command.c | 123 +++++++++
.../qemuxml2argv-virtio-rng-egd.args | 1 +
.../qemuxml2argv-virtio-rng-egd.xml | 26 ++
.../qemuxml2argv-virtio-rng-random.args | 1 +
.../qemuxml2argv-virtio-rng-random.xml | 24 ++
tests/qemuxml2argvtest.c | 5 +
tests/qemuxml2xmltest.c | 3 +
14 files changed, 652 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml
--
1.8.1.1
11 years, 10 months
[libvirt] [PATCH] conf: Avoid leaking of RNG device definition
by Peter Krempa
---
Yet another place not guarded by the compiler :(
This should qualify as trivial, so I'm pushing it directly.
src/conf/domain_conf.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3cb780d..b65e52a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1775,6 +1775,8 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainRedirdevDefFree(def->redirdevs[i]);
VIR_FREE(def->redirdevs);
+ virDomainRNGDefFree(def->rng);
+
VIR_FREE(def->os.type);
VIR_FREE(def->os.machine);
VIR_FREE(def->os.init);
--
1.8.1.1
11 years, 10 months
[libvirt] [PATCH] qemu: enable direct migration over IPv6
by Ján Tomko
Use virURIParse in qemuMigrationPrepareDirect to allow parsing
IPv6 addresses, which would cause an 'incorrect :port' error message
before.
To be able to migrate over IPv6, QEMU needs to listen on [::] instead
of 0.0.0.0. This patch adds a call to getaddrinfo and sets the listen
address based on the result.
It also uses the same listen address for the NBD server.
This will break migration if a hostname does not resolve to the same
address family on both sides.
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=846013
---
Diff to V1:
* initialize uri_str
* reuse STRSKIP("tcp:") result instead of doing strlen on it
* print a warning instead of failing when the hostname can't be resolved
Diff to V2:
* freeaddrinfo
* separate the listen address to allow reuse in qemuMigrationStartNBDServer
src/qemu/qemu_migration.c | 77 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 59 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index cae58fa..ff9b959 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -22,7 +22,10 @@
#include <config.h>
+#include <netdb.h>
+#include <sys/socket.h>
#include <sys/time.h>
+#include <sys/types.h>
#ifdef WITH_GNUTLS
# include <gnutls/gnutls.h>
# include <gnutls/x509.h>
@@ -1103,12 +1106,12 @@ error:
*/
static int
qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ const char *listenAddr)
{
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
unsigned short port = 0;
- const char *listenAddr = "0.0.0.0";
char *diskAlias = NULL;
size_t i;
@@ -1981,6 +1984,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
const char *dom_xml,
const char *migrateFrom,
virStreamPtr st,
+ const char *listenAddr,
unsigned long flags)
{
virDomainDefPtr def = NULL;
@@ -2168,7 +2172,7 @@ done:
if (flags & VIR_MIGRATE_TUNNELLED)
VIR_DEBUG("NBD in tunnelled migration is currently not supported");
else {
- if (qemuMigrationStartNBDServer(driver, vm) < 0) {
+ if (qemuMigrationStartNBDServer(driver, vm, listenAddr) < 0) {
/* error already reported */
goto endjob;
}
@@ -2271,7 +2275,7 @@ qemuMigrationPrepareTunnel(virQEMUDriverPtr driver,
*/
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, dname, dom_xml,
- "stdio", st, flags);
+ "stdio", st, NULL, flags);
return ret;
}
@@ -2292,9 +2296,14 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
static int port = 0;
int this_port;
char *hostname = NULL;
+ char listenAddr[8];
char migrateFrom [64];
const char *p;
+ char *uri_str = NULL;
int ret = -1;
+ bool ipv6 = false;
+ struct addrinfo *info;
+ virURIPtr uri;
VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
@@ -2343,16 +2352,39 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
* URI when passing it to the qemu monitor, so bad
* characters in hostname part don't matter.
*/
- if (!STRPREFIX(uri_in, "tcp:")) {
+ if (!(p = STRSKIP(uri_in, "tcp:"))) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("only tcp URIs are supported for KVM/QEMU"
" migrations"));
goto cleanup;
}
- /* Get the port number. */
- p = strrchr(uri_in, ':');
- if (p == strchr(uri_in, ':')) {
+ /* Convert uri_in to well-formed URI with // after tcp: */
+ if (!(STRPREFIX(uri_in, "tcp://"))) {
+ if (virAsprintf(&uri_str, "tcp://%s", p) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ uri = virURIParse(uri_str ? uri_str : uri_in);
+ VIR_FREE(uri_str);
+
+ if (uri == NULL) {
+ virReportError(VIR_ERR_INVALID_ARG, _("unable to parse URI: %s"),
+ uri_in);
+ goto cleanup;
+ }
+
+ if (uri->server == NULL) {
+ virReportError(VIR_ERR_INVALID_ARG, _("missing host in migration"
+ " URI: %s"), uri_in);
+ goto cleanup;
+ } else {
+ hostname = uri->server;
+ }
+
+ if (uri->port == 0) {
/* Generate a port */
this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
if (port == QEMUD_MIGRATION_NUM_PORTS)
@@ -2365,25 +2397,34 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
}
} else {
- p++; /* definitely has a ':' in it, see above */
- this_port = virParseNumber(&p);
- if (this_port == -1 || p-uri_in != strlen(uri_in)) {
- virReportError(VIR_ERR_INVALID_ARG,
- "%s", _("URI ended with incorrect ':port'"));
- goto cleanup;
- }
+ this_port = uri->port;
}
}
+ if (getaddrinfo(hostname, NULL, NULL, &info)) {
+ VIR_WARN("unable to get address info for %s, defaulting to IPv4",
+ hostname);
+ } else {
+ ipv6 = info->ai_family == AF_INET6;
+ freeaddrinfo(info);
+ }
+
if (*uri_out)
VIR_DEBUG("Generated uri_out=%s", *uri_out);
- /* QEMU will be started with -incoming tcp:0.0.0.0:port */
- snprintf(migrateFrom, sizeof(migrateFrom), "tcp:0.0.0.0:%d", this_port);
+ /* QEMU will be started with -incoming tcp:0.0.0.0:port
+ * or -incoming tcp:[::]:port for IPv6 */
+ if (ipv6)
+ snprintf(listenAddr, sizeof(listenAddr), "[::]");
+ else
+ snprintf(listenAddr, sizeof(listenAddr), "0.0.0.0");
+
+ snprintf(migrateFrom, sizeof(migrateFrom),
+ "tcp:%s:%d", listenAddr, this_port);
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, dname, dom_xml,
- migrateFrom, NULL, flags);
+ migrateFrom, NULL, listenAddr, flags);
cleanup:
VIR_FREE(hostname);
if (ret != 0)
--
1.7.12.4
11 years, 10 months
[libvirt] [PATCH 0/2] network: add force attribute for dhcp options
by Laine Stump
The firs patch just fixes unexpected behavior in
virNetworkDHCPOptionDefParseXML found when testing the second patch.
The second patch adds the "force" attribute I mentioned in the review
of the patch that added support for specifying dhcp options in network
config. While documenting this new attribute, I noticed that I'd
neglected to see that original patch didn't include documentation, so
I added full documentation for <option> in order to have a place to
add the documentation for "force='yes'".
I'm also working on a way to allow specification of option names
rather than numbers, but didn't know if I could get it in before the
freeze, so I'm sending this patch now.
Laine Stump (2):
conf: use VIR_EXPAND instead of VIR_REALLOC in
virNetworkDHCPDefParseXML
network: add force attribute for dhcp options
docs/formatnetwork.html.in | 21 ++++++++++++++++++++
src/conf/network_conf.c | 32 +++++++++++++++++++++---------
src/conf/network_conf.h | 3 ++-
src/network/bridge_driver.c | 3 ++-
tests/networkxml2confdata/nat-network.conf | 2 +-
tests/networkxml2confdata/nat-network.xml | 2 +-
6 files changed, 50 insertions(+), 13 deletions(-)
--
1.7.11.7
11 years, 10 months