Blame SOURCES/kvm-qemu-error-introduce-error-warn-_report_once.patch

7711c0
From 22b617c9f567f65f72a29fff454a40f4ed67b45d Mon Sep 17 00:00:00 2001
7711c0
From: Peter Xu <peterx@redhat.com>
7711c0
Date: Thu, 8 Nov 2018 05:37:15 +0100
7711c0
Subject: [PATCH 08/22] qemu-error: introduce {error|warn}_report_once
7711c0
MIME-Version: 1.0
7711c0
Content-Type: text/plain; charset=UTF-8
7711c0
Content-Transfer-Encoding: 8bit
7711c0
7711c0
RH-Author: Peter Xu <peterx@redhat.com>
7711c0
Message-id: <20181108053721.13162-2-peterx@redhat.com>
7711c0
Patchwork-id: 82951
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 1/7] qemu-error: introduce {error|warn}_report_once
7711c0
Bugzilla: 1627272
7711c0
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
7711c0
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
7711c0
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7711c0
7711c0
There are many error_report()s that can be used in frequently called
7711c0
functions, especially on IO paths.  That can be unideal in that
7711c0
malicious guest can try to trigger the error tons of time which might
7711c0
use up the log space on the host (e.g., libvirt can capture the stderr
7711c0
of QEMU and put it persistently onto disk).  In VT-d emulation code, we
7711c0
have trace_vtd_error() tracer.  AFAIU all those places can be replaced
7711c0
by something like error_report() but trace points are mostly used to
7711c0
avoid the DDOS attack that mentioned above.  However using trace points
7711c0
mean that errors are not dumped if trace not enabled.
7711c0
7711c0
It's not a big deal in most modern server managements since we have
7711c0
things like logrotate to maintain the logs and make sure the quota is
7711c0
expected.  However it'll still be nice that we just provide another way
7711c0
to restrict message generations.  In most cases, this kind of
7711c0
error_report()s will only provide valid information on the first message
7711c0
sent, and all the rest of similar messages will be mostly talking about
7711c0
the same thing.  This patch introduces *_report_once() helpers to allow
7711c0
a message to be dumped only once during one QEMU process's life cycle.
7711c0
It will make sure: (1) it's on by deffault, so we can even get something
7711c0
without turning the trace on and reproducing, and (2) it won't be
7711c0
affected by DDOS attack.
7711c0
7711c0
To implement it, I stole the printk_once() macro from Linux.
7711c0
7711c0
CC: Eric Blake <eblake@redhat.com>
7711c0
CC: Markus Armbruster <armbru@redhat.com>
7711c0
Signed-off-by: Peter Xu <peterx@redhat.com>
7711c0
Message-Id: <20180815095328.32414-2-peterx@redhat.com>
7711c0
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7711c0
[Whitespace adjusted, comments improved]
7711c0
Signed-off-by: Markus Armbruster <armbru@redhat.com>
7711c0
(cherry picked from commit bc6a69dd4bfa41ae56235dcbb9a28a56e12a7dc6)
7711c0
Signed-off-by: Peter Xu <peterx@redhat.com>
7711c0
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 include/qemu/error-report.h | 32 ++++++++++++++++++++++++++++++++
7711c0
 1 file changed, 32 insertions(+)
7711c0
7711c0
diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
7711c0
index e1c8ae1..72fab2b 100644
7711c0
--- a/include/qemu/error-report.h
7711c0
+++ b/include/qemu/error-report.h
7711c0
@@ -44,6 +44,38 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
7711c0
 void warn_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
7711c0
 void info_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
7711c0
 
7711c0
+/*
7711c0
+ * Similar to error_report(), except it prints the message just once.
7711c0
+ * Return true when it prints, false otherwise.
7711c0
+ */
7711c0
+#define error_report_once(fmt, ...)             \
7711c0
+    ({                                          \
7711c0
+        static bool print_once_;                \
7711c0
+        bool ret_print_once_ = !print_once_;    \
7711c0
+                                                \
7711c0
+        if (!print_once_) {                     \
7711c0
+            print_once_ = true;                 \
7711c0
+            error_report(fmt, ##__VA_ARGS__);   \
7711c0
+        }                                       \
7711c0
+        unlikely(ret_print_once_);              \
7711c0
+    })
7711c0
+
7711c0
+/*
7711c0
+ * Similar to warn_report(), except it prints the message just once.
7711c0
+ * Return true when it prints, false otherwise.
7711c0
+ */
7711c0
+#define warn_report_once(fmt, ...)              \
7711c0
+    ({                                          \
7711c0
+        static bool print_once_;                \
7711c0
+        bool ret_print_once_ = !print_once_;    \
7711c0
+                                                \
7711c0
+        if (!print_once_) {                     \
7711c0
+            print_once_ = true;                 \
7711c0
+            warn_report(fmt, ##__VA_ARGS__);    \
7711c0
+        }                                       \
7711c0
+        unlikely(ret_print_once_);              \
7711c0
+    })
7711c0
+
7711c0
 const char *error_get_progname(void);
7711c0
 extern bool enable_timestamp_msg;
7711c0
 
7711c0
-- 
7711c0
1.8.3.1
7711c0