return ret;
}
+static int
+virSysinfoBIOSParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virSysinfoBIOSDefPtr *bios)
+{
+ int ret = -1;
+ virSysinfoBIOSDefPtr def;
+
+ if (!xmlStrEqual(node->name, BAD_CAST "bios")) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("XML does not contain expected 'bios' element"));
+ return ret;
+ }
+
+ if (VIR_ALLOC(def) < 0)
+ goto cleanup;
+
+ def->vendor = virXPathString("string(entry[@name='vendor'])", ctxt);
+ def->version = virXPathString("string(entry[@name='version'])", ctxt);
+ def->date = virXPathString("string(entry[@name='date'])", ctxt);
+ def->release = virXPathString("string(entry[@name='release'])", ctxt);
+ if (def->date != NULL) {
+ char *ptr;
+ int month, day, year;
+
+ /* Validate just the format of the date
+ * Expect mm/dd/yyyy or mm/dd/yy,
+ * where yy must be 00->99 and would be assumed to be 19xx
+ * a yyyy date should be 1900 and beyond
+ */
+ if (virStrToLong_i(def->date, &ptr, 10, &month) < 0 ||
+ *ptr != '/' ||
+ virStrToLong_i(ptr + 1, &ptr, 10, &day) < 0 ||
+ *ptr != '/' ||
+ virStrToLong_i(ptr + 1, &ptr, 10, &year) < 0 ||
+ *ptr != '\0' ||
+ (month < 1 || month > 12) ||
+ (day < 1 || day > 31) ||
+ (year < 0 || (year >= 100 && year < 1900))) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("Invalid BIOS 'date' format"));
+ goto cleanup;
+ }
+ }
+
+ if (!def->vendor && !def->version &&
+ !def->date && !def->release) {
+ virSysinfoBIOSDefFree(def);
+ def = NULL;
+ }
+
+ *bios = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoBIOSDefFree(def);
+ return ret;
+}
+
static virSysinfoDefPtr
virSysinfoParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
bool uuid_generated)
{
virSysinfoDefPtr def;
+ xmlNodePtr oldnode, tmpnode;
char *type;
char *tmpUUID = NULL;
goto error;
}
-
/* Extract BIOS related metadata */
- def->bios_vendor =
- virXPathString("string(bios/entry[@name='vendor'])", ctxt);
- def->bios_version =
- virXPathString("string(bios/entry[@name='version'])", ctxt);
- def->bios_date =
- virXPathString("string(bios/entry[@name='date'])", ctxt);
- if (def->bios_date != NULL) {
- char *ptr;
- int month, day, year;
-
- /* Validate just the format of the date
- * Expect mm/dd/yyyy or mm/dd/yy,
- * where yy must be 00->99 and would be assumed to be 19xx
- * a yyyy date should be 1900 and beyond
- */
- if (virStrToLong_i(def->bios_date, &ptr, 10, &month) < 0 ||
- *ptr != '/' ||
- virStrToLong_i(ptr + 1, &ptr, 10, &day) < 0 ||
- *ptr != '/' ||
- virStrToLong_i(ptr + 1, &ptr, 10, &year) < 0 ||
- *ptr != '\0' ||
- (month < 1 || month > 12) ||
- (day < 1 || day > 31) ||
- (year < 0 || (year >= 100 && year < 1900))) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("Invalid BIOS 'date' format"));
+ if ((tmpnode = virXPathNode("./bios[1]", ctxt)) != NULL) {
+ oldnode = ctxt->node;
+ ctxt->node = tmpnode;
+ if (virSysinfoBIOSParseXML(tmpnode, ctxt, &def->bios) < 0) {
+ ctxt->node = oldnode;
goto error;
}
+ ctxt->node = oldnode;
}
- def->bios_release =
- virXPathString("string(bios/entry[@name='release'])", ctxt);
/* Extract system related metadata */
def->system_manufacturer =
}
-static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
+static char *qemuBuildSmbiosBiosStr(virSysinfoBIOSDefPtr def)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- if ((def->bios_vendor == NULL) && (def->bios_version == NULL) &&
- (def->bios_date == NULL) && (def->bios_release == NULL))
+ if (!def)
return NULL;
virBufferAddLit(&buf, "type=0");
/* 0:Vendor */
- if (def->bios_vendor)
- virBufferAsprintf(&buf, ",vendor=%s", def->bios_vendor);
+ if (def->vendor)
+ virBufferAsprintf(&buf, ",vendor=%s", def->vendor);
/* 0:BIOS Version */
- if (def->bios_version)
- virBufferAsprintf(&buf, ",version=%s", def->bios_version);
+ if (def->version)
+ virBufferAsprintf(&buf, ",version=%s", def->version);
/* 0:BIOS Release Date */
- if (def->bios_date)
- virBufferAsprintf(&buf, ",date=%s", def->bios_date);
+ if (def->date)
+ virBufferAsprintf(&buf, ",date=%s", def->date);
/* 0:System BIOS Major Release and 0:System BIOS Minor Release */
- if (def->bios_release)
- virBufferAsprintf(&buf, ",release=%s", def->bios_release);
+ if (def->release)
+ virBufferAsprintf(&buf, ",release=%s", def->release);
if (virBufferCheckError(&buf) < 0)
goto error;
if (source != NULL) {
char *smbioscmd;
- smbioscmd = qemuBuildSmbiosBiosStr(source);
+ smbioscmd = qemuBuildSmbiosBiosStr(source->bios);
if (smbioscmd != NULL) {
virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
VIR_FREE(smbioscmd);
sysinfoCpuinfo = cpuinfo;
}
+void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def)
+{
+ if (def == NULL)
+ return;
+
+ VIR_FREE(def->vendor);
+ VIR_FREE(def->version);
+ VIR_FREE(def->date);
+ VIR_FREE(def->release);
+ VIR_FREE(def);
+}
+
/**
* virSysinfoDefFree:
* @def: a sysinfo structure
if (def == NULL)
return;
- VIR_FREE(def->bios_vendor);
- VIR_FREE(def->bios_version);
- VIR_FREE(def->bios_date);
- VIR_FREE(def->bios_release);
+ virSysinfoBIOSDefFree(def->bios);
VIR_FREE(def->system_manufacturer);
VIR_FREE(def->system_product);
#else /* !WIN32 && x86 */
static int
-virSysinfoParseBIOS(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseBIOS(const char *base, virSysinfoBIOSDefPtr *bios)
{
+ int ret = -1;
const char *cur, *eol = NULL;
+ virSysinfoBIOSDefPtr def;
if ((cur = strstr(base, "BIOS Information")) == NULL)
return 0;
+ if (VIR_ALLOC(def) < 0)
+ return ret;
+
base = cur;
if ((cur = strstr(base, "Vendor: ")) != NULL) {
cur += 8;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->bios_vendor, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->vendor, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "Version: ")) != NULL) {
cur += 9;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->bios_version, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "Release Date: ")) != NULL) {
cur += 14;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->bios_date, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->date, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "BIOS Revision: ")) != NULL) {
cur += 15;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->bios_release, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->release, cur, eol - cur) < 0)
+ goto cleanup;
}
- return 0;
+ if (!def->vendor && !def->version &&
+ !def->date && !def->release) {
+ virSysinfoBIOSDefFree(def);
+ def = NULL;
+ }
+
+ *bios = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoBIOSDefFree(def);
+ return ret;
}
static int
ret->type = VIR_SYSINFO_SMBIOS;
- if (virSysinfoParseBIOS(outbuf, ret) < 0)
+ if (virSysinfoParseBIOS(outbuf, &ret->bios) < 0)
goto error;
if (virSysinfoParseSystem(outbuf, ret) < 0)
#endif /* !WIN32 && x86 */
static void
-virSysinfoBIOSFormat(virBufferPtr buf, virSysinfoDefPtr def)
+virSysinfoBIOSFormat(virBufferPtr buf, virSysinfoBIOSDefPtr def)
{
- if (!def->bios_vendor && !def->bios_version &&
- !def->bios_date && !def->bios_release)
+ if (!def)
return;
virBufferAddLit(buf, "<bios>\n");
virBufferAdjustIndent(buf, 2);
virBufferEscapeString(buf, "<entry name='vendor'>%s</entry>\n",
- def->bios_vendor);
+ def->vendor);
virBufferEscapeString(buf, "<entry name='version'>%s</entry>\n",
- def->bios_version);
+ def->version);
virBufferEscapeString(buf, "<entry name='date'>%s</entry>\n",
- def->bios_date);
+ def->date);
virBufferEscapeString(buf, "<entry name='release'>%s</entry>\n",
- def->bios_release);
+ def->release);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</bios>\n");
}
virBufferAdjustIndent(&childrenBuf, indent + 2);
- virSysinfoBIOSFormat(&childrenBuf, def);
+ virSysinfoBIOSFormat(&childrenBuf, def->bios);
virSysinfoSystemFormat(&childrenBuf, def);
virSysinfoProcessorFormat(&childrenBuf, def);
virSysinfoMemoryFormat(&childrenBuf, def);
return ret;
}
+#define CHECK_FIELD(name, desc) \
+ do { \
+ if (STRNEQ_NULLABLE(src->name, dst->name)) { \
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
+ _("Target sysinfo %s %s does not match source %s"), \
+ desc, NULLSTR(dst->name), NULLSTR(src->name)); \
+ goto cleanup; \
+ } \
+ } while (0)
+
+static bool
+virSysinfoBIOSIsEqual(virSysinfoBIOSDefPtr src,
+ virSysinfoBIOSDefPtr dst)
+{
+ bool identical = false;
+
+ if (!src && !dst)
+ return true;
+
+ if ((src && !dst) || (!src && dst)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Target sysinfo does not match source"));
+ goto cleanup;
+ }
+
+ CHECK_FIELD(vendor, "BIOS vendor");
+ CHECK_FIELD(version, "BIOS version");
+ CHECK_FIELD(date, "BIOS date");
+ CHECK_FIELD(release, "BIOS release");
+
+ identical = true;
+ cleanup:
+ return identical;
+}
+
bool virSysinfoIsEqual(virSysinfoDefPtr src,
virSysinfoDefPtr dst)
{
goto cleanup;
}
-#define CHECK_FIELD(name, desc) \
- do { \
- if (STRNEQ_NULLABLE(src->name, dst->name)) { \
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
- _("Target sysinfo %s %s does not match source %s"), \
- desc, NULLSTR(src->name), NULLSTR(dst->name)); \
- } \
- } while (0)
-
- CHECK_FIELD(bios_vendor, "BIOS vendor");
- CHECK_FIELD(bios_version, "BIOS version");
- CHECK_FIELD(bios_date, "BIOS date");
- CHECK_FIELD(bios_release, "BIOS release");
+ if (!virSysinfoBIOSIsEqual(src->bios, dst->bios))
+ goto cleanup;
CHECK_FIELD(system_manufacturer, "system vendor");
CHECK_FIELD(system_product, "system product");