From: Peter Xu <peterx@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH RFC] qemu-error: introduce error_report_once
Date: Tue, 15 May 2018 20:38:27 +0800 [thread overview]
Message-ID: <20180515123827.GB9089@xz-mi> (raw)
In-Reply-To: <87mux16s9c.fsf@dusky.pond.sub.org>
On Tue, May 15, 2018 at 02:02:55PM +0200, Markus Armbruster wrote:
> Peter Xu <peterx@redhat.com> writes:
>
> > I stole the printk_once() macro.
> >
> > I always wanted to be able to print some error directly if there is a
> > buffer to dump, however we can't use error_report() really quite often
> > when there can be any DDOS attack.
>
> Got an example?
There aren't much, but there are still some error_report()s that can
be used in frequently called functions, especially on IO paths. For
example:
*** hw/usb/dev-storage.c:
usb_msd_handle_data[422] error_report("usb-msd: Bad CBW size");
usb_msd_handle_data[427] error_report("usb-msd: Bad signature %08x",
usb_msd_handle_data[434] error_report("usb-msd: Bad LUN %d", cbw.lun);
*** hw/usb/dev-uas.c:
usb_uas_handle_control[656] error_report("%s: unhandled control request (req 0x%x, val 0x%x, idx 0x%x",
usb_uas_handle_data[823] error_report("%s: unknown command iu: id 0x%x",
usb_uas_handle_data[870] error_report("%s: no inflight request", __func__);
usb_uas_handle_data[888] error_report("%s: invalid endpoint %d", __func__, p->ep->nr);
*** hw/virtio/vhost-user.c:
vhost_user_read[208] error_report("Failed to read msg header. Read %d instead of %d."
vhost_user_read[215] error_report("Failed to read msg header."
vhost_user_read[223] error_report("Failed to read msg header."
vhost_user_read[234] error_report("Failed to read msg payload."
process_message_reply[260] error_report("Received unexpected msg type."
vhost_user_write[302] error_report("Failed to set msg fds.");
vhost_user_write[308] error_report("Failed to write msg."
...
slave_read[859] error_report("Failed to read from slave.");
slave_read[864] error_report("Failed to read msg header."
slave_read[873] error_report("Failed to read payload from slave.");
slave_read[885] error_report("Received unexpected msg type.");
slave_read[910] error_report("Failed to send msg reply to slave.");
...
I only picked some of the callers, they might not all suite in this
case, but just to show what I mean.
Another example is 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 DDOS attack,
say, an evil guest might trigger this error tons of times to even use
up a host's disk space (e.g., in libvirt qemu log, since libvirt might
capture that). However using trace points mean that errors are not
dumped if trace not enabled.
So this print_once() thing 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 avoid that, we can introduce a
> > print-once function for it.
> >
> > CC: Markus Armbruster <armbru@redhat.com>
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> > We can for sure introduce similar functions for the rest of the
> > error_*() functions, it's just an idea to see whether we'd like it
> > in general.
> > ---
> > include/qemu/error-report.h | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
> > index e1c8ae1a52..efebb80e2c 100644
> > --- a/include/qemu/error-report.h
> > +++ b/include/qemu/error-report.h
> > @@ -44,6 +44,18 @@ 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);
> >
> > +#define error_report_once(fmt, ...) \
> > + ({ \
> > + static bool __print_once; \
> > + bool __ret_print_once = !__print_once; \
> > + \
> > + if (!__print_once) { \
> > + __print_once = true; \
> > + error_report(fmt, ##__VA_ARGS__); \
> > + } \
> > + unlikely(__ret_print_once); \
> > + })
> > +
> > const char *error_get_progname(void);
> > extern bool enable_timestamp_msg;
>
> Ignorant question: what's the return value's intended use?
For me I don't need it, I just didn't see a reason to remove it - it's
quite cheap as a stack variable (comparing to the heap variable
__print_once which will really consume some byte in the binaries) and
basically it works just like we exported that __print_once when
needed, so I kept it in case people might use it.
One example I can think of is that we can keep some error environment
when the first error happens:
if (something_wrong_happened) {
if (error_report_once("blablabla")) {
/* only cache the first error */
error_cmd = xxx;
error_param = xxx;
...
}
}
Regards,
--
Peter Xu
next prev parent reply other threads:[~2018-05-15 12:38 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-15 9:13 [Qemu-devel] [PATCH RFC] qemu-error: introduce error_report_once Peter Xu
2018-05-15 9:16 ` no-reply
2018-05-15 12:02 ` Markus Armbruster
2018-05-15 12:38 ` Peter Xu [this message]
2018-05-15 15:56 ` Markus Armbruster
2018-05-15 16:39 ` Eric Blake
2018-05-16 3:08 ` Peter Xu
2018-05-15 15:29 ` Eric Blake
2018-05-16 3:07 ` Peter Xu
2018-05-16 14:02 ` Eric Blake
2018-05-17 2:51 ` Peter Xu
2018-05-31 11:03 ` Stefan Hajnoczi
2018-06-01 3:17 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180515123827.GB9089@xz-mi \
--to=peterx@redhat.com \
--cc=armbru@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).