mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
conf: Add firmware blob configuration
QEMU has -fw_cfg which allows users to tweak how firmware configures itself and/or provide new configuration blobs. Introduce new <sysinfo/> type "fwcfg" that will hold these new blobs. It's possible to either specify new value as a string or provide a filename which contents then serve as the value. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
b44898dd31
commit
3dda889a44
@ -479,6 +479,10 @@
|
|||||||
<entry>otherappname:more arbitrary data</entry>
|
<entry>otherappname:more arbitrary data</entry>
|
||||||
</oemStrings>
|
</oemStrings>
|
||||||
</sysinfo>
|
</sysinfo>
|
||||||
|
<sysinfo type='fwcfg'>
|
||||||
|
<entry name='opt/com.example/name'>example value</entry>
|
||||||
|
<entry name='opt/com.coreos/config' file='/tmp/provision.ign'/>
|
||||||
|
</sysinfo>
|
||||||
...</pre>
|
...</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -593,6 +597,34 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dt><code>fwcfg</code></dt>
|
||||||
|
<dd>
|
||||||
|
Some hypervisors provide unified way to tweak how firmware configures
|
||||||
|
itself, or may contain tables to be installed for the guest OS, for
|
||||||
|
instance boot order, ACPI, SMBIOS, etc. It even allows users to define
|
||||||
|
their own config blobs. In case of QEMU, these then appear under domain's
|
||||||
|
sysfs, under <code>/sys/firmware/qemu_fw_cfg</code>. Note, that these
|
||||||
|
values apply regardless the <smbios/> mode under <os/>.
|
||||||
|
<span class="since">Since 6.5.0</span>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<smbios type='fwcfg'>
|
||||||
|
<entry name='opt/com.example/name'>example value</entry>
|
||||||
|
<entry name='opt/com.coreos/config' file='/tmp/provision.ign'/>
|
||||||
|
</smbios>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The <code>smbios</code> element can have multiple <code>entry</code>
|
||||||
|
child elements. Each element then has mandatory <code>name</code>
|
||||||
|
attribute, which defines the name of the blob and must begin with
|
||||||
|
<code>"opt/"</code> and to avoid clashing with other names is advised to
|
||||||
|
be in form <code>"opt/$RFQDN/$name"</code> where <code>$RFQDN</code> is a
|
||||||
|
reverse fully qualified domain name you control.
|
||||||
|
Then, the element can either contain the value (to set the blob value
|
||||||
|
directly), or <code>file</code> attribute (to set the blob value from
|
||||||
|
the file).
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h3><a id="elementsCPUAllocation">CPU Allocation</a></h3>
|
<h3><a id="elementsCPUAllocation">CPU Allocation</a></h3>
|
||||||
|
@ -46,9 +46,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="cpu"/>
|
<ref name="cpu"/>
|
||||||
</optional>
|
</optional>
|
||||||
<optional>
|
<zeroOrMore>
|
||||||
<ref name="sysinfo"/>
|
<ref name="sysinfo"/>
|
||||||
</optional>
|
</zeroOrMore>
|
||||||
<ref name="os"/>
|
<ref name="os"/>
|
||||||
<ref name="clock"/>
|
<ref name="clock"/>
|
||||||
<ref name="resources"/>
|
<ref name="resources"/>
|
||||||
@ -5511,68 +5511,95 @@
|
|||||||
-->
|
-->
|
||||||
<define name="sysinfo">
|
<define name="sysinfo">
|
||||||
<element name="sysinfo">
|
<element name="sysinfo">
|
||||||
<attribute name="type">
|
<choice>
|
||||||
<value>smbios</value>
|
<group>
|
||||||
</attribute>
|
<attribute name="type">
|
||||||
<interleave>
|
<value>smbios</value>
|
||||||
<optional>
|
</attribute>
|
||||||
<element name="bios">
|
<interleave>
|
||||||
<oneOrMore>
|
<optional>
|
||||||
<element name="entry">
|
<element name="bios">
|
||||||
<attribute name="name">
|
<oneOrMore>
|
||||||
<ref name="sysinfo-bios-name"/>
|
<element name="entry">
|
||||||
</attribute>
|
<attribute name="name">
|
||||||
<ref name="sysinfo-value"/>
|
<ref name="sysinfo-bios-name"/>
|
||||||
|
</attribute>
|
||||||
|
<ref name="sysinfo-value"/>
|
||||||
|
</element>
|
||||||
|
</oneOrMore>
|
||||||
</element>
|
</element>
|
||||||
</oneOrMore>
|
</optional>
|
||||||
</element>
|
<optional>
|
||||||
</optional>
|
<element name="system">
|
||||||
<optional>
|
<oneOrMore>
|
||||||
<element name="system">
|
<element name="entry">
|
||||||
<oneOrMore>
|
<attribute name="name">
|
||||||
<element name="entry">
|
<ref name="sysinfo-system-name"/>
|
||||||
<attribute name="name">
|
</attribute>
|
||||||
<ref name="sysinfo-system-name"/>
|
<ref name="sysinfo-value"/>
|
||||||
</attribute>
|
</element>
|
||||||
<ref name="sysinfo-value"/>
|
</oneOrMore>
|
||||||
</element>
|
</element>
|
||||||
</oneOrMore>
|
</optional>
|
||||||
</element>
|
<zeroOrMore>
|
||||||
</optional>
|
<element name="baseBoard">
|
||||||
<zeroOrMore>
|
<oneOrMore>
|
||||||
<element name="baseBoard">
|
<element name="entry">
|
||||||
<oneOrMore>
|
<attribute name="name">
|
||||||
<element name="entry">
|
<ref name="sysinfo-baseBoard-name"/>
|
||||||
<attribute name="name">
|
</attribute>
|
||||||
<ref name="sysinfo-baseBoard-name"/>
|
<ref name="sysinfo-value"/>
|
||||||
</attribute>
|
</element>
|
||||||
<ref name="sysinfo-value"/>
|
</oneOrMore>
|
||||||
</element>
|
</element>
|
||||||
</oneOrMore>
|
</zeroOrMore>
|
||||||
</element>
|
<optional>
|
||||||
</zeroOrMore>
|
<element name="chassis">
|
||||||
<optional>
|
<oneOrMore>
|
||||||
<element name="chassis">
|
<element name="entry">
|
||||||
<oneOrMore>
|
<attribute name="name">
|
||||||
<element name="entry">
|
<ref name="sysinfo-chassis-name"/>
|
||||||
<attribute name="name">
|
</attribute>
|
||||||
<ref name="sysinfo-chassis-name"/>
|
<ref name="sysinfo-value"/>
|
||||||
</attribute>
|
</element>
|
||||||
<ref name="sysinfo-value"/>
|
</oneOrMore>
|
||||||
</element>
|
</element>
|
||||||
</oneOrMore>
|
</optional>
|
||||||
</element>
|
<optional>
|
||||||
</optional>
|
<element name="oemStrings">
|
||||||
<optional>
|
<oneOrMore>
|
||||||
<element name="oemStrings">
|
<element name="entry">
|
||||||
<oneOrMore>
|
<ref name="sysinfo-value"/>
|
||||||
<element name="entry">
|
</element>
|
||||||
<ref name="sysinfo-value"/>
|
</oneOrMore>
|
||||||
</element>
|
</element>
|
||||||
</oneOrMore>
|
</optional>
|
||||||
</element>
|
</interleave>
|
||||||
</optional>
|
</group>
|
||||||
</interleave>
|
<group>
|
||||||
|
<attribute name="type">
|
||||||
|
<value>fwcfg</value>
|
||||||
|
</attribute>
|
||||||
|
<zeroOrMore>
|
||||||
|
<element name="entry">
|
||||||
|
<attribute name="name">
|
||||||
|
<data type="string"/>
|
||||||
|
</attribute>
|
||||||
|
<choice>
|
||||||
|
<group>
|
||||||
|
<attribute name="file">
|
||||||
|
<data type="string"/>
|
||||||
|
</attribute>
|
||||||
|
<empty/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<ref name="sysinfo-value"/>
|
||||||
|
</group>
|
||||||
|
</choice>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
|
</group>
|
||||||
|
</choice>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
@ -3551,7 +3551,9 @@ void virDomainDefFree(virDomainDefPtr def)
|
|||||||
|
|
||||||
virDomainNumaFree(def->numa);
|
virDomainNumaFree(def->numa);
|
||||||
|
|
||||||
virSysinfoDefFree(def->sysinfo);
|
for (i = 0; i < def->nsysinfo; i++)
|
||||||
|
virSysinfoDefFree(def->sysinfo[i]);
|
||||||
|
VIR_FREE(def->sysinfo);
|
||||||
|
|
||||||
virDomainRedirFilterDefFree(def->redirfilter);
|
virDomainRedirFilterDefFree(def->redirfilter);
|
||||||
|
|
||||||
@ -15708,16 +15710,115 @@ virSysinfoChassisParseXML(xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSysinfoParseSMBIOSDef(virSysinfoDefPtr def,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
unsigned char *domUUID,
|
||||||
|
bool uuid_generated)
|
||||||
|
{
|
||||||
|
xmlNodePtr tmpnode;
|
||||||
|
|
||||||
|
/* Extract BIOS related metadata */
|
||||||
|
if ((tmpnode = virXPathNode("./bios[1]", ctxt)) != NULL) {
|
||||||
|
if (virSysinfoBIOSParseXML(tmpnode, ctxt, &def->bios) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract system related metadata */
|
||||||
|
if ((tmpnode = virXPathNode("./system[1]", ctxt)) != NULL) {
|
||||||
|
if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system,
|
||||||
|
domUUID, uuid_generated) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract system base board metadata */
|
||||||
|
if (virSysinfoBaseBoardParseXML(ctxt, &def->baseBoard, &def->nbaseBoard) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Extract chassis related metadata */
|
||||||
|
if ((tmpnode = virXPathNode("./chassis[1]", ctxt)) != NULL) {
|
||||||
|
if (virSysinfoChassisParseXML(tmpnode, ctxt, &def->chassis) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract system related metadata */
|
||||||
|
if ((tmpnode = virXPathNode("./oemStrings[1]", ctxt)) != NULL) {
|
||||||
|
if (virSysinfoOEMStringsParseXML(tmpnode, ctxt, &def->oemStrings) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virSysinfoParseFWCfgDef(virSysinfoDefPtr def,
|
||||||
|
xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt)
|
||||||
|
{
|
||||||
|
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
||||||
|
g_autofree xmlNodePtr *nodes = NULL;
|
||||||
|
int n;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if ((n = virXPathNodeSet("./entry", ctxt, &nodes)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
def->fw_cfgs = g_new0(virSysinfoFWCfgDef, n);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
g_autofree char *name = NULL;
|
||||||
|
g_autofree char *value = NULL;
|
||||||
|
g_autofree char *file = NULL;
|
||||||
|
g_autofree char *sanitizedFile = NULL;
|
||||||
|
|
||||||
|
if (!(name = virXMLPropString(nodes[i], "name"))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("Firmware entry is missing 'name' attribute"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = virXMLNodeContentString(nodes[i]);
|
||||||
|
file = virXMLPropString(nodes[i], "file");
|
||||||
|
|
||||||
|
if (virStringIsEmpty(value))
|
||||||
|
VIR_FREE(value);
|
||||||
|
|
||||||
|
if (!value && !file) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("Firmware entry must have either value or "
|
||||||
|
"'file' attribute"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
sanitizedFile = virFileSanitizePath(file);
|
||||||
|
|
||||||
|
def->fw_cfgs[i].name = g_steal_pointer(&name);
|
||||||
|
def->fw_cfgs[i].value = g_steal_pointer(&value);
|
||||||
|
def->fw_cfgs[i].file = g_steal_pointer(&sanitizedFile);
|
||||||
|
def->nfw_cfgs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static virSysinfoDefPtr
|
static virSysinfoDefPtr
|
||||||
virSysinfoParseXML(xmlNodePtr node,
|
virSysinfoParseXML(xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
unsigned char *domUUID,
|
unsigned char *domUUID,
|
||||||
bool uuid_generated)
|
bool uuid_generated)
|
||||||
{
|
{
|
||||||
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
||||||
virSysinfoDefPtr def;
|
virSysinfoDefPtr def;
|
||||||
xmlNodePtr tmpnode;
|
g_autofree char *typeStr = NULL;
|
||||||
g_autofree char *type = NULL;
|
int type;
|
||||||
|
|
||||||
ctxt->node = node;
|
ctxt->node = node;
|
||||||
|
|
||||||
@ -15730,45 +15831,32 @@ virSysinfoParseXML(xmlNodePtr node,
|
|||||||
if (VIR_ALLOC(def) < 0)
|
if (VIR_ALLOC(def) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
type = virXMLPropString(node, "type");
|
typeStr = virXMLPropString(node, "type");
|
||||||
if (type == NULL) {
|
if (typeStr == NULL) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("sysinfo must contain a type attribute"));
|
_("sysinfo must contain a type attribute"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ((def->type = virSysinfoTypeFromString(type)) < 0) {
|
if ((type = virSysinfoTypeFromString(typeStr)) < 0) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("unknown sysinfo type '%s'"), type);
|
_("unknown sysinfo type '%s'"), typeStr);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
def->type = type;
|
||||||
|
|
||||||
/* Extract BIOS related metadata */
|
switch (def->type) {
|
||||||
if ((tmpnode = virXPathNode("./bios[1]", ctxt)) != NULL) {
|
case VIR_SYSINFO_SMBIOS:
|
||||||
if (virSysinfoBIOSParseXML(tmpnode, ctxt, &def->bios) < 0)
|
if (virSysinfoParseSMBIOSDef(def, ctxt, domUUID, uuid_generated) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
break;
|
||||||
|
|
||||||
/* Extract system related metadata */
|
case VIR_SYSINFO_FWCFG:
|
||||||
if ((tmpnode = virXPathNode("./system[1]", ctxt)) != NULL) {
|
if (virSysinfoParseFWCfgDef(def, node, ctxt) < 0)
|
||||||
if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system,
|
|
||||||
domUUID, uuid_generated) < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
break;
|
||||||
|
|
||||||
/* Extract system base board metadata */
|
case VIR_SYSINFO_LAST:
|
||||||
if (virSysinfoBaseBoardParseXML(ctxt, &def->baseBoard, &def->nbaseBoard) < 0)
|
break;
|
||||||
goto error;
|
|
||||||
|
|
||||||
/* Extract chassis related metadata */
|
|
||||||
if ((tmpnode = virXPathNode("./chassis[1]", ctxt)) != NULL) {
|
|
||||||
if (virSysinfoChassisParseXML(tmpnode, ctxt, &def->chassis) < 0)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract system related metadata */
|
|
||||||
if ((tmpnode = virXPathNode("./oemStrings[1]", ctxt)) != NULL) {
|
|
||||||
if (virSysinfoOEMStringsParseXML(tmpnode, ctxt, &def->oemStrings) < 0)
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
@ -22173,6 +22261,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
|
|
||||||
def->idmap.ngidmap = n;
|
def->idmap.ngidmap = n;
|
||||||
}
|
}
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
if ((def->idmap.uidmap && !def->idmap.gidmap) ||
|
if ((def->idmap.uidmap && !def->idmap.gidmap) ||
|
||||||
(!def->idmap.uidmap && def->idmap.gidmap)) {
|
(!def->idmap.uidmap && def->idmap.gidmap)) {
|
||||||
@ -22181,13 +22270,21 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node = virXPathNode("./sysinfo[1]", ctxt)) != NULL) {
|
if ((n = virXPathNodeSet("./sysinfo", ctxt, &nodes)) < 0)
|
||||||
def->sysinfo = virSysinfoParseXML(node, ctxt,
|
goto error;
|
||||||
def->uuid, uuid_generated);
|
|
||||||
|
|
||||||
if (def->sysinfo == NULL)
|
def->sysinfo = g_new0(virSysinfoDefPtr, n);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
virSysinfoDefPtr sysinfo = virSysinfoParseXML(nodes[i], ctxt,
|
||||||
|
def->uuid, uuid_generated);
|
||||||
|
|
||||||
|
if (!sysinfo)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
def->sysinfo[def->nsysinfo++] = sysinfo;
|
||||||
}
|
}
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
if ((tmp = virXPathString("string(./os/smbios/@mode)", ctxt))) {
|
if ((tmp = virXPathString("string(./os/smbios/@mode)", ctxt))) {
|
||||||
int mode;
|
int mode;
|
||||||
@ -24072,8 +24169,16 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
|
|||||||
if (!virCPUDefIsEqual(src->cpu, dst->cpu, true))
|
if (!virCPUDefIsEqual(src->cpu, dst->cpu, true))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!virSysinfoIsEqual(src->sysinfo, dst->sysinfo))
|
if (src->nsysinfo != dst->nsysinfo) {
|
||||||
goto error;
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("Target domain count of sysinfo does not match source"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < src->nsysinfo; i++) {
|
||||||
|
if (!virSysinfoIsEqual(src->sysinfo[i], dst->sysinfo[i]))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (src->ndisks != dst->ndisks) {
|
if (src->ndisks != dst->ndisks) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
@ -29507,8 +29612,8 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def,
|
|||||||
if (def->resource)
|
if (def->resource)
|
||||||
virDomainResourceDefFormat(buf, def->resource);
|
virDomainResourceDefFormat(buf, def->resource);
|
||||||
|
|
||||||
if (def->sysinfo)
|
for (i = 0; i < def->nsysinfo; i++)
|
||||||
ignore_value(virSysinfoFormat(buf, def->sysinfo));
|
virSysinfoFormat(buf, def->sysinfo[i]);
|
||||||
|
|
||||||
if (def->os.bootloader) {
|
if (def->os.bootloader) {
|
||||||
virBufferEscapeString(buf, "<bootloader>%s</bootloader>\n",
|
virBufferEscapeString(buf, "<bootloader>%s</bootloader>\n",
|
||||||
|
@ -2624,13 +2624,15 @@ struct _virDomainDef {
|
|||||||
size_t npanics;
|
size_t npanics;
|
||||||
virDomainPanicDefPtr *panics;
|
virDomainPanicDefPtr *panics;
|
||||||
|
|
||||||
|
size_t nsysinfo;
|
||||||
|
virSysinfoDefPtr *sysinfo;
|
||||||
|
|
||||||
/* Only 1 */
|
/* Only 1 */
|
||||||
virDomainWatchdogDefPtr watchdog;
|
virDomainWatchdogDefPtr watchdog;
|
||||||
virDomainMemballoonDefPtr memballoon;
|
virDomainMemballoonDefPtr memballoon;
|
||||||
virDomainNVRAMDefPtr nvram;
|
virDomainNVRAMDefPtr nvram;
|
||||||
virDomainTPMDefPtr tpm;
|
virDomainTPMDefPtr tpm;
|
||||||
virCPUDefPtr cpu;
|
virCPUDefPtr cpu;
|
||||||
virSysinfoDefPtr sysinfo;
|
|
||||||
virDomainRedirFilterDefPtr redirfilter;
|
virDomainRedirFilterDefPtr redirfilter;
|
||||||
virDomainIOMMUDefPtr iommu;
|
virDomainIOMMUDefPtr iommu;
|
||||||
virDomainVsockDefPtr vsock;
|
virDomainVsockDefPtr vsock;
|
||||||
|
@ -5736,13 +5736,19 @@ qemuBuildSmbiosCommandLine(virCommandPtr cmd,
|
|||||||
/* Host and guest uuid must differ, by definition of UUID. */
|
/* Host and guest uuid must differ, by definition of UUID. */
|
||||||
skip_uuid = true;
|
skip_uuid = true;
|
||||||
} else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) {
|
} else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) {
|
||||||
if (def->sysinfo == NULL) {
|
for (i = 0; i < def->nsysinfo; i++) {
|
||||||
|
if (def->sysinfo[i]->type == VIR_SYSINFO_SMBIOS) {
|
||||||
|
source = def->sysinfo[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!source) {
|
||||||
virReportError(VIR_ERR_XML_ERROR,
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
_("Domain '%s' sysinfo are not available"),
|
_("Domain '%s' sysinfo are not available"),
|
||||||
def->name);
|
def->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
source = def->sysinfo;
|
|
||||||
/* domain_conf guaranteed that system_uuid matches guest uuid. */
|
/* domain_conf guaranteed that system_uuid matches guest uuid. */
|
||||||
}
|
}
|
||||||
if (source != NULL) {
|
if (source != NULL) {
|
||||||
|
@ -43,6 +43,7 @@ VIR_LOG_INIT("util.sysinfo");
|
|||||||
VIR_ENUM_IMPL(virSysinfo,
|
VIR_ENUM_IMPL(virSysinfo,
|
||||||
VIR_SYSINFO_LAST,
|
VIR_SYSINFO_LAST,
|
||||||
"smbios",
|
"smbios",
|
||||||
|
"fwcfg"
|
||||||
);
|
);
|
||||||
|
|
||||||
static const char *sysinfoSysinfo = "/proc/sysinfo";
|
static const char *sysinfoSysinfo = "/proc/sysinfo";
|
||||||
@ -1513,6 +1514,40 @@ virSysinfoOEMStringsFormat(virBufferPtr buf, virSysinfoOEMStringsDefPtr def)
|
|||||||
virBufferAddLit(buf, "</oemStrings>\n");
|
virBufferAddLit(buf, "</oemStrings>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virSysinfoFormatSMBIOS(virBufferPtr buf,
|
||||||
|
virSysinfoDefPtr def)
|
||||||
|
{
|
||||||
|
virSysinfoBIOSFormat(buf, def->bios);
|
||||||
|
virSysinfoSystemFormat(buf, def->system);
|
||||||
|
virSysinfoBaseBoardFormat(buf, def->baseBoard, def->nbaseBoard);
|
||||||
|
virSysinfoChassisFormat(buf, def->chassis);
|
||||||
|
virSysinfoProcessorFormat(buf, def);
|
||||||
|
virSysinfoMemoryFormat(buf, def);
|
||||||
|
virSysinfoOEMStringsFormat(buf, def->oemStrings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virSysinfoFormatFWCfg(virBufferPtr buf,
|
||||||
|
virSysinfoDefPtr def)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < def->nfw_cfgs; i++) {
|
||||||
|
const virSysinfoFWCfgDef *f = &def->fw_cfgs[i];
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<entry name='%s'", f->name);
|
||||||
|
|
||||||
|
if (f->file)
|
||||||
|
virBufferEscapeString(buf, " file='%s'/>\n", f->file);
|
||||||
|
else
|
||||||
|
virBufferEscapeString(buf, ">%s</entry>\n", f->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virSysinfoFormat:
|
* virSysinfoFormat:
|
||||||
* @buf: buffer to append output to (may use auto-indentation)
|
* @buf: buffer to append output to (may use auto-indentation)
|
||||||
@ -1535,13 +1570,16 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virSysinfoBIOSFormat(&childrenBuf, def->bios);
|
switch (def->type) {
|
||||||
virSysinfoSystemFormat(&childrenBuf, def->system);
|
case VIR_SYSINFO_SMBIOS:
|
||||||
virSysinfoBaseBoardFormat(&childrenBuf, def->baseBoard, def->nbaseBoard);
|
virSysinfoFormatSMBIOS(&childrenBuf, def);
|
||||||
virSysinfoChassisFormat(&childrenBuf, def->chassis);
|
break;
|
||||||
virSysinfoProcessorFormat(&childrenBuf, def);
|
case VIR_SYSINFO_FWCFG:
|
||||||
virSysinfoMemoryFormat(&childrenBuf, def);
|
virSysinfoFormatFWCfg(&childrenBuf, def);
|
||||||
virSysinfoOEMStringsFormat(&childrenBuf, def->oemStrings);
|
break;
|
||||||
|
case VIR_SYSINFO_LAST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
virBufferAsprintf(&attrBuf, " type='%s'", type);
|
virBufferAsprintf(&attrBuf, " type='%s'", type);
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_SYSINFO_SMBIOS,
|
VIR_SYSINFO_SMBIOS,
|
||||||
|
VIR_SYSINFO_FWCFG,
|
||||||
|
|
||||||
VIR_SYSINFO_LAST
|
VIR_SYSINFO_LAST
|
||||||
} virSysinfoType;
|
} virSysinfoType;
|
||||||
@ -112,11 +113,20 @@ struct _virSysinfoOEMStringsDef {
|
|||||||
char **values;
|
char **values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virSysinfoFWCfgDef virSysinfoFWCfgDef;
|
||||||
|
typedef virSysinfoFWCfgDef *virSysinfoFWCfgDefPtr;
|
||||||
|
struct _virSysinfoFWCfgDef {
|
||||||
|
char *name;
|
||||||
|
char *value;
|
||||||
|
char *file;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _virSysinfoDef virSysinfoDef;
|
typedef struct _virSysinfoDef virSysinfoDef;
|
||||||
typedef virSysinfoDef *virSysinfoDefPtr;
|
typedef virSysinfoDef *virSysinfoDefPtr;
|
||||||
struct _virSysinfoDef {
|
struct _virSysinfoDef {
|
||||||
int type;
|
virSysinfoType type;
|
||||||
|
|
||||||
|
/* The following members are valid for type == VIR_SYSINFO_SMBIOS */
|
||||||
virSysinfoBIOSDefPtr bios;
|
virSysinfoBIOSDefPtr bios;
|
||||||
virSysinfoSystemDefPtr system;
|
virSysinfoSystemDefPtr system;
|
||||||
|
|
||||||
@ -132,6 +142,10 @@ struct _virSysinfoDef {
|
|||||||
virSysinfoMemoryDefPtr memory;
|
virSysinfoMemoryDefPtr memory;
|
||||||
|
|
||||||
virSysinfoOEMStringsDefPtr oemStrings;
|
virSysinfoOEMStringsDefPtr oemStrings;
|
||||||
|
|
||||||
|
/* The following members are valid for type == VIR_SYSINFO_FWCFG */
|
||||||
|
size_t nfw_cfgs;
|
||||||
|
virSysinfoFWCfgDefPtr fw_cfgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
virSysinfoDefPtr virSysinfoRead(void);
|
virSysinfoDefPtr virSysinfoRead(void);
|
||||||
|
63
tests/qemuxml2argvdata/smbios-type-fwcfg.xml
Normal file
63
tests/qemuxml2argvdata/smbios-type-fwcfg.xml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>219100</memory>
|
||||||
|
<currentMemory unit='KiB'>219100</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<sysinfo type='smbios'>
|
||||||
|
<bios>
|
||||||
|
<entry name='vendor'>LENOVO</entry>
|
||||||
|
<entry name='version'>6FET82WW (3.12 )</entry>
|
||||||
|
</bios>
|
||||||
|
<system>
|
||||||
|
<entry name='manufacturer'>Fedora</entry>
|
||||||
|
<entry name='product'>Virt-Manager</entry>
|
||||||
|
<entry name='version'>0.8.2-3.fc14</entry>
|
||||||
|
<entry name='serial'>32dfcb37-5af1-552b-357c-be8c3aa38310</entry>
|
||||||
|
<entry name='uuid'>c7a5fdbd-edaf-9455-926a-d65c16db1809</entry>
|
||||||
|
<entry name='sku'>1234567890</entry>
|
||||||
|
<entry name='family'>Red Hat</entry>
|
||||||
|
</system>
|
||||||
|
<baseBoard>
|
||||||
|
<entry name='manufacturer'>Lenovo</entry>
|
||||||
|
<entry name='product'>20BE0061MC</entry>
|
||||||
|
<entry name='version'>0B98401 Pro</entry>
|
||||||
|
<entry name='serial'>W1KS427111E</entry>
|
||||||
|
<entry name='location'>Not Available</entry>
|
||||||
|
</baseBoard>
|
||||||
|
</sysinfo>
|
||||||
|
<sysinfo type='fwcfg'>
|
||||||
|
<entry name='opt/com.example/name'>example value</entry>
|
||||||
|
<entry name='opt/com.coreos/config' file='/tmp/provision.ign'/>
|
||||||
|
</sysinfo>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
<smbios mode='sysinfo'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu-system-i386</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<driver name='qemu' type='raw'/>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='ide' index='0'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='0'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<input type='mouse' bus='ps2'/>
|
||||||
|
<input type='keyboard' bus='ps2'/>
|
||||||
|
<memballoon model='virtio'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
||||||
|
</memballoon>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
1
tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml
Symbolic link
1
tests/qemuxml2xmloutdata/smbios-type-fwcfg.xml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../qemuxml2argvdata/smbios-type-fwcfg.xml
|
@ -1125,6 +1125,7 @@ mymain(void)
|
|||||||
DO_TEST("shmem-plain-doorbell", NONE);
|
DO_TEST("shmem-plain-doorbell", NONE);
|
||||||
DO_TEST("smbios", NONE);
|
DO_TEST("smbios", NONE);
|
||||||
DO_TEST("smbios-multiple-type2", NONE);
|
DO_TEST("smbios-multiple-type2", NONE);
|
||||||
|
DO_TEST("smbios-type-fwcfg", NONE);
|
||||||
|
|
||||||
DO_TEST_CAPS_LATEST("os-firmware-bios");
|
DO_TEST_CAPS_LATEST("os-firmware-bios");
|
||||||
DO_TEST_CAPS_LATEST("os-firmware-efi");
|
DO_TEST_CAPS_LATEST("os-firmware-efi");
|
||||||
|
Loading…
Reference in New Issue
Block a user