[libvirt] [PATCH] 0/4 Add SMBIOS settings to domain definition

The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations. Spec available at the DMTF: http://dmtf.org/standards/smbios From a virtualization POV, it's mostly the first block describing the BIOS named "type 0" and the second block describing the machine named "type 1" which are of interest. Those data are usually accessed either from the OS or from management application, and being able to override the default setings may be needed for such management. The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea: <smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios> The patch serie includes: - the change to the doamin schemas - the code to parse this in config structure - the QEmu driver part - a test example Currently missing is the conf code to save the data back, and documentation for the domain extension. I think it's possible set some of those settings in Xen too, but I don't know if I will take the time of a driver for it. For ESX it seems there is an option to inherit some of the SMBIOS data from the host on the guest but I'm not sure some of the fields can be manipulated directly. I don't know what VirtualBox can set there either, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea: <smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios> I didn't tried in the RNG and in the conf parser in general to wire down the description to the very limited set actually allowed by QEmu, but tried to stay generic. However a lot of the smbios data has 'no serviceable parts' inside, and is mostly a binary blob with various data encoded in binary, but I think the above model is sufficiently flexible and common to allow setting other various types of data. To avoid problems with space normalization in attribute values, I preferred to encode the entry content as text node chidren of entries rather than use an attribute. The name descriptions used by the standard are simple enough that they should not be a problem in attributes. In the schemas I currently limit to only type 0 and 1, I could remove that and limit to 0..32 since that's the set allowed by the spec, but other blocks are a priori harder to use in virtualization at least when and user describes a domain. Daniel diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index a934a77..a42961c 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -30,6 +30,9 @@ <optional> <ref name="cpu"/> </optional> + <optional> + <ref name="smbios"/> + </optional> <ref name="os"/> <ref name="clock"/> <ref name="resources"/> @@ -1746,6 +1749,51 @@ </element> </define> + <!-- + SMBIOS specification + The DMTF spec doesn't specify any string subset, just 0 terminated + byte strings, but better be safe and restrict at least the names + to avoid problems with space normalization in attribute values, + the value is kept as the element body for maximum flexibility. + A priori we allow only type 0 and type 1 string updates + --> + <define name="smbios"> + <element name="smbios"> + <zeroOrMore> + <element name="table"> + <attribute name="type"> + <ref name="smbios-type"/> + </attribute> + <oneOrMore> + <element name="entry"> + <attribute name="name"> + <ref name="smbios-name"/> + </attribute> + <ref name="smbios-value"/> + </element> + </oneOrMore> + </element> + </zeroOrMore> + </element> + </define> + + <define name="smbios-type"> + <data type="int"> + <param name="minInclusive">0</param> + <param name="maxInclusive">1</param> + </data> + </define> + + <define name="smbios-name"> + <data type="string"> + <param name='pattern'>[a-zA-Z0-9\-_\. ]+</param> + </data> + </define> + + <define name="smbios-value"> + <data type="string"/> + </define> + <define name="address"> <element name="address"> <choice> -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 10/21/2010 02:13 PM, Daniel Veillard wrote:
The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios>
Seems reasonable to me.
+<define name="smbios-name"> +<data type="string"> +<param name='pattern'>[a-zA-Z0-9\-_\. ]+</param> ^^^
Is that the range of characters from \ to _, or is just the two characters - and _?
Currently missing is the conf code to save the data back, and documentation for the domain extension.
Indeed. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Thu, Oct 21, 2010 at 03:35:37PM -0600, Eric Blake wrote:
On 10/21/2010 02:13 PM, Daniel Veillard wrote:
The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios>
Seems reasonable to me.
+<define name="smbios-name"> +<data type="string"> +<param name='pattern'>[a-zA-Z0-9\-_\. ]+</param> ^^^
Is that the range of characters from \ to _, or is just the two characters - and _?
just the two characters, \is an escape code to avoid the sequence
Currently missing is the conf code to save the data back, and documentation for the domain extension.
Indeed.
TODO :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

This lacks the saving of the smbios data, should not be hard really, and the parsing is rather trivial, the data structures follow the XML format: Daniel diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5499f28..9dff0f7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -606,6 +606,29 @@ struct _virDomainMemballoonDef { }; + +typedef struct _virSmbiosEntry virSmbiosEntry; +typedef virSmbiosEntry *virSmbiosEntryPtr; +struct _virSmbiosEntry { + virSmbiosEntryPtr next; + char *name; + char *value; +}; + +typedef struct _virSmbiosBlock virSmbiosBlock; +typedef virSmbiosBlock *virSmbiosBlockPtr; +struct _virSmbiosBlock { + unsigned int type; + virSmbiosEntryPtr entries; +}; + +typedef struct _virSmbiosDef virSmbiosDef; +typedef virSmbiosDef *virSmbiosDefPtr; +struct _virSmbiosDef { + unsigned int nbblocks; + virSmbiosBlockPtr *blocks; +}; + /* Flags for the 'type' field in next struct */ enum virDomainDeviceType { VIR_DOMAIN_DEVICE_DISK, @@ -943,6 +966,7 @@ struct _virDomainDef { virDomainWatchdogDefPtr watchdog; virDomainMemballoonDefPtr memballoon; virCPUDefPtr cpu; + virSmbiosDefPtr smbios; void *namespaceData; virDomainXMLNamespace ns; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a997e06..fd85398 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -712,6 +712,48 @@ virDomainClockDefClear(virDomainClockDefPtr def) VIR_FREE(def->timers); } +static void virSmbiosEntriesFree(virSmbiosEntryPtr cur) +{ + virSmbiosEntryPtr next; + + if (cur == NULL) + return; + + while (cur != NULL) { + next = cur->next; + + VIR_FREE(cur->name); + VIR_FREE(cur->value); + VIR_FREE(cur); + + cur = next; + } +} + +static void virSmbiosBlockFree(virSmbiosBlockPtr block) +{ + if (block == NULL) + return; + + virSmbiosEntriesFree(block->entries); + VIR_FREE(block); +} + +static void virSmbiosDefFree(virSmbiosDefPtr def) +{ + unsigned int i; + + if (def == NULL) + return; + + if (def->blocks != NULL) { + for (i = 0;i < def->nbblocks;i++) + virSmbiosBlockFree(def->blocks[i]); + VIR_FREE(def->blocks); + } + VIR_FREE(def); +} + void virDomainDefFree(virDomainDefPtr def) { unsigned int i; @@ -796,6 +838,8 @@ void virDomainDefFree(virDomainDefPtr def) virCPUDefFree(def->cpu); + virSmbiosDefFree(def->smbios); + if (def->namespaceData && def->ns.free) (def->ns.free)(def->namespaceData); @@ -3341,6 +3385,150 @@ error: goto cleanup; } +static virSmbiosEntryPtr +virSmbiosEntryParseXML(xmlXPathContextPtr ctxt) +{ + char *name, *value; + virSmbiosEntryPtr def; + + name = virXPathString("string(./@name)", ctxt); + if (name == NULL) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("XML element 'entry' requires a 'name' attrbute")); + return(NULL); + } + value = virXPathString("string(.)", ctxt); + if (value == NULL) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("failed to get content of element 'entry'")); + VIR_FREE(name); + return(NULL); + } + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + VIR_FREE(name); + VIR_FREE(value); + return(NULL); + } + def->name = name; + def->value = value; + def->next = NULL; + + return(def); +} + +static virSmbiosBlockPtr +virSmbiosBlockParseXML(xmlXPathContextPtr ctxt) +{ + virSmbiosBlockPtr def; + virSmbiosEntryPtr cur, next; + xmlNodePtr *nodes = NULL; + int n; + unsigned int i; + long type; + + if (virXPathLong("string(./@type)", ctxt, &type) < 0) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("XML element 'table' requires a numeric 'type' attrbute")); + return(NULL); + } + if ((type < 0) || (type > 32)) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("XML 'type' attribute on 'table' out of 0..32 range got %ld"), + type); + return(NULL); + } + n = virXPathNodeSet("./entry", ctxt, &nodes); + if (n <= 0) + return(NULL); + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + goto error; + } + def->type = (unsigned int) type; + def->entries = NULL; + cur = NULL; + + for (i = 0;i < n;i++) { + if (nodes[i] != NULL) { + ctxt->node = nodes[i]; + next = virSmbiosEntryParseXML(ctxt); + if (next == NULL) + goto error; + if (cur == NULL) { + def->entries = next; + cur = next; + } else { + cur->next = next; + cur = next; + } + cur->next = NULL; + } + } + +cleanup: + xmlFree(nodes); + return(def); + +error: + virSmbiosBlockFree(def); + def = NULL; + goto cleanup; +} + +static virSmbiosDefPtr +virSmbiosParseXML(const xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + virSmbiosDefPtr def; + virSmbiosBlockPtr block; + xmlNodePtr *nodes = NULL; + int n; + unsigned int i, j; + + if (!xmlStrEqual(node->name, BAD_CAST "smbios")) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("XML does not contain expected 'smbios' element")); + return(NULL); + } + + n = virXPathNodeSet("./table", ctxt, &nodes); + if (n <= 0) + return(NULL); + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + goto error; + } + if (VIR_ALLOC_N(def->blocks, n) < 0) { + virReportOOMError(); + goto error; + } + + for (i = 0, j = 0;i < n;i++) { + if (nodes[i] != NULL) { + ctxt->node = nodes[i]; + block = virSmbiosBlockParseXML(ctxt); + if (block != NULL) + def->blocks[j++] = block; + else + goto error; + def->nbblocks = j; + } + } + + +cleanup: + xmlFree(nodes); + return(def); + +error: + virSmbiosDefFree(def); + def = NULL; + goto cleanup; +} int virDomainVideoDefaultRAM(virDomainDefPtr def, @@ -4970,6 +5158,16 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, goto error; } + if ((node = virXPathNode("./smbios[1]", ctxt)) != NULL) { + xmlNodePtr oldnode = ctxt->node; + ctxt->node = node; + def->smbios = virSmbiosParseXML(node, ctxt); + ctxt->node = oldnode; + + if (def->smbios == NULL) + goto error; + } + /* we have to make a copy of all of the callback pointers here since * we won't have the virCaps structure available during free */ -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 10/21/2010 02:16 PM, Daniel Veillard wrote:
This lacks the saving of the smbios data, should not be hard really, and the parsing is rather trivial, the data structures follow the XML format:
Daniel
+static void virSmbiosEntriesFree(virSmbiosEntryPtr cur)
Should this function be added to the list of useless_free_options in cfg.mk?
+{ + virSmbiosEntryPtr next; + + if (cur == NULL) + return;
Redundant, given that
+ + while (cur != NULL) {
this safely skips a NULL argument.
@@ -3341,6 +3385,150 @@ error: goto cleanup; }
+static virSmbiosEntryPtr +virSmbiosEntryParseXML(xmlXPathContextPtr ctxt) +{ + char *name, *value; + virSmbiosEntryPtr def; + + name = virXPathString("string(./@name)", ctxt); + if (name == NULL) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("XML element 'entry' requires a 'name' attrbute"));
s/attrbute/attribute/
+ +static virSmbiosBlockPtr +virSmbiosBlockParseXML(xmlXPathContextPtr ctxt) +{ + virSmbiosBlockPtr def; + virSmbiosEntryPtr cur, next; + xmlNodePtr *nodes = NULL; + int n; + unsigned int i; + long type; + + if (virXPathLong("string(./@type)", ctxt,&type)< 0) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("XML element 'table' requires a numeric 'type' attrbute"));
s/attrbute/attribute/
+ return(NULL); + } + if ((type< 0) || (type> 32)) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("XML 'type' attribute on 'table' out of 0..32 range got %ld"), + type); + return(NULL); + }
Should you also be checking for duplicate types, or is it okay to do: <smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> </table> <table type="0"> <entry name="Version">0.13</entry> </table> </smbios> -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Thu, Oct 21, 2010 at 03:45:40PM -0600, Eric Blake wrote:
On 10/21/2010 02:16 PM, Daniel Veillard wrote:
This lacks the saving of the smbios data, should not be hard really, and the parsing is rather trivial, the data structures follow the XML format:
Daniel
+static void virSmbiosEntriesFree(virSmbiosEntryPtr cur)
Should this function be added to the list of useless_free_options in cfg.mk?
+{ + virSmbiosEntryPtr next; + + if (cur == NULL) + return;
Redundant, given that
+ + while (cur != NULL) {
this safely skips a NULL argument.
ah, true :-) fixed
@@ -3341,6 +3385,150 @@ error: goto cleanup; }
+static virSmbiosEntryPtr +virSmbiosEntryParseXML(xmlXPathContextPtr ctxt) +{ + char *name, *value; + virSmbiosEntryPtr def; + + name = virXPathString("string(./@name)", ctxt); + if (name == NULL) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("XML element 'entry' requires a 'name' attrbute"));
s/attrbute/attribute/
heh, good spotting [...]
+ if ((type< 0) || (type> 32)) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("XML 'type' attribute on 'table' out of 0..32 range got %ld"), + type); + return(NULL); + }
Should you also be checking for duplicate types, or is it okay to do:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> </table> <table type="0"> <entry name="Version">0.13</entry> </table> </smbios>
For type 0 and 1 no they are unique in theory, but other tables can have duplicates like type 4 since there is one per processor. I don't think we should go too deep trying to assert semantic at that level, since anyway the drivers will have a very restricted view of the whole thing, and will only pick some of the information they can process. Still I wanted the format to be as generic as possible, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The main trouble here is that the QEmu command uses names which are similar to the official names for the entries used by the DMTF, but that mean we cant base on name equality. I was tempted to use something like strcasestr to go fishing on the names but since we never used this in libvirt yet, and I'm not sure it's available in gnulib, I did the patch using strstr, assuming entries provided by the users would contain the word in lower case usually except maybe for the first character. The matching glue is certainly perfectible. Also decided that if we can't associate an entry with an existing QEmu SMBIOS command we would ignore it. On the ther hand if a block other than type 0 or 1 is used in the XML definition we would emit a warning, but still not fail. diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 5907bf3..6d4479e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1224,6 +1224,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_BOOT_MENU; if (strstr(help, "-fsdev")) flags |= QEMUD_CMD_FLAG_FSDEV; + if (strstr(help, "-smbios type")) + flags |= QEMUD_CMD_FLAG_SMBIOS_TYPE; /* Keep disabled till we're actually ready to turn on netdev mode * The plan is todo it in 0.13.0 QEMU, but lets wait & see... */ @@ -3494,6 +3496,73 @@ error: return NULL; } +static char *qemuBuildSmbiosBlockStr(virSmbiosBlockPtr def) +{ + virSmbiosEntryPtr cur; + + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferVSprintf(&buf, "type=%d", def->type); + + /* + * QEmu accepts only a limited set of System informations, and + * use command line arguments shortcuts from the DMTF real names + * so go fishing for those + */ + cur = def->entries; + while (cur != NULL) { + /* 0:Vendor */ + if ((def->type == 0) && (strstr(cur->name, "endor"))) + virBufferVSprintf(&buf, ",vendor=\"%s\"", cur->value); + /* 0:BIOS Version */ + else if ((def->type == 0) && (strstr(cur->name, "ersion"))) + virBufferVSprintf(&buf, ",version=\"%s\"", cur->value); + /* 0:BIOS Release Date */ + else if ((def->type == 0) && (strstr(cur->name, "ate"))) + virBufferVSprintf(&buf, ",date=\"%s\"", cur->value); + /* 0:System BIOS Major Release and 0:System BIOS Minor Release */ + else if ((def->type == 0) && (strstr(cur->name, "elease"))) + virBufferVSprintf(&buf, ",date=\"%s\"", cur->value); + /* 1:Manufacturer */ + else if ((def->type == 1) && (strstr(cur->name, "anuf"))) + virBufferVSprintf(&buf, ",manufacturer=\"%s\"", cur->value); + /* 1:Product Name */ + else if ((def->type == 1) && (strstr(cur->name, "roduct"))) + virBufferVSprintf(&buf, ",product=\"%s\"", cur->value); + /* 1:Version */ + else if ((def->type == 1) && (strstr(cur->name, "ersion"))) + virBufferVSprintf(&buf, ",version=\"%s\"", cur->value); + /* 1:Serial Number */ + else if ((def->type == 1) && (strstr(cur->name, "erial"))) + virBufferVSprintf(&buf, ",serial=\"%s\"", cur->value); + /* 1:UUID */ + else if ((def->type == 1) && (strstr(cur->name, "uuid"))) + virBufferVSprintf(&buf, ",uuid=\"%s\"", cur->value); + else if ((def->type == 1) && (strstr(cur->name, "UUID"))) + virBufferVSprintf(&buf, ",uuid=\"%s\"", cur->value); + /* 1:SKU Number */ + else if ((def->type == 1) && (strstr(cur->name, "sku"))) + virBufferVSprintf(&buf, ",sku=\"%s\"", cur->value); + else if ((def->type == 1) && (strstr(cur->name, "SKU"))) + virBufferVSprintf(&buf, ",sku=\"%s\"", cur->value); + /* 1:Family */ + else if ((def->type == 1) && (strstr(cur->name, "amily"))) + virBufferVSprintf(&buf, ",family=\"%s\"", cur->value); + /* other non string or type are not available just ignore them */ + cur = cur->next; + } + + if (virBufferError(&buf)) { + virReportOOMError(); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return(NULL); +} static char * qemuBuildClockArgStr(virDomainClockDefPtr def) @@ -4074,6 +4143,26 @@ int qemudBuildCommandLine(virConnectPtr conn, } } + if ((def->smbios != NULL) && (qemuCmdFlags & QEMUD_CMD_FLAG_SMBIOS_TYPE)) { + int blk; + + for (blk = 0;blk < def->smbios->nbblocks;blk++) { + virSmbiosBlockPtr block = def->smbios->blocks[blk]; + char *smbiosblockcmd; + + if ((block->type == 0) || (block->type == 1)) { + smbiosblockcmd = qemuBuildSmbiosBlockStr(block); + if (smbiosblockcmd == NULL) + goto error; + ADD_ARG_LIT("-smbios"); + ADD_ARG(smbiosblockcmd); + } else { + VIR_WARN("QEmu handles only SMBIOS type 0 and 1, not '%d'", + block->type); + } + } + } + /* * NB, -nographic *MUST* come before any serial, or monitor * or parallel port flags due to QEMU craziness, where it diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 005031d..7ff7900 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -96,6 +96,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_FSDEV = (1LL << 40), /* -fstype filesystem passthrough */ QEMUD_CMD_FLAG_NESTING = (1LL << 41), /* -enable-nesting (SVM/VMX) */ QEMUD_CMD_FLAG_NAME_PROCESS = (1LL << 42), /* Is -name process= available */ + QEMUD_CMD_FLAG_SMBIOS_TYPE = (1LL << 43), /* Is -smbios type= available */ }; /* Main driver state */ -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 10/21/2010 02:23 PM, Daniel Veillard wrote:
The main trouble here is that the QEmu command uses names which are similar to the official names for the entries used by the DMTF, but that mean we cant base on name equality. I was tempted to use
s/cant/can't/
something like strcasestr to go fishing on the names but since we never used this in libvirt yet, and I'm not sure it's available in gnulib, I did the patch using strstr, assuming entries provided by the
Gnulib provides strcasestr() as LGPLv2+ (but beware - it only does what you want in unibyte locales); it also provides the c-strcasestr module (which is probably exactly what you want!), but it is currently LGPLv3+, although I can request on the gnulib list to have it relaxed if you'd like.
users would contain the word in lower case usually except maybe for the first character. The matching glue is certainly perfectible.
c_strcasestr() would certainly make it easier. Or, is this something where STRCASEEQ() would be good enough? That is, do we expect a user to always provide the full DMTF name "BIOS Version", or is the substring matching important because we want to all the user the shortcut of "Version"?
Also decided that if we can't associate an entry with an existing QEmu SMBIOS command we would ignore it. On the ther hand if a block
s/ther/other/
other than type 0 or 1 is used in the XML definition we would emit a warning, but still not fail.
+ /* + * QEmu accepts only a limited set of System informations, and + * use command line arguments shortcuts from the DMTF real names + * so go fishing for those + */ + cur = def->entries; + while (cur != NULL) { + /* 0:Vendor */ + if ((def->type == 0)&& (strstr(cur->name, "endor"))) + virBufferVSprintf(&buf, ",vendor=\"%s\"", cur->value); + /* 0:BIOS Version */ + else if ((def->type == 0)&& (strstr(cur->name, "ersion"))) + virBufferVSprintf(&buf, ",version=\"%s\"", cur->value); + /* 0:BIOS Release Date */ + else if ((def->type == 0)&& (strstr(cur->name, "ate"))) + virBufferVSprintf(&buf, ",date=\"%s\"", cur->value); + /* 0:System BIOS Major Release and 0:System BIOS Minor Release */ + else if ((def->type == 0)&& (strstr(cur->name, "elease"))) + virBufferVSprintf(&buf, ",date=\"%s\"", cur->value);
If the user provides both "Date" and "Major Release" names, does qemu complain about the doubled-up date="" option? -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Thu, Oct 21, 2010 at 03:58:50PM -0600, Eric Blake wrote:
On 10/21/2010 02:23 PM, Daniel Veillard wrote:
The main trouble here is that the QEmu command uses names which are similar to the official names for the entries used by the DMTF, but that mean we cant base on name equality. I was tempted to use
s/cant/can't/
something like strcasestr to go fishing on the names but since we never used this in libvirt yet, and I'm not sure it's available in gnulib, I did the patch using strstr, assuming entries provided by the
Gnulib provides strcasestr() as LGPLv2+ (but beware - it only does what you want in unibyte locales); it also provides the c-strcasestr module (which is probably exactly what you want!), but it is currently LGPLv3+, although I can request on the gnulib list to have it relaxed if you'd like.
users would contain the word in lower case usually except maybe for the first character. The matching glue is certainly perfectible.
c_strcasestr() would certainly make it easier.
Or, is this something where STRCASEEQ() would be good enough? That is, do we expect a user to always provide the full DMTF name "BIOS Version", or is the substring matching important because we want to all the user the shortcut of "Version"?
Well coming from a QEmu usage, people will likely just expect "version" as that's what is used on the command line. I think matching by subset is less likely to get users wondering why this doesn't work as expected. Since we don't do exact name checking on input, I think it's better to be flexible.
Also decided that if we can't associate an entry with an existing QEmu SMBIOS command we would ignore it. On the ther hand if a block
s/ther/other/
other than type 0 or 1 is used in the XML definition we would emit a warning, but still not fail.
+ /* + * QEmu accepts only a limited set of System informations, and + * use command line arguments shortcuts from the DMTF real names + * so go fishing for those + */ + cur = def->entries; + while (cur != NULL) { + /* 0:Vendor */ + if ((def->type == 0)&& (strstr(cur->name, "endor"))) + virBufferVSprintf(&buf, ",vendor=\"%s\"", cur->value); + /* 0:BIOS Version */ + else if ((def->type == 0)&& (strstr(cur->name, "ersion"))) + virBufferVSprintf(&buf, ",version=\"%s\"", cur->value); + /* 0:BIOS Release Date */ + else if ((def->type == 0)&& (strstr(cur->name, "ate"))) + virBufferVSprintf(&buf, ",date=\"%s\"", cur->value); + /* 0:System BIOS Major Release and 0:System BIOS Minor Release */ + else if ((def->type == 0)&& (strstr(cur->name, "elease"))) + virBufferVSprintf(&buf, ",date=\"%s\"", cur->value);
If the user provides both "Date" and "Major Release" names, does qemu complain about the doubled-up date="" option?
No actually that's different entries :-) But qemu will complain if release is not formated as %d.%d, it takes as a string what is 2 byte values in the SMBIOS tables. I didn't tried to validate that at the driver level, rather let qemu report the error I checked it shows up back up to virt-manager if something is not formatted to its taste like the UUID Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Add an entry in the test suite and add the new flag detection Note that the UUID will have to be fixed as QEmu check the UUID format and requires the standard formation with dashes Daniel libvirt/tests/qemuxml2argvdata/qemuxml2argv-smbios.args: LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -smbios type=0,vendor="QEmu/KVM",version="0.13" -smbios type=1,manufacturer="Fedora",product="Virt-Manager",version="0.8.2-3.fc14",serial="32dfcb375af1552b357cbe8c3aa38310",uuid="c7a5fdbdedaf9455926ad65c16db1809" -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb libvirt/tests/qemuxml2argvdata/qemuxml2argv-smbios.xml <domain type='qemu'> <name>QEMUGuest1</name> <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> <memory>219200</memory> <currentMemory>219200</currentMemory> <vcpu>1</vcpu> <smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="Serial">32dfcb375af1552b357cbe8c3aa38310</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios> <os> <type arch='i686' machine='pc'>hvm</type> <boot dev='hd'/> </os> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> <emulator>/usr/bin/qemu</emulator> <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> <controller type='ide' index='0'/> <memballoon model='virtio'/> </devices> </domain> diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index d4453db..afd1e4a 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -196,7 +196,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_NO_HPET | QEMUD_CMD_FLAG_NO_KVM_PIT | QEMUD_CMD_FLAG_TDF | - QEMUD_CMD_FLAG_NESTING, + QEMUD_CMD_FLAG_NESTING | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 10050, 1, 0); DO_TEST("qemu-kvm-0.11.0-rc2", QEMUD_CMD_FLAG_VNC_COLON | @@ -225,7 +226,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_TDF | QEMUD_CMD_FLAG_BOOT_MENU | QEMUD_CMD_FLAG_NESTING | - QEMUD_CMD_FLAG_NAME_PROCESS, + QEMUD_CMD_FLAG_NAME_PROCESS | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 10092, 1, 0); DO_TEST("qemu-0.12.1", QEMUD_CMD_FLAG_VNC_COLON | @@ -251,7 +253,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_RTC | QEMUD_CMD_FLAG_NO_HPET | QEMUD_CMD_FLAG_BOOT_MENU | - QEMUD_CMD_FLAG_NAME_PROCESS, + QEMUD_CMD_FLAG_NAME_PROCESS | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 12001, 0, 0); DO_TEST("qemu-kvm-0.12.3", QEMUD_CMD_FLAG_VNC_COLON | @@ -284,7 +287,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_TDF | QEMUD_CMD_FLAG_BOOT_MENU | QEMUD_CMD_FLAG_NESTING | - QEMUD_CMD_FLAG_NAME_PROCESS, + QEMUD_CMD_FLAG_NAME_PROCESS | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 12003, 1, 0); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 551d6c4..eb66620 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -358,6 +358,8 @@ mymain(int argc, char **argv) DO_TEST("console-virtio", QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG); + DO_TEST("smbios", QEMUD_CMD_FLAG_SMBIOS_TYPE); + DO_TEST("watchdog", 0); DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG); -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 10/21/2010 02:45 PM, Daniel Veillard wrote:
Add an entry in the test suite and add the new flag detection Note that the UUID will have to be fixed as QEmu check the UUID format and requires the standard formation with dashes
Looks like a reasonable start for a patch series, but as you pointed out, there's more work to go before the series is complete. Looking forward to a v2! Are you trying to target this for 0.8.5 or later? -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

2010/10/21 Daniel Veillard <veillard@redhat.com>:
 The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
 Spec available at the DMTF: http://dmtf.org/standards/smbios
 From a virtualization POV, it's mostly the first block describing the BIOS named "type 0" and the second block describing the machine named "type 1" which are of interest. Those data are usually accessed either from the OS or from management application, and being able to override the default setings may be needed for such management.
 The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
 <smbios>   <table type="0">    <entry name="Vendor">QEmu/KVM</entry>    <entry name="Version">0.13</entry>   </table>   <table type="1">    <entry name="Manufacturer">Fedora</entry>    <entry name="Product">Virt-Manager</entry>    <entry name="Version">0.8.2-3.fc14</entry>    <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry>   </table>  </smbios>
 The patch serie includes:  - the change to the doamin schemas  - the code to parse this in config structure  - the QEmu driver part  - a test example
Currently missing is the conf code to save the data back, and documentation for the domain extension. I think it's possible set some of those settings in Xen too, but I don't know if I will take the time of a driver for it. For ESX it seems there is an option to inherit some of the SMBIOS data from the host on the guest but I'm not sure some of the fields can be manipulated directly. I don't know what  VirtualBox can set there either,
Daniel
Okay, I looked at what can be done for ESX. Looking at the SMBIOS data from _inside_ a ESX guest using dmidecode I can get this <smbios> <table type="0"> <entry name="Vendor">Phoenix Technologies LTD</entry> <entry name="Version">6.00</entry> </table> <table type="1"> <entry name="Manufacturer">VMware Inc.</entry> <entry name="Product">VMware Virtual Platform</entry> <entry name="Version">None</entry> <entry name="Serial">VMware-[domain/uuid]</entry> <entry name="UUID">[domain/uuid]</entry> </table> </smbios> The UUID and Serial are basically the UUID of the guest. Putting smbios.reflecthost = "true" (defaults to false) in the VMX file results in <smbios> <table type="0"> <entry name="Vendor">Phoenix Technologies LTD</entry> <entry name="Version">6.00</entry> </table> <table type="1"> <entry name="Manufacturer">LENOVO</entry> <entry name="Product">7673J3G</entry> <entry name="Version">None</entry> <entry name="Serial">VMware-[domain/uuid]</entry> <entry name="UUID">[domain/uuid]</entry> </table> </smbios> So Manufacturer and Product from the type 1 table are now inherited from the SMBIOS of the physical host. But this is all from inside the guest. From _outside_ the guest over the vSphere API I can only access "LENOVO" and "7673J3G", the data of the physical host. To make it even worse, it seems that none of this can be edited in any way (apart from the Serial/UUID because this is the domain UUID). Therefore, I think there is no possible useful implementation for this in the ESX driver, besides outputting static unchangeable data. Matthias

On Fri, Oct 22, 2010 at 01:09:30AM +0200, Matthias Bolte wrote:
2010/10/21 Daniel Veillard <veillard@redhat.com>:
Okay, I looked at what can be done for ESX.
Looking at the SMBIOS data from _inside_ a ESX guest using dmidecode I can get this
<smbios> <table type="0"> <entry name="Vendor">Phoenix Technologies LTD</entry> <entry name="Version">6.00</entry> </table> <table type="1"> <entry name="Manufacturer">VMware Inc.</entry> <entry name="Product">VMware Virtual Platform</entry> <entry name="Version">None</entry> <entry name="Serial">VMware-[domain/uuid]</entry> <entry name="UUID">[domain/uuid]</entry> </table> </smbios>
The UUID and Serial are basically the UUID of the guest.
Putting smbios.reflecthost = "true" (defaults to false) in the VMX file results in
<smbios> <table type="0"> <entry name="Vendor">Phoenix Technologies LTD</entry> <entry name="Version">6.00</entry> </table> <table type="1"> <entry name="Manufacturer">LENOVO</entry> <entry name="Product">7673J3G</entry> <entry name="Version">None</entry> <entry name="Serial">VMware-[domain/uuid]</entry> <entry name="UUID">[domain/uuid]</entry> </table> </smbios>
So Manufacturer and Product from the type 1 table are now inherited from the SMBIOS of the physical host.
But this is all from inside the guest. From _outside_ the guest over the vSphere API I can only access "LENOVO" and "7673J3G", the data of the physical host.
To make it even worse, it seems that none of this can be edited in any way (apart from the Serial/UUID because this is the domain UUID).
Therefore, I think there is no possible useful implementation for this in the ESX driver, besides outputting static unchangeable data.
Okay, I looked up for VirtualBox, and apparently there is some support for editing some of the BIOS and system entries too based on this post http://forums.virtualbox.org/viewtopic.php?t=3224 but that looks like ad-hoc, the idea of trying to push a complete SMBios implementation probably doesn't make that much sense, and a simplified indirect version like Dan suggested might be sufficient At least we should try to expose reflecthost = "true" at the libvirt level, for ESX (and QEmu/VBox once we can parse the dmidecode output). Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

2010/10/22 Daniel Veillard <veillard@redhat.com>:
On Fri, Oct 22, 2010 at 01:09:30AM +0200, Matthias Bolte wrote:
2010/10/21 Daniel Veillard <veillard@redhat.com>:
Okay, I looked at what can be done for ESX.
Looking at the SMBIOS data from _inside_ a ESX guest using dmidecode I can get this
 <smbios>   <table type="0">    <entry name="Vendor">Phoenix Technologies LTD</entry>    <entry name="Version">6.00</entry>   </table>   <table type="1">    <entry name="Manufacturer">VMware Inc.</entry>    <entry name="Product">VMware Virtual Platform</entry>    <entry name="Version">None</entry>    <entry name="Serial">VMware-[domain/uuid]</entry>    <entry name="UUID">[domain/uuid]</entry>   </table>  </smbios>
The UUID and Serial are basically the UUID of the guest.
Putting smbios.reflecthost = "true" (defaults to false) in the VMX file results in
 <smbios>   <table type="0">    <entry name="Vendor">Phoenix Technologies LTD</entry>    <entry name="Version">6.00</entry>   </table>   <table type="1">    <entry name="Manufacturer">LENOVO</entry>    <entry name="Product">7673J3G</entry>    <entry name="Version">None</entry>    <entry name="Serial">VMware-[domain/uuid]</entry>    <entry name="UUID">[domain/uuid]</entry>   </table>  </smbios>
So Manufacturer and Product from the type 1 table are now inherited from the SMBIOS of the physical host.
But this is all from inside the guest. From _outside_ the guest over the vSphere API I can only access "LENOVO" and "7673J3G", the data of the physical host.
To make it even worse, it seems that none of this can be edited in any way (apart from the Serial/UUID because this is the domain UUID).
Therefore, I think there is no possible useful implementation for this in the ESX driver, besides outputting static unchangeable data.
 Okay, I looked up for VirtualBox, and apparently there is some support for editing some of the BIOS and system entries too based on this post  http://forums.virtualbox.org/viewtopic.php?t=3224
It seems that one of the posters suggests to hack the VirtualBox codebase. It doesn't look like the XPCOM API exposes this. src/vbox/vbox_CAPI_v3_2.h in the libvirt codebase doesn't contain any SMBIOS related things. Matthias

On Fri, Oct 22, 2010 at 04:00:31PM +0200, Matthias Bolte wrote:
2010/10/22 Daniel Veillard <veillard@redhat.com>:
 Okay, I looked up for VirtualBox, and apparently there is some support for editing some of the BIOS and system entries too based on this post  http://forums.virtualbox.org/viewtopic.php?t=3224
It seems that one of the posters suggests to hack the VirtualBox codebase. It doesn't look like the XPCOM API exposes this.
Yeah, I misunderstood though it was a config file :-( Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

2010/10/22 Daniel Veillard <veillard@redhat.com>:
On Fri, Oct 22, 2010 at 04:00:31PM +0200, Matthias Bolte wrote:
2010/10/22 Daniel Veillard <veillard@redhat.com>:
 Okay, I looked up for VirtualBox, and apparently there is some support for editing some of the BIOS and system entries too based on this post  http://forums.virtualbox.org/viewtopic.php?t=3224
It seems that one of the posters suggests to hack the VirtualBox codebase. It doesn't look like the XPCOM API exposes this.
 Yeah, I misunderstood though it was a config file :-(
Daniel
I just came a cross this forum post from 2008: http://forums.virtualbox.org/viewtopic.php?f=2&t=7731 I tested it and it works. This allows to override the defaults. Matthias

2010/10/22 Matthias Bolte <matthias.bolte@googlemail.com>:
2010/10/22 Daniel Veillard <veillard@redhat.com>:
On Fri, Oct 22, 2010 at 04:00:31PM +0200, Matthias Bolte wrote:
2010/10/22 Daniel Veillard <veillard@redhat.com>:
 Okay, I looked up for VirtualBox, and apparently there is some support for editing some of the BIOS and system entries too based on this post  http://forums.virtualbox.org/viewtopic.php?t=3224
It seems that one of the posters suggests to hack the VirtualBox codebase. It doesn't look like the XPCOM API exposes this.
 Yeah, I misunderstood though it was a config file :-(
Daniel
I just came a cross this forum post from 2008:
http://forums.virtualbox.org/viewtopic.php?f=2&t=7731
I tested it and it works. This allows to override the defaults.
Matthias
The [sg]etextradata functions are also available in the XPCOM API. Matthias

On Fri, Oct 22, 2010 at 07:15:43PM +0200, Matthias Bolte wrote:
2010/10/22 Matthias Bolte <matthias.bolte@googlemail.com>:
2010/10/22 Daniel Veillard <veillard@redhat.com>:
On Fri, Oct 22, 2010 at 04:00:31PM +0200, Matthias Bolte wrote:
2010/10/22 Daniel Veillard <veillard@redhat.com>:
 Okay, I looked up for VirtualBox, and apparently there is some support for editing some of the BIOS and system entries too based on this post  http://forums.virtualbox.org/viewtopic.php?t=3224
It seems that one of the posters suggests to hack the VirtualBox codebase. It doesn't look like the XPCOM API exposes this.
 Yeah, I misunderstood though it was a config file :-(
Daniel
I just came a cross this forum post from 2008:
http://forums.virtualbox.org/viewtopic.php?f=2&t=7731
I tested it and it works. This allows to override the defaults.
Matthias
The [sg]etextradata functions are also available in the XPCOM API.
Ah, good ! I had seen it too but it was looking fuzzier than the other thread :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Thu, Oct 21, 2010 at 09:52:51PM +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Spec available at the DMTF: http://dmtf.org/standards/smbios
From a virtualization POV, it's mostly the first block describing the BIOS named "type 0" and the second block describing the machine named "type 1" which are of interest. Those data are usually accessed either from the OS or from management application, and being able to override the default setings may be needed for such management.
The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios>
I've never really been a fan of the idea of including SMBios data in the XML because it is an x86 specific concept, which only works with HVM guests & the type=1/2/3 is rather opaque in meaning. I can't help thinking that we should define a set of general metadata tags, and then have a internal mapping of those to SMBIOS fields, in the same way that the <uuid> is automatically mapped to SMBIOS. eg, define a set of metadata like this: <metadata> <bios-vendor>SeaBIOS</bios-vendor> <bios-version>0.13</bios-version> <system-manufacturer>Fedora</system-manufacturer> <system-product>KVM</system-product> <system-version>0.8.2</system-version> <system-uuid>c7a5fdbdedaf9455926ad65c16db1809</system-uuid> </metadata> And for smbios just indicate what the source of the data is: <smbios mode="host|emulate"/> host - copy from host SMBIOS emulate - generic emulator settings + metadata overrides This would map better to what VMWare is letting you do, and let us expose the metadata through other non-SMBIOS data channels Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Oct 22, 2010 at 09:28:48AM +0100, Daniel P. Berrange wrote:
On Thu, Oct 21, 2010 at 09:52:51PM +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Spec available at the DMTF: http://dmtf.org/standards/smbios
From a virtualization POV, it's mostly the first block describing the BIOS named "type 0" and the second block describing the machine named "type 1" which are of interest. Those data are usually accessed either from the OS or from management application, and being able to override the default setings may be needed for such management.
The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios>
I've never really been a fan of the idea of including SMBios data in the XML because it is an x86 specific concept, which only works with HVM guests & the type=1/2/3 is rather opaque in meaning.
The semantic is well defined it's information available from the BIOS, c.f. the DMTF spec. The we know how to get it from a guest, and it's not dependant on the virtualization layer used, it may or may not support it, but at least the expectation are clear.
I can't help thinking that we should define a set of general metadata tags, and then have a internal mapping of those to SMBIOS fields, in the same way that the <uuid> is automatically mapped to SMBIOS.
eg, define a set of metadata like this:
<metadata> <bios-vendor>SeaBIOS</bios-vendor> <bios-version>0.13</bios-version> <system-manufacturer>Fedora</system-manufacturer> <system-product>KVM</system-product> <system-version>0.8.2</system-version> <system-uuid>c7a5fdbdedaf9455926ad65c16db1809</system-uuid> </metadata>
Okay, but what is the semantic of <system-product> for example ? Does that mean SMBIOS type 1 Product Name or something else left to the appreciation of the driver or of the user ?
And for smbios just indicate what the source of the data is:
<smbios mode="host|emulate"/>
host - copy from host SMBIOS emulate - generic emulator settings + metadata overrides
This would map better to what VMWare is letting you do, and let us expose the metadata through other non-SMBIOS data channels
Your suggestion is far more flexible, but that comes with the trouble that we have to define those metadata semantic, or we don't define their semantic, and it may get messy in the long term. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Oct 22, 2010 at 11:23:45AM +0200, Daniel Veillard wrote:
On Fri, Oct 22, 2010 at 09:28:48AM +0100, Daniel P. Berrange wrote:
On Thu, Oct 21, 2010 at 09:52:51PM +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Spec available at the DMTF: http://dmtf.org/standards/smbios
From a virtualization POV, it's mostly the first block describing the BIOS named "type 0" and the second block describing the machine named "type 1" which are of interest. Those data are usually accessed either from the OS or from management application, and being able to override the default setings may be needed for such management.
The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios>
I've never really been a fan of the idea of including SMBios data in the XML because it is an x86 specific concept, which only works with HVM guests & the type=1/2/3 is rather opaque in meaning.
The semantic is well defined it's information available from the BIOS, c.f. the DMTF spec. The we know how to get it from a guest, and it's not dependant on the virtualization layer used, it may or may not support it, but at least the expectation are clear.
I can't help thinking that we should define a set of general metadata tags, and then have a internal mapping of those to SMBIOS fields, in the same way that the <uuid> is automatically mapped to SMBIOS.
eg, define a set of metadata like this:
<metadata> <bios-vendor>SeaBIOS</bios-vendor> <bios-version>0.13</bios-version> <system-manufacturer>Fedora</system-manufacturer> <system-product>KVM</system-product> <system-version>0.8.2</system-version> <system-uuid>c7a5fdbdedaf9455926ad65c16db1809</system-uuid> </metadata>
Okay, but what is the semantic of <system-product> for example ? Does that mean SMBIOS type 1 Product Name or something else left to the appreciation of the driver or of the user ?
It is simply a NULL terminated string for the system product name.
And for smbios just indicate what the source of the data is:
<smbios mode="host|emulate"/>
host - copy from host SMBIOS emulate - generic emulator settings + metadata overrides
This would map better to what VMWare is letting you do, and let us expose the metadata through other non-SMBIOS data channels
Your suggestion is far more flexible, but that comes with the trouble that we have to define those metadata semantic, or we don't define their semantic, and it may get messy in the long term.
It is worth the extra work, because it gives us a representation of data which is hypervisor-agnostic, which is the primary goal of our XML format. If I want to specify a 'product name' for the LXC containers, I don't want to have to use different XML for that, compared to setting 'product name' for KVM. With the exception of the UUID field, these are all simply NULL terminated free form strings, so defining a mapping to SMBIOS fields is pretty straightforward. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Oct 22, 2010 at 11:23:45AM +0200, Daniel Veillard wrote:
On Fri, Oct 22, 2010 at 09:28:48AM +0100, Daniel P. Berrange wrote:
On Thu, Oct 21, 2010 at 09:52:51PM +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Spec available at the DMTF: http://dmtf.org/standards/smbios
From a virtualization POV, it's mostly the first block describing the BIOS named "type 0" and the second block describing the machine named "type 1" which are of interest. Those data are usually accessed either from the OS or from management application, and being able to override the default setings may be needed for such management.
The suggested XML description follows the logical structure of the data, one top smbios description, with one or more blocks, each containing the entries, the example below gives an idea:
<smbios> <table type="0"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </table> <table type="1"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </table> </smbios>
I've never really been a fan of the idea of including SMBios data in the XML because it is an x86 specific concept, which only works with HVM guests & the type=1/2/3 is rather opaque in meaning.
The semantic is well defined it's information available from the BIOS, c.f. the DMTF spec. The we know how to get it from a guest, and it's not dependant on the virtualization layer used, it may or may not support it, but at least the expectation are clear.
I can't help thinking that we should define a set of general metadata tags, and then have a internal mapping of those to SMBIOS fields, in the same way that the <uuid> is automatically mapped to SMBIOS.
eg, define a set of metadata like this:
<metadata> <bios-vendor>SeaBIOS</bios-vendor> <bios-version>0.13</bios-version> <system-manufacturer>Fedora</system-manufacturer> <system-product>KVM</system-product> <system-version>0.8.2</system-version> <system-uuid>c7a5fdbdedaf9455926ad65c16db1809</system-uuid> </metadata>
Okay, but what is the semantic of <system-product> for example ? Does that mean SMBIOS type 1 Product Name or something else left to the appreciation of the driver or of the user ?
And for smbios just indicate what the source of the data is:
<smbios mode="host|emulate"/>
host - copy from host SMBIOS emulate - generic emulator settings + metadata overrides
This would map better to what VMWare is letting you do, and let us expose the metadata through other non-SMBIOS data channels
Your suggestion is far more flexible, but that comes with the trouble that we have to define those metadata semantic, or we don't define their semantic, and it may get messy in the long term.
How about a different variation on the theme. <sysinfo type="smbios"> <section name="bios"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </section> <section namee="platform"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </section> </sysinfo> Where the valid section types, and entry names are defined according to the sysinfo type. So with type='smbios', the valid section/entries names would be 100% as per the SMBIOS spec. If we add different sysinfo types, we can define appropriate sections/entries as per the spec for those types. This keeps the strictly defined semantics, while avoiding a schema that is tied to smbios Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Oct 22, 2010 at 01:16:16PM +0100, Daniel P. Berrange wrote:
On Fri, Oct 22, 2010 at 11:23:45AM +0200, Daniel Veillard wrote:
On Fri, Oct 22, 2010 at 09:28:48AM +0100, Daniel P. Berrange wrote: [...]
I can't help thinking that we should define a set of general metadata tags, and then have a internal mapping of those to SMBIOS fields, in the same way that the <uuid> is automatically mapped to SMBIOS.
eg, define a set of metadata like this:
<metadata> <bios-vendor>SeaBIOS</bios-vendor> <bios-version>0.13</bios-version> <system-manufacturer>Fedora</system-manufacturer> <system-product>KVM</system-product> <system-version>0.8.2</system-version> <system-uuid>c7a5fdbdedaf9455926ad65c16db1809</system-uuid> </metadata>
Okay, but what is the semantic of <system-product> for example ? Does that mean SMBIOS type 1 Product Name or something else left to the appreciation of the driver or of the user ?
And for smbios just indicate what the source of the data is:
<smbios mode="host|emulate"/>
host - copy from host SMBIOS emulate - generic emulator settings + metadata overrides
This would map better to what VMWare is letting you do, and let us expose the metadata through other non-SMBIOS data channels
Your suggestion is far more flexible, but that comes with the trouble that we have to define those metadata semantic, or we don't define their semantic, and it may get messy in the long term.
How about a different variation on the theme.
<sysinfo type="smbios"> <section name="bios"> <entry name="Vendor">QEmu/KVM</entry> <entry name="Version">0.13</entry> </section> <section namee="platform"> <entry name="Manufacturer">Fedora</entry> <entry name="Product">Virt-Manager</entry> <entry name="Version">0.8.2-3.fc14</entry> <entry name="UUID">c7a5fdbdedaf9455926ad65c16db1809</entry> </section> </sysinfo>
Where the valid section types, and entry names are defined according to the sysinfo type. So with type='smbios', the valid section/entries names would be 100% as per the SMBIOS spec. If we add different sysinfo types, we can define appropriate sections/entries as per the spec for those types. This keeps the strictly defined semantics, while avoiding a schema that is tied to smbios
Okay, agreed, hierarchy may look a bit more complex as a result but it allows to preserve both viewpoint. Also for the <smbios> element, should we make the mode a tristate: - emulate: do not try to override the default set by the hypervisor (if any) - host: get the values from the host (libvirtd may have to parse the dmidecode output as I don't see how to implement this for QEmu otherwise), the only useful mode for ESX driver - sysinfo: get the values from <sysinfo> section and pass them to the hypervisor. Also I'm wondering if we should treat <smbios> as a device or keep it as a top level element along <cpu> etc. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Thu, 2010-10-21 at 21:52 +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Daniel, Can you tell me if you are (or are willing or planning to) going to implement structure Type 9 of the SMBIOS specification? Specifically, this provides a mapping from the "system slots" (in the chassis) to the PCI devices in the system (as an example), especially where network is concerned (but not limited to that). We are investigating generic solutions for mapping network devices presented by Linux through to the physical devices themselves. So for example, network device eth0 is replaced by eth-slot0-<etc> or lom0, or whatever. I know virt doesn't have a physical slot, but the ordering of devices does matter very much. Let me know your plans. I am still catching up from LPC last week, so I just skimmed libvirt list. I have a plan to read over your patches soon. Jon.

On Tue, Nov 09, 2010 at 04:22:56AM -0500, Jon Masters wrote:
On Thu, 2010-10-21 at 21:52 +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Daniel,
Can you tell me if you are (or are willing or planning to) going to implement structure Type 9 of the SMBIOS specification? Specifically, this provides a mapping from the "system slots" (in the chassis) to the PCI devices in the system (as an example), especially where network is concerned (but not limited to that). We are investigating generic solutions for mapping network devices presented by Linux through to the physical devices themselves. So for example, network device eth0 is replaced by eth-slot0-<etc> or lom0, or whatever.
I know virt doesn't have a physical slot, but the ordering of devices does matter very much. Let me know your plans. I am still catching up from LPC last week, so I just skimmed libvirt list. I have a plan to read over your patches soon.
A priori no hypervisor expose any of the type 9 informations. So I don't think using the SMBIOS stucture may actually help solving the device ordering in the guests. My pervious version of the patch which was very close to SMBIOS structure would have allowed to expose those but that's not something we could have used for the hypervisor. Also contrary to the current set of sysinfo informations we won't be able to pick them up from the host in any meaningful way. The device ordering is still something to be improved but for a given class of devices we tend to assign them PCI slots in the order found in the XML docmain declaration. Right now the order between different classes of devices is hardcoded and that is one point we should be able to improve, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Tue, Nov 09, 2010 at 11:29:31AM +0100, Daniel Veillard wrote:
On Tue, Nov 09, 2010 at 04:22:56AM -0500, Jon Masters wrote:
On Thu, 2010-10-21 at 21:52 +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Daniel,
Can you tell me if you are (or are willing or planning to) going to implement structure Type 9 of the SMBIOS specification? Specifically, this provides a mapping from the "system slots" (in the chassis) to the PCI devices in the system (as an example), especially where network is concerned (but not limited to that). We are investigating generic solutions for mapping network devices presented by Linux through to the physical devices themselves. So for example, network device eth0 is replaced by eth-slot0-<etc> or lom0, or whatever.
I know virt doesn't have a physical slot, but the ordering of devices does matter very much. Let me know your plans. I am still catching up from LPC last week, so I just skimmed libvirt list. I have a plan to read over your patches soon.
A priori no hypervisor expose any of the type 9 informations. So I don't think using the SMBIOS stucture may actually help solving the device ordering in the guests. My pervious version of the patch which was very close to SMBIOS structure would have allowed to expose those but that's not something we could have used for the hypervisor. Also contrary to the current set of sysinfo informations we won't be able to pick them up from the host in any meaningful way.
The device ordering is still something to be improved but for a given class of devices we tend to assign them PCI slots in the order found in the XML docmain declaration. Right now the order between different classes of devices is hardcoded and that is one point we should be able to improve,
Actually that's not quite correct. If you give a XML config to libvirt without any PCI addresses, libvirt will auto-assign slots in an order that matches QEMU's default auto-assignment. If you want to explicitly control PCI addresses yourself, you can include them in the XML given to libvirt and that will cause libvirt's autoassignment to be skipped. So a mgmt app can guarantee a PCI slot for a given device across all guests if it so desires Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Tue, 2010-11-09 at 11:29 +0100, Daniel Veillard wrote:
On Tue, Nov 09, 2010 at 04:22:56AM -0500, Jon Masters wrote:
On Thu, 2010-10-21 at 21:52 +0200, Daniel Veillard wrote:
The SMBIOS data are a standardized set of data structures available in the BIOS area of PCs. Those blocks of data describe things like BIOS version informations, machine vendor, model and identifiers, as well as various parts of the machine capability. On a linux machine running dmidecode allows to dump those informations.
Daniel,
Can you tell me if you are (or are willing or planning to) going to implement structure Type 9 of the SMBIOS specification? Specifically, this provides a mapping from the "system slots" (in the chassis) to the PCI devices in the system (as an example), especially where network is concerned (but not limited to that). We are investigating generic solutions for mapping network devices presented by Linux through to the physical devices themselves. So for example, network device eth0 is replaced by eth-slot0-<etc> or lom0, or whatever.
I know virt doesn't have a physical slot, but the ordering of devices does matter very much. Let me know your plans. I am still catching up from LPC last week, so I just skimmed libvirt list. I have a plan to read over your patches soon.
A priori no hypervisor expose any of the type 9 informations.
But that's not a reason not to :) One of the (many) reasons that extension was added was to help even hypervisors.
I don't think using the SMBIOS stucture may actually help solving the device ordering in the guests.
Why not? Guest Operating Systems are starting to support this extension, and there's an ACPI extension coming along too. I would have thought an OS-independent way of ensuring consistent ordering is pretty useful!
The device ordering is still something to be improved but for a given class of devices we tend to assign them PCI slots in the order found in the XML docmain declaration. Right now the order between different classes of devices is hardcoded and that is one point we should be able to improve,
You could just pass the SMBIOS data such that you map PCI "slots" to devices in linear order. That will ensure one kind of ordering. And you can change the logic later since you know how the guest OS(es) will react and so can still ensure a consistent mapping. Jon.
participants (5)
-
Daniel P. Berrange
-
Daniel Veillard
-
Eric Blake
-
Jon Masters
-
Matthias Bolte