Remove unapplied patches

remotes/origin/f16
Cole Robinson 2012-06-19 09:49:03 -04:00
parent 21b5b71da6
commit 4b8c90d47a
23 changed files with 0 additions and 3385 deletions

View File

@ -1,734 +0,0 @@
From f514fb152ed5f2ff5bd372c07e47e56f8496a3db Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
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 <berrange@redhat.com>
+ *
+ * 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 <config.h>
+
+#include <stdio.h>
+#ifndef HAVE_CLOCK_GETTIME
+# include <sys/time.h>
+#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 <berrange@redhat.com>
+ */
+
+#ifndef __VIR_TIME_H__
+# define __VIR_TIME_H__
+
+# include <time.h>
+
+# 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 <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <signal.h>
+
+#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

View File

@ -1,45 +0,0 @@
From 7a1eb2ead5d441e3604070e8fe89cce475cc45a8 Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Thu, 1 Dec 2011 11:33:50 -0500
Subject: [PATCH] Avoid crash in shunloadtest
For unknown reasons, the shunloadtest will crash on Fedora 16
inside dlopen()
(gdb) bt
#0 0x00000000000050e6 in ?? ()
#1 0x00007ff61a77b9d5 in floor () from /lib64/libm.so.6
#2 0x00007ff61e522963 in _dl_relocate_object () from /lib64/ld-linux-x86-64.so.2
#3 0x00007ff61e5297e6 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#4 0x00007ff61e525006 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#5 0x00007ff61e52917a in _dl_open () from /lib64/ld-linux-x86-64.so.2
#6 0x00007ff61e0f6f26 in dlopen_doit () from /lib64/libdl.so.2
#7 0x00007ff61e525006 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#8 0x00007ff61e0f752f in _dlerror_run () from /lib64/libdl.so.2
#9 0x00007ff61e0f6fc1 in dlopen@@GLIBC_2.2.5 () from /lib64/libdl.so.2
#10 0x0000000000400a15 in main (argc=<optimized out>, argv=<optimized out>) at shunloadtest.c:105
Changing from RTLD_NOW to RTLD_LAZY avoids this problem,
but quite possibly does not fix the root cause.
* shunloadtest.c: s/NOW/LAZY/
---
tests/shunloadtest.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tests/shunloadtest.c b/tests/shunloadtest.c
index 2cdb8b8..ab6e56f 100644
--- a/tests/shunloadtest.c
+++ b/tests/shunloadtest.c
@@ -102,7 +102,7 @@ int main(int argc ATTRIBUTE_UNUSED, char **argv)
fprintf(stderr, " .%*s 1 ", 39, "");
signal(SIGSEGV, sigHandler);
- if (!(lib = dlopen("./.libs/libshunload.so", RTLD_NOW))) {
+ if (!(lib = dlopen("./.libs/libshunload.so", RTLD_LAZY))) {
fprintf(stderr, "Cannot load ./.libs/libshunload.so %s\n", dlerror());
return 1;
}
--
1.7.7.4

View File

@ -1,44 +0,0 @@
From 73469d2989ad7cd4ed0802ea75d5b111af44eeb1 Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
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

View File

@ -1,89 +0,0 @@
From 744247bcfdba1dc90f71f3ef693f557b663a9cc8 Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
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

View File

@ -1,364 +0,0 @@
From 711c78a100649a47c11c90f5efa510421f711013 Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
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 <sys/time.h>
#include <fcntl.h>
@@ -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 <fcntl.h>
#include <errno.h>
#include <poll.h>
-#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
-#include <sys/time.h>
#if HAVE_MMAP
# include <sys/mman.h>
#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(&timestamp, "%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

View File

@ -1,30 +0,0 @@
From 69b05e20e64836c3a1a125b17b0101f70492ffd7 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
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

View File

@ -1,327 +0,0 @@
From 978ca41b4bc59033e39cf8b1a69f3869d160e7d6 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
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

View File

@ -1,63 +0,0 @@
From 5518346b4eb63a89d61f49f3ae9e58dd2ebfbd94 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
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

View File

@ -1,581 +0,0 @@
From 3962198d82ab90d21144479c1d822db5d1f640a4 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@laine.org>
Date: Wed, 28 Sep 2011 14:19:59 -0400
Subject: [PATCH 2/2] qemu: make PCI multifunction support more manual
(This is a merge of cherry-picking upstream commits
c329db7180d77c8077b9f9cd167a71d7f347227a and
be7bc4d5ccb502c2da85d3b3db804fd53b70449e (a one liner). There were no
merge conflicts.)
When support for was added for PCI multifunction cards (in commit
9f8baf, first included in libvirt 0.9.3), it was done by always
turning on the multifunction bit for all PCI devices. Since that time
it has been realized that this is not an ideal solution, and that the
multifunction bit must be selectively turned on. For example, see
https://bugzilla.redhat.com/show_bug.cgi?id=742836
and the discussion before and after
https://www.redhat.com/archives/libvir-list/2011-September/msg01036.html
This patch modifies multifunction support so that the multifunction=on
option is only added to the qemu commandline for a device if its PCI
<address> definition has the attribute "multifunction='on'", e.g.:
<address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0' multifunction='on'/>
In practice, the multifunction bit should only be turned on if
function='0' AND other functions will be used in the same slot - it
usually isn't needed for functions 1-7 (although there are apparently
some exceptions, e.g. the Intel X53 according to the QEMU source
code), and should never be set if only function 0 will be used in the
slot. The test cases have been changed accordingly to illustrate.
With this patch in place, if a user attempts to assign multiple
functions in a slot without setting the multifunction bit for function
0, libvirt will issue an error when the domain is defined, and the
define operation will fail. In the future, we may decide to detect
this situation and automatically add multifunction=on to avoid the
error; even then it will still be useful to have a manual method of
turning on multifunction since, as stated above, there are some
devices that excpect it to be turned on for all functions in a slot.
A side effect of this patch is that attempts to use the same PCI
address for two different devices will now log an error (previously
this would cause the domain define operation to fail, but there would
be no log message generated). Because the function doing this log was
almost completely rewritten, I didn't think it worthwhile to make a
separate patch for that fix (the entire patch would immediately be
obsoleted).
---
docs/formatdomain.html.in | 29 +++++--
docs/schemas/domaincommon.rng | 8 ++
src/conf/domain_conf.c | 22 +++++-
src/conf/domain_conf.h | 11 +++-
src/libvirt_private.syms | 2 +
src/qemu/qemu_command.c | 81 ++++++++++++++++----
.../qemuxml2argv-multifunction-pci-device.args | 18 ++--
.../qemuxml2argv-multifunction-pci-device.xml | 6 +-
.../qemuxml2argv-usb-ich9-companion.args | 15 ++--
.../qemuxml2argv-usb-ich9-companion.xml | 2 +-
.../qemuxml2argv-usb-ich9-ehci-addr.args | 7 ++-
.../qemuxml2argv-usb-piix3-controller.args | 7 ++-
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args | 10 +-
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args | 25 ++++---
tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml | 4 +-
16 files changed, 183 insertions(+), 66 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0a7abaf..390476d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1113,10 +1113,14 @@
The <code>type</code> attribute is mandatory, and is typically
"pci" or "drive". For a "pci" controller, additional
attributes for <code>bus</code>, <code>slot</code>,
- and <code>function</code> must be present, as well as an
- optional <code>domain</code>. For a "drive" controller,
- additional attributes <code>controller</code>, <code>bus</code>,
+ and <code>function</code> must be present, as well as
+ optional <code>domain</code> and <code>multifunction</code>.
+ Multifunction defaults to 'off'; any other value requires
+ QEMU 0.1.3 and <span class="since">libvirt 0.9.7</span>. For a
+ "drive" controller, additional attributes
+ <code>controller</code>, <code>bus</code>,
and <code>unit</code> are available, each defaulting to 0.
+
</dd>
</dl>
@@ -1293,7 +1297,7 @@
&lt;/controller&gt;
&lt;controller type='usb' index='0' model='ich9-uhci1'&gt;
&lt;master startport='0'/&gt;
- &lt;address type='pci' domain='0' bus='0' slot='4' function='0'/&gt;
+ &lt;address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/&gt;
&lt;/controller&gt;
...
&lt;/devices&gt;
@@ -1413,10 +1417,16 @@
with <code>virsh nodedev-list</code>. The
<code>bus</code> attribute allows the hexadecimal values 0 to ff, the
<code>slot</code> attribute allows the hexadecimal values 0 to 1f, and
- the <code>function</code> attribute allows the hexadecimal values 0 to
- 7. There is also an optional <code>domain</code> attribute for the
- PCI domain, with hexadecimal values 0 to ffff, but it is currently
- not used by qemu.</dd>
+ the <code>function</code> attribute allows the hexadecimal values 0 to 7.
+ The <code>multifunction</code> attribute controls turning on the
+ multifunction bit for a particular slot/function in the PCI
+ control register<span class="since">since 0.9.7, requires QEMU
+ 0.13</span>. <code>multifunction</code> defaults to 'off', but
+ should be set to 'on' for function 0 of a slot that will have
+ multiple functions used.
+ There is also an optional <code>domain</code> attribute for
+ the PCI domain, with hexadecimal values 0 to ffff, but it is
+ currently not used by qemu.</dd>
</dl>
<h4><a name="elementsRedir">Redirected devices</a></h4>
@@ -1584,7 +1594,8 @@
the interface to a particular pci slot, with
attribute <code>type='pci'</code> and additional
attributes <code>domain</code>, <code>bus</code>, <code>slot</code>,
- and <code>function</code> as appropriate.
+ <code>function</code>, and <code>multifunction</code>
+ <span class="since">since 0.9.7, requires QEMU 0.13</span> as appropriate.
</p>
<h5><a name="elementsNICSVirtual">Virtual network</a></h5>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d0da41c..9f8d292 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2106,6 +2106,14 @@
<attribute name="function">
<ref name="pciFunc"/>
</attribute>
+ <optional>
+ <attribute name="multifunction">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ </optional>
</define>
<define name="driveaddress">
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7463d7c..318f523 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -138,6 +138,12 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"ccid",
"usb")
+VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
+ VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
+ "default",
+ "on",
+ "off")
+
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block",
"file",
@@ -1645,6 +1651,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
info->addr.pci.bus,
info->addr.pci.slot,
info->addr.pci.function);
+ if (info->addr.pci.multi) {
+ virBufferAsprintf(buf, " multifunction='%s'",
+ virDomainDeviceAddressPciMultiTypeToString(info->addr.pci.multi));
+ }
break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
@@ -1689,7 +1699,7 @@ static int
virDomainDevicePCIAddressParseXML(xmlNodePtr node,
virDomainDevicePCIAddressPtr addr)
{
- char *domain, *slot, *bus, *function;
+ char *domain, *slot, *bus, *function, *multi;
int ret = -1;
memset(addr, 0, sizeof(*addr));
@@ -1698,6 +1708,7 @@ virDomainDevicePCIAddressParseXML(xmlNodePtr node,
bus = virXMLPropString(node, "bus");
slot = virXMLPropString(node, "slot");
function = virXMLPropString(node, "function");
+ multi = virXMLPropString(node, "multifunction");
if (domain &&
virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
@@ -1727,6 +1738,14 @@ virDomainDevicePCIAddressParseXML(xmlNodePtr node,
goto cleanup;
}
+ if (multi &&
+ ((addr->multi = virDomainDeviceAddressPciMultiTypeFromString(multi)) <= 0)) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unknown value '%s' for <address> 'multifunction' attribute"),
+ multi);
+ goto cleanup;
+
+ }
if (!virDomainDevicePCIAddressIsValid(addr)) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Insufficient specification for PCI address"));
@@ -1740,6 +1759,7 @@ cleanup:
VIR_FREE(bus);
VIR_FREE(slot);
VIR_FREE(function);
+ VIR_FREE(multi);
return ret;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 371f270..f4a38fb 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -74,6 +74,14 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
};
+enum virDomainDeviceAddressPciMulti {
+ VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_DEFAULT = 0,
+ VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON,
+ VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_OFF,
+
+ VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST
+};
+
typedef struct _virDomainDevicePCIAddress virDomainDevicePCIAddress;
typedef virDomainDevicePCIAddress *virDomainDevicePCIAddressPtr;
struct _virDomainDevicePCIAddress {
@@ -81,6 +89,7 @@ struct _virDomainDevicePCIAddress {
unsigned int bus;
unsigned int slot;
unsigned int function;
+ int multi; /* enum virDomainDeviceAddressPciMulti */
};
typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress;
@@ -1820,7 +1829,7 @@ VIR_ENUM_DECL(virDomainLifecycle)
VIR_ENUM_DECL(virDomainLifecycleCrash)
VIR_ENUM_DECL(virDomainDevice)
VIR_ENUM_DECL(virDomainDeviceAddress)
-VIR_ENUM_DECL(virDomainDeviceAddressMode)
+VIR_ENUM_DECL(virDomainDeviceAddressPciMulti)
VIR_ENUM_DECL(virDomainDisk)
VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8235ea1..da3042e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -269,6 +269,8 @@ virDomainDefParseNode;
virDomainDefParseString;
virDomainDeleteConfig;
virDomainDeviceAddressIsValid;
+virDomainDeviceAddressPciMultiTypeFromString;
+virDomainDeviceAddressPciMultiTypeToString;
virDomainDeviceAddressTypeToString;
virDomainDeviceDefFree;
virDomainDeviceDefParse;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0adc56a..ee184c2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -772,22 +772,65 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceInfoPtr dev,
void *opaque)
{
+ int ret = -1;
+ char *addr = NULL;
qemuDomainPCIAddressSetPtr addrs = opaque;
- if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
- char *addr = qemuPCIAddressAsString(dev);
- if (!addr)
- return -1;
+ if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+ return 0;
- VIR_DEBUG("Remembering PCI addr %s", addr);
+ addr = qemuPCIAddressAsString(dev);
+ if (!addr)
+ goto cleanup;
- if (virHashAddEntry(addrs->used, addr, addr) < 0) {
- VIR_FREE(addr);
- return -1;
+ if (virHashLookup(addrs->used, addr)) {
+ if (dev->addr.pci.function != 0) {
+ qemuReportError(VIR_ERR_XML_ERROR,
+ _("Attempted double use of PCI Address '%s' "
+ "(may need \"multifunction='on'\" for device on function 0"),
+ addr);
+ } else {
+ qemuReportError(VIR_ERR_XML_ERROR,
+ _("Attempted double use of PCI Address '%s'"), addr);
}
+ goto cleanup;
}
- return 0;
+ VIR_DEBUG("Remembering PCI addr %s", addr);
+ if (virHashAddEntry(addrs->used, addr, addr) < 0)
+ goto cleanup;
+ addr = NULL;
+
+ if ((dev->addr.pci.function == 0) &&
+ (dev->addr.pci.multi != VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)) {
+ /* a function 0 w/o multifunction=on must reserve the entire slot */
+ int function;
+ virDomainDeviceInfo temp_dev = *dev;
+
+ for (function = 1; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
+ temp_dev.addr.pci.function = function;
+ addr = qemuPCIAddressAsString(&temp_dev);
+ if (!addr)
+ goto cleanup;
+
+ if (virHashLookup(addrs->used, addr)) {
+ qemuReportError(VIR_ERR_XML_ERROR,
+ _("Attempted double use of PCI Address '%s'"
+ "(need \"multifunction='off'\" for device on function 0)"),
+ addr);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", addr);
+ if (virHashAddEntry(addrs->used, addr, addr))
+ goto cleanup;
+ addr = NULL;
+ }
+ }
+ ret = 0;
+cleanup:
+ VIR_FREE(addr);
+ return ret;
}
@@ -1374,7 +1417,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
if (info->addr.pci.function != 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Only PCI device addresses with function=0 "
- "are supported"));
+ "are supported with this QEMU binary"));
+ return -1;
+ }
+ if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("'multifunction=on' is not supported with "
+ "this QEMU binary"));
return -1;
}
}
@@ -1389,11 +1438,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
virBufferAsprintf(buf, ",bus=pci.0");
else
virBufferAsprintf(buf, ",bus=pci");
- if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION))
- virBufferAsprintf(buf, ",multifunction=on,addr=0x%x.0x%x",
- info->addr.pci.slot, info->addr.pci.function);
- else
- virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot);
+ if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)
+ virBufferAddLit(buf, ",multifunction=on");
+ else if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_OFF)
+ virBufferAddLit(buf, ",multifunction=off");
+ virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot);
+ if (info->addr.pci.function != 0)
+ virBufferAsprintf(buf, ".0x%x", info->addr.pci.function);
} else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
virBufferAsprintf(buf, ",bus=");
qemuUsbId(buf, info->addr.usb.bus);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.args b/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.args
index ff229f2..8a2150e 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.args
@@ -1,15 +1,15 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
--device lsi,id=scsi0,bus=pci.0,multifunction=on,addr=0x3.0x0 \
--device lsi,id=scsi1,bus=pci.0,multifunction=on,addr=0x4.0x0 \
+-device lsi,id=scsi0,bus=pci.0,multifunction=off,addr=0x3 \
+-device lsi,id=scsi1,bus=pci.0,multifunction=on,addr=0x4 \
-device lsi,id=scsi2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device lsi,id=scsi3,bus=pci.0,multifunction=on,addr=0x4.0x2 \
--device lsi,id=scsi4,bus=pci.0,multifunction=on,addr=0x4.0x3 \
--device lsi,id=scsi5,bus=pci.0,multifunction=on,addr=0x4.0x4 \
--device lsi,id=scsi6,bus=pci.0,multifunction=on,addr=0x4.0x5 \
--device lsi,id=scsi7,bus=pci.0,multifunction=on,addr=0x4.0x6 \
--device lsi,id=scsi8,bus=pci.0,multifunction=on,addr=0x4.0x7 \
+-device lsi,id=scsi3,bus=pci.0,addr=0x4.0x2 \
+-device lsi,id=scsi4,bus=pci.0,addr=0x4.0x3 \
+-device lsi,id=scsi5,bus=pci.0,addr=0x4.0x4 \
+-device lsi,id=scsi6,bus=pci.0,addr=0x4.0x5 \
+-device lsi,id=scsi7,bus=pci.0,addr=0x4.0x6 \
+-device lsi,id=scsi8,bus=pci.0,addr=0x4.0x7 \
-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi0-0-0 \
-device scsi-disk,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0 \
--usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x5.0x0
+-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.xml
index 672fb61..24b95b8 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.xml
@@ -20,13 +20,13 @@
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='scsi' index='0'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='off'/>
</controller>
<controller type='scsi' index='1'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
</controller>
<controller type='scsi' index='2'>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1' multifunction='on'/>
</controller>
<controller type='scsi' index='3'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args
index 1007544..080d483 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args
@@ -1,6 +1,9 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
--device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 \
--device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
--device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
--device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
+-m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
index 05a6adf..5a43638 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
@@ -15,7 +15,7 @@
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
- <address type='pci' domain='0' bus='0' slot='4' function='0'/>
+ <address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-ehci-addr.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-ehci-addr.args
index 0059ab5..babd4f8 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-ehci-addr.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-ehci-addr.args
@@ -1 +1,6 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
+-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args
index 06863bb..1b2d5c1 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args
@@ -1 +1,6 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device piix3-usb-uhci,id=usb,bus=pci.0,multifunction=on,addr=0x1.0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
+-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
index f6270d5..7d34c2a 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
@@ -1,10 +1,10 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
--device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 \
--device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
--device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
+-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
-chardev socket,id=charredir0,host=localhost,port=4000 \
-device usb-redir,chardev=charredir0,id=redir0 \
-chardev spicevmc,id=charredir1,name=usbredir \
-device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=4 \
--device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
index 1dac3fb..a359a3d 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
@@ -19,7 +19,7 @@
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args b/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args
index be4a78e..0a61af5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args
@@ -1,15 +1,18 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
--device piix3-usb-uhci,id=usb,bus=pci.0,multifunction=on,addr=0x1.0x2 \
--device ich9-usb-ehci1,id=usb1,bus=pci.0,multifunction=on,addr=0x4.0x7 \
--device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
--device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
--device ich9-usb-ehci1,id=usb2,bus=pci.0,multifunction=on,addr=0x5.0x7 \
--device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5.0x0 \
--device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.0,multifunction=on,addr=0x5.0x1 \
--device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.0,multifunction=on,addr=0x5.0x2 \
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
+-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device ich9-usb-ehci1,id=usb1,bus=pci.0,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
+-device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
+-device ich9-usb-ehci1,id=usb2,bus=pci.0,addr=0x5.0x7 \
+-device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 \
+-device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.0,addr=0x5.0x1 \
+-device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.0,addr=0x5.0x2 \
-device usb-hub,id=hub0,bus=usb1.0,port=1 \
-device usb-tablet,id=input0,bus=usb.0,port=2 \
-device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bus=usb2.0,port=1 \
-device usb-host,hostbus=14,hostaddr=7,id=hostdev1,bus=usb2.0,port=2 \
--device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml
index e8ada4d..b12b841 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml
@@ -21,7 +21,7 @@
</controller>
<controller type='usb' index='1' model='ich9-uhci1'>
<master startport='0'/>
- <address type='pci' domain='0' bus='0' slot='4' function='0'/>
+ <address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/>
</controller>
<controller type='usb' index='1' model='ich9-uhci2'>
<master startport='2'/>
@@ -37,7 +37,7 @@
</controller>
<controller type='usb' index='2' model='ich9-uhci1'>
<master startport='0'/>
- <address type='pci' domain='0' bus='0' slot='5' function='0'/>
+ <address type='pci' domain='0' bus='0' slot='5' function='0' multifunction='on'/>
</controller>
<controller type='usb' index='2' model='ich9-uhci2'>
<master startport='2'/>
--
1.7.4.4

View File

@ -1,156 +0,0 @@
From eaf056bf995558ecf6620ce031287f3aa81b66de Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@laine.org>
Date: Tue, 6 Dec 2011 12:47:28 -0500
Subject: [PATCH 1/2] 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 | 62 +++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 318f523..7906bb8 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,30 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, " <type");
if (def->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"
+ * (in the original DomainDef as well as in the xml output).
+ * 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);
+ /* It's not exactly nice to modify the source object,
+ * but sometimes virDomainFormat is called > 100 times for the
+ * same object, which would result in far too many warning logs.
+ */
+ VIR_FREE(def->os.machine);
+ if (!(def->os.machine = strdup("pc-0.14"))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } 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 +11140,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.4

View File

@ -1,56 +0,0 @@
From 5d219e1bd98b562eed28e1df424a2590bb92b366 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 26 Sep 2011 14:28:47 -0600
Subject: [PATCH 1/2] spec: F15 still uses cgconfig, RHEL lacks hyperv
Commit ecd8725c dropped attempts to probe the cgconfig service on
new enough Fedora where systemd took over that aspect of the system,
but mistakenly used F14 instead of F15 as the cutoff point.
https://bugzilla.redhat.com/show_bug.cgi?id=741358
Also, RHEL does not include HyperV support yet.
* libvirt.spec.in (with_cgconfig): Check cgconfig service in F15.
(%{?rhel}): Provide default for with_hyperv.
---
libvirt.spec.in | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index c0ea898..b87e3f6 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -97,7 +97,8 @@
%endif
# RHEL doesn't ship OpenVZ, VBox, UML, PowerHypervisor,
-# VMWare, libxenserver (xenapi), or libxenlight (Xen 4.1 and newer)
+# VMWare, libxenserver (xenapi), libxenlight (Xen 4.1 and newer),
+# or HyperV.
%if 0%{?rhel}
%define with_openvz 0
%define with_vbox 0
@@ -106,6 +107,7 @@
%define with_vmware 0
%define with_xenapi 0
%define with_libxl 0
+%define with_hyperv 0
%endif
# RHEL-5 has restricted QEMU to x86_64 only and is too old for LXC
@@ -894,9 +896,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} <= 14 || 0%{?rhel} <= 6
+%if 0%{?fedora} <= 15 || 0%{?rhel} <= 6
if [ "$1" -eq "1" ]; then
/sbin/chkconfig cgconfig on
fi
--
1.7.4.4

View File

@ -1,37 +0,0 @@
From 72675eeaebc67857d0f1f62b5daeaa35506cd207 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
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

View File

@ -1,51 +0,0 @@
From 65a4c1782b197787bb960427cf0106c8d8225777 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
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,</name>,</name>\n <uuid>$UUID</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

View File

@ -1,52 +0,0 @@
From 6b9e1293f940536fcdfba91b1aea776ad847e09c Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
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

View File

@ -1,109 +0,0 @@
From 473e5ca36260011a330e1e3bf8f4f3b6865b5638 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 5 Dec 2011 10:22:10 -0700
Subject: [PATCH 2/2] spec: make it easier to autoreconf when building rpm
Over time, Fedora and RHEL RPMs have often backported upstream
patches that touched configure.ac and/or Makefile.am; this
necessitates rerunning the autotools for the patch to be effective.
Making this a one-liner spec tweak will make it easier for future
backports to pull patches without having to find all the places
to touch to properly use the autotools. Meanwhile, there have been
historical instances where an update in the autotools caused FTBFS
situations, so this is not on by default.
* libvirt.spec.in (enable_autotools): New variable, default off.
(BuildRequires): Conditionally add autotools.
(%build): Conditionally use them before configure.
* mingw32-libvirt.spec.in: Likewise.
Conflicts:
mingw32-libvirt.spec.in - caused by change in context
---
libvirt.spec.in | 14 ++++++++++++++
mingw32-libvirt.spec.in | 15 +++++++++++++++
2 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index cfc3a43..8579ba8 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -8,6 +8,11 @@
sed -ne 's/^\.fc\?\([0-9]\+\).*/%%define fedora \1/p')}
%endif
+# Default to skipping autoreconf. Distros can change just this one line
+# (or provide a command-line override) if they backport any patches that
+# touch configure.ac or Makefile.am.
+%{!?enable_autotools:%define enable_autotools 0}
+
# A client only build will create a libvirt.so only containing
# the generic RPC driver, and test driver and no libvirtd
# Default to a full server + client build
@@ -330,6 +335,12 @@ Requires: libcgroup
Requires: dmidecode
# All build-time requirements
+%if 0%{?enable_autotools}
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: gettext-devel
+BuildRequires: libtool
+%endif
BuildRequires: python-devel
%if %{with_xen}
@@ -700,6 +711,9 @@ of recent versions of Linux (and other OSes).
%define with_packager_version --with-packager-version="%{release}"
+%if 0%{?enable_autotools}
+autoreconf -if
+%endif
%configure %{?_without_xen} \
%{?_without_qemu} \
%{?_without_openvz} \
diff --git a/mingw32-libvirt.spec.in b/mingw32-libvirt.spec.in
index f651d11..e071c38 100644
--- a/mingw32-libvirt.spec.in
+++ b/mingw32-libvirt.spec.in
@@ -5,6 +5,11 @@
%define __find_provides %{_mingw32_findprovides}
%define __debug_install_post %{_mingw32_debug_install_post}
+# Default to skipping autoreconf. Distros can change just this one line
+# (or provide a command-line override) if they backport any patches that
+# touch configure.ac or Makefile.am.
+%{!?enable_autotools:%define enable_autotools 0}
+
Name: mingw32-libvirt
Version: @VERSION@
Release: 3%{?dist}%{?extra_release}
@@ -28,6 +33,12 @@ BuildRequires: mingw32-portablexdr
BuildRequires: pkgconfig
# Need native version for msgfmt
BuildRequires: gettext
+%if 0%{?enable_autotools}
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: gettext-devel
+BuildRequires: libtool
+%endif
BuildArch: noarch
@@ -42,6 +53,10 @@ MinGW Windows libvirt virtualization library.
%build
+%if 0%{?enable_autotools}
+autoreconf -if
+%endif
+
# XXX enable SASL in future
%{_mingw32_configure} \
--without-sasl \
--
1.7.7.4

View File

@ -1,74 +0,0 @@
From 15dbf094eb90a896ecb73c4c92bed649eb8b5f4c Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
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

View File

@ -1,40 +0,0 @@
From b221be79d0682b12249cb4b408e1b649cb2bc974 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@laine.org>
Date: Mon, 12 Mar 2012 14:03:38 -0400
Subject: [PATCH] specfile: fix typo in chkconfig commandline
This addresses https://bugzilla.redhat.com/show_bug.cgi?id=786890 in
the simplest manner possible.
The problem is that the chkconfig command is being called with
"--levels", but the option name is actually "--level".
Upstream libvirt has completely removed the offending code, but the
patch that does that is more invasive than this patch, which simply
corrects the misspelling.
Note that this change really needs to be in the Fedora-git
libvirt.spec file, *not* the specfile in the source RPM. This patch to
the src.rpm copy is included purely to prevent potential regression in
the event someone regenerates Fedora's libvirt.spec from sources.
---
libvirt.spec.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 8579ba8..4b311b7 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -947,7 +947,7 @@ fi
/sbin/chkconfig --add libvirt-guests
if [ $1 -ge 1 ]; then
level=$(/sbin/runlevel | /bin/cut -d ' ' -f 2)
- if /sbin/chkconfig --levels $level libvirt-guests; then
+ if /sbin/chkconfig --level $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.6

View File

@ -1,52 +0,0 @@
From 3ee5e12e58f876cf2ffc7d668e4ce9d461a9a7fd Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@laine.org>
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 @@
<currentMemory>524288</currentMemory>
<vcpu>1</vcpu>
<os>
- <type arch='i686' machine='fedora-13'>hvm</type>
+ <type arch='i686' machine='pc-0.13'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
--
1.7.7.3

View File

@ -1,153 +0,0 @@
commit 06b9c5b9231ef4dbd4b5ff69564305cd4f814879
Author: Michal Privoznik <mprivozn@redhat.com>
Date: Tue Jan 3 18:40:55 2012 +0100
virCommand: Properly handle POLLHUP
It is a good practise to set revents to zero before doing any poll().
Moreover, we should check if event we waited for really occurred or
if any of fds we were polling on didn't encountered hangup.
diff --git a/src/util/command.c b/src/util/command.c
index f5effdf..bdaa88b 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -1620,16 +1620,19 @@ virCommandProcessIO(virCommandPtr cmd)
if (infd != -1) {
fds[nfds].fd = infd;
fds[nfds].events = POLLOUT;
+ fds[nfds].revents = 0;
nfds++;
}
if (outfd != -1) {
fds[nfds].fd = outfd;
fds[nfds].events = POLLIN;
+ fds[nfds].revents = 0;
nfds++;
}
if (errfd != -1) {
fds[nfds].fd = errfd;
fds[nfds].events = POLLIN;
+ fds[nfds].revents = 0;
nfds++;
}
@@ -1645,8 +1648,8 @@ virCommandProcessIO(virCommandPtr cmd)
}
for (i = 0; i < nfds ; i++) {
- if (fds[i].fd == errfd ||
- fds[i].fd == outfd) {
+ if (fds[i].revents & POLLIN &&
+ (fds[i].fd == errfd || fds[i].fd == outfd)) {
char data[1024];
char **buf;
size_t *len;
@@ -1684,7 +1687,10 @@ virCommandProcessIO(virCommandPtr cmd)
memcpy(*buf + *len, data, done);
*len += done;
}
- } else {
+ }
+
+ if (fds[i].revents & POLLOUT &&
+ fds[i].fd == infd) {
int done;
/* Coverity 5.3.0 can't see that we only get here if
@@ -1710,6 +1716,18 @@ virCommandProcessIO(virCommandPtr cmd)
}
}
+ if (fds[i].revents & (POLLHUP | POLLERR)) {
+ if (fds[i].fd == errfd) {
+ VIR_DEBUG("hangup on stderr");
+ errfd = -1;
+ } else if (fds[i].fd == outfd) {
+ VIR_DEBUG("hangup on stdout");
+ outfd = -1;
+ } else {
+ VIR_DEBUG("hangup on stdin");
+ infd = -1;
+ }
+ }
}
}
commit d19149dda888d36cea58b6cdf7446f98bd1bf734
Author: Laszlo Ersek <lersek@redhat.com>
Date: Tue Jan 24 15:55:19 2012 +0100
virCommandProcessIO(): make poll() usage more robust
POLLIN and POLLHUP are not mutually exclusive. Currently the following
seems possible: the child writes 3K to its stdout or stderr pipe, and
immediately closes it. We get POLLIN|POLLHUP (I'm not sure that's possible
on Linux, but SUSv4 seems to allow it). We read 1K and throw away the
rest.
When poll() returns and we're about to check the /revents/ member in a
given array element, let's map all the revents bits to two (independent)
ideas: "let's attempt to read()", and "let's attempt to write()". This
should cover all errors, EOFs, and normal conditions; the read()/write()
call should report any pending error.
Under this approach, both POLLHUP and POLLERR are mapped to "needs read()"
if we're otherwise prepared for POLLIN. POLLERR also maps to "needs
write()" if we're otherwise prepared for POLLOUT. The rest of the mappings
(POLLPRI etc.) would be easy, but probably useless for pipes.
Additionally, SUSv4 doesn't appear to forbid POLLIN|POLLERR (or
POLLOUT|POLLERR) set simultaneously. One could argue that the read() or
write() call would return without blocking in these cases (with an error),
so POLLIN / POLLOUT would be justified beside POLLERR.
The code now penalizes POLLIN|POLLERR differently from plain POLLERR. The
former (ie. read() returning -1) is terminal and we jump to cleanup, while
plain POLLERR masks only the affected file descriptor for the future.
Let's unify those.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
diff --git a/src/util/command.c b/src/util/command.c
index f05493e..dc3cfc5 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -1710,7 +1710,7 @@ virCommandProcessIO(virCommandPtr cmd)
}
for (i = 0; i < nfds ; i++) {
- if (fds[i].revents & POLLIN &&
+ if (fds[i].revents & (POLLIN | POLLHUP | POLLERR) &&
(fds[i].fd == errfd || fds[i].fd == outfd)) {
char data[1024];
char **buf;
@@ -1751,7 +1751,7 @@ virCommandProcessIO(virCommandPtr cmd)
}
}
- if (fds[i].revents & POLLOUT &&
+ if (fds[i].revents & (POLLOUT | POLLERR) &&
fds[i].fd == infd) {
int done;
@@ -1777,19 +1777,6 @@ virCommandProcessIO(virCommandPtr cmd)
}
}
}
-
- if (fds[i].revents & (POLLHUP | POLLERR)) {
- if (fds[i].fd == errfd) {
- VIR_DEBUG("hangup on stderr");
- errfd = -1;
- } else if (fds[i].fd == outfd) {
- VIR_DEBUG("hangup on stdout");
- outfd = -1;
- } else {
- VIR_DEBUG("hangup on stdin");
- infd = -1;
- }
- }
}
}

View File

@ -1,36 +0,0 @@
commit 275155f664614fd32bcf5e963488e6f97b66dae4
Author: Cole Robinson <crobinso@redhat.com>
Date: Wed Jan 25 12:07:14 2012 -0500
storage: Fix any VolLookupByPath if we have an empty logical pool
On F16 at least, empty volume groups don't have a directory under /dev.
The directory only appears once a logical volume is created.
This tickles some behavior in BackendStablePath which ends with
libvirt sleeping for 5 seconds while waiting for the directory to appear.
This causes all sorts of problems for the virStorageVolLookupByPath API
which virtinst uses, even if trying to resolve a path that is independent
of the logical pool.
In reality we don't even need to do that checking since logical pools
always have a stable target path. Short circuit the polling in that
case.
Fixes bug 782261
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index d7394e0..306e487 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1347,6 +1347,10 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
if (!STRPREFIX(pool->def->target.path, "/dev"))
goto ret_strdup;
+ /* Logical pools are under /dev but already have stable paths */
+ if (pool->def->type == VIR_STORAGE_POOL_LOGICAL)
+ goto ret_strdup;
+
/* We loop here because /dev/disk/by-{id,path} may not have existed
* before we started this operation, so we have to give it some time to
* get created.

View File

@ -1,72 +0,0 @@
commit 74ff57506c762f7c1f2bdbcce55f6d620687caab
Author: Eric Blake <eblake@redhat.com>
Date: Fri Jan 6 14:07:23 2012 -0700
tests: avoid test failure on rawhide gnutls
I hit a VERY weird testsuite failure on rawhide, which included
_binary_ output to stderr, followed by a hang waiting for me
to type something! (Here, using ^@ for NUL):
$ ./commandtest
TEST: commandtest
WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
.WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
.WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
.8^@^@^@8^@^@^@^A^@^@^@^Bay^A^@^@^@)PRIVATE-GNOME-KEYRING-PKCS11-PROTOCOL-V-1
I finally traced it to the fact that gnome-keyring, called via
gnutls_global_init which is turn called by virNetTLSInit, opens
an internal fd that it expects to communicate to via a
pthread_atfork handler (never mind that it violates POSIX by
using non-async-signal-safe functions in that handler:
https://bugzilla.redhat.com/show_bug.cgi?id=772320).
Our problem stems from the fact that we pulled the rug out from
under the library's expectations by closing an fd that it had
just opened. While we aren't responsible for fixing the bugs
in that pthread_atfork handler, we can at least avoid the bugs
by not closing the fd in the first place.
* tests/commandtest.c (mymain): Avoid closing fds that were opened
by virInitialize.
diff --git a/tests/commandtest.c b/tests/commandtest.c
index efc48fe..b4b6044 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -784,6 +784,22 @@ mymain(void)
setpgid(0, 0);
setsid();
+ /* Our test expects particular fd values; to get that, we must not
+ * leak fds that we inherited from a lazy parent. At the same
+ * time, virInitialize may open some fds (perhaps via third-party
+ * libraries that it uses), and we must not kill off an fd that
+ * this process opens as it might break expectations of a
+ * pthread_atfork handler, as well as interfering with our tests
+ * trying to ensure we aren't leaking to our children. The
+ * solution is to do things in two phases - reserve the fds we
+ * want by overwriting any externally inherited fds, then
+ * initialize, then clear the slots for testing. */
+ if ((fd = open("/dev/null", O_RDONLY)) < 0 ||
+ dup2(fd, 3) < 0 ||
+ dup2(fd, 4) < 0 ||
+ dup2(fd, 5) < 0 ||
+ (fd > 5 && VIR_CLOSE(fd) < 0))
+ return EXIT_FAILURE;
/* Prime the debug/verbose settings from the env vars,
* since we're about to reset 'environ' */
@@ -791,8 +807,8 @@ mymain(void)
virTestGetVerbose();
virInitialize();
- /* Kill off any inherited fds that might interfere with our
- * testing. */
+
+ /* Phase two of killing interfering fds; see above. */
fd = 3;
VIR_FORCE_CLOSE(fd);
fd = 4;

View File

@ -1,199 +0,0 @@
commit 9bc9999b6eb815268798120d7fe8834d822f098d
Author: Michal Privoznik <mprivozn@redhat.com>
Date: Tue Oct 11 10:40:36 2011 +0200
qemu: Check for domain being active on successful job acquire
As this is needed. Although some functions check for domain
being active before obtaining job, we need to check it after,
because obtaining job unlocks domain object, during which
a state of domain can be changed.
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a5be925..0e307e1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1948,9 +1948,18 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
ret = qemuMonitorInjectNMI(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
goto cleanup;
@@ -4397,7 +4406,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom,
virDomainObjPtr vm;
char *ret = NULL;
unsigned long balloon;
- int err;
+ int err = 0;
/* Flags checked by virDomainDefFormat */
@@ -4423,9 +4432,17 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
goto cleanup;
@@ -7163,6 +7180,12 @@ qemudDomainBlockStatsFlags (virDomainPtr dom,
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitor(driver, vm);
tmp = *nparams;
ret = qemuMonitorGetBlockStatsParamsNumber(priv->mon, nparams);
@@ -8682,6 +8705,12 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0)
goto cleanup;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
@@ -8690,6 +8719,7 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
if (ret == 0)
priv->migMaxBandwidth = bandwidth;
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0)
vm = NULL;
} else {
@@ -8784,6 +8814,12 @@ qemuDomainSnapshotCreateActive(virConnectPtr conn,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
return -1;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
/* savevm monitor command pauses the domain emitting an event which
* confuses libvirt since it's not notified when qemu resumes the
@@ -8833,6 +8869,7 @@ cleanup:
_("resuming after snapshot failed"));
}
+endjob:
if (vm && qemuDomainObjEndJob(driver, vm) == 0) {
/* Only possible if a transient vm quit while our locks were down,
* in which case we don't want to save snapshot metadata. */
@@ -9055,6 +9092,13 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
return -1;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
/* In qemu, snapshot_blkdev on a single disk will pause cpus,
* but this confuses libvirt since notifications are not given
@@ -9137,12 +9181,14 @@ cleanup:
(persist &&
virDomainSaveConfig(driver->configDir, vm->newDef) < 0))
ret = -1;
- if (qemuDomainObjEndJob(driver, vm) == 0) {
+ }
+
+endjob:
+ if (vm && (qemuDomainObjEndJob(driver, vm) == 0)) {
/* Only possible if a transient vm quit while our locks were down,
* in which case we don't want to save snapshot metadata. */
*vmptr = NULL;
ret = -1;
- }
}
return ret;
@@ -10286,20 +10332,28 @@ static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd,
goto cleanup;
}
+ if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is not running"));
+ goto endjob;
+ }
+
priv = vm->privateData;
qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_CUSTOM_MONITOR, -1);
hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP);
- if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
- goto cleanup;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
- goto cleanup;
}
cleanup:
@@ -10536,10 +10590,19 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
priv = vm->privateData;
ret = qemuMonitorBlockJob(priv->mon, device, bandwidth, info, mode);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
goto cleanup;

View File

@ -1,21 +0,0 @@
commit 2dcca3ec0a28c6562ebfbe7a5eae4729fb5de904
Author: Peter Krempa <pkrempa@redhat.com>
Date: Fri Mar 2 15:12:32 2012 +0100
daemon: Remove deprecated HAL from init script dependencies
The init script for the daemon requests to start HAL although it has
been deprecated long time ago. This patch removes the dependency.
diff --git a/daemon/libvirtd.init.in b/daemon/libvirtd.init.in
index 3c49b1f..f66ddad 100644
--- a/daemon/libvirtd.init.in
+++ b/daemon/libvirtd.init.in
@@ -8,7 +8,6 @@
# Required-Start: $network messagebus
# Should-Start: $named
# Should-Start: xend
-# Should-Start: hal
# Should-Start: avahi-daemon
# Required-Stop: $network messagebus
# Should-Stop: $named