virsysinfo: Calculate OEM string index better

As can be seen in earlier commits, there can be two OEM strings
with the same index. But since our parser
(virSysinfoParseOEMStrings()) doesn't expect that, it increments
index in each run and thus skips over these strings.
Fortunately, we have the right index at hand - we're just
skipping over it in a loop. Just reconstruct the index back
inside the loop.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Michal Privoznik 2024-07-18 15:09:22 +02:00
parent 5bb4540dbb
commit bd11c753f3
3 changed files with 18 additions and 11 deletions

View File

@ -895,13 +895,13 @@ virSysinfoParseX86Chassis(const char *base,
static int
virSysinfoDMIDecodeOEMString(size_t i,
virSysinfoDMIDecodeOEMString(unsigned int idx,
char **str)
{
g_autofree char *err = NULL;
g_autoptr(virCommand) cmd = virCommandNewArgList(DMIDECODE, "--dump",
"--oem-string", NULL);
virCommandAddArgFormat(cmd, "%zu", i);
virCommandAddArgFormat(cmd, "%u", idx);
virCommandSetOutputBuffer(cmd, str);
virCommandSetErrorBuffer(cmd, &err);
@ -936,7 +936,6 @@ virSysinfoParseOEMStrings(const char *base,
virSysinfoOEMStringsDef **stringsRet)
{
virSysinfoOEMStringsDef *strings = NULL;
size_t i = 1;
int ret = -1;
const char *cur;
@ -946,6 +945,8 @@ virSysinfoParseOEMStrings(const char *base,
strings = g_new0(virSysinfoOEMStringsDef, 1);
while ((cur = strstr(cur, "String "))) {
char *collon = NULL;
unsigned int idx = 0;
char *eol;
cur += 7;
@ -956,8 +957,13 @@ virSysinfoParseOEMStrings(const char *base,
goto cleanup;
}
while (g_ascii_isdigit(*cur))
cur++;
if (virStrToLong_ui(cur, &collon, 10, &idx) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Malformed output of dmidecode"));
goto cleanup;
}
cur = collon;
if (*cur != ':') {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -980,7 +986,7 @@ virSysinfoParseOEMStrings(const char *base,
if (memchr(cur, '.', eol - cur)) {
char *str;
if (virSysinfoDMIDecodeOEMString(i, &str) < 0)
if (virSysinfoDMIDecodeOEMString(idx, &str) < 0)
goto cleanup;
strings->values[strings->nvalues - 1] = g_steal_pointer(&str);
@ -988,7 +994,6 @@ virSysinfoParseOEMStrings(const char *base,
strings->values[strings->nvalues - 1] = g_strndup(cur, eol - cur);
}
i++;
cur = eol;
}

View File

@ -82,9 +82,7 @@
<oemStrings>
<entry>Default string</entry>
<entry>ThunderX2 System</entry>
<entry>Ha ha ha try parsing\n
String 3: this correctly
String 4:then</entry>
<entry>Some valid OEM string</entry>
<entry>Comanche</entry>
</oemStrings>
</sysinfo>

View File

@ -63,7 +63,11 @@ testDMIDecodeDryRun(const char *const*args G_GNUC_UNUSED,
return;
}
if (STREQ(args[3], "3")) {
if (STREQ(args[3], "2")) {
*output = g_strdup("Some valid OEM string\n");
*error = g_strdup_printf("No OEM string number %s", args[3]);
return;
} else if (STREQ(args[3], "3")) {
*output = g_strdup("Ha ha ha try parsing\\n\n"
" String 3: this correctly\n"
" String 4:then\n");