From bc1f80dd2cc55bb30bfb83bace819ebde84d8c86 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Mon, 29 Jan 2007 19:00:48 +0000 Subject: [PATCH] Move the io bandwidth fields from PIF onto a new PIF_metrics class. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 211 ++++++++++++++++++-- tools/libxen/include/xen_pif.h | 15 +- tools/libxen/include/xen_pif_metrics.h | 192 ++++++++++++++++++ tools/libxen/include/xen_pif_metrics_decl.h | 30 +++ tools/libxen/src/xen_pif.c | 34 +--- tools/libxen/src/xen_pif_metrics.c | 172 ++++++++++++++++ tools/python/xen/xend/XendAPI.py | 47 ++++- tools/python/xen/xend/XendNode.py | 34 ++-- tools/python/xen/xend/XendPIF.py | 32 +-- tools/python/xen/xend/XendPIFMetrics.py | 46 +++++ tools/python/xen/xm/messages/en/xen-xm.po | 8 +- 11 files changed, 726 insertions(+), 95 deletions(-) create mode 100644 tools/libxen/include/xen_pif_metrics.h create mode 100644 tools/libxen/include/xen_pif_metrics_decl.h create mode 100644 tools/libxen/src/xen_pif_metrics.c create mode 100644 tools/python/xen/xend/XendPIFMetrics.py diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index dabbbc53be..610ed27dc3 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -30,6 +30,7 @@ Name & Description \\ {\tt network} & A virtual network \\ {\tt VIF} & A virtual network interface \\ {\tt PIF} & A physical network interface (note separate VLANs are represented as several PIFs) \\ +{\tt PIF\_metrics} & The metrics associated with a physical network interface \\ {\tt SR} & A storage repository \\ {\tt VDI} & A virtual disk image \\ {\tt VBD} & A virtual block device \\ @@ -53,6 +54,7 @@ VDI.VBDs & VBD.VDI & many-to-one\\ VBD.VM & VM.VBDs & one-to-many\\ VIF.VM & VM.VIFs & one-to-many\\ VIF.network & network.VIFs & one-to-many\\ +PIF.metrics & PIF\_metrics.PIF & one-to-one\\ PIF.host & host.PIFs & one-to-many\\ PIF.network & network.PIFs & one-to-many\\ SR.VDIs & VDI.SR & many-to-one\\ @@ -6378,8 +6380,7 @@ $\mathit{RO}_\mathit{ins}$ & {\tt host} & host ref & physical machine to which $\mathit{RW}$ & {\tt MAC} & string & ethernet MAC address of physical interface \\ $\mathit{RW}$ & {\tt MTU} & int & MTU in octets \\ $\mathit{RW}$ & {\tt VLAN} & int & VLAN tag for all traffic passing through this interface \\ -$\mathit{RO}_\mathit{run}$ & {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\ -$\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ +$\mathit{RO}_\mathit{ins}$ & {\tt metrics} & PIF\_metrics ref & metrics associated with this PIF. \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: PIF} @@ -6818,13 +6819,13 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~get\_io\_read\_kbs} +\subsubsection{RPC name:~get\_metrics} {\bf Overview:} -Get the io/read\_kbs field of the given PIF. +Get the metrics field of the given PIF. \noindent {\bf Signature:} -\begin{verbatim} float get_io_read_kbs (session_id s, PIF ref self)\end{verbatim} +\begin{verbatim} (PIF_metrics ref) get_metrics (session_id s, PIF ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -6838,6 +6839,186 @@ Get the io/read\_kbs field of the given PIF. \end{tabular} +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +PIF\_metrics ref +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_by\_uuid} + +{\bf Overview:} +Get a reference to the PIF instance with the specified UUID. + + \noindent {\bf Signature:} +\begin{verbatim} (PIF ref) get_by_uuid (session_id s, string uuid)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt string } & uuid & UUID of object to return \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +PIF ref +} + + +reference to the object +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_record} + +{\bf Overview:} +Get a record containing the current state of the given PIF. + + \noindent {\bf Signature:} +\begin{verbatim} (PIF record) get_record (session_id s, PIF ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt PIF ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +PIF record +} + + +all fields from the object +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} + +\vspace{1cm} +\newpage +\section{Class: PIF\_metrics} +\subsection{Fields for class: PIF\_metrics} +\begin{longtable}{|lllp{0.38\textwidth}|} +\hline +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf PIF\_metrics} \\ +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em +The metrics associated with a physical network interface.}} \\ +\hline +Quals & Field & Type & Description \\ +\hline +$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ +$\mathit{RO}_\mathit{ins}$ & {\tt PIF} & PIF ref & PIF to which these metrics apply \\ +$\mathit{RO}_\mathit{run}$ & {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\ +$\mathit{RO}_\mathit{run}$ & {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\ +\hline +\end{longtable} +\subsection{Additional RPCs associated with class: PIF\_metrics} +\subsubsection{RPC name:~get\_uuid} + +{\bf Overview:} +Get the uuid field of the given PIF\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} string get_uuid (session_id s, PIF_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt PIF\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_PIF} + +{\bf Overview:} +Get the PIF field of the given PIF\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} (PIF ref) get_PIF (session_id s, PIF_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt PIF\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +PIF ref +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_io\_read\_kbs} + +{\bf Overview:} +Get the io/read\_kbs field of the given PIF\_metrics. + + \noindent {\bf Signature:} +\begin{verbatim} float get_io_read_kbs (session_id s, PIF_metrics ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt PIF\_metrics ref } & self & reference to the object \\ \hline + +\end{tabular} + \vspace{0.3cm} \noindent {\bf Return Type:} @@ -6853,10 +7034,10 @@ value of the field \subsubsection{RPC name:~get\_io\_write\_kbs} {\bf Overview:} -Get the io/write\_kbs field of the given PIF. +Get the io/write\_kbs field of the given PIF\_metrics. \noindent {\bf Signature:} -\begin{verbatim} float get_io_write_kbs (session_id s, PIF ref self)\end{verbatim} +\begin{verbatim} float get_io_write_kbs (session_id s, PIF_metrics ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -6866,7 +7047,7 @@ Get the io/write\_kbs field of the given PIF. \begin{tabular}{|c|c|p{7cm}|} \hline {\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt PIF ref } & self & reference to the object \\ \hline +{\tt PIF\_metrics ref } & self & reference to the object \\ \hline \end{tabular} @@ -6885,10 +7066,10 @@ value of the field \subsubsection{RPC name:~get\_by\_uuid} {\bf Overview:} -Get a reference to the PIF instance with the specified UUID. +Get a reference to the PIF\_metrics instance with the specified UUID. \noindent {\bf Signature:} -\begin{verbatim} (PIF ref) get_by_uuid (session_id s, string uuid)\end{verbatim} +\begin{verbatim} (PIF_metrics ref) get_by_uuid (session_id s, string uuid)\end{verbatim} \noindent{\bf Arguments:} @@ -6906,7 +7087,7 @@ Get a reference to the PIF instance with the specified UUID. \noindent {\bf Return Type:} {\tt -PIF ref +PIF\_metrics ref } @@ -6917,10 +7098,10 @@ reference to the object \subsubsection{RPC name:~get\_record} {\bf Overview:} -Get a record containing the current state of the given PIF. +Get a record containing the current state of the given PIF\_metrics. \noindent {\bf Signature:} -\begin{verbatim} (PIF record) get_record (session_id s, PIF ref self)\end{verbatim} +\begin{verbatim} (PIF_metrics record) get_record (session_id s, PIF_metrics ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -6930,7 +7111,7 @@ Get a record containing the current state of the given PIF. \begin{tabular}{|c|c|p{7cm}|} \hline {\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt PIF ref } & self & reference to the object \\ \hline +{\tt PIF\_metrics ref } & self & reference to the object \\ \hline \end{tabular} @@ -6938,7 +7119,7 @@ Get a record containing the current state of the given PIF. \noindent {\bf Return Type:} {\tt -PIF record +PIF\_metrics record } diff --git a/tools/libxen/include/xen_pif.h b/tools/libxen/include/xen_pif.h index 6905c60fe5..a4d6db7420 100644 --- a/tools/libxen/include/xen_pif.h +++ b/tools/libxen/include/xen_pif.h @@ -23,6 +23,7 @@ #include "xen_host_decl.h" #include "xen_network_decl.h" #include "xen_pif_decl.h" +#include "xen_pif_metrics_decl.h" /* @@ -71,8 +72,7 @@ typedef struct xen_pif_record char *mac; int64_t mtu; int64_t vlan; - double io_read_kbs; - double io_write_kbs; + struct xen_pif_metrics_record_opt *metrics; } xen_pif_record; /** @@ -218,17 +218,10 @@ xen_pif_get_vlan(xen_session *session, int64_t *result, xen_pif pif); /** - * Get the io/read_kbs field of the given PIF. + * Get the metrics field of the given PIF. */ extern bool -xen_pif_get_io_read_kbs(xen_session *session, double *result, xen_pif pif); - - -/** - * Get the io/write_kbs field of the given PIF. - */ -extern bool -xen_pif_get_io_write_kbs(xen_session *session, double *result, xen_pif pif); +xen_pif_get_metrics(xen_session *session, xen_pif_metrics *result, xen_pif pif); /** diff --git a/tools/libxen/include/xen_pif_metrics.h b/tools/libxen/include/xen_pif_metrics.h new file mode 100644 index 0000000000..420516d8b6 --- /dev/null +++ b/tools/libxen/include/xen_pif_metrics.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2006, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef XEN_PIF_METRICS_H +#define XEN_PIF_METRICS_H + +#include "xen_common.h" +#include "xen_pif_decl.h" +#include "xen_pif_metrics_decl.h" + + +/* + * The PIF_metrics class. + * + * The metrics associated with a physical network interface. + */ + + +/** + * Free the given xen_pif_metrics. The given handle must have been + * allocated by this library. + */ +extern void +xen_pif_metrics_free(xen_pif_metrics pif_metrics); + + +typedef struct xen_pif_metrics_set +{ + size_t size; + xen_pif_metrics *contents[]; +} xen_pif_metrics_set; + +/** + * Allocate a xen_pif_metrics_set of the given size. + */ +extern xen_pif_metrics_set * +xen_pif_metrics_set_alloc(size_t size); + +/** + * Free the given xen_pif_metrics_set. The given set must have been + * allocated by this library. + */ +extern void +xen_pif_metrics_set_free(xen_pif_metrics_set *set); + + +typedef struct xen_pif_metrics_record +{ + xen_pif_metrics handle; + char *uuid; + struct xen_pif_record_opt *pif; + double io_read_kbs; + double io_write_kbs; +} xen_pif_metrics_record; + +/** + * Allocate a xen_pif_metrics_record. + */ +extern xen_pif_metrics_record * +xen_pif_metrics_record_alloc(void); + +/** + * Free the given xen_pif_metrics_record, and all referenced values. + * The given record must have been allocated by this library. + */ +extern void +xen_pif_metrics_record_free(xen_pif_metrics_record *record); + + +typedef struct xen_pif_metrics_record_opt +{ + bool is_record; + union + { + xen_pif_metrics handle; + xen_pif_metrics_record *record; + } u; +} xen_pif_metrics_record_opt; + +/** + * Allocate a xen_pif_metrics_record_opt. + */ +extern xen_pif_metrics_record_opt * +xen_pif_metrics_record_opt_alloc(void); + +/** + * Free the given xen_pif_metrics_record_opt, and all referenced + * values. The given record_opt must have been allocated by this library. + */ +extern void +xen_pif_metrics_record_opt_free(xen_pif_metrics_record_opt *record_opt); + + +typedef struct xen_pif_metrics_record_set +{ + size_t size; + xen_pif_metrics_record *contents[]; +} xen_pif_metrics_record_set; + +/** + * Allocate a xen_pif_metrics_record_set of the given size. + */ +extern xen_pif_metrics_record_set * +xen_pif_metrics_record_set_alloc(size_t size); + +/** + * Free the given xen_pif_metrics_record_set, and all referenced + * values. The given set must have been allocated by this library. + */ +extern void +xen_pif_metrics_record_set_free(xen_pif_metrics_record_set *set); + + + +typedef struct xen_pif_metrics_record_opt_set +{ + size_t size; + xen_pif_metrics_record_opt *contents[]; +} xen_pif_metrics_record_opt_set; + +/** + * Allocate a xen_pif_metrics_record_opt_set of the given size. + */ +extern xen_pif_metrics_record_opt_set * +xen_pif_metrics_record_opt_set_alloc(size_t size); + +/** + * Free the given xen_pif_metrics_record_opt_set, and all referenced + * values. The given set must have been allocated by this library. + */ +extern void +xen_pif_metrics_record_opt_set_free(xen_pif_metrics_record_opt_set *set); + + +/** + * Get a record containing the current state of the given PIF_metrics. + */ +extern bool +xen_pif_metrics_get_record(xen_session *session, xen_pif_metrics_record **result, xen_pif_metrics pif_metrics); + + +/** + * Get a reference to the PIF_metrics instance with the specified UUID. + */ +extern bool +xen_pif_metrics_get_by_uuid(xen_session *session, xen_pif_metrics *result, char *uuid); + + +/** + * Get the uuid field of the given PIF_metrics. + */ +extern bool +xen_pif_metrics_get_uuid(xen_session *session, char **result, xen_pif_metrics pif_metrics); + + +/** + * Get the PIF field of the given PIF_metrics. + */ +extern bool +xen_pif_metrics_get_pif(xen_session *session, xen_pif *result, xen_pif_metrics pif_metrics); + + +/** + * Get the io/read_kbs field of the given PIF_metrics. + */ +extern bool +xen_pif_metrics_get_io_read_kbs(xen_session *session, double *result, xen_pif_metrics pif_metrics); + + +/** + * Get the io/write_kbs field of the given PIF_metrics. + */ +extern bool +xen_pif_metrics_get_io_write_kbs(xen_session *session, double *result, xen_pif_metrics pif_metrics); + + +#endif diff --git a/tools/libxen/include/xen_pif_metrics_decl.h b/tools/libxen/include/xen_pif_metrics_decl.h new file mode 100644 index 0000000000..71afe69d53 --- /dev/null +++ b/tools/libxen/include/xen_pif_metrics_decl.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef XEN_PIF_METRICS_DECL_H +#define XEN_PIF_METRICS_DECL_H + +typedef void *xen_pif_metrics; + +struct xen_pif_metrics_set; +struct xen_pif_metrics_record; +struct xen_pif_metrics_record_set; +struct xen_pif_metrics_record_opt; +struct xen_pif_metrics_record_opt_set; + +#endif diff --git a/tools/libxen/src/xen_pif.c b/tools/libxen/src/xen_pif.c index 39f8c748e6..0e9af6a382 100644 --- a/tools/libxen/src/xen_pif.c +++ b/tools/libxen/src/xen_pif.c @@ -25,6 +25,7 @@ #include "xen_internal.h" #include "xen_network.h" #include "xen_pif.h" +#include "xen_pif_metrics.h" XEN_FREE(xen_pif) @@ -59,12 +60,9 @@ static const struct_member xen_pif_record_struct_members[] = { .key = "VLAN", .type = &abstract_type_int, .offset = offsetof(xen_pif_record, vlan) }, - { .key = "io_read_kbs", - .type = &abstract_type_float, - .offset = offsetof(xen_pif_record, io_read_kbs) }, - { .key = "io_write_kbs", - .type = &abstract_type_float, - .offset = offsetof(xen_pif_record, io_write_kbs) } + { .key = "metrics", + .type = &abstract_type_ref, + .offset = offsetof(xen_pif_record, metrics) } }; const abstract_type xen_pif_record_abstract_type_ = @@ -90,6 +88,7 @@ xen_pif_record_free(xen_pif_record *record) xen_network_record_opt_free(record->network); xen_host_record_opt_free(record->host); free(record->mac); + xen_pif_metrics_record_opt_free(record->metrics); free(record); } @@ -235,23 +234,7 @@ xen_pif_get_vlan(xen_session *session, int64_t *result, xen_pif pif) bool -xen_pif_get_io_read_kbs(xen_session *session, double *result, xen_pif pif) -{ - abstract_value param_values[] = - { - { .type = &abstract_type_string, - .u.string_val = pif } - }; - - abstract_type result_type = abstract_type_float; - - XEN_CALL_("PIF.get_io_read_kbs"); - return session->ok; -} - - -bool -xen_pif_get_io_write_kbs(xen_session *session, double *result, xen_pif pif) +xen_pif_get_metrics(xen_session *session, xen_pif_metrics *result, xen_pif pif) { abstract_value param_values[] = { @@ -259,9 +242,10 @@ xen_pif_get_io_write_kbs(xen_session *session, double *result, xen_pif pif) .u.string_val = pif } }; - abstract_type result_type = abstract_type_float; + abstract_type result_type = abstract_type_string; - XEN_CALL_("PIF.get_io_write_kbs"); + *result = NULL; + XEN_CALL_("PIF.get_metrics"); return session->ok; } diff --git a/tools/libxen/src/xen_pif_metrics.c b/tools/libxen/src/xen_pif_metrics.c new file mode 100644 index 0000000000..3f09ae7dc1 --- /dev/null +++ b/tools/libxen/src/xen_pif_metrics.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2006, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include + +#include "xen_common.h" +#include "xen_internal.h" +#include "xen_pif.h" +#include "xen_pif_metrics.h" + + +XEN_FREE(xen_pif_metrics) +XEN_SET_ALLOC_FREE(xen_pif_metrics) +XEN_ALLOC(xen_pif_metrics_record) +XEN_SET_ALLOC_FREE(xen_pif_metrics_record) +XEN_ALLOC(xen_pif_metrics_record_opt) +XEN_RECORD_OPT_FREE(xen_pif_metrics) +XEN_SET_ALLOC_FREE(xen_pif_metrics_record_opt) + + +static const struct_member xen_pif_metrics_record_struct_members[] = + { + { .key = "uuid", + .type = &abstract_type_string, + .offset = offsetof(xen_pif_metrics_record, uuid) }, + { .key = "PIF", + .type = &abstract_type_ref, + .offset = offsetof(xen_pif_metrics_record, pif) }, + { .key = "io_read_kbs", + .type = &abstract_type_float, + .offset = offsetof(xen_pif_metrics_record, io_read_kbs) }, + { .key = "io_write_kbs", + .type = &abstract_type_float, + .offset = offsetof(xen_pif_metrics_record, io_write_kbs) } + }; + +const abstract_type xen_pif_metrics_record_abstract_type_ = + { + .typename = STRUCT, + .struct_size = sizeof(xen_pif_metrics_record), + .member_count = + sizeof(xen_pif_metrics_record_struct_members) / sizeof(struct_member), + .members = xen_pif_metrics_record_struct_members + }; + + +void +xen_pif_metrics_record_free(xen_pif_metrics_record *record) +{ + if (record == NULL) + { + return; + } + free(record->handle); + free(record->uuid); + xen_pif_record_opt_free(record->pif); + free(record); +} + + +bool +xen_pif_metrics_get_record(xen_session *session, xen_pif_metrics_record **result, xen_pif_metrics pif_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = pif_metrics } + }; + + abstract_type result_type = xen_pif_metrics_record_abstract_type_; + + *result = NULL; + XEN_CALL_("PIF_metrics.get_record"); + + if (session->ok) + { + (*result)->handle = xen_strdup_((*result)->uuid); + } + + return session->ok; +} + + +bool +xen_pif_metrics_get_by_uuid(xen_session *session, xen_pif_metrics *result, char *uuid) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = uuid } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("PIF_metrics.get_by_uuid"); + return session->ok; +} + + +bool +xen_pif_metrics_get_pif(xen_session *session, xen_pif *result, xen_pif_metrics pif_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = pif_metrics } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("PIF_metrics.get_PIF"); + return session->ok; +} + + +bool +xen_pif_metrics_get_io_read_kbs(xen_session *session, double *result, xen_pif_metrics pif_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = pif_metrics } + }; + + abstract_type result_type = abstract_type_float; + + XEN_CALL_("PIF_metrics.get_io_read_kbs"); + return session->ok; +} + + +bool +xen_pif_metrics_get_io_write_kbs(xen_session *session, double *result, xen_pif_metrics pif_metrics) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = pif_metrics } + }; + + abstract_type result_type = abstract_type_float; + + XEN_CALL_("PIF_metrics.get_io_write_kbs"); + return session->ok; +} + + +bool +xen_pif_metrics_get_uuid(xen_session *session, char **result, xen_pif_metrics pif_metrics) +{ + *result = session->ok ? xen_strdup_((char *)pif_metrics) : NULL; + return session->ok; +} diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 972c2b230b..cfc06fae09 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -12,7 +12,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ -# Copyright (C) 2006 XenSource Ltd. +# Copyright (C) 2006-2007 XenSource Ltd. #============================================================================ import inspect @@ -261,6 +261,17 @@ def valid_pif(func): _check_ref(lambda r: r in XendNode.instance().pifs, 'PIF_HANDLE_INVALID', func, *args, **kwargs) +def valid_pif_metrics(func): + """Decorator to verify if pif_metrics_ref is valid before calling + method. + + @param func: function with params: (self, session, pif_metrics_ref) + @rtype: callable object + """ + return lambda *args, **kwargs: \ + _check_ref(lambda r: r in XendNode.instance().pif_metrics, + 'PIF_METRICS_HANDLE_INVALID', func, *args, **kwargs) + def valid_task(func): """Decorator to verify if task_ref is valid before calling method. @@ -361,6 +372,7 @@ class XendAPI(object): 'console' : valid_console, 'SR' : valid_sr, 'PIF' : valid_pif, + 'PIF_metrics': valid_pif_metrics, 'task' : valid_task, 'debug' : valid_debug, } @@ -738,8 +750,7 @@ class XendAPI(object): # Xen API: Class PIF # ---------------------------------------------------------------- - PIF_attr_ro = ['io_read_kbs', - 'io_write_kbs'] + PIF_attr_ro = ['metrics'] PIF_attr_rw = ['device', 'network', 'host', @@ -767,6 +778,9 @@ class XendAPI(object): def PIF_get_all(self, _): return xen_api_success(XendNode.instance().pifs.keys()) + def PIF_get_metrics(self, _, ref): + return xen_api_success(self._get_PIF(ref).metrics.uuid) + def PIF_get_device(self, _, ref): return xen_api_success(self._get_PIF(ref).device) @@ -785,12 +799,6 @@ class XendAPI(object): def PIF_get_VLAN(self, _, ref): return xen_api_success(self._get_PIF(ref).vlan) - def PIF_get_io_read_kbs(self, _, ref): - return xen_api_success(self._get_PIF(ref).get_io_read_kbs()) - - def PIF_get_io_write_kbs(self, _, ref): - return xen_api_success(self._get_PIF(ref).get_io_write_kbs()) - def PIF_set_device(self, _, ref, device): return xen_api_success(self._get_PIF(ref).set_device(device)) @@ -821,6 +829,27 @@ class XendAPI(object): return xen_api_error(['VLAN_TAG_INVALID', vlan]) + # Xen API: Class PIF_metrics + # ---------------------------------------------------------------- + + PIF_metrics_attr_ro = ['io_read_kbs', + 'io_write_kbs'] + PIF_metrics_attr_rw = [] + PIF_methods = [] + + def _PIF_metrics_get(self, ref): + return XendNode.instance().pif_metrics[ref] + + def PIF_metrics_get_record(self, _, ref): + return xen_api_success(self._PIF_metrics_get(ref).get_record()) + + def PIF_metrics_get_io_read_kbs(self, _, ref): + return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs()) + + def PIF_metrics_get_io_write_kbs(self, _, ref): + return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs()) + + # Xen API: Class VM # ---------------------------------------------------------------- diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index e742477ee4..f4b9dbf33c 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -13,7 +13,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ # Copyright (C) 2004, 2005 Mike Wray -# Copyright (c) 2006 Xensource Inc. +# Copyright (c) 2006, 2007 Xensource Inc. #============================================================================ import os @@ -29,6 +29,7 @@ from xen.xend.XendQCoWStorageRepo import XendQCoWStorageRepo from xen.xend.XendLocalStorageRepo import XendLocalStorageRepo from xen.xend.XendLogging import log from xen.xend.XendPIF import * +from xen.xend.XendPIFMetrics import XendPIFMetrics from xen.xend.XendNetwork import * from xen.xend.XendStateStore import XendStateStore from xen.xend.XendMonitor import XendMonitor @@ -88,6 +89,7 @@ class XendNode: self.cpus[cpu_uuid] = cpu_info self.pifs = {} + self.pif_metrics = {} self.networks = {} self.srs = {} @@ -114,10 +116,14 @@ class XendNode: if 'device' not in pif and 'name' in pif: # Compatibility hack, can go pretty soon. pif['device'] = pif['name'] - + if 'metrics' not in pif: + # Compatibility hack, can go pretty soon. + pif['metrics'] = uuid.createString() + self._PIF_create(pif['device'], pif['MTU'], int(pif['VLAN']), - pif['MAC'], network, False, pif_uuid) + pif['MAC'], network, False, pif_uuid, + pif['metrics']) except NetworkAlreadyConnected, exn: log.error('Cannot load saved PIF %s, as network %s ' + 'is already connected to PIF %s', @@ -167,15 +173,23 @@ class XendNode: def _PIF_create(self, name, mtu, vlan, mac, network, persist = True, - pif_uuid = None): + pif_uuid = None, metrics_uuid = None): for pif in self.pifs.values(): if pif.network == network: raise NetworkAlreadyConnected(pif.uuid) if pif_uuid is None: pif_uuid = uuid.createString() - self.pifs[pif_uuid] = XendPIF(pif_uuid, name, mtu, vlan, mac, network, - self) + if metrics_uuid is None: + metrics_uuid = uuid.createString() + + metrics = XendPIFMetrics(metrics_uuid) + pif = XendPIF(pif_uuid, metrics, name, mtu, vlan, mac, network, self) + metrics.set_PIF(pif) + + self.pif_metrics[metrics_uuid] = metrics + self.pifs[pif_uuid] = pif + if persist: self.save_PIFs() self.refreshBridges() @@ -212,7 +226,7 @@ class XendNode: self.save_SRs() def save_PIFs(self): - pif_records = dict([(k, v.get_record(transient = False)) + pif_records = dict([(k, v.get_record()) for k, v in self.pifs.items()]) self.state_store.save_state('pif', pif_records) @@ -495,12 +509,6 @@ class XendNode: return vbd_loads[domid].get(vbdid, (0.0, 0.0)) return (0.0, 0.0) - def get_pif_util(self, pifname): - pifs_util = self.monitor.get_pifs_util() - if pifname in pifs_util: - return pifs_util[pifname] - return (0.0, 0.0) - # dictionary version of *info() functions to get rid of # SXPisms. def nodeinfo_dict(self): diff --git a/tools/python/xen/xend/XendPIF.py b/tools/python/xen/xend/XendPIF.py index b7c9c27320..6c8fcae6d6 100644 --- a/tools/python/xen/xend/XendPIF.py +++ b/tools/python/xen/xend/XendPIF.py @@ -90,8 +90,10 @@ def linux_set_mtu(iface, mtu): class XendPIF: """Representation of a Physical Network Interface.""" - def __init__(self, uuid, device, mtu, vlan, mac, network, host): + def __init__(self, uuid, metrics, device, mtu, vlan, mac, network, + host): self.uuid = uuid + self.metrics = metrics self.device = device self.mac = mac self.mtu = mtu @@ -114,26 +116,14 @@ class XendPIF: self.mtu = new_mtu return success - def get_io_read_kbs(self): - from xen.xend.XendNode import instance as xennode - return xennode().get_pif_util(self.device)[0] - - def get_io_write_kbs(self): - from xen.xend.XendNode import instance as xennode - return xennode().get_pif_util(self.device)[1] - - def get_record(self, transient = True): - result = {'device': self.device, - 'MAC': self.mac, - 'MTU': self.mtu, - 'VLAN': self.vlan, - 'host': self.host.uuid, - 'network': self.network.uuid} - if transient: - result['io_read_kbs'] = self.get_io_read_kbs() - result['io_write_kbs'] = self.get_io_write_kbs() - return result - + def get_record(self): + return {'device': self.device, + 'MAC': self.mac, + 'MTU': self.mtu, + 'VLAN': self.vlan, + 'host': self.host.uuid, + 'network': self.network.uuid, + 'metrics': self.metrics.uuid} def refresh(self, bridges): ifname = self.interface_name() diff --git a/tools/python/xen/xend/XendPIFMetrics.py b/tools/python/xen/xend/XendPIFMetrics.py new file mode 100644 index 0000000000..68b32f1653 --- /dev/null +++ b/tools/python/xen/xend/XendPIFMetrics.py @@ -0,0 +1,46 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# 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 +#============================================================================ +# Copyright (c) 2006-2007 Xensource Inc. +#============================================================================ + + +class XendPIFMetrics: + """PIF Metrics.""" + + def __init__(self, uuid): + self.uuid = uuid + + def set_PIF(self, pif): + self.pif = pif + + def get_io_read_kbs(self): + return self._get_stat(0) + + def get_io_write_kbs(self): + return self._get_stat(1) + + def _get_stat(self, n): + from xen.xend.XendNode import instance as xennode + pifname = self.pif.device + pifs_util = xennode().monitor.get_pifs_util() + if pifname in pifs_util: + return pifs_util[pifname][n] + return 0.0 + + def get_record(self): + return {'PIF' : self.pif.uuid, + 'io_read_kbs' : self.get_io_read_kbs(), + 'io_write_kbs' : self.get_io_write_kbs() + } diff --git a/tools/python/xen/xm/messages/en/xen-xm.po b/tools/python/xen/xm/messages/en/xen-xm.po index 50dc3eef14..52e0237dc4 100644 --- a/tools/python/xen/xm/messages/en/xen-xm.po +++ b/tools/python/xen/xm/messages/en/xen-xm.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Xen-xm 3.0\n" -"PO-Revision-Date: 2007-01-28 21:58+0000\n" +"PO-Revision-Date: 2007-01-29 18:50+0000\n" "Last-Translator: Ewan Mellor \n" "Language-Team: xen-devel \n" "MIME-Version: 1.0\n" @@ -47,6 +47,12 @@ msgstr "The host_cpu handle %(1)s is invalid." msgid "HOST_HANDLE_INVALID" msgstr "The host handle %(1)s is invalid." +msgid "PIF_HANDLE_INVALID" +msgstr "The PIF handle %(1)s is invalid." + +msgid "PIF_METRICS_HANDLE_INVALID" +msgstr "The PIF_METRICS handle %(1)s is invalid." + msgid "SR_HANDLE_INVALID" msgstr "The SR handle %(1)s is invalid." -- 2.30.2