From 63cdc92f046694620e96538ee97360769922f913 Mon Sep 17 00:00:00 2001
From: Wido den Hollander <wido@widodh.nl>
Date: Wed, 27 Jan 2016 11:20:07 +0100
Subject: [PATCH] storage: Add TRIM algorithm to storage volume API

This new algorithm adds support for wiping volumes using TRIM.

It does not overwrite all the data in a volume, but it tells the
backing storage pool/driver that all bytes in a volume can be
discarded.

It depends on the backing storage pool how this is handled.

A SCSI backend might send UNMAP commands to remove all data present
on a LUN.

A Ceph backend might use rbd_discard() to instruct the Ceph cluster
that all data on that RBD volume can be discarded.

Signed-off-by: Wido den Hollander <wido@widodh.nl>
---
 include/libvirt/libvirt-storage.h |  5 ++++-
 src/storage/storage_backend.c     |  4 ++++
 src/storage/storage_backend_rbd.c |  1 +
 tools/virsh-volume.c              |  2 +-
 tools/virsh.pod                   | 14 ++++++++++++--
 5 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index 2c55c93e74..1a868ccddd 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -4,7 +4,7 @@
  * Description: Provides APIs for the management of storage pools and volumes
  * Author: Daniel Veillard <veillard@redhat.com>
  *
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2016 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
@@ -153,6 +153,9 @@ typedef enum {
 
     VIR_STORAGE_VOL_WIPE_ALG_RANDOM = 8, /* 1-pass random */
 
+    VIR_STORAGE_VOL_WIPE_ALG_TRIM = 9, /* 1-pass, trim all data on the
+                                          volume by using TRIM or DISCARD */
+
 # ifdef VIR_ENUM_SENTINELS
     VIR_STORAGE_VOL_WIPE_ALG_LAST
     /*
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 8fb869c0a8..c07b642b24 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -2105,6 +2105,10 @@ virStorageBackendVolWipeLocal(virConnectPtr conn ATTRIBUTE_UNUSED,
     case VIR_STORAGE_VOL_WIPE_ALG_RANDOM:
         alg_char = "random";
         break;
+    case VIR_STORAGE_VOL_WIPE_ALG_TRIM:
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                       _("'trim' algorithm not supported"));
+        goto cleanup;
     case VIR_STORAGE_VOL_WIPE_ALG_LAST:
         virReportError(VIR_ERR_INVALID_ARG,
                        _("unsupported algorithm %d"),
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 59a281b9c3..8a3efe9f9d 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -831,6 +831,7 @@ virStorageBackendRBDVolWipe(virConnectPtr conn,
     case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7:
     case VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33:
     case VIR_STORAGE_VOL_WIPE_ALG_RANDOM:
+    case VIR_STORAGE_VOL_WIPE_ALG_TRIM:
     case VIR_STORAGE_VOL_WIPE_ALG_LAST:
         virReportError(VIR_ERR_INVALID_ARG, _("unsupported algorithm %d"),
                        algorithm);
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 661c876042..35f0cbd78e 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -906,7 +906,7 @@ static const vshCmdOptDef opts_vol_wipe[] = {
 VIR_ENUM_DECL(virStorageVolWipeAlgorithm)
 VIR_ENUM_IMPL(virStorageVolWipeAlgorithm, VIR_STORAGE_VOL_WIPE_ALG_LAST,
               "zero", "nnsa", "dod", "bsi", "gutmann", "schneier",
-              "pfitzner7", "pfitzner33", "random");
+              "pfitzner7", "pfitzner33", "random", "trim");
 
 static bool
 cmdVolWipe(vshControl *ctl, const vshCmd *cmd)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index e830c597dd..435c64907e 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -3546,9 +3546,19 @@ B<Supported algorithms>
   pfitzner7  - Roy Pfitzner's 7-random-pass method: random x7.
   pfitzner33 - Roy Pfitzner's 33-random-pass method: random x33.
   random     - 1-pass pattern: random.
+  trim       - 1-pass trimming the volume using TRIM or DISCARD
 
-B<Note>: The availability of algorithms may be limited by the version
-of the C<scrub> binary installed on the host.
+B<Note>: The C<scrub> binary will be used to handle the 'nnsa', 'dod',
+'bsi', 'gutmann', 'schneier', 'pfitzner7' and 'pfitzner33' algorithms.
+The availability of the algorithms may be limited by the version of
+the C<scrub> binary installed on the host. The 'zero' algorithm will
+write zeroes to the entire volume. For some volumes, such as sparse
+or rbd volumes, this may result in completely filling the volume with
+zeroes making it appear to be completely full. As an alternative, the
+'trim' algorithm does not overwrite all the data in a volume, rather
+it expects the storage driver to be able to discard all bytes in a
+volume. It is up to the storage driver to handle how the discarding
+occurs. Not all storage drivers or volume types can support 'trim'.
 
 =item B<vol-dumpxml> [I<--pool> I<pool-or-uuid>] I<vol-name-or-key-or-path>