mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-27 18:03:50 +03: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>
|
||||
...
|
||||
</domain>
|
||||
</pre>
|
||||
<pre>
|
||||
<domain>
|
||||
...
|
||||
<iothreadids>
|
||||
<iothread id="2"/>
|
||||
<iothread id="4"/>
|
||||
<iothread id="6"/>
|
||||
<iothread id="8"/>
|
||||
</iothreadids>
|
||||
...
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<dl>
|
||||
@ -530,7 +542,25 @@
|
||||
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
|
||||
than one supported device assigned to each IOThread.
|
||||
<span class="since">Since 1.2.8</span>
|
||||
</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>
|
||||
|
||||
<h3><a name="elementsCPUTuning">CPU Tuning</a></h3>
|
||||
|
@ -538,6 +538,18 @@
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
<optional>
|
||||
<element name="iothreadids">
|
||||
<zeroOrMore>
|
||||
<element name="iothread">
|
||||
<attribute name="id">
|
||||
<ref name="unsignedInt"/>
|
||||
</attribute>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
<optional>
|
||||
<ref name="blkiotune"/>
|
||||
</optional>
|
||||
|
@ -2102,6 +2102,32 @@ virDomainPinDefCopy(virDomainPinDefPtr *src, int npin)
|
||||
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
|
||||
virDomainPinDefFree(virDomainPinDefPtr def)
|
||||
{
|
||||
@ -2298,6 +2324,8 @@ void virDomainDefFree(virDomainDefPtr def)
|
||||
|
||||
virCPUDefFree(def->cpu);
|
||||
|
||||
virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);
|
||||
|
||||
virDomainPinDefArrayFree(def->cputune.vcpupin, def->cputune.nvcpupin);
|
||||
|
||||
virDomainPinDefFree(def->cputune.emulatorpin);
|
||||
@ -13170,6 +13198,54 @@ virDomainIdmapDefParseXML(xmlXPathContextPtr ctxt,
|
||||
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
|
||||
*
|
||||
* vcpupin has the form of
|
||||
@ -13976,6 +14052,49 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
}
|
||||
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. */
|
||||
if ((n = virXPathULong("string(./cputune/shares[1])", ctxt,
|
||||
&def->cputune.shares)) < -1) {
|
||||
@ -17260,6 +17379,67 @@ virDomainDefAddImplicitControllers(virDomainDefPtr def)
|
||||
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. */
|
||||
bool
|
||||
virDomainPinIsDuplicate(virDomainPinDefPtr *def,
|
||||
@ -20602,8 +20782,27 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||
virBufferAsprintf(buf, " current='%u'", def->vcpus);
|
||||
virBufferAsprintf(buf, ">%u</vcpu>\n", def->maxvcpus);
|
||||
|
||||
if (def->iothreads > 0)
|
||||
virBufferAsprintf(buf, "<iothreads>%u</iothreads>\n", def->iothreads);
|
||||
if (def->iothreads > 0) {
|
||||
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 ||
|
||||
(def->cputune.nvcpupin && !virDomainIsAllVcpupinInherited(def)) ||
|
||||
|
@ -2054,6 +2054,16 @@ struct _virDomainHugePage {
|
||||
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 virDomainCputune *virDomainCputunePtr;
|
||||
|
||||
@ -2145,6 +2155,8 @@ struct _virDomainDef {
|
||||
virBitmapPtr cpumask;
|
||||
|
||||
unsigned int iothreads;
|
||||
size_t niothreadids;
|
||||
virDomainIOThreadIDDefPtr *iothreadids;
|
||||
|
||||
virDomainCputune cputune;
|
||||
|
||||
@ -2604,6 +2616,12 @@ bool virDomainDefCheckABIStability(virDomainDefPtr src,
|
||||
|
||||
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);
|
||||
|
||||
char *virDomainDefFormat(virDomainDefPtr def,
|
||||
|
@ -324,6 +324,10 @@ virDomainHubTypeToString;
|
||||
virDomainHypervTypeFromString;
|
||||
virDomainHypervTypeToString;
|
||||
virDomainInputDefFree;
|
||||
virDomainIOThreadIDAdd;
|
||||
virDomainIOThreadIDDefFree;
|
||||
virDomainIOThreadIDDel;
|
||||
virDomainIOThreadIDFind;
|
||||
virDomainLeaseDefFree;
|
||||
virDomainLeaseIndex;
|
||||
virDomainLeaseInsert;
|
||||
|
Loading…
x
Reference in New Issue
Block a user