[libvirt] [libvirt-glib 3/4] config: Handle units in gvir_config_[gs]et_memory

Daniel P. Berrange berrange at redhat.com
Fri Sep 7 12:27:32 UTC 2012


On Tue, Sep 04, 2012 at 02:44:47PM +0200, Christophe Fergeau wrote:
> gvir_config_[gs]et_memory have an optional 'unit' attribute which
> indicates the unit used to express the memory size. This commit
> adds support for parsing this unit, and adjusting the returned
> value accordingly.
> ---
>  libvirt-gconfig/libvirt-gconfig-domain.c | 81 ++++++++++++++++++++++++++++++--
>  1 file changed, 76 insertions(+), 5 deletions(-)
> 
> diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
> index e6f22bd..dd4e232 100644
> --- a/libvirt-gconfig/libvirt-gconfig-domain.c
> +++ b/libvirt-gconfig/libvirt-gconfig-domain.c
> @@ -275,13 +275,70 @@ const char *gvir_config_domain_get_description(GVirConfigDomain *domain)
>   * @domain: a #GVirConfigDomain
>   * @description: (allow-none):
>   */
> -void gvir_config_domain_set_description(GVirConfigDomain *domain, const char *description)
> +void gvir_config_domain_set_description(GVirConfigDomain *domain,
> +                                        const char *description)
>  {
>      gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
>                                          "description", description);
>      g_object_notify(G_OBJECT(domain), "description");
>  }
>  
> +static void insert_base(GHashTable *unit_bases,
> +                        const char *unit,
> +                        guint64 unit_base)
> +{
> +    guint64 *base;
> +    base = g_slice_alloc(sizeof(*base));
> +    *base = unit_base;
> +    g_hash_table_insert(unit_bases, (gpointer)unit, base);
> +}
> +
> +static gpointer set_unit_bases(G_GNUC_UNUSED gpointer user_data)
> +{
> +    GHashTable *unit_bases;
> +
> +    unit_bases = g_hash_table_new(g_str_hash, g_str_equal);
> +
> +    insert_base(unit_bases, "b", 1);
> +    insert_base(unit_bases, "bytes", 1);
> +    insert_base(unit_bases, "KB", 1000);
> +    insert_base(unit_bases, "k", 1024);
> +    insert_base(unit_bases, "KiB", 1024);
> +    insert_base(unit_bases, "MB", 1000*1000);
> +    insert_base(unit_bases, "M", 1024*1024);
> +    insert_base(unit_bases, "MiB", 1024*1024);
> +    insert_base(unit_bases, "GB", 1000*1000*1000);
> +    insert_base(unit_bases, "G", 1024*1024*1024);
> +    insert_base(unit_bases, "GiB", 1024*1024*1024);
> +    insert_base(unit_bases, "TB", (guint64)1000*1000*1000*1000);
> +    insert_base(unit_bases, "T", (guint64)1024*1024*1024*1024);
> +    insert_base(unit_bases, "TiB", (guint64)1024*1024*1024*1024);
> +
> +    return unit_bases;
> +}
> +
> +static guint64 get_unit_base(const char *unit, guint64 default_base)
> +{
> +    static GOnce set_unit_bases_once = G_ONCE_INIT;
> +    GHashTable *unit_bases;
> +    guint64 *unit_base;
> +
> +    if (unit == NULL) {
> +        return default_base;
> +    }
> +
> +    unit_bases = g_once (&set_unit_bases_once, set_unit_bases, &unit_bases);
> +    g_return_val_if_fail (unit_bases != NULL, default_base);
> +
> +    unit_base = g_hash_table_lookup(unit_bases, unit);
> +    if (unit_base == NULL) {
> +        /* unknown unit, fall back to the default unit */
> +        g_return_val_if_reached(default_base);
> +    }
> +
> +    return *unit_base;
> +}
> +
>  /**
>   * gvir_config_domain_get_memory:
>   * @domain: a #GVirConfigDomain
> @@ -290,8 +347,17 @@ void gvir_config_domain_set_description(GVirConfigDomain *domain, const char *de
>   */
>  guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain)
>  {
> -    return gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
> -                                                      "memory");
> +    const char *unit;
> +    guint64 unit_base;
> +    guint64 memory;
> +
> +    unit = gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(domain), "memory", "unit");
> +    unit_base = get_unit_base(unit, 1024);
> +
> +    memory = gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
> +                                                        "memory");
> +
> +    return memory * unit_base / 1024;
>  }
>  
>  /**
> @@ -304,8 +370,13 @@ guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain)
>   */
>  void gvir_config_domain_set_memory(GVirConfigDomain *domain, guint64 memory)
>  {
> -    gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
> -                                               "memory", memory);
> +    GVirConfigObject *node;
> +
> +    node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain), "memory");
> +    gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(node), NULL, memory);
> +    gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(node),
> +                                     "unit", "KiB",
> +                                     NULL);
>      g_object_notify(G_OBJECT(domain), "memory");

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




More information about the libvir-list mailing list