[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 04/24] util/log: Always send errors to logfile when daemonized
From: |
Paolo Bonzini |
Subject: |
[PULL 04/24] util/log: Always send errors to logfile when daemonized |
Date: |
Wed, 21 Dec 2022 19:01:21 +0100 |
From: Greg Kurz <groug@kaod.org>
When QEMU is started with `-daemonize`, all stdio descriptors get
redirected to `/dev/null`. This basically means that anything
printed with error_report() and friends is lost.
Current logging code allows to redirect to a file with `-D` but
this requires to enable some logging item with `-d` as well to
be functional.
Relax the check on the log flags when QEMU is daemonized, so that
other users of stderr can benefit from the redirection, without the
need to enable unwanted debug logs. Previous behaviour is retained
for the non-daemonized case. The logic is unrolled as an `if` for
better readability. The qemu_log_level and log_per_thread globals
reflect the state we want to transition to at this point : use
them instead of the intermediary locals for correctness.
qemu_set_log_internal() is adapted to open a per-thread log file
when '-d tid' is passed. This is done by hijacking qemu_try_lock()
which seems simpler that refactoring the code.
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <20221108140032.1460307-3-groug@kaod.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
util/log.c | 72 ++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 53 insertions(+), 19 deletions(-)
diff --git a/util/log.c b/util/log.c
index fb843453dd49..7837ff991769 100644
--- a/util/log.c
+++ b/util/log.c
@@ -79,13 +79,15 @@ static int log_thread_id(void)
static void qemu_log_thread_cleanup(Notifier *n, void *unused)
{
- fclose(thread_file);
- thread_file = NULL;
+ if (thread_file != stderr) {
+ fclose(thread_file);
+ thread_file = NULL;
+ }
}
/* Lock/unlock output. */
-FILE *qemu_log_trylock(void)
+static FILE *qemu_log_trylock_with_err(Error **errp)
{
FILE *logfile;
@@ -96,6 +98,9 @@ FILE *qemu_log_trylock(void)
= g_strdup_printf(global_filename, log_thread_id());
logfile = fopen(filename, "w");
if (!logfile) {
+ error_setg_errno(errp, errno,
+ "Error opening logfile %s for thread %d",
+ filename, log_thread_id());
return NULL;
}
thread_file = logfile;
@@ -122,6 +127,11 @@ FILE *qemu_log_trylock(void)
return logfile;
}
+FILE *qemu_log_trylock(void)
+{
+ return qemu_log_trylock_with_err(NULL);
+}
+
void qemu_log_unlock(FILE *logfile)
{
if (logfile) {
@@ -265,16 +275,21 @@ static bool qemu_set_log_internal(const char *filename,
bool changed_name,
#endif
qemu_loglevel = log_flags;
- /*
- * In all cases we only log if qemu_loglevel is set.
- * Also:
- * If per-thread, open the file for each thread in qemu_log_lock.
- * If not daemonized we will always log either to stderr
- * or to a file (if there is a filename).
- * If we are daemonized, we will only log if there is a filename.
- */
daemonized = is_daemonized();
- need_to_open_file = log_flags && !per_thread && (!daemonized || filename);
+ need_to_open_file = false;
+ if (!daemonized) {
+ /*
+ * If not daemonized we only log if qemu_loglevel is set, either to
+ * stderr or to a file (if there is a filename).
+ * If per-thread, open the file for each thread in qemu_log_trylock().
+ */
+ need_to_open_file = qemu_loglevel && !log_per_thread;
+ } else {
+ /*
+ * If we are daemonized, we will only log if there is a filename.
+ */
+ need_to_open_file = filename != NULL;
+ }
if (logfile) {
fflush(logfile);
@@ -287,19 +302,34 @@ static bool qemu_set_log_internal(const char *filename,
bool changed_name,
}
}
+ if (log_per_thread && daemonized) {
+ logfile = thread_file;
+ }
+
if (!logfile && need_to_open_file) {
if (filename) {
- logfile = fopen(filename, "w");
- if (!logfile) {
- error_setg_errno(errp, errno, "Error opening logfile %s",
- filename);
- return false;
+ if (log_per_thread) {
+ logfile = qemu_log_trylock_with_err(errp);
+ if (!logfile) {
+ return false;
+ }
+ qemu_log_unlock(logfile);
+ } else {
+ logfile = fopen(filename, "w");
+ if (!logfile) {
+ error_setg_errno(errp, errno, "Error opening logfile %s",
+ filename);
+ return false;
+ }
}
/* In case we are a daemon redirect stderr to logfile */
if (daemonized) {
dup2(fileno(logfile), STDERR_FILENO);
fclose(logfile);
- /* This will skip closing logfile in rcu_close_file. */
+ /*
+ * This will skip closing logfile in rcu_close_file()
+ * or qemu_log_thread_cleanup().
+ */
logfile = stderr;
}
} else {
@@ -308,7 +338,11 @@ static bool qemu_set_log_internal(const char *filename,
bool changed_name,
logfile = stderr;
}
- qatomic_rcu_set(&global_file, logfile);
+ if (log_per_thread && daemonized) {
+ thread_file = logfile;
+ } else {
+ qatomic_rcu_set(&global_file, logfile);
+ }
}
return true;
}
--
2.38.1
- [PULL 00/24] QEMU patches for 2022-12-21, Paolo Bonzini, 2022/12/21
- [PULL 03/24] util/log: do not close and reopen log files when flags are turned off, Paolo Bonzini, 2022/12/21
- [PULL 01/24] typedefs: Forward-declare AccelState, Paolo Bonzini, 2022/12/21
- [PULL 04/24] util/log: Always send errors to logfile when daemonized,
Paolo Bonzini <=
- [PULL 05/24] ide: Add 8-bit data mode, Paolo Bonzini, 2022/12/21
- [PULL 06/24] ide: Add "ide-cf" driver, a CompactFlash card, Paolo Bonzini, 2022/12/21
- [PULL 08/24] configure: remove dead function, Paolo Bonzini, 2022/12/21
- [PULL 10/24] configure: preserve qemu-ga variables, Paolo Bonzini, 2022/12/21
- [PULL 02/24] hw: Reduce "qemu/accel.h" inclusion, Paolo Bonzini, 2022/12/21
- [PULL 07/24] configure: remove useless write_c_skeleton, Paolo Bonzini, 2022/12/21
- [PULL 11/24] configure: remove backwards-compatibility and obsolete options, Paolo Bonzini, 2022/12/21
- [PULL 09/24] configure: cleanup $cpu tests, Paolo Bonzini, 2022/12/21
- [PULL 12/24] meson: tweak hardening options for Windows, Paolo Bonzini, 2022/12/21
- [PULL 13/24] meson: cleanup dummy-cpus.c rules, Paolo Bonzini, 2022/12/21