提交 c8fec256 编写于 作者: Z Zhuang Yanying 提交者: John Ferlan

conf: Add support for setting Chassis SMBIOS data fields

This type of information defines attributes of a system
chassis, such as SMBIOS Chassis Asset Tag.

access inside VM (for example)
Linux:   /sys/class/dmi/id/chassis_asset_tag.
Windows: (Get-WmiObject Win32_SystemEnclosure).SMBIOSAssetTag
          wirhin Windows PowerShell.

As an example, add the following to the guest XML

    <chassis>
      <entry name='manufacturer'>Dell Inc.</entry>
      <entry name='version'>2.12</entry>
      <entry name='serial'>65X0XF2</entry>
      <entry name='asset'>40000101</entry>
      <entry name='sku'>Type3Sku1</entry>
    </chassis>
Signed-off-by: NZhuang Yanying <ann.zhuangyanying@huawei.com>
Reviewed-by: NJohn Ferlan <jferlan@redhat.com>
上级 91482930
...@@ -411,6 +411,13 @@ ...@@ -411,6 +411,13 @@
&lt;entry name='version'&gt;0B98401 Pro&lt;/entry&gt; &lt;entry name='version'&gt;0B98401 Pro&lt;/entry&gt;
&lt;entry name='serial'&gt;W1KS427111E&lt;/entry&gt; &lt;entry name='serial'&gt;W1KS427111E&lt;/entry&gt;
&lt;/baseBoard&gt; &lt;/baseBoard&gt;
&lt;chassis&gt;
&lt;entry name='manufacturer'&gt;Dell Inc.&lt;/entry&gt;
&lt;entry name='version'&gt;2.12&lt;/entry&gt;
&lt;entry name='serial'&gt;65X0XF2&lt;/entry&gt;
&lt;entry name='asset'&gt;40000101&lt;/entry&gt;
&lt;entry name='sku'&gt;Type3Sku1&lt;/entry&gt;
&lt;/chassis&gt;
&lt;oemStrings&gt; &lt;oemStrings&gt;
&lt;entry&gt;myappname:some arbitrary data&lt;/entry&gt; &lt;entry&gt;myappname:some arbitrary data&lt;/entry&gt;
&lt;entry&gt;otherappname:more arbitrary data&lt;/entry&gt; &lt;entry&gt;otherappname:more arbitrary data&lt;/entry&gt;
...@@ -502,6 +509,23 @@ ...@@ -502,6 +509,23 @@
validation and <code>date</code> format checking, all values are validation and <code>date</code> format checking, all values are
passed as strings to the hypervisor driver. passed as strings to the hypervisor driver.
</dd> </dd>
<dt><code>chassis</code></dt>
<dd>
<span class="since">Since 4.1.0,</span> this is block 3 of
SMBIOS, with entry names drawn from:
<dl>
<dt><code>manufacturer</code></dt>
<dd>Manufacturer of Chassis</dd>
<dt><code>version</code></dt>
<dd>Version of the Chassis</dd>
<dt><code>serial</code></dt>
<dd>Serial number</dd>
<dt><code>asset</code></dt>
<dd>Asset tag</dd>
<dt><code>sku</code></dt>
<dd>SKU number</dd>
</dl>
</dd>
<dt><code>oemStrings</code></dt> <dt><code>oemStrings</code></dt>
<dd> <dd>
This is block 11 of SMBIOS. This element should appear once and This is block 11 of SMBIOS. This element should appear once and
......
...@@ -4895,6 +4895,18 @@ ...@@ -4895,6 +4895,18 @@
</oneOrMore> </oneOrMore>
</element> </element>
</zeroOrMore> </zeroOrMore>
<optional>
<element name="chassis">
<oneOrMore>
<element name="entry">
<attribute name="name">
<ref name="sysinfo-chassis-name"/>
</attribute>
<ref name="sysinfo-value"/>
</element>
</oneOrMore>
</element>
</optional>
<optional> <optional>
<element name="oemStrings"> <element name="oemStrings">
<oneOrMore> <oneOrMore>
...@@ -4940,6 +4952,16 @@ ...@@ -4940,6 +4952,16 @@
</choice> </choice>
</define> </define>
<define name="sysinfo-chassis-name">
<choice>
<value>manufacturer</value>
<value>version</value>
<value>serial</value>
<value>asset</value>
<value>sku</value>
</choice>
</define>
<define name="sysinfo-value"> <define name="sysinfo-value">
<data type="string"/> <data type="string"/>
</define> </define>
......
...@@ -14543,6 +14543,50 @@ virSysinfoOEMStringsParseXML(xmlXPathContextPtr ctxt, ...@@ -14543,6 +14543,50 @@ virSysinfoOEMStringsParseXML(xmlXPathContextPtr ctxt,
return ret; return ret;
} }
static int
virSysinfoChassisParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
virSysinfoChassisDefPtr *chassisdef)
{
int ret = -1;
virSysinfoChassisDefPtr def;
if (!xmlStrEqual(node->name, BAD_CAST "chassis")) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("XML does not contain expected 'chassis' element"));
return ret;
}
if (VIR_ALLOC(def) < 0)
goto cleanup;
def->manufacturer =
virXPathString("string(entry[@name='manufacturer'])", ctxt);
def->version =
virXPathString("string(entry[@name='version'])", ctxt);
def->serial =
virXPathString("string(entry[@name='serial'])", ctxt);
def->asset =
virXPathString("string(entry[@name='asset'])", ctxt);
def->sku =
virXPathString("string(entry[@name='sku'])", ctxt);
if (!def->manufacturer && !def->version &&
!def->serial && !def->asset && !def->sku) {
virSysinfoChassisDefFree(def);
def = NULL;
}
*chassisdef = def;
def = NULL;
ret = 0;
cleanup:
virSysinfoChassisDefFree(def);
return ret;
}
static virSysinfoDefPtr static virSysinfoDefPtr
virSysinfoParseXML(xmlNodePtr node, virSysinfoParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
...@@ -14601,6 +14645,17 @@ virSysinfoParseXML(xmlNodePtr node, ...@@ -14601,6 +14645,17 @@ virSysinfoParseXML(xmlNodePtr node,
if (virSysinfoBaseBoardParseXML(ctxt, &def->baseBoard, &def->nbaseBoard) < 0) if (virSysinfoBaseBoardParseXML(ctxt, &def->baseBoard, &def->nbaseBoard) < 0)
goto error; goto error;
/* Extract chassis related metadata */
if ((tmpnode = virXPathNode("./chassis[1]", ctxt)) != NULL) {
oldnode = ctxt->node;
ctxt->node = tmpnode;
if (virSysinfoChassisParseXML(tmpnode, ctxt, &def->chassis) < 0) {
ctxt->node = oldnode;
goto error;
}
ctxt->node = oldnode;
}
/* Extract system related metadata */ /* Extract system related metadata */
if ((tmpnode = virXPathNode("./oemStrings[1]", ctxt)) != NULL) { if ((tmpnode = virXPathNode("./oemStrings[1]", ctxt)) != NULL) {
oldnode = ctxt->node; oldnode = ctxt->node;
......
...@@ -2862,6 +2862,7 @@ virVasprintfInternal; ...@@ -2862,6 +2862,7 @@ virVasprintfInternal;
# util/virsysinfo.h # util/virsysinfo.h
virSysinfoBaseBoardDefClear; virSysinfoBaseBoardDefClear;
virSysinfoBIOSDefFree; virSysinfoBIOSDefFree;
virSysinfoChassisDefFree;
virSysinfoDefFree; virSysinfoDefFree;
virSysinfoFormat; virSysinfoFormat;
virSysinfoRead; virSysinfoRead;
......
...@@ -108,6 +108,21 @@ void virSysinfoBaseBoardDefClear(virSysinfoBaseBoardDefPtr def) ...@@ -108,6 +108,21 @@ void virSysinfoBaseBoardDefClear(virSysinfoBaseBoardDefPtr def)
VIR_FREE(def->location); VIR_FREE(def->location);
} }
void virSysinfoChassisDefFree(virSysinfoChassisDefPtr def)
{
if (def == NULL)
return;
VIR_FREE(def->manufacturer);
VIR_FREE(def->version);
VIR_FREE(def->serial);
VIR_FREE(def->asset);
VIR_FREE(def->sku);
VIR_FREE(def);
}
void virSysinfoOEMStringsDefFree(virSysinfoOEMStringsDefPtr def) void virSysinfoOEMStringsDefFree(virSysinfoOEMStringsDefPtr def)
{ {
size_t i; size_t i;
...@@ -143,6 +158,8 @@ void virSysinfoDefFree(virSysinfoDefPtr def) ...@@ -143,6 +158,8 @@ void virSysinfoDefFree(virSysinfoDefPtr def)
virSysinfoBaseBoardDefClear(def->baseBoard + i); virSysinfoBaseBoardDefClear(def->baseBoard + i);
VIR_FREE(def->baseBoard); VIR_FREE(def->baseBoard);
virSysinfoChassisDefFree(def->chassis);
for (i = 0; i < def->nprocessor; i++) { for (i = 0; i < def->nprocessor; i++) {
VIR_FREE(def->processor[i].processor_socket_destination); VIR_FREE(def->processor[i].processor_socket_destination);
VIR_FREE(def->processor[i].processor_type); VIR_FREE(def->processor[i].processor_type);
...@@ -825,6 +842,68 @@ virSysinfoParseX86BaseBoard(const char *base, ...@@ -825,6 +842,68 @@ virSysinfoParseX86BaseBoard(const char *base,
return ret; return ret;
} }
static int
virSysinfoParseX86Chassis(const char *base,
virSysinfoChassisDefPtr *chassisdef)
{
int ret = -1;
const char *cur, *eol = NULL;
virSysinfoChassisDefPtr def;
if ((cur = strstr(base, "Chassis Information")) == NULL)
return 0;
if (VIR_ALLOC(def) < 0)
return ret;
base = cur;
if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
cur += 14;
eol = strchr(cur, '\n');
if (eol && VIR_STRNDUP(def->manufacturer, cur, eol - cur) < 0)
goto cleanup;
}
if ((cur = strstr(base, "Version: ")) != NULL) {
cur += 9;
eol = strchr(cur, '\n');
if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
goto cleanup;
}
if ((cur = strstr(base, "Serial Number: ")) != NULL) {
cur += 15;
eol = strchr(cur, '\n');
if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
goto cleanup;
}
if ((cur = strstr(base, "Asset Tag: ")) != NULL) {
cur += 11;
eol = strchr(cur, '\n');
if (eol && VIR_STRNDUP(def->sku, cur, eol - cur) < 0)
goto cleanup;
}
if ((cur = strstr(base, "SKU Number: ")) != NULL) {
cur += 12;
eol = strchr(cur, '\n');
if (eol && VIR_STRNDUP(def->sku, cur, eol - cur) < 0)
goto cleanup;
}
if (!def->manufacturer && !def->version &&
!def->serial && !def->asset && !def->sku) {
virSysinfoChassisDefFree(def);
def = NULL;
}
*chassisdef = def;
def = NULL;
ret = 0;
cleanup:
virSysinfoChassisDefFree(def);
return ret;
}
static int static int
virSysinfoParseX86Processor(const char *base, virSysinfoDefPtr ret) virSysinfoParseX86Processor(const char *base, virSysinfoDefPtr ret)
{ {
...@@ -1047,7 +1126,7 @@ virSysinfoReadX86(void) ...@@ -1047,7 +1126,7 @@ virSysinfoReadX86(void)
return NULL; return NULL;
} }
cmd = virCommandNewArgList(path, "-q", "-t", "0,1,2,4,17", NULL); cmd = virCommandNewArgList(path, "-q", "-t", "0,1,2,3,4,17", NULL);
VIR_FREE(path); VIR_FREE(path);
virCommandSetOutputBuffer(cmd, &outbuf); virCommandSetOutputBuffer(cmd, &outbuf);
if (virCommandRun(cmd, NULL) < 0) if (virCommandRun(cmd, NULL) < 0)
...@@ -1067,6 +1146,9 @@ virSysinfoReadX86(void) ...@@ -1067,6 +1146,9 @@ virSysinfoReadX86(void)
if (virSysinfoParseX86BaseBoard(outbuf, &ret->baseBoard, &ret->nbaseBoard) < 0) if (virSysinfoParseX86BaseBoard(outbuf, &ret->baseBoard, &ret->nbaseBoard) < 0)
goto error; goto error;
if (virSysinfoParseX86Chassis(outbuf, &ret->chassis) < 0)
goto error;
ret->nprocessor = 0; ret->nprocessor = 0;
ret->processor = NULL; ret->processor = NULL;
if (virSysinfoParseX86Processor(outbuf, ret) < 0) if (virSysinfoParseX86Processor(outbuf, ret) < 0)
...@@ -1202,6 +1284,31 @@ virSysinfoBaseBoardFormat(virBufferPtr buf, ...@@ -1202,6 +1284,31 @@ virSysinfoBaseBoardFormat(virBufferPtr buf,
} }
} }
static void
virSysinfoChassisFormat(virBufferPtr buf,
virSysinfoChassisDefPtr def)
{
if (!def)
return;
virBufferAddLit(buf, "<chassis>\n");
virBufferAdjustIndent(buf, 2);
virBufferEscapeString(buf, "<entry name='manufacturer'>%s</entry>\n",
def->manufacturer);
virBufferEscapeString(buf, "<entry name='version'>%s</entry>\n",
def->version);
virBufferEscapeString(buf, "<entry name='serial'>%s</entry>\n",
def->serial);
virBufferEscapeString(buf, "<entry name='asset'>%s</entry>\n",
def->asset);
virBufferEscapeString(buf, "<entry name='sku'>%s</entry>\n",
def->sku);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</chassis>\n");
}
static void static void
virSysinfoProcessorFormat(virBufferPtr buf, virSysinfoDefPtr def) virSysinfoProcessorFormat(virBufferPtr buf, virSysinfoDefPtr def)
{ {
...@@ -1354,6 +1461,7 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def) ...@@ -1354,6 +1461,7 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
virSysinfoBIOSFormat(&childrenBuf, def->bios); virSysinfoBIOSFormat(&childrenBuf, def->bios);
virSysinfoSystemFormat(&childrenBuf, def->system); virSysinfoSystemFormat(&childrenBuf, def->system);
virSysinfoBaseBoardFormat(&childrenBuf, def->baseBoard, def->nbaseBoard); virSysinfoBaseBoardFormat(&childrenBuf, def->baseBoard, def->nbaseBoard);
virSysinfoChassisFormat(&childrenBuf, def->chassis);
virSysinfoProcessorFormat(&childrenBuf, def); virSysinfoProcessorFormat(&childrenBuf, def);
virSysinfoMemoryFormat(&childrenBuf, def); virSysinfoMemoryFormat(&childrenBuf, def);
virSysinfoOEMStringsFormat(&childrenBuf, def->oemStrings); virSysinfoOEMStringsFormat(&childrenBuf, def->oemStrings);
...@@ -1466,6 +1574,34 @@ virSysinfoBaseBoardIsEqual(virSysinfoBaseBoardDefPtr src, ...@@ -1466,6 +1574,34 @@ virSysinfoBaseBoardIsEqual(virSysinfoBaseBoardDefPtr src,
return identical; return identical;
} }
static bool
virSysinfoChassisIsEqual(virSysinfoChassisDefPtr src,
virSysinfoChassisDefPtr dst)
{
bool identical = false;
if (!src && !dst)
return true;
if ((src && !dst) || (!src && dst)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Target chassis does not match source"));
goto cleanup;
}
CHECK_FIELD(manufacturer, "chassis vendor");
CHECK_FIELD(version, "chassis version");
CHECK_FIELD(serial, "chassis serial");
CHECK_FIELD(asset, "chassis asset");
CHECK_FIELD(sku, "chassis sku");
identical = true;
cleanup:
return identical;
}
#undef CHECK_FIELD #undef CHECK_FIELD
bool virSysinfoIsEqual(virSysinfoDefPtr src, bool virSysinfoIsEqual(virSysinfoDefPtr src,
...@@ -1509,6 +1645,9 @@ bool virSysinfoIsEqual(virSysinfoDefPtr src, ...@@ -1509,6 +1645,9 @@ bool virSysinfoIsEqual(virSysinfoDefPtr src,
dst->baseBoard + i)) dst->baseBoard + i))
goto cleanup; goto cleanup;
if (!virSysinfoChassisIsEqual(src->chassis, dst->chassis))
goto cleanup;
identical = true; identical = true;
cleanup: cleanup:
......
...@@ -98,6 +98,16 @@ struct _virSysinfoBaseBoardDef { ...@@ -98,6 +98,16 @@ struct _virSysinfoBaseBoardDef {
/* XXX board type */ /* XXX board type */
}; };
typedef struct _virSysinfoChassisDef virSysinfoChassisDef;
typedef virSysinfoChassisDef *virSysinfoChassisDefPtr;
struct _virSysinfoChassisDef {
char *manufacturer;
char *version;
char *serial;
char *asset;
char *sku;
};
typedef struct _virSysinfoOEMStringsDef virSysinfoOEMStringsDef; typedef struct _virSysinfoOEMStringsDef virSysinfoOEMStringsDef;
typedef virSysinfoOEMStringsDef *virSysinfoOEMStringsDefPtr; typedef virSysinfoOEMStringsDef *virSysinfoOEMStringsDefPtr;
struct _virSysinfoOEMStringsDef { struct _virSysinfoOEMStringsDef {
...@@ -116,6 +126,8 @@ struct _virSysinfoDef { ...@@ -116,6 +126,8 @@ struct _virSysinfoDef {
size_t nbaseBoard; size_t nbaseBoard;
virSysinfoBaseBoardDefPtr baseBoard; virSysinfoBaseBoardDefPtr baseBoard;
virSysinfoChassisDefPtr chassis;
size_t nprocessor; size_t nprocessor;
virSysinfoProcessorDefPtr processor; virSysinfoProcessorDefPtr processor;
...@@ -130,6 +142,7 @@ virSysinfoDefPtr virSysinfoRead(void); ...@@ -130,6 +142,7 @@ virSysinfoDefPtr virSysinfoRead(void);
void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def); void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def);
void virSysinfoSystemDefFree(virSysinfoSystemDefPtr def); void virSysinfoSystemDefFree(virSysinfoSystemDefPtr def);
void virSysinfoBaseBoardDefClear(virSysinfoBaseBoardDefPtr def); void virSysinfoBaseBoardDefClear(virSysinfoBaseBoardDefPtr def);
void virSysinfoChassisDefFree(virSysinfoChassisDefPtr def);
void virSysinfoOEMStringsDefFree(virSysinfoOEMStringsDefPtr def); void virSysinfoOEMStringsDefFree(virSysinfoOEMStringsDefPtr def);
void virSysinfoDefFree(virSysinfoDefPtr def); void virSysinfoDefFree(virSysinfoDefPtr def);
......
...@@ -26,6 +26,13 @@ ...@@ -26,6 +26,13 @@
<entry name='asset'>CZC1065993</entry> <entry name='asset'>CZC1065993</entry>
<entry name='location'>Upside down</entry> <entry name='location'>Upside down</entry>
</baseBoard> </baseBoard>
<chassis>
<entry name='manufacturer'>Dell Inc.</entry>
<entry name='version'>2.12</entry>
<entry name='serial'>65X0XF2</entry>
<entry name='asset'>40000101</entry>
<entry name='sku'>Type3Sku1</entry>
</chassis>
<oemStrings> <oemStrings>
<entry>Hello</entry> <entry>Hello</entry>
<entry>World</entry> <entry>World</entry>
......
...@@ -26,6 +26,13 @@ ...@@ -26,6 +26,13 @@
<entry name='asset'>CZC1065993</entry> <entry name='asset'>CZC1065993</entry>
<entry name='location'>Upside down</entry> <entry name='location'>Upside down</entry>
</baseBoard> </baseBoard>
<chassis>
<entry name='manufacturer'>Dell Inc.</entry>
<entry name='version'>2.12</entry>
<entry name='serial'>65X0XF2</entry>
<entry name='asset'>40000101</entry>
<entry name='sku'>Type3Sku1</entry>
</chassis>
<oemStrings> <oemStrings>
<entry>Hello</entry> <entry>Hello</entry>
<entry>World</entry> <entry>World</entry>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册