[libvirt] [PATCH libvirt-glib 1/3] Add GVirDomainDevice abstract class

--- libvirt-gobject/Makefile.am | 3 + .../libvirt-gobject-domain-device-private.h | 31 +++++ libvirt-gobject/libvirt-gobject-domain-device.c | 139 ++++++++++++++++++++ libvirt-gobject/libvirt-gobject-domain-device.h | 64 +++++++++ libvirt-gobject/libvirt-gobject.h | 1 + libvirt-gobject/libvirt-gobject.sym | 2 + 6 files changed, 240 insertions(+), 0 deletions(-) create mode 100644 libvirt-gobject/libvirt-gobject-domain-device-private.h create mode 100644 libvirt-gobject/libvirt-gobject-domain-device.c create mode 100644 libvirt-gobject/libvirt-gobject-domain-device.h diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am index 4f84b8b..56a047e 100644 --- a/libvirt-gobject/Makefile.am +++ b/libvirt-gobject/Makefile.am @@ -7,6 +7,7 @@ GOBJECT_HEADER_FILES = \ libvirt-gobject.h \ libvirt-gobject-main.h \ libvirt-gobject-domain-snapshot.h \ + libvirt-gobject-domain-device.h \ libvirt-gobject-domain.h \ libvirt-gobject-interface.h \ libvirt-gobject-network.h \ @@ -21,6 +22,7 @@ GOBJECT_HEADER_FILES = \ GOBJECT_SOURCE_FILES = \ libvirt-gobject-main.c \ libvirt-gobject-domain-snapshot.c \ + libvirt-gobject-domain-device.c \ libvirt-gobject-domain.c \ libvirt-gobject-interface.c \ libvirt-gobject-network.c \ @@ -42,6 +44,7 @@ libvirt_gobject_1_0_la_HEADERS = \ $(GOBJECT_HEADER_FILES) \ libvirt-gobject-input-stream.h nodist_libvirt_gobject_1_0_la_HEADERS = \ + libvirt-gobject-domain-device-private.h \ libvirt-gobject-enums.h libvirt_gobject_1_0_la_SOURCES = \ $(libvirt_gobject_1_0_la_HEADERS) \ diff --git a/libvirt-gobject/libvirt-gobject-domain-device-private.h b/libvirt-gobject/libvirt-gobject-domain-device-private.h new file mode 100644 index 0000000..2a34309 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-device-private.h @@ -0,0 +1,31 @@ +/* + * libvirt-gobject-domain-device-private.h: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ +#ifndef __LIBVIRT_GOBJECT_DOMAIN_DEVICE_PRIVATE_H__ +#define __LIBVIRT_GOBJECT_DOMAIN_DEVICE_PRIVATEH__ + +G_BEGIN_DECLS + +virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self); + +G_END_DECLS + +#endif /* __LIBVIRT_GOBJECT_DOMAIN_DEVICE_PRIVATEH__ */ diff --git a/libvirt-gobject/libvirt-gobject-domain-device.c b/libvirt-gobject/libvirt-gobject-domain-device.c new file mode 100644 index 0000000..ae03489 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-device.c @@ -0,0 +1,139 @@ +/* + * libvirt-gobject-domain-device.c: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#include <config.h> + +#include <libvirt/virterror.h> +#include <string.h> + +#include "libvirt-glib/libvirt-glib.h" +#include "libvirt-gobject/libvirt-gobject.h" + +#include "libvirt-gobject/libvirt-gobject-domain-device-private.h" + +extern gboolean debugFlag; + +#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0) + +#define GVIR_DOMAIN_DEVICE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_DEVICE, GVirDomainDevicePrivate)) + +struct _GVirDomainDevicePrivate +{ + GVirDomain *domain; +}; + +G_DEFINE_ABSTRACT_TYPE(GVirDomainDevice, gvir_domain_device, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_DOMAIN, +}; + +static void gvir_domain_device_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirDomainDevice *self = GVIR_DOMAIN_DEVICE(object); + GVirDomainDevicePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_DOMAIN: + g_value_set_object(value, priv->domain); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_device_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirDomainDevice *self = GVIR_DOMAIN_DEVICE(object); + GVirDomainDevicePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_DOMAIN: + g_clear_object(&priv->domain); + priv->domain = g_value_dup_object(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_device_finalize(GObject *object) +{ + GVirDomainDevice *self = GVIR_DOMAIN_DEVICE(object); + GVirDomainDevicePrivate *priv = self->priv; + + DEBUG("Finalize GVirDomainDevice=%p", self); + + g_clear_object(&priv->domain); + + G_OBJECT_CLASS(gvir_domain_device_parent_class)->finalize(object); +} + +static void gvir_domain_device_class_init(GVirDomainDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gvir_domain_device_finalize; + object_class->get_property = gvir_domain_device_get_property; + object_class->set_property = gvir_domain_device_set_property; + + g_object_class_install_property(object_class, + PROP_DOMAIN, + g_param_spec_object("domain", + "domain", + "The associated domain", + GVIR_TYPE_DOMAIN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private(klass, sizeof(GVirDomainDevicePrivate)); +} + +static void gvir_domain_device_init(GVirDomainDevice *self) +{ + DEBUG("Init GVirDomainDevice=%p", self); + + self->priv = GVIR_DOMAIN_DEVICE_GET_PRIVATE(self); +} + +G_GNUC_INTERNAL +virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self) +{ + virDomainPtr handle; + + g_object_get(self->priv->domain, "handle", &handle, NULL); + + return handle; +} diff --git a/libvirt-gobject/libvirt-gobject-domain-device.h b/libvirt-gobject/libvirt-gobject-domain-device.h new file mode 100644 index 0000000..35d70f5 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-device.h @@ -0,0 +1,64 @@ +/* + * libvirt-gobject-domain-device.h: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#if !defined(__LIBVIRT_GOBJECT_H__) && !defined(LIBVIRT_GOBJECT_BUILD) +#error "Only <libvirt-gobject/libvirt-gobject.h> can be included directly." +#endif + +#ifndef __LIBVIRT_GOBJECT_DOMAIN_DEVICE_H__ +#define __LIBVIRT_GOBJECT_DOMAIN_DEVICE_H__ + +G_BEGIN_DECLS + +#define GVIR_TYPE_DOMAIN_DEVICE (gvir_domain_device_get_type ()) +#define GVIR_DOMAIN_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_TYPE_DOMAIN_DEVICE, GVirDomainDevice)) +#define GVIR_DOMAIN_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_TYPE_DOMAIN_DEVICE, GVirDomainDeviceClass)) +#define GVIR_IS_DOMAIN_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_TYPE_DOMAIN_DEVICE)) +#define GVIR_IS_DOMAIN_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_TYPE_DOMAIN_DEVICE)) +#define GVIR_DOMAIN_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_TYPE_DOMAIN_DEVICE, GVirDomainDeviceClass)) + +typedef struct _GVirDomainDevice GVirDomainDevice; +typedef struct _GVirDomainDevicePrivate GVirDomainDevicePrivate; +typedef struct _GVirDomainDeviceClass GVirDomainDeviceClass; + +struct _GVirDomainDevice +{ + GObject parent; + + GVirDomainDevicePrivate *priv; + + /* Do not add fields to this struct */ +}; + +struct _GVirDomainDeviceClass +{ + GObjectClass parent_class; + + gpointer padding[20]; +}; + + +GType gvir_domain_device_get_type(void); + +G_END_DECLS + +#endif /* __LIBVIRT_GOBJECT_DOMAIN_DEVICE_H__ */ diff --git a/libvirt-gobject/libvirt-gobject.h b/libvirt-gobject/libvirt-gobject.h index 12124e9..3bec2c9 100644 --- a/libvirt-gobject/libvirt-gobject.h +++ b/libvirt-gobject/libvirt-gobject.h @@ -30,6 +30,7 @@ #include <libvirt-gobject/libvirt-gobject-main.h> #include <libvirt-gobject/libvirt-gobject-enums.h> #include <libvirt-gobject/libvirt-gobject-stream.h> +#include <libvirt-gobject/libvirt-gobject-domain-device.h> #include <libvirt-gobject/libvirt-gobject-domain-snapshot.h> #include <libvirt-gobject/libvirt-gobject-domain.h> #include <libvirt-gobject/libvirt-gobject-interface.h> diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index f0e8402..da03001 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -29,6 +29,8 @@ LIBVIRT_GOBJECT_0.0.1 { gvir_connection_create_domain; gvir_connection_create_storage_pool; + gvir_domain_device_get_type; + gvir_domain_get_type; gvir_domain_handle_get_type; gvir_domain_info_get_type; -- 1.7.7

--- libvirt-gobject/Makefile.am | 2 + libvirt-gobject/libvirt-gobject-domain-interface.c | 213 ++++++++++++++++++++ libvirt-gobject/libvirt-gobject-domain-interface.h | 81 ++++++++ libvirt-gobject/libvirt-gobject.h | 1 + libvirt-gobject/libvirt-gobject.sym | 4 + 5 files changed, 301 insertions(+), 0 deletions(-) create mode 100644 libvirt-gobject/libvirt-gobject-domain-interface.c create mode 100644 libvirt-gobject/libvirt-gobject-domain-interface.h diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am index 56a047e..8b59109 100644 --- a/libvirt-gobject/Makefile.am +++ b/libvirt-gobject/Makefile.am @@ -8,6 +8,7 @@ GOBJECT_HEADER_FILES = \ libvirt-gobject-main.h \ libvirt-gobject-domain-snapshot.h \ libvirt-gobject-domain-device.h \ + libvirt-gobject-domain-interface.h \ libvirt-gobject-domain.h \ libvirt-gobject-interface.h \ libvirt-gobject-network.h \ @@ -23,6 +24,7 @@ GOBJECT_SOURCE_FILES = \ libvirt-gobject-main.c \ libvirt-gobject-domain-snapshot.c \ libvirt-gobject-domain-device.c \ + libvirt-gobject-domain-interface.c \ libvirt-gobject-domain.c \ libvirt-gobject-interface.c \ libvirt-gobject-network.c \ diff --git a/libvirt-gobject/libvirt-gobject-domain-interface.c b/libvirt-gobject/libvirt-gobject-domain-interface.c new file mode 100644 index 0000000..65a5467 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-interface.c @@ -0,0 +1,213 @@ +/* + * libvirt-gobject-domain-interface.c: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#include <config.h> + +#include <libvirt/virterror.h> +#include <string.h> + +#include "libvirt-glib/libvirt-glib.h" +#include "libvirt-gobject/libvirt-gobject.h" + +#include "libvirt-gobject/libvirt-gobject-domain-device-private.h" + +extern gboolean debugFlag; + +#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0) + +#define GVIR_DOMAIN_INTERFACE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfacePrivate)) + +struct _GVirDomainInterfacePrivate +{ + gchar *path; +}; + +G_DEFINE_TYPE(GVirDomainInterface, gvir_domain_interface, GVIR_TYPE_DOMAIN_DEVICE); + +enum { + PROP_0, + PROP_PATH, +}; + +#define GVIR_DOMAIN_INTERFACE_ERROR gvir_domain_interface_error_quark() + + +static GQuark +gvir_domain_interface_error_quark(void) +{ + return g_quark_from_static_string("gvir-domain-interface"); +} + +static void gvir_domain_interface_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + g_value_set_string(value, priv->path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_interface_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + if (priv->path) + g_free(priv->path); + priv->path = g_value_dup_string(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_interface_finalize(GObject *object) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + DEBUG("Finalize GVirDomainInterface=%p", self); + + if (priv->path) + g_free(priv->path); + + G_OBJECT_CLASS(gvir_domain_interface_parent_class)->finalize(object); +} + +static void gvir_domain_interface_class_init(GVirDomainInterfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gvir_domain_interface_finalize; + object_class->get_property = gvir_domain_interface_get_property; + object_class->set_property = gvir_domain_interface_set_property; + + g_object_class_install_property(object_class, + PROP_PATH, + g_param_spec_string("path", + "Path", + "The interface path", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private(klass, sizeof(GVirDomainInterfacePrivate)); +} + +static void gvir_domain_interface_init(GVirDomainInterface *self) +{ + DEBUG("Init GVirDomainInterface=%p", self); + + self->priv = GVIR_DOMAIN_INTERFACE_GET_PRIVATE(self); +} + +static GVirDomainInterfaceStats * +gvir_domain_interface_stats_copy(GVirDomainInterfaceStats *stats) +{ + return g_slice_dup(GVirDomainInterfaceStats, stats); +} + + +static void +gvir_domain_interface_stats_free(GVirDomainInterfaceStats *stats) +{ + g_slice_free(GVirDomainInterfaceStats, stats); +} + + +GType gvir_domain_interface_stats_get_type(void) +{ + static GType stats_type = 0; + + if (G_UNLIKELY(stats_type == 0)) + stats_type = g_boxed_type_register_static + ("GVirDomainInterfaceStats", + (GBoxedCopyFunc)gvir_domain_interface_stats_copy, + (GBoxedFreeFunc)gvir_domain_interface_stats_free); + + return stats_type; +} + +/** + * gvir_domain_interface_get_stats: + * @self: the domain interface + * @err: an error + * + * This function returns network interface stats. Individual fields + * within the stats structure may be returned as -1, which indicates + * that the hypervisor does not support that particular statistic. + * + * Returns: (transfer full): the stats or %NULL in case of error + **/ +GVirDomainInterfaceStats *gvir_domain_interface_get_stats(GVirDomainInterface *self, GError **err) +{ + GVirDomainInterfaceStats *ret; + virDomainInterfaceStatsStruct stats; + GVirDomainInterfacePrivate *priv; + virDomainPtr handle; + + g_return_val_if_fail(GVIR_IS_DOMAIN_INTERFACE(self), NULL); + + priv = self->priv; + handle = gvir_domain_device_get_domain_handle(GVIR_DOMAIN_DEVICE(self)); + + if (virDomainInterfaceStats(handle, priv->path, &stats, sizeof (stats)) < 0) { + if (err) + *err = gvir_error_new_literal(GVIR_DOMAIN_INTERFACE_ERROR, + 0, + "Unable to get domain interface stats"); + goto end; + } + + ret = g_slice_new(GVirDomainInterfaceStats); + ret->rx_bytes = stats.rx_bytes; + ret->rx_packets = stats.rx_packets; + ret->rx_errs = stats.rx_errs; + ret->rx_drop = stats.rx_drop; + ret->tx_bytes = stats.tx_bytes; + ret->tx_packets = stats.tx_packets; + ret->tx_errs = stats.tx_errs; + ret->tx_drop = stats.tx_drop; + +end: + virDomainFree(handle); + return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-domain-interface.h b/libvirt-gobject/libvirt-gobject-domain-interface.h new file mode 100644 index 0000000..5541f91 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-interface.h @@ -0,0 +1,81 @@ +/* + * libvirt-gobject-domain-interface.h: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#if !defined(__LIBVIRT_GOBJECT_H__) && !defined(LIBVIRT_GOBJECT_BUILD) +#error "Only <libvirt-gobject/libvirt-gobject.h> can be included directly." +#endif + +#ifndef __LIBVIRT_GOBJECT_DOMAIN_INTERFACE_H__ +#define __LIBVIRT_GOBJECT_DOMAIN_INTERFACE_H__ + +G_BEGIN_DECLS + +#define GVIR_TYPE_DOMAIN_INTERFACE (gvir_domain_interface_get_type ()) +#define GVIR_DOMAIN_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterface)) +#define GVIR_DOMAIN_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfaceClass)) +#define GVIR_IS_DOMAIN_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_TYPE_DOMAIN_INTERFACE)) +#define GVIR_IS_DOMAIN_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_TYPE_DOMAIN_INTERFACE)) +#define GVIR_DOMAIN_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfaceClass)) + +#define GVIR_TYPE_DOMAIN_INTERFACE_STATS (gvir_domain_interface_stats_get_type()) + +typedef struct _GVirDomainInterfaceStats GVirDomainInterfaceStats; +struct _GVirDomainInterfaceStats +{ + gint64 rx_bytes; + gint64 rx_packets; + gint64 rx_errs; + gint64 rx_drop; + gint64 tx_bytes; + gint64 tx_packets; + gint64 tx_errs; + gint64 tx_drop; +}; + +typedef struct _GVirDomainInterface GVirDomainInterface; +typedef struct _GVirDomainInterfacePrivate GVirDomainInterfacePrivate; +typedef struct _GVirDomainInterfaceClass GVirDomainInterfaceClass; + +struct _GVirDomainInterface +{ + GVirDomainDevice parent; + + GVirDomainInterfacePrivate *priv; + + /* Do not add fields to this struct */ +}; + +struct _GVirDomainInterfaceClass +{ + GVirDomainDeviceClass parent_class; + + gpointer padding[20]; +}; + +GType gvir_domain_interface_get_type(void); +GType gvir_domain_interface_stats_get_type(void); + +GVirDomainInterfaceStats *gvir_domain_interface_get_stats(GVirDomainInterface *self, GError **err); + +G_END_DECLS + +#endif /* __LIBVIRT_GOBJECT_DOMAIN_INTERFACE_H__ */ diff --git a/libvirt-gobject/libvirt-gobject.h b/libvirt-gobject/libvirt-gobject.h index 3bec2c9..6038036 100644 --- a/libvirt-gobject/libvirt-gobject.h +++ b/libvirt-gobject/libvirt-gobject.h @@ -31,6 +31,7 @@ #include <libvirt-gobject/libvirt-gobject-enums.h> #include <libvirt-gobject/libvirt-gobject-stream.h> #include <libvirt-gobject/libvirt-gobject-domain-device.h> +#include <libvirt-gobject/libvirt-gobject-domain-interface.h> #include <libvirt-gobject/libvirt-gobject-domain-snapshot.h> #include <libvirt-gobject/libvirt-gobject-domain.h> #include <libvirt-gobject/libvirt-gobject-interface.h> diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index da03001..9118b11 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -31,6 +31,10 @@ LIBVIRT_GOBJECT_0.0.1 { gvir_domain_device_get_type; + gvir_domain_interface_get_type; + gvir_domain_interface_stats_get_type; + gvir_domain_interface_get_stats; + gvir_domain_get_type; gvir_domain_handle_get_type; gvir_domain_info_get_type; -- 1.7.7

A few preliminary remark below, they apply to the next patch as well. On Thu, Nov 10, 2011 at 09:33:42PM +0100, Marc-André Lureau wrote:
--- libvirt-gobject/Makefile.am | 2 + libvirt-gobject/libvirt-gobject-domain-interface.c | 213 ++++++++++++++++++++ libvirt-gobject/libvirt-gobject-domain-interface.h | 81 ++++++++ libvirt-gobject/libvirt-gobject.h | 1 + libvirt-gobject/libvirt-gobject.sym | 4 + 5 files changed, 301 insertions(+), 0 deletions(-) create mode 100644 libvirt-gobject/libvirt-gobject-domain-interface.c create mode 100644 libvirt-gobject/libvirt-gobject-domain-interface.h
diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am index 56a047e..8b59109 100644 --- a/libvirt-gobject/Makefile.am +++ b/libvirt-gobject/Makefile.am @@ -8,6 +8,7 @@ GOBJECT_HEADER_FILES = \ libvirt-gobject-main.h \ libvirt-gobject-domain-snapshot.h \ libvirt-gobject-domain-device.h \ + libvirt-gobject-domain-interface.h \ libvirt-gobject-domain.h \ libvirt-gobject-interface.h \ libvirt-gobject-network.h \ @@ -23,6 +24,7 @@ GOBJECT_SOURCE_FILES = \ libvirt-gobject-main.c \ libvirt-gobject-domain-snapshot.c \ libvirt-gobject-domain-device.c \ + libvirt-gobject-domain-interface.c \ libvirt-gobject-domain.c \ libvirt-gobject-interface.c \ libvirt-gobject-network.c \ diff --git a/libvirt-gobject/libvirt-gobject-domain-interface.c b/libvirt-gobject/libvirt-gobject-domain-interface.c new file mode 100644 index 0000000..65a5467 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-interface.c @@ -0,0 +1,213 @@ +/* + * libvirt-gobject-domain-interface.c: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#include <config.h> + +#include <libvirt/virterror.h> +#include <string.h> + +#include "libvirt-glib/libvirt-glib.h" +#include "libvirt-gobject/libvirt-gobject.h" + +#include "libvirt-gobject/libvirt-gobject-domain-device-private.h" + +extern gboolean debugFlag; + +#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0) + +#define GVIR_DOMAIN_INTERFACE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfacePrivate)) + +struct _GVirDomainInterfacePrivate +{ + gchar *path; +}; + +G_DEFINE_TYPE(GVirDomainInterface, gvir_domain_interface, GVIR_TYPE_DOMAIN_DEVICE); + +enum { + PROP_0, + PROP_PATH, +}; + +#define GVIR_DOMAIN_INTERFACE_ERROR gvir_domain_interface_error_quark() + + +static GQuark +gvir_domain_interface_error_quark(void) +{ + return g_quark_from_static_string("gvir-domain-interface"); +} + +static void gvir_domain_interface_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + g_value_set_string(value, priv->path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_interface_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + if (priv->path) + g_free(priv->path);
You can safely call g_free on a NULL pointer, this makes the code a bit simpler, there are several occurrences of this in the 2 patches.
+ priv->path = g_value_dup_string(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_interface_finalize(GObject *object) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + DEBUG("Finalize GVirDomainInterface=%p", self); + + if (priv->path) + g_free(priv->path); + + G_OBJECT_CLASS(gvir_domain_interface_parent_class)->finalize(object); +} + +static void gvir_domain_interface_class_init(GVirDomainInterfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gvir_domain_interface_finalize; + object_class->get_property = gvir_domain_interface_get_property; + object_class->set_property = gvir_domain_interface_set_property; + + g_object_class_install_property(object_class, + PROP_PATH, + g_param_spec_string("path", + "Path", + "The interface path", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private(klass, sizeof(GVirDomainInterfacePrivate)); +} + +static void gvir_domain_interface_init(GVirDomainInterface *self) +{ + DEBUG("Init GVirDomainInterface=%p", self); + + self->priv = GVIR_DOMAIN_INTERFACE_GET_PRIVATE(self); +} + +static GVirDomainInterfaceStats * +gvir_domain_interface_stats_copy(GVirDomainInterfaceStats *stats) +{ + return g_slice_dup(GVirDomainInterfaceStats, stats); +}
Do we really need to use GSlice here? I consider GSlice as something to use when you want to make many allocations of same-size objects, will we allocate many of these stats objects?
+ + +static void +gvir_domain_interface_stats_free(GVirDomainInterfaceStats *stats) +{ + g_slice_free(GVirDomainInterfaceStats, stats); +} + + +GType gvir_domain_interface_stats_get_type(void) +{ + static GType stats_type = 0; + + if (G_UNLIKELY(stats_type == 0)) + stats_type = g_boxed_type_register_static + ("GVirDomainInterfaceStats", + (GBoxedCopyFunc)gvir_domain_interface_stats_copy, + (GBoxedFreeFunc)gvir_domain_interface_stats_free); + + return stats_type; +} + +/** + * gvir_domain_interface_get_stats: + * @self: the domain interface + * @err: an error + * + * This function returns network interface stats. Individual fields + * within the stats structure may be returned as -1, which indicates + * that the hypervisor does not support that particular statistic. + * + * Returns: (transfer full): the stats or %NULL in case of error + **/ +GVirDomainInterfaceStats *gvir_domain_interface_get_stats(GVirDomainInterface *self, GError **err) +{ + GVirDomainInterfaceStats *ret; + virDomainInterfaceStatsStruct stats; + GVirDomainInterfacePrivate *priv; + virDomainPtr handle; + + g_return_val_if_fail(GVIR_IS_DOMAIN_INTERFACE(self), NULL); + + priv = self->priv; + handle = gvir_domain_device_get_domain_handle(GVIR_DOMAIN_DEVICE(self)); + + if (virDomainInterfaceStats(handle, priv->path, &stats, sizeof (stats)) < 0) { + if (err) + *err = gvir_error_new_literal(GVIR_DOMAIN_INTERFACE_ERROR, + 0, + "Unable to get domain interface stats"); + goto end; + } + + ret = g_slice_new(GVirDomainInterfaceStats); + ret->rx_bytes = stats.rx_bytes; + ret->rx_packets = stats.rx_packets; + ret->rx_errs = stats.rx_errs; + ret->rx_drop = stats.rx_drop; + ret->tx_bytes = stats.tx_bytes; + ret->tx_packets = stats.tx_packets; + ret->tx_errs = stats.tx_errs; + ret->tx_drop = stats.tx_drop; + +end: + virDomainFree(handle); + return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-domain-interface.h b/libvirt-gobject/libvirt-gobject-domain-interface.h new file mode 100644 index 0000000..5541f91 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-interface.h @@ -0,0 +1,81 @@ +/* + * libvirt-gobject-domain-interface.h: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#if !defined(__LIBVIRT_GOBJECT_H__) && !defined(LIBVIRT_GOBJECT_BUILD) +#error "Only <libvirt-gobject/libvirt-gobject.h> can be included directly." +#endif + +#ifndef __LIBVIRT_GOBJECT_DOMAIN_INTERFACE_H__ +#define __LIBVIRT_GOBJECT_DOMAIN_INTERFACE_H__ + +G_BEGIN_DECLS + +#define GVIR_TYPE_DOMAIN_INTERFACE (gvir_domain_interface_get_type ()) +#define GVIR_DOMAIN_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterface)) +#define GVIR_DOMAIN_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfaceClass)) +#define GVIR_IS_DOMAIN_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_TYPE_DOMAIN_INTERFACE)) +#define GVIR_IS_DOMAIN_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_TYPE_DOMAIN_INTERFACE)) +#define GVIR_DOMAIN_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfaceClass)) + +#define GVIR_TYPE_DOMAIN_INTERFACE_STATS (gvir_domain_interface_stats_get_type()) + +typedef struct _GVirDomainInterfaceStats GVirDomainInterfaceStats; +struct _GVirDomainInterfaceStats +{ + gint64 rx_bytes; + gint64 rx_packets; + gint64 rx_errs; + gint64 rx_drop; + gint64 tx_bytes; + gint64 tx_packets; + gint64 tx_errs; + gint64 tx_drop; +};
2 questions about this: * should we use more explicit names (which probably means longer ones)? * how do we handle ABI compatibility the day we need to add fields to this struct?
+ +typedef struct _GVirDomainInterface GVirDomainInterface; +typedef struct _GVirDomainInterfacePrivate GVirDomainInterfacePrivate; +typedef struct _GVirDomainInterfaceClass GVirDomainInterfaceClass; + +struct _GVirDomainInterface +{ + GVirDomainDevice parent; + + GVirDomainInterfacePrivate *priv; + + /* Do not add fields to this struct */ +}; + +struct _GVirDomainInterfaceClass +{ + GVirDomainDeviceClass parent_class; + + gpointer padding[20]; +}; + +GType gvir_domain_interface_get_type(void); +GType gvir_domain_interface_stats_get_type(void); + +GVirDomainInterfaceStats *gvir_domain_interface_get_stats(GVirDomainInterface *self, GError **err); + +G_END_DECLS + +#endif /* __LIBVIRT_GOBJECT_DOMAIN_INTERFACE_H__ */ diff --git a/libvirt-gobject/libvirt-gobject.h b/libvirt-gobject/libvirt-gobject.h index 3bec2c9..6038036 100644 --- a/libvirt-gobject/libvirt-gobject.h +++ b/libvirt-gobject/libvirt-gobject.h @@ -31,6 +31,7 @@ #include <libvirt-gobject/libvirt-gobject-enums.h> #include <libvirt-gobject/libvirt-gobject-stream.h> #include <libvirt-gobject/libvirt-gobject-domain-device.h> +#include <libvirt-gobject/libvirt-gobject-domain-interface.h> #include <libvirt-gobject/libvirt-gobject-domain-snapshot.h> #include <libvirt-gobject/libvirt-gobject-domain.h> #include <libvirt-gobject/libvirt-gobject-interface.h> diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index da03001..9118b11 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -31,6 +31,10 @@ LIBVIRT_GOBJECT_0.0.1 {
gvir_domain_device_get_type;
+ gvir_domain_interface_get_type; + gvir_domain_interface_stats_get_type; + gvir_domain_interface_get_stats; + gvir_domain_get_type; gvir_domain_handle_get_type; gvir_domain_info_get_type; -- 1.7.7
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

Hi
On Thu, Nov 10, 2011 at 09:33:42PM +0100, Marc-André Lureau wrote:
+ case PROP_PATH: + if (priv->path) + g_free(priv->path);
You can safely call g_free on a NULL pointer, this makes the code a bit simpler, there are several occurrences of this in the 2 patches.
Correct, I forgot. I will fix that.
+static GVirDomainInterfaceStats * +gvir_domain_interface_stats_copy(GVirDomainInterfaceStats *stats) +{ + return g_slice_dup(GVirDomainInterfaceStats, stats); +}
Do we really need to use GSlice here? I consider GSlice as something to use when you want to make many allocations of same-size objects, will we allocate many of these stats objects?
Yes, it's frequently allocated (1/second), and kept in memory too for history.
+typedef struct _GVirDomainInterfaceStats GVirDomainInterfaceStats; +struct _GVirDomainInterfaceStats +{ + gint64 rx_bytes; + gint64 rx_packets; + gint64 rx_errs; + gint64 rx_drop; + gint64 tx_bytes; + gint64 tx_packets; + gint64 tx_errs; + gint64 tx_drop; +};
2 questions about this: * should we use more explicit names (which probably means longer ones)?
I don't mind. I just copy&pasted libvirt here, which I like because you can directly map it to libvirt struct.
* how do we handle ABI compatibility the day we need to add fields to this struct?
It's only a returned structure, allocated by the lib, so I guess that's fine to append fields later, right? regards

On Thu, Nov 10, 2011 at 04:15:01PM -0500, Marc-André Lureau wrote:
On Thu, Nov 10, 2011 at 09:33:42PM +0100, Marc-André Lureau wrote: Do we really need to use GSlice here? I consider GSlice as something to use when you want to make many allocations of same-size objects, will we allocate many of these stats objects?
Yes, it's frequently allocated (1/second), and kept in memory too for history.
Ok, fine with me then.
* how do we handle ABI compatibility the day we need to add fields to this struct?
It's only a returned structure, allocated by the lib, so I guess that's fine to append fields later, right?
Yes, I think it should be fine, I think it's possible to find scenarios that could break when adding fields, but that's probably some convoluted cases where we can say "don't do that". Iirc libvirt does this too, so this should be good enough for us :) Christophe

Hey, A few more comments I made on IRC (no access to this email when I reviewed the patches), sending them here to be sure they are not missed/lost. The same comments apply to patch 3/3. Can you resend the 3 patches with the various issues fixed? then I'll ACK them. Christophe On Thu, Nov 10, 2011 at 09:33:42PM +0100, Marc-André Lureau wrote:
diff --git a/libvirt-gobject/libvirt-gobject-domain-interface.c b/libvirt-gobject/libvirt-gobject-domain-interface.c new file mode 100644 index 0000000..65a5467 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-interface.c @@ -0,0 +1,213 @@ +/* + * libvirt-gobject-domain-interface.c: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#include <config.h> + +#include <libvirt/virterror.h> +#include <string.h> + +#include "libvirt-glib/libvirt-glib.h" +#include "libvirt-gobject/libvirt-gobject.h" + +#include "libvirt-gobject/libvirt-gobject-domain-device-private.h" + +extern gboolean debugFlag; + +#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0) + +#define GVIR_DOMAIN_INTERFACE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_INTERFACE, GVirDomainInterfacePrivate)) + +struct _GVirDomainInterfacePrivate +{ + gchar *path; +}; + +G_DEFINE_TYPE(GVirDomainInterface, gvir_domain_interface, GVIR_TYPE_DOMAIN_DEVICE); + +enum { + PROP_0, + PROP_PATH, +}; + +#define GVIR_DOMAIN_INTERFACE_ERROR gvir_domain_interface_error_quark() + + +static GQuark +gvir_domain_interface_error_quark(void) +{ + return g_quark_from_static_string("gvir-domain-interface"); +} + +static void gvir_domain_interface_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + g_value_set_string(value, priv->path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_interface_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + if (priv->path) + g_free(priv->path); + priv->path = g_value_dup_string(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_interface_finalize(GObject *object) +{ + GVirDomainInterface *self = GVIR_DOMAIN_INTERFACE(object); + GVirDomainInterfacePrivate *priv = self->priv; + + DEBUG("Finalize GVirDomainInterface=%p", self); + + if (priv->path) + g_free(priv->path); + + G_OBJECT_CLASS(gvir_domain_interface_parent_class)->finalize(object); +} + +static void gvir_domain_interface_class_init(GVirDomainInterfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gvir_domain_interface_finalize; + object_class->get_property = gvir_domain_interface_get_property; + object_class->set_property = gvir_domain_interface_set_property; + + g_object_class_install_property(object_class, + PROP_PATH, + g_param_spec_string("path", + "Path", + "The interface path", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private(klass, sizeof(GVirDomainInterfacePrivate)); +} + +static void gvir_domain_interface_init(GVirDomainInterface *self) +{ + DEBUG("Init GVirDomainInterface=%p", self); + + self->priv = GVIR_DOMAIN_INTERFACE_GET_PRIVATE(self); +} + +static GVirDomainInterfaceStats * +gvir_domain_interface_stats_copy(GVirDomainInterfaceStats *stats) +{ + return g_slice_dup(GVirDomainInterfaceStats, stats); +} + + +static void +gvir_domain_interface_stats_free(GVirDomainInterfaceStats *stats) +{ + g_slice_free(GVirDomainInterfaceStats, stats); +} + + +GType gvir_domain_interface_stats_get_type(void) +{ + static GType stats_type = 0; + + if (G_UNLIKELY(stats_type == 0)) + stats_type = g_boxed_type_register_static + ("GVirDomainInterfaceStats", + (GBoxedCopyFunc)gvir_domain_interface_stats_copy, + (GBoxedFreeFunc)gvir_domain_interface_stats_free); + + return stats_type; +}
Using G_DEFINE_BOXED_TYPE would be slightly better here as it is thread-safe (using GOnce).
+ +/** + * gvir_domain_interface_get_stats: + * @self: the domain interface + * @err: an error + * + * This function returns network interface stats. Individual fields + * within the stats structure may be returned as -1, which indicates + * that the hypervisor does not support that particular statistic. + * + * Returns: (transfer full): the stats or %NULL in case of error + **/ +GVirDomainInterfaceStats *gvir_domain_interface_get_stats(GVirDomainInterface *self, GError **err) +{ + GVirDomainInterfaceStats *ret;
This needs to be initialized to NULL otherwise...
+ virDomainInterfaceStatsStruct stats; + GVirDomainInterfacePrivate *priv; + virDomainPtr handle; + + g_return_val_if_fail(GVIR_IS_DOMAIN_INTERFACE(self), NULL); + + priv = self->priv; + handle = gvir_domain_device_get_domain_handle(GVIR_DOMAIN_DEVICE(self)); + + if (virDomainInterfaceStats(handle, priv->path, &stats, sizeof (stats)) < 0) { + if (err) + *err = gvir_error_new_literal(GVIR_DOMAIN_INTERFACE_ERROR, + 0, + "Unable to get domain interface stats"); + goto end;
... when this error path is taken ...
+ } + + ret = g_slice_new(GVirDomainInterfaceStats); + ret->rx_bytes = stats.rx_bytes; + ret->rx_packets = stats.rx_packets; + ret->rx_errs = stats.rx_errs; + ret->rx_drop = stats.rx_drop; + ret->tx_bytes = stats.tx_bytes; + ret->tx_packets = stats.tx_packets; + ret->tx_errs = stats.tx_errs; + ret->tx_drop = stats.tx_drop; + +end: + virDomainFree(handle); + return ret;
... we return an uninitialized pointer.
+}

--- libvirt-gobject/Makefile.am | 2 + libvirt-gobject/libvirt-gobject-domain-disk.c | 210 +++++++++++++++++++++++++ libvirt-gobject/libvirt-gobject-domain-disk.h | 78 +++++++++ libvirt-gobject/libvirt-gobject.h | 1 + libvirt-gobject/libvirt-gobject.sym | 4 + 5 files changed, 295 insertions(+), 0 deletions(-) create mode 100644 libvirt-gobject/libvirt-gobject-domain-disk.c create mode 100644 libvirt-gobject/libvirt-gobject-domain-disk.h diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am index 8b59109..101007e 100644 --- a/libvirt-gobject/Makefile.am +++ b/libvirt-gobject/Makefile.am @@ -8,6 +8,7 @@ GOBJECT_HEADER_FILES = \ libvirt-gobject-main.h \ libvirt-gobject-domain-snapshot.h \ libvirt-gobject-domain-device.h \ + libvirt-gobject-domain-disk.h \ libvirt-gobject-domain-interface.h \ libvirt-gobject-domain.h \ libvirt-gobject-interface.h \ @@ -24,6 +25,7 @@ GOBJECT_SOURCE_FILES = \ libvirt-gobject-main.c \ libvirt-gobject-domain-snapshot.c \ libvirt-gobject-domain-device.c \ + libvirt-gobject-domain-disk.c \ libvirt-gobject-domain-interface.c \ libvirt-gobject-domain.c \ libvirt-gobject-interface.c \ diff --git a/libvirt-gobject/libvirt-gobject-domain-disk.c b/libvirt-gobject/libvirt-gobject-domain-disk.c new file mode 100644 index 0000000..0481967 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-disk.c @@ -0,0 +1,210 @@ +/* + * libvirt-gobject-domain-disk.c: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#include <config.h> + +#include <libvirt/virterror.h> +#include <string.h> + +#include "libvirt-glib/libvirt-glib.h" +#include "libvirt-gobject/libvirt-gobject.h" + +#include "libvirt-gobject/libvirt-gobject-domain-device-private.h" + +extern gboolean debugFlag; + +#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0) + +#define GVIR_DOMAIN_DISK_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN_DISK, GVirDomainDiskPrivate)) + +struct _GVirDomainDiskPrivate +{ + gchar *path; +}; + +G_DEFINE_TYPE(GVirDomainDisk, gvir_domain_disk, GVIR_TYPE_DOMAIN_DEVICE); + +enum { + PROP_0, + PROP_PATH, +}; + +#define GVIR_DOMAIN_DISK_ERROR gvir_domain_disk_error_quark() + + +static GQuark +gvir_domain_disk_error_quark(void) +{ + return g_quark_from_static_string("gvir-domain-disk"); +} + +static void gvir_domain_disk_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); + GVirDomainDiskPrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + g_value_set_string(value, priv->path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_disk_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); + GVirDomainDiskPrivate *priv = self->priv; + + switch (prop_id) { + case PROP_PATH: + if (priv->path) + g_free(priv->path); + priv->path = g_value_dup_string(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + + +static void gvir_domain_disk_finalize(GObject *object) +{ + GVirDomainDisk *self = GVIR_DOMAIN_DISK(object); + GVirDomainDiskPrivate *priv = self->priv; + + DEBUG("Finalize GVirDomainDisk=%p", self); + + if (priv->path) + g_free(priv->path); + + G_OBJECT_CLASS(gvir_domain_disk_parent_class)->finalize(object); +} + +static void gvir_domain_disk_class_init(GVirDomainDiskClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gvir_domain_disk_finalize; + object_class->get_property = gvir_domain_disk_get_property; + object_class->set_property = gvir_domain_disk_set_property; + + g_object_class_install_property(object_class, + PROP_PATH, + g_param_spec_string("path", + "Path", + "The disk path", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_type_class_add_private(klass, sizeof(GVirDomainDiskPrivate)); +} + +static void gvir_domain_disk_init(GVirDomainDisk *self) +{ + DEBUG("Init GVirDomainDisk=%p", self); + + self->priv = GVIR_DOMAIN_DISK_GET_PRIVATE(self); +} + +static GVirDomainDiskStats * +gvir_domain_disk_stats_copy(GVirDomainDiskStats *stats) +{ + return g_slice_dup(GVirDomainDiskStats, stats); +} + + +static void +gvir_domain_disk_stats_free(GVirDomainDiskStats *stats) +{ + g_slice_free(GVirDomainDiskStats, stats); +} + + +GType gvir_domain_disk_stats_get_type(void) +{ + static GType stats_type = 0; + + if (G_UNLIKELY(stats_type == 0)) + stats_type = g_boxed_type_register_static + ("GVirDomainDiskStats", + (GBoxedCopyFunc)gvir_domain_disk_stats_copy, + (GBoxedFreeFunc)gvir_domain_disk_stats_free); + + return stats_type; +} + +/** + * gvir_domain_disk_get_stats: + * @self: the domain disk + * @err: an error + * + * This function returns network disk stats. Individual fields + * within the stats structure may be returned as -1, which indicates + * that the hypervisor does not support that particular statistic. + * + * Returns: (transfer full): the stats or %NULL in case of error + **/ +GVirDomainDiskStats *gvir_domain_disk_get_stats(GVirDomainDisk *self, GError **err) +{ + GVirDomainDiskStats *ret; + virDomainBlockStatsStruct stats; + GVirDomainDiskPrivate *priv; + virDomainPtr handle; + + g_return_val_if_fail(GVIR_IS_DOMAIN_DISK(self), NULL); + + priv = self->priv; + handle = gvir_domain_device_get_domain_handle(GVIR_DOMAIN_DEVICE(self)); + + if (virDomainBlockStats(handle, priv->path, &stats, sizeof (stats)) < 0) { + if (err) + *err = gvir_error_new_literal(GVIR_DOMAIN_DISK_ERROR, + 0, + "Unable to get domain disk stats"); + goto end; + } + + ret = g_slice_new(GVirDomainDiskStats); + ret->rd_req = stats.rd_req; + ret->rd_bytes = stats.rd_bytes; + ret->wr_req = stats.wr_req; + ret->wr_bytes = stats.wr_bytes; + ret->errs = stats.errs; + +end: + virDomainFree(handle); + return ret; +} diff --git a/libvirt-gobject/libvirt-gobject-domain-disk.h b/libvirt-gobject/libvirt-gobject-domain-disk.h new file mode 100644 index 0000000..8b59170 --- /dev/null +++ b/libvirt-gobject/libvirt-gobject-domain-disk.h @@ -0,0 +1,78 @@ +/* + * libvirt-gobject-domain-disk.h: libvirt gobject integration + * + * Copyright (C) 2011 Red Hat + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Marc-André Lureau <marcandre.lureau@redhat.com> + */ + +#if !defined(__LIBVIRT_GOBJECT_H__) && !defined(LIBVIRT_GOBJECT_BUILD) +#error "Only <libvirt-gobject/libvirt-gobject.h> can be included directly." +#endif + +#ifndef __LIBVIRT_GOBJECT_DOMAIN_DISK_H__ +#define __LIBVIRT_GOBJECT_DOMAIN_DISK_H__ + +G_BEGIN_DECLS + +#define GVIR_TYPE_DOMAIN_DISK (gvir_domain_disk_get_type ()) +#define GVIR_DOMAIN_DISK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_TYPE_DOMAIN_DISK, GVirDomainDisk)) +#define GVIR_DOMAIN_DISK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_TYPE_DOMAIN_DISK, GVirDomainDiskClass)) +#define GVIR_IS_DOMAIN_DISK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_TYPE_DOMAIN_DISK)) +#define GVIR_IS_DOMAIN_DISK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_TYPE_DOMAIN_DISK)) +#define GVIR_DOMAIN_DISK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_TYPE_DOMAIN_DISK, GVirDomainDiskClass)) + +#define GVIR_TYPE_DOMAIN_DISK_STATS (gvir_domain_disk_stats_get_type()) + +typedef struct _GVirDomainDiskStats GVirDomainDiskStats; +struct _GVirDomainDiskStats +{ + gint64 rd_req; /* number of read requests */ + gint64 rd_bytes; /* number of read bytes */ + gint64 wr_req; /* number of write requests */ + gint64 wr_bytes; /* number of written bytes */ + gint64 errs; /* In Xen this returns the mysterious 'oo_req'. */ +}; + +typedef struct _GVirDomainDisk GVirDomainDisk; +typedef struct _GVirDomainDiskPrivate GVirDomainDiskPrivate; +typedef struct _GVirDomainDiskClass GVirDomainDiskClass; + +struct _GVirDomainDisk +{ + GVirDomainDevice parent; + + GVirDomainDiskPrivate *priv; + + /* Do not add fields to this struct */ +}; + +struct _GVirDomainDiskClass +{ + GVirDomainDeviceClass parent_class; + + gpointer padding[20]; +}; + +GType gvir_domain_disk_get_type(void); +GType gvir_domain_disk_stats_get_type(void); + +GVirDomainDiskStats *gvir_domain_disk_get_stats(GVirDomainDisk *self, GError **err); + +G_END_DECLS + +#endif /* __LIBVIRT_GOBJECT_DOMAIN_DISK_H__ */ diff --git a/libvirt-gobject/libvirt-gobject.h b/libvirt-gobject/libvirt-gobject.h index 6038036..aef749b 100644 --- a/libvirt-gobject/libvirt-gobject.h +++ b/libvirt-gobject/libvirt-gobject.h @@ -31,6 +31,7 @@ #include <libvirt-gobject/libvirt-gobject-enums.h> #include <libvirt-gobject/libvirt-gobject-stream.h> #include <libvirt-gobject/libvirt-gobject-domain-device.h> +#include <libvirt-gobject/libvirt-gobject-domain-disk.h> #include <libvirt-gobject/libvirt-gobject-domain-interface.h> #include <libvirt-gobject/libvirt-gobject-domain-snapshot.h> #include <libvirt-gobject/libvirt-gobject-domain.h> diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym index 9118b11..164b6b8 100644 --- a/libvirt-gobject/libvirt-gobject.sym +++ b/libvirt-gobject/libvirt-gobject.sym @@ -31,6 +31,10 @@ LIBVIRT_GOBJECT_0.0.1 { gvir_domain_device_get_type; + gvir_domain_disk_get_type; + gvir_domain_disk_stats_get_type; + gvir_domain_disk_get_stats; + gvir_domain_interface_get_type; gvir_domain_interface_stats_get_type; gvir_domain_interface_get_stats; -- 1.7.7

Hey, a few preliminary comments, On Thu, Nov 10, 2011 at 09:33:41PM +0100, Marc-André Lureau wrote:
+ +G_GNUC_INTERNAL +virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self)
G_GNUC_INTERNAL isn't needed here since it's the default setting for symbols not listed in the .sym file. Christophe

Hi ----- Mensaje original -----
+G_GNUC_INTERNAL +virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self)
G_GNUC_INTERNAL isn't needed here since it's the default setting for symbols not listed in the .sym file.
I think it's better to be explicit about it. It's a way to declare in the code that this function is private, without having to look into the sym file. I wish we could do the same for the rest of the prviate functions. regards

Hey, On Thu, Nov 10, 2011 at 04:10:32PM -0500, Marc-André Lureau wrote:
----- Mensaje original -----
+G_GNUC_INTERNAL +virDomainPtr gvir_domain_device_get_domain_handle(GVirDomainDevice *self)
G_GNUC_INTERNAL isn't needed here since it's the default setting for symbols not listed in the .sym file.
I think it's better to be explicit about it. It's a way to declare in the code that this function is private, without having to look into the sym file. I wish we could do the same for the rest of the prviate functions.
Given that having it or not will have exactly the same result, I have doubts we'll consistently mark all private functions with G_GNUC_INTERNAL. Only having some of the private functions marked with it, and the others without the marking will only create more confusion. If we are careful about marking all private functions with G_GNUC_INTERNAL, then why not. Christophe
participants (3)
-
Christophe Fergeau
-
Marc-André Lureau
-
Marc-André Lureau