[libvirt] [PATCH v2 0/4] Introduce support for FITRIM within guest OS

https://bugzilla.redhat.com/show_bug.cgi?id=831159 diff to v1: - Peter's review suggestions worked in 2/4 has been ACKed already. Michal Privoznik (4): Introduce virDomainFSTrim() public API remote: Implement virDomainFSTrim qemu: Implement virDomainFSTrim virsh: Expose new virDomainFSTrim API include/libvirt/libvirt.h.in | 4 ++ src/driver.h | 6 ++++ src/libvirt.c | 55 ++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_agent.c | 25 +++++++++++++++ src/qemu/qemu_agent.h | 2 + src/qemu/qemu_driver.c | 68 ++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 10 +++++- src/remote_protocol-structs | 7 ++++ src/rpc/gendispatch.pl | 1 + tools/virsh-domain.c | 47 +++++++++++++++++++++++++++++ tools/virsh.pod | 14 ++++++++ 13 files changed, 244 insertions(+), 1 deletions(-) -- 1.7.8.6

This will call FITRIM within guest. The API has 4 arguments, however, only 2 will be used for now (@dom and @minumum). The rest two are there if in future qemu guest agent learns them. --- include/libvirt/libvirt.h.in | 4 +++ src/driver.h | 6 ++++ src/libvirt.c | 55 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 70 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 84dcde1..bd03315 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4457,6 +4457,10 @@ int virDomainOpenGraphics(virDomainPtr dom, int virDomainInjectNMI(virDomainPtr domain, unsigned int flags); +int virDomainFSTrim(virDomainPtr dom, + const char *mountPoint, + unsigned long long minimum, + unsigned int flags); /** * virSchedParameterType: diff --git a/src/driver.h b/src/driver.h index 7ba66ad..5163840 100644 --- a/src/driver.h +++ b/src/driver.h @@ -903,6 +903,11 @@ typedef int unsigned char **cpumap, unsigned int *online, unsigned int flags); +typedef int + (*virDrvDomainFSTrim)(virDomainPtr dom, + const char *mountPoint, + unsigned long long minimum, + unsigned int flags); /** * _virDriver: @@ -1094,6 +1099,7 @@ struct _virDriver { virDrvNodeGetMemoryParameters nodeGetMemoryParameters; virDrvNodeSetMemoryParameters nodeSetMemoryParameters; virDrvNodeGetCPUMap nodeGetCPUMap; + virDrvDomainFSTrim domainFSTrim; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index 4af6089..23c36f9 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -20224,3 +20224,58 @@ error: virDispatchError(conn); return -1; } + +/** + * virDomainFSTrim: + * @dom: a domain object + * @mountPoint: which mount point trim + * @minimum: Minimum contiguous free range to discard in bytes + * @flags: extra flags, not used yet, so callers should always pass 0 + * + * Calls FITRIM within the guest (hence guest agent may be + * required depending on hypervisor used). Either call it on each + * mounted filesystem (@mountPoint is NULL) or just on specified + * @mountPoint. @minimum tell that 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. + * + * Returns 0 on success, -1 otherwise. + */ +int +virDomainFSTrim(virDomainPtr dom, + const char *mountPoint, + unsigned long long minimum, + unsigned int flags) +{ + VIR_DOMAIN_DEBUG(dom, "mountPoint=%s, minimum=%llu, flags=%x", + mountPoint, minimum, flags); + + virResetLastError(); + + if (!VIR_IS_DOMAIN(dom)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (dom->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (dom->conn->driver->domainFSTrim) { + int ret = dom->conn->driver->domainFSTrim(dom, mountPoint, + minimum, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(dom->conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index f494821..f699e93 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -574,4 +574,9 @@ LIBVIRT_1.0.0 { virNodeGetCPUMap; } LIBVIRT_0.10.2; +LIBVIRT_1.0.1 { + global: + virDomainFSTrim; +} LIBVIRT_1.0.0; + # .... define new API here using predicted next version number .... -- 1.7.8.6

On Wed, Nov 28, 2012 at 03:50:29PM +0100, Michal Privoznik wrote:
This will call FITRIM within guest. The API has 4 arguments, however, only 2 will be used for now (@dom and @minumum). The rest two are there if in future qemu guest agent learns them. --- include/libvirt/libvirt.h.in | 4 +++ src/driver.h | 6 ++++ src/libvirt.c | 55 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 70 insertions(+), 0 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

This will call FITRIM within guest. The API has 4 arguments, however, only 2 will be used for now (@dom and @minumum). The rest two are there if in future qemu guest agent learns them.
s/in future/in the future/
+/** + * virDomainFSTrim: + * @dom: a domain object + * @mountPoint: which mount point trim
s/trim/to trim/
+ * @minimum: Minimum contiguous free range to discard in bytes + * @flags: extra flags, not used yet, so callers should always pass 0 + * + * Calls FITRIM within the guest (hence guest agent may be + * required depending on hypervisor used). Either call it on each + * mounted filesystem (@mountPoint is NULL) or just on specified + * @mountPoint. @minimum tell that free ranges smaller than this
s/tell/hints/
+ * 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.
Maybe mention that the command may fail if @minimum is not 0.

On 29.11.2012 00:41, Eric Blake wrote:
This will call FITRIM within guest. The API has 4 arguments, however, only 2 will be used for now (@dom and @minumum). The rest two are there if in future qemu guest agent learns them.
s/in future/in the future/
+/** + * virDomainFSTrim: + * @dom: a domain object + * @mountPoint: which mount point trim
s/trim/to trim/
+ * @minimum: Minimum contiguous free range to discard in bytes + * @flags: extra flags, not used yet, so callers should always pass 0 + * + * Calls FITRIM within the guest (hence guest agent may be + * required depending on hypervisor used). Either call it on each + * mounted filesystem (@mountPoint is NULL) or just on specified + * @mountPoint. @minimum tell that free ranges smaller than this
s/tell/hints/
+ * 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.
Maybe mention that the command may fail if @minimum is not 0.
Right. But since I've already pushed the patches I am pushing a separate commit to fix those nits under trivial rule: commit 5049b53689128701e5bb72fa578467ac34071be9 Author: Michal Privoznik <mprivozn@redhat.com> AuthorDate: Thu Nov 29 09:30:58 2012 +0100 Commit: Michal Privoznik <mprivozn@redhat.com> CommitDate: Thu Nov 29 09:30:58 2012 +0100 libvirt.c: Fix wording and grammar in virDomainFSTrim The documentation to this API has some defects from grammar and wording POV. These were raised after I've pushed the patches, so they are in a separate commit. diff --git a/src/libvirt.c b/src/libvirt.c index b1854e3..4581394 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -20229,18 +20229,19 @@ error: /** * virDomainFSTrim: * @dom: a domain object - * @mountPoint: which mount point trim + * @mountPoint: which mount point to trim * @minimum: Minimum contiguous free range to discard in bytes * @flags: extra flags, not used yet, so callers should always pass 0 * * Calls FITRIM within the guest (hence guest agent may be * required depending on hypervisor used). Either call it on each * mounted filesystem (@mountPoint is NULL) or just on specified - * @mountPoint. @minimum tell that free ranges smaller than this + * @mountPoint. @minimum hints that 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. + * If @minimum is not zero, the command may fail. * * Returns 0 on success, -1 otherwise. */

A new rule to fixup_name() in gendispatch.pl needs to be added, otherwise we are left with remoteDomainFstrim which is not wanted. --- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 10 +++++++++- src/remote_protocol-structs | 7 +++++++ src/rpc/gendispatch.pl | 1 + 4 files changed, 18 insertions(+), 1 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ec33698..49d89be 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6145,6 +6145,7 @@ static virDriver remote_driver = { .nodeSetMemoryParameters = remoteNodeSetMemoryParameters, /* 0.10.2 */ .nodeGetMemoryParameters = remoteNodeGetMemoryParameters, /* 0.10.2 */ .nodeGetCPUMap = remoteNodeGetCPUMap, /* 1.0.0 */ + .domainFSTrim = remoteDomainFSTrim, /* 1.0.1 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index d6ac3c1..31567e2 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2682,6 +2682,13 @@ struct remote_node_get_cpu_map_ret { int ret; }; +struct remote_domain_fstrim_args { + remote_nonnull_domain dom; + remote_string mountPoint; + unsigned hyper minimum; + unsigned int flags; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -3026,7 +3033,8 @@ enum remote_procedure { REMOTE_PROC_NETWORK_UPDATE = 291, /* autogen autogen priority:high */ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, /* autogen autogen */ - REMOTE_PROC_NODE_GET_CPU_MAP = 293 /* skipgen skipgen */ + REMOTE_PROC_NODE_GET_CPU_MAP = 293, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_FSTRIM = 294 /* autogen autogen */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 6fe7213..d0d4f53 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2139,6 +2139,12 @@ struct remote_node_get_cpu_map_ret { u_int online; int ret; }; +struct remote_domain_fstrim_args { + remote_nonnull_domain dom; + remote_string mountPoint; + uint64_t minimum; + u_int flags; +}; enum remote_procedure { REMOTE_PROC_OPEN = 1, REMOTE_PROC_CLOSE = 2, @@ -2433,4 +2439,5 @@ enum remote_procedure { REMOTE_PROC_NETWORK_UPDATE = 291, REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, REMOTE_PROC_NODE_GET_CPU_MAP = 293, + REMOTE_PROC_DOMAIN_FSTRIM = 294, }; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index ae7ecba..899f4bc 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -44,6 +44,7 @@ sub fixup_name { $name =~ s/Os$/OS/; $name =~ s/Nmi$/NMI/; $name =~ s/Pm/PM/; + $name =~ s/Fstrim$/FSTrim/; return $name; } -- 1.7.8.6

On Wed, Nov 28, 2012 at 03:50:30PM +0100, Michal Privoznik wrote:
A new rule to fixup_name() in gendispatch.pl needs to be added, otherwise we are left with remoteDomainFstrim which is not wanted. --- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 10 +++++++++- src/remote_protocol-structs | 7 +++++++ src/rpc/gendispatch.pl | 1 + 4 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ec33698..49d89be 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6145,6 +6145,7 @@ static virDriver remote_driver = { .nodeSetMemoryParameters = remoteNodeSetMemoryParameters, /* 0.10.2 */ .nodeGetMemoryParameters = remoteNodeGetMemoryParameters, /* 0.10.2 */ .nodeGetCPUMap = remoteNodeGetCPUMap, /* 1.0.0 */ + .domainFSTrim = remoteDomainFSTrim, /* 1.0.1 */ };
static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index d6ac3c1..31567e2 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2682,6 +2682,13 @@ struct remote_node_get_cpu_map_ret { int ret; };
+struct remote_domain_fstrim_args { + remote_nonnull_domain dom; + remote_string mountPoint; + unsigned hyper minimum; + unsigned int flags; +}; + /*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */ @@ -3026,7 +3033,8 @@ enum remote_procedure {
REMOTE_PROC_NETWORK_UPDATE = 291, /* autogen autogen priority:high */ REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, /* autogen autogen */ - REMOTE_PROC_NODE_GET_CPU_MAP = 293 /* skipgen skipgen */ + REMOTE_PROC_NODE_GET_CPU_MAP = 293, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_FSTRIM = 294 /* autogen autogen */
/* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 6fe7213..d0d4f53 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2139,6 +2139,12 @@ struct remote_node_get_cpu_map_ret { u_int online; int ret; }; +struct remote_domain_fstrim_args { + remote_nonnull_domain dom; + remote_string mountPoint; + uint64_t minimum; + u_int flags; +}; enum remote_procedure { REMOTE_PROC_OPEN = 1, REMOTE_PROC_CLOSE = 2, @@ -2433,4 +2439,5 @@ enum remote_procedure { REMOTE_PROC_NETWORK_UPDATE = 291, REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, REMOTE_PROC_NODE_GET_CPU_MAP = 293, + REMOTE_PROC_DOMAIN_FSTRIM = 294, }; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index ae7ecba..899f4bc 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -44,6 +44,7 @@ sub fixup_name { $name =~ s/Os$/OS/; $name =~ s/Nmi$/NMI/; $name =~ s/Pm/PM/; + $name =~ s/Fstrim$/FSTrim/;
return $name; } ACK
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

using qemu guest agent. As said in previous patch, @mountPoint must be NULL and @flags zero because qemu guest agent doesn't support these arguments yet. If qemu learns them, we can start supporting them as well. --- src/qemu/qemu_agent.c | 25 +++++++++++++++++ src/qemu/qemu_agent.h | 2 + src/qemu/qemu_driver.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index ab6dc22..6f517c9 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1448,3 +1448,28 @@ qemuAgentArbitraryCommand(qemuAgentPtr mon, virJSONValueFree(reply); return ret; } + +int +qemuAgentFSTrim(qemuAgentPtr mon, + unsigned long long minimum) +{ + int ret = -1; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + + cmd = qemuAgentMakeCommand("guest-fstrim", + "U:minimum", minimum, + NULL); + if (!cmd) + return ret; + + ret = qemuAgentCommand(mon, cmd, &reply, + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK); + + if (reply && ret == 0) + ret = qemuAgentCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index c62c438..dad068b 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -83,4 +83,6 @@ int qemuAgentArbitraryCommand(qemuAgentPtr mon, const char *cmd, char **result, int timeout); +int qemuAgentFSTrim(qemuAgentPtr mon, + unsigned long long minimum); #endif /* __QEMU_AGENT_H__ */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7892293..3e3f08d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14728,6 +14728,73 @@ cleanup: return result; } +static int +qemuDomainFSTrim(virDomainPtr dom, + const char *mountPoint, + unsigned long long minimum, + unsigned int flags) +{ + struct qemud_driver *driver = dom->conn->privateData; + virDomainObjPtr vm; + int ret = -1; + qemuDomainObjPrivatePtr priv; + + virCheckFlags(0, -1); + + if (mountPoint) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("Specifying mount point " + "is not supported for now")); + return -1; + } + + if (!(vm = qemuDomObjFromDomain(dom))) + goto cleanup; + + priv = vm->privateData; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto cleanup; + } + + if (!priv->agent) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("QEMU guest agent is not configured")); + goto cleanup; + } + + if (priv->agentError) { + virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s", + _("QEMU guest agent is not " + "available due to an error")); + goto cleanup; + } + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + + qemuDomainObjEnterAgent(driver, vm); + ret = qemuAgentFSTrim(priv->agent, minimum); + qemuDomainObjExitAgent(driver, vm); + +endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) + vm = NULL; + +cleanup: + if (vm) + virDomainObjUnlock(vm); + return ret; +} + static virDriver qemuDriver = { .no = VIR_DRV_QEMU, .name = QEMU_DRIVER_NAME, @@ -14901,6 +14968,7 @@ static virDriver qemuDriver = { .nodeGetMemoryParameters = nodeGetMemoryParameters, /* 0.10.2 */ .nodeSetMemoryParameters = nodeSetMemoryParameters, /* 0.10.2 */ .nodeGetCPUMap = nodeGetCPUMap, /* 1.0.0 */ + .domainFSTrim = qemuDomainFSTrim, /* 1.0.1 */ }; -- 1.7.8.6

On Wed, Nov 28, 2012 at 03:50:31PM +0100, Michal Privoznik wrote:
using qemu guest agent. As said in previous patch, @mountPoint must be NULL and @flags zero because qemu guest agent doesn't support these arguments yet. If qemu learns them, we can start supporting them as well. --- src/qemu/qemu_agent.c | 25 +++++++++++++++++ src/qemu/qemu_agent.h | 2 + src/qemu/qemu_driver.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 0 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

under domfstrim command. Since API doesn't support all parameters (some must be NULL or zero), don't expose these in virsh neither. --- tools/virsh-domain.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 14 ++++++++++++++ 2 files changed, 61 insertions(+), 0 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index cc47383..3e81e4a 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -8300,6 +8300,52 @@ cleanup: return ret; } +static const vshCmdInfo info_domfstrim[] = { + {"help", N_("Invoke fstrim on domain's mounted filesystems.")}, + {"desc", N_("Invoke fstrim on domain's mounted filesystems.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_domfstrim[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"minimum", VSH_OT_INT, 0, N_("Just a hint to ignore contiguous " + "free ranges smaller than this (Bytes)")}, + {"mountpoint", VSH_OT_DATA, 0, N_("which mount point to trim")}, + {NULL, 0, 0, NULL} +}; +static bool +cmdDomFSTrim(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + bool ret = false; + unsigned long long minimum = 0; + const char *mountPoint = NULL; + unsigned int flags = 0; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + goto cleanup; + + if (vshCommandOptULongLong(cmd, "minimum", &minimum) < 0) { + vshError(ctl, _("Unable to parse integer parameter minimum")); + goto cleanup; + } + + if (vshCommandOptString(cmd, "mountpoint", &mountPoint) < 0) { + vshError(ctl, _("Unable to parse mountpoint parameter")); + goto cleanup; + } + + if (virDomainFSTrim(dom, mountPoint, minimum, flags) < 0) { + vshError(ctl, _("Unable to invoke fstrim")); + goto cleanup; + } + + ret = true; + +cleanup: + return ret; +} + const vshCmdDef domManagementCmds[] = { {"attach-device", cmdAttachDevice, opts_attach_device, info_attach_device, 0}, @@ -8332,6 +8378,7 @@ const vshCmdDef domManagementCmds[] = { {"detach-interface", cmdDetachInterface, opts_detach_interface, info_detach_interface, 0}, {"domdisplay", cmdDomDisplay, opts_domdisplay, info_domdisplay, 0}, + {"domfstrim", cmdDomFSTrim, opts_domfstrim, info_domfstrim, 0}, {"domhostname", cmdDomHostname, opts_domhostname, info_domhostname, 0}, {"domid", cmdDomid, opts_domid, info_domid, 0}, {"domif-setlink", cmdDomIfSetLink, opts_domif_setlink, info_domif_setlink, 0}, diff --git a/tools/virsh.pod b/tools/virsh.pod index c4d505f..353af66 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -878,6 +878,20 @@ Output a URI which can be used to connect to the graphical display of the domain via VNC, SPICE or RDP. If I<--include-password> is specified, the SPICE channel password will be included in the URI. +=item B<domfstrim> I<domain> [I<--minimum> B<bytes>] +[I<--mountpoint mountPoint>] + +Issue a fstrim command on all mounted filesystems within a running +domain. It discards blocks which are not in use by the filesystem. +If I<--minimum> B<bytes> is specified, it tells guest kernel length +of contiguous free range. 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". Moreover, a if user wants to trim only one mount +point, it can be specified via optional I<--mountpoint> parameter. + =item B<domhostname> I<domain> Returns the hostname of a domain, if the hypervisor makes it available. -- 1.7.8.6

On Wed, Nov 28, 2012 at 03:50:32PM +0100, Michal Privoznik wrote:
under domfstrim command. Since API doesn't support all
The body of the commit message should be a separate paragraph from the subject line, so you need to change this first sentence
parameters (some must be NULL or zero), don't expose these in virsh neither.
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 28.11.2012 15:58, Daniel P. Berrange wrote:
On Wed, Nov 28, 2012 at 03:50:32PM +0100, Michal Privoznik wrote:
under domfstrim command. Since API doesn't support all
The body of the commit message should be a separate paragraph from the subject line, so you need to change this first sentence
parameters (some must be NULL or zero), don't expose these in virsh neither.
ACK
Daniel
Fixed and pushed whole set. Thanks. Michal
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Michal Privoznik