mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
conf: Add new domain XML element 'iothreadids'
Adding a new XML element 'iothreadids' in order to allow defining specific IOThread ID's rather than relying on the algorithm to assign IOThread ID's starting at 1 and incrementing to iothreads count. This will allow future patches to be able to add new IOThreads by a specific iothread_id and of course delete any exisiting IOThread. Each iothreadids element will have 'n' <iothread> children elements which will have attribute "id". The "id" will allow for definition of any "valid" (eg > 0) iothread_id value. On input, if any <iothreadids> <iothread>'s are provided, they will be marked so that we only print out what we read in. On input, if no <iothreadids> are provided, the PostParse code will self generate a list of ID's starting at 1 and going to the number of iothreads defined for the domain (just like the current algorithm numbering scheme). A future patch will rework the existing algorithm to make use of the iothreadids list. On output, only print out the <iothreadids> if they were read in.
This commit is contained in:
parent
a7f0db6904
commit
93383c1ffa
@ -520,6 +520,18 @@
|
|||||||
<iothreads>4</iothreads>
|
<iothreads>4</iothreads>
|
||||||
...
|
...
|
||||||
</domain>
|
</domain>
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
<domain>
|
||||||
|
...
|
||||||
|
<iothreadids>
|
||||||
|
<iothread id="2"/>
|
||||||
|
<iothread id="4"/>
|
||||||
|
<iothread id="6"/>
|
||||||
|
<iothread id="8"/>
|
||||||
|
</iothreadids>
|
||||||
|
...
|
||||||
|
</domain>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
@ -530,7 +542,25 @@
|
|||||||
virtio-blk-pci and virtio-blk-ccw target storage devices. There
|
virtio-blk-pci and virtio-blk-ccw target storage devices. There
|
||||||
should be only 1 or 2 IOThreads per host CPU. There may be more
|
should be only 1 or 2 IOThreads per host CPU. There may be more
|
||||||
than one supported device assigned to each IOThread.
|
than one supported device assigned to each IOThread.
|
||||||
|
<span class="since">Since 1.2.8</span>
|
||||||
</dd>
|
</dd>
|
||||||
|
<dt><code>iothreadids</code></dt>
|
||||||
|
<dd>
|
||||||
|
The optional <code>iothreadids</code> element provides the capability
|
||||||
|
to specifically define the IOThread ID's for the domain. By default,
|
||||||
|
IOThread ID's are sequentially numbered starting from 1 through the
|
||||||
|
number of <code>iothreads</code> defined for the domain. The
|
||||||
|
<code>id</code> attribute is used to define the IOThread ID. The
|
||||||
|
<code>id</code> attribute must be a positive integer greater than 0.
|
||||||
|
If there are less <code>iothreadids</code> defined than
|
||||||
|
<code>iothreads</code> defined for the domain, then libvirt will
|
||||||
|
sequentially fill <code>iothreadids</code> starting at 1 avoiding
|
||||||
|
any predefined <code>id</code>. If there are more
|
||||||
|
<code>iothreadids</code> defined than <code>iothreads</code>
|
||||||
|
defined for the domain, then the <code>iothreads</code> value
|
||||||
|
will be adjusted accordingly.
|
||||||
|
<span class="since">Since 1.2.15</span>
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h3><a name="elementsCPUTuning">CPU Tuning</a></h3>
|
<h3><a name="elementsCPUTuning">CPU Tuning</a></h3>
|
||||||
|
@ -538,6 +538,18 @@
|
|||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
|
|
||||||
|
<optional>
|
||||||
|
<element name="iothreadids">
|
||||||
|
<zeroOrMore>
|
||||||
|
<element name="iothread">
|
||||||
|
<attribute name="id">
|
||||||
|
<ref name="unsignedInt"/>
|
||||||
|
</attribute>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
|
|
||||||
<optional>
|
<optional>
|
||||||
<ref name="blkiotune"/>
|
<ref name="blkiotune"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
@ -2102,6 +2102,32 @@ virDomainPinDefCopy(virDomainPinDefPtr *src, int npin)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def)
|
||||||
|
{
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virDomainIOThreadIDDefArrayFree(virDomainIOThreadIDDefPtr *def,
|
||||||
|
int nids)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < nids; i++)
|
||||||
|
virDomainIOThreadIDDefFree(def[i]);
|
||||||
|
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
virDomainPinDefFree(virDomainPinDefPtr def)
|
virDomainPinDefFree(virDomainPinDefPtr def)
|
||||||
{
|
{
|
||||||
@ -2298,6 +2324,8 @@ void virDomainDefFree(virDomainDefPtr def)
|
|||||||
|
|
||||||
virCPUDefFree(def->cpu);
|
virCPUDefFree(def->cpu);
|
||||||
|
|
||||||
|
virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);
|
||||||
|
|
||||||
virDomainPinDefArrayFree(def->cputune.vcpupin, def->cputune.nvcpupin);
|
virDomainPinDefArrayFree(def->cputune.vcpupin, def->cputune.nvcpupin);
|
||||||
|
|
||||||
virDomainPinDefFree(def->cputune.emulatorpin);
|
virDomainPinDefFree(def->cputune.emulatorpin);
|
||||||
@ -13170,6 +13198,54 @@ virDomainIdmapDefParseXML(xmlXPathContextPtr ctxt,
|
|||||||
return idmap;
|
return idmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse the XML definition for an IOThread ID
|
||||||
|
*
|
||||||
|
* Format is :
|
||||||
|
*
|
||||||
|
* <iothreads>4</iothreads>
|
||||||
|
* <iothreadids>
|
||||||
|
* <iothread id='1'/>
|
||||||
|
* <iothread id='3'/>
|
||||||
|
* <iothread id='5'/>
|
||||||
|
* <iothread id='7'/>
|
||||||
|
* </iothreadids>
|
||||||
|
*/
|
||||||
|
static virDomainIOThreadIDDefPtr
|
||||||
|
virDomainIOThreadIDDefParseXML(xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt)
|
||||||
|
{
|
||||||
|
virDomainIOThreadIDDefPtr iothrid;
|
||||||
|
xmlNodePtr oldnode = ctxt->node;
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(iothrid) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if (!(tmp = virXPathString("string(./@id)", ctxt))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("Missing 'id' attribute in <iothread> element"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (virStrToLong_uip(tmp, NULL, 10, &iothrid->iothread_id) < 0 ||
|
||||||
|
iothrid->iothread_id == 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("invalid iothread 'id' value '%s'"), tmp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
ctxt->node = oldnode;
|
||||||
|
return iothrid;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDomainIOThreadIDDefFree(iothrid);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse the XML definition for a vcpupin
|
/* Parse the XML definition for a vcpupin
|
||||||
*
|
*
|
||||||
* vcpupin has the form of
|
* vcpupin has the form of
|
||||||
@ -13976,6 +14052,49 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
}
|
}
|
||||||
VIR_FREE(tmp);
|
VIR_FREE(tmp);
|
||||||
|
|
||||||
|
/* Extract any iothread id's defined */
|
||||||
|
if ((n = virXPathNodeSet("./iothreadids/iothread", ctxt, &nodes)) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (n > def->iothreads)
|
||||||
|
def->iothreads = n;
|
||||||
|
|
||||||
|
if (n && VIR_ALLOC_N(def->iothreadids, n) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
virDomainIOThreadIDDefPtr iothrid = NULL;
|
||||||
|
if (!(iothrid = virDomainIOThreadIDDefParseXML(nodes[i], ctxt)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virDomainIOThreadIDFind(def, iothrid->iothread_id)) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("duplicate iothread id '%u' found"),
|
||||||
|
iothrid->iothread_id);
|
||||||
|
virDomainIOThreadIDDefFree(iothrid);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->iothreadids[def->niothreadids++] = iothrid;
|
||||||
|
}
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
|
/* If no iothreadid's or not fully populated, let's finish the job
|
||||||
|
* here rather than in PostParseCallback
|
||||||
|
*/
|
||||||
|
if (def->iothreads && def->iothreads != def->niothreadids) {
|
||||||
|
unsigned int iothread_id = 1;
|
||||||
|
while (def->niothreadids != def->iothreads) {
|
||||||
|
if (!virDomainIOThreadIDFind(def, iothread_id)) {
|
||||||
|
virDomainIOThreadIDDefPtr iothrid;
|
||||||
|
|
||||||
|
if (!(iothrid = virDomainIOThreadIDAdd(def, iothread_id)))
|
||||||
|
goto error;
|
||||||
|
iothrid->autofill = true;
|
||||||
|
}
|
||||||
|
iothread_id++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Extract cpu tunables. */
|
/* Extract cpu tunables. */
|
||||||
if ((n = virXPathULong("string(./cputune/shares[1])", ctxt,
|
if ((n = virXPathULong("string(./cputune/shares[1])", ctxt,
|
||||||
&def->cputune.shares)) < -1) {
|
&def->cputune.shares)) < -1) {
|
||||||
@ -17260,6 +17379,67 @@ virDomainDefAddImplicitControllers(virDomainDefPtr def)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virDomainIOThreadIDDefPtr
|
||||||
|
virDomainIOThreadIDFind(virDomainDefPtr def,
|
||||||
|
unsigned int iothread_id)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!def->iothreadids || !def->niothreadids)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < def->niothreadids; i++) {
|
||||||
|
if (iothread_id == def->iothreadids[i]->iothread_id)
|
||||||
|
return def->iothreadids[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainIOThreadIDDefPtr
|
||||||
|
virDomainIOThreadIDAdd(virDomainDefPtr def,
|
||||||
|
unsigned int iothread_id)
|
||||||
|
{
|
||||||
|
virDomainIOThreadIDDefPtr iothrid = NULL;
|
||||||
|
|
||||||
|
if (virDomainIOThreadIDFind(def, iothread_id)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("cannot duplicate iothread_id '%u' in iothreadids"),
|
||||||
|
iothread_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(iothrid) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
iothrid->iothread_id = iothread_id;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT_COPY(def->iothreadids, def->niothreadids,
|
||||||
|
iothrid) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return iothrid;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDomainIOThreadIDDefFree(iothrid);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virDomainIOThreadIDDel(virDomainDefPtr def,
|
||||||
|
unsigned int iothread_id)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n = 0; n < def->niothreadids; n++) {
|
||||||
|
if (def->iothreadids[n]->iothread_id == iothread_id) {
|
||||||
|
virDomainIOThreadIDDefFree(def->iothreadids[n]);
|
||||||
|
VIR_DELETE_ELEMENT(def->iothreadids, n, def->niothreadids);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if vcpupin with same id already exists. */
|
/* Check if vcpupin with same id already exists. */
|
||||||
bool
|
bool
|
||||||
virDomainPinIsDuplicate(virDomainPinDefPtr *def,
|
virDomainPinIsDuplicate(virDomainPinDefPtr *def,
|
||||||
@ -20602,8 +20782,27 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
|||||||
virBufferAsprintf(buf, " current='%u'", def->vcpus);
|
virBufferAsprintf(buf, " current='%u'", def->vcpus);
|
||||||
virBufferAsprintf(buf, ">%u</vcpu>\n", def->maxvcpus);
|
virBufferAsprintf(buf, ">%u</vcpu>\n", def->maxvcpus);
|
||||||
|
|
||||||
if (def->iothreads > 0)
|
if (def->iothreads > 0) {
|
||||||
virBufferAsprintf(buf, "<iothreads>%u</iothreads>\n", def->iothreads);
|
virBufferAsprintf(buf, "<iothreads>%u</iothreads>\n",
|
||||||
|
def->iothreads);
|
||||||
|
/* Only print out iothreadids if we read at least one */
|
||||||
|
for (i = 0; i < def->niothreadids; i++) {
|
||||||
|
if (!def->iothreadids[i]->autofill)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < def->niothreadids) {
|
||||||
|
virBufferAddLit(buf, "<iothreadids>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
for (i = 0; i < def->niothreadids; i++) {
|
||||||
|
if (def->iothreadids[i]->autofill)
|
||||||
|
continue;
|
||||||
|
virBufferAsprintf(buf, "<iothread id='%u'/>\n",
|
||||||
|
def->iothreadids[i]->iothread_id);
|
||||||
|
}
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</iothreadids>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (def->cputune.sharesSpecified ||
|
if (def->cputune.sharesSpecified ||
|
||||||
(def->cputune.nvcpupin && !virDomainIsAllVcpupinInherited(def)) ||
|
(def->cputune.nvcpupin && !virDomainIsAllVcpupinInherited(def)) ||
|
||||||
|
@ -2054,6 +2054,16 @@ struct _virDomainHugePage {
|
|||||||
unsigned long long size; /* hugepage size in KiB */
|
unsigned long long size; /* hugepage size in KiB */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
|
||||||
|
typedef virDomainIOThreadIDDef *virDomainIOThreadIDDefPtr;
|
||||||
|
|
||||||
|
struct _virDomainIOThreadIDDef {
|
||||||
|
bool autofill;
|
||||||
|
unsigned int iothread_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
void virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def);
|
||||||
|
|
||||||
typedef struct _virDomainCputune virDomainCputune;
|
typedef struct _virDomainCputune virDomainCputune;
|
||||||
typedef virDomainCputune *virDomainCputunePtr;
|
typedef virDomainCputune *virDomainCputunePtr;
|
||||||
|
|
||||||
@ -2145,6 +2155,8 @@ struct _virDomainDef {
|
|||||||
virBitmapPtr cpumask;
|
virBitmapPtr cpumask;
|
||||||
|
|
||||||
unsigned int iothreads;
|
unsigned int iothreads;
|
||||||
|
size_t niothreadids;
|
||||||
|
virDomainIOThreadIDDefPtr *iothreadids;
|
||||||
|
|
||||||
virDomainCputune cputune;
|
virDomainCputune cputune;
|
||||||
|
|
||||||
@ -2604,6 +2616,12 @@ bool virDomainDefCheckABIStability(virDomainDefPtr src,
|
|||||||
|
|
||||||
int virDomainDefAddImplicitControllers(virDomainDefPtr def);
|
int virDomainDefAddImplicitControllers(virDomainDefPtr def);
|
||||||
|
|
||||||
|
virDomainIOThreadIDDefPtr virDomainIOThreadIDFind(virDomainDefPtr def,
|
||||||
|
unsigned int iothread_id);
|
||||||
|
virDomainIOThreadIDDefPtr virDomainIOThreadIDAdd(virDomainDefPtr def,
|
||||||
|
unsigned int iothread_id);
|
||||||
|
void virDomainIOThreadIDDel(virDomainDefPtr def, unsigned int iothread_id);
|
||||||
|
|
||||||
unsigned int virDomainDefFormatConvertXMLFlags(unsigned int flags);
|
unsigned int virDomainDefFormatConvertXMLFlags(unsigned int flags);
|
||||||
|
|
||||||
char *virDomainDefFormat(virDomainDefPtr def,
|
char *virDomainDefFormat(virDomainDefPtr def,
|
||||||
|
@ -324,6 +324,10 @@ virDomainHubTypeToString;
|
|||||||
virDomainHypervTypeFromString;
|
virDomainHypervTypeFromString;
|
||||||
virDomainHypervTypeToString;
|
virDomainHypervTypeToString;
|
||||||
virDomainInputDefFree;
|
virDomainInputDefFree;
|
||||||
|
virDomainIOThreadIDAdd;
|
||||||
|
virDomainIOThreadIDDefFree;
|
||||||
|
virDomainIOThreadIDDel;
|
||||||
|
virDomainIOThreadIDFind;
|
||||||
virDomainLeaseDefFree;
|
virDomainLeaseDefFree;
|
||||||
virDomainLeaseIndex;
|
virDomainLeaseIndex;
|
||||||
virDomainLeaseInsert;
|
virDomainLeaseInsert;
|
||||||
|
Loading…
Reference in New Issue
Block a user