提交 3f9cae18 编写于 作者: M Michal Privoznik

virSysinfoDef: Exempt BIOS variables

Move all the bios_* fields into a separate struct. Not only this
simplifies the code a bit it also helps us to identify whether BIOS
info is present. We don't have to check all the four variables for
being not-NULL, but we can just check the pointer to the struct.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
上级 a377408f
......@@ -11093,6 +11093,65 @@ virDomainShmemDefParseXML(xmlNodePtr node,
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,
......@@ -11100,6 +11159,7 @@ virSysinfoParseXML(xmlNodePtr node,
bool uuid_generated)
{
virSysinfoDefPtr def;
xmlNodePtr oldnode, tmpnode;
char *type;
char *tmpUUID = NULL;
......@@ -11124,39 +11184,16 @@ virSysinfoParseXML(xmlNodePtr node,
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 =
......
......@@ -2182,6 +2182,7 @@ virVasprintfInternal;
# util/virsysinfo.h
virSysinfoBIOSDefFree;
virSysinfoDefFree;
virSysinfoFormat;
virSysinfoRead;
......
......@@ -6701,28 +6701,27 @@ static char *qemuBuildTPMDevStr(const virDomainDef *def,
}
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;
......@@ -9047,7 +9046,7 @@ qemuBuildCommandLine(virConnectPtr conn,
if (source != NULL) {
char *smbioscmd;
smbioscmd = qemuBuildSmbiosBiosStr(source);
smbioscmd = qemuBuildSmbiosBiosStr(source->bios);
if (smbioscmd != NULL) {
virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
VIR_FREE(smbioscmd);
......
......@@ -64,6 +64,18 @@ void virSysinfoSetup(const char *dmidecode, const char *sysinfo,
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
......@@ -78,10 +90,7 @@ void virSysinfoDefFree(virSysinfoDefPtr def)
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);
......@@ -522,40 +531,56 @@ virSysinfoRead(void)
#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
......@@ -846,7 +871,7 @@ virSysinfoRead(void)
ret->type = VIR_SYSINFO_SMBIOS;
if (virSysinfoParseBIOS(outbuf, ret) < 0)
if (virSysinfoParseBIOS(outbuf, &ret->bios) < 0)
goto error;
if (virSysinfoParseSystem(outbuf, ret) < 0)
......@@ -876,22 +901,21 @@ virSysinfoRead(void)
#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");
}
......@@ -1055,7 +1079,7 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
virBufferAdjustIndent(&childrenBuf, indent + 2);
virSysinfoBIOSFormat(&childrenBuf, def);
virSysinfoBIOSFormat(&childrenBuf, def->bios);
virSysinfoSystemFormat(&childrenBuf, def);
virSysinfoProcessorFormat(&childrenBuf, def);
virSysinfoMemoryFormat(&childrenBuf, def);
......@@ -1078,6 +1102,41 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr 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)
{
......@@ -1100,19 +1159,8 @@ bool virSysinfoIsEqual(virSysinfoDefPtr src,
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");
......
......@@ -65,15 +65,21 @@ struct _virSysinfoMemoryDef {
char *memory_part_number;
};
typedef struct _virSysinfoBIOSDef virSysinfoBIOSDef;
typedef virSysinfoBIOSDef *virSysinfoBIOSDefPtr;
struct _virSysinfoBIOSDef {
char *vendor;
char *version;
char *date;
char *release;
};
typedef struct _virSysinfoDef virSysinfoDef;
typedef virSysinfoDef *virSysinfoDefPtr;
struct _virSysinfoDef {
int type;
char *bios_vendor;
char *bios_version;
char *bios_date;
char *bios_release;
virSysinfoBIOSDefPtr bios;
char *system_manufacturer;
char *system_product;
......@@ -92,6 +98,7 @@ struct _virSysinfoDef {
virSysinfoDefPtr virSysinfoRead(void);
void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def);
void virSysinfoDefFree(virSysinfoDefPtr def);
int virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册