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

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