diff --git a/configure.ac b/configure.ac index 8a4083f93e..3cd824afb1 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,25 @@ AC_SUBST([LIBVIRT_VERSION]) AC_SUBST([LIBVIRT_VERSION_INFO]) AC_SUBST([LIBVIRT_VERSION_NUMBER]) +AC_ARG_WITH([packager], + [AS_HELP_STRING([--with-packager], + [Extra packager name])], + [],[]) +AC_ARG_WITH([packager-version], + [AS_HELP_STRING([--with-packager-version], + [Extra packager version])], + [],[]) +if test "x$with_packager" != "xno" +then + AC_DEFINE_UNQUOTED([PACKAGER], ["$with_packager"], + [Extra package name]) +fi +if test "x$with_packager_version" != "xno" +then + AC_DEFINE_UNQUOTED([PACKAGER_VERSION], ["$with_packager_version"], + [Extra package version]) +fi + dnl Required minimum versions of all libs we depend on LIBXML_REQUIRED="2.6.0" GNUTLS_REQUIRED="1.0.25" diff --git a/libvirt.spec.in b/libvirt.spec.in index 0a2d10ea0b..5021f45470 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -592,6 +592,13 @@ of recent versions of Linux (and other OSes). %define _without_dtrace --without-dtrace %endif +%define when %(date +"%%F-%%T") +%define where %(hostname) +%define who %{?packager}%{!?packager:Unknown} +%define with_packager --with-packager="%{who}, %{when}, %{where}" +%define with_packager_version --with-packager-version="%{release}" + + %configure %{?_without_xen} \ %{?_without_qemu} \ %{?_without_openvz} \ @@ -626,6 +633,8 @@ of recent versions of Linux (and other OSes). %{?_without_macvtap} \ %{?_without_audit} \ %{?_without_dtrace} \ + %{with_packager} \ + %{with_packager_version} \ --with-qemu-user=%{qemu_user} \ --with-qemu-group=%{qemu_group} \ --with-init-script=redhat \ diff --git a/src/util/logging.c b/src/util/logging.c index a80c3e3f35..c59819521d 100644 --- a/src/util/logging.c +++ b/src/util/logging.c @@ -108,6 +108,7 @@ static int virLogNbFilters = 0; * after filtering, multiple output can be used simultaneously */ struct _virLogOutput { + bool logVersion; void *data; virLogOutputFunc f; virLogCloseFunc c; @@ -490,6 +491,7 @@ int virLogDefineOutput(virLogOutputFunc f, virLogCloseFunc c, void *data, goto cleanup; } ret = virLogNbOutputs++; + virLogOutputs[ret].logVersion = true; virLogOutputs[ret].f = f; virLogOutputs[ret].c = c; virLogOutputs[ret].data = data; @@ -501,6 +503,55 @@ cleanup: return ret; } +static int +virLogFormatString(char **msg, + const char *funcname, + long long linenr, + struct tm *time_info, + struct timeval *cur_time, + int priority, + const char *str) +{ + int ret; + if ((funcname != NULL)) { + ret = virAsprintf(msg, "%02d:%02d:%02d.%03d: %d: %s : %s:%lld : %s\n", + time_info->tm_hour, time_info->tm_min, + time_info->tm_sec, (int) cur_time->tv_usec / 1000, + virThreadSelfID(), + virLogPriorityString(priority), funcname, linenr, str); + } else { + ret = virAsprintf(msg, "%02d:%02d:%02d.%03d: %d: %s : %s\n", + time_info->tm_hour, time_info->tm_min, + time_info->tm_sec, (int) cur_time->tv_usec / 1000, + virThreadSelfID(), + virLogPriorityString(priority), str); + } + return ret; +} + +static int +virLogVersionString(char **msg, + struct tm *time_info, + struct timeval *cur_time) +{ +#ifdef PACKAGER_VERSION +# ifdef PACKAGER +# define LOG_VERSION_STRING \ + "libvirt version: " VERSION ", package: " PACKAGER_VERSION " (" PACKAGER ")" +# else +# define LOG_VERSION_STRING \ + "libvirt version: " VERSION ", package: " PACKAGER_VERSION +# endif +#else +# define LOG_VERSION_STRING \ + "libvirt version: " VERSION +#endif + + return virLogFormatString(msg, NULL, 0, + time_info, cur_time, + VIR_LOG_INFO, LOG_VERSION_STRING); +} + /** * virLogMessage: * @category: where is that message coming from @@ -516,6 +567,7 @@ cleanup: */ void virLogMessage(const char *category, int priority, const char *funcname, long long linenr, int flags, const char *fmt, ...) { + static bool logVersionStderr = true; char *str = NULL; char *msg; struct timeval cur_time; @@ -547,19 +599,9 @@ void virLogMessage(const char *category, int priority, const char *funcname, gettimeofday(&cur_time, NULL); localtime_r(&cur_time.tv_sec, &time_info); - if ((funcname != NULL)) { - ret = virAsprintf(&msg, "%02d:%02d:%02d.%03d: %d: %s : %s:%lld : %s\n", - time_info.tm_hour, time_info.tm_min, - time_info.tm_sec, (int) cur_time.tv_usec / 1000, - virThreadSelfID(), - virLogPriorityString(priority), funcname, linenr, str); - } else { - ret = virAsprintf(&msg, "%02d:%02d:%02d.%03d: %d: %s : %s\n", - time_info.tm_hour, time_info.tm_min, - time_info.tm_sec, (int) cur_time.tv_usec / 1000, - virThreadSelfID(), - virLogPriorityString(priority), str); - } + ret = virLogFormatString(&msg, funcname, linenr, + &time_info, &cur_time, + priority, str); VIR_FREE(str); if (ret < 0) { /* apparently we're running out of memory */ @@ -578,12 +620,31 @@ void virLogMessage(const char *category, int priority, const char *funcname, virLogStr(msg, len); virLogLock(); for (i = 0; i < virLogNbOutputs;i++) { - if (priority >= virLogOutputs[i].priority) + if (priority >= virLogOutputs[i].priority) { + if (virLogOutputs[i].logVersion) { + char *ver = NULL; + if (virLogVersionString(&ver, &time_info, &cur_time) >= 0) + virLogOutputs[i].f(category, VIR_LOG_INFO, __func__, __LINE__, + ver, strlen(ver), + virLogOutputs[i].data); + VIR_FREE(ver); + virLogOutputs[i].logVersion = false; + } virLogOutputs[i].f(category, priority, funcname, linenr, msg, len, virLogOutputs[i].data); + } } - if ((virLogNbOutputs == 0) && (flags != 1)) + if ((virLogNbOutputs == 0) && (flags != 1)) { + if (logVersionStderr) { + char *ver = NULL; + if (virLogVersionString(&ver, &time_info, &cur_time) >= 0) + ignore_value (safewrite(STDERR_FILENO, + ver, strlen(ver))); + VIR_FREE(ver); + logVersionStderr = false; + } ignore_value (safewrite(STDERR_FILENO, msg, len)); + } virLogUnlock(); VIR_FREE(msg);