[libvirt] [libvirt-glib] [PATCH v2] GVirDomainSnapshot: Add gvir_domain_snapshot_delete
by Timm Bäder
---
Whoops, totally forgot about the delete flags in the first version,
sorry.
As for the underline in domain_snapshot, I took that from
gvir_domain_snapshot_get_config so I don't really know what's the
correct version.
Since this is using gvir_domain_snapshot_get_name now, the patch
removing the #if 0's in libvirt-gobject-domain-snapshot.c is needed.
libvirt-gobject/libvirt-gobject-domain-snapshot.c | 25 +++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain-snapshot.h | 16 +++++++++++++++
libvirt-gobject/libvirt-gobject.sym | 6 ++++++
3 files changed, 47 insertions(+)
diff --git a/libvirt-gobject/libvirt-gobject-domain-snapshot.c b/libvirt-gobject/libvirt-gobject-domain-snapshot.c
index fcf70ed..aa0504d 100644
--- a/libvirt-gobject/libvirt-gobject-domain-snapshot.c
+++ b/libvirt-gobject/libvirt-gobject-domain-snapshot.c
@@ -205,3 +205,28 @@ GVirConfigDomainSnapshot *gvir_domain_snapshot_get_config
free(xml);
return conf;
}
+
+/**
+ * gvir_domain_snapshot_delete:
+ * @snapshot: the domain snapshot
+ * @flags: Bitwise or of #GVirDomainSnapshotDeleteFlags
+ * @error: (allow-none): Place-holder for error or NULL
+ */
+void gvir_domain_snapshot_delete (GVirDomainSnapshot *snapshot,
+ GVirDomainSnapshotDeleteFlags flags,
+ GError **error)
+{
+ GVirDomainSnapshotPrivate *priv;
+ int status;
+
+ g_return_if_fail(GVIR_IS_DOMAIN_SNAPSHOT (snapshot));
+ g_return_if_fail(error == NULL || *error == NULL);
+
+ priv = snapshot->priv;
+ status = virDomainSnapshotDelete(priv->handle, flags);
+ if (status < 0) {
+ gvir_set_error(error, GVIR_DOMAIN_SNAPSHOT_ERROR, 0,
+ "Unable to delete snapshot `%s'",
+ gvir_domain_snapshot_get_name(snapshot));
+ }
+}
diff --git a/libvirt-gobject/libvirt-gobject-domain-snapshot.h b/libvirt-gobject/libvirt-gobject-domain-snapshot.h
index 5bd827c..3985795 100644
--- a/libvirt-gobject/libvirt-gobject-domain-snapshot.h
+++ b/libvirt-gobject/libvirt-gobject-domain-snapshot.h
@@ -58,6 +58,18 @@ struct _GVirDomainSnapshotClass
gpointer padding[20];
};
+/**
+ * GVirDomainSnapshotDeleteFlags:
+ * @GVIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN: Also delete children
+ * @GVIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY: Delete just metadata
+ * @GVIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY: Delete just children
+ */
+typedef enum {
+ GVIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN = 1,
+ GVIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY = 2,
+ GVIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY = 4
+} GVirDomainSnapshotDeleteFlags;
+
GType gvir_domain_snapshot_get_type(void);
GType gvir_domain_snapshot_handle_get_type(void);
@@ -69,6 +81,10 @@ GVirConfigDomainSnapshot *gvir_domain_snapshot_get_config
guint flags,
GError **err);
+void gvir_domain_snapshot_delete (GVirDomainSnapshot *snapshot,
+ guint flags,
+ GError **error);
+
G_END_DECLS
#endif /* __LIBVIRT_GOBJECT_DOMAIN_SNAPSHOT_H__ */
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index f2419ac..232e63b 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -234,4 +234,10 @@ LIBVIRT_GOBJECT_0.1.5 {
gvir_connection_open_read_only_finish;
} LIBVIRT_GOBJECT_0.1.4;
+LIBVIRT_GOBJECT_0.1.9 {
+ global:
+ gvir_domain_snapshot_delete_flags_get_type;
+ gvir_domain_snapshot_delete;
+} LIBVIRT_GOBJECT_0.1.5;
+
# .... define new API here using predicted next version number ....
--
1.9.3
10 years, 5 months
[libvirt] [PATCH v5] Add helper program to create custom leases
by Nehal J Wani
Introduce helper program to catch events from dnsmasq and maintain a custom
lease file per network. It supports dhcpv4 and dhcpv6. The file is saved as
"<interface-name>.status".
Each lease contains the following info:
<expiry-time (epoch time)> <mac> <iaid> <ip-address> <hostname> <clientid>
Example of custom leases file content:
[
{
"iaid": "1221229",
"ip-address": "2001:db8:ca2:2:1::95",
"mac-address": "52:54:00:12:a2:6d",
"hostname": "Fedora20",
"client-id": "00:04:1a:c1:d9:6b:5a:0a:e2:bc:f8:4b:1e:37:2e:38:22:55",
"expiry-time": 1393244216
},
{
"ip-address": "192.168.150.208",
"mac-address": "52:54:00:11:56:b3",
"hostname": "Wani-PC",
"client-id": "01:52:54:00:11:56:b3",
"expiry-time": 1393244248
}
]
src/Makefile.am:
* Add options to compile the helper program
src/network/bridge_driver.c:
* Introduce networkDnsmasqLeaseFileNameCustom()
* Invoke helper program along with dnsmasq
* Delete the .status file when corresponding n/w is destroyed.
src/network/leaseshelper.c
* Helper program to create the custom lease file
---
v5:
* More comments added, for better explanation
* Use of virFileFindResource() to identify proper path to helper binary
* Use of VIR_ENUM_IMPL for handling action events added
v4:
* Addition of pidfile and a corresponding lock for it
* Make correction for dnsmasq < 2.52 (Only IPv4)
* Move helper file from src/util to src/network
* Increase limit on max size of leases file
* Refer: https://www.redhat.com/archives/libvir-list/2014-March/msg01038.html
v3:
* Improved file handling, removed redundant copying, introduced --help and --version
* Refer: https://www.redhat.com/archives/libvir-list/2014-February/msg01431.html
v2:
* Changed format to JSON
* Refer: https://www.redhat.com/archives/libvir-list/2014-January/msg01234.html
v1:
* Refer: https://www.redhat.com/archives/libvir-list/2014-January/msg00626.html
src/Makefile.am | 22 +++
src/network/bridge_driver.c | 27 ++++
src/network/leaseshelper.c | 360 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 409 insertions(+), 0 deletions(-)
create mode 100644 src/network/leaseshelper.c
diff --git a/src/Makefile.am b/src/Makefile.am
index dd0abe7..fbe72c4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -859,6 +859,9 @@ STORAGE_HELPER_DISK_SOURCES = \
UTIL_IO_HELPER_SOURCES = \
util/iohelper.c
+NETWORK_LEASES_HELPER_SOURCES = \
+ network/leaseshelper.c
+
# Network filters
NWFILTER_DRIVER_SOURCES = \
nwfilter/nwfilter_driver.h nwfilter/nwfilter_driver.c \
@@ -2466,6 +2469,25 @@ libvirt_iohelper_CFLAGS = \
$(AM_CFLAGS) \
$(PIE_CFLAGS) \
$(NULL)
+
+if WITH_NETWORK
+libexec_PROGRAMS += libvirt_leaseshelper
+libvirt_leaseshelper_SOURCES = $(NETWORK_LEASES_HELPER_SOURCES)
+libvirt_leaseshelper_LDADD = \
+ libvirt_util.la \
+ ../gnulib/lib/libgnu.la
+if WITH_DTRACE_PROBES
+libvirt_leaseshelper_LDADD += libvirt_probes.lo
+endif WITH_DTRACE_PROBES
+
+libvirt_leaseshelper_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(PIE_CFLAGS) \
+ $(NULL)
+else ! WITH_NETWORK
+EXTRA_DIST += $(NETWORK_LEASES_HELPER_SOURCES)
+endif ! WITH_NETWORK
+
endif WITH_LIBVIRTD
if WITH_STORAGE_DISK
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 201b22f..ade664d 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -210,6 +210,16 @@ networkDnsmasqLeaseFileNameFunc networkDnsmasqLeaseFileName =
networkDnsmasqLeaseFileNameDefault;
static char *
+networkDnsmasqLeaseFileNameCustom(const char *bridge)
+{
+ char *leasefile;
+
+ ignore_value(virAsprintf(&leasefile, "%s/%s.status",
+ driverState->dnsmasqStateDir, bridge));
+ return leasefile;
+}
+
+static char *
networkDnsmasqConfigFileName(const char *netname)
{
char *conffile;
@@ -245,6 +255,7 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
virNetworkObjPtr net)
{
char *leasefile = NULL;
+ char *customleasefile = NULL;
char *radvdconfigfile = NULL;
char *configfile = NULL;
char *radvdpidbase = NULL;
@@ -263,6 +274,9 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
if (!(leasefile = networkDnsmasqLeaseFileName(def->name)))
goto cleanup;
+ if (!(customleasefile = networkDnsmasqLeaseFileNameCustom(def->bridge)))
+ goto cleanup;
+
if (!(radvdconfigfile = networkRadvdConfigFileName(def->name)))
goto cleanup;
@@ -279,6 +293,7 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
/* dnsmasq */
dnsmasqDelete(dctx);
unlink(leasefile);
+ unlink(customleasefile);
unlink(configfile);
/* radvd */
@@ -296,6 +311,7 @@ networkRemoveInactive(virNetworkDriverStatePtr driver,
cleanup:
VIR_FREE(leasefile);
VIR_FREE(configfile);
+ VIR_FREE(customleasefile);
VIR_FREE(radvdconfigfile);
VIR_FREE(radvdpidbase);
VIR_FREE(statusfile);
@@ -1120,6 +1136,7 @@ networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
int ret = -1;
char *configfile = NULL;
char *configstr = NULL;
+ char *leaseshelper_path;
network->dnsmasqPid = -1;
@@ -1142,11 +1159,21 @@ networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
cmd = virCommandNew(dnsmasqCapsGetBinaryPath(caps));
virCommandAddArgFormat(cmd, "--conf-file=%s", configfile);
+
+ /* This helper is used to create custom leases file for libvirt */
+ if (!(leaseshelper_path = virFileFindResource("libvirt_leaseshelper",
+ "src",
+ LIBEXECDIR)))
+ goto cleanup;
+
+ virCommandAddArgFormat(cmd, "--dhcp-script=%s", leaseshelper_path);
+
*cmdout = cmd;
ret = 0;
cleanup:
VIR_FREE(configfile);
VIR_FREE(configstr);
+ VIR_FREE(leaseshelper_path);
return ret;
}
diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c
new file mode 100644
index 0000000..d580369
--- /dev/null
+++ b/src/network/leaseshelper.c
@@ -0,0 +1,360 @@
+/*
+ * leasehelper.c: Helper program to create custom leases file
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014 Nehal J Wani
+ *
+ * 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, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Nehal J Wani <nehaljw.kkd1(a)gmail.com>
+ *
+ * For IPv6 support, use dnsmasq >= 2.67
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "virutil.h"
+#include "virthread.h"
+#include "virfile.h"
+#include "virpidfile.h"
+#include "virbuffer.h"
+#include "virstring.h"
+#include "virerror.h"
+#include "viralloc.h"
+#include "virjson.h"
+#include "configmake.h"
+
+#define VIR_FROM_THIS VIR_FROM_NETWORK
+
+/**
+ * VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX:
+ *
+ * Macro providing the upper limit on the size of leases file
+ */
+#define VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX (32 * 1024 * 1024)
+
+static const char *program_name;
+
+/* Display version information. */
+static void
+helperVersion(const char *argv0)
+{
+ printf("%s (%s) %s\n", argv0, PACKAGE_NAME, PACKAGE_VERSION);
+}
+
+ATTRIBUTE_NORETURN static void
+usage(int status)
+{
+ if (status) {
+ fprintf(stderr, _("%s: try --help for more details\n"), program_name);
+ } else {
+ printf(_("Usage: %s add|old|del mac|clientid ip [hostname]\n"
+ "Designed for use with 'dnsmasq --dhcp-script'\n"
+ "Refer to man page of dnsmasq for more details'\n"),
+ program_name);
+ }
+ exit(status);
+}
+
+static int
+customLeaseRewriteFile(int fd, void *opaque)
+{
+ char **data = opaque;
+
+ if (safewrite(fd, *data, strlen(*data)) < 0)
+ return -1;
+
+ return 0;
+}
+
+/* Flags denoting actions for a lease */
+enum virLeaseActionFlags {
+ VIR_LEASE_ACTION_ADD, /* Create new lease */
+ VIR_LEASE_ACTION_OLD, /* Lease already exists, renew it */
+ VIR_LEASE_ACTION_DEL, /* Delete the lease */
+
+ VIR_LEASE_ACTION_LAST
+};
+
+VIR_ENUM_DECL(virLeaseAction);
+
+VIR_ENUM_IMPL(virLeaseAction, VIR_LEASE_ACTION_LAST,
+ "add", "old", "del");
+
+int
+main(int argc, char **argv)
+{
+ char *exptime = NULL;
+ char *pid_file = NULL;
+ char *lease_entries = NULL;
+ char *custom_lease_file = NULL;
+ const char *ip = NULL;
+ const char *mac = NULL;
+ const char *iaid = virGetEnvAllowSUID("DNSMASQ_IAID");
+ const char *clientid = virGetEnvAllowSUID("DNSMASQ_CLIENT_ID");
+ const char *interface = virGetEnvAllowSUID("DNSMASQ_INTERFACE");
+ const char *exptime_tmp = virGetEnvAllowSUID("DNSMASQ_LEASE_EXPIRES");
+ const char *hostname = virGetEnvAllowSUID("DNSMASQ_SUPPLIED_HOSTNAME");
+ const char *leases_str = NULL;
+ long long currtime = 0;
+ long long expirytime = 0;
+ size_t i = 0;
+ int size = 0;
+ int action = -1;
+ int pid_file_fd = -1;
+ int rv = EXIT_FAILURE;
+ int custom_lease_file_len = 0;
+ bool add = false;
+ bool delete = false;
+ virJSONValuePtr lease_new = NULL;
+ virJSONValuePtr lease_tmp = NULL;
+ virJSONValuePtr leases_array = NULL;
+ virJSONValuePtr leases_array_new = NULL;
+
+ virSetErrorFunc(NULL, NULL);
+ virSetErrorLogPriorityFunc(NULL);
+
+ program_name = argv[0];
+
+ if (setlocale(LC_ALL, "") == NULL ||
+ bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
+ textdomain(PACKAGE) == NULL) {
+ fprintf(stderr, _("%s: initialization failed\n"), program_name);
+ exit(EXIT_FAILURE);
+ }
+
+ if (virThreadInitialize() < 0 ||
+ virErrorInitialize() < 0) {
+ fprintf(stderr, _("%s: initialization failed\n"), program_name);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Doesn't hurt to check */
+ if (argc > 1) {
+ if(STREQ(argv[1], "--help"))
+ usage(EXIT_SUCCESS);
+
+ if (STREQ(argv[1], "--version")) {
+ helperVersion(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ if (argc != 4 && argc != 5) {
+ /* Refer man page of dnsmasq --dhcp-script for more details */
+ usage(EXIT_FAILURE);
+ }
+
+ /* Make sure dnsmasq knows the interface. The interface name is not known
+ * when dnsmasq (re)starts and throws 'del' events for expired leases.
+ * So, if any old lease has expired, it will be automatically removed the
+ * next time this program is invoked */
+ if (!interface)
+ goto cleanup;
+
+ ip = argv[3];
+ mac = argv[2];
+ action = virLeaseActionTypeFromString(argv[1]);
+
+ /* In case hostname is known, it is the 5th argument */
+ if (argc == 5)
+ hostname = argv[4];
+
+ if (VIR_STRDUP(exptime, exptime_tmp) < 0)
+ goto cleanup;
+
+ /* Removed extraneous trailing space in DNSMASQ_LEASE_EXPIRES (dnsmasq < 2.52) */
+ if (exptime[strlen(exptime) - 1] == ' ')
+ exptime[strlen(exptime) - 1] = '\0';
+
+ /* Check if it is an IPv6 lease */
+ if (virGetEnvAllowSUID("DNSMASQ_IAID")) {
+ mac = virGetEnvAllowSUID("DNSMASQ_MAC");
+ clientid = argv[2];
+ }
+
+ if (virAsprintf(&custom_lease_file,
+ LOCALSTATEDIR "/lib/libvirt/dnsmasq/%s.status",
+ interface) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(pid_file, LOCALSTATEDIR "/run/leaseshelper.pid") < 0)
+ goto cleanup;
+
+ /* Try to claim the pidfile, exiting if we can't */
+ if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0)
+ goto cleanup;
+
+ /* Since interfaces can be hot plugged, we need to make sure that the
+ * corresponding custom lease file exists. If not, 'touch' it */
+ if (virFileTouch(custom_lease_file, 0644) < 0)
+ goto cleanup;
+
+ /* Read entire contents */
+ if ((custom_lease_file_len = virFileReadAll(custom_lease_file,
+ VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX,
+ &lease_entries)) < 0) {
+ goto cleanup;
+ }
+
+ if (action == VIR_LEASE_ACTION_ADD ||
+ action == VIR_LEASE_ACTION_OLD ||
+ action == VIR_LEASE_ACTION_DEL) {
+ /* Custom ipv6 leases *will not* be created if the env-var DNSMASQ_MAC
+ * is not set. In the special case, when the $(interface).status file
+ * is not already present and dnsmasq is (re)started, the corresponding
+ * ipv6 custom lease will be created only when the guest sends the
+ * 'old' action for its existing ipv6 interfaces.
+ *
+ * According to rfc3315, the combination of DUID and IAID can be used
+ * to uniquely identify each ipv6 guest interface. So, in future, if
+ * we introduce virNetworkGetDHCPLeaseBy(IAID|DUID|IAID+DUID) for ipv6
+ * interfaces, then, the following if condition won't be required, as
+ * the new lease will be created irrespective of whether the MACID is
+ * known or not.
+ */
+ if (mac || action == VIR_LEASE_ACTION_DEL) {
+ /* Delete the corresponding lease, if it already exists */
+ delete = true;
+ if (action == VIR_LEASE_ACTION_ADD ||
+ action == VIR_LEASE_ACTION_OLD) {
+ add = true;
+ /* Create new lease */
+ if (!(lease_new = virJSONValueNewObject())) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to create json"));
+ goto cleanup;
+ }
+
+ if (virStrToLong_ll(exptime, NULL, 10, &expirytime) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to convert lease expiry time to long long: %s"),
+ exptime);
+ goto cleanup;
+ }
+
+ if (iaid && virJSONValueObjectAppendString(lease_new, "iaid", iaid) < 0)
+ goto cleanup;
+ if (ip && virJSONValueObjectAppendString(lease_new, "ip-address", ip) < 0)
+ goto cleanup;
+ if (mac && virJSONValueObjectAppendString(lease_new, "mac-address", mac) < 0)
+ goto cleanup;
+ if (hostname && virJSONValueObjectAppendString(lease_new, "hostname", hostname) < 0)
+ goto cleanup;
+ if (clientid && virJSONValueObjectAppendString(lease_new, "client-id", clientid) < 0)
+ goto cleanup;
+ if (expirytime && virJSONValueObjectAppendNumberLong(lease_new, "expiry-time", expirytime) < 0)
+ goto cleanup;
+ }
+ }
+ } else {
+ fprintf(stderr, _("Unsupported action: %s\n"),
+ virLeaseActionTypeToString(action));
+ exit(EXIT_FAILURE);
+ }
+ /* Check for previous leases */
+ if (custom_lease_file_len) {
+ if (!(leases_array = virJSONValueFromString(lease_entries))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("invalid json in file: %s"), custom_lease_file);
+ goto cleanup;
+ }
+
+ if ((size = virJSONValueArraySize(leases_array)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("couldn't fetch array of leases"));
+ goto cleanup;
+ }
+ }
+
+ if (!(leases_array_new = virJSONValueNewArray())) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to create json"));
+ goto cleanup;
+ }
+
+ currtime = (long long) time(NULL);
+
+ for (i = 0; i < size; i++) {
+ const char *ip_tmp = NULL;
+ long long expirytime_tmp = -1;
+
+ if (!(lease_tmp = virJSONValueArrayGet(leases_array, i))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to parse json"));
+ goto cleanup;
+ }
+
+ if (!(ip_tmp = virJSONValueObjectGetString(lease_tmp, "ip-address")) ||
+ (virJSONValueObjectGetNumberLong(lease_tmp, "expiry-time", &expirytime_tmp) < 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to parse json"));
+ goto cleanup;
+ }
+
+ /* Check whether lease has expired or not */
+ if (expirytime_tmp < currtime)
+ continue;
+
+ /* Check whether lease has to be included or not */
+ if (delete && STREQ(ip_tmp, ip))
+ continue;
+
+ /* Add old lease to new array */
+ if (virJSONValueArrayAppend(leases_array_new, lease_tmp) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to create json"));
+ goto cleanup;
+ }
+ }
+
+ if (add) {
+ if (virJSONValueArrayAppend(leases_array_new, lease_new) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to create json"));
+ goto cleanup;
+ }
+ }
+
+ if (!(leases_str = virJSONValueToString(leases_array_new, true))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("empty json array"));
+ goto cleanup;
+ }
+
+ /* Write to file */
+ if (virFileRewrite(custom_lease_file, 0644,
+ customLeaseRewriteFile, &leases_str) < 0)
+ goto cleanup;
+
+ rv = EXIT_SUCCESS;
+
+cleanup:
+ if (pid_file_fd != -1)
+ virPidFileReleasePath(pid_file, pid_file_fd);
+
+ VIR_FREE(pid_file);
+ VIR_FREE(exptime_tmp);
+ VIR_FREE(custom_lease_file);
+ virJSONValueFree(lease_new);
+ virJSONValueFree(leases_array);
+ virJSONValueFree(leases_array_new);
+
+ return rv;
+}
--
1.7.1
10 years, 5 months
[libvirt] [PATCH v2] qemu: Properly label FDs when restoring domain with static label
by Shivaprasad G Bhat
The restore of a saved image file fails when the selinux context is static.
The libvirt has to set the conext of save image file handle to that of
the guest before handing off the FD to qemu.
Signed-off-by: Shivaprasad G Bhat <shivaprasadbhat(a)gmail.com>
---
src/qemu/qemu_process.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 124fe28..47d1f7d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4052,14 +4052,14 @@ int qemuProcessStart(virConnectPtr conn,
*/
struct stat stdin_sb;
- VIR_DEBUG("setting security label on pipe used for migration");
+ VIR_DEBUG("setting security label on fd used for migration or restore");
if (fstat(stdin_fd, &stdin_sb) < 0) {
virReportSystemError(errno,
_("cannot stat fd %d"), stdin_fd);
goto cleanup;
}
- if (S_ISFIFO(stdin_sb.st_mode) &&
+ if ((S_ISFIFO(stdin_sb.st_mode) || S_ISREG(stdin_sb.st_mode)) &&
virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def, stdin_fd) < 0)
goto cleanup;
}
10 years, 5 months
[libvirt] [PATCH] virsh: Check wether found volume is member of the specified storage pool
by Peter Krempa
When looking up storage volumes virsh uses multiple lookup steps. Some
of the steps don't require a pool name specified. This resulted into a
possibility that a volume would be part of a different pool than the
user specified:
Let's have a /var/lib/libvirt/images/test.qcow image in the 'default'
pool and a second pool 'emptypool':
Currently we'd return:
$ virsh vol-info --pool emptypool /var/lib/libvirt/images/test.qcow
Name: test.qcow
Type: file
Capacity: 100.00 MiB
Allocation: 212.00 KiB
After the fix:
$ tools/virsh vol-info --pool emptypool /var/lib/libvirt/images/test.qcow
error: Requested volume '/var/lib/libvirt/images/test.qcow' found in a different pool (default) than specified
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1088667
---
tools/virsh-volume.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 55bf6f0..6416ba6 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -104,6 +104,26 @@ vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd,
"might help"), n, pooloptname);
}
+ /* If the pool was specified, then make sure that the returned
+ * volume is from the given pool */
+ if (pool && vol) {
+ virStoragePoolPtr volpool = NULL;
+
+ if ((volpool = virStoragePoolLookupByVolume(vol))) {
+ if (STRNEQ(virStoragePoolGetName(volpool),
+ virStoragePoolGetName(pool))) {
+ vshResetLibvirtError();
+ vshError(ctl,
+ _("Requested volume '%s' found in a different "
+ "pool (%s) than specified"),
+ n, virStoragePoolGetName(volpool));
+ virStorageVolFree(vol);
+ vol = NULL;
+ }
+ virStoragePoolFree(volpool);
+ }
+ }
+
if (pool)
virStoragePoolFree(pool);
--
1.9.3
10 years, 5 months
[libvirt] Availability of libvirt-python-1.2.5
by Daniel Veillard
I also made a new release for the python bindings, they are
available at:
ftp://libvirt.org/libvirt/python
they include support for the 2 new set of APIs introduced in 1.2.5
and a memory leak in older python version, so peope are also invited
to update:
- fix leak in memoryStats with older python (Martin Kletzander)
- Implement virDomain{Get,Set}Time APIs (Michal Privoznik)
- override: add virDomainFSFreeze and virDomainFSThaw API (Tomoki Sekiyama)
thanks everybody !
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
10 years, 5 months
[libvirt] Release fo libvirt-1.2.5
by Daniel Veillard
As planned the release of libvirt 1.2.5 is out, it is tagged in git
and available as tarballs and rpms at the usual place:
ftp://libvirt.org/libvirt/
This is a relatively small release in the number of commits, around 150,
but includes a security fix (which happened to be my fault !) and 2 new
set of APIs. There is also some interesting refactoring work and the
usual flow of bug fixes, so people are really invited to update:
Security:
- LSN-2014-0003: Don't expand entities when parsing XML (Daniel P. Berrange)
Features:
- Introduce virDomain{Get,Set}Time APIs (Michal Privoznik)
- Introduce virDomainFSFreeze() and virDomainFSThaw() public API (Tomoki Sekiyama)
Portability:
- build: avoid compiler warning on 32-bit platform (Eric Blake)
- build: fix build with libselinux 2.3 (Cédric Bosdonnat)
- qemu: Fix specifying char devs for PPC (Olivia Yin)
- change machine name ppce500v2 to ppce500 (Olivia Yin)
- tests: avoid dlsym mocking on mingw (Eric Blake)
- avoid 'sync' as variable name (Pavel Hrdina)
- Fix build wihout macvtap or virtualport (Ján Tomko)
Bug Fixes:
- util: fix DST end date in virtimetest timezones (Laine Stump)
- qemu: snapshot: Improve detection of mixed snapshots (Peter Krempa)
- qemu: snapshot: Reject internal active snapshot without memory state (Peter Krempa)
- util: storage: Fix crash of libvirtd on network backed guest block-pull (Peter Krempa)
- util: fix virTimeLocalOffsetFromUTC DST processing (Laine Stump)
- qemu: managedsave: Don't spam logs with warnings about corrupted image (Peter Krempa)
- utils: storage: Canonicalize paths only for local filesystems (Peter Krempa)
- qemu: reject rather than hang on blockcommit of active layer (Eric Blake)
- Clean up chardev sockets on QEMU shutdown (Ján Tomko)
- qemu: fix <clock offset='variable' basis='localtime'/> (Laine Stump)
- qemu: fix RTC_CHANGE event for <clock offset='variable' basis='utc'/> (Laine Stump)
- qemu: Properly abort migration to a file (Jiri Denemark)
- qemu: Send migrate_cancel when aborting migration (Jiri Denemark)
- Fix error message when TUNNELLED flag is used in non-p2p migration (Jiri Denemark)
- conf: fix backing store parse off-by-one (Eric Blake)
- Fix crash in DAC driver with no seclabels (Ján Tomko)
- util: fix memory leak in failure path of virCgroupKillRecursiveInternal (Chen Hanxiao)
- qemu: Avoid leak in qemuDomainCheckRemoveOptionalDisk (Jiri Denemark)
- qemu: Ignore temporary job errors when checking migration status (Jiri Denemark)
- qemu: snapshot: Terminate job when memory compression program isn't found (Peter Krempa)
- sanlock: avoid leak in acquire() (Martin Kletzander)
- virsh: domain: Fix output of the VNC display number for domdisplay (Peter Krempa)
- sanlock: don't fail with unregistered domains (Martin Kletzander)
- storage: Resolve issues in failure path (John Ferlan)
- spec: Don't install nonexistent test_libvirt_lockd.aug (Jiri Denemark)
- spec: sanlock is x86_64 only on RHEL (Jiri Denemark)
- Fix vlan ID detection in udev interface driver (Ján Tomko)
Documentation:
- bhyve driver documentation improvements (Roman Bogorodskiy)
- virsh: fix typos in virsh man page (Eric Blake)
- maint: fix typo in previous patch (Eric Blake)
- fix documentation of virDomainSet(Get)Metadata (Dan Kenigsberg)
- Fix an extra ' in a translated string (Daniel Veillard)
- add a serial device with a seclabel example (Ján Tomko)
- maint: fix typos related to disk name resolution (Eric Blake)
- maint: fix typos related to 'frozen' (Eric Blake)
- mention vagrant-libvirt in apps.html (James Shubin)
- update documentation of <interface type='hostdev'> (Chunyan Liu)
- update README-hacking (Chen Hanxiao)
- virerror: Fix an error message typo (Cole Robinson)
- fix a typo in formatdomain (Chen Hanxiao)
- typos: fix s/it/is/ where applicable (Martin Kletzander)
- datatypes: Fix comment of secret uuid (Li Yang)
Improvements:
- maint: cleanup detection of const'ness of selinux ctx (Jim Fehlig)
- storage: fs: Drop-in replace use of virStorageFileGetMetadataFromBuf (Peter Krempa)
- storage: Return backing format from virStorageFileGetMetadataFromFD (Peter Krempa)
- util: new function virTimeLocalOffsetFromUTC (Laine Stump)
- storage: Add storage file API to read file headers (Peter Krempa)
- storage: Add support for access to files using provided uid/gid (Peter Krempa)
- storage: Add NONE protocol type for network disks (Peter Krempa)
- conf: Fix domain disk path iterator to work with networked storage (Peter Krempa)
- storage: Rework debugging of storage file access through storage driver (Peter Krempa)
- storage: Store gluster volume name separately (Peter Krempa)
- qemu: Make qemuDomainPrepareDiskChainElement aware of remote storage (Peter Krempa)
- qemu: process: Refresh backing chain info when reconnecting to qemu (Peter Krempa)
- Don't log an internal error when the guest hasn't updated balloon stats (Ján Tomko)
- qemuSetupCgroupForVcpu: s/virProcessInfoSetAffinity/virProcessSetAffinity/ (Michal Privoznik)
- bhyve: fix virObjectUnlock() usage (Roman Bogorodskiy)
- virdbus: Show method name in error message (Cole Robinson)
- virdbus: Remove redundant error macro (Cole Robinson)
- qemu: snapshot: Fix return value of external checkpoint with no disks (Peter Krempa)
- qemu: snapshot: Forbid empty snapshots (Peter Krempa)
- qemu: snapshot: Forbid partial internal snapshots (Peter Krempa)
- qemu: snapshot: Use typecasted switch in qemuDomainSnapshotPrepare() (Peter Krempa)
- bhyve: domain events support (Roman Bogorodskiy)
- migration: add support for migrateURI configuration (Chen Fan)
- util: refactor virNetlinkCommand to fix several bugs / style problems (Laine Stump)
- build: nuke more uses of 'sync' (Eric Blake)
- Return error when updating cdrom device (Pavel Hrdina)
- Revert "maint: prefer enum over int for virstoragefile structs" (Eric Blake)
- parallels: create VMs in the default place (Dmitry Guryanov)
- parallels: add disks correctly (Dmitry Guryanov)
- parallels: set file format in virDomainDef (Dmitry Guryanov)
- parallels: add VIR_STORAGE_FILE_PLOOP format (Dmitry Guryanov)
- conf: fix seclabels for chardevs (Ján Tomko)
- Rename virDomainDiskSourceDefFormatSeclabel (Ján Tomko)
- security_dac: honor relabel='no' in chardev config (Jim Fehlig)
- security_dac: avoid relabeling hostdevs when relabel='no' (Jim Fehlig)
- security_dac: honor relabel='no' in disk config (Jim Fehlig)
- security_dac: avoid relabeling when relabel='no' (Jim Fehlig)
- security_dac: rework callback parameter passing (Jim Fehlig)
- security_dac: cleanup use of enum types (Jim Fehlig)
- security_dac: annotate some functions with ATTRIBUTE_NONNULL (Jim Fehlig)
- maint: prefer enum over int for virstoragefile structs (Eric Blake)
- maint: shorten 'TypeType' function names (Eric Blake)
- maint: use enum typedef for virstorageencryption.h (Eric Blake)
- vbox: fix stale comment about vdi storage type (Eric Blake)
- qemu: Implement virDomain{Get,Set}Time (Michal Privoznik)
- virsh: Expose virDomain{Get,Set}Time (Michal Privoznik)
- security_dac: Fix indentation (Jim Fehlig)
- security_dac: Remove unnecessary curly braces (Jim Fehlig)
- security_dac: Remove unnecessary ATTRIBUTE_UNUSED (Jim Fehlig)
- virsh: reject undefine --wipe-storage without also naming storage (Li Yang)
- conf: use typedefs for enums in "src/conf/snapshot_conf.h" (Julio Faracco)
- conf: use typedefs for enums in "src/conf/storage_conf.h" (Julio Faracco)
- conf: use typedefs for enums in "src/conf/nwfilter_conf.h" (Julio Faracco)
- qemu: Make qemuProcess{Start,Stop}CPUs easier to follow (Jiri Denemark)
- qemuDomainObjBeginNestedJob: Return -2 for temporary failures (Jiri Denemark)
- qemu: Make qemuDomainObjBeginNestedJob static (Jiri Denemark)
- qemu: extract common PCI handling functions (Roman Bogorodskiy)
- qemu: extract PCI handling structs (Roman Bogorodskiy)
- qemu: Adjust size for qcow2/qed if not on sector boundary (John Ferlan)
- sanlock: code movement in virLockManagerSanlockAcquire (Martin Kletzander)
- apibuild: Disallow 'returns' return description (Michal Privoznik)
- qemu: Support mountpoints option of guest-fsfreeze-freeze (Tomoki Sekiyama)
- virsh: Expose new virDomainFSFreeze and virDomainFSThaw API (Tomoki Sekiyama)
- qemu: Implement virDomainFSFreeze and virDomainFSThaw (Tomoki Sekiyama)
- conf: use typedefs for enums in node_device_conf, nwfilter_params (Julio Faracco)
- libxl: fix support for <interface type="hostdev"> syntax (Chunyan Liu)
- maint: use $(SED) instead of sed for syntax-check (Roman Bogorodskiy)
- bhyve: implement connectGetSysinfo (Roman Bogorodskiy)
- qemu: Implement a stub cpuArchDriver.compare() handler for arm and aarch64 (Oleg Strikov)
- ESX: add virStorageVolGetInfo in iSCSI backend. (Dawid Zamirski)
- parallels: add a set of trivial functions (Dmitry Guryanov)
- parallels: don't add domain to the list twice (Dmitry Guryanov)
- parallels: don't enable VNC when we define a new domain (Dmitry Guryanov)
- parallels: fix virDomainDef.features comparison (Dmitry Guryanov)
- Add support for timestamping QEMU logs (Ján Tomko)
- qemu: track quiesced status in qemuDomainSnapshotFSFreeze (Tomoki Sekiyama)
- remote: Implement virDomainFSFreeze and virDomainFSThaw (Tomoki Sekiyama)
- udev: consider the device a CDROM when ID_CDROM=1 (Giuseppe Scrivano)
- virdbus: Make virDBusCall static (Cole Robinson)
- qemu: specify domain in host-side PCI addresses when needed/supported (Laine Stump)
- qemu: add host-pci-multidomain capability (Laine Stump)
- storageVolCreateXMLFrom: Allow multiple accesses to origvol (Michal Privoznik)
- conf: use typedefs for enums in "src/conf/{network,interface}_conf.h" (Julio Faracco)
- conf: use typedefs for enums in "src/conf/cpu_conf.h" (Julio Faracco)
- util: use typedefs for enums in "src/util/" directory (Julio Faracco)
- virsh: Replace list element to defined variable (Li Yang)
- libxl: support PARAVIRT reboot flag (Jim Fehlig)
- libxl: support PARAVIRT and ACPI shutdown flags (Jim Fehlig)
- Introduce a new flag for controlling shutdown/reboot (Jim Fehlig)
- conf: drop extra storage probe (Eric Blake)
- bhyve: report cpuTime in bhyveDomainGetInfo (Roman Bogorodskiy)
- bhyve: implement connectDomainXMLToNative (Roman Bogorodskiy)
- bhyve: improve bhyve_command.c testability (Roman Bogorodskiy)
Cleanup:
- virSecurityDACRestoreSecurityHostdevLabel: Unmark @def as unused (Michal Privoznik)
Thanks everybody who contributed in one way or anither to this release
with bug reports, fixes, documentation and patch reviews !
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
10 years, 5 months
[libvirt] [PATCH v5] bhyve: implement PCI address allocation
by Roman Bogorodskiy
Changes from v4:
- Qemu-related part of sharing the common code is complete and
pushed, so patch lives on its own now
- virBhyveProcessBuildBhyveCmd() modified to loop over disks and nets
and call bhyveBuildDiskArgStr() and bhyveBuildNetArgStr() for an
individual device to make the latter more readable
- Fix double assing / double semicolon typo
- Fix spelling in virReportError() for disks
- Make bhyveAssignDevicePCISlots() assign nets before disks to reproduce
the old behaviour when one net and one disk were supported
- Make persistentAddrs of _bhyveDomainObjPrivate bool.
Roman Bogorodskiy (1):
bhyve: implement PCI address allocation
po/POTFILES.in | 1 +
src/Makefile.am | 4 +
src/bhyve/bhyve_command.c | 112 +++++++------
src/bhyve/bhyve_device.c | 174 +++++++++++++++++++++
src/bhyve/bhyve_device.h | 38 +++++
src/bhyve/bhyve_domain.c | 75 +++++++++
src/bhyve/bhyve_domain.h | 39 +++++
src/bhyve/bhyve_driver.c | 12 +-
.../bhyvexml2argvdata/bhyvexml2argv-acpiapic.args | 2 +-
tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml | 2 +
tests/bhyvexml2argvdata/bhyvexml2argv-base.args | 2 +-
tests/bhyvexml2argvdata/bhyvexml2argv-base.xml | 2 +
tests/bhyvexml2argvdata/bhyvexml2argv-console.args | 4 +-
tests/bhyvexml2argvdata/bhyvexml2argv-console.xml | 2 +
.../bhyvexml2argv-disk-virtio.args | 2 +-
.../bhyvexml2argv-disk-virtio.xml | 2 +
tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args | 2 +-
tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml | 2 +
tests/bhyvexml2argvdata/bhyvexml2argv-serial.args | 4 +-
tests/bhyvexml2argvdata/bhyvexml2argv-serial.xml | 2 +
20 files changed, 416 insertions(+), 67 deletions(-)
create mode 100644 src/bhyve/bhyve_device.c
create mode 100644 src/bhyve/bhyve_device.h
create mode 100644 src/bhyve/bhyve_domain.c
create mode 100644 src/bhyve/bhyve_domain.h
--
1.9.0
10 years, 5 months
[libvirt] [PATCH] docs: bhyve driver documentation improvements
by Roman Bogorodskiy
- Document 'domxml-to-native' command
- Mention that the nmdm console support needs an appropriate
kernel module loaded
---
docs/drvbhyve.html.in | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/docs/drvbhyve.html.in b/docs/drvbhyve.html.in
index 603be80..ecd7c0c 100644
--- a/docs/drvbhyve.html.in
+++ b/docs/drvbhyve.html.in
@@ -98,6 +98,9 @@ the following to the domain XML (<span class="since">Since 1.2.4</span>):
</devices>
...</pre>
+
+<p>Make sure to load the <code>nmdm</code> kernel module if you plan to use that.</p>
+
<p>
Then <code>virsh console</code> command can be used to connect to the text console
of a guest.</p>
@@ -110,6 +113,24 @@ to let a guest boot or start a guest using:</p>
<pre>start --console domname</pre>
+<h3><a name="xmltonative">Converting from domain XML to Bhyve args</a></h3>
+
+<p>
+The <code>virsh domxml-to-native</code> command allows to preview the actual <code>bhyve</code> commands
+that will be executed for a given domain. It outputs two lines, the first line is a <code>bhyveload</code>
+command and the second is a <code>bhyve</code> command.
+</p>
+
+<p>Please note that the <code>virsh domxml-to-native</code> doesn't do any real actions but printing the command,
+for example, it doesn't try to find a proper TAP interface and create it, like it's done when starting a domain, and
+always returns <code>tap0</code> for the network interface. So if you're going to run these commands manually, most likely
+you might want to tweak them.</p>
+
+<pre>
+# virsh -c "bhyve:///system" domxml-to-native --format bhyve-argv --xml /path/to/bhyve.xml
+/usr/sbin/bhyveload -m 214 -d /home/user/vm1.img vm1
+/usr/sbin/bhyve -c 2 -m 214 -A -I -H -P -s 0:0,hostbridge -s 3:0,virtio-net,tap0,mac=52:54:00:5d:74:e3 -s 2:0,virtio-blk,/home/user/vm1.img -s 1,lpc -l com1,/dev/nmdm0A vm1
+</pre>
</body>
</html>
--
1.9.0
10 years, 5 months
[libvirt] [PATCH] util: fix DST end date in virtimetest timezones
by Laine Stump
Reported by: Roman Bogorodskiy <bogorodskiy(a)gmail.com>
Some of the tests for virTimeLocalOffsetFromUTC set an imaginary
timezone that attempts to force dyalight savings time active all the
time by setting a start date of 0/00:00:00 and end date of
366/23:59:59. Since the day is 0-based, 366 really means "day 367"
which will never occur - this was an attempt to eliminate problems
with DST not being active in some cases right around midnight on
January 1. Even though it didn't completely solve the problem, it
didn't seem to cause harm so it was left in the test timezones.
Although Linux glibc doesn't mind having a DST end date of 366,
FreeBSD refuses to use such timezones, so the tests fail. This patch
changes the 366 to 365.
This may or may not cause failure of the remaining DST tests around
midnight Jan 1. If so, we will need to disable those tests at year's
end too.
---
Pushed as a build breaker.
tests/virtimetest.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tests/virtimetest.c b/tests/virtimetest.c
index 749a112..859bd13 100644
--- a/tests/virtimetest.c
+++ b/tests/virtimetest.c
@@ -192,13 +192,13 @@ mymain(void)
* have DST in effect; what's more, cover a zone with
* with an unusual DST different than a usual one hour
*/
- TEST_LOCALOFFSET("VIR-00:30VID,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR-00:30VID,0/00:00:00,365/23:59:59",
((1 * 60) + 30) * 60);
- TEST_LOCALOFFSET("VIR-02:30VID,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR-02:30VID,0/00:00:00,365/23:59:59",
((3 * 60) + 30) * 60);
- TEST_LOCALOFFSET("VIR-02:30VID-04:30,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59",
((4 * 60) + 30) * 60);
- TEST_LOCALOFFSET("VIR-12:00VID-13:00,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59",
((13 * 60) + 0) * 60);
if (!isNearYearEnd()) {
@@ -214,11 +214,11 @@ mymain(void)
* tests, except on Dec 31 and Jan 1.
*/
- TEST_LOCALOFFSET("VIR02:45VID00:45,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR02:45VID00:45,0/00:00:00,365/23:59:59",
-45 * 60);
- TEST_LOCALOFFSET("VIR05:00VID04:00,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR05:00VID04:00,0/00:00:00,365/23:59:59",
((-4 * 60) + 0) * 60);
- TEST_LOCALOFFSET("VIR11:00VID10:00,0/00:00:00,366/23:59:59",
+ TEST_LOCALOFFSET("VIR11:00VID10:00,0/00:00:00,365/23:59:59",
((-10 * 60) + 0) * 60);
}
--
1.9.3
10 years, 5 months
[libvirt] [PATCHv2 0/4] qemu: fix broken RTC_CHANGE event when clock offset='variable'
by Laine Stump
(the cover letter from V1 has been preserved here with small updates)
This patch series is all about:
https://bugzilla.redhat.com/show_bug.cgi?id=964177
which points out a flaw in qemu's RTC_CHANGE event when the base for
the guest's real time clock was given as an explicit date (rather than
as 'utc' or 'localtime'). Patch 3/4 explains what qemu does, and how
this patch fixes it (for the case of basis='utc' - an additional fix
to properly support basis='localtime', both for RTC_CHANGE and when
migrating across timezone/DST boundaries, is in Patch 4/4). (NB: the
flawed RTC_CHANGE offset has been in QEMU for so long now that it has
been documented and cannot be changed, so libvirt must work around it)
In the meantime, the fix for basis='localtime' required that we learn
the offset of localtime from utc, and that seems like something we
might want to do for other reasons, so Patch 1/4 adds a new utility
function do get that value that is (I hope!) POSIX compliant.
Since the original patch to fix this problem was incorrect, and the
new patch doesn't use any of its code, Patch 2/4 reverts that patch
completely.
Note that I have tested this patch by starting a domain with several
variations of <clock> parameters (in a locale that is currently at
UTC+3) and using the following short script to add and remove seconds
from the guest's RTC while watching both the <clock> line in
/var/run/libvirt/qemu/$domain.xml and the offset value sent in
libvirt's VIR_DOMAIN_EVENT_ID_RTC_CHANGE event (using
examples/domain-events/events-c/event-test from a libvirt source tree
that has been built). All cases appear to maintain the adjustment in
the status properly, as well as sending the correct value to any event
handler.
Here is the script I used to add/remove time from the RTC:
#!/bin/sh
old=$(hwclock --show | cut -f1-7 -d' ')
oldabs=$(date +%s --date="$old")
newabs=$(expr $oldabs + $1)
new=$(date --date="@$newabs")
echo Old: $oldabs $old
echo New: $newabs $new
hwclock --set --date="@$newabs"
Laine Stump (4):
util: new function virTimeLocalOffsetFromUTC
Revert "qemu: Report the offset from host UTC for RTC_CHANGE event"
qemu: fix RTC_CHANGE event for <clock offset='variable' basis='utc'/>
qemu: fix <clock offset='variable' basis='localtime'/>
src/conf/domain_conf.c | 32 +++++++++++++-------------------
src/conf/domain_conf.h | 8 +++++---
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 43 ++++++++++++++++++++++++++++++-------------
src/qemu/qemu_process.c | 34 +++++++++++++++++++---------------
src/util/virtime.c | 41 ++++++++++++++++++++++++++++++++++++++++-
src/util/virtime.h | 5 +++--
tests/virtimetest.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 155 insertions(+), 53 deletions(-)
--
1.9.0
10 years, 5 months