From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: mprivozn@redhat.com, qemu-devel@nongnu.org, lcapitulino@redhat.com
Subject: Re: [Qemu-devel] [PATCH 2/2] qemu-ga: add guest-fstrim command
Date: Tue, 12 Jun 2012 16:05:36 -0500 [thread overview]
Message-ID: <20120612210536.GB11828@illuin> (raw)
In-Reply-To: <1339498208-11390-3-git-send-email-pbonzini@redhat.com>
On Tue, Jun 12, 2012 at 12:50:08PM +0200, Paolo Bonzini wrote:
> FITRIM is a mounted filesystem feature to discard (or "trim") blocks which
> are not in use by the filesystem. This is useful for solid-state drives
> (SSDs) and thinly-provisioned storage. Provide access to the feature
> from the host so that filesystems can be trimmed periodically or before
> migration.
>
> Here is an example using scsi_debug:
>
> # modprobe scsi_debug lbpu=1 lbpws=1
> # sg_vpd -p0xb2 /dev/sdb
> Logical block provisioning VPD page (SBC):
> Unmap command supported (LBPU): 1
> Write same (16) with unmap bit supported (LBWS): 1
> Write same (10) with unmap bit supported (LBWS10): 0
> # mke2fs /dev/sdb
> # cat /sys/bus/pseudo/drivers/scsi_debug/map
> 1-616,16257-16383
> # mount /dev/sdb /run/media/pbonzini/test
> # dd if=/dev/zero of=/run/media/pbonzini/test/file
> # cat map
> 1-616,645-1588,1599-4026,4029-16383
> # rm /run/media/pbonzini/test/file
> # ./qemu-ga /dev/fd/0
> {"execute":"guest-fstrim"}
> {"return": {}}
> # cat map
> 1-612
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> qapi-schema-guest.json | 20 ++++++++++++++
> qga/commands-posix.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++-
> qga/commands-win32.c | 11 ++++++++
> 3 files changed, 102 insertions(+), 1 deletion(-)
>
> diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
> index d4055d2..72bedac 100644
> --- a/qapi-schema-guest.json
> +++ b/qapi-schema-guest.json
> @@ -351,6 +351,26 @@
> 'returns': 'int' }
>
> ##
> +# @guest-fstrim:
> +#
> +# Discard (or "trim") blocks which are not in use by the filesystem.
> +#
> +# @minimum:
> +# Minimum contiguous free range to discard, in bytes. Free ranges
> +# smaller than this may be ignored (this is a hint and the guest
> +# may not respect it). By increasing this value, the fstrim
> +# operation will complete more quickly for filesystems with badly
> +# fragmented free space, although not all blocks will be discarded.
> +# The default value is zero, meaning "discard every free block".
> +#
> +# Returns: Nothing.
> +#
> +# Since: 0.15.0
> +##
> +{ 'command': 'guest-fstrim',
> + 'data': { '*minimum': 'int' } }
> +
> +##
> # @guest-suspend-disk
> #
> # Suspend guest to disk.
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index b1a7ce6..802d13a 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -38,9 +38,12 @@ extern char **environ;
> #include <sys/socket.h>
> #include <net/if.h>
>
> -#if defined(__linux__) && defined(FIFREEZE)
> +#ifdef FIFREEZE
> #define CONFIG_FSFREEZE
> #endif
> +#ifdef FITRIM
> +#define CONFIG_FSTRIM
> +#endif
> #endif
>
> void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
> @@ -525,6 +528,65 @@ static void guest_fsfreeze_cleanup(void)
> }
> #endif /* CONFIG_FSFREEZE */
>
> +#if defined(CONFIG_FSTRIM)
The FsMount* stuff is still only declared if CONFIG_FSFREEZE is defined,
we'll need to make sure those are declared when CONFIG_FSTRIM is defined
as well.
Other than that looks good.
> +/*
> + * Walk list of mounted file systems in the guest, and trim them.
> + */
> +void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
> +{
> + int ret = 0;
> + FsMountList mounts;
> + struct FsMount *mount;
> + int fd;
> + char err_msg[512];
> + struct fstrim_range r = {
> + .start = 0,
> + .len = -1,
> + .minlen = has_minimum ? minimum : 0,
> + };
> +
> + slog("guest-fstrim called");
> +
> + QTAILQ_INIT(&mounts);
> + ret = build_fs_mount_list(&mounts);
> + if (ret < 0) {
> + return;
> + }
> +
> + QTAILQ_FOREACH(mount, &mounts, next) {
> + fd = qemu_open(mount->dirname, O_RDONLY);
> + if (fd == -1) {
> + sprintf(err_msg, "failed to open %s, %s", mount->dirname,
> + strerror(errno));
> + error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
> + goto error;
> + }
> +
> + /* We try to cull filesytems we know won't work in advance, but other
> + * filesytems may not implement fstrim for less obvious reasons. these
> + * will report EOPNOTSUPP. we simply ignore these errors. Any other
> + * error means an unexpected error, so return it in those cases. In
> + * some other cases ENOTTY will be reported (e.g. CD-ROMs).
> + */
> + ret = ioctl(fd, FITRIM, &r);
> + if (ret == -1) {
> + if (errno != ENOTTY && errno != EOPNOTSUPP) {
> + sprintf(err_msg, "failed to trim %s, %s",
> + mount->dirname, strerror(errno));
> + error_set(err, QERR_QGA_COMMAND_FAILED, err_msg);
> + close(fd);
> + goto error;
> + }
> + }
> + close(fd);
> + }
> +
> +error:
> + free_fs_mount_list(&mounts);
> +}
> +#endif /* CONFIG_FSTRIM */
> +
> +
> #define LINUX_SYS_STATE_FILE "/sys/power/state"
> #define SUSPEND_SUPPORTED 0
> #define SUSPEND_NOT_SUPPORTED 1
> @@ -918,7 +980,15 @@ int64_t qmp_guest_fsfreeze_thaw(Error **err)
>
> return 0;
> }
> +#endif /* CONFIG_FSFREEZE */
>
> +#if !defined(CONFIG_FSTRIM)
> +void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
> +{
> + error_set(err, QERR_UNSUPPORTED);
> +
> + return;
> +}
> #endif
>
> /* register init/cleanup routines for stateful command groups */
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index eb8d140..54bc546 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -173,6 +173,17 @@ int64_t qmp_guest_fsfreeze_thaw(Error **err)
> return 0;
> }
>
> +/*
> + * Walk list of mounted file systems in the guest, and discard unused
> + * areas.
> + */
> +void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
> +{
> + error_set(err, QERR_UNSUPPORTED);
> +
> + return;
> +}
> +
> typedef enum {
> GUEST_SUSPEND_MODE_DISK,
> GUEST_SUSPEND_MODE_RAM
> --
> 1.7.10.2
>
next prev parent reply other threads:[~2012-06-12 21:05 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-12 10:50 [Qemu-devel] [PATCH 0/2] qemu-ga: Add guest-fstrim command Paolo Bonzini
2012-06-12 10:50 ` [Qemu-devel] [PATCH 1/2] qemu-ga: make names more generic for mount list functions Paolo Bonzini
2012-06-12 10:50 ` [Qemu-devel] [PATCH 2/2] qemu-ga: add guest-fstrim command Paolo Bonzini
2012-06-12 19:54 ` Luiz Capitulino
2012-06-12 21:05 ` Michael Roth [this message]
2012-06-13 5:31 ` Paolo Bonzini
-- strict thread matches above, loose matches on Subject: below --
2012-06-21 23:04 [Qemu-devel] [PULL] qemu-ga patches for " Michael Roth
2012-06-21 23:04 ` [Qemu-devel] [PATCH 2/2] qemu-ga: add " Michael Roth
2012-06-22 17:48 ` Chris Wedgwood
2012-06-22 21:12 ` Michael Roth
2012-06-23 3:38 ` Chris Wedgwood
2012-06-23 20:54 ` Michael Roth
2012-06-24 16:33 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120612210536.GB11828@illuin \
--to=mdroth@linux.vnet.ibm.com \
--cc=lcapitulino@redhat.com \
--cc=mprivozn@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.