[libvirt] [PATCH 10/23] lib: Add API for setting the threshold size for VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD

Peter Krempa posted 23 patches 8 years, 11 months ago
[libvirt] [PATCH 10/23] lib: Add API for setting the threshold size for VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD
Posted by Peter Krempa 8 years, 11 months ago
The new API can be used to configure the threshold when
VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD should be fired.
---
 include/libvirt/libvirt-domain.h |  5 ++++
 src/driver-hypervisor.h          |  8 +++++++
 src/libvirt-domain.c             | 51 ++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms          |  1 +
 src/remote/remote_driver.c       |  1 +
 src/remote/remote_protocol.x     | 17 +++++++++++++-
 src/remote_protocol-structs      |  7 ++++++
 7 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 12f8ac21c..296c5664f 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4656,4 +4656,9 @@ int virDomainSetVcpu(virDomainPtr domain,
                      int state,
                      unsigned int flags);

+int virDomainSetBlockThreshold(virDomainPtr domain,
+                               const char *dev,
+                               unsigned long long threshold,
+                               unsigned int flags);
+
 #endif /* __VIR_LIBVIRT_DOMAIN_H__ */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index b81420aef..3053d7ae8 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1257,6 +1257,13 @@ typedef int
                        int state,
                        unsigned int flags);

+typedef int
+(*virDrvDomainSetBlockThreshold)(virDomainPtr domain,
+                                 const char *dev,
+                                 unsigned long long threshold,
+                                 unsigned int flags);
+
+
 typedef struct _virHypervisorDriver virHypervisorDriver;
 typedef virHypervisorDriver *virHypervisorDriverPtr;

@@ -1496,6 +1503,7 @@ struct _virHypervisorDriver {
     virDrvDomainGetGuestVcpus domainGetGuestVcpus;
     virDrvDomainSetGuestVcpus domainSetGuestVcpus;
     virDrvDomainSetVcpu domainSetVcpu;
+    virDrvDomainSetBlockThreshold domainSetBlockThreshold;
 };


diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index d8c88e06c..fd367bcb0 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11822,3 +11822,54 @@ virDomainSetVcpu(virDomainPtr domain,
     virDispatchError(domain->conn);
     return -1;
 }
+
+
+/**
+ * virDomainSetBlockThreshold:
+ * @domain: pointer to domain object
+ * @dev: string specifying the block device or backing chain element
+ * @threshold: threshold in bytes when to fire the event
+ * @flags: currently unused, callers should pass 0
+ *
+ * Set the threshold level for delivering the
+ * VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD if the device or backing chain element
+ * described by @dev is written beyond the set threshold level. The threshold
+ * level is unset once the event fired. The event may not be delivered at all if
+ * libvirtd was not running at the moment when the threshold was reached.
+ *
+ * This event allows to use thin-provisioned storage which needs management
+ * tools to grow it without the need for polling of the data.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+int
+virDomainSetBlockThreshold(virDomainPtr domain,
+                           const char *dev,
+                           unsigned long long threshold,
+                           unsigned int flags)
+{
+    VIR_DOMAIN_DEBUG(domain, "dev='%s' threshold=%llu flags=%x",
+                     NULLSTR(dev), threshold, flags);
+
+    virResetLastError();
+
+    virCheckDomainReturn(domain, -1);
+    virCheckReadOnlyGoto(domain->conn->flags, error);
+
+    virCheckNonNullArgGoto(dev, error);
+
+    if (domain->conn->driver->domainSetBlockThreshold) {
+        int ret;
+        ret = domain->conn->driver->domainSetBlockThreshold(domain, dev,
+                                                            threshold, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(domain->conn);
+    return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 04ef58021..428cf2e19 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -755,6 +755,7 @@ LIBVIRT_3.0.0 {

 LIBVIRT_3.1.0 {
     global:
+        virDomainSetBlockThreshold;
         virDomainSetVcpu;
 } LIBVIRT_3.0.0;

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index efa47beaf..baa5cbab3 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8436,6 +8436,7 @@ static virHypervisorDriver hypervisor_driver = {
     .domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */
     .domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */
     .domainSetVcpu = remoteDomainSetVcpu, /* 3.1.0 */
+    .domainSetBlockThreshold = remoteDomainSetBlockThreshold, /* 3.1.0 */
 };

 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 39dd2b728..87b2bd365 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3402,6 +3402,14 @@ struct remote_secret_event_value_changed_msg {
     remote_nonnull_secret secret;
 };

+struct remote_domain_set_block_threshold_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string dev;
+    unsigned hyper threshold;
+    unsigned int flags;
+};
+
+
 /*----- Protocol. -----*/

 /* Define the program number, protocol version and procedure numbers here. */
@@ -6048,6 +6056,13 @@ enum remote_procedure {
      * @generate: both
      * @acl: none
      */
-    REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385
+    REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385,
+
+    /**
+     * @generate: both
+     * @acl: domain:write
+     */
+    REMOTE_PROC_DOMAIN_SET_BLOCK_THRESHOLD = 386
+

 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 67e43a4ac..a46fe37bf 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2840,6 +2840,12 @@ struct remote_secret_event_value_changed_msg {
         int                        callbackID;
         remote_nonnull_secret      secret;
 };
+struct remote_domain_set_block_threshold_args {
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      dev;
+        uint64_t                   threshold;
+        u_int                      flags;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3226,4 +3232,5 @@ enum remote_procedure {
         REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED = 383,
         REMOTE_PROC_DOMAIN_SET_VCPU = 384,
         REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385,
+        REMOTE_PROC_DOMAIN_SET_BLOCK_THRESHOLD = 386,
 };
-- 
2.12.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 10/23] lib: Add API for setting the threshold size for VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD
Posted by Eric Blake 8 years, 10 months ago
On 03/15/2017 11:37 AM, Peter Krempa wrote:
> The new API can be used to configure the threshold when
> VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD should be fired.
> ---

> +++ b/src/libvirt-domain.c
> @@ -11822,3 +11822,54 @@ virDomainSetVcpu(virDomainPtr domain,
>      virDispatchError(domain->conn);
>      return -1;
>  }
> +
> +
> +/**
> + * virDomainSetBlockThreshold:
> + * @domain: pointer to domain object
> + * @dev: string specifying the block device or backing chain element
> + * @threshold: threshold in bytes when to fire the event
> + * @flags: currently unused, callers should pass 0
> + *
> + * Set the threshold level for delivering the
> + * VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD if the device or backing chain element
> + * described by @dev is written beyond the set threshold level. The threshold
> + * level is unset once the event fired. The event may not be delivered at all if

maybe s/may/might/

> + * libvirtd was not running at the moment when the threshold was reached.

We should document that the user can already poll the current write
levels via querying block status information, to make it obvious that
missing the event isn't necessarily fatal (when first [re-]connecting to
libvirt, use the poll operation; from there, you can rely on the event
to avoid further polling)

> + *
> + * This event allows to use thin-provisioned storage which needs management
> + * tools to grow it without the need for polling of the data.
> + *
> + * Returns 0 if the operation has started, -1 on failure.
> + */
> +int
> +virDomainSetBlockThreshold(virDomainPtr domain,
> +                           const char *dev,
> +                           unsigned long long threshold,
> +                           unsigned int flags)

Hmm. Because the threshold resets once the event fires, we don't have a
handy way to say 'set a threshold 100M or 10% further out than the last
limit).  That would be a reason for using flags, although I don't think
we need to worry about it for now.

Does setting the threshold lower than the current high-water mark (as
reported by polling block status information) immediately fire an event,
or will an event never fire in that situation?

> @@ -6048,6 +6056,13 @@ enum remote_procedure {
>       * @generate: both
>       * @acl: none
>       */
> -    REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385
> +    REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385,
> +
> +    /**
> +     * @generate: both
> +     * @acl: domain:write

This doesn't modify the domain.  Why does it need domain:write; wouldn't
domain:read be sufficient (namely, the same privileges you already
require for polling block status information to learn the current high
water mark)?

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 10/23] lib: Add API for setting the threshold size for VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD
Posted by Peter Krempa 8 years, 10 months ago
On Thu, Mar 23, 2017 at 12:56:10 -0500, Eric Blake wrote:
> On 03/15/2017 11:37 AM, Peter Krempa wrote:
> > The new API can be used to configure the threshold when
> > VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD should be fired.
> > ---

[...]

> > + * This event allows to use thin-provisioned storage which needs management
> > + * tools to grow it without the need for polling of the data.
> > + *
> > + * Returns 0 if the operation has started, -1 on failure.
> > + */
> > +int
> > +virDomainSetBlockThreshold(virDomainPtr domain,
> > +                           const char *dev,
> > +                           unsigned long long threshold,
> > +                           unsigned int flags)
> 
> Hmm. Because the threshold resets once the event fires, we don't have a
> handy way to say 'set a threshold 100M or 10% further out than the last
> limit).  That would be a reason for using flags, although I don't think
> we need to worry about it for now.
> 
> Does setting the threshold lower than the current high-water mark (as
> reported by polling block status information) immediately fire an event,
> or will an event never fire in that situation?

It will fire once the hypervisor writes beyond the threshold. If you set
it lower than the previous event, it will fire on the next write.

> > @@ -6048,6 +6056,13 @@ enum remote_procedure {
> >       * @generate: both
> >       * @acl: none
> >       */
> > -    REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385
> > +    REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385,
> > +
> > +    /**
> > +     * @generate: both
> > +     * @acl: domain:write
> 
> This doesn't modify the domain.  Why does it need domain:write; wouldn't
> domain:read be sufficient (namely, the same privileges you already
> require for polling block status information to learn the current high
> water mark)?

Since this api is setting the watermark level I don't feel it's right to
allow it using read-only connection.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list