[libvirt] [RFC] New API to retrieve node CPU map
by Viktor Mihajlovski
Hi,
in order to use the APIs listed below it is necessary for a client to
know the maximum number of node CPUs which is passed via the maplen
argument.
virDomainGetEmulatorPinInfo
virDomainGetVcpuPinInfo
virDomainGetVcpus
virDomainPinEmulator
virDomainPinVcpu
virDomainPinVcpuFlags
The current approach uses virNodeGetInfo to determine the maximum CPU
number. This can lead to incorrect results if not all node CPUs are
online. The maximum CPU number should always be the number of CPUs
present on the host, regardless of their online/offline state.
The following example illustrates the issue:
Host has 3 logical CPUs, 1 socket, 3 cores, 1 thread.
Guest has 1 virtual CPU and is started while all 3 host CPUs are
online.
$ virsh vcpuinfo guest
VCPU: 0
CPU: 0
State: running
CPU time: 35.4s
CPU Affinity: yyy
$ echo 0 > /sys/devices/system/cpu/cpu1/online
$ virsh vcpuinfo guest
VCPU: 0
CPU: 0
State: running
CPU time: 35.5s
CPU Affinity: y-
The correct display for CPU affinity would have been y-y, as the guest
continues to use CPUs 0 and 2.
This is not a display problem only, because it is also not possible to
explicitly pin the virtual CPU to host CPUs 0 and 2, due to the
truncated CPU mask.
PROPOSAL:
To help solve the issue above I suggest two new public API functions:
int
virNodeGetCpuNum(virConnectPtr conn);
returning the number of present CPUs on the host or -1 upon failure
and
int
virNodeGetCpuMap(virConnectPtr conn, unsigned char * cpumap, int maplen);
returning the number of present CPUs or -1 on failure and storing a bit
map of real CPUs as described in virDomainPinVcpu in cpumap. The bits in
the bit map are set to 1 for online CPUs and set to 0 for offline CPUs.
Implementation is facilitated by the function nodeGetCPUmap in nodeinfo.c.
Clients can use virNodeGetCpuNum to properly determine the maximum
number of node CPUs and the online/offline information.
Thanks for your comments.
--
Mit freundlichen Grüßen/Kind Regards
Viktor Mihajlovski
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
11 years, 6 months
[libvirt] [PATCH] portability: handle ifreq differences in virnetdev
by Roman Bogorodskiy
FreeBSD (and maybe other BSDs) have different member
names in struct ifreq when compared to Linux, such as:
- uses ifr_data instead of ifr_newname for setting
interface names
- uses ifr_index instead of ifr_ifindex for interface
index
Also, add a check for SIOCGIFHWADDR for virNetDevValidateConfig().
Use AF_LOCAL if AF_PACKET is not available.
---
configure.ac | 8 ++++++++
src/util/virnetdev.c | 23 +++++++++++++++++------
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index 23c24d2..4a32f8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2363,6 +2363,14 @@ AM_CONDITIONAL([HAVE_LIBNL], [test "$have_libnl" = "yes"])
AC_SUBST([LIBNL_CFLAGS])
AC_SUBST([LIBNL_LIBS])
+AC_CHECK_MEMBERS([struct ifreq.ifr_newname,
+ struct ifreq.ifr_ifindex,
+ struct ifreq.ifr_index],
+ [], [],
+ [#include <sys/ioctl.h>
+ #include <net/if.h>
+ ])
+
# Only COPYING.LIB is under version control, yet COPYING
# is included as part of the distribution tarball.
# Copy one to the other, but only if this is a srcdir-build.
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 7ffaac1..02c1716 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -38,7 +38,10 @@
#ifdef __linux__
# include <linux/sockios.h>
# include <linux/if_vlan.h>
-#elif !defined(AF_PACKET)
+# define VIR_NETDEV_FAMILY AF_PACKET
+#elif defined(HAVE_STRUCT_IFREQ) && defined(AF_LOCAL)
+# define VIR_NETDEV_FAMILY AF_LOCAL
+#else
# undef HAVE_STRUCT_IFREQ
#endif
@@ -81,7 +84,7 @@ static int virNetDevSetupControlFull(const char *ifname,
static int virNetDevSetupControl(const char *ifname,
struct ifreq *ifr)
{
- return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM);
+ return virNetDevSetupControlFull(ifname, ifr, VIR_NETDEV_FAMILY, SOCK_DGRAM);
}
#endif
@@ -478,12 +481,16 @@ int virNetDevSetName(const char* ifname, const char *newifname)
if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0)
return -1;
+#if !defined(HAVE_STRUCT_IFREQ_IFR_NEWNAME)
+ ifr.ifr_data = (caddr_t)newifname;
+#else
if (virStrcpyStatic(ifr.ifr_newname, newifname) == NULL) {
virReportSystemError(ERANGE,
_("Network interface name '%s' is too long"),
newifname);
goto cleanup;
}
+#endif
if (ioctl(fd, SIOCSIFNAME, &ifr)) {
virReportSystemError(errno,
@@ -630,7 +637,7 @@ int virNetDevGetIndex(const char *ifname, int *ifindex)
{
int ret = -1;
struct ifreq ifreq;
- int fd = socket(PF_PACKET, SOCK_DGRAM, 0);
+ int fd = socket(VIR_NETDEV_FAMILY, SOCK_DGRAM, 0);
if (fd < 0) {
virReportSystemError(errno, "%s",
@@ -654,7 +661,11 @@ int virNetDevGetIndex(const char *ifname, int *ifindex)
goto cleanup;
}
+#if defined(HAVE_STRUCT_IFREQ_IFR_INDEX)
+ *ifindex = ifreq.ifr_index;
+#else
*ifindex = ifreq.ifr_ifindex;
+#endif
ret = 0;
cleanup:
@@ -870,7 +881,7 @@ int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED,
*
* Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error
*/
-#if defined(HAVE_STRUCT_IFREQ)
+#if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ)
int virNetDevValidateConfig(const char *ifname,
const virMacAddrPtr macaddr, int ifindex)
{
@@ -924,7 +935,7 @@ int virNetDevValidateConfig(const char *ifname,
VIR_FORCE_CLOSE(fd);
return ret;
}
-#else /* ! HAVE_STRUCT_IFREQ */
+#else
int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED,
const virMacAddrPtr macaddr ATTRIBUTE_UNUSED,
int ifindex ATTRIBUTE_UNUSED)
@@ -933,7 +944,7 @@ int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED,
_("Unable to check interface config on this platform"));
return -1;
}
-#endif /* ! HAVE_STRUCT_IFREQ */
+#endif
#ifdef __linux__
--
1.8.0
11 years, 6 months
[libvirt] [PATCH v2 1/1][RESEND] 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, 6 months
[libvirt] Entering freeze for libvirt-1.0.5
by Daniel Veillard
So as discussed earlier this week, I have tagged the release candidate 1
of libvirt-1.0.5 in git and pushed the tarball and associated rpms to
the FTP at:
ftp://libvirt.org/libvirt/
We may still push some of the patches needed by Laine to finish the
serie started yesterday, but at this point we should focuse our commits
on bug fixes and documentation. I will make an rc2 at the beginning of
next week and hopefully can push the final version on May 2nd.
This passed my own small usage tests, but please give it a try.
As usual some feedback on portability issues are really welcome too :-)
thanks !
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
11 years, 6 months
[libvirt] Bug Reports
by Dennis Zou (yunzou)
1.Lost soapAction in http request header
When I tried to retrieve the property of storage.perDatastoreUsage under specify virtual machine and got a invalidProperty error but other properties(e.g. summary.storage, guest) under the same virtual machine are ok.
Then I write a same program use vsphere web service sdk in java and catch the http package by wireshark.
By comparing, I found that we lost soapAction field in http request header, it seems to like this: SOAPAction: "urn:vim25/5.0".
I checked the vsphere development document and found some key description as following:
When a client application connects to a Web service running on an vSphere server (ESX/ESXi or vCenter Server system), the server detects the version of the API that was used to develop the client and makes available only those operations supported by the client.
Client applications convey information about the API version used in the SOAP messages that they send to a vSphere server. These SOAP messages include a versionID in the soapAction attribute. The details are handled transparently by the SOAP toolkit and the client proxy code. The server adjusts its behavior based on the client's version information, exposing the API version that the client supports to the client.
If you are developing a client application that must support multiple server versions at the same time (ESX/ESXi 5.0 and ESX/ESXi 3.x, for example), you must obtain information about the API versions that are supported on the server and provide logic in your code to use or not use features, based upon the version information.
Finally, I added the soapAction field into http request header and got a correct result. So I added some lines in function esxVI_Context_Connect() at src/esx/esx_vi.c as following:
if (virAsprintf(&soapAction, "SOAPAction: \"urn:vim25/%s\"",
ctx->service->about->apiVersion) < 0) {
virReportOOMError();
goto cleanup;
}
ctx->curl->headers = curl_slist_append(ctx->curl->headers, soapAction);
2.cat not deserialize the String(maybe other primary types are included) which as a list
when I tried to retrieve the property of config.network.pnic under hostsystem and got an error in virsh.log which goes like as following:
2013-04-22 01:57:42.692+0000: 29640: error : esxVI_String_Deserialize:1233 : internal error Wrong XML element type 3
Then I debug my program and find that bug lays where deserialize resourcePoolSchedulerDisallowedReason which is a member of PhysicalNic and has a string[] type.
I catch the soap message by wireshark and find that this xml element has no child ,it seems like as following:
<resourcePoolSchedulerDisallowedReason>hardwareUnsupported</resourcePoolSchedulerDisallowedReason
But the libvirt program still parses it as if it has children, I think this is key point that leads to this bug.
Now I fix my program by setting this member as ignore in esx_vi_generator.input.
Maybe you want to investigate and fix this bug.
Regards,
Dennis
11 years, 6 months
[libvirt] [PATCHv2] rpc: message related sizes enlarged
by Viktor Mihajlovski
From: Daniel Hansel <daniel.hansel(a)linux.vnet.ibm.com>
We have seen an issue on s390x platform where domain XMLs larger than 1MB
were used. The define command was finished successfully. The dumpxml command
was not successful (i.e. could not encode message payload).
Enlarged message related sizes (e.g. maximum string size, message size, etc.)
to handle larger system configurations used on s390x platform.
To improve handling of the RPC message size the allocation during encode process
is changed to a dynamic one (i.e. starting with 64kB initial size and increasing
that size in steps up to 16MB if the payload data is larger).
Signed-off-by: Daniel Hansel <daniel.hansel(a)linux.vnet.ibm.com>
Signed-off-by: Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
---
src/libvirt.c | 4 ++++
src/remote/remote_protocol.x | 6 +++---
src/rpc/virnetmessage.c | 46 ++++++++++++++++++++++++++++++++++--------
src/rpc/virnetmessage.h | 3 ++-
src/rpc/virnetprotocol.x | 16 +++++++++++----
tests/virnetmessagetest.c | 2 +-
6 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 2daa0b4..e6dd315 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7784,6 +7784,8 @@ error:
* For your program to be able to work reliably over a remote
* connection you should split large requests to <= 65536 bytes.
* However, with 0.9.13 this RPC limit has been raised to 1M byte.
+ * Starting with version 1.0.5 the RPC limit has been raised again.
+ * Now large requests up to 16M byte are supported.
*
* Returns: 0 in case of success or -1 in case of failure.
*/
@@ -7934,6 +7936,8 @@ error:
* For your program to be able to work reliably over a remote
* connection you should split large requests to <= 65536 bytes.
* However, with 0.9.13 this RPC limit has been raised to 1M byte.
+ * Starting with version 1.0.5 the RPC limit has been raised again.
+ * Now large requests up to 16M byte are supported.
*
* Returns: 0 in case of success or -1 in case of failure.
*/
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 512ba2e..f61d10c 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -65,7 +65,7 @@
* This is an arbitrary limit designed to stop the decoder from trying
* to allocate unbounded amounts of memory when fed with a bad message.
*/
-const REMOTE_STRING_MAX = 1048576;
+const REMOTE_STRING_MAX = 4194304;
/* A long string, which may NOT be NULL. */
typedef string remote_nonnull_string<REMOTE_STRING_MAX>;
@@ -160,13 +160,13 @@ const REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX = 1024;
* Note applications need to be aware of this limit and issue multiple
* requests for large amounts of data.
*/
-const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 1048576;
+const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 4194304;
/* Maximum length of a memory peek buffer message.
* Note applications need to be aware of this limit and issue multiple
* requests for large amounts of data.
*/
-const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 1048576;
+const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 4194304;
/*
* Maximum length of a security label list.
diff --git a/src/rpc/virnetmessage.c b/src/rpc/virnetmessage.c
index 647fef7..b2c6e5b 100644
--- a/src/rpc/virnetmessage.c
+++ b/src/rpc/virnetmessage.c
@@ -221,7 +221,7 @@ int virNetMessageEncodeHeader(virNetMessagePtr msg)
int ret = -1;
unsigned int len = 0;
- msg->bufferLength = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX;
+ msg->bufferLength = VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX;
if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
virReportOOMError();
return ret;
@@ -351,9 +351,27 @@ int virNetMessageEncodePayload(virNetMessagePtr msg,
xdrmem_create(&xdr, msg->buffer + msg->bufferOffset,
msg->bufferLength - msg->bufferOffset, XDR_ENCODE);
- if (!(*filter)(&xdr, data)) {
- virReportError(VIR_ERR_RPC, "%s", _("Unable to encode message payload"));
- goto error;
+ /* Try to encode the payload. If the buffer is too small increase it. */
+ while (!(*filter)(&xdr, data)) {
+ if ((msg->bufferLength - VIR_NET_MESSAGE_LEN_MAX) * 4 > VIR_NET_MESSAGE_MAX) {
+ virReportError(VIR_ERR_RPC, "%s", _("Unable to encode message payload"));
+ goto error;
+ }
+
+ xdr_destroy(&xdr);
+
+ msg->bufferLength = (msg->bufferLength - VIR_NET_MESSAGE_LEN_MAX) * 4 +
+ VIR_NET_MESSAGE_LEN_MAX;
+
+ if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ xdrmem_create(&xdr, msg->buffer + msg->bufferOffset,
+ msg->bufferLength - msg->bufferOffset, XDR_ENCODE);
+
+ VIR_DEBUG("Increased message buffer length = %zu", msg->bufferLength);
}
/* Get the length stored in buffer. */
@@ -415,11 +433,23 @@ int virNetMessageEncodePayloadRaw(virNetMessagePtr msg,
XDR xdr;
unsigned int msglen;
+ /* If the message buffer is too small for the payload increase it accordingly. */
if ((msg->bufferLength - msg->bufferOffset) < len) {
- virReportError(VIR_ERR_RPC,
- _("Stream data too long to send (%zu bytes needed, %zu bytes available)"),
- len, (msg->bufferLength - msg->bufferOffset));
- return -1;
+ if ((msg->bufferOffset + len) > VIR_NET_MESSAGE_MAX) {
+ virReportError(VIR_ERR_RPC,
+ _("Stream data too long to send (%zu bytes needed, %zu bytes available)"),
+ len, (VIR_NET_MESSAGE_MAX - msg->bufferOffset));
+ return -1;
+ }
+
+ msg->bufferLength = msg->bufferOffset + len;
+
+ if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ VIR_DEBUG("Increased message buffer length = %zu", msg->bufferLength);
}
memcpy(msg->buffer + msg->bufferOffset, data, len);
diff --git a/src/rpc/virnetmessage.h b/src/rpc/virnetmessage.h
index dfa1c6c..c94dddc 100644
--- a/src/rpc/virnetmessage.h
+++ b/src/rpc/virnetmessage.h
@@ -34,7 +34,8 @@ typedef void (*virNetMessageFreeCallback)(virNetMessagePtr msg, void *opaque);
struct _virNetMessage {
bool tracked;
- char *buffer; /* Typically VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX */
+ char *buffer; /* Initially VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX */
+ /* Maximum VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX */
size_t bufferLength;
size_t bufferOffset;
diff --git a/src/rpc/virnetprotocol.x b/src/rpc/virnetprotocol.x
index eb2e81d..131e40b 100644
--- a/src/rpc/virnetprotocol.x
+++ b/src/rpc/virnetprotocol.x
@@ -44,23 +44,31 @@
/*----- Data types. -----*/
+/* Initial message size.
+ * When the message payload is larger this initial size will be
+ * quadrupled until the maximum total message size is reached.
+ */
+const VIR_NET_MESSAGE_INITIAL = 65536;
+
/* Maximum total message size (serialised). */
-const VIR_NET_MESSAGE_MAX = 4194304;
+const VIR_NET_MESSAGE_MAX = 16777216;
/* Size of struct virNetMessageHeader (serialised)*/
const VIR_NET_MESSAGE_HEADER_MAX = 24;
/* Size of message payload */
-const VIR_NET_MESSAGE_PAYLOAD_MAX = 4194280;
+const VIR_NET_MESSAGE_PAYLOAD_MAX = 16777192;
-/* Size of message length field. Not counted in VIR_NET_MESSAGE_MAX */
+/* Size of message length field. Not counted in VIR_NET_MESSAGE_MAX
+ * and VIR_NET_MESSAGE_INITIAL.
+ */
const VIR_NET_MESSAGE_LEN_MAX = 4;
/* Length of long, but not unbounded, strings.
* This is an arbitrary limit designed to stop the decoder from trying
* to allocate unbounded amounts of memory when fed with a bad message.
*/
-const VIR_NET_MESSAGE_STRING_MAX = 1048576;
+const VIR_NET_MESSAGE_STRING_MAX = 4194304;
/* Limit on number of File Descriptors allowed to be
* passed per message
diff --git a/tests/virnetmessagetest.c b/tests/virnetmessagetest.c
index e58fd1f..607e0bd 100644
--- a/tests/virnetmessagetest.c
+++ b/tests/virnetmessagetest.c
@@ -47,7 +47,7 @@ static int testMessageHeaderEncode(const void *args ATTRIBUTE_UNUSED)
};
/* According to doc to virNetMessageEncodeHeader(&msg):
* msg->buffer will be this long */
- unsigned long msg_buf_size = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX;
+ unsigned long msg_buf_size = VIR_NET_MESSAGE_INITIAL + VIR_NET_MESSAGE_LEN_MAX;
int ret = -1;
if (!msg) {
--
1.7.9.5
11 years, 6 months
[libvirt] [PATCH] qemu: fix failure to start with spice graphics and no tls
by Laine Stump
Commit eca3fdf inadvertantly caused a failure to start for any domain
with the following in its config:
<graphics type='spice' autoport='yes'/>
The problem is that when tlsPort == 0 and defaultMode == "any" (which
is the default for defaultMode), this would be flagged in the code as
"needTLSPort", and if there was then no spice tls config, the new
error+fail would happen.
This patch checks for the case of defaultMode == "any", and in that
case simply doesn't allocate a TLS port (since that's probably not
what the user wanted, and it would have failed later anyway.). It does
leave the error in place for cases when the user specifically asked to
use tls in one way or another, though.
---
src/qemu/qemu_process.c | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e75c8c9..58f64b7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3294,23 +3294,34 @@ qemuProcessSPICEAllocatePorts(virQEMUDriverPtr driver,
if (needTLSPort || graphics->data.spice.tlsPort == -1) {
if (!cfg->spiceTLS) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Auto allocation of spice TLS port requested "
- "but spice TLS is disabled in qemu.conf"));
- goto error;
- }
-
- if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
- goto error;
+ /* log an error and fail if tls was specifically
+ * requested, or simply ignore (don't allocate a port)
+ * if we're here due to "defaultMode='any'"
+ * (aka unspecified).
+ */
+ if ((graphics->data.spice.tlsPort == -1) ||
+ (graphics->data.spice.defaultMode
+ == VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Auto allocation of spice TLS port requested "
+ "but spice TLS is disabled in qemu.conf"));
+ goto error;
+ }
+ } else {
+ /* cfg->spiceTLS *is* in place, so it makes sense to
+ * allocate a port.
+ */
+ if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
+ goto error;
- if (tlsPort == 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Unable to find an unused port for SPICE TLS"));
- virPortAllocatorRelease(driver->remotePorts, port);
- goto error;
+ if (tlsPort == 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to find an unused port for SPICE TLS"));
+ virPortAllocatorRelease(driver->remotePorts, port);
+ goto error;
+ }
+ graphics->data.spice.tlsPort = tlsPort;
}
-
- graphics->data.spice.tlsPort = tlsPort;
}
return 0;
--
1.7.11.7
11 years, 6 months
[libvirt] [PATCH 0/2] Get rid of default USB controller on S390
by Viktor Mihajlovski
QEMU for S390 has presently no USB controllers nor a PCI bus.
Both are created by the default in the libvirt domain definition.
Although this can be suppressed by explicitly specifying
an USB controller with model='none', it's a real bad default.
With Jan's recent patch we can reliably suppress the USB controller
(including it's bogus PCI address) if the source XML has no
usb controller element. Explicitly set addresses are still honored.
Viktor Mihajlovski (2):
S390: Mention changed USB behavior
S390: Do not generate a default USB controller
docs/formatdomain.html.in | 5 +++--
src/qemu/qemu_domain.c | 8 ++++++++
.../qemuxml2argv-console-sclp.args | 2 +-
.../qemuxml2argv-console-virtio-ccw.args | 2 +-
.../qemuxml2argv-console-virtio-s390.args | 2 +-
.../qemuxml2argv-disk-virtio-ccw-many.args | 2 +-
.../qemuxml2argv-disk-virtio-ccw.args | 2 +-
.../qemuxml2argv-disk-virtio-s390.args | 2 +-
.../qemuxml2argv-disk-virtio-scsi-ccw.args | 2 +-
.../qemuxml2argv-net-virtio-ccw.args | 2 +-
.../qemuxml2argv-net-virtio-s390.args | 2 +-
.../qemuxml2argv-virtio-rng-ccw.args | 2 +-
12 files changed, 21 insertions(+), 12 deletions(-)
--
1.7.9.5
11 years, 6 months
[libvirt] [PATCH] build: fix cygwin build in virnetdev
by Eric Blake
On cygwin, compilation failed because SIOCSIFHWADDR is undefined.
* src/util/virnetdev.c (virNetDevSetMAC): Cygwin can query but not
set mac address.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule. I may have a few more
cygwin-related patches as I continue to try and build there, but
figured it's better to send things as individual patches instead
of squashing unrelated fixes in one go.
src/util/virnetdev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 0a3e17d..8013f23 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -132,7 +132,8 @@ int virNetDevExists(const char *ifname)
#endif
-#if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ)
+#if defined(SIOCGIFHWADDR) && defined(SIOCSIFHWADDR) && \
+ defined(HAVE_STRUCT_IFREQ)
/**
* virNetDevSetMAC:
* @ifname: interface name to set MTU for
--
1.8.1.4
11 years, 6 months