[libvirt] [PATCH] Fix virNetDevWaitDadFinish stub
by Roman Bogorodskiy
Build on non-Linux fails because the virNetDevWaitDadFinish() stub
has unused parameters. Fix by adding appropriate ATTRIBUTE_UNUSED
for these parameters.
Pushing under build-breaker rule.
---
src/util/virnetdev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index b84437e..9789e93 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1527,7 +1527,8 @@ int virNetDevClearIPAddress(const char *ifname,
/* return after DAD finishes for all known IPv6 addresses or an error */
int
-virNetDevWaitDadFinish(virSocketAddrPtr *addrs, size_t count)
+virNetDevWaitDadFinish(virSocketAddrPtr *addrs ATTRIBUTE_UNUSED,
+ size_t count ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Unable to wait for IPv6 DAD on this platform"));
--
2.4.6
9 years
[libvirt] [PATCH] util: remove unnecessary code to avoid error overwrite
by Luyao Huang
virCgroupRemove use VIR_ERROR to log the error and won't
change the virLastErr in the thread, so no need do this.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/util/vircgroup.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 0379c2e..a120a15 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1670,13 +1670,8 @@ virCgroupNewMachineSystemd(const char *name,
}
if (virCgroupAddTask(*group, pidleader) < 0) {
- virErrorPtr saved = virSaveLastError();
virCgroupRemove(*group);
virCgroupFree(group);
- if (saved) {
- virSetError(saved);
- virFreeError(saved);
- }
}
ret = 0;
@@ -1728,13 +1723,8 @@ virCgroupNewMachineManual(const char *name,
goto cleanup;
if (virCgroupAddTask(*group, pidleader) < 0) {
- virErrorPtr saved = virSaveLastError();
virCgroupRemove(*group);
virCgroupFree(group);
- if (saved) {
- virSetError(saved);
- virFreeError(saved);
- }
}
done:
--
1.8.3.1
9 years
[libvirt] [PATCH] qemu: fix wrong nodeset info when numatune placement is auto
by Luyao Huang
https://bugzilla.redhat.com/show_bug.cgi?id=1270715
Since commit 9deb96f remove check the nodeset from cgroup for
a running vm, the numatune nodeset reporting for those guest
numatune placement is auto is not right. Pass the autonodeset
to virDomainNumatuneFormatNodeset() to fix this.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/qemu/qemu_driver.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8cd5ee3..8ca55dd 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10177,6 +10177,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
size_t i;
virDomainObjPtr vm = NULL;
virDomainNumatuneMemMode tmpmode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+ qemuDomainObjPrivatePtr priv;
char *nodeset = NULL;
int ret = -1;
virDomainDefPtr def = NULL;
@@ -10187,6 +10188,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
+ priv = vm->privateData;
if (virDomainGetNumaParametersEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
@@ -10214,7 +10216,8 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
break;
case 1: /* fill numa nodeset here */
- nodeset = virDomainNumatuneFormatNodeset(def->numa, NULL, -1);
+ nodeset = virDomainNumatuneFormatNodeset(def->numa,
+ priv->autoNodeset, -1);
if (!nodeset ||
virTypedParameterAssign(param, VIR_DOMAIN_NUMA_NODESET,
VIR_TYPED_PARAM_STRING, nodeset) < 0)
--
1.8.3.1
9 years
[libvirt] [PATCHv4 0/2] Added waiting for DAD to finish for bridge address.
by Maxim Perevedentsev
This is a fix for commit db488c79173b240459c7754f38c3c6af9b432970
dnsmasq main process which is relied on when waiting for DAD to complete
exits without actually waiting for DAD. This is dnsmasq daemon's task.
It seems to be a race that DAD finished before dnsmasq main process exited.
The above commit needs the execution to block until DAD finishes
for bridge IPv6 address because then it closes dummy tap device.
Thus we need to ensure this ourselves.
So we periodically poll the kernel using netlink and
check whether there are any IPv6 addresses assigned to bridge
which have 'tentative' state. After DAD is finished, execution continues.
I guess that is what dnsmasq was assumed to do.
We use netlink to dump information about existing IPv6 addresses. Netlink's
response is a multi-part message. Unfortunately, the current implementation
of virNetlink treats such messages as faulty and throws an error. So the patch 2/2
adds multi-part nelink response support.
Update v2: fixed syntax.
Update v3: moved to virnetdev.
Update v4: added DAD timeout, minor fixes.
Maxim Perevedentsev (2):
network: added waiting for DAD to finish for bridge address.
netlink: add support for multi-part netlink messages.
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 34 +++++++++++++-
src/util/virnetdev.c | 110 ++++++++++++++++++++++++++++++++++++++++++++
src/util/virnetdev.h | 2 +
src/util/virnetlink.c | 4 +-
5 files changed, 149 insertions(+), 2 deletions(-)
--
1.8.3.1
9 years
[libvirt] [libvirt-glib] gobject: Add wrapper virDomainSetTime()
by Zeeshan Ali (Khattak)
---
libvirt-gobject/libvirt-gobject-domain.c | 126 +++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 25 ++++++
libvirt-gobject/libvirt-gobject.sym | 9 +++
3 files changed, 160 insertions(+)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 34eb7ca..26d0cba 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -1886,3 +1886,129 @@ gboolean gvir_domain_get_has_current_snapshot(GVirDomain *dom,
return TRUE;
}
+
+/**
+ * gvir_domain_set_time:
+ * @dom: the domain
+ * @seconds: The seconds since Epoch in UTC.
+ * @nseconds: The microseconds.
+ * @flags: bitwise-OR of #GVirDomainSetTimeFlags.
+ *
+ * This function tries to set guest time to the given value. The time to set
+ * (@seconds and @nseconds) should be in seconds relative to the Epoch of
+ * 1970-01-01 00:00:00 in UTC.
+ *
+ * If you pass #GVIR_DOMAIN_TIME_SYNC as @flags, the time is reset using
+ * domain's RTC and @seconds and @nseconds arguments are ignored.
+ *
+ * Please note that some hypervisors may require guest agent to be configured
+ * and running in order for this function to work.
+ */
+gboolean gvir_domain_set_time(GVirDomain *dom,
+ gint64 seconds,
+ guint nseconds,
+ guint flags,
+ GError **err)
+{
+ GVirDomainPrivate *priv;
+ int ret;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+ g_return_val_if_fail(flags == 0 || flags & GVIR_DOMAIN_TIME_SYNC, FALSE);
+
+ priv = dom->priv;
+ ret = virDomainSetTime(priv->handle, seconds, nseconds, flags);
+ if (ret < 0) {
+ gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
+ 0,
+ "Unable to set domain time");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct {
+ gint64 seconds;
+ guint nseconds;
+ guint flags;
+} DomainSetTimeData;
+
+static void domain_set_time_data_free(DomainSetTimeData *data)
+{
+ g_slice_free(DomainSetTimeData, data);
+}
+
+static void
+gvir_domain_set_time_helper(GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable G_GNUC_UNUSED)
+{
+ GVirDomain *dom = GVIR_DOMAIN(object);
+ DomainSetTimeData *data = (DomainSetTimeData *) task_data;
+ GError *err = NULL;
+
+ if (!gvir_domain_set_time(dom,
+ data->seconds,
+ data->nseconds,
+ data->flags,
+ &err))
+ g_task_return_error(task, err);
+ else
+ g_task_return_boolean(task, TRUE);
+}
+
+/**
+ * gvir_domain_set_time_async:
+ * @dom: the domain
+ * @dom: the domain
+ * @seconds: The seconds since Epoch in UTC.
+ * @nseconds: The microseconds.
+ * @flags: bitwise-OR of #GVirDomainSetTimeFlags.
+ * @cancellable: (allow-none)(transfer none): cancellation object
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
+ *
+ * Asynchronous variant of #gvir_domain_set_time.
+ */
+void gvir_domain_set_time_async(GVirDomain *dom,
+ gint64 seconds,
+ guint nseconds,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ DomainSetTimeData *data;
+
+ g_return_if_fail(GVIR_IS_DOMAIN(dom));
+ g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
+
+ data = g_slice_new0(DomainSetTimeData);
+ data->seconds = seconds;
+ data->nseconds = nseconds;
+ data->flags = flags;
+
+ task = g_task_new (G_OBJECT(dom),
+ cancellable,
+ callback,
+ user_data);
+ g_task_set_task_data (task, data, (GDestroyNotify)domain_set_time_data_free);
+ g_task_run_in_thread(task, gvir_domain_set_time_helper);
+
+ g_object_unref(task);
+}
+
+gboolean gvir_domain_set_time_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err)
+{
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(dom)), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), err);
+}
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 4fe381e..fbf7173 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -215,6 +215,15 @@ typedef enum {
GVIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL = VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL
} GVirDomainSnapshotListFlags;
+/**
+ * GVirDomainSetTimeFlags:
+ * @GVIR_DOMAIN_TIME_NONE: Re-sync domain time to given values.
+ * @GVIR_DOMAIN_TIME_SYNC: Re-sync domain time from domain's RTC.
+ */
+typedef enum {
+ GVIR_DOMAIN_TIME_NONE = 0,
+ GVIR_DOMAIN_TIME_SYNC = VIR_DOMAIN_TIME_SYNC,
+} GVirDomainSetTimeFlags;
typedef struct _GVirDomainInfo GVirDomainInfo;
struct _GVirDomainInfo
@@ -401,6 +410,22 @@ gboolean gvir_domain_get_has_current_snapshot(GVirDomain *dom,
gboolean *has_current_snapshot,
GError **error);
+gboolean gvir_domain_set_time(GVirDomain *dom,
+ gint64 seconds,
+ guint nseconds,
+ guint flags,
+ GError **err);
+void gvir_domain_set_time_async(GVirDomain *dom,
+ gint64 seconds,
+ guint nseconds,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gvir_domain_set_time_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err);
+
G_END_DECLS
#endif /* __LIBVIRT_GOBJECT_DOMAIN_H__ */
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index ca89a45..cbfaa71 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -304,4 +304,13 @@ LIBVIRT_GOBJECT_0.2.2 {
gvir_network_get_dhcp_leases;
} LIBVIRT_GOBJECT_0.2.1;
+LIBVIRT_GOBJECT_0.2.3 {
+ global:
+ gvir_domain_set_time_flags_get_type;
+
+ gvir_domain_set_time;
+ gvir_domain_set_time_async;
+ gvir_domain_set_time_finish;
+} LIBVIRT_GOBJECT_0.2.2;
+
# .... define new API here using predicted next version number ....
--
2.5.0
9 years
[libvirt] [PATCH] Use correct pci addresses during device-detach
by Nitesh_Konkar
From: Nitesh_Konkar <niteshkonkar(a)in.ibm.com>
The attach-device on live and persistent copies can be done independently.
Thus devices can end up having different pci addresses in live and persistent
copies. The detach device should try to detach the device from their respective
addresses instead of using the same from live/persistent.
Signed-off-by:nitkon12@linux.vnet.ibm.com
---
src/driver-nodedev.h | 1 +
src/qemu/qemu_driver.c | 25 ++++++++++---------------
2 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/src/driver-nodedev.h b/src/driver-nodedev.h
index e846612..dea79bd 100644
--- a/src/driver-nodedev.h
+++ b/src/driver-nodedev.h
@@ -59,6 +59,7 @@ typedef char *
typedef char *
(*virDrvNodeDeviceGetParent)(virNodeDevicePtr dev);
+
typedef int
(*virDrvNodeDeviceNumOfCaps)(virNodeDevicePtr dev);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f133b45..6fd58c2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8708,23 +8708,12 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
!(flags & VIR_DOMAIN_AFFECT_LIVE))
parse_flags |= VIR_DOMAIN_DEF_PARSE_INACTIVE;
- dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
+ dev_copy = virDomainDeviceDefParse(xml, vm->def,
caps, driver->xmlopt,
parse_flags);
- if (dev == NULL)
+ if (dev_copy == NULL)
goto endjob;
- if (flags & VIR_DOMAIN_AFFECT_CONFIG &&
- flags & VIR_DOMAIN_AFFECT_LIVE) {
- /* If we are affecting both CONFIG and LIVE
- * create a deep copy of device as adding
- * to CONFIG takes one instance.
- */
- dev_copy = virDomainDeviceDefCopy(dev, vm->def, caps, driver->xmlopt);
- if (!dev_copy)
- goto endjob;
- }
-
if (priv->qemuCaps)
qemuCaps = virObjectRef(priv->qemuCaps);
else if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, vm->def->emulator)))
@@ -8736,6 +8725,13 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
if (!vmdef)
goto endjob;
+ dev = virDomainDeviceDefParse(xml, vmdef,
+ caps, driver->xmlopt,
+ parse_flags);
+ if (!dev)
+ goto endjob;
+
+
if (virDomainDefCompatibleDevice(vmdef, dev,
VIR_DOMAIN_DEVICE_ACTION_DETACH) < 0)
goto endjob;
@@ -8777,8 +8773,7 @@ static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
cleanup:
virObjectUnref(qemuCaps);
virDomainDefFree(vmdef);
- if (dev != dev_copy)
- virDomainDeviceDefFree(dev_copy);
+ virDomainDeviceDefFree(dev_copy);
virDomainDeviceDefFree(dev);
virDomainObjEndAPI(&vm);
virObjectUnref(caps);
--
2.4.0
9 years
[libvirt] [PATCH] qemu: fix migration flags undefinesource cannot work
by Luyao Huang
In commit f41be296, we moved vm->persistent check into
qemuDomainRemoveInactive, but we didn't change the vm->persistent
before call qemuDomainRemoveInactive in some place before and just
call it to remove the inactive vm.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/qemu/qemu_migration.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b53491a..2abf2ee 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3912,8 +3912,10 @@ qemuMigrationConfirm(virConnectPtr conn,
qemuMigrationJobFinish(driver, vm);
if (!virDomainObjIsActive(vm)) {
- if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
+ if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) {
virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
+ vm->persistent = 0;
+ }
qemuDomainRemoveInactive(driver, vm);
}
@@ -5405,8 +5407,10 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver,
qemuMigrationJobFinish(driver, vm);
if (!virDomainObjIsActive(vm) && ret == 0) {
- if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
+ if (flags & VIR_MIGRATE_UNDEFINE_SOURCE) {
virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm);
+ vm->persistent = 0;
+ }
qemuDomainRemoveInactive(driver, vm);
}
--
1.8.3.1
9 years
[libvirt] [PATCH] conf: Add serial target type to ABI stability check
by Luyao Huang
https://bugzilla.redhat.com/show_bug.cgi?id=1273686
There is no ABI check for serial target type attribute, just
add it.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/conf/domain_conf.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 02cc8ad..a31bc05 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -17225,6 +17225,14 @@ static bool
virDomainSerialDefCheckABIStability(virDomainChrDefPtr src,
virDomainChrDefPtr dst)
{
+ if (src->targetType != dst->targetType) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target serial type %s does not match source %s"),
+ virDomainChrSerialTargetTypeToString(dst->targetType),
+ virDomainChrSerialTargetTypeToString(src->targetType));
+ return false;
+ }
+
if (src->target.port != dst->target.port) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target serial port %d does not match source %d"),
--
1.8.3.1
9 years
[libvirt] [PATCH] rbd: Remove snapshots if the FORCED flag has been provided
by Wido den Hollander
When a RBD volume has snapshots it can not be removed.
This patch introduces a new flag to force volume removal,
VIR_STORAGE_VOL_DELETE_FORCED.
With this flag any existing snapshots will be removed prior
to removing the volume.
No existing mechanism in libvirt allowed us to pass such information,
so that's why a new flag was introduced.
Signed-off-by: Wido den Hollander <wido(a)widodh.nl>
---
include/libvirt/libvirt-storage.h | 1 +
src/storage/storage_backend_rbd.c | 58 +++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index 453089e..36ff979 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -115,6 +115,7 @@ typedef enum {
typedef enum {
VIR_STORAGE_VOL_DELETE_NORMAL = 0, /* Delete metadata only (fast) */
VIR_STORAGE_VOL_DELETE_ZEROED = 1 << 0, /* Clear all data to zeros (slow) */
+ VIR_STORAGE_VOL_DELETE_FORCED = 2, /* Force removal of volume, even if in use */
} virStorageVolDeleteFlags;
typedef enum {
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index ac5085a..ca5e802 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -428,9 +428,13 @@ static int virStorageBackendRBDDeleteVol(virConnectPtr conn,
{
int ret = -1;
int r = 0;
+ int max_snaps = 128;
+ int i, snap_count, protected;
virStorageBackendRBDState ptr;
ptr.cluster = NULL;
ptr.ioctx = NULL;
+ rbd_snap_info_t *snaps;
+ rbd_image_t image = NULL;
VIR_DEBUG("Removing RBD image %s/%s", pool->def->source.name, vol->name);
@@ -443,6 +447,59 @@ static int virStorageBackendRBDDeleteVol(virConnectPtr conn,
if (virStorageBackendRBDOpenIoCTX(&ptr, pool) < 0)
goto cleanup;
+ r = rbd_open(ptr.ioctx, vol->name, &image, NULL);
+ if (r < 0) {
+ virReportSystemError(-r, _("failed to open the RBD image '%s'"),
+ vol->name);
+ goto cleanup;
+ }
+
+ do {
+ if (VIR_ALLOC_N(snaps, max_snaps))
+ goto cleanup;
+
+ snap_count = rbd_snap_list(image, snaps, &max_snaps);
+ if (snap_count <= 0) {
+ VIR_FREE(snaps);
+ }
+ } while (snap_count == -ERANGE);
+
+ VIR_DEBUG("Found %d snapshots for volume %s/%s", snap_count,
+ pool->def->source.name, vol->name);
+
+ if (snap_count > 0 && (flags & VIR_STORAGE_VOL_DELETE_FORCED)) {
+ for (i = 0; i < snap_count; i++) {
+ if (rbd_snap_is_protected(image, snaps[i].name, &protected))
+ goto cleanup;
+
+ if (protected == 1) {
+ VIR_DEBUG("Snapshot %s/%s@%s is protected needs to be "
+ "unprotected", pool->def->source.name, vol->name,
+ snaps[i].name);
+
+ if (rbd_snap_unprotect(image, snaps[i].name) < 0)
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Removing snapshot %s/%s@%s", pool->def->source.name,
+ vol->name, snaps[i].name);
+
+ if (rbd_snap_remove(image, snaps[i].name) < 0) {
+ virReportSystemError(-r, _("failed to remove snapshot '%s/%s@%s'"),
+ pool->def->source.name, vol->name,
+ snaps[i].name);
+ goto cleanup;
+ }
+ }
+
+ rbd_snap_list_end(snaps);
+ }
+
+ if (rbd_close(image) < 0)
+ goto cleanup;
+
+ VIR_DEBUG("Removing volume %s/%s", pool->def->source.name, vol->name);
+
r = rbd_remove(ptr.ioctx, vol->name);
if (r < 0 && (-r) != ENOENT) {
virReportSystemError(-r, _("failed to remove volume '%s/%s'"),
@@ -453,6 +510,7 @@ static int virStorageBackendRBDDeleteVol(virConnectPtr conn,
ret = 0;
cleanup:
+ VIR_FREE(snaps);
virStorageBackendRBDCloseRADOSConn(&ptr);
return ret;
}
--
1.9.1
9 years
[libvirt] Plan for next release
by Daniel Veillard
I'm a bit late, sorry, but I think we should freeze on Thursday
for the next release, and then shoot for middle of next week for the
actual release,
I hope this last moment warning isn't a problem,
thanks,
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/
9 years