[libvirt] [PATCH 2/2] storage: Disallow vol_wipe for sparse logical volumes

John Ferlan jferlan at redhat.com
Thu Jul 17 18:10:48 UTC 2014


https://bugzilla.redhat.com/show_bug.cgi?id=1091866

Add a new boolean 'sparse'.  This will be used by the logical backend
storage driver to determine whether the target volume is sparse or not
(also known by a snapshot or thin logical volume). Although setting sparse
to true at creation could be seen as duplicitous to setting during
virStorageBackendLogicalMakeVol() in case there are ever other code paths
between Create and FindLVs that need to know about the volume be sparse.

Use the 'sparse' in a new virStorageBackendLogicalVolWipe() to decide whether
to attempt to wipe the logical volume or not. For now, I have found no
means to wipe the volume without writing to it. Writing to the sparse
volume causes it to be filled. A sparse logical volume is not complely
writeable as there exists metadata which if overwritten will cause the
sparse lv to go INACTIVE which means pool-refresh will not find it.
Access to whatever lvm uses to manage data blocks is not provided by
any API I could find.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/storage/storage_backend_logical.c | 39 ++++++++++++++++++++++++++++++++++-
 src/util/virstoragefile.h             |  1 +
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index ab1e64b..ed62c2f 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -131,6 +131,15 @@ virStorageBackendLogicalMakeVol(char **const groups,
             goto cleanup;
     }
 
+    /* Mark the (s) sparse/snapshot lv, e.g. the lv created using
+     * the --virtualsize/-V option. We've already ignored the (t)hin
+     * pool definition. In the manner libvirt defines these, the
+     * thin pool is hidden to the lvs output, except as the name
+     * in brackets [] described for the groups[1] (backingStore).
+     */
+    if (attrs[0] == 's')
+        vol->target.sparse = true;
+
     /* Skips the backingStore of lv created with "--virtualsize",
      * its original device "/dev/$vgname/$lvname_vorigin" is
      * just for lvm internal use, one should never use it.
@@ -752,6 +761,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
                                VIR_DIV_UP(vol->target.allocation
                                           ? vol->target.allocation : 1, 1024));
         virCommandAddArg(cmd, "--virtualsize");
+        vol->target.sparse = true;
     }
     virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(vol->target.capacity,
                                                     1024));
@@ -829,6 +839,33 @@ virStorageBackendLogicalBuildVolFrom(virConnectPtr conn,
     return build_func(conn, pool, vol, inputvol, flags);
 }
 
+static int
+virStorageBackendLogicalVolWipe(virConnectPtr conn,
+                                virStoragePoolObjPtr pool,
+                                virStorageVolDefPtr vol,
+                                unsigned int algorithm,
+                                unsigned int flags)
+{
+    if (!vol->target.sparse)
+        return virStorageBackendVolWipeLocal(conn, pool, vol, algorithm, flags);
+
+    /* The wiping algorithms will write something to the logical volume.
+     * Writing to a sparse logical volume causes it to be filled resulting
+     * in the volume becoming INACTIVE because there is some amount of
+     * metadata contained within the sparse lv. Choosing to only write
+     * a wipe pattern to the already written portion lv based on what
+     * 'lvs' shows in the "Data%" column/field for the sparse lv was
+     * considered. However, there is no guarantee that sparse lv could
+     * grow or shrink outside of libvirt's knowledge and thus still render
+     * the volume INACTIVE. Until there is some sort of wipe function
+     * implemented by lvm for one of these sparse lv, we'll just return
+     * unsupported.
+     */
+    virReportError(VIR_ERR_NO_SUPPORT,
+                   _("logical volue '%s' is sparse, volume wipe not supported"),
+                   vol->target.path);
+    return -1;
+}
 
 virStorageBackend virStorageBackendLogical = {
     .type = VIR_STORAGE_POOL_LOGICAL,
@@ -846,5 +883,5 @@ virStorageBackend virStorageBackendLogical = {
     .deleteVol = virStorageBackendLogicalDeleteVol,
     .uploadVol = virStorageBackendVolUploadLocal,
     .downloadVol = virStorageBackendVolDownloadLocal,
-    .wipeVol = virStorageBackendVolWipeLocal,
+    .wipeVol = virStorageBackendLogicalVolWipe,
 };
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index c840aa0..eccbf4e 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -248,6 +248,7 @@ struct _virStorageSource {
     virBitmapPtr features;
     char *compat;
     bool nocow;
+    bool sparse;
 
     virStoragePermsPtr perms;
     virStorageTimestampsPtr timestamps;
-- 
1.9.3




More information about the libvir-list mailing list