---
daemon/Makefile.am | 1 +
daemon/blkdiscard.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 15 ++++++++++
po/POTFILES | 1 +
src/MAX_PROC_NR | 2 +-
5 files changed, 95 insertions(+), 1 deletion(-)
create mode 100644 daemon/blkdiscard.c
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index e64caca..b18f9ff 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -83,6 +83,7 @@ guestfsd_SOURCES = \
available.c \
augeas.c \
base64.c \
+ blkdiscard.c \
blkid.c \
blockdev.c \
btrfs.c \
diff --git a/daemon/blkdiscard.c b/daemon/blkdiscard.c
new file mode 100644
index 0000000..26d5f7d
--- /dev/null
+++ b/daemon/blkdiscard.c
@@ -0,0 +1,77 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
+#include "daemon.h"
+#include "actions.h"
+
+/*
http://rwmj.wordpress.com/2014/03/11/blkdiscard-blkzeroout-blkdiscardzero...
*/
+
+int
+do_blkdiscard (const char *device)
+{
+ /* XXX We could read /sys/block/<device>/queue/discard_* in order to
+ * determine if discard is supported and the largest request size we
+ * are allowed to make. However:
+ *
+ * (1) Mapping the device name to /sys/block/<device> is quite hard
+ * (cf. the lv_canonical function in daemon/lvm.c)
+ *
+ * (2) We don't really need to do this in modern libguestfs since
+ * we're very likely to be using virtio-scsi, which supports
+ * arbitrary block discards.
+ *
+ * Let's wait to see if it causes a problem in real world
+ * situations.
+ */
+ uint64_t range[2];
+ int64_t size;
+ int fd;
+
+ size = do_blockdev_getsize64 (device);
+ if (size == -1)
+ return -1;
+
+ range[0] = 0;
+ range[1] = (uint64_t) size;
+
+ fd = open (device, O_WRONLY|O_CLOEXEC);
+ if (fd == -1) {
+ reply_with_perror ("open: %s", device);
+ return -1;
+ }
+
+ if (ioctl (fd, BLKDISCARD, range) == -1) {
+ reply_with_perror ("ioctl: %s: BLKDISCARD", device);
+ close (fd);
+ return -1;
+ }
+
+ close (fd);
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index b25194c..beb1182 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -11818,6 +11818,21 @@ device C<device>. Note that partitions are numbered from
1.
The partition name can only be read on certain types of partition
table. This works on C<gpt> but not on C<mbr> partitions." };
+ { defaults with
+ name = "blkdiscard";
+ style = RErr, [Device "device"], [];
+ proc_nr = Some 417;
+ shortdesc = "discard all blocks on a device";
+ longdesc = "\
+This discards all blocks on the block device C<device>, giving
+the free space back to the host.
+
+This operation requires support in libguestfs, the host filesystem,
+qemu and the host kernel. If this support isn't present it may give
+an error or even appear to run but do nothing. You must also
+set the C<discard> attribute on the block device (see
+C<guestfs_add_drive_opts>)." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/po/POTFILES b/po/POTFILES
index 5aeeb2e..ecdbae4 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -16,6 +16,7 @@ daemon/acl.c
daemon/augeas.c
daemon/available.c
daemon/base64.c
+daemon/blkdiscard.c
daemon/blkid.c
daemon/blockdev.c
daemon/btrfs.c
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 1c105f1..53c86ff 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-416
+417
--
1.8.5.3