util/log: Make the per-thread flag immutable

Per-thread logging was implemented under the assumption that once
enabled, it is not possible to switch back to single file logging.
This isn't enforced though and it is possible to go through the
global file opening sequence in per-thread mode. The code isn't
ready for this and produces unexpected results as detailed below.

Start QEMU in system emulation mode with `-D ./qemu.log.%d -d tid`
and then change the log level from the monitor to something that
doesn't have tid, e.g. `log cpu_reset`. The value of log_flags
is zero and per_thread is set to false : the rest of the code
then assumes it is running in the global log case and opens a
file named `qemu.log.%d`, which is obviously not an expected
behavior.

Enforce the immutability of the flag early in qemu_set_log_internal()
so that its value is correct for all subsequent users.

Fixes: 4e51069d67 ("util/log: Support per-thread log files")
Cc: richard.henderson@linaro.org
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20221104120059.678470-2-groug@kaod.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Greg Kurz 2022-11-04 13:00:58 +01:00 committed by Stefan Hajnoczi
parent 622a84ef76
commit 479b350ebf

View File

@ -206,6 +206,11 @@ static bool qemu_set_log_internal(const char *filename, bool changed_name,
QEMU_LOCK_GUARD(&global_mutex);
logfile = global_file;
/* The per-thread flag is immutable. */
if (log_per_thread) {
log_flags |= LOG_PER_THREAD;
}
per_thread = log_flags & LOG_PER_THREAD;
if (changed_name) {