Blame libvirt-gobject/libvirt-gobject-storage-vol.c

Packit a07778
/*
Packit a07778
 * libvirt-gobject-storage_vol.c: libvirt glib integration
Packit a07778
 *
Packit a07778
 * Copyright (C) 2008 Daniel P. Berrange
Packit a07778
 * Copyright (C) 2010-2011 Red Hat, Inc.
Packit a07778
 *
Packit a07778
 * This library is free software; you can redistribute it and/or
Packit a07778
 * modify it under the terms of the GNU Lesser General Public
Packit a07778
 * License as published by the Free Software Foundation; either
Packit a07778
 * version 2.1 of the License, or (at your option) any later version.
Packit a07778
 *
Packit a07778
 * This library is distributed in the hope that it will be useful,
Packit a07778
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a07778
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a07778
 * Lesser General Public License for more details.
Packit a07778
 *
Packit a07778
 * You should have received a copy of the GNU Lesser General Public
Packit a07778
 * License along with this library. If not, see
Packit a07778
 * <http://www.gnu.org/licenses/>.
Packit a07778
 *
Packit a07778
 * Author: Daniel P. Berrange <berrange@redhat.com>
Packit a07778
 */
Packit a07778
Packit a07778
#include <config.h>
Packit a07778
Packit a07778
#include <libvirt/virterror.h>
Packit a07778
#include <string.h>
Packit a07778
Packit a07778
#include "libvirt-glib/libvirt-glib.h"
Packit a07778
#include "libvirt-gobject/libvirt-gobject.h"
Packit a07778
#include "libvirt-gobject-compat.h"
Packit a07778
#include "libvirt-gobject-storage-pool-private.h"
Packit a07778
Packit a07778
#define GVIR_STORAGE_VOL_GET_PRIVATE(obj)                         \
Packit a07778
        (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_STORAGE_VOL, GVirStorageVolPrivate))
Packit a07778
Packit a07778
struct _GVirStorageVolPrivate
Packit a07778
{
Packit a07778
    virStorageVolPtr handle;
Packit a07778
Packit a07778
    GVirStoragePool *pool;
Packit a07778
};
Packit a07778
Packit a07778
G_DEFINE_TYPE_WITH_PRIVATE(GVirStorageVol, gvir_storage_vol, G_TYPE_OBJECT);
Packit a07778
Packit a07778
Packit a07778
enum {
Packit a07778
    PROP_0,
Packit a07778
    PROP_HANDLE,
Packit a07778
    PROP_POOL,
Packit a07778
};
Packit a07778
Packit a07778
Packit a07778
#define GVIR_STORAGE_VOL_ERROR gvir_storage_vol_error_quark()
Packit a07778
Packit a07778
Packit a07778
static GQuark
Packit a07778
gvir_storage_vol_error_quark(void)
Packit a07778
{
Packit a07778
    return g_quark_from_static_string("gvir-storage-vol");
Packit a07778
}
Packit a07778
Packit a07778
static void gvir_storage_vol_get_property(GObject *object,
Packit a07778
                                          guint prop_id,
Packit a07778
                                          GValue *value,
Packit a07778
                                          GParamSpec *pspec)
Packit a07778
{
Packit a07778
    GVirStorageVol *vol = GVIR_STORAGE_VOL(object);
Packit a07778
    GVirStorageVolPrivate *priv = vol->priv;
Packit a07778
Packit a07778
    switch (prop_id) {
Packit a07778
    case PROP_HANDLE:
Packit a07778
        g_value_set_boxed(value, priv->handle);
Packit a07778
        break;
Packit a07778
Packit a07778
    case PROP_POOL:
Packit a07778
        g_value_set_object(value, priv->pool);
Packit a07778
        break;
Packit a07778
Packit a07778
    default:
Packit a07778
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
Packit a07778
    }
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
static void gvir_storage_vol_set_property(GObject *object,
Packit a07778
                                          guint prop_id,
Packit a07778
                                          const GValue *value,
Packit a07778
                                          GParamSpec *pspec)
Packit a07778
{
Packit a07778
    GVirStorageVol *vol = GVIR_STORAGE_VOL(object);
Packit a07778
    GVirStorageVolPrivate *priv = vol->priv;
Packit a07778
Packit a07778
    switch (prop_id) {
Packit a07778
    case PROP_HANDLE:
Packit a07778
        if (priv->handle)
Packit a07778
            virStorageVolFree(priv->handle);
Packit a07778
        priv->handle = g_value_dup_boxed(value);
Packit a07778
        break;
Packit a07778
    case PROP_POOL:
Packit a07778
        priv->pool = g_value_get_object(value);
Packit a07778
        break;
Packit a07778
Packit a07778
    default:
Packit a07778
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
Packit a07778
    }
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
static void gvir_storage_vol_finalize(GObject *object)
Packit a07778
{
Packit a07778
    GVirStorageVol *vol = GVIR_STORAGE_VOL(object);
Packit a07778
    GVirStorageVolPrivate *priv = vol->priv;
Packit a07778
Packit a07778
    virStorageVolFree(priv->handle);
Packit a07778
Packit a07778
    G_OBJECT_CLASS(gvir_storage_vol_parent_class)->finalize(object);
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
static void gvir_storage_vol_class_init(GVirStorageVolClass *klass)
Packit a07778
{
Packit a07778
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit a07778
Packit a07778
    object_class->finalize = gvir_storage_vol_finalize;
Packit a07778
    object_class->get_property = gvir_storage_vol_get_property;
Packit a07778
    object_class->set_property = gvir_storage_vol_set_property;
Packit a07778
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_HANDLE,
Packit a07778
                                    g_param_spec_boxed("handle",
Packit a07778
                                                       "Handle",
Packit a07778
                                                       "The storage_vol handle",
Packit a07778
                                                       GVIR_TYPE_STORAGE_VOL_HANDLE,
Packit a07778
                                                       G_PARAM_READABLE |
Packit a07778
                                                       G_PARAM_WRITABLE |
Packit a07778
                                                       G_PARAM_CONSTRUCT_ONLY |
Packit a07778
                                                       G_PARAM_STATIC_STRINGS));
Packit a07778
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_POOL,
Packit a07778
                                    g_param_spec_object("pool",
Packit a07778
                                                        "Pool",
Packit a07778
                                                        "The containing storage pool",
Packit a07778
                                                        GVIR_TYPE_STORAGE_POOL,
Packit a07778
                                                        G_PARAM_READABLE |
Packit a07778
                                                        G_PARAM_WRITABLE |
Packit a07778
                                                        G_PARAM_CONSTRUCT_ONLY |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
static void gvir_storage_vol_init(GVirStorageVol *vol)
Packit a07778
{
Packit a07778
    vol->priv = GVIR_STORAGE_VOL_GET_PRIVATE(vol);
Packit a07778
}
Packit a07778
Packit a07778
typedef struct virStorageVol GVirStorageVolHandle;
Packit a07778
Packit a07778
static GVirStorageVolHandle*
Packit a07778
gvir_storage_vol_handle_copy(GVirStorageVolHandle *src)
Packit a07778
{
Packit a07778
    virStorageVolRef((virStorageVolPtr)src);
Packit a07778
    return src;
Packit a07778
}
Packit a07778
Packit a07778
static void
Packit a07778
gvir_storage_vol_handle_free(GVirStorageVolHandle *src)
Packit a07778
{
Packit a07778
    virStorageVolFree((virStorageVolPtr)src);
Packit a07778
}
Packit a07778
Packit a07778
G_DEFINE_BOXED_TYPE(GVirStorageVolHandle, gvir_storage_vol_handle,
Packit a07778
                    gvir_storage_vol_handle_copy, gvir_storage_vol_handle_free)
Packit a07778
Packit a07778
static GVirStorageVolInfo *
Packit a07778
gvir_storage_vol_info_copy(GVirStorageVolInfo *info)
Packit a07778
{
Packit a07778
    return g_slice_dup(GVirStorageVolInfo, info);
Packit a07778
}
Packit a07778
Packit a07778
static void
Packit a07778
gvir_storage_vol_info_free(GVirStorageVolInfo *info)
Packit a07778
{
Packit a07778
    g_slice_free(GVirStorageVolInfo, info);
Packit a07778
}
Packit a07778
Packit a07778
G_DEFINE_BOXED_TYPE(GVirStorageVolInfo, gvir_storage_vol_info,
Packit a07778
                    gvir_storage_vol_info_copy, gvir_storage_vol_info_free)
Packit a07778
Packit a07778
const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol)
Packit a07778
{
Packit a07778
    const char *name;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), NULL);
Packit a07778
Packit a07778
    if (!(name = virStorageVolGetName(vol->priv->handle))) {
Packit a07778
        gvir_warning("Failed to get storage_vol name on %p", vol->priv->handle);
Packit a07778
        return NULL;
Packit a07778
    }
Packit a07778
Packit a07778
    return name;
Packit a07778
}
Packit a07778
Packit a07778
const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error)
Packit a07778
{
Packit a07778
    const char *path;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), NULL);
Packit a07778
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
Packit a07778
Packit a07778
    if (!(path = virStorageVolGetPath(vol->priv->handle))) {
Packit a07778
        gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0,
Packit a07778
                       "Failed to get storage_vol path on %p",
Packit a07778
                       vol->priv->handle);
Packit a07778
        return NULL;
Packit a07778
    }
Packit a07778
Packit a07778
    return path;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_storage_vol_get_config:
Packit a07778
 * @vol: the storage_vol
Packit a07778
 * @flags: the flags
Packit a07778
 * @err: Place-holder for possible errors
Packit a07778
 *
Packit a07778
 * Returns: (transfer full): the config. The returned object should be
Packit a07778
 * unreffed with g_object_unref() when no longer needed.
Packit a07778
 */
Packit a07778
GVirConfigStorageVol *gvir_storage_vol_get_config(GVirStorageVol *vol,
Packit a07778
                                                  guint flags,
Packit a07778
                                                  GError **err)
Packit a07778
{
Packit a07778
    GVirStorageVolPrivate *priv;
Packit a07778
    gchar *xml;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), NULL);
Packit a07778
    g_return_val_if_fail(err == NULL || *err == NULL, NULL);
Packit a07778
Packit a07778
    priv = vol->priv;
Packit a07778
    if (!(xml = virStorageVolGetXMLDesc(priv->handle, flags))) {
Packit a07778
        gvir_set_error_literal(err, GVIR_STORAGE_VOL_ERROR,
Packit a07778
                               0,
Packit a07778
                               "Unable to get storage_vol XML config");
Packit a07778
        return NULL;
Packit a07778
    }
Packit a07778
Packit a07778
    GVirConfigStorageVol *conf = gvir_config_storage_vol_new_from_xml(xml, err);
Packit a07778
Packit a07778
    free(xml);
Packit a07778
    return conf;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_storage_vol_get_info:
Packit a07778
 * @vol: the storage_vol
Packit a07778
 * @err: Place-holder for possible errors
Packit a07778
 *
Packit a07778
 * Returns: (transfer full): the info. The returned object should be
Packit a07778
 * unreffed with g_object_unref() when no longer needed.
Packit a07778
 */
Packit a07778
GVirStorageVolInfo *gvir_storage_vol_get_info(GVirStorageVol *vol,
Packit a07778
                                              GError **err)
Packit a07778
{
Packit a07778
    GVirStorageVolPrivate *priv;
Packit a07778
    virStorageVolInfo info;
Packit a07778
    GVirStorageVolInfo *ret;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), NULL);
Packit a07778
    g_return_val_if_fail(err == NULL || *err == NULL, NULL);
Packit a07778
Packit a07778
    priv = vol->priv;
Packit a07778
    if (virStorageVolGetInfo(priv->handle, &info) < 0) {
Packit a07778
        if (err)
Packit a07778
            *err = gvir_error_new_literal(GVIR_STORAGE_VOL_ERROR,
Packit a07778
                                          0,
Packit a07778
                                          "Unable to get storage vol info");
Packit a07778
        return NULL;
Packit a07778
    }
Packit a07778
Packit a07778
    ret = g_slice_new(GVirStorageVolInfo);
Packit a07778
    ret->type = info.type;
Packit a07778
    ret->capacity = info.capacity;
Packit a07778
    ret->allocation = info.allocation;
Packit a07778
Packit a07778
    return ret;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_storage_vol_delete:
Packit a07778
 * @vol: the storage volume to delete
Packit a07778
 * @flags: the flags
Packit a07778
 * @err: Return location for errors, or NULL
Packit a07778
 *
Packit a07778
 * Deletes the storage volume @vol.
Packit a07778
 *
Packit a07778
 * Returns: %TRUE on success, %FALSE otherwise
Packit a07778
 */
Packit a07778
gboolean gvir_storage_vol_delete(GVirStorageVol *vol,
Packit a07778
                                 guint flags,
Packit a07778
                                 GError **err)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), FALSE);
Packit a07778
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
Packit a07778
Packit a07778
    gvir_storage_pool_delete_vol(vol->priv->pool, vol);
Packit a07778
Packit a07778
    if (virStorageVolDelete(vol->priv->handle, flags) < 0) {
Packit a07778
        gvir_set_error_literal(err,
Packit a07778
                               GVIR_STORAGE_VOL_ERROR,
Packit a07778
                               0,
Packit a07778
                               "Unable to delete storage volume");
Packit a07778
        return FALSE;
Packit a07778
    }
Packit a07778
Packit a07778
    return TRUE;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_storage_vol_resize:
Packit a07778
 * @vol: the storage volume to resize
Packit a07778
 * @capacity: the new capacity of the volume
Packit a07778
 * @flags: (type GVirStorageVolResizeFlags): the flags
Packit a07778
 * @err: Return location for errors, or NULL
Packit a07778
 *
Packit a07778
 * Changes the capacity of the storage volume @vol to @capacity.
Packit a07778
 *
Packit a07778
 * Returns: #TRUE success, #FALSE otherwise
Packit a07778
 */
Packit a07778
gboolean gvir_storage_vol_resize(GVirStorageVol *vol,
Packit a07778
                                 guint64 capacity,
Packit a07778
                                 guint flags,
Packit a07778
                                 GError **err)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), FALSE);
Packit a07778
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
Packit a07778
Packit a07778
    if (virStorageVolResize(vol->priv->handle, capacity, flags) < 0) {
Packit a07778
        gvir_set_error_literal(err,
Packit a07778
                               GVIR_STORAGE_VOL_ERROR,
Packit a07778
                               0,
Packit a07778
                               "Unable to resize volume storage");
Packit a07778
        return FALSE;
Packit a07778
    }
Packit a07778
Packit a07778
    return TRUE;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_storage_vol_download:
Packit a07778
 * @vol: the storage volume to download from
Packit a07778
 * @stream: stream to use as output
Packit a07778
 * @offset: position in @vol to start reading from
Packit a07778
 * @length: limit on amount of data to download, or 0 for downloading all data
Packit a07778
 * @flags: extra flags, not used yet, pass 0
Packit a07778
 *
Packit a07778
 * Returns: #TRUE of success, #FALSE otherwise
Packit a07778
 */
Packit a07778
gboolean gvir_storage_vol_download(GVirStorageVol *vol,
Packit a07778
                                   GVirStream *stream,
Packit a07778
                                   guint64 offset,
Packit a07778
                                   guint64 length,
Packit a07778
                                   guint flags G_GNUC_UNUSED,
Packit a07778
                                   GError **err)
Packit a07778
{
Packit a07778
    virStreamPtr stream_handle = NULL;
Packit a07778
    gboolean ret = FALSE;
Packit a07778
Packit a07778
    g_object_get(stream, "handle", &stream_handle, NULL);
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), FALSE);
Packit a07778
    g_return_val_if_fail(GVIR_IS_STREAM(stream), FALSE);
Packit a07778
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
Packit a07778
Packit a07778
    if (virStorageVolDownload(vol->priv->handle,
Packit a07778
                              stream_handle,
Packit a07778
                              offset,
Packit a07778
                              length,
Packit a07778
                              0) < 0) {
Packit a07778
        gvir_set_error_literal(err,
Packit a07778
                               GVIR_STORAGE_VOL_ERROR,
Packit a07778
                               0,
Packit a07778
                               "Unable to download volume storage");
Packit a07778
Packit a07778
        goto cleanup;
Packit a07778
    }
Packit a07778
Packit a07778
    ret = TRUE;
Packit a07778
cleanup:
Packit a07778
    if (stream_handle != NULL)
Packit a07778
        virStreamFree(stream_handle);
Packit a07778
    return ret;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_storage_vol_upload:
Packit a07778
 * @vol: the storage volume to upload
Packit a07778
 * @stream: stream to use as input
Packit a07778
 * @offset: position in @vol to start to write to
Packit a07778
 * @length: limit on amount of data to upload, or 0 for uploading all data
Packit a07778
 * @flags: the flags, not set yet, pass 0
Packit a07778
 *
Packit a07778
 * Returns: #TRUE of success, #FALSE otherwise
Packit a07778
 */
Packit a07778
gboolean gvir_storage_vol_upload(GVirStorageVol *vol,
Packit a07778
                                 GVirStream *stream,
Packit a07778
                                 guint64 offset,
Packit a07778
                                 guint64 length,
Packit a07778
                                 guint flags G_GNUC_UNUSED,
Packit a07778
                                 GError **err)
Packit a07778
{
Packit a07778
    virStreamPtr stream_handle = NULL;
Packit a07778
    gboolean ret = FALSE;
Packit a07778
Packit a07778
    g_object_get(stream, "handle", &stream_handle, NULL);
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_IS_STORAGE_VOL(vol), FALSE);
Packit a07778
    g_return_val_if_fail(GVIR_IS_STREAM(stream), FALSE);
Packit a07778
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
Packit a07778
Packit a07778
    if (virStorageVolUpload(vol->priv->handle,
Packit a07778
                            stream_handle,
Packit a07778
                            offset,
Packit a07778
                            length,
Packit a07778
                            0) < 0) {
Packit a07778
        gvir_set_error_literal(err,
Packit a07778
                               GVIR_STORAGE_VOL_ERROR,
Packit a07778
                               0,
Packit a07778
                               "Unable to upload to stream");
Packit a07778
Packit a07778
        goto cleanup;
Packit a07778
    }
Packit a07778
Packit a07778
    ret = TRUE;
Packit a07778
cleanup:
Packit a07778
    if (stream_handle != NULL)
Packit a07778
        virStreamFree(stream_handle);
Packit a07778
    return ret;
Packit a07778
}