debuggers.hg
changeset 14681:414735d45904
Added asynchronous event notification through the Xen-API. Added a new command,
xm event-monitor, a new test program for the C bindings, and new bindings
themselves.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
xm event-monitor, a new test program for the C bindings, and new bindings
themselves.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
author | Ewan Mellor <ewan@xensource.com> |
---|---|
date | Thu Mar 29 15:46:30 2007 +0100 (2007-03-29) |
parents | 121fb4046945 |
children | dd844ac0c289 |
files | .hgignore docs/xen-api/xenapi-datamodel.tex tools/libxen/Makefile tools/libxen/include/xen_event.h tools/libxen/include/xen_event_decl.h tools/libxen/include/xen_event_operation.h tools/libxen/include/xen_event_operation_internal.h tools/libxen/src/xen_event.c tools/libxen/src/xen_event_operation.c tools/libxen/test/test_event_handling.c tools/python/xen/xend/XendAPI.py tools/python/xen/xm/main.py |
line diff
1.1 --- a/.hgignore Thu Mar 29 15:22:02 2007 +0100 1.2 +++ b/.hgignore Thu Mar 29 15:46:30 2007 +0100 1.3 @@ -126,6 +126,7 @@ 1.4 ^tools/ioemu/qemu\.pod$ 1.5 ^tools/libxc/xen/.*$ 1.6 ^tools/libxen/test/test_bindings$ 1.7 +^tools/libxen/test/test_event_handling$ 1.8 ^tools/libaio/src/.*\.ol$ 1.9 ^tools/libaio/src/.*\.os$ 1.10 ^tools/misc/cpuperf/cpuperf-perfcntr$
2.1 --- a/docs/xen-api/xenapi-datamodel.tex Thu Mar 29 15:22:02 2007 +0100 2.2 +++ b/docs/xen-api/xenapi-datamodel.tex Thu Mar 29 15:46:30 2007 +0100 2.3 @@ -24,6 +24,7 @@ Name & Description \\ 2.4 \hline 2.5 {\tt session} & A session \\ 2.6 {\tt task} & A long-running asynchronous task \\ 2.7 +{\tt event} & Asynchronous event registration and handling \\ 2.8 {\tt VM} & A virtual machine (or 'guest') \\ 2.9 {\tt VM\_metrics} & The metrics associated with a VM \\ 2.10 {\tt VM\_guest\_metrics} & The metrics reported by the guest (as opposed to inferred from outside) \\ 2.11 @@ -112,6 +113,17 @@ The following enumeration types are used 2.12 2.13 \begin{longtable}{|ll|} 2.14 \hline 2.15 +{\tt enum event\_operation} & \\ 2.16 +\hline 2.17 +\hspace{0.5cm}{\tt add} & An object has been created \\ 2.18 +\hspace{0.5cm}{\tt del} & An object has been deleted \\ 2.19 +\hspace{0.5cm}{\tt mod} & An object has been modified \\ 2.20 +\hline 2.21 +\end{longtable} 2.22 + 2.23 +\vspace{1cm} 2.24 +\begin{longtable}{|ll|} 2.25 +\hline 2.26 {\tt enum console\_protocol} & \\ 2.27 \hline 2.28 \hspace{0.5cm}{\tt vt100} & VT100 terminal \\ 2.29 @@ -1016,6 +1028,114 @@ references to objects with match names 2.30 2.31 \vspace{1cm} 2.32 \newpage 2.33 +\section{Class: event} 2.34 +\subsection{Fields for class: event} 2.35 +\begin{longtable}{|lllp{0.38\textwidth}|} 2.36 +\hline 2.37 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf event} \\ 2.38 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em 2.39 +Asynchronous event registration and handling.}} \\ 2.40 +\hline 2.41 +Quals & Field & Type & Description \\ 2.42 +\hline 2.43 +$\mathit{RO}_\mathit{ins}$ & {\tt id} & int & An ID, monotonically increasing, and local to the current session \\ 2.44 +$\mathit{RO}_\mathit{ins}$ & {\tt timestamp} & datetime & The time at which the event occurred \\ 2.45 +$\mathit{RO}_\mathit{ins}$ & {\tt class} & string & The name of the class of the object that changed \\ 2.46 +$\mathit{RO}_\mathit{ins}$ & {\tt operation} & event\_operation & The operation that was performed \\ 2.47 +$\mathit{RO}_\mathit{ins}$ & {\tt ref} & string & A reference to the object that changed \\ 2.48 +$\mathit{RO}_\mathit{ins}$ & {\tt obj\_uuid} & string & The uuid of the object that changed \\ 2.49 +\hline 2.50 +\end{longtable} 2.51 +\subsection{RPCs associated with class: event} 2.52 +\subsubsection{RPC name:~register} 2.53 + 2.54 +{\bf Overview:} 2.55 +Registers this session with the event system. Specifying the empty list 2.56 +will register for all classes. 2.57 + 2.58 + \noindent {\bf Signature:} 2.59 +\begin{verbatim} void register (session_id s, string Set classes)\end{verbatim} 2.60 + 2.61 + 2.62 +\noindent{\bf Arguments:} 2.63 + 2.64 + 2.65 +\vspace{0.3cm} 2.66 +\begin{tabular}{|c|c|p{7cm}|} 2.67 + \hline 2.68 +{\bf type} & {\bf name} & {\bf description} \\ \hline 2.69 +{\tt string Set } & classes & register for events for the indicated classes \\ \hline 2.70 + 2.71 +\end{tabular} 2.72 + 2.73 +\vspace{0.3cm} 2.74 + 2.75 + \noindent {\bf Return Type:} 2.76 +{\tt 2.77 +void 2.78 +} 2.79 + 2.80 + 2.81 + 2.82 +\vspace{0.3cm} 2.83 +\vspace{0.3cm} 2.84 +\vspace{0.3cm} 2.85 +\subsubsection{RPC name:~unregister} 2.86 + 2.87 +{\bf Overview:} 2.88 +Unregisters this session with the event system. 2.89 + 2.90 + \noindent {\bf Signature:} 2.91 +\begin{verbatim} void unregister (session_id s, string Set classes)\end{verbatim} 2.92 + 2.93 + 2.94 +\noindent{\bf Arguments:} 2.95 + 2.96 + 2.97 +\vspace{0.3cm} 2.98 +\begin{tabular}{|c|c|p{7cm}|} 2.99 + \hline 2.100 +{\bf type} & {\bf name} & {\bf description} \\ \hline 2.101 +{\tt string Set } & classes & remove this session's registration for the indicated classes \\ \hline 2.102 + 2.103 +\end{tabular} 2.104 + 2.105 +\vspace{0.3cm} 2.106 + 2.107 + \noindent {\bf Return Type:} 2.108 +{\tt 2.109 +void 2.110 +} 2.111 + 2.112 + 2.113 + 2.114 +\vspace{0.3cm} 2.115 +\vspace{0.3cm} 2.116 +\vspace{0.3cm} 2.117 +\subsubsection{RPC name:~next} 2.118 + 2.119 +{\bf Overview:} 2.120 +Blocking call which returns a (possibly empty) batch of events. 2.121 + 2.122 + \noindent {\bf Signature:} 2.123 +\begin{verbatim} ((event record) Set) next (session_id s)\end{verbatim} 2.124 + 2.125 + 2.126 +\vspace{0.3cm} 2.127 + 2.128 + \noindent {\bf Return Type:} 2.129 +{\tt 2.130 +(event record) Set 2.131 +} 2.132 + 2.133 + 2.134 +the batch of events 2.135 +\vspace{0.3cm} 2.136 +\vspace{0.3cm} 2.137 +\vspace{0.3cm} 2.138 + 2.139 +\vspace{1cm} 2.140 +\newpage 2.141 \section{Class: VM} 2.142 \subsection{Fields for class: VM} 2.143 \begin{longtable}{|lllp{0.38\textwidth}|}
3.1 --- a/tools/libxen/Makefile Thu Mar 29 15:22:02 2007 +0100 3.2 +++ b/tools/libxen/Makefile Thu Mar 29 15:46:30 2007 +0100 3.3 @@ -51,6 +51,9 @@ libxenapi.a: $(LIBXENAPI_OBJS) 3.4 test/test_bindings: test/test_bindings.o libxenapi.so 3.5 $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi 3.6 3.7 +test/test_event_handling: test/test_event_handling.o libxenapi.so 3.8 + $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi 3.9 + 3.10 test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so 3.11 $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi 3.12
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/tools/libxen/include/xen_event.h Thu Mar 29 15:46:30 2007 +0100 4.3 @@ -0,0 +1,102 @@ 4.4 +/* 4.5 + * Copyright (c) 2006-2007, XenSource Inc. 4.6 + * 4.7 + * This library is free software; you can redistribute it and/or 4.8 + * modify it under the terms of the GNU Lesser General Public 4.9 + * License as published by the Free Software Foundation; either 4.10 + * version 2.1 of the License, or (at your option) any later version. 4.11 + * 4.12 + * This library is distributed in the hope that it will be useful, 4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4.15 + * Lesser General Public License for more details. 4.16 + * 4.17 + * You should have received a copy of the GNU Lesser General Public 4.18 + * License along with this library; if not, write to the Free Software 4.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 4.20 + */ 4.21 + 4.22 +#ifndef XEN_EVENT_H 4.23 +#define XEN_EVENT_H 4.24 + 4.25 +#include "xen_common.h" 4.26 +#include "xen_event_decl.h" 4.27 +#include "xen_event_operation.h" 4.28 +#include "xen_string_set.h" 4.29 + 4.30 + 4.31 +/* 4.32 + * The event class. 4.33 + * 4.34 + * Asynchronous event registration and handling. 4.35 + */ 4.36 + 4.37 + 4.38 + 4.39 +typedef struct xen_event_record 4.40 +{ 4.41 + int64_t id; 4.42 + time_t timestamp; 4.43 + char *class; 4.44 + enum xen_event_operation operation; 4.45 + char *ref; 4.46 + char *obj_uuid; 4.47 +} xen_event_record; 4.48 + 4.49 +/** 4.50 + * Allocate a xen_event_record. 4.51 + */ 4.52 +extern xen_event_record * 4.53 +xen_event_record_alloc(void); 4.54 + 4.55 +/** 4.56 + * Free the given xen_event_record, and all referenced values. The 4.57 + * given record must have been allocated by this library. 4.58 + */ 4.59 +extern void 4.60 +xen_event_record_free(xen_event_record *record); 4.61 + 4.62 + 4.63 +typedef struct xen_event_record_set 4.64 +{ 4.65 + size_t size; 4.66 + xen_event_record *contents[]; 4.67 +} xen_event_record_set; 4.68 + 4.69 +/** 4.70 + * Allocate a xen_event_record_set of the given size. 4.71 + */ 4.72 +extern xen_event_record_set * 4.73 +xen_event_record_set_alloc(size_t size); 4.74 + 4.75 +/** 4.76 + * Free the given xen_event_record_set, and all referenced values. The 4.77 + * given set must have been allocated by this library. 4.78 + */ 4.79 +extern void 4.80 +xen_event_record_set_free(xen_event_record_set *set); 4.81 + 4.82 + 4.83 +/** 4.84 + * Registers this session with the event system. Specifying the empty 4.85 + * list will register for all classes. 4.86 + */ 4.87 +extern bool 4.88 +xen_event_register(xen_session *session, struct xen_string_set *classes); 4.89 + 4.90 + 4.91 +/** 4.92 + * Unregisters this session with the event system. 4.93 + */ 4.94 +extern bool 4.95 +xen_event_unregister(xen_session *session, struct xen_string_set *classes); 4.96 + 4.97 + 4.98 +/** 4.99 + * Blocking call which returns a (possibly empty) batch of events. 4.100 + */ 4.101 +extern bool 4.102 +xen_event_next(xen_session *session, struct xen_event_record_set **result); 4.103 + 4.104 + 4.105 +#endif
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/tools/libxen/include/xen_event_decl.h Thu Mar 29 15:46:30 2007 +0100 5.3 @@ -0,0 +1,25 @@ 5.4 +/* 5.5 + * Copyright (c) 2006-2007, XenSource Inc. 5.6 + * 5.7 + * This library is free software; you can redistribute it and/or 5.8 + * modify it under the terms of the GNU Lesser General Public 5.9 + * License as published by the Free Software Foundation; either 5.10 + * version 2.1 of the License, or (at your option) any later version. 5.11 + * 5.12 + * This library is distributed in the hope that it will be useful, 5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5.15 + * Lesser General Public License for more details. 5.16 + * 5.17 + * You should have received a copy of the GNU Lesser General Public 5.18 + * License along with this library; if not, write to the Free Software 5.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 5.20 + */ 5.21 + 5.22 +#ifndef XEN_EVENT_DECL_H 5.23 +#define XEN_EVENT_DECL_H 5.24 + 5.25 +struct xen_event_record; 5.26 +struct xen_event_record_set; 5.27 + 5.28 +#endif
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/tools/libxen/include/xen_event_operation.h Thu Mar 29 15:46:30 2007 +0100 6.3 @@ -0,0 +1,82 @@ 6.4 +/* 6.5 + * Copyright (c) 2006-2007, XenSource Inc. 6.6 + * 6.7 + * This library is free software; you can redistribute it and/or 6.8 + * modify it under the terms of the GNU Lesser General Public 6.9 + * License as published by the Free Software Foundation; either 6.10 + * version 2.1 of the License, or (at your option) any later version. 6.11 + * 6.12 + * This library is distributed in the hope that it will be useful, 6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6.15 + * Lesser General Public License for more details. 6.16 + * 6.17 + * You should have received a copy of the GNU Lesser General Public 6.18 + * License along with this library; if not, write to the Free Software 6.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6.20 + */ 6.21 + 6.22 +#ifndef XEN_EVENT_OPERATION_H 6.23 +#define XEN_EVENT_OPERATION_H 6.24 + 6.25 + 6.26 +#include "xen_common.h" 6.27 + 6.28 + 6.29 +enum xen_event_operation 6.30 +{ 6.31 + /** 6.32 + * An object has been created 6.33 + */ 6.34 + XEN_EVENT_OPERATION_ADD, 6.35 + 6.36 + /** 6.37 + * An object has been deleted 6.38 + */ 6.39 + XEN_EVENT_OPERATION_DEL, 6.40 + 6.41 + /** 6.42 + * An object has been modified 6.43 + */ 6.44 + XEN_EVENT_OPERATION_MOD 6.45 +}; 6.46 + 6.47 + 6.48 +typedef struct xen_event_operation_set 6.49 +{ 6.50 + size_t size; 6.51 + enum xen_event_operation contents[]; 6.52 +} xen_event_operation_set; 6.53 + 6.54 +/** 6.55 + * Allocate a xen_event_operation_set of the given size. 6.56 + */ 6.57 +extern xen_event_operation_set * 6.58 +xen_event_operation_set_alloc(size_t size); 6.59 + 6.60 +/** 6.61 + * Free the given xen_event_operation_set. The given set must have 6.62 + * been allocated by this library. 6.63 + */ 6.64 +extern void 6.65 +xen_event_operation_set_free(xen_event_operation_set *set); 6.66 + 6.67 + 6.68 +/** 6.69 + * Return the name corresponding to the given code. This string must 6.70 + * not be modified or freed. 6.71 + */ 6.72 +extern const char * 6.73 +xen_event_operation_to_string(enum xen_event_operation val); 6.74 + 6.75 + 6.76 +/** 6.77 + * Return the correct code for the given string, or set the session 6.78 + * object to failure and return an undefined value if the given string does 6.79 + * not match a known code. 6.80 + */ 6.81 +extern enum xen_event_operation 6.82 +xen_event_operation_from_string(xen_session *session, const char *str); 6.83 + 6.84 + 6.85 +#endif
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/tools/libxen/include/xen_event_operation_internal.h Thu Mar 29 15:46:30 2007 +0100 7.3 @@ -0,0 +1,37 @@ 7.4 +/* 7.5 + * Copyright (c) 2006-2007, XenSource Inc. 7.6 + * 7.7 + * This library is free software; you can redistribute it and/or 7.8 + * modify it under the terms of the GNU Lesser General Public 7.9 + * License as published by the Free Software Foundation; either 7.10 + * version 2.1 of the License, or (at your option) any later version. 7.11 + * 7.12 + * This library is distributed in the hope that it will be useful, 7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7.15 + * Lesser General Public License for more details. 7.16 + * 7.17 + * You should have received a copy of the GNU Lesser General Public 7.18 + * License along with this library; if not, write to the Free Software 7.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7.20 + */ 7.21 + 7.22 + 7.23 +/* 7.24 + * Declarations of the abstract types used during demarshalling of enum 7.25 + * xen_event_operation. Internal to this library -- do not use from outside. 7.26 + */ 7.27 + 7.28 + 7.29 +#ifndef XEN_EVENT_OPERATION_INTERNAL_H 7.30 +#define XEN_EVENT_OPERATION_INTERNAL_H 7.31 + 7.32 + 7.33 +#include "xen_internal.h" 7.34 + 7.35 + 7.36 +extern const abstract_type xen_event_operation_abstract_type_; 7.37 +extern const abstract_type xen_event_operation_set_abstract_type_; 7.38 + 7.39 + 7.40 +#endif
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/tools/libxen/src/xen_event.c Thu Mar 29 15:46:30 2007 +0100 8.3 @@ -0,0 +1,123 @@ 8.4 +/* 8.5 + * Copyright (c) 2006-2007, XenSource Inc. 8.6 + * 8.7 + * This library is free software; you can redistribute it and/or 8.8 + * modify it under the terms of the GNU Lesser General Public 8.9 + * License as published by the Free Software Foundation; either 8.10 + * version 2.1 of the License, or (at your option) any later version. 8.11 + * 8.12 + * This library is distributed in the hope that it will be useful, 8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8.15 + * Lesser General Public License for more details. 8.16 + * 8.17 + * You should have received a copy of the GNU Lesser General Public 8.18 + * License along with this library; if not, write to the Free Software 8.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 8.20 + */ 8.21 + 8.22 + 8.23 +#include <stddef.h> 8.24 +#include <stdlib.h> 8.25 + 8.26 +#include "xen_common.h" 8.27 +#include "xen_event.h" 8.28 +#include "xen_event_operation_internal.h" 8.29 +#include "xen_internal.h" 8.30 + 8.31 + 8.32 +XEN_ALLOC(xen_event_record) 8.33 +XEN_SET_ALLOC_FREE(xen_event_record) 8.34 + 8.35 + 8.36 +static const struct_member xen_event_record_struct_members[] = 8.37 + { 8.38 + { .key = "id", 8.39 + .type = &abstract_type_int, 8.40 + .offset = offsetof(xen_event_record, id) }, 8.41 + { .key = "timestamp", 8.42 + .type = &abstract_type_datetime, 8.43 + .offset = offsetof(xen_event_record, timestamp) }, 8.44 + { .key = "class", 8.45 + .type = &abstract_type_string, 8.46 + .offset = offsetof(xen_event_record, class) }, 8.47 + { .key = "operation", 8.48 + .type = &xen_event_operation_abstract_type_, 8.49 + .offset = offsetof(xen_event_record, operation) }, 8.50 + { .key = "ref", 8.51 + .type = &abstract_type_string, 8.52 + .offset = offsetof(xen_event_record, ref) }, 8.53 + { .key = "obj_uuid", 8.54 + .type = &abstract_type_string, 8.55 + .offset = offsetof(xen_event_record, obj_uuid) } 8.56 + }; 8.57 + 8.58 +const abstract_type xen_event_record_abstract_type_ = 8.59 + { 8.60 + .typename = STRUCT, 8.61 + .struct_size = sizeof(xen_event_record), 8.62 + .member_count = 8.63 + sizeof(xen_event_record_struct_members) / sizeof(struct_member), 8.64 + .members = xen_event_record_struct_members 8.65 + }; 8.66 + 8.67 + 8.68 +const abstract_type xen_event_record_set_abstract_type_ = 8.69 + { 8.70 + .typename = SET, 8.71 + .child = &xen_event_record_abstract_type_ 8.72 + }; 8.73 + 8.74 + 8.75 +void 8.76 +xen_event_record_free(xen_event_record *record) 8.77 +{ 8.78 + if (record == NULL) 8.79 + { 8.80 + return; 8.81 + } 8.82 + free(record->class); 8.83 + free(record->ref); 8.84 + free(record->obj_uuid); 8.85 + free(record); 8.86 +} 8.87 + 8.88 + 8.89 +bool 8.90 +xen_event_register(xen_session *session, struct xen_string_set *classes) 8.91 +{ 8.92 + abstract_value param_values[] = 8.93 + { 8.94 + { .type = &abstract_type_string_set, 8.95 + .u.set_val = (arbitrary_set *)classes } 8.96 + }; 8.97 + 8.98 + xen_call_(session, "event.register", param_values, 1, NULL, NULL); 8.99 + return session->ok; 8.100 +} 8.101 + 8.102 + 8.103 +bool 8.104 +xen_event_unregister(xen_session *session, struct xen_string_set *classes) 8.105 +{ 8.106 + abstract_value param_values[] = 8.107 + { 8.108 + { .type = &abstract_type_string_set, 8.109 + .u.set_val = (arbitrary_set *)classes } 8.110 + }; 8.111 + 8.112 + xen_call_(session, "event.unregister", param_values, 1, NULL, NULL); 8.113 + return session->ok; 8.114 +} 8.115 + 8.116 + 8.117 +bool 8.118 +xen_event_next(xen_session *session, struct xen_event_record_set **result) 8.119 +{ 8.120 + 8.121 + abstract_type result_type = xen_event_record_set_abstract_type_; 8.122 + 8.123 + *result = NULL; 8.124 + xen_call_(session, "event.next", NULL, 0, &result_type, result); 8.125 + return session->ok; 8.126 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tools/libxen/src/xen_event_operation.c Thu Mar 29 15:46:30 2007 +0100 9.3 @@ -0,0 +1,75 @@ 9.4 +/* 9.5 + * Copyright (c) 2006-2007, XenSource Inc. 9.6 + * 9.7 + * This library is free software; you can redistribute it and/or 9.8 + * modify it under the terms of the GNU Lesser General Public 9.9 + * License as published by the Free Software Foundation; either 9.10 + * version 2.1 of the License, or (at your option) any later version. 9.11 + * 9.12 + * This library is distributed in the hope that it will be useful, 9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9.15 + * Lesser General Public License for more details. 9.16 + * 9.17 + * You should have received a copy of the GNU Lesser General Public 9.18 + * License along with this library; if not, write to the Free Software 9.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 9.20 + */ 9.21 + 9.22 +#include <string.h> 9.23 + 9.24 +#include "xen_internal.h" 9.25 +#include "xen_event_operation.h" 9.26 +#include "xen_event_operation_internal.h" 9.27 + 9.28 + 9.29 +/* 9.30 + * Maintain this in the same order as the enum declaration! 9.31 + */ 9.32 +static const char *lookup_table[] = 9.33 +{ 9.34 + "add", 9.35 + "del", 9.36 + "mod" 9.37 +}; 9.38 + 9.39 + 9.40 +extern xen_event_operation_set * 9.41 +xen_event_operation_set_alloc(size_t size) 9.42 +{ 9.43 + return calloc(1, sizeof(xen_event_operation_set) + 9.44 + size * sizeof(enum xen_event_operation)); 9.45 +} 9.46 + 9.47 + 9.48 +extern void 9.49 +xen_event_operation_set_free(xen_event_operation_set *set) 9.50 +{ 9.51 + free(set); 9.52 +} 9.53 + 9.54 + 9.55 +const char * 9.56 +xen_event_operation_to_string(enum xen_event_operation val) 9.57 +{ 9.58 + return lookup_table[val]; 9.59 +} 9.60 + 9.61 + 9.62 +extern enum xen_event_operation 9.63 +xen_event_operation_from_string(xen_session *session, const char *str) 9.64 +{ 9.65 + return ENUM_LOOKUP(session, str, lookup_table); 9.66 +} 9.67 + 9.68 + 9.69 +const abstract_type xen_event_operation_abstract_type_ = 9.70 + { 9.71 + .typename = ENUM, 9.72 + .enum_marshaller = 9.73 + (const char *(*)(int))&xen_event_operation_to_string, 9.74 + .enum_demarshaller = 9.75 + (int (*)(xen_session *, const char *))&xen_event_operation_from_string 9.76 + }; 9.77 + 9.78 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/libxen/test/test_event_handling.c Thu Mar 29 15:46:30 2007 +0100 10.3 @@ -0,0 +1,211 @@ 10.4 +/* 10.5 + * Copyright (c) 2006-2007 XenSource, Inc. 10.6 + * 10.7 + * This library is free software; you can redistribute it and/or 10.8 + * modify it under the terms of the GNU Lesser General Public 10.9 + * License as published by the Free Software Foundation; either 10.10 + * version 2.1 of the License, or (at your option) any later version. 10.11 + * 10.12 + * This library is distributed in the hope that it will be useful, 10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10.15 + * Lesser General Public License for more details. 10.16 + * 10.17 + * You should have received a copy of the GNU Lesser General Public 10.18 + * License along with this library; if not, write to the Free Software 10.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 10.20 + */ 10.21 + 10.22 +#define _GNU_SOURCE 10.23 +#include <assert.h> 10.24 +#include <inttypes.h> 10.25 +#include <stdlib.h> 10.26 +#include <stdio.h> 10.27 +#include <string.h> 10.28 + 10.29 +#include <libxml/parser.h> 10.30 +#include <curl/curl.h> 10.31 + 10.32 +#include "xen_event.h" 10.33 + 10.34 +//#define PRINT_XML 10.35 + 10.36 +static void usage() 10.37 +{ 10.38 + fprintf(stderr, 10.39 +"Usage:\n" 10.40 +"\n" 10.41 +" test_event_handling <server> <username> <password>\n" 10.42 +"\n" 10.43 +"where\n" 10.44 +" <server> is the server's host and port, e.g. localhost:9363;\n" 10.45 +" <username> is the username to use at the server; and\n" 10.46 +" <password> is the password.\n"); 10.47 + 10.48 + exit(EXIT_FAILURE); 10.49 +} 10.50 + 10.51 + 10.52 +static char *url; 10.53 + 10.54 + 10.55 +typedef struct 10.56 +{ 10.57 + xen_result_func func; 10.58 + void *handle; 10.59 +} xen_comms; 10.60 + 10.61 + 10.62 +static size_t 10.63 +write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms) 10.64 +{ 10.65 + size_t n = size * nmemb; 10.66 +#ifdef PRINT_XML 10.67 + printf("\n\n---Result from server -----------------------\n"); 10.68 + printf("%s\n",((char*) ptr)); 10.69 + fflush(stdout); 10.70 +#endif 10.71 + return comms->func(ptr, n, comms->handle) ? n : 0; 10.72 +} 10.73 + 10.74 + 10.75 +static int 10.76 +call_func(const void *data, size_t len, void *user_handle, 10.77 + void *result_handle, xen_result_func result_func) 10.78 +{ 10.79 + (void)user_handle; 10.80 + 10.81 +#ifdef PRINT_XML 10.82 + printf("\n\n---Data to server: -----------------------\n"); 10.83 + printf("%s\n",((char*) data)); 10.84 + fflush(stdout); 10.85 +#endif 10.86 + 10.87 + CURL *curl = curl_easy_init(); 10.88 + if (!curl) { 10.89 + return -1; 10.90 + } 10.91 + 10.92 + xen_comms comms = { 10.93 + .func = result_func, 10.94 + .handle = result_handle 10.95 + }; 10.96 + 10.97 + curl_easy_setopt(curl, CURLOPT_URL, url); 10.98 + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); 10.99 + curl_easy_setopt(curl, CURLOPT_MUTE, 1); 10.100 + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func); 10.101 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms); 10.102 + curl_easy_setopt(curl, CURLOPT_POST, 1); 10.103 + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); 10.104 + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len); 10.105 + 10.106 + CURLcode result = curl_easy_perform(curl); 10.107 + 10.108 + curl_easy_cleanup(curl); 10.109 + 10.110 + return result; 10.111 +} 10.112 + 10.113 + 10.114 +static void print_error(xen_session *session) 10.115 +{ 10.116 + fprintf(stderr, "Error: %d", session->error_description_count); 10.117 + for (int i = 0; i < session->error_description_count; i++) 10.118 + { 10.119 + fprintf(stderr, "%s ", session->error_description[i]); 10.120 + } 10.121 + fprintf(stderr, "\n"); 10.122 +} 10.123 + 10.124 + 10.125 +/** 10.126 + * Workaround for whinging GCCs, as suggested by strftime(3). 10.127 + */ 10.128 +static size_t my_strftime(char *s, size_t max, const char *fmt, 10.129 + const struct tm *tm) 10.130 +{ 10.131 + return strftime(s, max, fmt, tm); 10.132 +} 10.133 + 10.134 + 10.135 +int main(int argc, char **argv) 10.136 +{ 10.137 + if (argc != 4) 10.138 + { 10.139 + usage(); 10.140 + } 10.141 + 10.142 + url = argv[1]; 10.143 + char *username = argv[2]; 10.144 + char *password = argv[3]; 10.145 + 10.146 + xmlInitParser(); 10.147 + xen_init(); 10.148 + curl_global_init(CURL_GLOBAL_ALL); 10.149 + 10.150 +#define CLEANUP \ 10.151 + do { \ 10.152 + xen_session_logout(session); \ 10.153 + curl_global_cleanup(); \ 10.154 + xen_fini(); \ 10.155 + xmlCleanupParser(); \ 10.156 + } while(0) \ 10.157 + 10.158 + 10.159 + xen_session *session = 10.160 + xen_session_login_with_password(call_func, NULL, username, password); 10.161 + 10.162 + struct xen_string_set *classes = xen_string_set_alloc(0); 10.163 + xen_event_register(session, classes); 10.164 + xen_string_set_free(classes); 10.165 + 10.166 + if (!session->ok) 10.167 + { 10.168 + print_error(session); 10.169 + CLEANUP; 10.170 + return 1; 10.171 + } 10.172 + 10.173 + while (true) 10.174 + { 10.175 + struct xen_event_record_set *events; 10.176 + if (!xen_event_next(session, &events)) 10.177 + { 10.178 + print_error(session); 10.179 + CLEANUP; 10.180 + return 1; 10.181 + } 10.182 + 10.183 + for (size_t i = 0; i < events->size; i++) 10.184 + { 10.185 + xen_event_record *ev = events->contents[i]; 10.186 + char time[256]; 10.187 + struct tm *tm = localtime(&ev->timestamp); 10.188 + my_strftime(time, 256, "%c, local time", tm); 10.189 + printf("Event received: ID = %"PRId64", %s.\n", ev->id, time); 10.190 + switch (ev->operation) 10.191 + { 10.192 + case XEN_EVENT_OPERATIONS_ADD: 10.193 + printf("%s created with UUID %s.\n", ev->class, ev->obj_uuid); 10.194 + break; 10.195 + 10.196 + case XEN_EVENT_OPERATIONS_DEL: 10.197 + printf("%s with UUID %s deleted.\n", ev->class, ev->obj_uuid); 10.198 + break; 10.199 + 10.200 + case XEN_EVENT_OPERATIONS_MOD: 10.201 + printf("%s with UUID %s modified.\n", ev->class, ev->obj_uuid); 10.202 + break; 10.203 + default: 10.204 + assert(false); 10.205 + } 10.206 + } 10.207 + 10.208 + xen_event_record_set_free(events); 10.209 + } 10.210 + 10.211 + CLEANUP; 10.212 + 10.213 + return 0; 10.214 +}
11.1 --- a/tools/python/xen/xend/XendAPI.py Thu Mar 29 15:22:02 2007 +0100 11.2 +++ b/tools/python/xen/xend/XendAPI.py Thu Mar 29 15:46:30 2007 +0100 11.3 @@ -17,6 +17,8 @@ 11.4 11.5 import inspect 11.6 import os 11.7 +import Queue 11.8 +import sets 11.9 import string 11.10 import sys 11.11 import traceback 11.12 @@ -87,6 +89,91 @@ def now(): 11.13 11.14 11.15 # --------------------------------------------------- 11.16 +# Event dispatch 11.17 +# --------------------------------------------------- 11.18 + 11.19 +EVENT_QUEUE_LENGTH = 50 11.20 +event_registrations = {} 11.21 + 11.22 +def event_register(session, reg_classes): 11.23 + if session not in event_registrations: 11.24 + event_registrations[session] = { 11.25 + 'classes' : sets.Set(), 11.26 + 'queue' : Queue.Queue(EVENT_QUEUE_LENGTH), 11.27 + 'next-id' : 1 11.28 + } 11.29 + if not reg_classes: 11.30 + reg_classes = classes 11.31 + event_registrations[session]['classes'].union_update(reg_classes) 11.32 + 11.33 + 11.34 +def event_unregister(session, unreg_classes): 11.35 + if session not in event_registrations: 11.36 + return 11.37 + 11.38 + if unreg_classes: 11.39 + event_registrations[session]['classes'].intersection_update( 11.40 + unreg_classes) 11.41 + if len(event_registrations[session]['classes']) == 0: 11.42 + del event_registrations[session] 11.43 + else: 11.44 + del event_registrations[session] 11.45 + 11.46 + 11.47 +def event_next(session): 11.48 + if session not in event_registrations: 11.49 + return xen_api_error(['SESSION_INVALID', session]) 11.50 + queue = event_registrations[session]['queue'] 11.51 + events = [queue.get()] 11.52 + try: 11.53 + while True: 11.54 + events.append(queue.get(False)) 11.55 + except Queue.Empty: 11.56 + pass 11.57 + 11.58 + return xen_api_success(events) 11.59 + 11.60 + 11.61 +def _ctor_event_dispatch(xenapi, ctor, api_cls, session, args): 11.62 + result = ctor(xenapi, session, *args) 11.63 + if result['Status'] == 'Success': 11.64 + ref = result['Value'] 11.65 + _event_dispatch('add', api_cls, ref, '') 11.66 + return result 11.67 + 11.68 + 11.69 +def _dtor_event_dispatch(xenapi, dtor, api_cls, session, ref, args): 11.70 + result = dtor(xenapi, session, ref, *args) 11.71 + if result['Status'] == 'Success': 11.72 + _event_dispatch('del', api_cls, ref, '') 11.73 + return result 11.74 + 11.75 + 11.76 +def _setter_event_dispatch(xenapi, setter, api_cls, attr_name, session, ref, 11.77 + args): 11.78 + result = setter(xenapi, session, ref, *args) 11.79 + if result['Status'] == 'Success': 11.80 + _event_dispatch('mod', api_cls, ref, attr_name) 11.81 + return result 11.82 + 11.83 + 11.84 +def _event_dispatch(operation, api_cls, ref, attr_name): 11.85 + event = { 11.86 + 'timestamp' : now(), 11.87 + 'class' : api_cls, 11.88 + 'operation' : operation, 11.89 + 'ref' : ref, 11.90 + 'obj_uuid' : ref, 11.91 + 'field' : attr_name, 11.92 + } 11.93 + for reg in event_registrations.values(): 11.94 + if api_cls in reg['classes']: 11.95 + event['id'] = reg['next-id'] 11.96 + reg['next-id'] += 1 11.97 + reg['queue'].put(event) 11.98 + 11.99 + 11.100 +# --------------------------------------------------- 11.101 # Python Method Decorators for input value validation 11.102 # --------------------------------------------------- 11.103 11.104 @@ -375,6 +462,36 @@ def do_vm_func(fn_name, vm_ref, *args, * 11.105 exn.actual]) 11.106 11.107 11.108 +classes = { 11.109 + 'session' : None, 11.110 + 'event' : None, 11.111 + 'host' : valid_host, 11.112 + 'host_cpu' : valid_host_cpu, 11.113 + 'host_metrics' : valid_host_metrics, 11.114 + 'network' : valid_network, 11.115 + 'VM' : valid_vm, 11.116 + 'VM_metrics' : valid_vm_metrics, 11.117 + 'VBD' : valid_vbd, 11.118 + 'VBD_metrics' : valid_vbd_metrics, 11.119 + 'VIF' : valid_vif, 11.120 + 'VIF_metrics' : valid_vif_metrics, 11.121 + 'VDI' : valid_vdi, 11.122 + 'VTPM' : valid_vtpm, 11.123 + 'console' : valid_console, 11.124 + 'SR' : valid_sr, 11.125 + 'PIF' : valid_pif, 11.126 + 'PIF_metrics' : valid_pif_metrics, 11.127 + 'task' : valid_task, 11.128 + 'debug' : valid_debug, 11.129 +} 11.130 + 11.131 +autoplug_classes = { 11.132 + 'network' : XendNetwork, 11.133 + 'VM_metrics' : XendVMMetrics, 11.134 + 'PIF_metrics' : XendPIFMetrics, 11.135 +} 11.136 + 11.137 + 11.138 class XendAPI(object): 11.139 """Implementation of the Xen-API in Xend. Expects to be 11.140 used via XMLRPCServer. 11.141 @@ -416,33 +533,7 @@ class XendAPI(object): 11.142 server. 11.143 """ 11.144 global_validators = [session_required, catch_typeerror] 11.145 - classes = { 11.146 - 'session' : None, 11.147 - 'host' : valid_host, 11.148 - 'host_cpu' : valid_host_cpu, 11.149 - 'host_metrics' : valid_host_metrics, 11.150 - 'network' : valid_network, 11.151 - 'VM' : valid_vm, 11.152 - 'VM_metrics' : valid_vm_metrics, 11.153 - 'VBD' : valid_vbd, 11.154 - 'VBD_metrics' : valid_vbd_metrics, 11.155 - 'VIF' : valid_vif, 11.156 - 'VIF_metrics' : valid_vif_metrics, 11.157 - 'VDI' : valid_vdi, 11.158 - 'VTPM' : valid_vtpm, 11.159 - 'console' : valid_console, 11.160 - 'SR' : valid_sr, 11.161 - 'PIF' : valid_pif, 11.162 - 'PIF_metrics' : valid_pif_metrics, 11.163 - 'task' : valid_task, 11.164 - 'debug' : valid_debug, 11.165 - } 11.166 - 11.167 - autoplug_classes = { 11.168 - 'network' : XendNetwork, 11.169 - 'VM_metrics' : XendVMMetrics, 11.170 - 'PIF_metrics' : XendPIFMetrics, 11.171 - } 11.172 + 11.173 11.174 # Cheat methods 11.175 # ------------- 11.176 @@ -499,6 +590,43 @@ class XendAPI(object): 11.177 doit('%s' % func_name) 11.178 11.179 11.180 + def wrap_method(name, new_f): 11.181 + try: 11.182 + f = getattr(cls, name) 11.183 + wrapped_f = (lambda *args: new_f(f, *args)) 11.184 + wrapped_f.api = f.api 11.185 + wrapped_f.async = f.async 11.186 + setattr(cls, name, wrapped_f) 11.187 + except AttributeError: 11.188 + # Logged below (API call: %s not found) 11.189 + pass 11.190 + 11.191 + 11.192 + def setter_event_wrapper(api_cls, attr_name): 11.193 + setter_name = '%s_set_%s' % (api_cls, attr_name) 11.194 + wrap_method( 11.195 + setter_name, 11.196 + lambda setter, s, session, ref, *args: 11.197 + _setter_event_dispatch(s, setter, api_cls, attr_name, 11.198 + session, ref, args)) 11.199 + 11.200 + 11.201 + def ctor_event_wrapper(api_cls): 11.202 + ctor_name = '%s_create' % api_cls 11.203 + wrap_method( 11.204 + ctor_name, 11.205 + lambda ctor, s, session, *args: 11.206 + _ctor_event_dispatch(s, ctor, api_cls, session, args)) 11.207 + 11.208 + 11.209 + def dtor_event_wrapper(api_cls): 11.210 + dtor_name = '%s_destroy' % api_cls 11.211 + wrap_method( 11.212 + dtor_name, 11.213 + lambda dtor, s, session, ref, *args: 11.214 + _dtor_event_dispatch(s, dtor, api_cls, session, ref, args)) 11.215 + 11.216 + 11.217 # Wrapping validators around XMLRPC calls 11.218 # --------------------------------------- 11.219 11.220 @@ -541,6 +669,7 @@ class XendAPI(object): 11.221 for attr_name in rw_attrs + cls.Base_attr_rw: 11.222 doit('%s.set_%s' % (api_cls, attr_name), True, 11.223 async_support = False) 11.224 + setter_event_wrapper(api_cls, attr_name) 11.225 11.226 # wrap validators around methods 11.227 for method_name, return_type in methods + cls.Base_methods: 11.228 @@ -552,6 +681,10 @@ class XendAPI(object): 11.229 doit('%s.%s' % (api_cls, func_name), False, async_support = True, 11.230 return_type = return_type) 11.231 11.232 + ctor_event_wrapper(api_cls) 11.233 + dtor_event_wrapper(api_cls) 11.234 + 11.235 + 11.236 _decorate = classmethod(_decorate) 11.237 11.238 def __init__(self, auth): 11.239 @@ -2388,6 +2521,26 @@ class XendAPI(object): 11.240 return xen_api_success_void() 11.241 11.242 11.243 + # Xen API: Class event 11.244 + # ---------------------------------------------------------------- 11.245 + 11.246 + event_attr_ro = [] 11.247 + event_attr_rw = [] 11.248 + event_funcs = [('register', None), 11.249 + ('unregister', None), 11.250 + ('next', None)] 11.251 + 11.252 + def event_register(self, session, reg_classes): 11.253 + event_register(session, reg_classes) 11.254 + return xen_api_success_void() 11.255 + 11.256 + def event_unregister(self, session, unreg_classes): 11.257 + event_unregister(session, reg_classes) 11.258 + return xen_api_success_void() 11.259 + 11.260 + def event_next(self, session): 11.261 + return event_next(session) 11.262 + 11.263 # Xen API: Class debug 11.264 # ---------------------------------------------------------------- 11.265
12.1 --- a/tools/python/xen/xm/main.py Thu Mar 29 15:22:02 2007 +0100 12.2 +++ b/tools/python/xen/xm/main.py Thu Mar 29 15:46:30 2007 +0100 12.3 @@ -345,7 +345,8 @@ acm_commands = [ 12.4 ] 12.5 12.6 all_commands = (domain_commands + host_commands + scheduler_commands + 12.7 - device_commands + vnet_commands + acm_commands + ['shell']) 12.8 + device_commands + vnet_commands + acm_commands + 12.9 + ['shell', 'event-monitor']) 12.10 12.11 12.12 ## 12.13 @@ -633,6 +634,17 @@ def xm_shell(args): 12.14 Shell().cmdloop('The Xen Master. Type "help" for a list of functions.') 12.15 12.16 12.17 +def xm_event_monitor(args): 12.18 + if serverType == SERVER_XEN_API: 12.19 + while True: 12.20 + server.xenapi.event.register(args) 12.21 + events = server.xenapi.event.next() 12.22 + for e in events: 12.23 + print e 12.24 + else: 12.25 + err("Event monitoring not supported unless using Xen-API.") 12.26 + 12.27 + 12.28 ######################################################################### 12.29 # 12.30 # Main xm functions 12.31 @@ -2169,6 +2181,7 @@ def xm_vnet_delete(args): 12.32 12.33 commands = { 12.34 "shell": xm_shell, 12.35 + "event-monitor": xm_event_monitor, 12.36 # console commands 12.37 "console": xm_console, 12.38 # xenstat commands