return ret;
}
+static int
+virSysinfoSystemParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virSysinfoSystemDefPtr *system,
+ unsigned char *domUUID,
+ bool uuid_generated)
+{
+ int ret = -1;
+ virSysinfoSystemDefPtr def;
+ char *tmpUUID = NULL;
+
+ if (!xmlStrEqual(node->name, BAD_CAST "system")) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("XML does not contain expected 'system' element"));
+ return ret;
+ }
+
+ if (VIR_ALLOC(def) < 0)
+ goto cleanup;
+
+ def->manufacturer =
+ virXPathString("string(entry[@name='manufacturer'])", ctxt);
+ def->product =
+ virXPathString("string(entry[@name='product'])", ctxt);
+ def->version =
+ virXPathString("string(entry[@name='version'])", ctxt);
+ def->serial =
+ virXPathString("string(entry[@name='serial'])", ctxt);
+ tmpUUID = virXPathString("string(entry[@name='uuid'])", ctxt);
+ if (tmpUUID) {
+ unsigned char uuidbuf[VIR_UUID_BUFLEN];
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ if (virUUIDParse(tmpUUID, uuidbuf) < 0) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ "%s", _("malformed <sysinfo> uuid element"));
+ goto cleanup;
+ }
+ if (uuid_generated) {
+ memcpy(domUUID, uuidbuf, VIR_UUID_BUFLEN);
+ } else if (memcmp(domUUID, uuidbuf, VIR_UUID_BUFLEN) != 0) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("UUID mismatch between <uuid> and "
+ "<sysinfo>"));
+ goto cleanup;
+ }
+ /* Although we've validated the UUID as good, virUUIDParse() is
+ * lax with respect to allowing extraneous "-" and " ", but the
+ * underlying hypervisor may be less forgiving. Use virUUIDFormat()
+ * to validate format in xml is right. If not, then format it
+ * properly so that it's used correctly later.
+ */
+ virUUIDFormat(uuidbuf, uuidstr);
+ if (VIR_STRDUP(def->uuid, uuidstr) < 0)
+ goto cleanup;
+ }
+ def->sku =
+ virXPathString("string(entry[@name='sku'])", ctxt);
+ def->family =
+ virXPathString("string(entry[@name='family'])", ctxt);
+
+ if (!def->manufacturer && !def->product && !def->version &&
+ !def->serial && !def->uuid && !def->sku && !def->family) {
+ virSysinfoSystemDefFree(def);
+ def = NULL;
+ }
+
+ *system = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoSystemDefFree(def);
+ VIR_FREE(tmpUUID);
+ return ret;
+}
+
static virSysinfoDefPtr
virSysinfoParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
virSysinfoDefPtr def;
xmlNodePtr oldnode, tmpnode;
char *type;
- char *tmpUUID = NULL;
if (!xmlStrEqual(node->name, BAD_CAST "sysinfo")) {
virReportError(VIR_ERR_XML_ERROR, "%s",
}
/* Extract system related metadata */
- def->system_manufacturer =
- virXPathString("string(system/entry[@name='manufacturer'])", ctxt);
- def->system_product =
- virXPathString("string(system/entry[@name='product'])", ctxt);
- def->system_version =
- virXPathString("string(system/entry[@name='version'])", ctxt);
- def->system_serial =
- virXPathString("string(system/entry[@name='serial'])", ctxt);
- tmpUUID = virXPathString("string(system/entry[@name='uuid'])", ctxt);
- if (tmpUUID) {
- unsigned char uuidbuf[VIR_UUID_BUFLEN];
- char uuidstr[VIR_UUID_STRING_BUFLEN];
- if (virUUIDParse(tmpUUID, uuidbuf) < 0) {
- virReportError(VIR_ERR_XML_DETAIL,
- "%s", _("malformed <sysinfo> uuid element"));
- goto error;
- }
- if (uuid_generated) {
- memcpy(domUUID, uuidbuf, VIR_UUID_BUFLEN);
- } else if (memcmp(domUUID, uuidbuf, VIR_UUID_BUFLEN) != 0) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("UUID mismatch between <uuid> and "
- "<sysinfo>"));
+ if ((tmpnode = virXPathNode("./system[1]", ctxt)) != NULL) {
+ oldnode = ctxt->node;
+ ctxt->node = tmpnode;
+ if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system,
+ domUUID, uuid_generated) < 0) {
+ ctxt->node = oldnode;
goto error;
}
- /* Although we've validated the UUID as good, virUUIDParse() is
- * lax with respect to allowing extraneous "-" and " ", but the
- * underlying hypervisor may be less forgiving. Use virUUIDFormat()
- * to validate format in xml is right. If not, then format it
- * properly so that it's used correctly later.
- */
- virUUIDFormat(uuidbuf, uuidstr);
- if (VIR_STRDUP(def->system_uuid, uuidstr) < 0)
- goto error;
+ ctxt->node = oldnode;
}
- def->system_sku =
- virXPathString("string(system/entry[@name='sku'])", ctxt);
- def->system_family =
- virXPathString("string(system/entry[@name='family'])", ctxt);
cleanup:
VIR_FREE(type);
- VIR_FREE(tmpUUID);
return def;
error:
return NULL;
}
-static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def, bool skip_uuid)
+static char *qemuBuildSmbiosSystemStr(virSysinfoSystemDefPtr def,
+ bool skip_uuid)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- if ((def->system_manufacturer == NULL) && (def->system_sku == NULL) &&
- (def->system_product == NULL) && (def->system_version == NULL) &&
- (def->system_serial == NULL) && (def->system_family == NULL) &&
- (def->system_uuid == NULL || skip_uuid))
+ if (!def ||
+ (!def->manufacturer && !def->product && !def->version &&
+ !def->serial && (!def->uuid || skip_uuid) &&
+ def->sku && !def->family))
return NULL;
virBufferAddLit(&buf, "type=1");
/* 1:Manufacturer */
- if (def->system_manufacturer)
+ if (def->manufacturer)
virBufferAsprintf(&buf, ",manufacturer=%s",
- def->system_manufacturer);
+ def->manufacturer);
/* 1:Product Name */
- if (def->system_product)
- virBufferAsprintf(&buf, ",product=%s", def->system_product);
+ if (def->product)
+ virBufferAsprintf(&buf, ",product=%s", def->product);
/* 1:Version */
- if (def->system_version)
- virBufferAsprintf(&buf, ",version=%s", def->system_version);
+ if (def->version)
+ virBufferAsprintf(&buf, ",version=%s", def->version);
/* 1:Serial Number */
- if (def->system_serial)
- virBufferAsprintf(&buf, ",serial=%s", def->system_serial);
+ if (def->serial)
+ virBufferAsprintf(&buf, ",serial=%s", def->serial);
/* 1:UUID */
- if (def->system_uuid && !skip_uuid)
- virBufferAsprintf(&buf, ",uuid=%s", def->system_uuid);
+ if (def->uuid && !skip_uuid)
+ virBufferAsprintf(&buf, ",uuid=%s", def->uuid);
/* 1:SKU Number */
- if (def->system_sku)
- virBufferAsprintf(&buf, ",sku=%s", def->system_sku);
+ if (def->sku)
+ virBufferAsprintf(&buf, ",sku=%s", def->sku);
/* 1:Family */
- if (def->system_family)
- virBufferAsprintf(&buf, ",family=%s", def->system_family);
+ if (def->family)
+ virBufferAsprintf(&buf, ",family=%s", def->family);
if (virBufferCheckError(&buf) < 0)
goto error;
virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
VIR_FREE(smbioscmd);
}
- smbioscmd = qemuBuildSmbiosSystemStr(source, skip_uuid);
+ smbioscmd = qemuBuildSmbiosSystemStr(source->system, skip_uuid);
if (smbioscmd != NULL) {
virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
VIR_FREE(smbioscmd);
VIR_FREE(def);
}
+void virSysinfoSystemDefFree(virSysinfoSystemDefPtr def)
+{
+ if (def == NULL)
+ return;
+
+ VIR_FREE(def->manufacturer);
+ VIR_FREE(def->product);
+ VIR_FREE(def->version);
+ VIR_FREE(def->serial);
+ VIR_FREE(def->uuid);
+ VIR_FREE(def->sku);
+ VIR_FREE(def->family);
+ VIR_FREE(def);
+}
+
+
/**
* virSysinfoDefFree:
* @def: a sysinfo structure
return;
virSysinfoBIOSDefFree(def->bios);
-
- VIR_FREE(def->system_manufacturer);
- VIR_FREE(def->system_product);
- VIR_FREE(def->system_version);
- VIR_FREE(def->system_serial);
- VIR_FREE(def->system_uuid);
- VIR_FREE(def->system_sku);
- VIR_FREE(def->system_family);
+ virSysinfoSystemDefFree(def->system);
for (i = 0; i < def->nprocessor; i++) {
VIR_FREE(def->processor[i].processor_socket_destination);
#if defined(__powerpc__)
static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
{
+ int ret = -1;
char *eol = NULL;
const char *cur;
+ virSysinfoSystemDefPtr def;
if ((cur = strstr(base, "platform")) == NULL)
return 0;
+ if (VIR_ALLOC(def) < 0)
+ return ret;
+
base = cur;
/* Account for format 'platform : XXXX'*/
cur = strchr(cur, ':') + 1;
eol = strchr(cur, '\n');
virSkipSpaces(&cur);
- if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
+ goto cleanup;
if ((cur = strstr(base, "model")) != NULL) {
cur = strchr(cur, ':') + 1;
eol = strchr(cur, '\n');
virSkipSpaces(&cur);
- if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "machine")) != NULL) {
cur = strchr(cur, ':') + 1;
eol = strchr(cur, '\n');
virSkipSpaces(&cur);
- if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
+ goto cleanup;
}
- return 0;
+ if (!def->manufacturer && !def->product && !def->version &&
+ !def->serial && !def->uuid && !def->sku && !def->family) {
+ virSysinfoSystemDefFree(def);
+ def = NULL;
+ }
+
+ *system = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoSystemDefFree(def);
+ return ret;
}
static int
if (virSysinfoParseProcessor(outbuf, ret) < 0)
goto no_memory;
- if (virSysinfoParseSystem(outbuf, ret) < 0)
+ if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
goto no_memory;
return ret;
#elif defined(__arm__) || defined(__aarch64__)
static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
{
+ int ret = -1;
char *eol = NULL;
const char *cur;
+ virSysinfoSystemDefPtr def;
if ((cur = strstr(base, "platform")) == NULL)
return 0;
+ if (VIR_ALLOC(def) < 0)
+ return ret;
+
base = cur;
/* Account for format 'platform : XXXX'*/
cur = strchr(cur, ':') + 1;
eol = strchr(cur, '\n');
virSkipSpaces(&cur);
- if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
+ goto cleanup;
if ((cur = strstr(base, "model")) != NULL) {
cur = strchr(cur, ':') + 1;
eol = strchr(cur, '\n');
virSkipSpaces(&cur);
- if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "machine")) != NULL) {
cur = strchr(cur, ':') + 1;
eol = strchr(cur, '\n');
virSkipSpaces(&cur);
- if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
+ goto cleanup;
}
- return 0;
+ if (!def->manufacturer && !def->product && !def->version &&
+ !def->serial && !def->uuid && !def->sku && !def->family) {
+ virSysinfoSystemDefFree(def);
+ def = NULL;
+ }
+
+ *system = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoSystemDefFree(def);
+ return ret;
}
static int
if (virSysinfoParseProcessor(outbuf, ret) < 0)
goto no_memory;
- if (virSysinfoParseSystem(outbuf, ret) < 0)
+ if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
goto no_memory;
return ret;
}
static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
{
- if (virSysinfoParseLine(base, "Manufacturer",
- &ret->system_manufacturer) &&
- virSysinfoParseLine(base, "Type",
- &ret->system_family) &&
- virSysinfoParseLine(base, "Sequence Code",
- &ret->system_serial))
- return 0;
- else
- return -1;
+ int ret = -1;
+ virSysinfoSystemDefPtr def;
+
+ if (VIR_ALLOC(def) < 0)
+ return ret;
+
+ if (!virSysinfoParseLine(base, "Manufacturer",
+ &def->manufacturer))
+ goto cleanup;
+
+ if (!virSysinfoParseLine(base, "Type",
+ &def->family))
+ goto cleanup;
+
+ if (!virSysinfoParseLine(base, "Sequence Code",
+ &def->serial))
+ goto cleanup;
+
+ if (!def->manufacturer && !def->product && !def->version &&
+ !def->serial && !def->uuid && !def->sku && !def->family) {
+ virSysinfoSystemDefFree(def);
+ def = NULL;
+ }
+
+ *system = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoSystemDefFree(def);
+ return ret;
}
static int
return NULL;
}
- if (virSysinfoParseSystem(outbuf, ret) < 0)
+ if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
goto no_memory;
return ret;
}
static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
{
+ int ret = -1;
const char *cur, *eol = NULL;
+ virSysinfoSystemDefPtr def;
if ((cur = strstr(base, "System 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(ret->system_manufacturer, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->manufacturer, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "Product Name: ")) != NULL) {
cur += 14;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->system_product, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->product, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "Version: ")) != NULL) {
cur += 9;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
- return -1;
+ 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(ret->system_serial, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "UUID: ")) != NULL) {
cur += 6;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->system_uuid, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->uuid, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "SKU Number: ")) != NULL) {
cur += 12;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->system_sku, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->sku, cur, eol - cur) < 0)
+ goto cleanup;
}
if ((cur = strstr(base, "Family: ")) != NULL) {
cur += 8;
eol = strchr(cur, '\n');
- if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
- return -1;
+ if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
+ goto cleanup;
}
- return 0;
+ if (!def->manufacturer && !def->product && !def->version &&
+ !def->serial && !def->uuid && !def->sku && !def->family) {
+ virSysinfoSystemDefFree(def);
+ def = NULL;
+ }
+
+ *system = def;
+ def = NULL;
+ ret = 0;
+ cleanup:
+ virSysinfoSystemDefFree(def);
+ return ret;
}
static int
if (virSysinfoParseBIOS(outbuf, &ret->bios) < 0)
goto error;
- if (virSysinfoParseSystem(outbuf, ret) < 0)
+ if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
goto error;
ret->nprocessor = 0;
}
static void
-virSysinfoSystemFormat(virBufferPtr buf, virSysinfoDefPtr def)
+virSysinfoSystemFormat(virBufferPtr buf, virSysinfoSystemDefPtr def)
{
- if (!def->system_manufacturer && !def->system_product &&
- !def->system_version && !def->system_serial &&
- !def->system_uuid && !def->system_sku && !def->system_family)
+ if (!def)
return;
virBufferAddLit(buf, "<system>\n");
virBufferAdjustIndent(buf, 2);
virBufferEscapeString(buf, "<entry name='manufacturer'>%s</entry>\n",
- def->system_manufacturer);
+ def->manufacturer);
virBufferEscapeString(buf, "<entry name='product'>%s</entry>\n",
- def->system_product);
+ def->product);
virBufferEscapeString(buf, "<entry name='version'>%s</entry>\n",
- def->system_version);
+ def->version);
virBufferEscapeString(buf, "<entry name='serial'>%s</entry>\n",
- def->system_serial);
+ def->serial);
virBufferEscapeString(buf, "<entry name='uuid'>%s</entry>\n",
- def->system_uuid);
+ def->uuid);
virBufferEscapeString(buf, "<entry name='sku'>%s</entry>\n",
- def->system_sku);
+ def->sku);
virBufferEscapeString(buf, "<entry name='family'>%s</entry>\n",
- def->system_family);
+ def->family);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</system>\n");
}
virBufferAdjustIndent(&childrenBuf, indent + 2);
virSysinfoBIOSFormat(&childrenBuf, def->bios);
- virSysinfoSystemFormat(&childrenBuf, def);
+ virSysinfoSystemFormat(&childrenBuf, def->system);
virSysinfoProcessorFormat(&childrenBuf, def);
virSysinfoMemoryFormat(&childrenBuf, def);
return identical;
}
+static bool
+virSysinfoSystemIsEqual(virSysinfoSystemDefPtr src,
+ virSysinfoSystemDefPtr 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(manufacturer, "system vendor");
+ CHECK_FIELD(product, "system product");
+ CHECK_FIELD(version, "system version");
+ CHECK_FIELD(serial, "system serial");
+ CHECK_FIELD(uuid, "system uuid");
+ CHECK_FIELD(sku, "system sku");
+ CHECK_FIELD(family, "system family");
+
+ identical = true;
+ cleanup:
+ return identical;
+}
+
+#undef CHECK_FIELD
+
bool virSysinfoIsEqual(virSysinfoDefPtr src,
virSysinfoDefPtr dst)
{
if (!virSysinfoBIOSIsEqual(src->bios, dst->bios))
goto cleanup;
- CHECK_FIELD(system_manufacturer, "system vendor");
- CHECK_FIELD(system_product, "system product");
- CHECK_FIELD(system_version, "system version");
- CHECK_FIELD(system_serial, "system serial");
- CHECK_FIELD(system_uuid, "system uuid");
- CHECK_FIELD(system_sku, "system sku");
- CHECK_FIELD(system_family, "system family");
-
-#undef CHECK_FIELD
+ if (!virSysinfoSystemIsEqual(src->system, dst->system))
+ goto cleanup;
identical = true;