New API: blkdiscard - discard all blocks on a block device.

This commit is contained in:
Richard W.M. Jones
2014-03-11 13:14:23 +00:00
parent 499b9ee416
commit 452b228b46
5 changed files with 109 additions and 1 deletions

View File

@@ -83,6 +83,7 @@ guestfsd_SOURCES = \
available.c \
augeas.c \
base64.c \
blkdiscard.c \
blkid.c \
blockdev.c \
btrfs.c \

90
daemon/blkdiscard.c Normal file
View File

@@ -0,0 +1,90 @@
/* 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"
#include "optgroups.h"
/* http://rwmj.wordpress.com/2014/03/11/blkdiscard-blkzeroout-blkdiscardzeroes-blksecdiscard/ */
#ifdef BLKDISCARD
int
optgroup_blkdiscard_available (void)
{
return 1;
}
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;
}
#else /* !BLKDISCARD */
OPTGROUP_BLKDISCARD_NOT_AVAILABLE
#endif

View File

@@ -11818,6 +11818,22 @@ 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;
optional = Some "blkdiscard";
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 underlying drive (see
C<guestfs_add_drive_opts>)." };
]
(* Non-API meta-commands available only in guestfish.

View File

@@ -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

View File

@@ -1 +1 @@
416
417