diff options
Diffstat (limited to 'util')
| -rw-r--r-- | util/Makefile.objs | 3 | ||||
| -rw-r--r-- | util/cutils.c | 8 | ||||
| -rw-r--r-- | util/error.c | 6 | ||||
| -rw-r--r-- | util/log.c | 100 | ||||
| -rw-r--r-- | util/qemu-error.c | 6 | ||||
| -rw-r--r-- | util/qsp.c | 22 |
6 files changed, 99 insertions, 46 deletions
diff --git a/util/Makefile.objs b/util/Makefile.objs index df124af1c5..63599d62aa 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -52,8 +52,7 @@ util-obj-y += stats64.o util-obj-y += systemd.o util-obj-y += iova-tree.o util-obj-$(CONFIG_INOTIFY1) += filemonitor-inotify.o +util-obj-$(call lnot,$(CONFIG_INOTIFY1)) += filemonitor-stub.o util-obj-$(CONFIG_LINUX) += vfio-helpers.o util-obj-$(CONFIG_POSIX) += drm.o util-obj-y += guest-random.o - -stub-obj-y += filemonitor-stub.o diff --git a/util/cutils.c b/util/cutils.c index 2380165230..36ce712271 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -542,7 +542,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, * Convert string @nptr to an int64_t. * * Works like qemu_strtol(), except it stores INT64_MAX on overflow, - * and INT_MIN on underflow. + * and INT64_MIN on underflow. */ int qemu_strtoi64(const char *nptr, const char **endptr, int base, int64_t *result) @@ -557,8 +557,9 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base, return -EINVAL; } + /* This assumes int64_t is long long TODO relax */ + QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long)); errno = 0; - /* FIXME This assumes int64_t is long long */ *result = strtoll(nptr, &ep, base); return check_strtox_error(nptr, ep, endptr, errno); } @@ -581,8 +582,9 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base, return -EINVAL; } + /* This assumes uint64_t is unsigned long long TODO relax */ + QEMU_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(unsigned long long)); errno = 0; - /* FIXME This assumes uint64_t is unsigned long long */ *result = strtoull(nptr, &ep, base); /* Windows returns 1 for negative out-of-range values. */ if (errno == ERANGE) { diff --git a/util/error.c b/util/error.c index d4532ce318..b6c89d1412 100644 --- a/util/error.c +++ b/util/error.c @@ -121,7 +121,7 @@ void error_setg_file_open_internal(Error **errp, "Could not open '%s'", filename); } -void error_vprepend(Error **errp, const char *fmt, va_list ap) +void error_vprepend(Error *const *errp, const char *fmt, va_list ap) { GString *newmsg; @@ -136,7 +136,7 @@ void error_vprepend(Error **errp, const char *fmt, va_list ap) (*errp)->msg = g_string_free(newmsg, 0); } -void error_prepend(Error **errp, const char *fmt, ...) +void error_prepend(Error *const *errp, const char *fmt, ...) { va_list ap; @@ -145,7 +145,7 @@ void error_prepend(Error **errp, const char *fmt, ...) va_end(ap); } -void error_append_hint(Error **errp, const char *fmt, ...) +void error_append_hint(Error *const *errp, const char *fmt, ...) { va_list ap; int saved_errno = errno; diff --git a/util/log.c b/util/log.c index 1ca13059ee..867264da8d 100644 --- a/util/log.c +++ b/util/log.c @@ -24,9 +24,11 @@ #include "qapi/error.h" #include "qemu/cutils.h" #include "trace/control.h" +#include "qemu/thread.h" static char *logfilename; -FILE *qemu_logfile; +static QemuMutex qemu_logfile_mutex; +QemuLogFile *qemu_logfile; int qemu_loglevel; static int log_append = 0; static GArray *debug_regions; @@ -35,10 +37,14 @@ static GArray *debug_regions; int qemu_log(const char *fmt, ...) { int ret = 0; - if (qemu_logfile) { + QemuLogFile *logfile; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { va_list ap; va_start(ap, fmt); - ret = vfprintf(qemu_logfile, fmt, ap); + ret = vfprintf(logfile->fd, fmt, ap); va_end(ap); /* Don't pass back error results. */ @@ -46,57 +52,91 @@ int qemu_log(const char *fmt, ...) ret = 0; } } + rcu_read_unlock(); return ret; } +static void __attribute__((__constructor__)) qemu_logfile_init(void) +{ + qemu_mutex_init(&qemu_logfile_mutex); +} + +static void qemu_logfile_free(QemuLogFile *logfile) +{ + g_assert(logfile); + + if (logfile->fd != stderr) { + fclose(logfile->fd); + } + g_free(logfile); +} + static bool log_uses_own_buffers; /* enable or disable low levels log */ void qemu_set_log(int log_flags) { + bool need_to_open_file = false; + QemuLogFile *logfile; + qemu_loglevel = log_flags; #ifdef CONFIG_TRACE_LOG qemu_loglevel |= LOG_TRACE; #endif - if (!qemu_logfile && - (is_daemonized() ? logfilename != NULL : qemu_loglevel)) { + /* + * In all cases we only log if qemu_loglevel is set. + * Also: + * If not daemonized we will always log either to stderr + * or to a file (if there is a logfilename). + * If we are daemonized, + * we will only log if there is a logfilename. + */ + if (qemu_loglevel && (!is_daemonized() || logfilename)) { + need_to_open_file = true; + } + qemu_mutex_lock(&qemu_logfile_mutex); + if (qemu_logfile && !need_to_open_file) { + logfile = qemu_logfile; + atomic_rcu_set(&qemu_logfile, NULL); + call_rcu(logfile, qemu_logfile_free, rcu); + } else if (!qemu_logfile && need_to_open_file) { + logfile = g_new0(QemuLogFile, 1); if (logfilename) { - qemu_logfile = fopen(logfilename, log_append ? "a" : "w"); - if (!qemu_logfile) { + logfile->fd = fopen(logfilename, log_append ? "a" : "w"); + if (!logfile->fd) { + g_free(logfile); perror(logfilename); _exit(1); } /* In case we are a daemon redirect stderr to logfile */ if (is_daemonized()) { - dup2(fileno(qemu_logfile), STDERR_FILENO); - fclose(qemu_logfile); + dup2(fileno(logfile->fd), STDERR_FILENO); + fclose(logfile->fd); /* This will skip closing logfile in qemu_log_close() */ - qemu_logfile = stderr; + logfile->fd = stderr; } } else { /* Default to stderr if no log file specified */ assert(!is_daemonized()); - qemu_logfile = stderr; + logfile->fd = stderr; } /* must avoid mmap() usage of glibc by setting a buffer "by hand" */ if (log_uses_own_buffers) { static char logfile_buf[4096]; - setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); + setvbuf(logfile->fd, logfile_buf, _IOLBF, sizeof(logfile_buf)); } else { #if defined(_WIN32) /* Win32 doesn't support line-buffering, so use unbuffered output. */ - setvbuf(qemu_logfile, NULL, _IONBF, 0); + setvbuf(logfile->fd, NULL, _IONBF, 0); #else - setvbuf(qemu_logfile, NULL, _IOLBF, 0); + setvbuf(logfile->fd, NULL, _IOLBF, 0); #endif log_append = 1; } + atomic_rcu_set(&qemu_logfile, logfile); } - if (qemu_logfile && - (is_daemonized() ? logfilename == NULL : !qemu_loglevel)) { - qemu_log_close(); - } + qemu_mutex_unlock(&qemu_logfile_mutex); } void qemu_log_needs_buffers(void) @@ -113,6 +153,7 @@ void qemu_set_log_filename(const char *filename, Error **errp) { char *pidstr; g_free(logfilename); + logfilename = NULL; pidstr = strstr(filename, "%"); if (pidstr) { @@ -224,18 +265,29 @@ out: /* fflush() the log file */ void qemu_log_flush(void) { - fflush(qemu_logfile); + QemuLogFile *logfile; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + fflush(logfile->fd); + } + rcu_read_unlock(); } /* Close the log file */ void qemu_log_close(void) { - if (qemu_logfile) { - if (qemu_logfile != stderr) { - fclose(qemu_logfile); - } - qemu_logfile = NULL; + QemuLogFile *logfile; + + qemu_mutex_lock(&qemu_logfile_mutex); + logfile = qemu_logfile; + + if (logfile) { + atomic_rcu_set(&qemu_logfile, NULL); + call_rcu(logfile, qemu_logfile_free, rcu); } + qemu_mutex_unlock(&qemu_logfile_mutex); } const QEMULogItem qemu_log_items[] = { diff --git a/util/qemu-error.c b/util/qemu-error.c index f373f3b3b0..dac7c7dc50 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -24,6 +24,9 @@ typedef enum { REPORT_TYPE_INFO, } report_type; +/* Prepend timestamp to messages */ +bool error_with_timestamp; + int error_printf(const char *fmt, ...) { va_list ap; @@ -191,7 +194,6 @@ static void print_loc(void) } } -bool enable_timestamp_msg; /* * Print a message to current monitor if we have one, else to stderr. * @report_type is the type of message: error, warning or informational. @@ -204,7 +206,7 @@ static void vreport(report_type type, const char *fmt, va_list ap) GTimeVal tv; gchar *timestr; - if (enable_timestamp_msg && !cur_mon) { + if (error_with_timestamp && !cur_mon) { g_get_current_time(&tv); timestr = g_time_val_to_iso8601(&tv); error_printf("%s ", timestr); diff --git a/util/qsp.c b/util/qsp.c index 62265417fd..7d5147f1b2 100644 --- a/util/qsp.c +++ b/util/qsp.c @@ -598,7 +598,6 @@ static void qsp_ht_delete(void *p, uint32_t h, void *htp) static void qsp_mktree(GTree *tree, bool callsite_coalesce) { - QSPSnapshot *snap; struct qht ht, coalesce_ht; struct qht *htp; @@ -610,20 +609,19 @@ static void qsp_mktree(GTree *tree, bool callsite_coalesce) * We must remain in an RCU read-side critical section until we're done * with the snapshot. */ - rcu_read_lock(); - snap = atomic_rcu_read(&qsp_snapshot); + WITH_RCU_READ_LOCK_GUARD() { + QSPSnapshot *snap = atomic_rcu_read(&qsp_snapshot); - /* Aggregate all results from the global hash table into a local one */ - qht_init(&ht, qsp_entry_no_thread_cmp, QSP_INITIAL_SIZE, - QHT_MODE_AUTO_RESIZE | QHT_MODE_RAW_MUTEXES); - qht_iter(&qsp_ht, qsp_aggregate, &ht); + /* Aggregate all results from the global hash table into a local one */ + qht_init(&ht, qsp_entry_no_thread_cmp, QSP_INITIAL_SIZE, + QHT_MODE_AUTO_RESIZE | QHT_MODE_RAW_MUTEXES); + qht_iter(&qsp_ht, qsp_aggregate, &ht); - /* compute the difference wrt the snapshot, if any */ - if (snap) { - qsp_diff(&snap->ht, &ht); + /* compute the difference wrt the snapshot, if any */ + if (snap) { + qsp_diff(&snap->ht, &ht); + } } - /* done with the snapshot; RCU can reclaim it */ - rcu_read_unlock(); htp = &ht; if (callsite_coalesce) { |