mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-06 20:00:05 +00:00
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: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
a377408f0b
commit
3f9cae18fe
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user