diff --git a/libvirt-0.9.6-Add-internal-APIs-for-dealing-with-time.patch b/libvirt-0.9.6-Add-internal-APIs-for-dealing-with-time.patch new file mode 100644 index 0000000..5957bea --- /dev/null +++ b/libvirt-0.9.6-Add-internal-APIs-for-dealing-with-time.patch @@ -0,0 +1,734 @@ +From f514fb152ed5f2ff5bd372c07e47e56f8496a3db Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +Date: Tue, 29 Nov 2011 12:11:01 +0000 +Subject: [PATCH 01/11] Add internal APIs for dealing with time + +(cherry pick (with small conflict resolution in src/Makefile.am, and +removing the change to tests/.gitignore) from upstream 3ec1289 to +address https://bugzilla.redhat.com/show_bug.cgi?id=757382) + +The logging APIs need to be able to generate formatted timestamps +using only async signal safe functions. This rules out using +gmtime/localtime/malloc/gettimeday(!) and much more. + +Introduce a new internal API which is async signal safe. + + virTimeMillisNowRaw replacement for gettimeofday. Uses clock_gettime + where available, otherwise falls back to the unsafe + gettimeofday + + virTimeFieldsNowRaw replacements for gmtime(), convert a timestamp + virTimeFieldsThenRaw into a broken out set of fields. No localtime() + replacement is provided, because converting to + local time is not practical with only async signal + safe APIs. + + virTimeStringNowRaw replacements for strftime() which print a timestamp + virTimeStringThenRaw into a string, using a pre-determined format, with + a fixed size buffer (VIR_TIME_STRING_BUFLEN) + +For each of these there is also a version without the Raw postfix +which raises a full libvirt error. These versions are not async +signal safe + +* src/Makefile.am, src/util/virtime.c, src/util/virtime.h: New files +* src/libvirt_private.syms: New APis +* configure.ac: Check for clock_gettime in -lrt +* tests/virtimetest.c, tests/Makefile.am: Test new APIs +--- + configure.ac | 10 ++ + po/POTFILES.in | 1 + + src/Makefile.am | 7 +- + src/libvirt_private.syms | 11 ++ + src/util/virtime.c | 350 ++++++++++++++++++++++++++++++++++++++++++++++ + src/util/virtime.h | 67 +++++++++ + tests/Makefile.am | 9 +- + tests/virtimetest.c | 124 ++++++++++++++++ + 8 files changed, 576 insertions(+), 3 deletions(-) + create mode 100644 src/util/virtime.c + create mode 100644 src/util/virtime.h + create mode 100644 tests/virtimetest.c + +diff --git a/configure.ac b/configure.ac +index df19445..3d3cbbe 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -150,6 +150,16 @@ LIBS="$LIBS $LIB_PTHREAD" + AC_CHECK_FUNCS([pthread_mutexattr_init]) + LIBS=$old_libs + ++old_LIBS=$LIBS ++RT_LIBS= ++LIBS="$LIBS $LIB_PTHREAD -lrt" ++AC_CHECK_FUNC([clock_gettime],[ ++ AC_DEFINE([HAVE_CLOCK_GETTIME],[],[Defined if clock_gettime() exists in librt.so]) ++ RT_LIBS=-lrt ++]) ++LIBS=$old_libs ++AC_SUBST(RT_LIBS) ++ + dnl Availability of various common headers (non-fatal if missing). + AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \ + sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \ +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 5ce35ae..5913e82 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -128,6 +128,7 @@ src/util/viraudit.c + src/util/virfile.c + src/util/virpidfile.c + src/util/virterror.c ++src/util/virtime.c + src/util/xml.c + src/vbox/vbox_MSCOMGlue.c + src/vbox/vbox_XPCOMCGlue.c +diff --git a/src/Makefile.am b/src/Makefile.am +index 738ee91..d3ebc73 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -88,7 +88,8 @@ UTIL_SOURCES = \ + util/xml.c util/xml.h \ + util/virterror.c util/virterror_internal.h \ + util/virkeycode.c util/virkeycode.h \ +- util/virkeymaps.h ++ util/virkeymaps.h \ ++ util/virtime.h util/virtime.c + + EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \ + $(srcdir)/util/virkeycode-mapgen.py +@@ -539,7 +540,8 @@ libvirt_util_la_SOURCES = \ + libvirt_util_la_CFLAGS = $(CAPNG_CFLAGS) $(YAJL_CFLAGS) $(LIBNL_CFLAGS) \ + $(AM_CFLAGS) $(AUDIT_CFLAGS) $(DEVMAPPER_CFLAGS) + libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \ +- $(LIB_PTHREAD) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) ++ $(LIB_PTHREAD) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \ ++ $(RT_LIBS) + + + noinst_LTLIBRARIES += libvirt_conf.la +@@ -1428,6 +1430,7 @@ libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS) + libvirt_lxc_LDADD = $(CAPNG_LIBS) $(YAJL_LIBS) \ + $(LIBXML_LIBS) $(NUMACTL_LIBS) $(LIB_PTHREAD) \ + $(LIBNL_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \ ++ $(RT_LIBS) \ + ../gnulib/lib/libgnu.la + libvirt_lxc_CFLAGS = \ + $(LIBPARTED_CFLAGS) \ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index da3042e..b07676f 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1196,6 +1196,17 @@ virKeycodeSetTypeFromString; + virKeycodeValueFromString; + virKeycodeValueTranslate; + ++ ++# virtime.h ++virTimeMillisNow; ++virTimeFieldsNow; ++virTimeFieldsThen; ++virTimeStringNow; ++virTimeStringThen; ++virTimeStringNewNow; ++virTimeStringNewThen; ++ ++ + # xml.h + virXMLParseHelper; + virXMLPropString; +diff --git a/src/util/virtime.c b/src/util/virtime.c +new file mode 100644 +index 0000000..25c2317 +--- /dev/null ++++ b/src/util/virtime.c +@@ -0,0 +1,350 @@ ++/* ++ * virtime.c: Time handling functions ++ * ++ * Copyright (C) 2006-2011 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Daniel P. Berrange ++ * ++ * The intent is that this file provides a set of time APIs which ++ * are async signal safe, to allow use in between fork/exec eg by ++ * the logging code. ++ * ++ * The reality is that wsnprintf is technically unsafe. We ought ++ * to roll out our int -> str conversions to avoid this. ++ * ++ * We do *not* use regular libvirt error APIs for most of the code, ++ * since those are not async signal safe, and we dont want logging ++ * APIs generating timestamps to blow away real errors ++ */ ++ ++#include ++ ++#include ++#ifndef HAVE_CLOCK_GETTIME ++# include ++#endif ++ ++#include "virtime.h" ++#include "util.h" ++#include "memory.h" ++#include "virterror_internal.h" ++ ++#define VIR_FROM_THIS VIR_FROM_NONE ++ ++/* We prefer clock_gettime if available because that is officially ++ * async signal safe according to POSIX. Many platforms lack it ++ * though, so fallback to gettimeofday everywhere else ++ */ ++ ++/** ++ * virTimeMillisNowRaw: ++ * @now: filled with current time in milliseconds ++ * ++ * Retrieves the current system time, in milliseconds since the ++ * epoch ++ * ++ * Returns 0 on success, -1 on error with errno set ++ */ ++int virTimeMillisNowRaw(unsigned long long *now) ++{ ++#ifdef HAVE_CLOCK_GETTIME ++ struct timespec ts; ++ ++ if (clock_gettime(CLOCK_REALTIME, &ts) < 0) ++ return -1; ++ ++ *now = (ts.tv_sec * 1000ull) + (ts.tv_nsec / (1000ull * 1000ull)); ++#else ++ struct timeval tv; ++ ++ if (gettimeofday(&tv, NULL) < 0) ++ return -1; ++ ++ *now = (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull); ++#endif ++ ++ return 0; ++} ++ ++ ++/** ++ * virTimeFieldsNowRaw: ++ * @fields: filled with current time fields ++ * ++ * Retrieves the current time, in broken-down field format. ++ * The time is always in UTC. ++ * ++ * Returns 0 on success, -1 on error with errno set ++ */ ++int virTimeFieldsNowRaw(struct tm *fields) ++{ ++ unsigned long long now; ++ ++ if (virTimeMillisNowRaw(&now) < 0) ++ return -1; ++ ++ return virTimeFieldsThenRaw(now, fields); ++} ++ ++ ++#define SECS_PER_HOUR (60 * 60) ++#define SECS_PER_DAY (SECS_PER_HOUR * 24) ++#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) ++#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) ++ ++const unsigned short int __mon_yday[2][13] = { ++ /* Normal years. */ ++ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, ++ /* Leap years. */ ++ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } ++}; ++ ++/** ++ * virTimeFieldsThenRaw: ++ * @when: the time to convert in milliseconds ++ * @fields: filled with time @when fields ++ * ++ * Converts the timestamp @when into broken-down field format. ++ * Time time is always in UTC ++ * ++ * Returns 0 on success, -1 on error with errno set ++ */ ++int virTimeFieldsThenRaw(unsigned long long when, struct tm *fields) ++{ ++ /* This code is taken from GLibC under terms of LGPLv2+ */ ++ long int days, rem, y; ++ const unsigned short int *ip; ++ unsigned long long whenSecs = when / 1000ull; ++ unsigned int offset = 0; /* We hardcoded GMT */ ++ ++ days = whenSecs / SECS_PER_DAY; ++ rem = whenSecs % SECS_PER_DAY; ++ rem += offset; ++ while (rem < 0) { ++ rem += SECS_PER_DAY; ++ --days; ++ } ++ while (rem >= SECS_PER_DAY) { ++ rem -= SECS_PER_DAY; ++ ++days; ++ } ++ fields->tm_hour = rem / SECS_PER_HOUR; ++ rem %= SECS_PER_HOUR; ++ fields->tm_min = rem / 60; ++ fields->tm_sec = rem % 60; ++ /* January 1, 1970 was a Thursday. */ ++ fields->tm_wday = (4 + days) % 7; ++ if (fields->tm_wday < 0) ++ fields->tm_wday += 7; ++ y = 1970; ++ ++ while (days < 0 || days >= (__isleap (y) ? 366 : 365)) { ++ /* Guess a corrected year, assuming 365 days per year. */ ++ long int yg = y + days / 365 - (days % 365 < 0); ++ ++ /* Adjust DAYS and Y to match the guessed year. */ ++ days -= ((yg - y) * 365 ++ + LEAPS_THRU_END_OF (yg - 1) ++ - LEAPS_THRU_END_OF (y - 1)); ++ y = yg; ++ } ++ fields->tm_year = y - 1900; ++ ++ fields->tm_yday = days; ++ ip = __mon_yday[__isleap(y)]; ++ for (y = 11; days < (long int) ip[y]; --y) ++ continue; ++ days -= ip[y]; ++ fields->tm_mon = y; ++ fields->tm_mday = days + 1; ++ return 0; ++} ++ ++ ++/** ++ * virTimeStringNowRaw: ++ * @buf: a buffer at least VIR_TIME_STRING_BUFLEN in length ++ * ++ * Initializes @buf to contain a formatted timestamp ++ * corresponding to the current time. ++ * ++ * Returns 0 on success, -1 on error ++ */ ++int virTimeStringNowRaw(char *buf) ++{ ++ unsigned long long now; ++ ++ if (virTimeMillisNowRaw(&now) < 0) ++ return -1; ++ ++ return virTimeStringThenRaw(now, buf); ++} ++ ++ ++/** ++ * virTimeStringThenRaw: ++ * @when: the time to format in milliseconds ++ * @buf: a buffer at least VIR_TIME_STRING_BUFLEN in length ++ * ++ * Initializes @buf to contain a formatted timestamp ++ * corresponding to the time @when. ++ * ++ * Returns 0 on success, -1 on error ++ */ ++int virTimeStringThenRaw(unsigned long long when, char *buf) ++{ ++ struct tm fields; ++ ++ if (virTimeFieldsThenRaw(when, &fields) < 0) ++ return -1; ++ ++ fields.tm_year += 1900; ++ fields.tm_mon += 1; ++ ++ if (snprintf(buf, VIR_TIME_STRING_BUFLEN, ++ "%4d-%02d-%02d %02d:%02d:%02d.%03d+0000", ++ fields.tm_year, fields.tm_mon, fields.tm_mday, ++ fields.tm_hour, fields.tm_min, fields.tm_sec, ++ (int) (when % 1000)) >= VIR_TIME_STRING_BUFLEN) { ++ errno = ERANGE; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++/** ++ * virTimeMillisNow: ++ * @now: filled with current time in milliseconds ++ * ++ * Retrieves the current system time, in milliseconds since the ++ * epoch ++ * ++ * Returns 0 on success, -1 on error with error reported ++ */ ++int virTimeMillisNow(unsigned long long *now) ++{ ++ if (virTimeMillisNowRaw(now) < 0) { ++ virReportSystemError(errno, "%s", ++ _("Unable to get current time")); ++ return -1; ++ } ++ return 0; ++} ++ ++ ++/** ++ * virTimeFieldsNowRaw: ++ * @fields: filled with current time fields ++ * ++ * Retrieves the current time, in broken-down field format. ++ * The time is always in UTC. ++ * ++ * Returns 0 on success, -1 on error with errno reported ++ */ ++int virTimeFieldsNow(struct tm *fields) ++{ ++ unsigned long long now; ++ ++ if (virTimeMillisNow(&now) < 0) ++ return -1; ++ ++ return virTimeFieldsThen(now, fields); ++} ++ ++ ++/** ++ * virTimeFieldsThen: ++ * @when: the time to convert in milliseconds ++ * @fields: filled with time @when fields ++ * ++ * Converts the timestamp @when into broken-down field format. ++ * Time time is always in UTC ++ * ++ * Returns 0 on success, -1 on error with error reported ++ */ ++int virTimeFieldsThen(unsigned long long when, struct tm *fields) ++{ ++ if (virTimeFieldsThenRaw(when, fields) < 0) { ++ virReportSystemError(errno, "%s", ++ _("Unable to break out time format")); ++ return -1; ++ } ++ return 0; ++} ++ ++ ++/** ++ * virTimeStringNow: ++ * ++ * Creates a string containing a formatted timestamp ++ * corresponding to the current time. ++ * ++ * This function is not async signal safe ++ * ++ * Returns a formatted allocated string, or NULL on error ++ */ ++char *virTimeStringNow(void) ++{ ++ char *ret; ++ ++ if (VIR_ALLOC_N(ret, VIR_TIME_STRING_BUFLEN) < 0) { ++ virReportOOMError(); ++ return NULL; ++ } ++ ++ if (virTimeStringNowRaw(ret) < 0) { ++ virReportSystemError(errno, "%s", ++ _("Unable to format time")); ++ VIR_FREE(ret); ++ return NULL; ++ } ++ ++ return ret; ++} ++ ++ ++/** ++ * virTimeStringThen: ++ * @when: the time to format in milliseconds ++ * ++ * Creates a string containing a formatted timestamp ++ * corresponding to the time @when. ++ * ++ * This function is not async signal safe ++ * ++ * Returns a formatted allocated string, or NULL on error ++ */ ++char *virTimeStringThen(unsigned long long when) ++{ ++ char *ret; ++ ++ if (VIR_ALLOC_N(ret, VIR_TIME_STRING_BUFLEN) < 0) { ++ virReportOOMError(); ++ return NULL; ++ } ++ ++ if (virTimeStringThenRaw(when, ret) < 0) { ++ virReportSystemError(errno, "%s", ++ _("Unable to format time")); ++ VIR_FREE(ret); ++ return NULL; ++ } ++ ++ return ret; ++} +diff --git a/src/util/virtime.h b/src/util/virtime.h +new file mode 100644 +index 0000000..59954c2 +--- /dev/null ++++ b/src/util/virtime.h +@@ -0,0 +1,67 @@ ++/* ++ * virtime.h: Time handling functions ++ * ++ * Copyright (C) 2006-2011 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Daniel P. Berrange ++ */ ++ ++#ifndef __VIR_TIME_H__ ++# define __VIR_TIME_H__ ++ ++# include ++ ++# include "internal.h" ++ ++/* The format string we intend to use is: ++ * ++ * Yr Mon Day Hour Min Sec Ms TZ ++ * %4d-%02d-%02d %02d:%02d:%02d.%03d+0000 ++ * ++ */ ++# define VIR_TIME_STRING_BUFLEN \ ++ (4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 3 + 5 + 1) ++/* Yr Mon Day Hour Min Sec Ms TZ NULL */ ++ ++/* These APIs are async signal safe and return -1, setting ++ * errno on failure */ ++int virTimeMillisNowRaw(unsigned long long *now) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++int virTimeFieldsNowRaw(struct tm *fields) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++int virTimeFieldsThenRaw(unsigned long long when, struct tm *fields) ++ ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; ++int virTimeStringNowRaw(char *buf) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++int virTimeStringThenRaw(unsigned long long when, char *buf) ++ ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; ++ ++ ++/* These APIs are *not* async signal safe and return -1, ++ * raising a libvirt error on failure ++ */ ++int virTimeMillisNow(unsigned long long *now) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++int virTimeFieldsNow(struct tm *fields) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++int virTimeFieldsThen(unsigned long long when, struct tm *fields) ++ ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; ++char *virTimeStringNow(void); ++char *virTimeStringThen(unsigned long long when); ++ ++ ++#endif +diff --git a/tests/Makefile.am b/tests/Makefile.am +index cbbbc6f..fba5e53 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -89,7 +89,8 @@ check_PROGRAMS = virshtest conftest sockettest \ + nodeinfotest qparamtest virbuftest \ + commandtest commandhelper seclabeltest \ + hashtest virnetmessagetest virnetsockettest ssh \ +- utiltest virnettlscontexttest shunloadtest ++ utiltest virnettlscontexttest shunloadtest \ ++ virtimetest + + check_LTLIBRARIES = libshunload.la + +@@ -209,6 +210,7 @@ TESTS = virshtest \ + virnetmessagetest \ + virnetsockettest \ + virnettlscontexttest \ ++ virtimetest \ + shunloadtest \ + utiltest \ + $(test_scripts) +@@ -475,6 +477,11 @@ else + EXTRA_DIST += pkix_asn1_tab.c + endif + ++virtimetest_SOURCES = \ ++ virtimetest.c testutils.h testutils.c ++virtimetest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS) ++virtimetest_LDADD = ../src/libvirt-net-rpc.la $(LDADDS) ++ + + seclabeltest_SOURCES = \ + seclabeltest.c +diff --git a/tests/virtimetest.c b/tests/virtimetest.c +new file mode 100644 +index 0000000..5d56dd3 +--- /dev/null ++++ b/tests/virtimetest.c +@@ -0,0 +1,124 @@ ++/* ++ * Copyright (C) 2011 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Daniel P. Berrange ++ */ ++ ++#include ++ ++#include ++#include ++ ++#include "testutils.h" ++#include "util.h" ++#include "virterror_internal.h" ++#include "memory.h" ++#include "logging.h" ++ ++#include "virtime.h" ++ ++#define VIR_FROM_THIS VIR_FROM_RPC ++ ++struct testTimeFieldsData { ++ unsigned long long when; ++ struct tm fields; ++}; ++ ++static int testTimeFields(const void *args) ++{ ++ const struct testTimeFieldsData *data = args; ++ struct tm actual; ++ ++ if (virTimeFieldsThen(data->when, &actual) < 0) ++ return -1; ++ ++#define COMPARE(field) \ ++ do { \ ++ if (data->fields.field != actual.field) { \ ++ VIR_DEBUG("Expect " #field " %d got %d", \ ++ data->fields.field, actual.field); \ ++ return -1; \ ++ } \ ++ } while (0) ++ ++ /* tm_year value 0 is based off epoch 1900 */ ++ actual.tm_year += 1900; ++ /* tm_mon is range 0-11, but we want 1-12 */ ++ actual.tm_mon += 1; ++ ++ COMPARE(tm_year); ++ COMPARE(tm_mon); ++ COMPARE(tm_mday); ++ COMPARE(tm_hour); ++ COMPARE(tm_min); ++ COMPARE(tm_sec); ++ ++ return 0; ++} ++ ++ ++static int ++mymain(void) ++{ ++ int ret = 0; ++ ++ signal(SIGPIPE, SIG_IGN); ++ ++#define TEST_FIELDS(ts, year, mon, day, hour, min, sec) \ ++ do { \ ++ struct testTimeFieldsData data = { \ ++ .when = ts, \ ++ .fields = { \ ++ .tm_year = year, \ ++ .tm_mon = mon, \ ++ .tm_mday = day, \ ++ .tm_hour = hour, \ ++ .tm_min = min, \ ++ .tm_sec = sec, \ ++ .tm_wday = 0, \ ++ .tm_yday = 0, \ ++ .tm_isdst = 0, \ ++ }, \ ++ }; \ ++ if (virtTestRun("Test fields " #ts " " #year " ", 1, testTimeFields, &data) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ TEST_FIELDS( 0ull, 1970, 1, 1, 0, 0, 0); ++ TEST_FIELDS( 5000ull, 1970, 1, 1, 0, 0, 5); ++ TEST_FIELDS( 3605000ull, 1970, 1, 1, 1, 0, 5); ++ TEST_FIELDS( 86405000ull, 1970, 1, 2, 0, 0, 5); ++ TEST_FIELDS( 31536000000ull, 1971, 1, 1, 0, 0, 0); ++ ++ TEST_FIELDS( 30866399000ull, 1970, 12, 24, 5, 59, 59); ++ TEST_FIELDS( 123465599000ull, 1973, 11, 29, 23, 59, 59); ++ TEST_FIELDS( 155001599000ull, 1974, 11, 29, 23, 59, 59); ++ ++ TEST_FIELDS( 186537599000ull, 1975, 11, 29, 23, 59, 59); ++ TEST_FIELDS( 344390399000ull, 1980, 11, 29, 23, 59, 59); ++ TEST_FIELDS(1203161493000ull, 2008, 2, 16, 11, 31, 33); ++ TEST_FIELDS(1234567890000ull, 2009, 2, 13, 23, 31, 30); ++ ++ TEST_FIELDS(1322524800000ull, 2011, 11, 29, 0, 0, 0); ++ TEST_FIELDS(1322611199000ull, 2011, 11, 29, 23, 59, 59); ++ ++ TEST_FIELDS(2147483648000ull, 2038, 1, 19, 3, 14, 8); ++ ++ return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE); ++} ++ ++VIRT_TEST_MAIN(mymain) +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-Fix-incorrect-symbols-for-virtime.h-module-breaking-.patch b/libvirt-0.9.6-Fix-incorrect-symbols-for-virtime.h-module-breaking-.patch new file mode 100644 index 0000000..2c6d587 --- /dev/null +++ b/libvirt-0.9.6-Fix-incorrect-symbols-for-virtime.h-module-breaking-.patch @@ -0,0 +1,44 @@ +From 73469d2989ad7cd4ed0802ea75d5b111af44eeb1 Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +Date: Mon, 5 Dec 2011 14:04:25 +0000 +Subject: [PATCH 07/13] Fix incorrect symbols for virtime.h module breaking + Mingw32 + +(prerequisite patch, direct cherry-pick of upstream b265bed, to +resolve: https://bugzilla.redhat.com/show_bug.cgi?id=757382) + +The Mingw32 linker highlighted that the symbols for virtime.h +declared in libvirt_private.syms were incorrect + +* src/libvirt_private.syms: Fix virtime.h symbols +--- + src/libvirt_private.syms | 9 ++++++--- + 1 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index b804b34..e4ade24 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1196,13 +1196,16 @@ virKeycodeValueTranslate; + + + # virtime.h +-virTimeMillisNow; + virTimeFieldsNow; ++virTimeFieldsNowRaw; + virTimeFieldsThen; ++virTimeFieldsThenRaw; ++virTimeMillisNow; ++virTimeMillisNowRaw; + virTimeStringNow; ++virTimeStringNowRaw; + virTimeStringThen; +-virTimeStringNewNow; +-virTimeStringNewThen; ++virTimeStringThenRaw; + + + # xml.h +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-Make-logging-async-signal-safe-wrt-time-stamp-genera.patch b/libvirt-0.9.6-Make-logging-async-signal-safe-wrt-time-stamp-genera.patch new file mode 100644 index 0000000..7c5ec8e --- /dev/null +++ b/libvirt-0.9.6-Make-logging-async-signal-safe-wrt-time-stamp-genera.patch @@ -0,0 +1,89 @@ +From 744247bcfdba1dc90f71f3ef693f557b663a9cc8 Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +Date: Tue, 29 Nov 2011 12:32:31 +0000 +Subject: [PATCH 04/13] Make logging async signal safe wrt time stamp + generation + +cherry pick (with small conflict resolution in src/util/logging.c) from +upstream 32d3ec7 to address: + + https://bugzilla.redhat.com/show_bug.cgi?id=757382 + +Use the new virTimeStringNowRaw() API for generating log timestamps +in an async signal safe manner + +* src/util/logging.c: Use virTimeStringNowRaw +--- + src/util/logging.c | 28 ++++------------------------ + 1 files changed, 4 insertions(+), 24 deletions(-) + +diff --git a/src/util/logging.c b/src/util/logging.c +index 9df9003..22d7c2b 100644 +--- a/src/util/logging.c ++++ b/src/util/logging.c +@@ -43,6 +43,7 @@ + #include "buf.h" + #include "threads.h" + #include "virfile.h" ++#include "virtime.h" + + #define VIR_FROM_THIS VIR_FROM_NONE + +@@ -618,26 +619,6 @@ cleanup: + return ret; + } + +-static char * +-virLogFormatTimestamp(void) +-{ +- struct timeval cur_time; +- struct tm time_info; +- char *str = NULL; +- +- gettimeofday(&cur_time, NULL); +- localtime_r(&cur_time.tv_sec, &time_info); +- time_info.tm_year += 1900; +- +- if (virAsprintf(&str, "%4d-%02d-%02d %02d:%02d:%02d.%03d", +- time_info.tm_year, time_info.tm_mon, time_info.tm_mday, +- time_info.tm_hour, time_info.tm_min, time_info.tm_sec, +- (int) (cur_time.tv_usec / 1000)) < 0) +- return NULL; +- +- return str; +-} +- + static int + virLogFormatString(char **msg, + const char *funcname, +@@ -704,7 +685,7 @@ void virLogMessage(const char *category, int priority, const char *funcname, + static bool logVersionStderr = true; + char *str = NULL; + char *msg = NULL; +- char *timestamp = NULL; ++ char timestamp[VIR_TIME_STRING_BUFLEN]; + int fprio, i, ret; + int saved_errno = errno; + int emit = 1; +@@ -745,8 +726,8 @@ void virLogMessage(const char *category, int priority, const char *funcname, + if (ret < 0) + goto cleanup; + +- if (!(timestamp = virLogFormatTimestamp())) +- goto cleanup; ++ if (virTimeStringNowRaw(timestamp) < 0) ++ timestamp[0] = '\0'; + + /* + * Log based on defaults, first store in the history buffer, +@@ -798,7 +779,6 @@ void virLogMessage(const char *category, int priority, const char *funcname, + + cleanup: + VIR_FREE(msg); +- VIR_FREE(timestamp); + errno = saved_errno; + } + +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-Remove-time-APIs-from-src-util-util.h.patch b/libvirt-0.9.6-Remove-time-APIs-from-src-util-util.h.patch new file mode 100644 index 0000000..e08214a --- /dev/null +++ b/libvirt-0.9.6-Remove-time-APIs-from-src-util-util.h.patch @@ -0,0 +1,364 @@ +From 711c78a100649a47c11c90f5efa510421f711013 Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +Date: Tue, 29 Nov 2011 12:33:23 +0000 +Subject: [PATCH 05/13] Remove time APIs from src/util/util.h + +cherry pick (with small conflict resolution detailed below) from +upstream a8bb75a to address: + + https://bugzilla.redhat.com/show_bug.cgi?id=757382 + +The virTimestamp and virTimeMs functions in src/util/util.h +duplicate functionality from virtime.h, in a non-async signal +safe manner. Remove them, and convert all code over to the new +APIs. + +* src/util/util.c, src/util/util.h: Delete virTimeMs and virTimestamp +* src/lxc/lxc_driver.c, src/qemu/qemu_domain.c, + src/qemu/qemu_driver.c, src/qemu/qemu_migration.c, + src/qemu/qemu_process.c, src/util/event_poll.c: Convert to use + virtime APIs + +Conflicts: + + src/lxc/lxc_driver.c + src/qemu/qemu_domain.c + src/qemu/qemu_driver.c + * the patches contained context with extra include files not + yet introduced on the branch. + src/util/event_poll.c + * the branch had context with a call to EVENT_DEBUG that + was no longer existing in the original patch. +--- + src/libvirt_private.syms | 2 - + src/lxc/lxc_driver.c | 3 +- + src/qemu/qemu_domain.c | 5 ++- + src/qemu/qemu_driver.c | 7 +++-- + src/qemu/qemu_migration.c | 5 ++- + src/qemu/qemu_process.c | 9 ++++--- + src/util/event_poll.c | 10 +++++--- + src/util/util.c | 53 --------------------------------------------- + src/util/util.h | 4 --- + 9 files changed, 23 insertions(+), 75 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index b07676f..b804b34 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1131,8 +1131,6 @@ virStrToLong_ul; + virStrToLong_ull; + virStrcpy; + virStrncpy; +-virTimeMs; +-virTimestamp; + virTrimSpaces; + virVasprintf; + +diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c +index 6cf7203..e7fb46d 100644 +--- a/src/lxc/lxc_driver.c ++++ b/src/lxc/lxc_driver.c +@@ -54,6 +54,7 @@ + #include "fdstream.h" + #include "domain_audit.h" + #include "domain_nwfilter.h" ++#include "virtime.h" + + #define VIR_FROM_THIS VIR_FROM_LXC + +@@ -1580,7 +1581,7 @@ static int lxcVmStart(virConnectPtr conn, + goto cleanup; + + /* Log timestamp */ +- if ((timestamp = virTimestamp()) == NULL) { ++ if ((timestamp = virTimeStringNow()) == NULL) { + virReportOOMError(); + goto cleanup; + } +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 4023648..66c0de9 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -35,6 +35,7 @@ + #include "ignore-value.h" + #include "uuid.h" + #include "virfile.h" ++#include "virtime.h" + + #include + #include +@@ -717,7 +718,7 @@ qemuDomainObjBeginJobInternal(struct qemud_driver *driver, + + priv->jobs_queued++; + +- if (virTimeMs(&now) < 0) ++ if (virTimeMillisNow(&now) < 0) + return -1; + then = now + QEMU_JOB_WAIT_TIME; + +@@ -911,7 +912,7 @@ qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver, + + qemuMonitorLock(priv->mon); + qemuMonitorRef(priv->mon); +- ignore_value(virTimeMs(&priv->monStart)); ++ ignore_value(virTimeMillisNow(&priv->monStart)); + virDomainObjUnlock(obj); + if (driver_locked) + qemuDriverUnlock(driver); +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 0d0bea2..09e0eaa 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -89,6 +89,7 @@ + #include "locking/lock_manager.h" + #include "locking/domain_lock.h" + #include "virkeycode.h" ++#include "virtime.h" + + #define VIR_FROM_THIS VIR_FROM_QEMU + +@@ -2130,12 +2131,12 @@ qemuDomainGetControlInfo(virDomainPtr dom, + } else if (priv->job.active) { + if (!priv->monStart) { + info->state = VIR_DOMAIN_CONTROL_JOB; +- if (virTimeMs(&info->stateTime) < 0) ++ if (virTimeMillisNow(&info->stateTime) < 0) + goto cleanup; + info->stateTime -= priv->job.start; + } else { + info->state = VIR_DOMAIN_CONTROL_OCCUPIED; +- if (virTimeMs(&info->stateTime) < 0) ++ if (virTimeMillisNow(&info->stateTime) < 0) + goto cleanup; + info->stateTime -= priv->monStart; + } +@@ -8446,7 +8447,7 @@ static int qemuDomainGetJobInfo(virDomainPtr dom, + * of incoming migration which we don't currently + * monitor actively in the background thread + */ +- if (virTimeMs(&info->timeElapsed) < 0) ++ if (virTimeMillisNow(&info->timeElapsed) < 0) + goto cleanup; + info->timeElapsed -= priv->job.start; + } else { +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 4fd2e9f..8fbf7b4 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -42,6 +42,7 @@ + #include "datatypes.h" + #include "fdstream.h" + #include "uuid.h" ++#include "virtime.h" + #include "locking/domain_lock.h" + #include "rpc/virnetsocket.h" + +@@ -790,7 +791,7 @@ qemuMigrationUpdateJobStatus(struct qemud_driver *driver, + &memTotal); + qemuDomainObjExitMonitorWithDriver(driver, vm); + +- if (ret < 0 || virTimeMs(&priv->job.info.timeElapsed) < 0) { ++ if (ret < 0 || virTimeMillisNow(&priv->job.info.timeElapsed) < 0) { + priv->job.info.type = VIR_DOMAIN_JOB_FAILED; + return -1; + } +@@ -1003,7 +1004,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, + qemuMigrationCookiePtr mig = NULL; + bool tunnel = !!st; + +- if (virTimeMs(&now) < 0) ++ if (virTimeMillisNow(&now) < 0) + return -1; + + if (!(def = virDomainDefParseString(driver->caps, dom_xml, +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index c8f22e2..1b895f6 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -60,6 +60,7 @@ + #include "locking/domain_lock.h" + #include "network/bridge_driver.h" + #include "uuid.h" ++#include "virtime.h" + + #define VIR_FROM_THIS VIR_FROM_QEMU + +@@ -845,7 +846,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm) + * deleted while the monitor is active */ + virDomainObjRef(vm); + +- ignore_value(virTimeMs(&priv->monStart)); ++ ignore_value(virTimeMillisNow(&priv->monStart)); + virDomainObjUnlock(vm); + qemuDriverUnlock(driver); + +@@ -3012,7 +3013,7 @@ int qemuProcessStart(virConnectPtr conn, + goto cleanup; + } + +- if ((timestamp = virTimestamp()) == NULL) { ++ if ((timestamp = virTimeStringNow()) == NULL) { + virReportOOMError(); + goto cleanup; + } else { +@@ -3290,7 +3291,7 @@ void qemuProcessStop(struct qemud_driver *driver, + VIR_WARN("Unable to open logfile: %s", + virStrerror(errno, ebuf, sizeof ebuf)); + } else { +- if ((timestamp = virTimestamp()) == NULL) { ++ if ((timestamp = virTimeStringNow()) == NULL) { + virReportOOMError(); + } else { + if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 || +@@ -3560,7 +3561,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, + priv->persistentAddrs = 0; + } + +- if ((timestamp = virTimestamp()) == NULL) { ++ if ((timestamp = virTimeStringNow()) == NULL) { + virReportOOMError(); + goto cleanup; + } else { +diff --git a/src/util/event_poll.c b/src/util/event_poll.c +index e8679b8..97118d9 100644 +--- a/src/util/event_poll.c ++++ b/src/util/event_poll.c +@@ -39,6 +39,7 @@ + #include "virfile.h" + #include "ignore-value.h" + #include "virterror_internal.h" ++#include "virtime.h" + + #define EVENT_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__) + +@@ -206,8 +207,9 @@ int virEventPollAddTimeout(int frequency, + { + unsigned long long now; + int ret; ++ + EVENT_DEBUG("Adding timer %d with %d ms freq", nextTimer, frequency); +- if (virTimeMs(&now) < 0) { ++ if (virTimeMillisNow(&now) < 0) { + return -1; + } + +@@ -249,7 +251,7 @@ void virEventPollUpdateTimeout(int timer, int frequency) + return; + } + +- if (virTimeMs(&now) < 0) { ++ if (virTimeMillisNow(&now) < 0) { + return; + } + +@@ -322,7 +324,7 @@ static int virEventPollCalculateTimeout(int *timeout) { + if (then > 0) { + unsigned long long now; + +- if (virTimeMs(&now) < 0) ++ if (virTimeMillisNow(&now) < 0) + return -1; + + *timeout = then - now; +@@ -398,7 +400,7 @@ static int virEventPollDispatchTimeouts(void) + int ntimeouts = eventLoop.timeoutsCount; + VIR_DEBUG("Dispatch %d", ntimeouts); + +- if (virTimeMs(&now) < 0) ++ if (virTimeMillisNow(&now) < 0) + return -1; + + for (i = 0 ; i < ntimeouts ; i++) { +diff --git a/src/util/util.c b/src/util/util.c +index 1ff287d..9b30f1e 100644 +--- a/src/util/util.c ++++ b/src/util/util.c +@@ -33,12 +33,10 @@ + #include + #include + #include +-#include + #include + #include + #include + #include +-#include + #if HAVE_MMAP + # include + #endif +@@ -2402,57 +2400,6 @@ int virBuildPathInternal(char **path, ...) + return ret; + } + +-/** +- * virTimestamp: +- * +- * Return an allocated string containing the current date and time, +- * followed by ": ". Return NULL on allocation failure. +- */ +-char * +-virTimestamp(void) +-{ +- struct timeval cur_time; +- struct tm time_info; +- char timestr[100]; +- char *timestamp; +- +- gettimeofday(&cur_time, NULL); +- localtime_r(&cur_time.tv_sec, &time_info); +- +- strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &time_info); +- +- if (virAsprintf(×tamp, "%s.%03d", +- timestr, (int) cur_time.tv_usec / 1000) < 0) { +- return NULL; +- } +- +- return timestamp; +-} +- +-#define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000)) +- +-/** +- * virTimeMs: +- * +- * Get current time in milliseconds. +- * +- * Returns 0 on success, -1 on failure. +- */ +-int +-virTimeMs(unsigned long long *ms) +-{ +- struct timeval now; +- +- if (gettimeofday(&now, NULL) < 0) { +- virReportSystemError(errno, "%s", +- _("cannot get time of day")); +- return -1; +- } +- +- *ms = timeval_to_ms(now); +- return 0; +-} +- + #if HAVE_LIBDEVMAPPER_H + bool + virIsDevMapperDevice(const char *dev_name) +diff --git a/src/util/util.h b/src/util/util.h +index c55e852..afa2221 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -251,10 +251,6 @@ void virFileWaitForDevices(void); + # define virBuildPath(path, ...) virBuildPathInternal(path, __VA_ARGS__, NULL) + int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL; + +-char *virTimestamp(void); +- +-int virTimeMs(unsigned long long *ms) ATTRIBUTE_NONNULL(1); +- + bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); + + int virEmitXMLWarning(int fd, +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-logging-Add-date-to-log-timestamp.patch b/libvirt-0.9.6-logging-Add-date-to-log-timestamp.patch new file mode 100644 index 0000000..0089fe0 --- /dev/null +++ b/libvirt-0.9.6-logging-Add-date-to-log-timestamp.patch @@ -0,0 +1,30 @@ +From 69b05e20e64836c3a1a125b17b0101f70492ffd7 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Wed, 28 Sep 2011 16:44:50 +0200 +Subject: [PATCH 02/13] logging: Add date to log timestamp + +(prerequisite patch, direct cherry-pick of upstream 11c6e09, to +resolve: https://bugzilla.redhat.com/show_bug.cgi?id=757382) +--- + src/util/logging.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/src/util/logging.c b/src/util/logging.c +index 4ffaf75..9df9003 100644 +--- a/src/util/logging.c ++++ b/src/util/logging.c +@@ -627,8 +627,10 @@ virLogFormatTimestamp(void) + + gettimeofday(&cur_time, NULL); + localtime_r(&cur_time.tv_sec, &time_info); ++ time_info.tm_year += 1900; + +- if (virAsprintf(&str, "%02d:%02d:%02d.%03d", ++ if (virAsprintf(&str, "%4d-%02d-%02d %02d:%02d:%02d.%03d", ++ time_info.tm_year, time_info.tm_mon, time_info.tm_mday, + time_info.tm_hour, time_info.tm_min, time_info.tm_sec, + (int) (cur_time.tv_usec / 1000)) < 0) + return NULL; +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-logging-Do-not-log-timestamp-through-syslog.patch b/libvirt-0.9.6-logging-Do-not-log-timestamp-through-syslog.patch new file mode 100644 index 0000000..09831df --- /dev/null +++ b/libvirt-0.9.6-logging-Do-not-log-timestamp-through-syslog.patch @@ -0,0 +1,327 @@ +From 978ca41b4bc59033e39cf8b1a69f3869d160e7d6 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Wed, 28 Sep 2011 15:20:07 +0200 +Subject: [PATCH 01/13] logging: Do not log timestamp through syslog + +(prerequisite patch, direct cherry-pick of upstream 2a44954, to +resolve: https://bugzilla.redhat.com/show_bug.cgi?id=757382) + +Syslog puts the timestamp to every message anyway so this removes +redundant data. +--- + src/util/logging.c | 121 +++++++++++++++++++++++++++++++-------------------- + src/util/logging.h | 9 ++-- + tests/testutils.c | 8 ++- + 3 files changed, 83 insertions(+), 55 deletions(-) + +diff --git a/src/util/logging.c b/src/util/logging.c +index a638510..4ffaf75 100644 +--- a/src/util/logging.c ++++ b/src/util/logging.c +@@ -98,7 +98,8 @@ static int virLogResetFilters(void); + static int virLogResetOutputs(void); + static int virLogOutputToFd(const char *category, int priority, + const char *funcname, long long linenr, +- const char *str, int len, void *data); ++ const char *timestamp, const char *str, ++ void *data); + + /* + * Logs accesses must be serialized though a mutex +@@ -282,16 +283,16 @@ void virLogShutdown(void) { + /* + * Store a string in the ring buffer + */ +-static void virLogStr(const char *str, int len) { ++static void virLogStr(const char *str) ++{ + int tmp; ++ int len; + + if ((str == NULL) || (virLogBuffer == NULL) || (virLogSize <= 0)) + return; +- if (len <= 0) +- len = strlen(str); ++ len = strlen(str); + if (len >= virLogSize) + return; +- virLogLock(); + + /* + * copy the data and reset the end, we cycle over the end of the buffer +@@ -317,7 +318,6 @@ static void virLogStr(const char *str, int len) { + if (virLogStart >= virLogSize) + virLogStart -= virLogSize; + } +- virLogUnlock(); + } + + static void virLogDumpAllFD(const char *msg, int len) { +@@ -618,12 +618,28 @@ cleanup: + return ret; + } + ++static char * ++virLogFormatTimestamp(void) ++{ ++ struct timeval cur_time; ++ struct tm time_info; ++ char *str = NULL; ++ ++ gettimeofday(&cur_time, NULL); ++ localtime_r(&cur_time.tv_sec, &time_info); ++ ++ if (virAsprintf(&str, "%02d:%02d:%02d.%03d", ++ time_info.tm_hour, time_info.tm_min, time_info.tm_sec, ++ (int) (cur_time.tv_usec / 1000)) < 0) ++ return NULL; ++ ++ return str; ++} ++ + static int + virLogFormatString(char **msg, + const char *funcname, + long long linenr, +- struct tm *time_info, +- struct timeval *cur_time, + int priority, + const char *str) + { +@@ -637,25 +653,19 @@ virLogFormatString(char **msg, + * to just grep for it to find the right place. + */ + 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); ++ ret = virAsprintf(msg, "%d: %s : %s:%lld : %s\n", ++ 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 = virAsprintf(msg, "%d: %s : %s\n", ++ virThreadSelfID(), virLogPriorityString(priority), ++ str); + } + return ret; + } + + static int +-virLogVersionString(char **msg, +- struct tm *time_info, +- struct timeval *cur_time) ++virLogVersionString(char **msg) + { + #ifdef PACKAGER_VERSION + # ifdef PACKAGER +@@ -670,9 +680,7 @@ virLogVersionString(char **msg, + "libvirt version: " VERSION + #endif + +- return virLogFormatString(msg, NULL, 0, +- time_info, cur_time, +- VIR_LOG_INFO, LOG_VERSION_STRING); ++ return virLogFormatString(msg, NULL, 0, VIR_LOG_INFO, LOG_VERSION_STRING); + } + + /** +@@ -694,9 +702,8 @@ void virLogMessage(const char *category, int priority, const char *funcname, + static bool logVersionStderr = true; + char *str = NULL; + char *msg = NULL; +- struct timeval cur_time; +- struct tm time_info; +- int len, fprio, i, ret; ++ char *timestamp = NULL; ++ int fprio, i, ret; + int saved_errno = errno; + int emit = 1; + va_list ap; +@@ -730,16 +737,15 @@ void virLogMessage(const char *category, int priority, const char *funcname, + goto cleanup; + } + va_end(ap); +- gettimeofday(&cur_time, NULL); +- localtime_r(&cur_time.tv_sec, &time_info); + +- ret = virLogFormatString(&msg, funcname, linenr, +- &time_info, &cur_time, +- priority, str); ++ ret = virLogFormatString(&msg, funcname, linenr, priority, str); + VIR_FREE(str); + if (ret < 0) + goto cleanup; + ++ if (!(timestamp = virLogFormatTimestamp())) ++ goto cleanup; ++ + /* + * Log based on defaults, first store in the history buffer, + * then if emit push the message on the outputs defined, if none +@@ -748,42 +754,49 @@ void virLogMessage(const char *category, int priority, const char *funcname, + * threads, but avoid intermixing. Maybe set up locks per output + * to improve paralellism. + */ +- len = strlen(msg); +- virLogStr(msg, len); ++ virLogLock(); ++ virLogStr(timestamp); ++ virLogStr(msg); ++ virLogUnlock(); + if (emit == 0) + goto cleanup; + + virLogLock(); +- for (i = 0; i < virLogNbOutputs;i++) { ++ for (i = 0; i < virLogNbOutputs; i++) { + 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), ++ if (virLogVersionString(&ver) >= 0) ++ virLogOutputs[i].f(category, VIR_LOG_INFO, ++ __func__, __LINE__, ++ timestamp, ver, + virLogOutputs[i].data); + VIR_FREE(ver); + virLogOutputs[i].logVersion = false; + } + virLogOutputs[i].f(category, priority, funcname, linenr, +- msg, len, virLogOutputs[i].data); ++ timestamp, msg, virLogOutputs[i].data); + } + } + 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))); ++ if (virLogVersionString(&ver) >= 0) ++ virLogOutputToFd(category, VIR_LOG_INFO, ++ __func__, __LINE__, ++ timestamp, ver, ++ (void *) STDERR_FILENO); + VIR_FREE(ver); + logVersionStderr = false; + } +- ignore_value (safewrite(STDERR_FILENO, msg, len)); ++ virLogOutputToFd(category, priority, funcname, linenr, ++ timestamp, msg, (void *) STDERR_FILENO); + } + virLogUnlock(); + + cleanup: + VIR_FREE(msg); ++ VIR_FREE(timestamp); + errno = saved_errno; + } + +@@ -791,13 +804,23 @@ static int virLogOutputToFd(const char *category ATTRIBUTE_UNUSED, + int priority ATTRIBUTE_UNUSED, + const char *funcname ATTRIBUTE_UNUSED, + long long linenr ATTRIBUTE_UNUSED, +- const char *str, int len, void *data) { ++ const char *timestamp, ++ const char *str, ++ void *data) ++{ + int fd = (long) data; + int ret; ++ char *msg; + + if (fd < 0) + return -1; +- ret = safewrite(fd, str, len); ++ ++ if (virAsprintf(&msg, "%s: %s", timestamp, str) < 0) ++ return -1; ++ ++ ret = safewrite(fd, msg, strlen(msg)); ++ VIR_FREE(msg); ++ + return ret; + } + +@@ -833,8 +856,10 @@ static int virLogOutputToSyslog(const char *category ATTRIBUTE_UNUSED, + int priority, + const char *funcname ATTRIBUTE_UNUSED, + long long linenr ATTRIBUTE_UNUSED, +- const char *str, int len ATTRIBUTE_UNUSED, +- void *data ATTRIBUTE_UNUSED) { ++ const char *timestamp ATTRIBUTE_UNUSED, ++ const char *str, ++ void *data ATTRIBUTE_UNUSED) ++{ + int prio; + + switch (priority) { +@@ -854,7 +879,7 @@ static int virLogOutputToSyslog(const char *category ATTRIBUTE_UNUSED, + prio = LOG_ERR; + } + syslog(prio, "%s", str); +- return len; ++ return strlen(str); + } + + static char *current_ident = NULL; +diff --git a/src/util/logging.h b/src/util/logging.h +index 20c8948..2343de0 100644 +--- a/src/util/logging.h ++++ b/src/util/logging.h +@@ -78,8 +78,8 @@ typedef enum { + * @priority: the priority for the message + * @funcname: the function emitting the message + * @linenr: line where the message was emitted +- * @msg: the message to log, preformatted and zero terminated +- * @len: the lenght of the message in bytes without the terminating zero ++ * @timestamp: zero terminated string with timestamp of the message ++ * @str: the message to log, preformatted and zero terminated + * @data: extra output logging data + * + * Callback function used to output messages +@@ -87,8 +87,9 @@ typedef enum { + * Returns the number of bytes written or -1 in case of error + */ + typedef int (*virLogOutputFunc) (const char *category, int priority, +- const char *funcname, long long lineno, +- const char *str, int len, void *data); ++ const char *funcname, long long linenr, ++ const char *timestamp, const char *str, ++ void *data); + + /** + * virLogCloseFunc: +diff --git a/tests/testutils.c b/tests/testutils.c +index d9582af..08db732 100644 +--- a/tests/testutils.c ++++ b/tests/testutils.c +@@ -458,11 +458,13 @@ virtTestLogOutput(const char *category ATTRIBUTE_UNUSED, + int priority ATTRIBUTE_UNUSED, + const char *funcname ATTRIBUTE_UNUSED, + long long lineno ATTRIBUTE_UNUSED, +- const char *str, int len, void *data) ++ const char *timestamp, ++ const char *str, ++ void *data) + { + struct virtTestLogData *log = data; +- virBufferAdd(&log->buf, str, len); +- return len; ++ virBufferAsprintf(&log->buf, "%s: %s", timestamp, str); ++ return strlen(timestamp) + 2 + strlen(str); + } + + static void +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-network-don-t-add-iptables-rules-for-externally-mana.patch b/libvirt-0.9.6-network-don-t-add-iptables-rules-for-externally-mana.patch new file mode 100644 index 0000000..87be2b3 --- /dev/null +++ b/libvirt-0.9.6-network-don-t-add-iptables-rules-for-externally-mana.patch @@ -0,0 +1,63 @@ +From 5518346b4eb63a89d61f49f3ae9e58dd2ebfbd94 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Tue, 6 Dec 2011 15:13:50 -0500 +Subject: [PATCH 11/13] network: don't add iptables rules for externally + managed networks + +(direct cherry-pick of upstream commit ae1232b) + +This patch addresses https://bugzilla.redhat.com/show_bug.cgi?id=760442 + +When a network has any forward type other than route, nat or none, the +network configuration should be done completely external to libvirt - +libvirt only uses these types to allow configuring guests in a manner +that isn't tied to a specific host (all the host-specific information, +in particular interface names, port profile data, and bandwidth +configuration is in the network definition, and the guest +configuration only references it). + +Due to a bug in the bridge network driver, libvirt was adding iptables +rules for networks with forward type='bridge' etc. any time libvirtd +was restarted while one of these networks was active. + +This patch eliminates that error by only "reloading" iptables rules if +forward type is route, nat, or none. +--- + src/network/bridge_driver.c | 18 +++++++++++++----- + 1 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index 9960745..be725d9 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -1480,14 +1480,22 @@ networkReloadIptablesRules(struct network_driver *driver) + VIR_INFO("Reloading iptables rules"); + + for (i = 0 ; i < driver->networks.count ; i++) { +- virNetworkObjLock(driver->networks.objs[i]); +- if (virNetworkObjIsActive(driver->networks.objs[i])) { +- networkRemoveIptablesRules(driver, driver->networks.objs[i]); +- if (networkAddIptablesRules(driver, driver->networks.objs[i]) < 0) { ++ virNetworkObjPtr network = driver->networks.objs[i]; ++ ++ virNetworkObjLock(network); ++ if (virNetworkObjIsActive(network) && ++ ((network->def->forwardType == VIR_NETWORK_FORWARD_NONE) || ++ (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) || ++ (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE))) { ++ /* Only the three L3 network types that are configured by libvirt ++ * need to have iptables rules reloaded. ++ */ ++ networkRemoveIptablesRules(driver, network); ++ if (networkAddIptablesRules(driver, network) < 0) { + /* failed to add but already logged */ + } + } +- virNetworkObjUnlock(driver->networks.objs[i]); ++ virNetworkObjUnlock(network); + } + } + +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-qemu-replace-deprecated-fedora-13-machine.patch b/libvirt-0.9.6-qemu-replace-deprecated-fedora-13-machine.patch new file mode 100644 index 0000000..50cea33 --- /dev/null +++ b/libvirt-0.9.6-qemu-replace-deprecated-fedora-13-machine.patch @@ -0,0 +1,145 @@ +From 3007fc36e4b437bf5ffe9dee4883e68e49740c92 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Tue, 6 Dec 2011 12:47:28 -0500 +Subject: [PATCH] qemu: replace deprecated fedora-13 machine type with pc-0.14 + +This addresses https://bugzilla.redhat.com/show_bug.cgi?id=754772 . +It should only be applied to Fedora builds of libvirt, F15 and +later, so there is no upstream equivalent patch. + +Background: + +During the lifetime of Fedora 13, some features were backported into +the F13 build of qemu-kvm from upstream. These features were part of +the functionality of machine type "pc-0.13" in upstream qemu-kvm, so a +special "fedora-13" machine type was created for the F13 qemu-kvm. +Since "fedora-13" became the new "canonical machine type", all new +domains created with F13 libvirt tools by default contained that +machine type in their configuration file. + +In Fedora 14, a patch was made to qemu to treat the fedora-13 machine +type as equivalent to "pc-0.13". When Fedora 15 was released, this was +inadvertently changed to make it equivalent to "pc-0.14". + +With the release of Fedora 16, qemu-kvm initially removed support for +this machine type, which caused failure of many guest configurations +to start. qemu-kvm subsequently re-added the patch to support +fedora-13 (as equivalent to pc-0.14), but with the promise that they +could remove it with the release of Fedora 17. (see +https://bugzilla.redhat.com/show_bug.cgi?id=748218 ). + +Solution: + +In order to create a repeat of the recent problems, prior to F17 +existing guest configurations need to be updated to change fedora-13 +to pc-0.14 (which has been determined to be equivalent for all +practical purposes in both F15 and F16). That's what this patch does: + +1) Each time libvirtd is started, it calls virDomainLoadAllConfigs() +which calls virDomainLoadConfig(); this function has been modified to +check for os.machine == "fedora-13", and change it to "pc-0.14" then +write the updated config back to disk. + +2) Also, any other time a domain definition is parsed, the parsed +version in memory is changed to turn "fedora-13" into "pc-0.14". This +handles domains that had been saved to disk prior to the upgrade, and +are subsequently restarted. + +3) Finally, whenever a domain definition is formatted into a string, +any occurrence of fedora-13 is replaced with pc-0.14 *directly in the +virDomainDef* (to avoid multiple warning messages for the same object +when it's formatted multiple times). This should deal with those cases +where a domain was running at the time of upgrade, and is later +saved/snapshotted. + +I had considered doing this with some sed commands in the specfile, +but that wouldn't do anything to help the xml saved in image files. + +(Also, one of the xml tests was using the machine type "fedora-13", +and since that machine type is treated specially by the rest of this +patch, it was failing. That has been changed in a separate patch, +which must be applied with this patch, and which *is* also upstream). +--- + src/conf/domain_conf.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-- + 1 files changed, 49 insertions(+), 3 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 318f523..4f4163e 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -7500,7 +7500,25 @@ virDomainDefPtr virDomainDefParseString(virCapsPtr caps, + unsigned int expectedVirtTypes, + unsigned int flags) + { +- return virDomainDefParse(xmlStr, NULL, caps, expectedVirtTypes, flags); ++ virDomainDefPtr def ++ = virDomainDefParse(xmlStr, NULL, caps, expectedVirtTypes, flags); ++ ++ /* Fedora-specific HACK - treat fedora-13 and pc-0.14 as equivalent. ++ * This handles the case of domains that had been saved to an image file ++ * prior to upgrade (save or snapshot), then restarted/reverted. ++ */ ++ if (def && STREQ_NULLABLE(def->os.machine, "fedora-13")) { ++ VIR_FREE(def->os.machine); ++ if (!(def->os.machine = strdup("pc-0.14"))) { ++ virReportOOMError(); ++ virDomainDefFree(def); ++ def = NULL; ++ } else { ++ VIR_WARN("Replacing deprecated 'fedora-13' machine type " ++ "with equivalent 'pc-0.14' in domain %s xml", def->name); ++ } ++ } ++ return def; + } + + virDomainDefPtr virDomainDefParseFile(virCapsPtr caps, +@@ -10648,8 +10666,20 @@ virDomainDefFormatInternal(virDomainDefPtr def, + virBufferAddLit(buf, " os.arch) + virBufferAsprintf(buf, " arch='%s'", def->os.arch); +- if (def->os.machine) +- virBufferAsprintf(buf, " machine='%s'", def->os.machine); ++ if (def->os.machine) { ++ /* Fedora-specific HACK - replace "fedora-13" with "pc-0.14". ++ * This will catch XML being written to save/migration images ++ * of domains that were running when libvirtd was restarted at ++ * the time of upgrade. ++ */ ++ if (STREQ_NULLABLE(def->os.machine, "fedora-13")) { ++ virBufferAddLit(buf, " machine='pc-0.14'"); ++ VIR_WARN("substituting machine type 'fedora-13' with 'pc-0.14' " ++ "in domain %s", def->name); ++ } else { ++ virBufferAsprintf(buf, " machine='%s'", def->os.machine); ++ } ++ } + /* + * HACK: For xen driver we previously used bogus 'linux' as the + * os type for paravirt, whereas capabilities declare it to +@@ -11100,6 +11130,22 @@ static virDomainObjPtr virDomainLoadConfig(virCapsPtr caps, + VIR_DOMAIN_XML_INACTIVE))) + goto error; + ++ /* Fedora-specific HACK - replace "fedora-13" with "pc-0.14". ++ * This updates all config files at the first restart of libvirt ++ * after upgrade. ++ */ ++ if (STREQ_NULLABLE(def->os.machine, "fedora-13")) { ++ VIR_FREE(def->os.machine); ++ if (!(def->os.machine = strdup("pc-0.14"))) { ++ virReportOOMError(); ++ goto error; ++ } ++ VIR_WARN("Replacing deprecated 'fedora-13' machine type " ++ "with equivalent 'pc-0.14' in domain %s configuration file", name); ++ if (virDomainSaveConfig(configDir, def) < 0) ++ goto error; ++ } ++ + if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL) + goto error; + +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-spec-add-dmidecode-as-prereq.patch b/libvirt-0.9.6-spec-add-dmidecode-as-prereq.patch new file mode 100644 index 0000000..26e9abb --- /dev/null +++ b/libvirt-0.9.6-spec-add-dmidecode-as-prereq.patch @@ -0,0 +1,37 @@ +From 72675eeaebc67857d0f1f62b5daeaa35506cd207 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Mon, 5 Dec 2011 10:32:41 -0700 +Subject: [PATCH 08/13] spec: add dmidecode as prereq + +(cherry-pick of upstream e7dfa46 with extra requires for with_systemd +removed, since the patch that adds that hasn't been backported) + +https://bugzilla.redhat.com/show_bug.cgi?id=754909 complains that +because libvirt didn't require dmidecode, that the logs are noisy +and virConnectGetSysinfo needlessly fails. Even 'virt-what' requires +dmidecode, so it's not that onerous of a dependency. We may be +able to drop this in the future when we move to parsing sysfs data, +but for now, listing the dependency will help matters. + +* libvirt.spec.in (Requires): Sort Requires before BuildRequires. +Add dmidecode. +--- + libvirt.spec.in | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index 5cb87fb..ba950c6 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -326,6 +326,8 @@ Requires: device-mapper + %if %{with_cgconfig} + Requires: libcgroup + %endif ++# For virConnectGetSysinfo ++Requires: dmidecode + + # All build-time requirements + BuildRequires: python-devel +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-spec-don-t-use-chkconfig-list.patch b/libvirt-0.9.6-spec-don-t-use-chkconfig-list.patch new file mode 100644 index 0000000..f52e637 --- /dev/null +++ b/libvirt-0.9.6-spec-don-t-use-chkconfig-list.patch @@ -0,0 +1,51 @@ +From 65a4c1782b197787bb960427cf0106c8d8225777 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Tue, 6 Dec 2011 16:16:34 -0700 +Subject: [PATCH 09/13] spec: don't use chkconfig --list + +(direct cherry-pick of upstream commit fea83dd) + +https://bugzilla.redhat.com/show_bug.cgi?id=694403 reports that +the specfile is incorrectly checking for a running libvirt-guests +service. For example, + +$ LC_ALL=es_ES chkconfig --list libvirt-guests +libvirt-guests 0:desactivado 1:desactivado 2:desactivado 3:activo 4:activo 5:activo 6:desactivado + +will fail to find 5:on, even though it is active. But chkconfig +already has a mode where you can silently use the exit status to +check for an active service. + +* libvirt.spec.in (%post): Use simpler chkconfig options, to avoid +issues with localization. +--- + libvirt.spec.in | 6 ++---- + 1 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index ba950c6..ad522bc 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -846,8 +846,7 @@ getent passwd qemu >/dev/null || \ + # We want to install the default network for initial RPM installs + # or on the first upgrade from a non-network aware libvirt only. + # We check this by looking to see if the daemon is already installed +-/sbin/chkconfig --list libvirtd 1>/dev/null 2>&1 +-if test $? != 0 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ++if ! /sbin/chkconfig libvirtd && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml + then + UUID=`/usr/bin/uuidgen` + sed -e "s,,\n $UUID," \ +@@ -934,8 +933,7 @@ fi + /sbin/chkconfig --add libvirt-guests + if [ $1 -ge 1 ]; then + level=$(/sbin/runlevel | /bin/cut -d ' ' -f 2) +- if /sbin/chkconfig --list libvirt-guests 2>/dev/null \ +- | /bin/grep -q $level:on ; then ++ if /sbin/chkconfig --levels $level libvirt-guests; then + # this doesn't do anything but allowing for libvirt-guests to be + # stopped on the first shutdown + /sbin/service libvirt-guests start > /dev/null 2>&1 || true +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-spec-fix-logic-bug-in-deciding-to-turn-on-cgconfig.patch b/libvirt-0.9.6-spec-fix-logic-bug-in-deciding-to-turn-on-cgconfig.patch new file mode 100644 index 0000000..13bcb4e --- /dev/null +++ b/libvirt-0.9.6-spec-fix-logic-bug-in-deciding-to-turn-on-cgconfig.patch @@ -0,0 +1,52 @@ +From 6b9e1293f940536fcdfba91b1aea776ad847e09c Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Thu, 8 Dec 2011 13:32:37 -0700 +Subject: [PATCH 10/13] spec: fix logic bug in deciding to turn on cgconfig + +(cirect cherry-pick of upstream commit 3b95f28) + +https://bugzilla.redhat.com/show_bug.cgi?id=738725 + +Commit ecd8725 tried to silence a spurious warning on the initial +libvirt install, and commit ba6cbb1 tried to fix up the logic to the +correct Fedora version, but the warning was still present due to a +logic bug: since %{fedora} and %{rhel} are never simulatanously +set, then 0%{rhel} <= 6 made the %if always true. Checking for +minimum versions (via >=) is okay, but checking for maximum versions +(via <=) requires a prerequisite test that the platform being tested +is non-zero. + +Also fix a bogus setting of with_libxl (although we previously +hard-code with_libxl to 0 for rhel earlier in the file, so this +was not as severe a bug). + +* libvirt.spec.in (with_cgconfig): Don't enable cgconfig on F16. +--- + libvirt.spec.in | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index ad522bc..cfc3a43 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -135,7 +135,7 @@ + %endif + + # Fedora doesn't have new enough Xen for libxl until F16 +-%if 0%{?fedora} < 16 ++%if 0%{?fedora} && 0%{?fedora} < 16 + %define with_libxl 0 + %endif + +@@ -899,7 +899,7 @@ done + %if %{with_cgconfig} + # Starting with Fedora 16, systemd automounts all cgroups, and cgconfig is + # no longer a necessary service. +-%if 0%{?fedora} <= 15 || 0%{?rhel} <= 6 ++%if 0%{?rhel} || (0%{?fedora} && 0%{?fedora} < 16) + if [ "$1" -eq "1" ]; then + /sbin/chkconfig cgconfig on + fi +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-spec-mark-directories-in-var-run-as-ghosts.patch b/libvirt-0.9.6-spec-mark-directories-in-var-run-as-ghosts.patch new file mode 100644 index 0000000..57756a5 --- /dev/null +++ b/libvirt-0.9.6-spec-mark-directories-in-var-run-as-ghosts.patch @@ -0,0 +1,74 @@ +From 15dbf094eb90a896ecb73c4c92bed649eb8b5f4c Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Wed, 30 Nov 2011 15:34:42 -0700 +Subject: [PATCH 06/13] spec: mark directories in /var/run as ghosts + +(direct cherry-pick of upstream 764574f to resolve +https://bugzilla.redhat.com/show_bug.cgi?id=758896) + +We have several directories that are created on the fly, and which +only contain state relevant to a running libvirtd process (all +located in /var/run). Since the directories are created as needed, +and make no sense without a running libvirtd, we want them deleted +if libvirt is uninstalled. And in F15 and newer, /var/run is on +tmpfs (forcing us to recreate on the fly); which means that someone +trying to verify a complete rpm will fail if the directory does not +currently exist because libvirtd has not been started since boot. +The solution, then, is to mark the directories as %ghost, so that +rpm knows that we own them and will clean it up if libvirt is +uninstalled, but will no longer create the directory for us at +install, nor complain at verify time if the directory does not exist. + +See https://bugzilla.redhat.com/show_bug.cgi?id=656611. + +* libvirt.spec.in (%files): Add %ghost to temporary directories +that we don't install, but want cleaned up on libvirt removal. +--- + libvirt.spec.in | 12 ++++++------ + 1 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/libvirt.spec.in b/libvirt.spec.in +index b87e3f6..5cb87fb 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -992,31 +992,31 @@ fi + %{_datadir}/libvirt/networks/default.xml + %endif + +-%dir %{_localstatedir}/run/libvirt/ ++%ghost %dir %{_localstatedir}/run/libvirt/ + + %dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/images/ + %dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/boot/ + %dir %attr(0711, root, root) %{_localstatedir}/cache/libvirt/ + + %if %{with_qemu} +-%dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/ ++%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/ + %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ + %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ + %endif + %if %{with_lxc} +-%dir %{_localstatedir}/run/libvirt/lxc/ ++%ghost %dir %{_localstatedir}/run/libvirt/lxc/ + %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/lxc/ + %endif + %if %{with_uml} +-%dir %{_localstatedir}/run/libvirt/uml/ ++%ghost %dir %{_localstatedir}/run/libvirt/uml/ + %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/ + %endif + %if %{with_libxl} +-%dir %{_localstatedir}/run/libvirt/libxl/ ++%ghost %dir %{_localstatedir}/run/libvirt/libxl/ + %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/ + %endif + %if %{with_network} +-%dir %{_localstatedir}/run/libvirt/network/ ++%ghost %dir %{_localstatedir}/run/libvirt/network/ + %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/ + %dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/ + %endif +-- +1.7.7.3 + diff --git a/libvirt-0.9.6-test-replace-deprecated-fedora-13-machine.patch b/libvirt-0.9.6-test-replace-deprecated-fedora-13-machine.patch new file mode 100644 index 0000000..d1ec284 --- /dev/null +++ b/libvirt-0.9.6-test-replace-deprecated-fedora-13-machine.patch @@ -0,0 +1,52 @@ +From 3ee5e12e58f876cf2ffc7d668e4ce9d461a9a7fd Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Fri, 9 Dec 2011 15:55:14 -0500 +Subject: [PATCH 12/13] test: replace deprecated "fedora-13" machine with + "pc-0.13" + +This is a direct cherry-pick of upstream commit 7204a9f. This patch is a +prerequisite for the following patch "qemu: replace deprecated +fedora-13 machine type with pc-0.14", which resolves +https://bugzilla.redhat.com/show_bug.cgi?id=754772 . + +One of the xml tests in the test suite was created using a +now-deprecated qemu machine type ("fedora-13", which was only ever +valid for Fedora builds of qemu). Although strictly speaking it's not +necessary to replace it with an actual supported qemu machine type +(since the xml in question is never actually sent to qemu), this patch +changes it to the actually-supported "pc-0.13" just for general +tidiness. (Also, on some Fedora builds which contain a special patch +to rid the world of "fedora-13", having it mentioned in the test suite +will cause make check to fail.) +--- + .../qemuxml2argv-encrypted-disk.args | 2 +- + .../qemuxml2argv-encrypted-disk.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.args b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.args +index 1da0073..c6634fd 100644 +--- a/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.args ++++ b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.args +@@ -1,5 +1,5 @@ + LC_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin HOME=/root USER=root LOGNAME=root \ +-/usr/bin/qemu -S -M fedora-13 -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name \ ++/usr/bin/qemu -S -M pc-0.13 -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name \ + encryptdisk -uuid 496898a6-e6ff-f7c8-5dc2-3cf410945ee9 -nographic -nodefconfig \ + -nodefaults -chardev socket,id=monitor,\ + path=//var/lib/libvirt/qemu/encryptdisk.monitor,server,nowait -mon \ +diff --git a/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.xml +index f5e5d74..fdcf624 100644 +--- a/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.xml ++++ b/tests/qemuxml2argvdata/qemuxml2argv-encrypted-disk.xml +@@ -5,7 +5,7 @@ + 524288 + 1 + +- hvm ++ hvm + + + +-- +1.7.7.3 + diff --git a/libvirt.spec b/libvirt.spec index d6afdbc..8ad5578 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -136,7 +136,7 @@ %endif # Fedora doesn't have new enough Xen for libxl until F16 -%if 0%{?fedora} < 16 +%if 0%{?fedora} && 0%{?fedora} < 16 %define with_libxl 0 %endif @@ -235,12 +235,26 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 0.9.6 -Release: 3%{?dist}%{?extra_release} +Release: 4%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz Patch1: %{name}-%{version}-spec-F15-still-uses-cgconfig.patch Patch2: %{name}-%{version}-qemu-make-PCI-multifunction-support-more-manual.patch +Patch3:%{name}-%{version}-logging-Do-not-log-timestamp-through-syslog.patch +Patch4:%{name}-%{version}-logging-Add-date-to-log-timestamp.patch +Patch5:%{name}-%{version}-Add-internal-APIs-for-dealing-with-time.patch +Patch6:%{name}-%{version}-Make-logging-async-signal-safe-wrt-time-stamp-genera.patch +Patch7:%{name}-%{version}-Remove-time-APIs-from-src-util-util.h.patch +Patch8:%{name}-%{version}-spec-mark-directories-in-var-run-as-ghosts.patch +Patch9:%{name}-%{version}-Fix-incorrect-symbols-for-virtime.h-module-breaking-.patch +Patch10:%{name}-%{version}-spec-add-dmidecode-as-prereq.patch +Patch11:%{name}-%{version}-spec-don-t-use-chkconfig-list.patch +Patch12:%{name}-%{version}-spec-fix-logic-bug-in-deciding-to-turn-on-cgconfig.patch +Patch13:%{name}-%{version}-network-don-t-add-iptables-rules-for-externally-mana.patch +Patch14:%{name}-%{version}-test-replace-deprecated-fedora-13-machine.patch +Patch15:%{name}-%{version}-qemu-replace-deprecated-fedora-13-machine.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/ @@ -329,6 +343,8 @@ Requires: device-mapper %if %{with_cgconfig} Requires: libcgroup %endif +# For virConnectGetSysinfo +Requires: dmidecode # All build-time requirements BuildRequires: python-devel @@ -554,6 +570,19 @@ of recent versions of Linux (and other OSes). %setup -q %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 %build %if ! %{with_xen} @@ -853,8 +882,7 @@ getent passwd qemu >/dev/null || \ # We want to install the default network for initial RPM installs # or on the first upgrade from a non-network aware libvirt only. # We check this by looking to see if the daemon is already installed -/sbin/chkconfig --list libvirtd 1>/dev/null 2>&1 -if test $? != 0 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml +if ! /sbin/chkconfig libvirtd && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml then UUID=`/usr/bin/uuidgen` sed -e "s,,\n $UUID," \ @@ -905,9 +933,9 @@ done %endif %if %{with_cgconfig} -# Starting with Fedora 15, systemd automounts all cgroups, and cgconfig is +# Starting with Fedora 16, systemd automounts all cgroups, and cgconfig is # no longer a necessary service. -%if 0%{?fedora} <= 15 || 0%{?rhel} <= 6 +%if 0%{?rhel} || (0%{?fedora} && 0%{?fedora} < 16) if [ "$1" -eq "1" ]; then /sbin/chkconfig cgconfig on fi @@ -941,8 +969,7 @@ fi /sbin/chkconfig --add libvirt-guests if [ $1 -ge 1 ]; then level=$(/sbin/runlevel | /bin/cut -d ' ' -f 2) - if /sbin/chkconfig --list libvirt-guests 2>/dev/null \ - | /bin/grep -q $level:on ; then + if /sbin/chkconfig --levels $level libvirt-guests; then # this doesn't do anything but allowing for libvirt-guests to be # stopped on the first shutdown /sbin/service libvirt-guests start > /dev/null 2>&1 || true @@ -1001,31 +1028,31 @@ fi %{_datadir}/libvirt/networks/default.xml %endif -%dir %{_localstatedir}/run/libvirt/ +%ghost %dir %{_localstatedir}/run/libvirt/ %dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/images/ %dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/boot/ %dir %attr(0711, root, root) %{_localstatedir}/cache/libvirt/ %if %{with_qemu} -%dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/ +%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %endif %if %{with_lxc} -%dir %{_localstatedir}/run/libvirt/lxc/ +%ghost %dir %{_localstatedir}/run/libvirt/lxc/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/lxc/ %endif %if %{with_uml} -%dir %{_localstatedir}/run/libvirt/uml/ +%ghost %dir %{_localstatedir}/run/libvirt/uml/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/ %endif %if %{with_libxl} -%dir %{_localstatedir}/run/libvirt/libxl/ +%ghost %dir %{_localstatedir}/run/libvirt/libxl/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/ %endif %if %{with_network} -%dir %{_localstatedir}/run/libvirt/network/ +%ghost %dir %{_localstatedir}/run/libvirt/network/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/ %dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/ %endif @@ -1161,6 +1188,19 @@ fi %endif %changelog +* Sun Dec 18 2011 Laine Stump - 0.9.6-4 +- replace "fedora-13" machine type with "pc-0.14" to prepare + systems for removal of "fedora-13" from qemu - Bug 754772 +- don't add iptables rules for externally managed networks + - Buf 765964 / CVE-2011-4600 +- specfile changes + - Bug 761329 don't use chkconfig --list + - Bug 758896 mark directories in /var/run as ghosts + - Bug 738725 fix logic bug in deciding to turn on cgconfig + - Bug 754909 add dmidecode as a prerequisite +- new async-safe time API + make logging async signal sage wrt. + time stamp generation - Bug 757382 + * Tue Oct 11 2011 Dan HorĂ¡k - 0.9.6-3 - xenlight available only on Xen arches (#745020)