/*
* ovirt-storage-domain.c: oVirt storage domain handling
*
* Copyright (C) 2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* .
*
* Author: Christophe Fergeau
*/
#include
#include "ovirt-enum-types.h"
#include "ovirt-storage-domain.h"
#include "govirt-private.h"
#define OVIRT_STORAGE_DOMAIN_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_STORAGE_DOMAIN, OvirtStorageDomainPrivate))
struct _OvirtStorageDomainPrivate {
OvirtCollection *files;
OvirtStorageDomainType type;
gboolean is_master;
guint64 available;
guint64 used;
guint64 committed;
OvirtStorageDomainFormatVersion version;
OvirtStorageDomainState state;
};
G_DEFINE_TYPE(OvirtStorageDomain, ovirt_storage_domain, OVIRT_TYPE_RESOURCE);
enum {
PROP_0,
PROP_STORAGE_TYPE,
PROP_MASTER,
PROP_AVAILABLE,
PROP_USED,
PROP_COMMITTED,
PROP_VERSION,
PROP_STATE
};
static gboolean
ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
RestXmlNode *node);
static void ovirt_storage_domain_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
OvirtStorageDomain *domain = OVIRT_STORAGE_DOMAIN(object);
switch (prop_id) {
case PROP_STORAGE_TYPE:
g_value_set_enum(value, domain->priv->type);
break;
case PROP_MASTER:
g_value_set_boolean(value, domain->priv->is_master);
break;
case PROP_AVAILABLE:
g_value_set_uint64(value, domain->priv->available);
break;
case PROP_USED:
g_value_set_uint64(value, domain->priv->used);
break;
case PROP_COMMITTED:
g_value_set_uint64(value, domain->priv->committed);
break;
case PROP_VERSION:
g_value_set_enum(value, domain->priv->version);
break;
case PROP_STATE:
g_value_set_enum(value, domain->priv->state);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void ovirt_storage_domain_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
OvirtStorageDomain *domain = OVIRT_STORAGE_DOMAIN(object);
switch (prop_id) {
case PROP_STORAGE_TYPE:
domain->priv->type = g_value_get_enum(value);
break;
case PROP_MASTER:
domain->priv->is_master = g_value_get_boolean(value);
break;
case PROP_AVAILABLE:
domain->priv->available = g_value_get_uint64(value);
break;
case PROP_USED:
domain->priv->used = g_value_get_uint64(value);
break;
case PROP_COMMITTED:
domain->priv->committed = g_value_get_uint64(value);
break;
case PROP_VERSION:
domain->priv->version = g_value_get_enum(value);
break;
case PROP_STATE:
domain->priv->state = g_value_get_enum(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
ovirt_storage_domain_dispose(GObject *obj)
{
OvirtStorageDomain *domain = OVIRT_STORAGE_DOMAIN(obj);
g_clear_object(&domain->priv->files);
G_OBJECT_CLASS(ovirt_storage_domain_parent_class)->dispose(obj);
}
static gboolean ovirt_storage_domain_init_from_xml(OvirtResource *resource,
RestXmlNode *node,
GError **error)
{
gboolean parsed_ok;
OvirtResourceClass *parent_class;
OvirtStorageDomain *domain;
domain = OVIRT_STORAGE_DOMAIN(resource);
parsed_ok = ovirt_storage_domain_refresh_from_xml(domain, node);
if (!parsed_ok) {
return FALSE;
}
parent_class = OVIRT_RESOURCE_CLASS(ovirt_storage_domain_parent_class);
return parent_class->init_from_xml(resource, node, error);
}
static void ovirt_storage_domain_class_init(OvirtStorageDomainClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
OvirtResourceClass *resource_class = OVIRT_RESOURCE_CLASS(klass);
GParamSpec *param_spec;
g_type_class_add_private(klass, sizeof(OvirtStorageDomainPrivate));
resource_class->init_from_xml = ovirt_storage_domain_init_from_xml;
object_class->dispose = ovirt_storage_domain_dispose;
object_class->get_property = ovirt_storage_domain_get_property;
object_class->set_property = ovirt_storage_domain_set_property;
param_spec = g_param_spec_enum("type",
"Storage Type",
"Type of the storage domain",
OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
OVIRT_STORAGE_DOMAIN_TYPE_DATA,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_STORAGE_TYPE,
param_spec);
param_spec = g_param_spec_boolean("master",
"Master Storage Domain?",
"Indicates whether the storage domain is a master on not",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_MASTER,
param_spec);
param_spec = g_param_spec_uint64("available",
"Space available",
"Space available in the storage domain in bytes",
0,
G_MAXUINT64,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_AVAILABLE,
param_spec);
param_spec = g_param_spec_uint64("used",
"Space used",
"Space used in the storage domain in bytes",
0,
G_MAXUINT64,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_USED,
param_spec);
param_spec = g_param_spec_uint64("committed",
"Space committed",
"Space committed in the storage domain in bytes",
0,
G_MAXUINT64,
0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_COMMITTED,
param_spec);
param_spec = g_param_spec_enum("version",
"Storage Format Version",
"Storage Format Version of the storage domain",
OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
OVIRT_STORAGE_DOMAIN_FORMAT_VERSION_V1,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_VERSION,
param_spec);
param_spec = g_param_spec_enum("state",
"Storage Domain State",
"State of the storage domain",
OVIRT_TYPE_STORAGE_DOMAIN_STATE,
OVIRT_STORAGE_DOMAIN_STATE_UNKNOWN,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property(object_class,
PROP_STATE,
param_spec);
}
static void ovirt_storage_domain_init(OvirtStorageDomain *domain)
{
domain->priv = OVIRT_STORAGE_DOMAIN_GET_PRIVATE(domain);
}
G_GNUC_INTERNAL
OvirtStorageDomain *ovirt_storage_domain_new_from_xml(RestXmlNode *node,
GError **error)
{
GObject *domain;
domain = g_initable_new(OVIRT_TYPE_STORAGE_DOMAIN, NULL, error,
"xml-node", node, NULL);
return OVIRT_STORAGE_DOMAIN(domain);
}
OvirtStorageDomain *ovirt_storage_domain_new(void)
{
GObject *domain;
domain = g_initable_new(OVIRT_TYPE_STORAGE_DOMAIN, NULL, NULL, NULL);
return OVIRT_STORAGE_DOMAIN(domain);
}
typedef struct {
const char *xml_node;
GType type;
const char *prop_name;
} OvirtXmlElement;
static gboolean
ovirt_resource_parse_xml(OvirtResource *resource,
RestXmlNode *node,
OvirtXmlElement *elements)
{
g_return_val_if_fail(OVIRT_IS_RESOURCE(resource), FALSE);
g_return_val_if_fail(elements != NULL, FALSE);
for (;elements->xml_node != NULL; elements++) {
const char *value_str;
GValue value = { 0, };
value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_node);
if (value_str == NULL) {
continue;
}
g_value_init(&value, elements->type);
if (G_TYPE_IS_ENUM(elements->type)) {
int enum_value;
enum_value = ovirt_utils_genum_get_value(elements->type,
value_str, 0);
g_value_set_enum(&value, enum_value);
} else if (elements->type == G_TYPE_BOOLEAN) {
gboolean bool_value;
bool_value = ovirt_utils_boolean_from_string(value_str);
g_value_set_boolean(&value, bool_value);
} else if (elements->type == G_TYPE_UINT64) {
guint64 int64_value;
int64_value = g_ascii_strtoull(value_str, NULL, 0);
g_value_set_uint64(&value, int64_value);
} else if (g_type_is_a(elements->type, OVIRT_TYPE_RESOURCE)) {
GObject *resource_value;
resource_value = g_initable_new(elements->type, NULL, NULL,
"xml-node", node, NULL);
g_value_set_object(&value, resource_value);
}
g_object_set_property(G_OBJECT(resource), elements->prop_name, &value);
g_value_unset(&value);
}
return TRUE;
}
static gboolean
ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
RestXmlNode *node)
{
OvirtXmlElement storage_domain_elements[] = {
{ "type", OVIRT_TYPE_STORAGE_DOMAIN_TYPE, "type" },
{ "master", G_TYPE_BOOLEAN, "master" },
{ "available", G_TYPE_UINT64, "available" },
{ "used", G_TYPE_UINT64, "used" },
{ "committed", G_TYPE_UINT64, "committed" },
{ "storage_format", OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION, "version" },
{ "status/state", OVIRT_TYPE_STORAGE_DOMAIN_STATE, "state" },
{ NULL, G_TYPE_INVALID, NULL }
};
return ovirt_resource_parse_xml(OVIRT_RESOURCE(domain), node, storage_domain_elements);
}
/**
* ovirt_storage_domain_get_files:
* @domain: a #OvirtStorageDomain
*
* Gets a #OvirtCollection representing the list of remote files from a
* storage domain object. This method does not initiate any network
* activity, the remote file list must be then be fetched using
* ovirt_collection_fetch() or ovirt_collection_fetch_async().
*
* Return value: (transfer none): a #OvirtCollection representing the list
* of files associated with @domain.
*/
OvirtCollection *ovirt_storage_domain_get_files(OvirtStorageDomain *domain)
{
const char *href;
g_return_val_if_fail(OVIRT_IS_STORAGE_DOMAIN(domain), NULL);
if (domain->priv->files != NULL)
return domain->priv->files;
href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(domain), "files");
if (href == NULL)
return NULL;
domain->priv->files = ovirt_collection_new(href, "files",
OVIRT_TYPE_RESOURCE,
"file");
return domain->priv->files;
}