From nobody Mon Feb 9 03:13:42 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534327015151266.87355572966067; Wed, 15 Aug 2018 02:56:55 -0700 (PDT) Received: from localhost ([::1]:48278 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpsXu-0006GB-3A for importer@patchew.org; Wed, 15 Aug 2018 05:56:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52613) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpsUs-0004BF-01 for qemu-devel@nongnu.org; Wed, 15 Aug 2018 05:53:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpsUq-0002rP-Vc for qemu-devel@nongnu.org; Wed, 15 Aug 2018 05:53:45 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:45966 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fpsUq-0002q9-Lr for qemu-devel@nongnu.org; Wed, 15 Aug 2018 05:53:44 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3461581663F1; Wed, 15 Aug 2018 09:53:44 +0000 (UTC) Received: from xz-mi.redhat.com (ovpn-12-105.pek2.redhat.com [10.72.12.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 00CB72026D7E; Wed, 15 Aug 2018 09:53:39 +0000 (UTC) From: Peter Xu To: qemu-devel@nongnu.org Date: Wed, 15 Aug 2018 17:53:26 +0800 Message-Id: <20180815095328.32414-2-peterx@redhat.com> In-Reply-To: <20180815095328.32414-1-peterx@redhat.com> References: <20180815095328.32414-1-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 15 Aug 2018 09:53:44 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 15 Aug 2018 09:53:44 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'peterx@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v5 1/3] qemu-error: introduce {error|warn}_report_once X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , "Michael S . Tsirkin" , Jason Wang , Cornelia Huck , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , peterx@redhat.com, Markus Armbruster , Halil Pasic , Eric Auger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" There are many error_report()s that can be used in frequently called functions, especially on IO paths. That can be unideal in that malicious guest can try to trigger the error tons of time which might use up the log space on the host (e.g., libvirt can capture the stderr of QEMU and put it persistently onto disk). In VT-d emulation code, we have trace_vtd_error() tracer. AFAIU all those places can be replaced by something like error_report() but trace points are mostly used to avoid the DDOS attack that mentioned above. However using trace points mean that errors are not dumped if trace not enabled. It's not a big deal in most modern server managements since we have things like logrotate to maintain the logs and make sure the quota is expected. However it'll still be nice that we just provide another way to restrict message generations. In most cases, this kind of error_report()s will only provide valid information on the first message sent, and all the rest of similar messages will be mostly talking about the same thing. This patch introduces *_report_once() helpers to allow a message to be dumped only once during one QEMU process's life cycle. It will make sure: (1) it's on by deffault, so we can even get something without turning the trace on and reproducing, and (2) it won't be affected by DDOS attack. To implement it, I stole the printk_once() macro from Linux. CC: Eric Blake CC: Markus Armbruster Signed-off-by: Peter Xu Reviewed-by: Markus Armbruster --- include/qemu/error-report.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h index e1c8ae1a52..c7ec54cb97 100644 --- a/include/qemu/error-report.h +++ b/include/qemu/error-report.h @@ -44,6 +44,38 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, = 2); void warn_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void info_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); =20 +/* + * Similar to error_report(), but it only prints the message once. It + * returns true when it prints the first time, otherwise false. + */ +#define error_report_once(fmt, ...) \ + ({ \ + static bool print_once_; \ + bool ret_print_once_ =3D !print_once_; \ + \ + if (!print_once_) { \ + print_once_ =3D true; \ + error_report(fmt, ##__VA_ARGS__); \ + } \ + unlikely(ret_print_once_); \ + }) + +/* + * Similar to warn_report(), but it only prints the message once. It + * returns true when it prints the first time, otherwise false. + */ +#define warn_report_once(fmt, ...) \ + ({ \ + static bool print_once_; \ + bool ret_print_once_ =3D !print_once_; \ + \ + if (!print_once_) { \ + print_once_ =3D true; \ + warn_report(fmt, ##__VA_ARGS__); \ + } \ + unlikely(ret_print_once_); \ + }) + const char *error_get_progname(void); extern bool enable_timestamp_msg; =20 --=20 2.17.1