Blame libvirt-gconfig/libvirt-gconfig-domain.c

Packit a07778
/*
Packit a07778
 * libvirt-gconfig-domain.c: libvirt domain configuration
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-gconfig/libvirt-gconfig.h"
Packit a07778
#include "libvirt-gconfig/libvirt-gconfig-private.h"
Packit a07778
Packit a07778
#define GVIR_CONFIG_DOMAIN_GET_PRIVATE(obj)                         \
Packit a07778
        (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN, GVirConfigDomainPrivate))
Packit a07778
Packit a07778
struct _GVirConfigDomainPrivate
Packit a07778
{
Packit a07778
    gboolean unused;
Packit a07778
};
Packit a07778
Packit a07778
G_DEFINE_TYPE_WITH_PRIVATE(GVirConfigDomain, gvir_config_domain, GVIR_CONFIG_TYPE_OBJECT);
Packit a07778
Packit a07778
enum {
Packit a07778
    PROP_0,
Packit a07778
    PROP_NAME,
Packit a07778
    PROP_UUID,
Packit a07778
    PROP_TITLE,
Packit a07778
    PROP_DESCRIPTION,
Packit a07778
    PROP_MEMORY,
Packit a07778
    PROP_VCPU,
Packit a07778
    PROP_FEATURES,
Packit a07778
    PROP_CURRENT_MEMORY
Packit a07778
};
Packit a07778
Packit a07778
static void gvir_config_domain_get_property(GObject *object,
Packit a07778
                                            guint prop_id,
Packit a07778
                                            GValue *value,
Packit a07778
                                            GParamSpec *pspec)
Packit a07778
{
Packit a07778
    GVirConfigDomain *domain = GVIR_CONFIG_DOMAIN(object);
Packit a07778
Packit a07778
    switch (prop_id) {
Packit a07778
    case PROP_NAME:
Packit a07778
        g_value_set_string(value, gvir_config_domain_get_name(domain));
Packit a07778
        break;
Packit a07778
    case PROP_UUID:
Packit a07778
        g_value_set_string(value, gvir_config_domain_get_uuid(domain));
Packit a07778
        break;
Packit a07778
    case PROP_TITLE:
Packit a07778
        g_value_set_string(value, gvir_config_domain_get_title(domain));
Packit a07778
        break;
Packit a07778
    case PROP_DESCRIPTION:
Packit a07778
        g_value_set_string(value, gvir_config_domain_get_description(domain));
Packit a07778
        break;
Packit a07778
    case PROP_MEMORY:
Packit a07778
        g_value_set_uint64(value, gvir_config_domain_get_memory(domain));
Packit a07778
        break;
Packit a07778
    case PROP_CURRENT_MEMORY:
Packit a07778
        g_value_set_uint64(value, gvir_config_domain_get_current_memory(domain));
Packit a07778
        break;
Packit a07778
    case PROP_VCPU:
Packit a07778
        g_value_set_uint64(value, gvir_config_domain_get_vcpus(domain));
Packit a07778
        break;
Packit a07778
    case PROP_FEATURES:
Packit a07778
        g_value_take_boxed(value, gvir_config_domain_get_features(domain));
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
static void gvir_config_domain_set_property(GObject *object,
Packit a07778
                                            guint prop_id,
Packit a07778
                                            const GValue *value,
Packit a07778
                                            GParamSpec *pspec)
Packit a07778
{
Packit a07778
    GVirConfigDomain *domain = GVIR_CONFIG_DOMAIN(object);
Packit a07778
Packit a07778
    switch (prop_id) {
Packit a07778
    case PROP_NAME:
Packit a07778
        gvir_config_domain_set_name(domain, g_value_get_string(value));
Packit a07778
        break;
Packit a07778
    case PROP_UUID:
Packit a07778
        gvir_config_domain_set_uuid(domain, g_value_get_string(value));
Packit a07778
        break;
Packit a07778
    case PROP_TITLE:
Packit a07778
        gvir_config_domain_set_title(domain, g_value_get_string(value));
Packit a07778
        break;
Packit a07778
    case PROP_DESCRIPTION:
Packit a07778
        gvir_config_domain_set_description(domain, g_value_get_string(value));
Packit a07778
        break;
Packit a07778
    case PROP_MEMORY:
Packit a07778
        gvir_config_domain_set_memory(domain, g_value_get_uint64(value));
Packit a07778
        break;
Packit a07778
    case PROP_CURRENT_MEMORY:
Packit a07778
        gvir_config_domain_set_current_memory(domain, g_value_get_uint64(value));
Packit a07778
        break;
Packit a07778
    case PROP_VCPU:
Packit a07778
        gvir_config_domain_set_vcpus(domain, g_value_get_uint64(value));
Packit a07778
        break;
Packit a07778
    case PROP_FEATURES:
Packit a07778
        gvir_config_domain_set_features(domain, g_value_get_boxed(value));
Packit a07778
        break;
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_config_domain_class_init(GVirConfigDomainClass *klass)
Packit a07778
{
Packit a07778
    GObjectClass *object_class = G_OBJECT_CLASS(klass);
Packit a07778
Packit a07778
    object_class->get_property = gvir_config_domain_get_property;
Packit a07778
    object_class->set_property = gvir_config_domain_set_property;
Packit a07778
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_NAME,
Packit a07778
                                    g_param_spec_string("name",
Packit a07778
                                                        "Name",
Packit a07778
                                                        "Domain Name",
Packit a07778
                                                        NULL,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_UUID,
Packit a07778
                                    g_param_spec_string("uuid",
Packit a07778
                                                        "UUID",
Packit a07778
                                                        "Domain UUID",
Packit a07778
                                                        NULL,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_TITLE,
Packit a07778
                                    g_param_spec_string("title",
Packit a07778
                                                        "Title",
Packit a07778
                                                        "A short description - title - of the domain",
Packit a07778
                                                        NULL,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_DESCRIPTION,
Packit a07778
                                    g_param_spec_string("description",
Packit a07778
                                                        "Description",
Packit a07778
                                                        "Some human readable description (could be anything).",
Packit a07778
                                                        NULL,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_MEMORY,
Packit a07778
                                    g_param_spec_uint64("memory",
Packit a07778
                                                        "Memory",
Packit a07778
                                                        "Maximum Guest Memory (in kilobytes)",
Packit a07778
                                                        0, G_MAXUINT64,
Packit a07778
                                                        0,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_CURRENT_MEMORY,
Packit a07778
                                    g_param_spec_uint64("current-memory",
Packit a07778
                                                        "Current memory",
Packit a07778
                                                        "Current Guest Memory (in kilobytes)",
Packit a07778
                                                        0, G_MAXUINT64,
Packit a07778
                                                        0,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_VCPU,
Packit a07778
                                    g_param_spec_uint64("vcpu",
Packit a07778
                                                        "Virtual CPUs",
Packit a07778
                                                        "Maximum Number of Guest Virtual CPUs",
Packit a07778
                                                        0, G_MAXUINT64,
Packit a07778
                                                        1,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
    g_object_class_install_property(object_class,
Packit a07778
                                    PROP_FEATURES,
Packit a07778
                                    g_param_spec_boxed("features",
Packit a07778
                                                        "Features",
Packit a07778
                                                        "Hypervisor Features",
Packit a07778
                                                        G_TYPE_STRV,
Packit a07778
                                                        G_PARAM_READWRITE |
Packit a07778
                                                        G_PARAM_STATIC_STRINGS));
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
static void gvir_config_domain_init(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    domain->priv = GVIR_CONFIG_DOMAIN_GET_PRIVATE(domain);
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
GVirConfigDomain *gvir_config_domain_new_from_xml(const gchar *xml,
Packit a07778
                                                  GError **error)
Packit a07778
{
Packit a07778
    GVirConfigObject *object;
Packit a07778
Packit a07778
    object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN,
Packit a07778
                                             "domain",
Packit a07778
                                             DATADIR "/libvirt/schemas/domain.rng",
Packit a07778
                                             xml, error);
Packit a07778
    return GVIR_CONFIG_DOMAIN(object);
Packit a07778
}
Packit a07778
Packit a07778
GVirConfigDomain *gvir_config_domain_new(void)
Packit a07778
{
Packit a07778
    GVirConfigObject *object;
Packit a07778
Packit a07778
    object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN,
Packit a07778
                                    "domain",
Packit a07778
                                    DATADIR "/libvirt/schemas/domain.rng");
Packit a07778
    return GVIR_CONFIG_DOMAIN(object);
Packit a07778
}
Packit a07778
Packit a07778
GVirConfigDomainVirtType gvir_config_domain_get_virt_type(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain),
Packit a07778
                         GVIR_CONFIG_DOMAIN_VIRT_QEMU);
Packit a07778
Packit a07778
    return gvir_config_object_get_attribute_genum
Packit a07778
                                (GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                 NULL,
Packit a07778
                                 "type",
Packit a07778
                                 GVIR_CONFIG_TYPE_DOMAIN_VIRT_TYPE,
Packit a07778
                                 GVIR_CONFIG_DOMAIN_VIRT_QEMU);
Packit a07778
}
Packit a07778
Packit a07778
void gvir_config_domain_set_virt_type(GVirConfigDomain *domain, GVirConfigDomainVirtType type)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                               "type",
Packit a07778
                                               GVIR_CONFIG_TYPE_DOMAIN_VIRT_TYPE,
Packit a07778
                                               type, NULL);
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
const char *gvir_config_domain_get_name(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                               "name");
Packit a07778
}
Packit a07778
Packit a07778
const char *gvir_config_domain_get_uuid(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                               "uuid");
Packit a07778
}
Packit a07778
Packit a07778
const char *gvir_config_domain_get_title(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                               "title");
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_name:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @name: (allow-none):
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_name(GVirConfigDomain *domain, const char *name)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                        "name", name);
Packit a07778
    g_object_notify(G_OBJECT(domain), "name");
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_uuid:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @uuid: (allow-none):
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_uuid(GVirConfigDomain *domain, const char *uuid)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                        "uuid", uuid);
Packit a07778
    g_object_notify(G_OBJECT(domain), "uuid");
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_title:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @title: (allow-none): title of the domain
Packit a07778
 *
Packit a07778
 * Sets the title of the domain. This is an optional short textual description of the domain. Passing a NULL @title
Packit a07778
 * unsets the current domain title.
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_title(GVirConfigDomain *domain, const char *title)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                        "title", title);
Packit a07778
    g_object_notify(G_OBJECT(domain), "title");
Packit a07778
}
Packit a07778
Packit a07778
const char *gvir_config_domain_get_description(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                               "description");
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_description:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @description: (allow-none):
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_description(GVirConfigDomain *domain,
Packit a07778
                                        const char *description)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                        "description", description);
Packit a07778
    g_object_notify(G_OBJECT(domain), "description");
Packit a07778
}
Packit a07778
Packit a07778
static void insert_base(GHashTable *unit_bases,
Packit a07778
                        const char *unit,
Packit a07778
                        guint64 unit_base)
Packit a07778
{
Packit a07778
    guint64 *base;
Packit a07778
    base = g_slice_alloc(sizeof(*base));
Packit a07778
    *base = unit_base;
Packit a07778
    g_hash_table_insert(unit_bases, (gpointer)unit, base);
Packit a07778
}
Packit a07778
Packit a07778
static gpointer set_unit_bases(G_GNUC_UNUSED gpointer user_data)
Packit a07778
{
Packit a07778
    GHashTable *unit_bases;
Packit a07778
Packit a07778
    unit_bases = g_hash_table_new(g_str_hash, g_str_equal);
Packit a07778
Packit a07778
    insert_base(unit_bases, "b", 1);
Packit a07778
    insert_base(unit_bases, "bytes", 1);
Packit a07778
    insert_base(unit_bases, "KB", 1000);
Packit a07778
    insert_base(unit_bases, "k", 1024);
Packit a07778
    insert_base(unit_bases, "KiB", 1024);
Packit a07778
    insert_base(unit_bases, "MB", 1000*1000);
Packit a07778
    insert_base(unit_bases, "M", 1024*1024);
Packit a07778
    insert_base(unit_bases, "MiB", 1024*1024);
Packit a07778
    insert_base(unit_bases, "GB", 1000*1000*1000);
Packit a07778
    insert_base(unit_bases, "G", 1024*1024*1024);
Packit a07778
    insert_base(unit_bases, "GiB", 1024*1024*1024);
Packit a07778
    insert_base(unit_bases, "TB", (guint64)1000*1000*1000*1000);
Packit a07778
    insert_base(unit_bases, "T", (guint64)1024*1024*1024*1024);
Packit a07778
    insert_base(unit_bases, "TiB", (guint64)1024*1024*1024*1024);
Packit a07778
Packit a07778
    return unit_bases;
Packit a07778
}
Packit a07778
Packit a07778
static guint64 get_unit_base(const char *unit, guint64 default_base)
Packit a07778
{
Packit a07778
    static GOnce set_unit_bases_once = G_ONCE_INIT;
Packit a07778
    GHashTable *unit_bases;
Packit a07778
    guint64 *unit_base;
Packit a07778
Packit a07778
    if (unit == NULL) {
Packit a07778
        return default_base;
Packit a07778
    }
Packit a07778
Packit a07778
    unit_bases = g_once (&set_unit_bases_once, set_unit_bases, &unit_bases);
Packit a07778
    g_return_val_if_fail (unit_bases != NULL, default_base);
Packit a07778
Packit a07778
    unit_base = g_hash_table_lookup(unit_bases, unit);
Packit a07778
    if (unit_base == NULL) {
Packit a07778
        /* unknown unit, fall back to the default unit */
Packit a07778
        g_return_val_if_reached(default_base);
Packit a07778
    }
Packit a07778
Packit a07778
    return *unit_base;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_memory:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Returns: maximum amount of RAM in kilobytes (i.e. blocks of 1024 bytes).
Packit a07778
 */
Packit a07778
guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    const char *unit;
Packit a07778
    guint64 unit_base;
Packit a07778
    guint64 memory;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), 0);
Packit a07778
Packit a07778
    unit = gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(domain), "memory", "unit");
Packit a07778
    unit_base = get_unit_base(unit, 1024);
Packit a07778
Packit a07778
    memory = gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                        "memory");
Packit a07778
Packit a07778
    return memory * unit_base / 1024;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_current_memory:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Returns: current amount of RAM in kilobytes (i.e. blocks of 1024 bytes).
Packit a07778
 */
Packit a07778
guint64 gvir_config_domain_get_current_memory(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    const char *unit;
Packit a07778
    guint64 unit_base;
Packit a07778
    guint64 memory;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), 0);
Packit a07778
Packit a07778
    unit = gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(domain), "currentMemory", "unit");
Packit a07778
    unit_base = get_unit_base(unit, 1024);
Packit a07778
Packit a07778
    memory = gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                        "currentMemory");
Packit a07778
Packit a07778
    return memory * unit_base / 1024;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_memory:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @memory: The maximum amount of RAM in kilobytes.
Packit a07778
 *
Packit a07778
 * Sets the maximum amount of RAM allocated to @domain in kilobytes (i.e.
Packit a07778
 * blocks of 1024 bytes).
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_memory(GVirConfigDomain *domain, guint64 memory)
Packit a07778
{
Packit a07778
    GVirConfigObject *node;
Packit a07778
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain), "memory");
Packit a07778
    gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(node), NULL, memory);
Packit a07778
    gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(node),
Packit a07778
                                     "unit", "KiB",
Packit a07778
                                     NULL);
Packit a07778
    g_object_unref(G_OBJECT(node));
Packit a07778
    g_object_notify(G_OBJECT(domain), "memory");
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_current_memory:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @memory: The current amount of RAM in kilobytes.
Packit a07778
 *
Packit a07778
 * Sets the current amount of RAM allocated to @domain in kilobytes (i.e.
Packit a07778
 * blocks of 1024 bytes). This can be set to less than the maximum domain
Packit a07778
 * memory to allow to balloon the guest memory on the fly. Be aware that
Packit a07778
 * libvirt will set it automatically if it's not explictly set, which means
Packit a07778
 * you may need to set this value in addition to 'memory' if you want to
Packit a07778
 * change the available domain memory after creation.
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_current_memory(GVirConfigDomain *domain,
Packit a07778
                                           guint64 memory)
Packit a07778
{
Packit a07778
    GVirConfigObject *node;
Packit a07778
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain), "currentMemory");
Packit a07778
    gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(node), NULL, memory);
Packit a07778
    gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(node),
Packit a07778
                                     "unit", "KiB",
Packit a07778
                                     NULL);
Packit a07778
    g_object_unref(G_OBJECT(node));
Packit a07778
    g_object_notify(G_OBJECT(domain), "current-memory");
Packit a07778
}
Packit a07778
Packit a07778
guint64 gvir_config_domain_get_vcpus(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    return gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                      "vcpu");
Packit a07778
}
Packit a07778
Packit a07778
void gvir_config_domain_set_vcpus(GVirConfigDomain *domain, guint64 vcpu_count)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                               "vcpu", vcpu_count);
Packit a07778
    g_object_notify(G_OBJECT(domain), "vcpu");
Packit a07778
}
Packit a07778
Packit a07778
static gboolean add_feature(xmlNodePtr node, gpointer opaque)
Packit a07778
{
Packit a07778
    GPtrArray *features;
Packit a07778
    g_return_val_if_fail(opaque != NULL, FALSE);
Packit a07778
Packit a07778
    features = (GPtrArray *)opaque;
Packit a07778
Packit a07778
    g_ptr_array_add(features, g_strdup((char *)node->name));
Packit a07778
Packit a07778
    return TRUE;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_features:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Returns: (transfer full): The returned list should be freed with
Packit a07778
 * g_strfreev() when no longer needed.
Packit a07778
Packit a07778
 */
Packit a07778
GStrv gvir_config_domain_get_features(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    GPtrArray *features;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    features = g_ptr_array_new();
Packit a07778
    gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "features",
Packit a07778
                                     add_feature, features);
Packit a07778
    g_ptr_array_add(features, NULL);
Packit a07778
Packit a07778
    return (GStrv)g_ptr_array_free(features, FALSE);
Packit a07778
}
Packit a07778
Packit a07778
void gvir_config_domain_set_features(GVirConfigDomain *domain,
Packit a07778
                                     const GStrv features)
Packit a07778
{
Packit a07778
    GVirConfigObject *features_node;
Packit a07778
    GStrv it;
Packit a07778
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    features_node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                     "features");
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_OBJECT(features_node));
Packit a07778
    for (it = features; *it != NULL; it++) {
Packit a07778
        GVirConfigObject *feature;
Packit a07778
        feature = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(features_node),
Packit a07778
                                                   *it);
Packit a07778
        g_object_unref(G_OBJECT(feature));
Packit a07778
    }
Packit a07778
    g_object_unref(G_OBJECT(features_node));
Packit a07778
    g_object_notify(G_OBJECT(domain), "features");
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_clock:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Gets the clock configuration of @domain
Packit a07778
 *
Packit a07778
 * Returns: (transfer full): A #GVirConfigDomainClock. The returned
Packit a07778
 * object should be unreffed with g_object_unref() when no longer needed.
Packit a07778
 */
Packit a07778
GVirConfigDomainClock *gvir_config_domain_get_clock(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    GVirConfigObject *object;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                    "clock",
Packit a07778
                                                    GVIR_CONFIG_TYPE_DOMAIN_CLOCK);
Packit a07778
Packit a07778
    return GVIR_CONFIG_DOMAIN_CLOCK(object);
Packit a07778
}
Packit a07778
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_clock:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @klock: (allow-none):
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_clock(GVirConfigDomain *domain,
Packit a07778
                                  GVirConfigDomainClock *klock)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail(klock == NULL || GVIR_CONFIG_IS_DOMAIN_CLOCK(klock));
Packit a07778
Packit a07778
    gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                      "clock",
Packit a07778
                                      GVIR_CONFIG_OBJECT(klock));
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_os:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Gets the operating system configuration of @domain
Packit a07778
 *
Packit a07778
 * Returns: (transfer full): A #GVirConfigDomainOs. The returned
Packit a07778
 * object should be unreffed with g_object_unref() when no longer needed.
Packit a07778
 */
Packit a07778
GVirConfigDomainOs *gvir_config_domain_get_os(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    GVirConfigObject *object;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                    "os",
Packit a07778
                                                    GVIR_CONFIG_TYPE_DOMAIN_OS);
Packit a07778
Packit a07778
    return GVIR_CONFIG_DOMAIN_OS(object);
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_os:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @os: (allow-none): the os configuration to set
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_os(GVirConfigDomain *domain,
Packit a07778
                               GVirConfigDomainOs *os)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail(os == NULL || GVIR_CONFIG_IS_DOMAIN_OS(os));
Packit a07778
Packit a07778
    gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                      "os",
Packit a07778
                                      GVIR_CONFIG_OBJECT(os));
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_seclabel:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @seclabel: (allow-none): the security label configuration to set
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_seclabel(GVirConfigDomain *domain,
Packit a07778
                                     GVirConfigDomainSeclabel *seclabel)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail(seclabel == NULL ||
Packit a07778
                     GVIR_CONFIG_IS_DOMAIN_SECLABEL(seclabel));
Packit a07778
Packit a07778
    gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                      "seclabel",
Packit a07778
                                      GVIR_CONFIG_OBJECT(seclabel));
Packit a07778
}
Packit a07778
Packit a07778
void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain,
Packit a07778
                                      GVirConfigDomainLifecycleEvent event,
Packit a07778
                                      GVirConfigDomainLifecycleAction action)
Packit a07778
{
Packit a07778
    const char *event_str;
Packit a07778
    const char *action_str;
Packit a07778
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail((event == GVIR_CONFIG_DOMAIN_LIFECYCLE_ON_CRASH) ||
Packit a07778
                     ((action != GVIR_CONFIG_DOMAIN_LIFECYCLE_COREDUMP_DESTROY) &&
Packit a07778
                      (action != GVIR_CONFIG_DOMAIN_LIFECYCLE_COREDUMP_RESTART)));
Packit a07778
Packit a07778
    event_str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_LIFECYCLE_EVENT, event);
Packit a07778
    g_return_if_fail(event_str != NULL);
Packit a07778
    action_str = gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_LIFECYCLE_ACTION, action);
Packit a07778
    g_return_if_fail(action_str != NULL);
Packit a07778
Packit a07778
    gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                        event_str, action_str);
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_devices:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @devices: (in) (element-type LibvirtGConfig.DomainDevice):
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_devices(GVirConfigDomain *domain,
Packit a07778
                                    GList *devices)
Packit a07778
{
Packit a07778
    GVirConfigObject *devices_node;
Packit a07778
    GList *it;
Packit a07778
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
Packit a07778
    if (devices == NULL) {
Packit a07778
        gvir_config_object_delete_children(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                           "devices",
Packit a07778
                                           NULL);
Packit a07778
        return;
Packit a07778
    }
Packit a07778
    devices_node = gvir_config_object_new(GVIR_CONFIG_TYPE_OBJECT,
Packit a07778
                                          "devices", NULL);
Packit a07778
Packit a07778
    for (it = devices; it != NULL; it = it->next) {
Packit a07778
        if (!GVIR_CONFIG_IS_DOMAIN_DEVICE(it->data)) {
Packit a07778
            g_warn_if_reached();
Packit a07778
            continue;
Packit a07778
        }
Packit a07778
        gvir_config_object_attach_add(devices_node,
Packit a07778
                                      GVIR_CONFIG_OBJECT(it->data));
Packit a07778
    }
Packit a07778
Packit a07778
    gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                      "devices",
Packit a07778
                                      devices_node);
Packit a07778
    g_object_unref(G_OBJECT(devices_node));
Packit a07778
}
Packit a07778
Packit a07778
void gvir_config_domain_add_device(GVirConfigDomain *domain,
Packit a07778
                                   GVirConfigDomainDevice *device)
Packit a07778
{
Packit a07778
    GVirConfigObject *devices_node;
Packit a07778
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DEVICE(device));
Packit a07778
Packit a07778
    devices_node = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                "devices");
Packit a07778
Packit a07778
    gvir_config_object_attach_add(devices_node, GVIR_CONFIG_OBJECT(device));
Packit a07778
    g_object_unref(G_OBJECT(devices_node));
Packit a07778
}
Packit a07778
Packit a07778
struct GetDeviceData {
Packit a07778
    GVirConfigXmlDoc *doc;
Packit a07778
    GList *devices;
Packit a07778
};
Packit a07778
Packit a07778
static gboolean add_device(xmlNodePtr node, gpointer opaque)
Packit a07778
{
Packit a07778
    struct GetDeviceData* data = (struct GetDeviceData*)opaque;
Packit a07778
    GVirConfigDomainDevice *device;
Packit a07778
Packit a07778
    device = gvir_config_domain_device_new_from_tree(data->doc, node);
Packit a07778
    if (device != NULL)
Packit a07778
        data->devices = g_list_append(data->devices, device);
Packit a07778
    else
Packit a07778
        g_debug("Failed to parse %s node", node->name);
Packit a07778
Packit a07778
    return TRUE;
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_devices:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Gets the list of devices attached to @domain.  The returned list should
Packit a07778
 * be freed with g_list_free(), after its elements have been unreffed with
Packit a07778
 * g_object_unref().
Packit a07778
 *
Packit a07778
 * Returns: (element-type LibvirtGConfig.DomainDevice) (transfer full):
Packit a07778
 * a newly allocated #GList of #GVirConfigDomainDevice.
Packit a07778
 */
Packit a07778
GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    struct GetDeviceData data;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    g_object_get(G_OBJECT(domain), "doc", &data.doc, NULL);
Packit a07778
    data.devices = NULL;
Packit a07778
    gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "devices",
Packit a07778
                                     add_device, &data);
Packit a07778
    if (data.doc != NULL) {
Packit a07778
        g_object_unref(G_OBJECT(data.doc));
Packit a07778
    }
Packit a07778
Packit a07778
    return data.devices;
Packit a07778
}
Packit a07778
Packit a07778
static gboolean gvir_config_domain_set_custom_xml_helper(GVirConfigDomain *domain,
Packit a07778
                                                         const gchar *xml,
Packit a07778
                                                         const gchar *ns,
Packit a07778
                                                         const gchar *ns_uri,
Packit a07778
                                                         gboolean ns_children,
Packit a07778
                                                         GError **error)
Packit a07778
{
Packit a07778
    GVirConfigObject *metadata;
Packit a07778
    GVirConfigObject *custom_xml;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE);
Packit a07778
    g_return_val_if_fail(xml != NULL, FALSE);
Packit a07778
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
Packit a07778
Packit a07778
    metadata = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                            "metadata");
Packit a07778
Packit a07778
    custom_xml = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_OBJECT,
Packit a07778
                                                 NULL, NULL, xml, error);
Packit a07778
    if (custom_xml == NULL) {
Packit a07778
        g_assert_not_reached();
Packit a07778
        g_object_unref(G_OBJECT(metadata));
Packit a07778
        return FALSE;
Packit a07778
    }
Packit a07778
Packit a07778
    gvir_config_object_set_namespace(custom_xml, ns, ns_uri, ns_children);
Packit a07778
Packit a07778
    gvir_config_object_delete_children(metadata, NULL, ns_uri);
Packit a07778
    gvir_config_object_attach_add(metadata, custom_xml);
Packit a07778
    g_object_unref(G_OBJECT(metadata));
Packit a07778
    g_object_unref(G_OBJECT(custom_xml));
Packit a07778
Packit a07778
    return TRUE;
Packit a07778
}
Packit a07778
Packit a07778
gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
Packit a07778
                                           const gchar *xml,
Packit a07778
                                           const gchar *ns,
Packit a07778
                                           const gchar *ns_uri,
Packit a07778
                                           GError **error)
Packit a07778
{
Packit a07778
    return gvir_config_domain_set_custom_xml_helper(domain,
Packit a07778
                                                    xml,
Packit a07778
                                                    ns,
Packit a07778
                                                    ns_uri,
Packit a07778
                                                    FALSE,
Packit a07778
                                                    error);
Packit a07778
}
Packit a07778
Packit a07778
gboolean gvir_config_domain_set_custom_xml_ns_children(GVirConfigDomain *domain,
Packit a07778
                                                       const gchar *xml,
Packit a07778
                                                       const gchar *ns,
Packit a07778
                                                       const gchar *ns_uri,
Packit a07778
                                                       GError **error)
Packit a07778
{
Packit a07778
    return gvir_config_domain_set_custom_xml_helper(domain,
Packit a07778
                                                    xml,
Packit a07778
                                                    ns,
Packit a07778
                                                    ns_uri,
Packit a07778
                                                    TRUE,
Packit a07778
                                                    error);
Packit a07778
}
Packit a07778
Packit a07778
struct LookupNamespacedNodeData {
Packit a07778
    const char *ns_uri;
Packit a07778
    xmlNodePtr node;
Packit a07778
};
Packit a07778
Packit a07778
static gboolean lookup_namespaced_node(xmlNodePtr node, gpointer opaque)
Packit a07778
{
Packit a07778
    struct LookupNamespacedNodeData* data = opaque;
Packit a07778
Packit a07778
    if (node->ns == NULL)
Packit a07778
        return TRUE;
Packit a07778
Packit a07778
    if (g_strcmp0((char *)node->ns->href, data->ns_uri) == 0) {
Packit a07778
        data->node = node;
Packit a07778
        return FALSE;
Packit a07778
    }
Packit a07778
Packit a07778
    return TRUE;
Packit a07778
}
Packit a07778
Packit a07778
gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
Packit a07778
                                         const gchar *ns_uri)
Packit a07778
{
Packit a07778
    struct LookupNamespacedNodeData data = { NULL, NULL };
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
    g_return_val_if_fail(ns_uri != NULL, NULL);
Packit a07778
Packit a07778
    data.ns_uri = ns_uri;
Packit a07778
    gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "metadata",
Packit a07778
                                     lookup_namespaced_node, &data);
Packit a07778
    return gvir_config_xml_node_to_string(data.node);
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_get_cpu:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 *
Packit a07778
 * Gets the CPU configuration of @domain
Packit a07778
 *
Packit a07778
 * Returns: (transfer full): A #GVirConfigDomainCpu. The returned object
Packit a07778
 * should be unreffed with g_object_unref() when no longer needed.
Packit a07778
 */
Packit a07778
GVirConfigDomainCpu *gvir_config_domain_get_cpu(GVirConfigDomain *domain)
Packit a07778
{
Packit a07778
    GVirConfigObject *object;
Packit a07778
Packit a07778
    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
Packit a07778
Packit a07778
    object = gvir_config_object_get_child_with_type(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                                    "cpu",
Packit a07778
                                                    GVIR_CONFIG_TYPE_DOMAIN_CPU);
Packit a07778
Packit a07778
    return GVIR_CONFIG_DOMAIN_CPU(object);
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_cpu:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @cpu: (allow-none):
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_cpu(GVirConfigDomain *domain,
Packit a07778
                                GVirConfigDomainCpu *cpu)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail(cpu == NULL || GVIR_CONFIG_IS_DOMAIN_CPU(cpu));
Packit a07778
Packit a07778
    gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                      "cpu",
Packit a07778
                                      GVIR_CONFIG_OBJECT(cpu));
Packit a07778
}
Packit a07778
Packit a07778
/**
Packit a07778
 * gvir_config_domain_set_power_management:
Packit a07778
 * @domain: a #GVirConfigDomain
Packit a07778
 * @pm: (allow-none): a #GVirPowerManagement instance
Packit a07778
 */
Packit a07778
void gvir_config_domain_set_power_management(GVirConfigDomain *domain,
Packit a07778
                                             GVirConfigDomainPowerManagement *pm)
Packit a07778
{
Packit a07778
    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain));
Packit a07778
    g_return_if_fail(pm != NULL || GVIR_CONFIG_IS_DOMAIN_POWER_MANAGEMENT(pm));
Packit a07778
Packit a07778
    gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain),
Packit a07778
                                      "pm",
Packit a07778
                                      GVIR_CONFIG_OBJECT(pm));
Packit a07778
}