]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: Attempt error recovery in virStorageBackendDiskCreateVol
authorJohn Ferlan <jferlan@redhat.com>
Wed, 21 Jan 2015 20:38:05 +0000 (15:38 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Wed, 28 Jan 2015 22:28:03 +0000 (17:28 -0500)
During virStorageBackendDiskCreateVol if virStorageBackendDiskReadPartitions
fails, then we were leaving with an error and a partition on the disk for
which there was no corresponding volume and used space on the disk which
could be reclaimable through direct parted activity. On a subsequent restart,
reload, or refresh the volume may magically appear too.

src/storage/storage_backend_disk.c

index 60f83931a420fb31fde6c5300dd34a682565230e..0c4126afc8390cbcc2453975409c77f9fc576ed3 100644 (file)
@@ -654,6 +654,13 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     virCheckFlags(0, -1);
 
+    if (!vol->target.path) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("volume target path empty for source path '%s'"),
+                      pool->def->source.devices[0].path);
+        return -1;
+    }
+
     if (virFileResolveLink(vol->target.path, &devpath) < 0) {
         virReportSystemError(errno,
                              _("Couldn't read volume target path '%s'"),
@@ -709,7 +716,7 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
 
 
 static int
-virStorageBackendDiskCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED,
+virStorageBackendDiskCreateVol(virConnectPtr conn,
                                virStoragePoolObjPtr pool,
                                virStorageVolDefPtr vol)
 {
@@ -756,8 +763,16 @@ virStorageBackendDiskCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED,
     VIR_FREE(vol->target.path);
 
     /* Fetch actual extent info, generate key */
-    if (virStorageBackendDiskReadPartitions(pool, vol) < 0)
+    if (virStorageBackendDiskReadPartitions(pool, vol) < 0) {
+        /* Best effort to remove the partition. Ignore any errors
+         * since we could be calling this with vol->target.path == NULL
+         */
+        virErrorPtr save_err = virSaveLastError();
+        ignore_value(virStorageBackendDiskDeleteVol(conn, pool, vol, 0));
+        virSetError(save_err);
+        virFreeError(save_err);
         goto cleanup;
+    }
 
     res = 0;