From nobody Thu May 15 06:04:19 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1513254865595922.075526753068; Thu, 14 Dec 2017 04:34:25 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 60BF0C074F14; Thu, 14 Dec 2017 12:34:24 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3B72860C9F; Thu, 14 Dec 2017 12:34:24 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 090FE3D3D4; Thu, 14 Dec 2017 12:34:24 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vBECYMjC011150 for ; Thu, 14 Dec 2017 07:34:22 -0500 Received: by smtp.corp.redhat.com (Postfix) id 8F2236061E; Thu, 14 Dec 2017 12:34:22 +0000 (UTC) Received: from inaba.usersys.redhat.com (ovpn-204-182.brq.redhat.com [10.40.204.182]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D6F6060A9D for ; Thu, 14 Dec 2017 12:34:20 +0000 (UTC) From: Andrea Bolognani To: libvir-list@redhat.com Date: Thu, 14 Dec 2017 13:34:00 +0100 Message-Id: <20171214123401.28950-5-abologna@redhat.com> In-Reply-To: <20171214123401.28950-1-abologna@redhat.com> References: <20171214123401.28950-1-abologna@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v3 4/5] util: Improve CPU frequency parsing X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 14 Dec 2017 12:34:24 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Make the parser both more strict, by not ignoring errors reported by virStrToLong_ui(), and more permissive, by not failing due to unrelated fields which just happen to have a know prefix and accepting any amount of whitespace before the numeric value. Signed-off-by: Andrea Bolognani Reviewed-by: Bjoern Walk --- src/util/virhostcpu.c | 62 +++++++++++++++++++++= ---- tests/virhostcpudata/linux-x86_64-test1.cpuinfo | 4 ++ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c index 3c20755eb..9c9f362de 100644 --- a/src/util/virhostcpu.c +++ b/src/util/virhostcpu.c @@ -508,6 +508,27 @@ virHostCPUHasValidSubcoreConfiguration(int threads_per= _subcore) return ret; } =20 +/** + * virHostCPUParseFrequencyString: + * @str: string to be parsed + * @prefix: expected prefix + * @mhz: output location + * + * Parse a /proc/cpuinfo line and extract the CPU frequency, if present. + * + * The expected format of @str looks like + * + * cpu MHz : 2100.000 + * + * where @prefix ("cpu MHz" in the example), is architecture-dependent. + * + * The decimal part of the CPU frequency, as well as all whitespace, is + * ignored. + * + * Returns: 0 when the string has been parsed successfully and the CPU + * frequency has been stored in @mhz, >0 when the string has not + * been parsed but no error has occurred, <0 on failure. + */ static int virHostCPUParseFrequencyString(const char *str, const char *prefix, @@ -516,26 +537,49 @@ virHostCPUParseFrequencyString(const char *str, char *p; unsigned int ui; =20 + /* If the string doesn't start with the expected prefix, then + * we're not looking at the right string and we should move on */ if (!STRPREFIX(str, prefix)) return 1; =20 + /* Skip the prefix */ str +=3D strlen(prefix); =20 - while (*str && c_isspace(*str)) + /* Skip all whitespace */ + while (c_isspace(*str)) str++; + if (*str =3D=3D '\0') + goto error; =20 - if (*str !=3D ':' || !str[1]) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("parsing cpu MHz from cpuinfo")); - return -1; + /* Skip the colon. If anything but a colon is found, then we're + * not looking at the right string and we should move on */ + if (*str !=3D ':') + return 1; + str++; + + /* Skip all whitespace */ + while (c_isspace(*str)) + str++; + if (*str =3D=3D '\0') + goto error; + + /* Parse the frequency. We expect an unsigned value, optionally + * followed by a fractional part (which gets discarded) or some + * leading whitespace */ + if (virStrToLong_ui(str, &p, 10, &ui) < 0 || + (*p !=3D '.' && *p !=3D '\0' && !c_isspace(*p))) { + goto error; } =20 - if (virStrToLong_ui(str + 1, &p, 10, &ui) =3D=3D 0 && - /* Accept trailing fractional part. */ - (*p =3D=3D '\0' || *p =3D=3D '.' || c_isspace(*p))) - *mhz =3D ui; + *mhz =3D ui; =20 return 0; + + error: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid CPU frequency in %s"), + CPUINFO_PATH); + return -1; } =20 static int diff --git a/tests/virhostcpudata/linux-x86_64-test1.cpuinfo b/tests/virhos= tcpudata/linux-x86_64-test1.cpuinfo index e88a48ff3..706b69a54 100644 --- a/tests/virhostcpudata/linux-x86_64-test1.cpuinfo +++ b/tests/virhostcpudata/linux-x86_64-test1.cpuinfo @@ -28,6 +28,10 @@ model : 4 model name : Intel(R) Xeon(TM) CPU 2.80GHz stepping : 8 cpu MHz : 2800.000 +# The following field is a made-up one, intended to make sure our cpuinfo +# parser deals correctly with the introduction of new fields that just so +# happen to share a prefix with the one used for CPU frequency +cpu MHz rounded up to GHz : 3000.000 cache size : 2048 KB physical id : 0 siblings : 2 --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list