[libvirt] [dbus PATCH v3 03/20] Implement MemoryStats for Domain Interface

Katerina Koukiou posted 20 patches 7 years, 1 month ago
[libvirt] [dbus PATCH v3 03/20] Implement MemoryStats for Domain Interface
Posted by Katerina Koukiou 7 years, 1 month ago
This method is not tested for now since the test driver
doesn't support this API.

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com>
---
 data/org.libvirt.Domain.xml |  6 ++++
 src/domain.c                | 72 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
index df9fbf9..7174769 100644
--- a/data/org.libvirt.Domain.xml
+++ b/data/org.libvirt.Domain.xml
@@ -69,6 +69,12 @@
       <arg name="flags" type="u" direction="in"/>
       <arg name="xml" type="s" direction="out"/>
     </method>
+    <method name="MemoryStats">
+      <annotation name="org.gtk.GDBus.DocString"
+        value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMemoryStats"/>
+      <arg name="flags" type="u" direction="in"/>
+      <arg name="stats" type="a{st}" direction="out"/>
+    </method>
     <method name="Reboot">
       <annotation name="org.gtk.GDBus.DocString"
         value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainReboot"/>
diff --git a/src/domain.c b/src/domain.c
index f775fd4..5f87572 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -3,6 +3,42 @@
 
 #include <libvirt/libvirt.h>
 
+VIRT_DBUS_ENUM_DECL(virtDBusDomainMemoryStat)
+VIRT_DBUS_ENUM_IMPL(virtDBusDomainMemoryStat,
+                    VIR_DOMAIN_MEMORY_STAT_LAST,
+                    "swap_in",
+                    "swap_out",
+                    "major_fault",
+                    "minor_fault",
+                    "unused",
+                    "available",
+                    "actual_baloon",
+                    "rss",
+                    "usable",
+                    "last_update")
+
+static GVariant *
+virtDBusDomainMemoryStatsToGVariant(virDomainMemoryStatPtr stats,
+                                    gint nr_stats,
+                                    GError **error)
+{
+    GVariantBuilder builder;
+
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("a{st}"));
+
+    for (gint i = 0; i < nr_stats; i++) {
+        const gchar *memoryStat = virtDBusDomainMemoryStatTypeToString(stats[i].tag);
+        if (!memoryStat) {
+            g_set_error(error, VIRT_DBUS_ERROR, VIRT_DBUS_ERROR_LIBVIRT,
+                        "Can't translate virDomainMemoryStatTags to string.");
+            return NULL;
+        }
+        g_variant_builder_add(&builder, "{st}", memoryStat, stats[i].val);
+    }
+
+    return g_variant_builder_end(&builder);
+}
+
 static virDomainPtr
 virtDBusDomainGetVirDomain(virtDBusConnect *connect,
                            const gchar *objectPath,
@@ -398,6 +434,41 @@ virtDBusDomainGetXMLDesc(GVariant *inArgs,
     *outArgs = g_variant_new("(s)", xml);
 }
 
+static void
+virtDBusDomainMemoryStats(GVariant *inArgs,
+                          GUnixFDList *inFDs G_GNUC_UNUSED,
+                          const gchar *objectPath,
+                          gpointer userData,
+                          GVariant **outArgs,
+                          GUnixFDList **outFDs G_GNUC_UNUSED,
+                          GError **error)
+{
+    virtDBusConnect *connect = userData;
+    g_autoptr(virDomain) domain = NULL;
+    virDomainMemoryStatStruct stats[VIR_DOMAIN_MEMORY_STAT_NR];
+    gint nr_stats;
+    guint flags;
+    GVariant *gstats;
+
+    g_variant_get(inArgs, "(u)", &flags);
+
+    domain = virtDBusDomainGetVirDomain(connect, objectPath, error);
+    if (!domain)
+        return;
+
+    nr_stats = virDomainMemoryStats(domain, stats, VIR_DOMAIN_MEMORY_STAT_NR, flags);
+    if (nr_stats < 0)
+        return virtDBusUtilSetLastVirtError(error);
+
+    gstats = virtDBusDomainMemoryStatsToGVariant(stats, nr_stats, error);
+    if (!gstats) {
+        virtDBusUtilSetLastVirtError(error);
+        return;
+    }
+
+    *outArgs = g_variant_new_tuple(&gstats, 1);
+}
+
 static void
 virtDBusDomainReboot(GVariant *inArgs,
                      GUnixFDList *inFDs G_GNUC_UNUSED,
@@ -551,6 +622,7 @@ static virtDBusGDBusMethodTable virtDBusDomainMethodTable[] = {
     { "GetStats", virtDBusDomainGetStats },
     { "GetVcpus", virtDBusDomainGetVcpus },
     { "GetXMLDesc", virtDBusDomainGetXMLDesc },
+    { "MemoryStats", virtDBusDomainMemoryStats },
     { "Reboot", virtDBusDomainReboot },
     { "Reset", virtDBusDomainReset },
     { "Resume", virtDBusDomainResume },
-- 
2.15.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [dbus PATCH v3 03/20] Implement MemoryStats for Domain Interface
Posted by Pavel Hrdina 7 years, 1 month ago
On Fri, Apr 13, 2018 at 01:15:14PM +0200, Katerina Koukiou wrote:
> This method is not tested for now since the test driver
> doesn't support this API.
> 
> Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com>
> ---
>  data/org.libvirt.Domain.xml |  6 ++++
>  src/domain.c                | 72 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 78 insertions(+)
> 
> diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
> index df9fbf9..7174769 100644
> --- a/data/org.libvirt.Domain.xml
> +++ b/data/org.libvirt.Domain.xml
> @@ -69,6 +69,12 @@
>        <arg name="flags" type="u" direction="in"/>
>        <arg name="xml" type="s" direction="out"/>
>      </method>
> +    <method name="MemoryStats">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMemoryStats"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="stats" type="a{st}" direction="out"/>
> +    </method>
>      <method name="Reboot">
>        <annotation name="org.gtk.GDBus.DocString"
>          value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainReboot"/>
> diff --git a/src/domain.c b/src/domain.c
> index f775fd4..5f87572 100644
> --- a/src/domain.c
> +++ b/src/domain.c
> @@ -3,6 +3,42 @@
>  
>  #include <libvirt/libvirt.h>
>  
> +VIRT_DBUS_ENUM_DECL(virtDBusDomainMemoryStat)
> +VIRT_DBUS_ENUM_IMPL(virtDBusDomainMemoryStat,
> +                    VIR_DOMAIN_MEMORY_STAT_LAST,
> +                    "swap_in",
> +                    "swap_out",
> +                    "major_fault",
> +                    "minor_fault",
> +                    "unused",
> +                    "available",
> +                    "actual_baloon",
> +                    "rss",
> +                    "usable",
> +                    "last_update")

I was looking at libvirt-python code to get some inspiration how to
handle the error message later in this code and find out that the last
two memory stats "usable" and "last_update" were introduced in libvirt
2.1.0 but we currently require only 1.2.8.

You need to bump it in configure.ac.

> +
> +static GVariant *
> +virtDBusDomainMemoryStatsToGVariant(virDomainMemoryStatPtr stats,
> +                                    gint nr_stats,
> +                                    GError **error)
> +{
> +    GVariantBuilder builder;
> +
> +    g_variant_builder_init(&builder, G_VARIANT_TYPE("a{st}"));
> +
> +    for (gint i = 0; i < nr_stats; i++) {
> +        const gchar *memoryStat = virtDBusDomainMemoryStatTypeToString(stats[i].tag);
> +        if (!memoryStat) {
> +            g_set_error(error, VIRT_DBUS_ERROR, VIRT_DBUS_ERROR_LIBVIRT,
> +                        "Can't translate virDomainMemoryStatTags to string.");
> +            return NULL;
> +        }

Now that I think about it a little bit more, we should probably skip it
in case that we don't know how to translate it.  Sorry about the noise.
The reason is that if libvirt-dbus is used with newer libvirt that has
some new stats this API would stop working.

So instead of setting an error simple 'continue' should be good enough.
You can remove the '**error' parameter.

> +        g_variant_builder_add(&builder, "{st}", memoryStat, stats[i].val);
> +    }
> +
> +    return g_variant_builder_end(&builder);
> +}
> +
>  static virDomainPtr
>  virtDBusDomainGetVirDomain(virtDBusConnect *connect,
>                             const gchar *objectPath,
> @@ -398,6 +434,41 @@ virtDBusDomainGetXMLDesc(GVariant *inArgs,
>      *outArgs = g_variant_new("(s)", xml);
>  }
>  
> +static void
> +virtDBusDomainMemoryStats(GVariant *inArgs,
> +                          GUnixFDList *inFDs G_GNUC_UNUSED,
> +                          const gchar *objectPath,
> +                          gpointer userData,
> +                          GVariant **outArgs,
> +                          GUnixFDList **outFDs G_GNUC_UNUSED,
> +                          GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomain) domain = NULL;
> +    virDomainMemoryStatStruct stats[VIR_DOMAIN_MEMORY_STAT_NR];
> +    gint nr_stats;
> +    guint flags;
> +    GVariant *gstats;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domain = virtDBusDomainGetVirDomain(connect, objectPath, error);
> +    if (!domain)
> +        return;
> +
> +    nr_stats = virDomainMemoryStats(domain, stats, VIR_DOMAIN_MEMORY_STAT_NR, flags);
> +    if (nr_stats < 0)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    gstats = virtDBusDomainMemoryStatsToGVariant(stats, nr_stats, error);
> +    if (!gstats) {
> +        virtDBusUtilSetLastVirtError(error);
> +        return;
> +    }

The whole if part can be dropped now.

Pavel
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list