From patchwork Thu Jan 18 05:05:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 862760 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zMXFK3pFZz9t1t for ; Thu, 18 Jan 2018 16:14:29 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="FJhZm+rk"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fNamfIKa"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3zMXFK2HyNzF0lH for ; Thu, 18 Jan 2018 16:14:29 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="FJhZm+rk"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fNamfIKa"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="FJhZm+rk"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fNamfIKa"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3zMXCg0D63zF0hX for ; Thu, 18 Jan 2018 16:13:02 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id EF7EB20F67; Thu, 18 Jan 2018 00:05:33 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute2.internal (MEProxy); Thu, 18 Jan 2018 00:05:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=UE0Z25gcKXReuo5a0p/HPXA9e0ca967c6Oc2p+fKG/M=; b=FJhZm+rk 5r5BxGJviSpS7IIAUuiMi0HiA5AL04mZsgg3bRZLCdFEhuNoHLljPfoE8Eiqy38Z tMc/YfsmFu8YuhFXcFaSE0DUV3crYBDTWOjlPbGZrmtVSBOzKqgaOQT8jT5yXe27 5GlUKb31i6VO1uYAsFZmIJPjFz07Pi91hqHNnfHYPHF9wtqkmNMZrfQirUO1Evgh pW1QVQvS6LCWkuW7foxdYvMi39/CqyYFTW9mmKyj4gPKIgXVwnstIwIKOnxChDwD l9tS5Y5U1aNqxFPDOKxg+F1dB4wIdz4oR4IP0af49e/AkQzkLWk36BRdKdpPfUeh LanUIShRWKe3EA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=UE0Z25gcKXReuo5a0p/HPXA9e0ca967c6Oc2p+fKG/M=; b=fNamfIKa Lu+iRm+H+zsi5ITHnuhrq7GmY1NFulnmwLrgjMjy0V6OR/VPfAJS8rMD5iFdNQhx UemwPi/i+38edy+JwRB1U261ufYcPLzlufTrNdKkZAVOMaRw75/hd1zFcIQB1kQM deg5XZlS0+8odQYuzJOGzcNV35zICbAd53lyIS06peC89z+tXiqgN0BXyka8K8uS J/VnSqgwFxJK91w6jmcd6YIVLPQyJ24ZEUjIvQj2WwoIwcvlsn8U9F9883I+H+Ul kS8fZfDfPKVy7IL8PCL7o3U48Wmkv1C4H52ng7r4j27MrSj6RrQOJGdZsZqgyg8b /glK5oAUW1Gujg== X-ME-Sender: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id AA3F6240F8; Thu, 18 Jan 2018 00:05:32 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [[RFC PATCH] v2 04/14] Explicitly parse version strings read from flash Date: Thu, 18 Jan 2018 16:05:07 +1100 Message-Id: <20180118050517.2442-5-sam@mendozajonas.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180118050517.2442-1-sam@mendozajonas.com> References: <20180118050517.2442-1-sam@mendozajonas.com> X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Currently the version strings obtained from lib/flash are used as-is for display only. To usefully compare versions however this strings need to be separated into at least package name and package version. On the OpenPOWER platforms from which these versions are obtained there is a known list of package names, which hostboot_load_versions() now uses to parse each version string into a new firmware_version struct containing the name and version strings. Signed-off-by: Samuel Mendoza-Jonas --- discover/hostboot.c | 85 +++++++++++++++++++++++++++++---- lib/flash/flash.c | 4 +- lib/pb-protocol/pb-protocol.c | 108 +++++++++++++++++++++++++++++++++--------- lib/types/types.h | 13 ++++- ui/ncurses/nc-sysinfo.c | 6 ++- 5 files changed, 180 insertions(+), 36 deletions(-) diff --git a/discover/hostboot.c b/discover/hostboot.c index bc9a3ba..c63e363 100644 --- a/discover/hostboot.c +++ b/discover/hostboot.c @@ -8,19 +8,88 @@ #include "hostboot.h" +/* Check each version string against a list of known package names and split + * them into separate name and version strings. + * In a nicer world we would just split based upon a known delimeter but version + * strings on OpenPOWER platforms are not consistent. + */ +static int parse_hostboot_versions(void *ctx, char **strings, + unsigned int n_str, struct firmware_version **versions) +{ + const char * cmp_str[] = {"open-power", "buildroot", "skiboot", + "hostboot-binaries", "hostboot", "linux", "petitboot", "occ", + "capp-ucode", "machine-xml"}; + unsigned int n_names = sizeof(cmp_str) / sizeof(cmp_str[0]); + struct firmware_version *tmp = NULL; + unsigned int i, j, n_versions = 0; + bool found; + char *sep; + + for (i = 0; i < n_str; i++) { + found = false; + for (j = 0; j < n_names; j++) { + if (strncmp(strings[i], cmp_str[j], + strlen(cmp_str[j])) == 0) { + found = true; + break; + } + } + if (!found) { + pb_log("Unrecognised version in flash: %s\n", + strings[i]); + continue; + } + + sep = strings[i] + strlen(cmp_str[j]); + *sep = '\0'; + tmp = talloc_realloc(ctx, tmp, struct firmware_version, + n_versions + 1); + if (!tmp) + return -ENOMEM; + tmp[n_versions].name = talloc_strdup(tmp, strings[i]); + tmp[n_versions].version = talloc_strdup(tmp, sep + 1); + n_versions++; + } + + *versions = tmp; + return n_versions; +} + void hostboot_load_versions(struct system_info *info) { + char **strings = NULL; int n = 0; - n = flash_parse_version(info, &info->platform_primary, true); - if (n < 0) + n = flash_parse_version(info, &strings, true); + if (n < 0) { pb_log("Failed to read platform versions for current side\n"); - else - info->n_primary = n; + return; + } - n = flash_parse_version(info, &info->platform_other, false); - if (n < 0) + n = parse_hostboot_versions(info, strings, n, &info->platform_primary); + if (n < 0) { + pb_log("Failed to parse platform versions for current side\n"); + return; + } + info->n_primary = n; + + n = 0; + talloc_free(strings); + strings = NULL; + + n = flash_parse_version(info, &strings, false); + if (n < 0) { pb_log("Failed to read platform versions for other side\n"); - else - info->n_other = n; + return; + } + + n = parse_hostboot_versions(info, strings, n, &info->platform_other); + if (n < 0) { + pb_log("Failed to parse platform versions for current side\n"); + return; + } + info->n_other = n; + + + talloc_free(strings); } diff --git a/lib/flash/flash.c b/lib/flash/flash.c index 464b876..2322da6 100644 --- a/lib/flash/flash.c +++ b/lib/flash/flash.c @@ -190,7 +190,7 @@ int flash_parse_version(void *ctx, char ***versions, bool current) pb_log("%s: Failed to allocate memory\n", __func__); goto out; } - tmp[n++] = talloc_strdup(ctx, tok); + tmp[n++] = talloc_strdup(tmp, tok); } tok = strtok_r(NULL, delim, &saveptr); @@ -202,7 +202,7 @@ int flash_parse_version(void *ctx, char ***versions, bool current) n = 0; goto out; } - tmp[n++] = talloc_strdup(ctx, tok + 1); + tmp[n++] = talloc_strdup(tmp, tok + 1); tok = strtok_r(NULL, delim, &saveptr); } diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c index dbbda40..76a2665 100644 --- a/lib/pb-protocol/pb-protocol.c +++ b/lib/pb-protocol/pb-protocol.c @@ -226,6 +226,21 @@ int pb_protocol_boot_status_len(const struct status *status) 4; } +static int pb_protocol_firmware_version_len( + const struct firmware_version *versions, + unsigned int n_versions) +{ + unsigned int i; + int len = 0; + + for (i = 0; i < n_versions; i++) { + len += 4 + optional_strlen(versions[i].name); + len += 4 + optional_strlen(versions[i].version); + } + + return len; +} + int pb_protocol_system_info_len(const struct system_info *sysinfo) { unsigned int len, i; @@ -234,12 +249,15 @@ int pb_protocol_system_info_len(const struct system_info *sysinfo) 4 + optional_strlen(sysinfo->identifier) + 4 + 4; - len += 4; - for (i = 0; i < sysinfo->n_primary; i++) - len += 4 + optional_strlen(sysinfo->platform_primary[i]); - len += 4; - for (i = 0; i < sysinfo->n_other; i++) - len += 4 + optional_strlen(sysinfo->platform_other[i]); + len += 4 /* n_primary */; + len += pb_protocol_firmware_version_len(sysinfo->platform_primary, + sysinfo->n_primary); + len += 4 /* n_other */; + len += pb_protocol_firmware_version_len(sysinfo->platform_other, + sysinfo->n_other); + len += 4 /* n_new */; + len += pb_protocol_firmware_version_len(sysinfo->platform_new, + sysinfo->n_new); len += 4; for (i = 0; i < sysinfo->n_bmc_current; i++) @@ -447,6 +465,21 @@ int pb_protocol_serialise_boot_status(const struct status *status, return 0; } +static int pb_protocol_serialse_firmware_version( + const struct firmware_version *versions, + unsigned int n_versions, char *buf) +{ + char *pos = buf; + unsigned int i; + + for (i = 0; i < n_versions; i++) { + pos += pb_protocol_serialise_string(pos, versions[i].name); + pos += pb_protocol_serialise_string(pos, versions[i].version); + } + + return pos - buf; +} + int pb_protocol_serialise_system_info(const struct system_info *sysinfo, char *buf, int buf_len) { @@ -458,13 +491,18 @@ int pb_protocol_serialise_system_info(const struct system_info *sysinfo, *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_primary); pos += sizeof(uint32_t); - for (i = 0; i < sysinfo->n_primary; i++) - pos += pb_protocol_serialise_string(pos, sysinfo->platform_primary[i]); + pos += pb_protocol_serialse_firmware_version( + sysinfo->platform_primary, sysinfo->n_primary, pos); *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_other); pos += sizeof(uint32_t); - for (i = 0; i < sysinfo->n_other; i++) - pos += pb_protocol_serialise_string(pos, sysinfo->platform_other[i]); + pos += pb_protocol_serialse_firmware_version( + sysinfo->platform_other, sysinfo->n_other, pos); + + *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_new); + pos += sizeof(uint32_t); + pos += pb_protocol_serialse_firmware_version( + sysinfo->platform_new, sysinfo->n_new, pos); *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_bmc_current); pos += sizeof(uint32_t); @@ -921,6 +959,25 @@ out: return rc; } +static int pb_protocol_deserialise_firmware_version(const char **buf, + unsigned int *len, struct firmware_version *versions, + unsigned int n_versions) +{ + unsigned int i; + char *tmp; + + for (i = 0; i < n_versions; i++) { + if (read_string(versions, buf, len, &tmp)) + return -1; + versions[i].name = talloc_strdup(versions, tmp); + if (read_string(versions, buf, len, &tmp)) + return -1; + versions[i].version = talloc_strdup(versions, tmp); + } + + return 0; +} + int pb_protocol_deserialise_system_info(struct system_info *sysinfo, const struct pb_protocol_message *message) { @@ -942,23 +999,30 @@ int pb_protocol_deserialise_system_info(struct system_info *sysinfo, /* Platform version strings for openpower platforms */ if (read_u32(&pos, &len, &sysinfo->n_primary)) goto out; - sysinfo->platform_primary = talloc_array(sysinfo, char *, + sysinfo->platform_primary = talloc_array(sysinfo, + struct firmware_version, sysinfo->n_primary); - for (i = 0; i < sysinfo->n_primary; i++) { - if (read_string(sysinfo, &pos, &len, &tmp)) - goto out; - sysinfo->platform_primary[i] = talloc_strdup(sysinfo, tmp); - } + if (pb_protocol_deserialise_firmware_version(&pos, &len, + sysinfo->platform_primary, sysinfo->n_primary)) + goto out; if (read_u32(&pos, &len, &sysinfo->n_other)) goto out; - sysinfo->platform_other = talloc_array(sysinfo, char *, + sysinfo->platform_other = talloc_array(sysinfo, + struct firmware_version, sysinfo->n_other); - for (i = 0; i < sysinfo->n_other; i++) { - if (read_string(sysinfo, &pos, &len, &tmp)) - goto out; - sysinfo->platform_other[i] = talloc_strdup(sysinfo, tmp); - } + if (pb_protocol_deserialise_firmware_version(&pos, &len, + sysinfo->platform_other, sysinfo->n_other)) + goto out; + + if (read_u32(&pos, &len, &sysinfo->n_new)) + goto out; + sysinfo->platform_new = talloc_array(sysinfo, + struct firmware_version, + sysinfo->n_new); + if (pb_protocol_deserialise_firmware_version(&pos, &len, + sysinfo->platform_new, sysinfo->n_new)) + goto out; /* BMC version strings for openpower platforms */ if (read_u32(&pos, &len, &sysinfo->n_bmc_current)) diff --git a/lib/types/types.h b/lib/types/types.h index 9ab2a43..f4312e6 100644 --- a/lib/types/types.h +++ b/lib/types/types.h @@ -118,13 +118,22 @@ struct blockdev_info { char *mountpoint; }; +struct firmware_version { + char *name; + char *version; +}; + struct system_info { char *type; char *identifier; - char **platform_primary; - char **platform_other; + + struct firmware_version *platform_primary; unsigned int n_primary; + struct firmware_version *platform_other; unsigned int n_other; + struct firmware_version *platform_new; + unsigned int n_new; + char **bmc_current; char **bmc_golden; unsigned int n_bmc_current; diff --git a/ui/ncurses/nc-sysinfo.c b/ui/ncurses/nc-sysinfo.c index 8252b45..2d3ce82 100644 --- a/ui/ncurses/nc-sysinfo.c +++ b/ui/ncurses/nc-sysinfo.c @@ -69,7 +69,8 @@ static void sysinfo_screen_populate(struct sysinfo_screen *screen, line(NULL); line("%s", _("Primary platform versions:")); for (i = 0; i < sysinfo->n_primary; i++) { - line("\t%s", sysinfo->platform_primary[i] ?: ""); + line("\t%s: %s", sysinfo->platform_primary[i].name, + sysinfo->platform_primary[i].version); } } @@ -77,7 +78,8 @@ static void sysinfo_screen_populate(struct sysinfo_screen *screen, line(NULL); line("%s", _("Alternate platform versions:")); for (i = 0; i < sysinfo->n_other; i++) { - line("\t%s", sysinfo->platform_other[i] ?: ""); + line("\t%s: %s", sysinfo->platform_other[i].name, + sysinfo->platform_other[i].version); } }