246 lines
7.8 KiB
Diff
246 lines
7.8 KiB
Diff
|
commit 68eed56b2d51e66bb540062fe09f5ffd44e99f6e
|
||
|
Author: Daniel P. Berrange <berrange@redhat.com>
|
||
|
Date: Sat Oct 28 14:56:51 2017 +0100
|
||
|
|
||
|
conf: add support for setting OEM strings SMBIOS data fields
|
||
|
|
||
|
The OEM strings table in SMBIOS allows the vendor to pass arbitrary
|
||
|
strings into the guest OS. This can be used as a way to pass data to an
|
||
|
application like cloud-init, or potentially as an alternative to the
|
||
|
kernel command line for OS installers where you can't modify the install
|
||
|
ISO image to change the kernel args.
|
||
|
|
||
|
As an example, consider if cloud-init and anaconda supported OEM strings
|
||
|
you could use something like
|
||
|
|
||
|
<oemStrings>
|
||
|
<entry>cloud-init:ds=nocloud-net;s=http://10.10.0.1:8000/</entry>
|
||
|
<entry>anaconda:method=http://dl.fedoraproject.org/pub/fedora/linux/releases/25/x86_64/os</entry>
|
||
|
</oemStrings>
|
||
|
|
||
|
use of a application specific prefix as illustrated above is
|
||
|
recommended, but not mandated, so that an app can reliably identify
|
||
|
which of the many OEM strings are targetted at it.
|
||
|
|
||
|
Reviewed-by: John Ferlan <jferlan@redhat.com>
|
||
|
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||
|
|
||
|
Index: libvirt-4.0.0/docs/formatdomain.html.in
|
||
|
===================================================================
|
||
|
--- libvirt-4.0.0.orig/docs/formatdomain.html.in
|
||
|
+++ libvirt-4.0.0/docs/formatdomain.html.in
|
||
|
@@ -411,6 +411,10 @@
|
||
|
<entry name='version'>0B98401 Pro</entry>
|
||
|
<entry name='serial'>W1KS427111E</entry>
|
||
|
</baseBoard>
|
||
|
+ <oemStrings>
|
||
|
+ <entry>myappname:some arbitrary data</entry>
|
||
|
+ <entry>otherappname:more arbitrary data</entry>
|
||
|
+ </oemStrings>
|
||
|
</sysinfo>
|
||
|
...</pre>
|
||
|
|
||
|
@@ -498,6 +502,15 @@
|
||
|
validation and <code>date</code> format checking, all values are
|
||
|
passed as strings to the hypervisor driver.
|
||
|
</dd>
|
||
|
+ <dt><code>oemStrings</code></dt>
|
||
|
+ <dd>
|
||
|
+ This is block 11 of SMBIOS. This element should appear once and
|
||
|
+ can have multiple <code>entry</code> child elements, each providing
|
||
|
+ arbitrary string data. There are no restrictions on what data can
|
||
|
+ be provided in the entries, however, if the data is intended to be
|
||
|
+ consumed by an application in the guest, it is recommended to use
|
||
|
+ the application name as a prefix in the string. (<span class="since">Since 4.1.0</span>)
|
||
|
+ </dd>
|
||
|
</dl>
|
||
|
</dd>
|
||
|
</dl>
|
||
|
Index: libvirt-4.0.0/docs/schemas/domaincommon.rng
|
||
|
===================================================================
|
||
|
--- libvirt-4.0.0.orig/docs/schemas/domaincommon.rng
|
||
|
+++ libvirt-4.0.0/docs/schemas/domaincommon.rng
|
||
|
@@ -4857,6 +4857,15 @@
|
||
|
</oneOrMore>
|
||
|
</element>
|
||
|
</zeroOrMore>
|
||
|
+ <optional>
|
||
|
+ <element name="oemStrings">
|
||
|
+ <oneOrMore>
|
||
|
+ <element name="entry">
|
||
|
+ <ref name="sysinfo-value"/>
|
||
|
+ </element>
|
||
|
+ </oneOrMore>
|
||
|
+ </element>
|
||
|
+ </optional>
|
||
|
</interleave>
|
||
|
</element>
|
||
|
</define>
|
||
|
Index: libvirt-4.0.0/src/conf/domain_conf.c
|
||
|
===================================================================
|
||
|
--- libvirt-4.0.0.orig/src/conf/domain_conf.c
|
||
|
+++ libvirt-4.0.0/src/conf/domain_conf.c
|
||
|
@@ -14461,6 +14461,42 @@ virSysinfoBaseBoardParseXML(xmlXPathCont
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+static int
|
||
|
+virSysinfoOEMStringsParseXML(xmlXPathContextPtr ctxt,
|
||
|
+ virSysinfoOEMStringsDefPtr *oem)
|
||
|
+{
|
||
|
+ int ret = -1;
|
||
|
+ virSysinfoOEMStringsDefPtr def;
|
||
|
+ xmlNodePtr *strings = NULL;
|
||
|
+ int nstrings;
|
||
|
+ size_t i;
|
||
|
+
|
||
|
+ nstrings = virXPathNodeSet("./entry", ctxt, &strings);
|
||
|
+ if (nstrings < 0)
|
||
|
+ return -1;
|
||
|
+ if (nstrings == 0)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ if (VIR_ALLOC(def) < 0)
|
||
|
+ goto cleanup;
|
||
|
+
|
||
|
+ if (VIR_ALLOC_N(def->values, nstrings) < 0)
|
||
|
+ goto cleanup;
|
||
|
+
|
||
|
+ def->nvalues = nstrings;
|
||
|
+ for (i = 0; i < nstrings; i++)
|
||
|
+ def->values[i] = virXMLNodeContentString(strings[i]);
|
||
|
+
|
||
|
+ *oem = def;
|
||
|
+ def = NULL;
|
||
|
+ ret = 0;
|
||
|
+ cleanup:
|
||
|
+ VIR_FREE(strings);
|
||
|
+ virSysinfoOEMStringsDefFree(def);
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static virSysinfoDefPtr
|
||
|
virSysinfoParseXML(xmlNodePtr node,
|
||
|
xmlXPathContextPtr ctxt,
|
||
|
@@ -14519,6 +14555,17 @@ virSysinfoParseXML(xmlNodePtr node,
|
||
|
if (virSysinfoBaseBoardParseXML(ctxt, &def->baseBoard, &def->nbaseBoard) < 0)
|
||
|
goto error;
|
||
|
|
||
|
+ /* Extract system related metadata */
|
||
|
+ if ((tmpnode = virXPathNode("./oemStrings[1]", ctxt)) != NULL) {
|
||
|
+ oldnode = ctxt->node;
|
||
|
+ ctxt->node = tmpnode;
|
||
|
+ if (virSysinfoOEMStringsParseXML(ctxt, &def->oemStrings) < 0) {
|
||
|
+ ctxt->node = oldnode;
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+ ctxt->node = oldnode;
|
||
|
+ }
|
||
|
+
|
||
|
cleanup:
|
||
|
VIR_FREE(type);
|
||
|
return def;
|
||
|
Index: libvirt-4.0.0/src/util/virsysinfo.c
|
||
|
===================================================================
|
||
|
--- libvirt-4.0.0.orig/src/util/virsysinfo.c
|
||
|
+++ libvirt-4.0.0/src/util/virsysinfo.c
|
||
|
@@ -108,6 +108,20 @@ void virSysinfoBaseBoardDefClear(virSysi
|
||
|
VIR_FREE(def->location);
|
||
|
}
|
||
|
|
||
|
+void virSysinfoOEMStringsDefFree(virSysinfoOEMStringsDefPtr def)
|
||
|
+{
|
||
|
+ size_t i;
|
||
|
+
|
||
|
+ if (def == NULL)
|
||
|
+ return;
|
||
|
+
|
||
|
+ for (i = 0; i < def->nvalues; i++)
|
||
|
+ VIR_FREE(def->values[i]);
|
||
|
+ VIR_FREE(def->values);
|
||
|
+
|
||
|
+ VIR_FREE(def);
|
||
|
+}
|
||
|
+
|
||
|
/**
|
||
|
* virSysinfoDefFree:
|
||
|
* @def: a sysinfo structure
|
||
|
@@ -157,6 +171,8 @@ void virSysinfoDefFree(virSysinfoDefPtr
|
||
|
}
|
||
|
VIR_FREE(def->memory);
|
||
|
|
||
|
+ virSysinfoOEMStringsDefFree(def->oemStrings);
|
||
|
+
|
||
|
VIR_FREE(def);
|
||
|
}
|
||
|
|
||
|
@@ -1294,6 +1310,24 @@ virSysinfoMemoryFormat(virBufferPtr buf,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+static void
|
||
|
+virSysinfoOEMStringsFormat(virBufferPtr buf, virSysinfoOEMStringsDefPtr def)
|
||
|
+{
|
||
|
+ size_t i;
|
||
|
+
|
||
|
+ if (!def)
|
||
|
+ return;
|
||
|
+
|
||
|
+ virBufferAddLit(buf, "<oemStrings>\n");
|
||
|
+ virBufferAdjustIndent(buf, 2);
|
||
|
+ for (i = 0; i < def->nvalues; i++) {
|
||
|
+ virBufferEscapeString(buf, "<entry>%s</entry>\n",
|
||
|
+ def->values[i]);
|
||
|
+ }
|
||
|
+ virBufferAdjustIndent(buf, -2);
|
||
|
+ virBufferAddLit(buf, "</oemStrings>\n");
|
||
|
+}
|
||
|
+
|
||
|
/**
|
||
|
* virSysinfoFormat:
|
||
|
* @buf: buffer to append output to (may use auto-indentation)
|
||
|
@@ -1324,6 +1358,7 @@ virSysinfoFormat(virBufferPtr buf, virSy
|
||
|
virSysinfoBaseBoardFormat(&childrenBuf, def->baseBoard, def->nbaseBoard);
|
||
|
virSysinfoProcessorFormat(&childrenBuf, def);
|
||
|
virSysinfoMemoryFormat(&childrenBuf, def);
|
||
|
+ virSysinfoOEMStringsFormat(&childrenBuf, def->oemStrings);
|
||
|
|
||
|
virBufferAsprintf(buf, "<sysinfo type='%s'", type);
|
||
|
if (virBufferUse(&childrenBuf)) {
|
||
|
Index: libvirt-4.0.0/src/util/virsysinfo.h
|
||
|
===================================================================
|
||
|
--- libvirt-4.0.0.orig/src/util/virsysinfo.h
|
||
|
+++ libvirt-4.0.0/src/util/virsysinfo.h
|
||
|
@@ -98,6 +98,13 @@ struct _virSysinfoBaseBoardDef {
|
||
|
/* XXX board type */
|
||
|
};
|
||
|
|
||
|
+typedef struct _virSysinfoOEMStringsDef virSysinfoOEMStringsDef;
|
||
|
+typedef virSysinfoOEMStringsDef *virSysinfoOEMStringsDefPtr;
|
||
|
+struct _virSysinfoOEMStringsDef {
|
||
|
+ size_t nvalues;
|
||
|
+ char **values;
|
||
|
+};
|
||
|
+
|
||
|
typedef struct _virSysinfoDef virSysinfoDef;
|
||
|
typedef virSysinfoDef *virSysinfoDefPtr;
|
||
|
struct _virSysinfoDef {
|
||
|
@@ -114,6 +121,8 @@ struct _virSysinfoDef {
|
||
|
|
||
|
size_t nmemory;
|
||
|
virSysinfoMemoryDefPtr memory;
|
||
|
+
|
||
|
+ virSysinfoOEMStringsDefPtr oemStrings;
|
||
|
};
|
||
|
|
||
|
virSysinfoDefPtr virSysinfoRead(void);
|
||
|
@@ -121,6 +130,7 @@ virSysinfoDefPtr virSysinfoRead(void);
|
||
|
void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def);
|
||
|
void virSysinfoSystemDefFree(virSysinfoSystemDefPtr def);
|
||
|
void virSysinfoBaseBoardDefClear(virSysinfoBaseBoardDefPtr def);
|
||
|
+void virSysinfoOEMStringsDefFree(virSysinfoOEMStringsDefPtr def);
|
||
|
void virSysinfoDefFree(virSysinfoDefPtr def);
|
||
|
|
||
|
int virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
|