Create field in virDomainDeviceInfo structure to hold
file descriptor set the device is associated with. Have
the number written into the Device Info XML and parsed
from the XML.
Remember the next-toy use file descriptor set in the QEMU
private domain structure.
Upon libvirt restart determine the maximum file descriptor
set used in the Device Info XML and remember the
next-to-use file descriptor set in the QEMU private domain
structure.
Upon termination of a domain, reset the next-to-use file
descriptor set to its initial value '1'.
Stefan Berger <stefanb(a)linux.vnet.ibm.com>
---
src/conf/capabilities.h | 5 ++++-
src/conf/domain_conf.c | 20 +++++++++++++++++---
src/conf/domain_conf.h | 1 +
src/lxc/lxc_domain.c | 3 ++-
src/qemu/qemu_domain.c | 23 ++++++++++++++++++++++-
src/qemu/qemu_domain.h | 2 ++
src/qemu/qemu_process.c | 2 ++
7 files changed, 50 insertions(+), 6 deletions(-)
Index: libvirt/src/qemu/qemu_domain.c
===================================================================
--- libvirt.orig/src/qemu/qemu_domain.c
+++ libvirt/src/qemu/qemu_domain.c
@@ -219,6 +219,7 @@ static void *qemuDomainObjPrivateAlloc(v
goto error;
priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
+ priv->nextfdset = 1;
return priv;
@@ -329,7 +330,25 @@ static int qemuDomainObjPrivateXMLFormat
return 0;
}
-static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
+static int qemuDomainRebuildFDSet(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+ virDomainDeviceInfoPtr info,
+ void *opaque)
+{
+ int *nextfdset = opaque;
+
+ if (info->fdset > 0 && *nextfdset <= info->fdset) {
+ *nextfdset = info->fdset + 1;
+ VIR_DEBUG("Found fdset %u for domain %s. Setting nextfdset = %u",
+ info->fdset, def->name, *nextfdset);
+ }
+
+
+ return 0;
+}
+
+static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data,
+ virDomainDefPtr def)
{
qemuDomainObjPrivatePtr priv = data;
char *monitorpath;
@@ -471,6 +490,8 @@ static int qemuDomainObjPrivateXMLParse(
priv->fakeReboot = virXPathBoolean("boolean(./fakereboot)", ctxt) == 1;
+ virDomainDeviceInfoIterate(def, qemuDomainRebuildFDSet, &priv->nextfdset);
+
return 0;
error:
Index: libvirt/src/qemu/qemu_domain.h
===================================================================
--- libvirt.orig/src/qemu/qemu_domain.h
+++ libvirt/src/qemu/qemu_domain.h
@@ -160,6 +160,8 @@ struct _qemuDomainObjPrivate {
qemuDomainCleanupCallback *cleanupCallbacks;
size_t ncleanupCallbacks;
size_t ncleanupCallbacks_max;
+
+ unsigned int nextfdset;
};
struct qemuDomainWatchdogEvent
Index: libvirt/src/conf/domain_conf.h
===================================================================
--- libvirt.orig/src/conf/domain_conf.h
+++ libvirt/src/conf/domain_conf.h
@@ -262,6 +262,7 @@ struct _virDomainDeviceInfo {
* to consider the new fields
*/
char *alias;
+ unsigned int fdset; /* > 0; "-add-fd set=%u,fd=123", fdsetnum */
int type;
union {
virDevicePCIAddress pci;
Index: libvirt/src/conf/domain_conf.c
===================================================================
--- libvirt.orig/src/conf/domain_conf.c
+++ libvirt/src/conf/domain_conf.c
@@ -2219,7 +2219,10 @@ virDomainDeviceInfoFormat(virBufferPtr b
if (info->alias &&
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
- virBufferAsprintf(buf, " <alias name='%s'/>\n",
info->alias);
+ virBufferAsprintf(buf, " <alias name='%s'",
info->alias);
+ if (info->fdset > 0)
+ virBufferAsprintf(buf, " fdset='%u'", info->fdset);
+ virBufferAddLit(buf, "/>\n");
}
if (info->mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
@@ -2597,6 +2600,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr n
xmlNodePtr boot = NULL;
xmlNodePtr rom = NULL;
char *type = NULL;
+ char *fdset = NULL;
int ret = -1;
virDomainDeviceInfoClear(info);
@@ -2627,9 +2631,18 @@ virDomainDeviceInfoParseXML(xmlNodePtr n
cur = cur->next;
}
- if (alias)
+ if (alias) {
info->alias = virXMLPropString(alias, "name");
+ fdset = virXMLPropString(alias, "fdset");
+ if (fdset && virStrToLong_ui(fdset, NULL, 10, &info->fdset) <
0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("incorrect fdset '%s', expecting positive
integer"),
+ fdset);
+ goto cleanup;
+ }
+ }
+
if (master) {
info->mastertype = VIR_DOMAIN_CONTROLLER_MASTER_USB;
if (virDomainDeviceUSBMasterParseXML(master, &info->master.usb) < 0)
@@ -2716,6 +2729,7 @@ cleanup:
if (ret == -1)
VIR_FREE(info->alias);
VIR_FREE(type);
+ VIR_FREE(fdset);
return ret;
}
@@ -10563,7 +10577,7 @@ static virDomainObjPtr virDomainObjParse
VIR_FREE(nodes);
if (caps->privateDataXMLParse &&
- ((caps->privateDataXMLParse)(ctxt, obj->privateData)) < 0)
+ ((caps->privateDataXMLParse)(ctxt, obj->privateData, obj->def)) < 0)
goto error;
return obj;
Index: libvirt/src/conf/capabilities.h
===================================================================
--- libvirt.orig/src/conf/capabilities.h
+++ libvirt/src/conf/capabilities.h
@@ -149,6 +149,9 @@ struct _virDomainXMLNamespace {
virDomainDefNamespaceHref href;
};
+typedef struct _virDomainDef virDomainDef;
+typedef virDomainDef *virDomainDefPtr;
+
typedef struct _virCaps virCaps;
typedef virCaps* virCapsPtr;
struct _virCaps {
@@ -164,7 +167,7 @@ struct _virCaps {
void *(*privateDataAllocFunc)(void);
void (*privateDataFreeFunc)(void *);
int (*privateDataXMLFormat)(virBufferPtr, void *);
- int (*privateDataXMLParse)(xmlXPathContextPtr, void *);
+ int (*privateDataXMLParse)(xmlXPathContextPtr, void *, virDomainDefPtr);
bool hasWideScsiBus;
const char *defaultInitPath;
Index: libvirt/src/lxc/lxc_domain.c
===================================================================
--- libvirt.orig/src/lxc/lxc_domain.c
+++ libvirt/src/lxc/lxc_domain.c
@@ -57,7 +57,8 @@ static int virLXCDomainObjPrivateXMLForm
return 0;
}
-static int virLXCDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
+static int virLXCDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
{
virLXCDomainObjPrivatePtr priv = data;
unsigned long long thepid;
Index: libvirt/src/qemu/qemu_process.c
===================================================================
--- libvirt.orig/src/qemu/qemu_process.c
+++ libvirt/src/qemu/qemu_process.c
@@ -4216,6 +4216,8 @@ void qemuProcessStop(virQEMUDriverPtr dr
priv->monConfig = NULL;
}
+ priv->nextfdset = 1;
+
/* shut it off for sure */
ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE|
VIR_QEMU_PROCESS_KILL_NOCHECK));