# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1172164529 25200
# Node ID 202eb735b425d4f99fb8a78ab6df6e7c9b70c6cb
# Parent 9364bea18bc4a2d83923a8ffd1481952e635c80f
# Parent f62a052384a54a379580a95aa79a70e3fcf86a6d
merge with xen-unstable.hg
---
docs/xen-api/xenapi-datamodel.tex | 2983 ++++++++++++---------
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 5
linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 2
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 12
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 11
linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 2
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 103
tools/libfsimage/Makefile | 2
tools/libfsimage/common/fsimage_grub.c | 78
tools/libfsimage/common/fsimage_grub.h | 5
tools/libfsimage/common/mapfile-GNU | 1
tools/libfsimage/common/mapfile-SunOS | 1
tools/libfsimage/ext2fs/fsys_ext2fs.c | 89
tools/libfsimage/fat/Makefile | 13
tools/libfsimage/fat/fat.h | 100
tools/libfsimage/fat/fsys_fat.c | 485 +++
tools/libfsimage/iso9660/Makefile | 15
tools/libfsimage/iso9660/fsys_iso9660.c | 463 +++
tools/libfsimage/iso9660/iso9660.h | 219 +
tools/libfsimage/reiserfs/fsys_reiserfs.c | 77
tools/libxen/include/xen_console.h | 49
tools/libxen/include/xen_host.h | 25
tools/libxen/include/xen_internal.h | 5
tools/libxen/include/xen_string_set.h | 47
tools/libxen/include/xen_vbd.h | 89
tools/libxen/include/xen_vbd_metrics.h | 183 +
tools/libxen/include/xen_vbd_metrics_decl.h | 30
tools/libxen/include/xen_vbd_type.h | 77
tools/libxen/include/xen_vbd_type_internal.h | 37
tools/libxen/include/xen_vif.h | 69
tools/libxen/include/xen_vif_metrics.h | 183 +
tools/libxen/include/xen_vif_metrics_decl.h | 30
tools/libxen/include/xen_vm_metrics.h | 11
tools/libxen/src/xen_common.c | 4
tools/libxen/src/xen_console.c | 106
tools/libxen/src/xen_host.c | 54
tools/libxen/src/xen_string_set.c | 47
tools/libxen/src/xen_string_set.h | 47
tools/libxen/src/xen_vbd.c | 208 +
tools/libxen/src/xen_vbd_metrics.c | 150 +
tools/libxen/src/xen_vbd_type.c | 81
tools/libxen/src/xen_vif.c | 161 -
tools/libxen/src/xen_vif_metrics.c | 150 +
tools/libxen/src/xen_vm_metrics.c | 24
tools/libxen/test/test_bindings.c | 79
tools/python/xen/xend/XendAPI.py | 214 -
tools/python/xen/xm/messages/en/xen-xm.po | 42
tools/tests/test_x86_emulator.c | 48
xen/acm/acm_chinesewall_hooks.c | 15
xen/acm/acm_simple_type_enforcement_hooks.c | 76
xen/arch/ia64/linux-xen/mca.c | 2
xen/arch/ia64/linux-xen/perfmon.c | 12
xen/arch/powerpc/audit.c | 2
xen/arch/x86/domctl.c | 36
xen/arch/x86/extable.c | 13
xen/arch/x86/hvm/io.c | 2
xen/arch/x86/hvm/platform.c | 1
xen/arch/x86/hvm/svm/vmcb.c | 5
xen/arch/x86/hvm/vmx/vmcs.c | 5
xen/arch/x86/hvm/vmx/vmx.c | 2
xen/arch/x86/mm.c | 17
xen/arch/x86/mm/shadow/common.c | 20
xen/arch/x86/mm/shadow/multi.c | 24
xen/arch/x86/time.c | 4
xen/arch/x86/traps.c | 101
xen/arch/x86/x86_32/entry.S | 4
xen/arch/x86/x86_64/entry.S | 4
xen/arch/x86/x86_emulate.c | 16
xen/common/domain.c | 96
xen/common/domctl.c | 11
xen/common/keyhandler.c | 4
xen/common/sched_sedf.c | 8
xen/common/sysctl.c | 4
xen/include/asm-x86/bug.h | 12
xen/include/asm-x86/event.h | 7
xen/include/asm-x86/x86_32/bug.h | 27
xen/include/asm-x86/x86_64/bug.h | 27
xen/include/asm-x86/x86_emulate.h | 24
xen/include/xen/lib.h | 22
xen/include/xen/rcupdate.h | 53
xen/include/xen/sched.h | 32
81 files changed, 5621 insertions(+), 1983 deletions(-)
diff -r 9364bea18bc4 -r 202eb735b425 docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Thu Feb 22 09:42:13 2007 -0700
+++ b/docs/xen-api/xenapi-datamodel.tex Thu Feb 22 10:15:29 2007 -0700
@@ -31,11 +31,13 @@ Name & Description \\
{\tt host\_cpu} & A physical CPU \\
{\tt network} & A virtual network \\
{\tt VIF} & A virtual network interface \\
+{\tt VIF\_metrics} & The metrics associated with a virtual network device \\
{\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 \\
+{\tt VBD\_metrics} & The metrics associated with a virtual block device \\
{\tt PBD} & The physical block devices through which hosts access SRs \\
{\tt crashdump} & A VM crashdump \\
{\tt VTPM} & A virtual TPM device \\
@@ -61,7 +63,6 @@ VIF.network & network.VIFs & one-to-many
VIF.network & network.VIFs & one-to-many\\
host.metrics & host\_metrics.host & one-to-one\\
PIF.metrics & PIF\_metrics.PIF & one-to-one\\
-VM.metrics & VM\_metrics.VM & one-to-one\\
PIF.host & host.PIFs & one-to-many\\
PIF.network & network.PIFs & one-to-many\\
SR.VDIs & VDI.SR & many-to-one\\
@@ -1076,8 +1077,6 @@ Quals & Field & Type & Description \\
$\mathit{RW}$ & {\tt VCPUs/params} & (string $\rightarrow$ string) Map &
configuration parameters for the selected VCPU policy \\
$\mathit{RW}$ & {\tt VCPUs/max} & int & Max number of VCPUs \\
$\mathit{RW}$ & {\tt VCPUs/at\_startup} & int & Boot number of VCPUs \\
-$\mathit{RO}_\mathit{ins}$ & {\tt VCPUs/number} & int & Current number of
VCPUs \\
-$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/utilisation} & (int $\rightarrow$
float) Map & Utilisation for all of guest's current VCPUs \\
$\mathit{RW}$ & {\tt actions/after\_shutdown} & on\_normal\_exit & action to
take after the guest has shutdown itself \\
$\mathit{RW}$ & {\tt actions/after\_reboot} & on\_normal\_exit & action to
take after the guest has rebooted itself \\
$\mathit{RW}$ & {\tt actions/after\_crash} & on\_crash\_behaviour & action to
take if the guest crashes \\
@@ -1102,7 +1101,7 @@ Quals & Field & Type & Description \\
$\mathit{RO}_\mathit{run}$ & {\tt tools\_version} & (string $\rightarrow$
string) Map & versions of installed paravirtualised drivers \\
$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map &
additional configuration \\
$\mathit{RO}_\mathit{run}$ & {\tt is\_control\_domain} & bool & true if this
is a control domain (domain 0 or a driver domain) \\
-$\mathit{RO}_\mathit{ins}$ & {\tt metrics} & VM\_metrics ref & metrics
associated with this VM. \\
+$\mathit{RO}_\mathit{run}$ & {\tt metrics} & VM\_metrics ref & metrics
associated with this VM. \\
\hline
\end{longtable}
\subsection{Additional RPCs associated with class: VM}
@@ -2545,70 +2544,6 @@ void
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_VCPUs\_number}
-
-{\bf Overview:}
-Get the VCPUs/number field of the given VM.
-
- \noindent {\bf Signature:}
-\begin{verbatim} int get_VCPUs_number (session_id s, VM 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 VM ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-int
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_VCPUs\_utilisation}
-
-{\bf Overview:}
-Get the VCPUs/utilisation field of the given VM.
-
- \noindent {\bf Signature:}
-\begin{verbatim} ((int -> float) Map) get_VCPUs_utilisation (session_id s, VM
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 VM ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-(int $\rightarrow$ float) Map
-}
-
-
-value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -4273,7 +4208,6 @@ Quals & Field & Type & Description \\
Quals & Field & Type & Description \\
\hline
$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object
reference \\
-$\mathit{RO}_\mathit{ins}$ & {\tt VM} & VM ref & VM to which these metrics
apply \\
$\mathit{RO}_\mathit{run}$ & {\tt memory/actual} & int & Guest's actual
memory (bytes) \\
$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/number} & int & Current number of
VCPUs \\
$\mathit{RO}_\mathit{run}$ & {\tt VCPUs/utilisation} & (int $\rightarrow$
float) Map & Utilisation for all of guest's current VCPUs \\
@@ -4305,38 +4239,6 @@ Get the uuid field of the given VM\_metr
\noindent {\bf Return Type:}
{\tt
string
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_VM}
-
-{\bf Overview:}
-Get the VM field of the given VM\_metrics.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VM ref) get_VM (session_id s, VM_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 VM\_metrics ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VM ref
}
@@ -4522,6 +4424,7 @@ Quals & Field & Type & Description \\
$\mathit{RW}$ & {\tt name/description} & string & a notes field containg
human-readable description \\
$\mathit{RO}_\mathit{run}$ & {\tt software\_version} & (string $\rightarrow$
string) Map & version strings \\
$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map &
additional configuration \\
+$\mathit{RO}_\mathit{run}$ & {\tt supported\_bootloaders} & string Set & a
list of the bootloaders installed on the machine \\
$\mathit{RO}_\mathit{run}$ & {\tt resident\_VMs} & (VM ref) Set & list of VMs
currently resident on host \\
$\mathit{RW}$ & {\tt logging} & (string $\rightarrow$ string) Map & logging
configuration \\
$\mathit{RO}_\mathit{run}$ & {\tt PIFs} & (PIF ref) Set & physical network
interfaces \\
@@ -5050,6 +4953,38 @@ void
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
+\subsubsection{RPC name:~get\_supported\_bootloaders}
+
+{\bf Overview:}
+Get the supported\_bootloaders field of the given host.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (string Set) get_supported_bootloaders (session_id s, host
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 host ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+string Set
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
\subsubsection{RPC name:~get\_resident\_VMs}
{\bf Overview:}
@@ -5476,70 +5411,6 @@ host\_metrics ref
value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~create}
-
-{\bf Overview:}
-Create a new host instance, and return its handle.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (host ref) create (session_id s, host record
args)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt host record } & args & All constructor arguments \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-host ref
-}
-
-
-reference to the newly created object
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~destroy}
-
-{\bf Overview:}
-Destroy the specified host instance.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void destroy (session_id s, host 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 host ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -6808,28 +6679,707 @@ Quals & Field & Type & Description \\
$\mathit{RO}_\mathit{ins}$ & {\tt VM} & VM ref & virtual machine to which
this vif is connected \\
$\mathit{RW}$ & {\tt MAC} & string & ethernet MAC address of virtual
interface, as exposed to guest \\
$\mathit{RW}$ & {\tt MTU} & int & MTU in octets \\
+$\mathit{RW}$ & {\tt qos/algorithm\_type} & string & QoS algorithm to use \\
+$\mathit{RW}$ & {\tt qos/algorithm\_params} & (string $\rightarrow$ string)
Map & Paramters for chosen QoS algorithm \\
+$\mathit{RO}_\mathit{run}$ & {\tt metrics} & VIF\_metrics ref & metrics
associated with this VIF. \\
+\hline
+\end{longtable}
+\subsection{Additional RPCs associated with class: VIF}
+\subsubsection{RPC name:~get\_uuid}
+
+{\bf Overview:}
+Get the uuid field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_uuid (session_id s, VIF 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 VIF 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\_device}
+
+{\bf Overview:}
+Get the device field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_device (session_id s, VIF 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 VIF 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:~set\_device}
+
+{\bf Overview:}
+Set the device field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_device (session_id s, VIF ref self, string
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt string } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_network}
+
+{\bf Overview:}
+Get the network field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (network ref) get_network (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+network ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_VM}
+
+{\bf Overview:}
+Get the VM field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VM ref) get_VM (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VM ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_MAC}
+
+{\bf Overview:}
+Get the MAC field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_MAC (session_id s, VIF 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 VIF 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:~set\_MAC}
+
+{\bf Overview:}
+Set the MAC field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_MAC (session_id s, VIF ref self, string
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt string } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_MTU}
+
+{\bf Overview:}
+Get the MTU field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} int get_MTU (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_MTU}
+
+{\bf Overview:}
+Set the MTU field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_MTU (session_id s, VIF ref self, int
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt int } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_qos\_algorithm\_type}
+
+{\bf Overview:}
+Get the qos/algorithm\_type field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_qos_algorithm_type (session_id s, VIF 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 VIF 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:~set\_qos\_algorithm\_type}
+
+{\bf Overview:}
+Set the qos/algorithm\_type field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_qos_algorithm_type (session_id s, VIF ref self,
string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt string } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Get the qos/algorithm\_params field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((string -> string) Map) get_qos_algorithm_params (session_id
s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+(string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Set the qos/algorithm\_params field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_qos_algorithm_params (session_id s, VIF ref self,
(string -> string) Map value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Add the given key-value pair to the qos/algorithm\_params field of the
+given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void add_to_qos_algorithm_params (session_id s, VIF ref self,
string key, string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to add \\ \hline
+
+{\tt string } & value & Value to add \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Remove the given key and its corresponding value from the
+qos/algorithm\_params field of the given VIF. If the key is not in that
+Map, then do nothing.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void remove_from_qos_algorithm_params (session_id s, VIF ref
self, string key)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to remove \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_metrics}
+
+{\bf Overview:}
+Get the metrics field of the given VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VIF_metrics ref) get_metrics (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VIF\_metrics ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~create}
+
+{\bf Overview:}
+Create a new VIF instance, and return its handle.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VIF ref) create (session_id s, VIF record args)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VIF record } & args & All constructor arguments \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VIF ref
+}
+
+
+reference to the newly created object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~destroy}
+
+{\bf Overview:}
+Destroy the specified VIF instance.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void destroy (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_by\_uuid}
+
+{\bf Overview:}
+Get a reference to the VIF instance with the specified UUID.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VIF 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
+VIF 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 VIF.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VIF record) get_record (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VIF record
+}
+
+
+all fields from the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
+\section{Class: VIF\_metrics}
+\subsection{Fields for class: VIF\_metrics}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VIF\_metrics} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
+The metrics associated with a virtual network device.}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object
reference \\
$\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: VIF}
+\subsection{Additional RPCs associated with class: VIF\_metrics}
\subsubsection{RPC name:~get\_uuid}
{\bf Overview:}
-Get the uuid field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} string get_uuid (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+Get the uuid field of the given VIF\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_uuid (session_id s, VIF_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 VIF\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
@@ -6845,285 +7395,23 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~get\_device}
-
-{\bf Overview:}
-Get the device field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} string get_device (session_id s, VIF 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 VIF 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:~set\_device}
-
-{\bf Overview:}
-Set the device field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_device (session_id s, VIF ref self, string
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VIF ref } & self & reference to the object \\ \hline
-
-{\tt string } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_network}
-
-{\bf Overview:}
-Get the network field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (network ref) get_network (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-network ref
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_VM}
-
-{\bf Overview:}
-Get the VM field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VM ref) get_VM (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VM ref
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_MAC}
-
-{\bf Overview:}
-Get the MAC field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} string get_MAC (session_id s, VIF 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 VIF 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:~set\_MAC}
-
-{\bf Overview:}
-Set the MAC field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_MAC (session_id s, VIF ref self, string
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VIF ref } & self & reference to the object \\ \hline
-
-{\tt string } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_MTU}
-
-{\bf Overview:}
-Get the MTU field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} int get_MTU (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-int
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~set\_MTU}
-
-{\bf Overview:}
-Set the MTU field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_MTU (session_id s, VIF ref self, int
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VIF ref } & self & reference to the object \\ \hline
-
-{\tt int } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\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 VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} float get_io_read_kbs (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+Get the io/read\_kbs field of the given VIF\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} float get_io_read_kbs (session_id s, VIF_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 VIF\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
@@ -7142,20 +7430,20 @@ value of the field
\subsubsection{RPC name:~get\_io\_write\_kbs}
{\bf Overview:}
-Get the io/write\_kbs field of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} float get_io_write_kbs (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
+Get the io/write\_kbs field of the given VIF\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} float get_io_write_kbs (session_id s, VIF_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 VIF\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
@@ -7171,77 +7459,13 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~create}
-
-{\bf Overview:}
-Create a new VIF instance, and return its handle.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VIF ref) create (session_id s, VIF record args)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VIF record } & args & All constructor arguments \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VIF ref
-}
-
-
-reference to the newly created object
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~destroy}
-
-{\bf Overview:}
-Destroy the specified VIF instance.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void destroy (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
\subsubsection{RPC name:~get\_by\_uuid}
{\bf Overview:}
-Get a reference to the VIF instance with the specified UUID.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VIF ref) get_by_uuid (session_id s, string
uuid)\end{verbatim}
+Get a reference to the VIF\_metrics instance with the specified UUID.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VIF_metrics ref) get_by_uuid (session_id s, string
uuid)\end{verbatim}
\noindent{\bf Arguments:}
@@ -7259,7 +7483,7 @@ Get a reference to the VIF instance with
\noindent {\bf Return Type:}
{\tt
-VIF ref
+VIF\_metrics ref
}
@@ -7270,28 +7494,28 @@ reference to the object
\subsubsection{RPC name:~get\_record}
{\bf Overview:}
-Get a record containing the current state of the given VIF.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VIF record) get_record (session_id s, VIF 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 VIF ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VIF record
+Get a record containing the current state of the given VIF\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VIF_metrics record) get_record (session_id s, VIF_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 VIF\_metrics ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VIF\_metrics record
}
@@ -9562,63 +9786,808 @@ Quals & Field & Type & Description \\
$\mathit{RW}$ & {\tt bootable} & bool & true if this VBD is bootable \\
$\mathit{RW}$ & {\tt mode} & vbd\_mode & the mode the VBD should be mounted
with \\
$\mathit{RW}$ & {\tt type} & vbd\_type & how the VBD will appear to the guest
(e.g. disk or CD) \\
+$\mathit{RW}$ & {\tt qos/algorithm\_type} & string & QoS algorithm to use \\
+$\mathit{RW}$ & {\tt qos/algorithm\_params} & (string $\rightarrow$ string)
Map & Paramters for chosen QoS algorithm \\
+$\mathit{RO}_\mathit{run}$ & {\tt metrics} & VBD\_metrics ref & metrics
associated with this VBD. \\
+\hline
+\end{longtable}
+\subsection{Additional RPCs associated with class: VBD}
+\subsubsection{RPC name:~media\_change}
+
+{\bf Overview:}
+Change the media in the device for CDROM-like devices only. For other
+devices, detach the VBD and attach a new one.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void media_change (session_id s, VBD ref vbd, VDI ref
vdi)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & vbd & The vbd representing the CDROM-like device \\ \hline
+
+{\tt VDI ref } & vdi & The new VDI to 'insert' \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uuid}
+
+{\bf Overview:}
+Get the uuid field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_uuid (session_id s, VBD 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 VBD 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\_VM}
+
+{\bf Overview:}
+Get the VM field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VM ref) get_VM (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VM ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_VDI}
+
+{\bf Overview:}
+Get the VDI field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VDI ref) get_VDI (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VDI ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_device}
+
+{\bf Overview:}
+Get the device field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_device (session_id s, VBD 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 VBD 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:~set\_device}
+
+{\bf Overview:}
+Set the device field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_device (session_id s, VBD ref self, string
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt string } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_bootable}
+
+{\bf Overview:}
+Get the bootable field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} bool get_bootable (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+bool
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_bootable}
+
+{\bf Overview:}
+Set the bootable field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_bootable (session_id s, VBD ref self, bool
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt bool } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_mode}
+
+{\bf Overview:}
+Get the mode field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (vbd_mode) get_mode (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+vbd\_mode
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_mode}
+
+{\bf Overview:}
+Set the mode field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_mode (session_id s, VBD ref self, vbd_mode
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt vbd\_mode } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_type}
+
+{\bf Overview:}
+Get the type field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (vbd_type) get_type (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+vbd\_type
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_type}
+
+{\bf Overview:}
+Set the type field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_type (session_id s, VBD ref self, vbd_type
value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt vbd\_type } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_qos\_algorithm\_type}
+
+{\bf Overview:}
+Get the qos/algorithm\_type field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_qos_algorithm_type (session_id s, VBD 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 VBD 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:~set\_qos\_algorithm\_type}
+
+{\bf Overview:}
+Set the qos/algorithm\_type field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_qos_algorithm_type (session_id s, VBD ref self,
string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt string } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Get the qos/algorithm\_params field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((string -> string) Map) get_qos_algorithm_params (session_id
s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+(string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Set the qos/algorithm\_params field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_qos_algorithm_params (session_id s, VBD ref self,
(string -> string) Map value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Add the given key-value pair to the qos/algorithm\_params field of the
+given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void add_to_qos_algorithm_params (session_id s, VBD ref self,
string key, string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to add \\ \hline
+
+{\tt string } & value & Value to add \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_qos\_algorithm\_params}
+
+{\bf Overview:}
+Remove the given key and its corresponding value from the
+qos/algorithm\_params field of the given VBD. If the key is not in that
+Map, then do nothing.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void remove_from_qos_algorithm_params (session_id s, VBD ref
self, string key)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to remove \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_metrics}
+
+{\bf Overview:}
+Get the metrics field of the given VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VBD_metrics ref) get_metrics (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VBD\_metrics ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~create}
+
+{\bf Overview:}
+Create a new VBD instance, and return its handle.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VBD ref) create (session_id s, VBD record args)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VBD record } & args & All constructor arguments \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VBD ref
+}
+
+
+reference to the newly created object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~destroy}
+
+{\bf Overview:}
+Destroy the specified VBD instance.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void destroy (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_by\_uuid}
+
+{\bf Overview:}
+Get a reference to the VBD instance with the specified UUID.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VBD 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
+VBD 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 VBD.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VBD record) get_record (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VBD record
+}
+
+
+all fields from the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
+\section{Class: VBD\_metrics}
+\subsection{Fields for class: VBD\_metrics}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VBD\_metrics} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
+The metrics associated with a virtual block device.}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object
reference \\
$\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: VBD}
-\subsubsection{RPC name:~media\_change}
-
-{\bf Overview:}
-Change the media in the device for CDROM-like devices only. For other
-devices, detach the VBD and attach a new one.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void media_change (session_id s, VBD ref vbd, VDI ref
vdi)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VBD ref } & vbd & The vbd representing the CDROM-like device \\ \hline
-
-{\tt VDI ref } & vdi & The new VDI to 'insert' \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
+\subsection{Additional RPCs associated with class: VBD\_metrics}
\subsubsection{RPC name:~get\_uuid}
{\bf Overview:}
-Get the uuid field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} string get_uuid (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+Get the uuid field of the given VBD\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_uuid (session_id s, VBD_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 VBD\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
@@ -9634,351 +10603,23 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~get\_VM}
-
-{\bf Overview:}
-Get the VM field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VM ref) get_VM (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VM ref
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_VDI}
-
-{\bf Overview:}
-Get the VDI field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VDI ref) get_VDI (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VDI ref
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_device}
-
-{\bf Overview:}
-Get the device field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} string get_device (session_id s, VBD 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 VBD 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:~set\_device}
-
-{\bf Overview:}
-Set the device field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_device (session_id s, VBD ref self, string
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VBD ref } & self & reference to the object \\ \hline
-
-{\tt string } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_bootable}
-
-{\bf Overview:}
-Get the bootable field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} bool get_bootable (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-bool
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~set\_bootable}
-
-{\bf Overview:}
-Set the bootable field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_bootable (session_id s, VBD ref self, bool
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VBD ref } & self & reference to the object \\ \hline
-
-{\tt bool } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_mode}
-
-{\bf Overview:}
-Get the mode field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (vbd_mode) get_mode (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-vbd\_mode
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~set\_mode}
-
-{\bf Overview:}
-Set the mode field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_mode (session_id s, VBD ref self, vbd_mode
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VBD ref } & self & reference to the object \\ \hline
-
-{\tt vbd\_mode } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~get\_type}
-
-{\bf Overview:}
-Get the type field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (vbd_type) get_type (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-vbd\_type
-}
-
-
-value of the field
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~set\_type}
-
-{\bf Overview:}
-Set the type field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void set_type (session_id s, VBD ref self, vbd_type
value)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VBD ref } & self & reference to the object \\ \hline
-
-{\tt vbd\_type } & value & New value to set \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\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 VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} float get_io_read_kbs (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+Get the io/read\_kbs field of the given VBD\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} float get_io_read_kbs (session_id s, VBD_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 VBD\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
@@ -9997,20 +10638,20 @@ value of the field
\subsubsection{RPC name:~get\_io\_write\_kbs}
{\bf Overview:}
-Get the io/write\_kbs field of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} float get_io_write_kbs (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
+Get the io/write\_kbs field of the given VBD\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} float get_io_write_kbs (session_id s, VBD_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 VBD\_metrics ref } & self & reference to the object \\ \hline
\end{tabular}
@@ -10026,77 +10667,13 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~create}
-
-{\bf Overview:}
-Create a new VBD instance, and return its handle.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VBD ref) create (session_id s, VBD record args)\end{verbatim}
-
-
-\noindent{\bf Arguments:}
-
-
-\vspace{0.3cm}
-\begin{tabular}{|c|c|p{7cm}|}
- \hline
-{\bf type} & {\bf name} & {\bf description} \\ \hline
-{\tt VBD record } & args & All constructor arguments \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VBD ref
-}
-
-
-reference to the newly created object
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
-\subsubsection{RPC name:~destroy}
-
-{\bf Overview:}
-Destroy the specified VBD instance.
-
- \noindent {\bf Signature:}
-\begin{verbatim} void destroy (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-void
-}
-
-
-
-\vspace{0.3cm}
-\vspace{0.3cm}
-\vspace{0.3cm}
\subsubsection{RPC name:~get\_by\_uuid}
{\bf Overview:}
-Get a reference to the VBD instance with the specified UUID.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VBD ref) get_by_uuid (session_id s, string
uuid)\end{verbatim}
+Get a reference to the VBD\_metrics instance with the specified UUID.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VBD_metrics ref) get_by_uuid (session_id s, string
uuid)\end{verbatim}
\noindent{\bf Arguments:}
@@ -10114,7 +10691,7 @@ Get a reference to the VBD instance with
\noindent {\bf Return Type:}
{\tt
-VBD ref
+VBD\_metrics ref
}
@@ -10125,28 +10702,28 @@ reference to the object
\subsubsection{RPC name:~get\_record}
{\bf Overview:}
-Get a record containing the current state of the given VBD.
-
- \noindent {\bf Signature:}
-\begin{verbatim} (VBD record) get_record (session_id s, VBD 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 VBD ref } & self & reference to the object \\ \hline
-
-\end{tabular}
-
-\vspace{0.3cm}
-
- \noindent {\bf Return Type:}
-{\tt
-VBD record
+Get a record containing the current state of the given VBD\_metrics.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VBD_metrics record) get_record (session_id s, VBD_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 VBD\_metrics ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VBD\_metrics record
}
@@ -10985,8 +11562,9 @@ Quals & Field & Type & Description \\
\hline
$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object
reference \\
$\mathit{RO}_\mathit{run}$ & {\tt protocol} & console\_protocol & the
protocol used by this console \\
-$\mathit{RO}_\mathit{run}$ & {\tt uri} & string & URI for the console service
\\
+$\mathit{RO}_\mathit{run}$ & {\tt location} & string & URI for the console
service \\
$\mathit{RO}_\mathit{run}$ & {\tt VM} & VM ref & VM to which this console is
attached \\
+$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map &
additional configuration \\
\hline
\end{longtable}
\subsection{Additional RPCs associated with class: console}
@@ -11054,13 +11632,13 @@ value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
-\subsubsection{RPC name:~get\_uri}
-
-{\bf Overview:}
-Get the uri field of the given console.
-
- \noindent {\bf Signature:}
-\begin{verbatim} string get_uri (session_id s, console ref self)\end{verbatim}
+\subsubsection{RPC name:~get\_location}
+
+{\bf Overview:}
+Get the location field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_location (session_id s, console ref
self)\end{verbatim}
\noindent{\bf Arguments:}
@@ -11115,6 +11693,145 @@ VM ref
value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_other\_config}
+
+{\bf Overview:}
+Get the other\_config field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((string -> string) Map) get_other_config (session_id s,
console 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 console ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+(string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_other\_config}
+
+{\bf Overview:}
+Set the other\_config field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_other_config (session_id s, console ref self,
(string -> string) Map value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & reference to the object \\ \hline
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_other\_config}
+
+{\bf Overview:}
+Add the given key-value pair to the other\_config field of the given
+console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void add_to_other_config (session_id s, console ref self,
string key, string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to add \\ \hline
+
+{\tt string } & value & Value to add \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_other\_config}
+
+{\bf Overview:}
+Remove the given key and its corresponding value from the other\_config
+field of the given console. If the key is not in that Map, then do
+nothing.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void remove_from_other_config (session_id s, console ref
self, string key)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to remove \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -11767,34 +12484,15 @@ Each possible error code is documented i
\subsection{Error Codes}
-\subsubsection{HOST\_CPU\_HANDLE\_INVALID}
-
-You gave an invalid host\_cpu handle. The host\_cpu may have recently been
-deleted. The handle parameter echoes the bad value given.
+\subsubsection{HANDLE\_INVALID}
+
+You gave an invalid handle. The object may have recently been deleted.
+The class parameter gives the type of reference given, and the handle
+parameter echoes the bad value given.
\vspace{0.3cm}
{\bf Signature:}
-\begin{verbatim}HOST_CPU_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{HOST\_HANDLE\_INVALID}
-
-You gave an invalid host handle. The host may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}HOST_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{HOST\_METRICS\_HANDLE\_INVALID}
-
-You gave an invalid host\_metrics handle. The host\_metrics may have
-recently been deleted. The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}HOST_METRICS_HANDLE_INVALID(handle)\end{verbatim}
+\begin{verbatim}HANDLE_INVALID(class, handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
\subsubsection{INTERNAL\_ERROR}
@@ -11854,18 +12552,7 @@ You attempted an operation that was not
You attempted an operation that was not allowed.
\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}OPERATION_NOT_ALLOWED()\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{PIF\_HANDLE\_INVALID}
-
-You gave an invalid PIF handle. The PIF may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}PIF_HANDLE_INVALID(handle)\end{verbatim}
+No parameters.
\begin{center}\rule{10em}{0.1pt}\end{center}
\subsubsection{PIF\_IS\_PHYSICAL}
@@ -11877,16 +12564,6 @@ PIF handle you gave.
\vspace{0.3cm}
{\bf Signature:}
\begin{verbatim}PIF_IS_PHYSICAL(PIF)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{PIF\_METRICS\_HANDLE\_INVALID}
-
-You gave an invalid PIF\_metrics handle. The PIF\_metrics may have
-recently been deleted. The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}PIF_METRICS_HANDLE_INVALID(handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
\subsubsection{SESSION\_AUTHENTICATION\_FAILED}
@@ -11910,26 +12587,6 @@ current connection. The handle paramete
\begin{verbatim}SESSION_INVALID(handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
-\subsubsection{SR\_HANDLE\_INVALID}
-
-You gave an invalid SR handle. The SR may have recently been deleted. The
-handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}SR_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{TASK\_HANDLE\_INVALID}
-
-You gave an invalid task handle. The task may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}TASK_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
\subsubsection{VALUE\_NOT\_SUPPORTED}
You attempted to set a value that is not supported by this implementation.
@@ -11939,36 +12596,6 @@ returned. Also returned is a developer-
\vspace{0.3cm}
{\bf Signature:}
\begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VBD\_HANDLE\_INVALID}
-
-You gave an invalid VBD handle. The VBD may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VBD_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VDI\_HANDLE\_INVALID}
-
-You gave an invalid VDI handle. The VDI may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VDI_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VIF\_HANDLE\_INVALID}
-
-You gave an invalid VIF handle. The VIF may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VIF_HANDLE_INVALID(handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
\subsubsection{VLAN\_TAG\_INVALID}
@@ -11991,36 +12618,6 @@ expected and actual VM state at the time
\vspace{0.3cm}
{\bf Signature:}
\begin{verbatim}VM_BAD_POWER_STATE(vm, expected, actual)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VM\_HANDLE\_INVALID}
-
-You gave an invalid VM handle. The VM may have recently been deleted. The
-handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VM_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VM\_METRICS\_HANDLE\_INVALID}
-
-You gave an invalid VM\_metrics handle. The VM\_metrics may have recently
-been deleted. The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VM_METRICS_HANDLE_INVALID(handle)\end{verbatim}
-\begin{center}\rule{10em}{0.1pt}\end{center}
-
-\subsubsection{VTPM\_HANDLE\_INVALID}
-
-You gave an invalid VTPM handle. The VTPM may have recently been deleted.
-The handle parameter echoes the bad value given.
-
-\vspace{0.3cm}
-{\bf Signature:}
-\begin{verbatim}VTPM_HANDLE_INVALID(handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
diff -r 9364bea18bc4 -r 202eb735b425
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Feb 22
09:42:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Feb 22
10:15:29 2007 -0700
@@ -490,6 +490,11 @@ static void dispatch_rw_block_io(blkif_t
for (i = 0; i < nbio; i++)
submit_bio(operation, biolist[i]);
+
+ if (operation == READ)
+ blkif->st_rd_sect += preq.nr_sects;
+ else if (operation == WRITE)
+ blkif->st_wr_sect += preq.nr_sects;
return;
diff -r 9364bea18bc4 -r 202eb735b425
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Feb 22 09:42:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Feb 22 10:15:29
2007 -0700
@@ -88,6 +88,8 @@ typedef struct blkif_st {
int st_wr_req;
int st_oo_req;
int st_br_req;
+ int st_rd_sect;
+ int st_wr_sect;
wait_queue_head_t waiting_to_free;
diff -r 9364bea18bc4 -r 202eb735b425
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Feb 22 09:42:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Feb 22 10:15:29
2007 -0700
@@ -111,16 +111,20 @@ static void update_blkif_status(blkif_t
} \
DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
-VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
-VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
-VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
-VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
+VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
+VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
+VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
static struct attribute *vbdstat_attrs[] = {
&dev_attr_oo_req.attr,
&dev_attr_rd_req.attr,
&dev_attr_wr_req.attr,
&dev_attr_br_req.attr,
+ &dev_attr_rd_sect.attr,
+ &dev_attr_wr_sect.attr,
NULL
};
diff -r 9364bea18bc4 -r 202eb735b425
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu Feb 22 09:42:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu Feb 22 10:15:29
2007 -0700
@@ -1195,7 +1195,7 @@ static void dispatch_rw_block_io(blkif_t
int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
unsigned int nseg;
- int ret, i;
+ int ret, i, nr_sects = 0;
tap_blkif_t *info;
uint64_t sector;
blkif_request_t *target;
@@ -1291,6 +1291,9 @@ static void dispatch_rw_block_io(blkif_t
req->seg[i].gref, blkif->domid);
op++;
}
+
+ nr_sects += (req->seg[i].last_sect -
+ req->seg[i].first_sect + 1);
}
ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
@@ -1403,6 +1406,12 @@ static void dispatch_rw_block_io(blkif_t
target->id = usr_idx;
wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
info->ufe_ring.req_prod_pvt++;
+
+ if (operation == READ)
+ blkif->st_rd_sect += nr_sects;
+ else if (operation == WRITE)
+ blkif->st_wr_sect += nr_sects;
+
return;
fail_flush:
diff -r 9364bea18bc4 -r 202eb735b425
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Feb 22 09:42:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Feb 22 10:15:29
2007 -0700
@@ -76,6 +76,8 @@ typedef struct blkif_st {
int st_rd_req;
int st_wr_req;
int st_oo_req;
+ int st_rd_sect;
+ int st_wr_sect;
wait_queue_head_t waiting_to_free;
diff -r 9364bea18bc4 -r 202eb735b425
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Thu Feb 22 09:42:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Thu Feb 22 10:15:29
2007 -0700
@@ -47,6 +47,7 @@ struct backend_info
blkif_t *blkif;
struct xenbus_watch backend_watch;
int xenbus_id;
+ int group_added;
};
@@ -112,6 +113,80 @@ static int blktap_name(blkif_t *blkif, c
return 0;
}
+/****************************************************************
+ * sysfs interface for VBD I/O requests
+ */
+
+#define VBD_SHOW(name, format, args...)
\
+ static ssize_t show_##name(struct device *_dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ struct xenbus_device *dev = to_xenbus_device(_dev); \
+ struct backend_info *be = dev->dev.driver_data; \
+ \
+ return sprintf(buf, format, ##args); \
+ } \
+ DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+VBD_SHOW(tap_oo_req, "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(tap_rd_req, "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(tap_wr_req, "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(tap_rd_sect, "%d\n", be->blkif->st_rd_sect);
+VBD_SHOW(tap_wr_sect, "%d\n", be->blkif->st_wr_sect);
+
+static struct attribute *tapstat_attrs[] = {
+ &dev_attr_tap_oo_req.attr,
+ &dev_attr_tap_rd_req.attr,
+ &dev_attr_tap_wr_req.attr,
+ &dev_attr_tap_rd_sect.attr,
+ &dev_attr_tap_wr_sect.attr,
+ NULL
+};
+
+static struct attribute_group tapstat_group = {
+ .name = "statistics",
+ .attrs = tapstat_attrs,
+};
+
+int xentap_sysfs_addif(struct xenbus_device *dev)
+{
+ int err;
+ struct backend_info *be = dev->dev.driver_data;
+ err = sysfs_create_group(&dev->dev.kobj, &tapstat_group);
+ if (!err)
+ be->group_added = 1;
+ return err;
+}
+
+void xentap_sysfs_delif(struct xenbus_device *dev)
+{
+ sysfs_remove_group(&dev->dev.kobj, &tapstat_group);
+}
+
+static int blktap_remove(struct xenbus_device *dev)
+{
+ struct backend_info *be = dev->dev.driver_data;
+
+ if (be->backend_watch.node) {
+ unregister_xenbus_watch(&be->backend_watch);
+ kfree(be->backend_watch.node);
+ be->backend_watch.node = NULL;
+ }
+ if (be->blkif) {
+ if (be->blkif->xenblkd)
+ kthread_stop(be->blkif->xenblkd);
+ signal_tapdisk(be->blkif->dev_num);
+ tap_blkif_free(be->blkif);
+ be->blkif = NULL;
+ }
+ if (be->group_added)
+ xentap_sysfs_delif(be->dev);
+ kfree(be);
+ dev->dev.driver_data = NULL;
+ return 0;
+}
+
static void tap_update_blkif_status(blkif_t *blkif)
{
int err;
@@ -134,6 +209,13 @@ static void tap_update_blkif_status(blki
err = blktap_name(blkif, name);
if (err) {
xenbus_dev_error(blkif->be->dev, err, "get blktap dev name");
+ return;
+ }
+
+ err = xentap_sysfs_addif(blkif->be->dev);
+ if (err) {
+ xenbus_dev_fatal(blkif->be->dev, err,
+ "creating sysfs entries");
return;
}
@@ -144,27 +226,6 @@ static void tap_update_blkif_status(blki
xenbus_dev_fatal(blkif->be->dev, err, "start xenblkd");
WPRINTK("Error starting thread\n");
}
-}
-
-static int blktap_remove(struct xenbus_device *dev)
-{
- struct backend_info *be = dev->dev.driver_data;
-
- if (be->backend_watch.node) {
- unregister_xenbus_watch(&be->backend_watch);
- kfree(be->backend_watch.node);
- be->backend_watch.node = NULL;
- }
- if (be->blkif) {
- if (be->blkif->xenblkd)
- kthread_stop(be->blkif->xenblkd);
- signal_tapdisk(be->blkif->dev_num);
- tap_blkif_free(be->blkif);
- be->blkif = NULL;
- }
- kfree(be);
- dev->dev.driver_data = NULL;
- return 0;
}
/**
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/Makefile
--- a/tools/libfsimage/Makefile Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/Makefile Thu Feb 22 10:15:29 2007 -0700
@@ -1,7 +1,7 @@ XEN_ROOT = ../..
XEN_ROOT = ../..
include $(XEN_ROOT)/tools/Rules.mk
-SUBDIRS-y = common ufs reiserfs
+SUBDIRS-y = common ufs reiserfs iso9660 fat
SUBDIRS-y += $(shell ./check-libext2fs)
.PHONY: all
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/common/fsimage_grub.c
--- a/tools/libfsimage/common/fsimage_grub.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_grub.c Thu Feb 22 10:15:29 2007 -0700
@@ -122,6 +122,84 @@ fsig_disk_read_junk(void)
return (&disk_read_junk);
}
+#if defined(__i386__) || defined(__x86_64__)
+
+#ifdef __amd64
+#define BSF "bsfq"
+#else
+#define BSF "bsfl"
+#endif
+unsigned long
+fsig_log2 (unsigned long word)
+{
+ __asm__ (BSF " %1,%0"
+ : "=r" (word)
+ : "r" (word));
+ return word;
+}
+
+#elif defined(__ia64__)
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define ia64_popcnt(x) __builtin_popcountl(x)
+#else
+# define ia64_popcnt(x) \
+ ({ \
+ __u64 ia64_intri_res; \
+ asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
+ ia64_intri_res; \
+ })
+#endif
+
+unsigned long
+fsig_log2 (unsigned long word)
+{
+ unsigned long result;
+
+ result = ia64_popcnt((word - 1) & ~word);
+ return result;
+}
+
+#elif defined(__powerpc__)
+
+#ifdef __powerpc64__
+#define PPC_CNTLZL "cntlzd"
+#else
+#define PPC_CNTLZL "cntlzw"
+#endif
+#define BITS_PER_LONG (sizeof(long) * 8)
+
+static int
+__ilog2(unsigned long x)
+{
+ int lz;
+
+ asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
+ return BITS_PER_LONG - 1 - lz;
+}
+
+unsigned long
+fsig_log2 (unsigned long word)
+{
+ return __ilog2(word & -word);
+}
+
+#else /* Unoptimized */
+
+unsigned long
+fsig_log2 (unsigned long word)
+{
+ unsigned long result = 0;
+
+ while (!(word & 1UL))
+ {
+ result++;
+ word >>= 1;
+ }
+ return result;
+}
+#endif
+
int
fsig_devread(fsi_file_t *ffi, unsigned int sector, unsigned int offset,
unsigned int bufsize, char *buf)
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/common/fsimage_grub.h
--- a/tools/libfsimage/common/fsimage_grub.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_grub.h Thu Feb 22 10:15:29 2007 -0700
@@ -57,16 +57,19 @@ typedef struct fsig_plugin_ops {
#define disk_read_func (*fsig_disk_read_junk())
#define disk_read_hook (*fsig_disk_read_junk())
#define print_possibilities 0
+#define noisy_printf
#define grub_memset memset
#define grub_memmove memmove
+#define grub_log2 fsig_log2
extern char **fsig_disk_read_junk(void);
+unsigned long fsig_log2(unsigned long);
#define ERR_FSYS_CORRUPT 1
+#define ERR_OUTSIDE_PART 1
#define ERR_SYMLINK_LOOP 1
#define ERR_FILELENGTH 1
-#define ERR_BAD_FILETYPE 1
#define ERR_BAD_FILETYPE 1
#define ERR_FILE_NOT_FOUND 1
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/common/mapfile-GNU
--- a/tools/libfsimage/common/mapfile-GNU Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/common/mapfile-GNU Thu Feb 22 10:15:29 2007 -0700
@@ -20,6 +20,7 @@ VERSION {
fsig_init;
fsig_devread;
fsig_substring;
+ fsig_log2;
fsig_fs_buf;
fsig_file_alloc;
fsig_file_buf;
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/common/mapfile-SunOS
--- a/tools/libfsimage/common/mapfile-SunOS Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/common/mapfile-SunOS Thu Feb 22 10:15:29 2007 -0700
@@ -19,6 +19,7 @@ libfsimage.so.1.0 {
fsig_init;
fsig_devread;
fsig_substring;
+ fsig_log2;
fsig_fs_buf;
fsig_file_alloc;
fsig_file_buf;
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/ext2fs/fsys_ext2fs.c
--- a/tools/libfsimage/ext2fs/fsys_ext2fs.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c Thu Feb 22 10:15:29 2007 -0700
@@ -191,7 +191,7 @@ struct ext2_dir_entry
/* ext2/super.c */
-#define log2(n) ffz(~(n))
+#define log2(n) grub_log2(n)
#define EXT2_SUPER_MAGIC 0xEF53 /* include/linux/ext2_fs.h */
#define EXT2_ROOT_INO 2 /* include/linux/ext2_fs.h */
@@ -231,93 +231,6 @@ struct ext2_dir_entry
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-
-#if defined(__i386__) || defined(__x86_64__)
-/* include/asm-i386/bitops.h */
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-#ifdef __amd64
-#define BSF "bsfq"
-#else
-#define BSF "bsfl"
-#endif
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
- __asm__ (BSF " %1,%0"
-: "=r" (word)
-: "r" (~word));
- return word;
-}
-
-#elif defined(__ia64__)
-
-typedef unsigned long __u64;
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# define ia64_popcnt(x) __builtin_popcountl(x)
-#else
-# define ia64_popcnt(x) \
- ({ \
- __u64 ia64_intri_res; \
- asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
- ia64_intri_res; \
- })
-#endif
-
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
- unsigned long result;
-
- result = ia64_popcnt(word & (~word - 1));
- return result;
-}
-
-#elif defined(__powerpc__)
-
-#ifdef __powerpc64__
-#define PPC_CNTLZL "cntlzd"
-#else
-#define PPC_CNTLZL "cntlzw"
-#endif
-#define BITS_PER_LONG (sizeof(long) * 8)
-
-static __inline__ int
-__ilog2(unsigned long x)
-{
- int lz;
-
- asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
- return BITS_PER_LONG - 1 - lz;
-}
-
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
- if ((word = ~word) == 0)
- return BITS_PER_LONG;
- return __ilog2(word & -word);
-}
-
-#else /* Unoptimized */
-
-static __inline__ unsigned long
-ffz (unsigned long word)
-{
- unsigned long result;
-
- result = 0;
- while(word & 1)
- {
- result++;
- word >>= 1;
- }
- return result;
-}
-#endif
/* check filesystem types and read superblock into memory buffer */
int
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/fat/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/fat/Makefile Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,13 @@
+XEN_ROOT = ../../..
+
+LIB_SRCS-y = fsys_fat.c
+
+FS = fat
+
+.PHONY: all
+all: fs-all
+
+.PHONY: install
+install: fs-install
+
+include $(XEN_ROOT)/tools/libfsimage/Rules.mk
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/fat/fat.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/fat/fat.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,100 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * Defines for the FAT BIOS Parameter Block (embedded in the first block
+ * of the partition.
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* Note that some shorts are not aligned, and must therefore
+ * be declared as array of two bytes.
+ */
+struct fat_bpb {
+ __s8 ignored[3]; /* Boot strap short or near jump */
+ __s8 system_id[8]; /* Name - can be used to special case
+ partition manager volumes */
+ __u8 bytes_per_sect[2]; /* bytes per logical sector */
+ __u8 sects_per_clust;/* sectors/cluster */
+ __u8 reserved_sects[2]; /* reserved sectors */
+ __u8 num_fats; /* number of FATs */
+ __u8 dir_entries[2]; /* root directory entries */
+ __u8 short_sectors[2]; /* number of sectors */
+ __u8 media; /* media code (unused) */
+ __u16 fat_length; /* sectors/FAT */
+ __u16 secs_track; /* sectors per track */
+ __u16 heads; /* number of heads */
+ __u32 hidden; /* hidden sectors (unused) */
+ __u32 long_sectors; /* number of sectors (if short_sectors == 0) */
+
+ /* The following fields are only used by FAT32 */
+ __u32 fat32_length; /* sectors/FAT */
+ __u16 flags; /* bit 8: fat mirroring, low 4: active fat */
+ __u8 version[2]; /* major, minor filesystem version */
+ __u32 root_cluster; /* first cluster in root directory */
+ __u16 info_sector; /* filesystem info sector */
+ __u16 backup_boot; /* backup boot sector */
+ __u16 reserved2[6]; /* Unused */
+};
+
+#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
+
+/*
+ * Defines how to differentiate a 12-bit and 16-bit FAT.
+ */
+
+#define FAT_MAX_12BIT_CLUST 4087 /* 4085 + 2 */
+
+/*
+ * Defines for the file "attribute" byte
+ */
+
+#define FAT_ATTRIB_OK_MASK 0x37
+#define FAT_ATTRIB_NOT_OK_MASK 0xC8
+#define FAT_ATTRIB_DIR 0x10
+#define FAT_ATTRIB_LONGNAME 0x0F
+
+/*
+ * Defines for FAT directory entries
+ */
+
+#define FAT_DIRENTRY_LENGTH 32
+
+#define FAT_DIRENTRY_ATTRIB(entry) \
+ (*((unsigned char *) (entry+11)))
+#define FAT_DIRENTRY_VALID(entry) \
+ ( ((*((unsigned char *) entry)) != 0) \
+ && ((*((unsigned char *) entry)) != 0xE5) \
+ && !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) )
+#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \
+ ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16))
+#define FAT_DIRENTRY_FILELENGTH(entry) \
+ (*((unsigned long *) (entry+28)))
+
+#define FAT_LONGDIR_ID(entry) \
+ (*((unsigned char *) (entry)))
+#define FAT_LONGDIR_ALIASCHECKSUM(entry) \
+ (*((unsigned char *) (entry+13)))
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/fat/fsys_fat.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/fat/fsys_fat.c Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,485 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2000,2001,2005 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <limits.h>
+#include <fsimage_grub.h>
+#include "fat.h"
+
+struct fat_superblock
+{
+ int fat_offset;
+ int fat_length;
+ int fat_size;
+ int root_offset;
+ int root_max;
+ int data_offset;
+
+ int num_sectors;
+ int num_clust;
+ int clust_eof_marker;
+ int sects_per_clust;
+ int sectsize_bits;
+ int clustsize_bits;
+ int root_cluster;
+
+ int cached_fat;
+ int file_cluster;
+ int current_cluster_num;
+ int current_cluster;
+};
+
+/* pointer(s) into filesystem info buffer for DOS stuff */
+#define FAT_SUPER ( (struct fat_superblock *) \
+ ( FSYS_BUF + 32256) )/* 512 bytes long */
+#define FAT_BUF ( FSYS_BUF + 30208 ) /* 4 sector FAT buffer */
+#define NAME_BUF ( FSYS_BUF + 29184 ) /* Filename buffer (833 bytes) */
+
+#define FAT_CACHE_SIZE 2048
+
+#define log2 grub_log2
+
+int
+fat_mount (fsi_file_t *ffi, const char *options)
+{
+ struct fat_bpb bpb;
+ __u32 magic, first_fat;
+
+ /* Read bpb */
+ if (! devread (ffi, 0, 0, sizeof (bpb), (char *) &bpb))
+ return 0;
+
+ /* Check if the number of sectors per cluster is zero here, to avoid
+ zero division. */
+ if (bpb.sects_per_clust == 0)
+ return 0;
+
+ FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect));
+ FAT_SUPER->clustsize_bits
+ = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust);
+
+ /* Fill in info about super block */
+ FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors)
+ ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors;
+
+ /* FAT offset and length */
+ FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects);
+ FAT_SUPER->fat_length =
+ bpb.fat_length ? bpb.fat_length : bpb.fat32_length;
+
+ /* Rootdir offset and length for FAT12/16 */
+ FAT_SUPER->root_offset =
+ FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length;
+ FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries);
+
+ /* Data offset and number of clusters */
+ FAT_SUPER->data_offset =
+ FAT_SUPER->root_offset
+ + ((FAT_SUPER->root_max - 1) >> FAT_SUPER->sectsize_bits) + 1;
+ FAT_SUPER->num_clust =
+ 2 + ((FAT_SUPER->num_sectors - FAT_SUPER->data_offset)
+ / bpb.sects_per_clust);
+ FAT_SUPER->sects_per_clust = bpb.sects_per_clust;
+
+ if (!bpb.fat_length)
+ {
+ /* This is a FAT32 */
+ if (FAT_CVT_U16(bpb.dir_entries))
+ return 0;
+
+ if (bpb.flags & 0x0080)
+ {
+ /* FAT mirroring is disabled, get active FAT */
+ int active_fat = bpb.flags & 0x000f;
+ if (active_fat >= bpb.num_fats)
+ return 0;
+ FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
+ }
+
+ FAT_SUPER->fat_size = 8;
+ FAT_SUPER->root_cluster = bpb.root_cluster;
+
+ /* Yes the following is correct. FAT32 should be called FAT28 :) */
+ FAT_SUPER->clust_eof_marker = 0xffffff8;
+ }
+ else
+ {
+ if (!FAT_SUPER->root_max)
+ return 0;
+
+ FAT_SUPER->root_cluster = -1;
+ if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST)
+ {
+ FAT_SUPER->fat_size = 4;
+ FAT_SUPER->clust_eof_marker = 0xfff8;
+ }
+ else
+ {
+ FAT_SUPER->fat_size = 3;
+ FAT_SUPER->clust_eof_marker = 0xff8;
+ }
+ }
+
+ /* Now do some sanity checks */
+
+ if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
+ || FAT_CVT_U16(bpb.bytes_per_sect) != SECTOR_SIZE
+ || bpb.sects_per_clust != (1 << (FAT_SUPER->clustsize_bits
+ - FAT_SUPER->sectsize_bits))
+ || FAT_SUPER->num_clust <= 2
+ || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * SECTOR_SIZE)
+ > FAT_SUPER->fat_length))
+ return 0;
+
+ /* kbs: Media check on first FAT entry [ported from PUPA] */
+
+ if (!devread(ffi, FAT_SUPER->fat_offset, 0,
+ sizeof(first_fat), (char *)&first_fat))
+ return 0;
+
+ if (FAT_SUPER->fat_size == 8)
+ {
+ first_fat &= 0x0fffffff;
+ magic = 0x0fffff00;
+ }
+ else if (FAT_SUPER->fat_size == 4)
+ {
+ first_fat &= 0x0000ffff;
+ magic = 0xff00;
+ }
+ else
+ {
+ first_fat &= 0x00000fff;
+ magic = 0x0f00;
+ }
+
+ /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
+ descriptor, even if it is a so-called superfloppy (e.g. an USB key).
+ The check may be too strict for this kind of stupid BIOSes, as
+ they overwrite the media descriptor. */
+ if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
+ return 0;
+
+ FAT_SUPER->cached_fat = - 2 * FAT_CACHE_SIZE;
+ return 1;
+}
+
+int
+fat_read (fsi_file_t *ffi, char *buf, int len)
+{
+ int logical_clust;
+ int offset;
+ int ret = 0;
+ int size;
+
+ if (FAT_SUPER->file_cluster < 0)
+ {
+ /* root directory for fat16 */
+ size = FAT_SUPER->root_max - filepos;
+ if (size > len)
+ size = len;
+ if (!devread(ffi, FAT_SUPER->root_offset, filepos, size, buf))
+ return 0;
+ filepos += size;
+ return size;
+ }
+
+ logical_clust = filepos >> FAT_SUPER->clustsize_bits;
+ offset = (filepos & ((1 << FAT_SUPER->clustsize_bits) - 1));
+ if (logical_clust < FAT_SUPER->current_cluster_num)
+ {
+ FAT_SUPER->current_cluster_num = 0;
+ FAT_SUPER->current_cluster = FAT_SUPER->file_cluster;
+ }
+
+ while (len > 0)
+ {
+ int sector;
+ while (logical_clust > FAT_SUPER->current_cluster_num)
+ {
+ /* calculate next cluster */
+ int fat_entry =
+ FAT_SUPER->current_cluster * FAT_SUPER->fat_size;
+ int next_cluster;
+ int cached_pos = (fat_entry - FAT_SUPER->cached_fat);
+
+ if (cached_pos < 0 ||
+ (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE)
+ {
+ FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1));
+ cached_pos = (fat_entry - FAT_SUPER->cached_fat);
+ sector = FAT_SUPER->fat_offset
+ + FAT_SUPER->cached_fat / (2*SECTOR_SIZE);
+ if (!devread (ffi, sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
+ return 0;
+ }
+ next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1));
+ if (FAT_SUPER->fat_size == 3)
+ {
+ if (cached_pos & 1)
+ next_cluster >>= 4;
+ next_cluster &= 0xFFF;
+ }
+ else if (FAT_SUPER->fat_size == 4)
+ next_cluster &= 0xFFFF;
+
+ if (next_cluster >= FAT_SUPER->clust_eof_marker)
+ return ret;
+ if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust)
+ {
+ errnum = ERR_FSYS_CORRUPT;
+ return 0;
+ }
+
+ FAT_SUPER->current_cluster = next_cluster;
+ FAT_SUPER->current_cluster_num++;
+ }
+
+ sector = FAT_SUPER->data_offset +
+ ((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits
+ - FAT_SUPER->sectsize_bits));
+ size = (1 << FAT_SUPER->clustsize_bits) - offset;
+ if (size > len)
+ size = len;
+
+ disk_read_func = disk_read_hook;
+
+ devread(ffi, sector, offset, size, buf);
+
+ disk_read_func = NULL;
+
+ len -= size;
+ buf += size;
+ ret += size;
+ filepos += size;
+ logical_clust++;
+ offset = 0;
+ }
+ return errnum ? 0 : ret;
+}
+
+int
+fat_dir (fsi_file_t *ffi, char *dirname)
+{
+ char *rest, ch, dir_buf[FAT_DIRENTRY_LENGTH];
+ char *filename = (char *) NAME_BUF;
+ int attrib = FAT_ATTRIB_DIR;
+#ifndef STAGE1_5
+ int do_possibilities = 0;
+#endif
+
+ /* XXX I18N:
+ * the positions 2,4,6 etc are high bytes of a 16 bit unicode char
+ */
+ static unsigned char longdir_pos[] =
+ { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
+ int slot = -2;
+ int alias_checksum = -1;
+
+ FAT_SUPER->file_cluster = FAT_SUPER->root_cluster;
+ filepos = 0;
+ FAT_SUPER->current_cluster_num = INT_MAX;
+
+ /* main loop to find desired directory entry */
+ loop:
+
+ /* if we have a real file (and we're not just printing possibilities),
+ then this is where we want to exit */
+
+ if (!*dirname || isspace (*dirname))
+ {
+ if (attrib & FAT_ATTRIB_DIR)
+ {
+ errnum = ERR_BAD_FILETYPE;
+ return 0;
+ }
+
+ return 1;
+ }
+
+ /* continue with the file/directory name interpretation */
+
+ while (*dirname == '/')
+ dirname++;
+
+ if (!(attrib & FAT_ATTRIB_DIR))
+ {
+ errnum = ERR_BAD_FILETYPE;
+ return 0;
+ }
+ /* Directories don't have a file size */
+ filemax = INT_MAX;
+
+ for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+
+ *rest = 0;
+
+# ifndef STAGE1_5
+ if (print_possibilities && ch != '/')
+ do_possibilities = 1;
+# endif
+
+ while (1)
+ {
+ if (fat_read (ffi, dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH
+ || dir_buf[0] == 0)
+ {
+ if (!errnum)
+ {
+# ifndef STAGE1_5
+ if (print_possibilities < 0)
+ {
+#if 0
+ putchar ('\n');
+#endif
+ return 1;
+ }
+# endif /* STAGE1_5 */
+
+ errnum = ERR_FILE_NOT_FOUND;
+ *rest = ch;
+ }
+
+ return 0;
+ }
+
+ if (FAT_DIRENTRY_ATTRIB (dir_buf) == FAT_ATTRIB_LONGNAME)
+ {
+ /* This is a long filename. The filename is build from back
+ * to front and may span multiple entries. To bind these
+ * entries together they all contain the same checksum over
+ * the short alias.
+ *
+ * The id field tells if this is the first entry (the last
+ * part) of the long filename, and also at which offset this
+ * belongs.
+ *
+ * We just write the part of the long filename this entry
+ * describes and continue with the next dir entry.
+ */
+ int i, offset;
+ unsigned char id = FAT_LONGDIR_ID(dir_buf);
+
+ if ((id & 0x40))
+ {
+ id &= 0x3f;
+ slot = id;
+ filename[slot * 13] = 0;
+ alias_checksum = FAT_LONGDIR_ALIASCHECKSUM(dir_buf);
+ }
+
+ if (id != slot || slot == 0
+ || alias_checksum != FAT_LONGDIR_ALIASCHECKSUM(dir_buf))
+ {
+ alias_checksum = -1;
+ continue;
+ }
+
+ slot--;
+ offset = slot * 13;
+
+ for (i=0; i < 13; i++)
+ filename[offset+i] = dir_buf[longdir_pos[i]];
+ continue;
+ }
+
+ if (!FAT_DIRENTRY_VALID (dir_buf))
+ continue;
+
+ if (alias_checksum != -1 && slot == 0)
+ {
+ int i;
+ unsigned char sum;
+
+ slot = -2;
+ for (sum = 0, i = 0; i< 11; i++)
+ sum = ((sum >> 1) | (sum << 7)) + dir_buf[i];
+
+ if (sum == alias_checksum)
+ {
+# ifndef STAGE1_5
+ if (do_possibilities)
+ goto print_filename;
+# endif /* STAGE1_5 */
+
+ if (substring (dirname, filename) == 0)
+ break;
+ }
+ }
+
+ /* XXX convert to 8.3 filename format here */
+ {
+ int i, j, c;
+
+ for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i]))
+ && !isspace (c); i++);
+
+ filename[i++] = '.';
+
+ for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j]))
+ && !isspace (c); j++);
+
+ if (j == 0)
+ i--;
+
+ filename[i + j] = 0;
+ }
+
+# ifndef STAGE1_5
+ if (do_possibilities)
+ {
+ print_filename:
+ if (substring (dirname, filename) <= 0)
+ {
+ if (print_possibilities > 0)
+ print_possibilities = -print_possibilities;
+ print_a_completion (filename);
+ }
+ continue;
+ }
+# endif /* STAGE1_5 */
+
+ if (substring (dirname, filename) == 0)
+ break;
+ }
+
+ *(dirname = rest) = ch;
+
+ attrib = FAT_DIRENTRY_ATTRIB (dir_buf);
+ filemax = FAT_DIRENTRY_FILELENGTH (dir_buf);
+ filepos = 0;
+ FAT_SUPER->file_cluster = FAT_DIRENTRY_FIRST_CLUSTER (dir_buf);
+ FAT_SUPER->current_cluster_num = INT_MAX;
+
+ /* go back to main loop at top of function */
+ goto loop;
+}
+
+fsi_plugin_ops_t *
+fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
+{
+ static fsig_plugin_ops_t ops = {
+ FSIMAGE_PLUGIN_VERSION,
+ .fpo_mount = fat_mount,
+ .fpo_dir = fat_dir,
+ .fpo_read = fat_read
+ };
+
+ *name = "fat";
+ return (fsig_init(fp, &ops));
+}
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/iso9660/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/iso9660/Makefile Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,15 @@
+XEN_ROOT = ../../..
+
+LIB_SRCS-y = fsys_iso9660.c
+
+FS = iso9660
+
+.PHONY: all
+all: fs-all
+
+.PHONY: install
+install: fs-install
+
+fsys_iso9660.c: iso9660.h
+
+include $(XEN_ROOT)/tools/libfsimage/Rules.mk
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/iso9660/fsys_iso9660.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/iso9660/fsys_iso9660.c Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,463 @@
+/*
+ * ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
+ * including Rock Ridge Extensions support
+ *
+ * Copyright (C) 1998, 1999 Kousuke Takai <tak@xxxxxxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * References:
+ * linux/fs/isofs/rock.[ch]
+ * mkisofs-1.11.1/diag/isoinfo.c
+ * mkisofs-1.11.1/iso9660.h
+ * (all are written by Eric Youngdale)
+ *
+ * Modifications by:
+ * Leonid Lisovskiy <lly@xxxxxxxxx> 2003
+ */
+
+#include <fsimage_grub.h>
+#include <limits.h>
+
+#include "iso9660.h"
+
+#define MAXINT INT_MAX
+
+/* iso9660 super-block data in memory */
+struct iso_sb_info {
+ unsigned long vol_sector;
+
+};
+
+/* iso fs inode data in memory */
+struct iso_inode_info {
+ unsigned long file_start;
+};
+
+#define ISO_SUPER \
+ ((struct iso_sb_info *)(FSYS_BUF))
+#define INODE \
+ ((struct iso_inode_info *)(FSYS_BUF+sizeof(struct iso_sb_info)))
+#define PRIMDESC ((struct iso_primary_descriptor *)(FSYS_BUF + 2048))
+#define DIRREC ((struct iso_directory_record *)(FSYS_BUF + 4096))
+#define RRCONT_BUF ((unsigned char *)(FSYS_BUF + 6144))
+#define NAME_BUF ((unsigned char *)(FSYS_BUF + 8192))
+
+
+#define log2 grub_log2
+
+static int
+iso9660_devread (fsi_file_t *ffi, int sector, int byte_offset, int byte_len,
char *buf)
+{
+ static int read_count = 0, threshold = 2;
+ unsigned short sector_size_lg2 = log2(512 /*buf_geom.sector_size*/);
+
+ /*
+ * We have to use own devread() function since BIOS return wrong geometry
+ */
+ if (sector < 0)
+ {
+ errnum = ERR_OUTSIDE_PART;
+ return 0;
+ }
+ if (byte_len <= 0)
+ return 1;
+
+#if 0
+ sector += (byte_offset >> sector_size_lg2);
+ byte_offset &= (buf_geom.sector_size - 1);
+ asm volatile ("shl%L0 %1,%0"
+ : "=r"(sector)
+ : "Ic"((int8_t)(ISO_SECTOR_BITS - sector_size_lg2)),
+ "0"(sector));
+#else
+ sector = (sector * 4) + (byte_offset >> sector_size_lg2);
+ byte_offset &= 511;
+#endif
+
+#if !defined(STAGE1_5)
+ if (disk_read_hook && debug)
+ printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
+#endif /* !STAGE1_5 */
+
+ read_count += (byte_len >> 9);
+ if ((read_count >> 11) > threshold) {
+ noisy_printf(".");
+ threshold += 2; /* one dot every 2 MB */
+ }
+ return devread(ffi, sector, byte_offset, byte_len, buf);
+}
+
+int
+iso9660_mount (fsi_file_t *ffi, const char *options)
+{
+ unsigned int sector;
+
+ /*
+ * Because there is no defined slice type ID for ISO-9660 filesystem,
+ * this test will pass only either (1) if entire disk is used, or
+ * (2) if current partition is BSD style sub-partition whose ID is
+ * ISO-9660.
+ */
+#if 0
+ if ((current_partition != 0xFFFFFF)
+ && !IS_PC_SLICE_TYPE_BSD_WITH_FS(current_slice, FS_ISO9660))
+ return 0;
+#endif
+
+ /*
+ * Currently, only FIRST session of MultiSession disks are supported !!!
+ */
+ for (sector = 16 ; sector < 32 ; sector++)
+ {
+ if (!iso9660_devread(ffi, sector, 0, sizeof(*PRIMDESC), (char
*)PRIMDESC))
+ break;
+ /* check ISO_VD_PRIMARY and ISO_STANDARD_ID */
+ if (PRIMDESC->type.l == ISO_VD_PRIMARY
+ && !memcmp(PRIMDESC->id, ISO_STANDARD_ID, sizeof(PRIMDESC->id)))
+ {
+ ISO_SUPER->vol_sector = sector;
+ INODE->file_start = 0;
+#if 0
+ fsmax = PRIMDESC->volume_space_size.l;
+#endif
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
+iso9660_dir (fsi_file_t *ffi, char *dirname)
+{
+ struct iso_directory_record *idr;
+ RR_ptr_t rr_ptr;
+ struct rock_ridge *ce_ptr;
+ unsigned int pathlen;
+ int size;
+ unsigned int extent;
+ unsigned char file_type;
+ unsigned int rr_len;
+ unsigned char rr_flag;
+
+ idr = &PRIMDESC->root_directory_record;
+ INODE->file_start = 0;
+
+ do
+ {
+ while (*dirname == '/') /* skip leading slashes */
+ dirname++;
+ /* pathlen = strcspn(dirname, "/\n\t "); */
+ for (pathlen = 0 ;
+ dirname[pathlen]
+ && !isspace(dirname[pathlen]) && dirname[pathlen] != '/' ;
+ pathlen++)
+ ;
+
+ size = idr->size.l;
+ extent = idr->extent.l;
+
+ while (size > 0)
+ {
+ if (!iso9660_devread(ffi, extent, 0, ISO_SECTOR_SIZE, (char *)DIRREC))
+ {
+ errnum = ERR_FSYS_CORRUPT;
+ return 0;
+ }
+ extent++;
+
+ idr = (struct iso_directory_record *)DIRREC;
+ for (; idr->length.l > 0;
+ idr = (struct iso_directory_record *)((char *)idr +
idr->length.l) )
+ {
+ const char *name = (const char *)idr->name;
+ unsigned int name_len = idr->name_len.l;
+
+ file_type = (idr->flags.l & 2) ? ISO_DIRECTORY : ISO_REGULAR;
+ if (name_len == 1)
+ {
+ if ((name[0] == 0) || /* self */
+ (name[0] == 1)) /* parent */
+ continue;
+ }
+ if (name_len > 2 && CHECK2(name + name_len - 2, ';', '1'))
+ {
+ name_len -= 2; /* truncate trailing file version */
+ if (name_len > 1 && name[name_len - 1] == '.')
+ name_len--; /* truncate trailing dot */
+ }
+
+ /*
+ * Parse Rock-Ridge extension
+ */
+ rr_len = (idr->length.l - idr->name_len.l
+ - sizeof(struct iso_directory_record)
+ + sizeof(idr->name));
+ rr_ptr.ptr = ((char *)idr + idr->name_len.l
+ + sizeof(struct iso_directory_record)
+ - sizeof(idr->name));
+ if (rr_ptr.i & 1)
+ rr_ptr.i++, rr_len--;
+ ce_ptr = NULL;
+ rr_flag = RR_FLAG_NM | RR_FLAG_PX /*| RR_FLAG_SL*/;
+
+ while (rr_len >= 4)
+ {
+ if (rr_ptr.rr->version != 1)
+ {
+#ifndef STAGE1_5
+ if (debug)
+ printf(
+ "Non-supported version (%d) RockRidge chunk "
+ "`%c%c'\n", rr_ptr.rr->version,
+ rr_ptr.rr->signature & 0xFF,
+ rr_ptr.rr->signature >> 8);
+#endif
+ }
+ else
+ {
+ switch (rr_ptr.rr->signature)
+ {
+ case RRMAGIC('R', 'R'):
+ if ( rr_ptr.rr->len >= (4+sizeof(struct RR)))
+ rr_flag &= rr_ptr.rr->u.rr.flags.l;
+ break;
+ case RRMAGIC('N', 'M'):
+ name = (const char *)rr_ptr.rr->u.nm.name;
+ name_len = rr_ptr.rr->len - (4+sizeof(struct NM));
+ rr_flag &= ~RR_FLAG_NM;
+ break;
+ case RRMAGIC('P', 'X'):
+ if (rr_ptr.rr->len >= (4+sizeof(struct PX)))
+ {
+ file_type = ((rr_ptr.rr->u.px.mode.l &
POSIX_S_IFMT)
+ == POSIX_S_IFREG
+ ? ISO_REGULAR
+ : ((rr_ptr.rr->u.px.mode.l &
POSIX_S_IFMT)
+ == POSIX_S_IFDIR
+ ? ISO_DIRECTORY : ISO_OTHER));
+ rr_flag &= ~RR_FLAG_PX;
+ }
+ break;
+ case RRMAGIC('C', 'E'):
+ if (rr_ptr.rr->len >= (4+sizeof(struct CE)))
+ ce_ptr = rr_ptr.rr;
+ break;
+#if 0 // RockRidge symlinks are not supported yet
+ case RRMAGIC('S', 'L'):
+ {
+ int slen;
+ unsigned char rootflag, prevflag;
+ char *rpnt = NAME_BUF+1024;
+ struct SL_component *slp;
+
+ slen = rr_ptr.rr->len - (4+1);
+ slp = &rr_ptr.rr->u.sl.link;
+ while (slen > 1)
+ {
+ rootflag = 0;
+ switch (slp->flags.l)
+ {
+ case 0:
+ memcpy(rpnt, slp->text, slp->len);
+ rpnt += slp->len;
+ break;
+ case 4:
+ *rpnt++ = '.';
+ /* fallthru */
+ case 2:
+ *rpnt++ = '.';
+ break;
+ case 8:
+ rootflag = 1;
+ *rpnt++ = '/';
+ break;
+ default:
+ printf("Symlink component flag not
implemented (%d)\n",
+ slp->flags.l);
+ slen = 0;
+ break;
+ }
+ slen -= slp->len + 2;
+ prevflag = slp->flags.l;
+ slp = (struct SL_component *) ((char *) slp +
slp->len + 2);
+
+ if (slen < 2)
+ {
+ /*
+ * If there is another SL record, and this
component
+ * record isn't continued, then add a slash.
+ */
+ if ((!rootflag) && (rr_ptr.rr->u.sl.flags.l
& 1) && !(prevflag & 1))
+ *rpnt++='/';
+ break;
+ }
+
+ /*
+ * If this component record isn't continued,
then append a '/'.
+ */
+ if (!rootflag && !(prevflag & 1))
+ *rpnt++ = '/';
+ }
+ *rpnt++ = '\0';
+ grub_putstr(NAME_BUF+1024);// debug print!
+ }
+ rr_flag &= ~RR_FLAG_SL;
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ if (!rr_flag)
+ /*
+ * There is no more extension we expects...
+ */
+ break;
+
+ rr_len -= rr_ptr.rr->len;
+ rr_ptr.ptr += rr_ptr.rr->len;
+ if (rr_len < 4 && ce_ptr != NULL)
+ {
+ /* preserve name before loading new extent. */
+ if( RRCONT_BUF <= (unsigned char *)name
+ && (unsigned char *)name < RRCONT_BUF +
ISO_SECTOR_SIZE )
+ {
+ memcpy(NAME_BUF, name, name_len);
+ name = (const char *)NAME_BUF;
+ }
+ rr_ptr.ptr = (char *)RRCONT_BUF + ce_ptr->u.ce.offset.l;
+ rr_len = ce_ptr->u.ce.size.l;
+ if (!iso9660_devread(ffi, ce_ptr->u.ce.extent.l, 0,
ISO_SECTOR_SIZE, (char *)RRCONT_BUF))
+ {
+ errnum = 0; /* this is not fatal. */
+ break;
+ }
+ ce_ptr = NULL;
+ }
+ } /* rr_len >= 4 */
+
+ filemax = MAXINT;
+ if (name_len >= pathlen
+ && !memcmp(name, dirname, pathlen))
+ {
+ if (dirname[pathlen] == '/' || !print_possibilities)
+ {
+ /*
+ * DIRNAME is directory component of pathname,
+ * or we are to open a file.
+ */
+ if (pathlen == name_len)
+ {
+ if (dirname[pathlen] == '/')
+ {
+ if (file_type != ISO_DIRECTORY)
+ {
+ errnum = ERR_BAD_FILETYPE;
+ return 0;
+ }
+ goto next_dir_level;
+ }
+ if (file_type != ISO_REGULAR)
+ {
+ errnum = ERR_BAD_FILETYPE;
+ return 0;
+ }
+ INODE->file_start = idr->extent.l;
+ filepos = 0;
+ filemax = idr->size.l;
+ return 1;
+ }
+ }
+ else /* Completion */
+ {
+#ifndef STAGE1_5
+ if (print_possibilities > 0)
+ print_possibilities = -print_possibilities;
+ memcpy(NAME_BUF, name, name_len);
+ NAME_BUF[name_len] = '\0';
+ print_a_completion (NAME_BUF);
+#endif
+ }
+ }
+ } /* for */
+
+ size -= ISO_SECTOR_SIZE;
+ } /* size>0 */
+
+ if (dirname[pathlen] == '/' || print_possibilities >= 0)
+ {
+ errnum = ERR_FILE_NOT_FOUND;
+ return 0;
+ }
+
+ next_dir_level:
+ dirname += pathlen;
+
+ } while (*dirname == '/');
+
+ return 1;
+}
+
+int
+iso9660_read (fsi_file_t *ffi, char *buf, int len)
+{
+ int sector, blkoffset, size, ret;
+
+ if (INODE->file_start == 0)
+ return 0;
+
+ ret = 0;
+ blkoffset = filepos & (ISO_SECTOR_SIZE - 1);
+ sector = filepos >> ISO_SECTOR_BITS;
+ while (len > 0)
+ {
+ size = ISO_SECTOR_SIZE - blkoffset;
+ if (size > len)
+ size = len;
+
+ disk_read_func = disk_read_hook;
+
+ if (!iso9660_devread(ffi, INODE->file_start + sector, blkoffset, size,
buf))
+ return 0;
+
+ disk_read_func = NULL;
+
+ len -= size;
+ buf += size;
+ ret += size;
+ filepos += size;
+ sector++;
+ blkoffset = 0;
+ }
+
+ return ret;
+}
+
+fsi_plugin_ops_t *
+fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
+{
+ static fsig_plugin_ops_t ops = {
+ FSIMAGE_PLUGIN_VERSION,
+ .fpo_mount = iso9660_mount,
+ .fpo_dir = iso9660_dir,
+ .fpo_read = iso9660_read
+ };
+
+ *name = "iso9660";
+ return (fsig_init(fp, &ops));
+}
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/iso9660/iso9660.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libfsimage/iso9660/iso9660.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,219 @@
+/*
+ * ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
+ * including Rock Ridge Extensions support
+ *
+ * Copyright (C) 1998, 1999 Kousuke Takai <tak@xxxxxxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * References:
+ * linux/fs/isofs/rock.[ch]
+ * mkisofs-1.11.1/diag/isoinfo.c
+ * mkisofs-1.11.1/iso9660.h
+ * (all are written by Eric Youngdale)
+ */
+
+#ifndef _ISO9660_H_
+#define _ISO9660_H_
+
+#define ISO_SECTOR_BITS (11)
+#define ISO_SECTOR_SIZE (1<<ISO_SECTOR_BITS)
+
+#define ISO_REGULAR 1 /* regular file */
+#define ISO_DIRECTORY 2 /* directory */
+#define ISO_OTHER 0 /* other file (with Rock Ridge) */
+
+#define RR_FLAG_PX 0x01 /* have POSIX file attributes */
+#define RR_FLAG_PN 0x02 /* POSIX devices */
+#define RR_FLAG_SL 0x04 /* Symbolic link */
+#define RR_FLAG_NM 0x08 /* have alternate file name */
+#define RR_FLAG_CL 0x10 /* Child link */
+#define RR_FLAG_PL 0x20 /* Parent link */
+#define RR_FLAG_RE 0x40 /* Relocation directory */
+#define RR_FLAG_TF 0x80 /* Timestamps */
+
+/* POSIX file attributes for Rock Ridge extensions */
+#define POSIX_S_IFMT 0xF000
+#define POSIX_S_IFREG 0x8000
+#define POSIX_S_IFDIR 0x4000
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+
+#ifndef ASM_FILE
+
+#ifndef __sun
+#ifndef __BIT_TYPES_DEFINED__
+typedef int int8_t __attribute__((mode(QI)));
+typedef unsigned int u_int8_t __attribute__((mode(QI)));
+typedef int int16_t __attribute__((mode(HI)));
+typedef unsigned int u_int16_t __attribute__((mode(HI)));
+typedef int int32_t __attribute__((mode(SI)));
+typedef unsigned int u_int32_t __attribute__((mode(SI)));
+#endif
+#else
+#ifndef GRUB_UTIL
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+#endif /* ! GRUB_UTIL */
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned int u_int32_t;
+#endif /* __sun */
+
+typedef union {
+ u_int8_t l,b;
+} iso_8bit_t;
+
+struct __iso_16bit {
+ u_int16_t l, b;
+} __attribute__ ((packed));
+typedef struct __iso_16bit iso_16bit_t;
+
+struct __iso_32bit {
+ u_int32_t l, b;
+} __attribute__ ((packed));
+typedef struct __iso_32bit iso_32bit_t;
+
+typedef u_int8_t iso_date_t[7];
+
+struct iso_directory_record {
+ iso_8bit_t length;
+ iso_8bit_t ext_attr_length;
+ iso_32bit_t extent;
+ iso_32bit_t size;
+ iso_date_t date;
+ iso_8bit_t flags;
+ iso_8bit_t file_unit_size;
+ iso_8bit_t interleave;
+ iso_16bit_t volume_seq_number;
+ iso_8bit_t name_len;
+ u_int8_t name[1];
+} __attribute__ ((packed));
+
+struct iso_primary_descriptor {
+ iso_8bit_t type;
+ u_int8_t id[5];
+ iso_8bit_t version;
+ u_int8_t _unused1[1];
+ u_int8_t system_id[32];
+ u_int8_t volume_id[32];
+ u_int8_t _unused2[8];
+ iso_32bit_t volume_space_size;
+ u_int8_t _unused3[32];
+ iso_16bit_t volume_set_size;
+ iso_16bit_t volume_seq_number;
+ iso_16bit_t logical_block_size;
+ iso_32bit_t path_table_size;
+ u_int8_t type_l_path_table[4];
+ u_int8_t opt_type_l_path_table[4];
+ u_int8_t type_m_path_table[4];
+ u_int8_t opt_type_m_path_table[4];
+ struct iso_directory_record root_directory_record;
+ u_int8_t volume_set_id[128];
+ u_int8_t publisher_id[128];
+ u_int8_t preparer_id[128];
+ u_int8_t application_id[128];
+ u_int8_t copyright_file_id[37];
+ u_int8_t abstract_file_id[37];
+ u_int8_t bibliographic_file_id[37];
+ u_int8_t creation_date[17];
+ u_int8_t modification_date[17];
+ u_int8_t expiration_date[17];
+ u_int8_t effective_date[17];
+ iso_8bit_t file_structure_version;
+ u_int8_t _unused4[1];
+ u_int8_t application_data[512];
+ u_int8_t _unused5[653];
+} __attribute__ ((packed));
+
+struct rock_ridge {
+ u_int16_t signature;
+ u_int8_t len;
+ u_int8_t version;
+ union {
+ struct SP {
+ u_int16_t magic;
+ u_int8_t skip;
+ } sp;
+ struct CE {
+ iso_32bit_t extent;
+ iso_32bit_t offset;
+ iso_32bit_t size;
+ } ce;
+ struct ER {
+ u_int8_t len_id;
+ u_int8_t len_des;
+ u_int8_t len_src;
+ u_int8_t ext_ver;
+ u_int8_t data[0];
+ } er;
+ struct RR {
+ iso_8bit_t flags;
+ } rr;
+ struct PX {
+ iso_32bit_t mode;
+ iso_32bit_t nlink;
+ iso_32bit_t uid;
+ iso_32bit_t gid;
+ } px;
+ struct PN {
+ iso_32bit_t dev_high;
+ iso_32bit_t dev_low;
+ } pn;
+ struct SL {
+ iso_8bit_t flags;
+ struct SL_component {
+ iso_8bit_t flags;
+ u_int8_t len;
+ u_int8_t text[0];
+ } link;
+ } sl;
+ struct NM {
+ iso_8bit_t flags;
+ u_int8_t name[0];
+ } nm;
+ struct CL {
+ iso_32bit_t location;
+ } cl;
+ struct PL {
+ iso_32bit_t location;
+ } pl;
+ struct TF {
+ iso_8bit_t flags;
+ iso_date_t times[0];
+ } tf;
+ } u;
+} __attribute__ ((packed));
+
+typedef union RR_ptr {
+ struct rock_ridge *rr;
+ char *ptr;
+ int i;
+} RR_ptr_t;
+
+#define RRMAGIC(c1, c2) ((c1)|(c2) << 8)
+
+#define CHECK2(ptr, c1, c2) \
+ (*(unsigned short *)(ptr) == (((c1) | (c2) << 8) & 0xFFFF))
+
+#endif /* !ASM_FILE */
+
+#endif /* _ISO9660_H_ */
diff -r 9364bea18bc4 -r 202eb735b425 tools/libfsimage/reiserfs/fsys_reiserfs.c
--- a/tools/libfsimage/reiserfs/fsys_reiserfs.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c Thu Feb 22 10:15:29 2007 -0700
@@ -363,83 +363,6 @@ struct fsys_reiser_info
#define JOURNAL_START ((__u32 *) (INFO + 1))
#define JOURNAL_END ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
-#if defined(__i386__) || defined(__x86_64__)
-
-#ifdef __amd64
-#define BSF "bsfq"
-#else
-#define BSF "bsfl"
-#endif
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
- __asm__ (BSF " %1,%0"
- : "=r" (word)
- : "r" (word));
- return word;
-}
-
-#elif defined(__ia64__)
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# define ia64_popcnt(x) __builtin_popcountl(x)
-#else
-# define ia64_popcnt(x) \
- ({ \
- __u64 ia64_intri_res; \
- asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
- ia64_intri_res; \
- })
-#endif
-
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
- unsigned long result;
-
- result = ia64_popcnt((word - 1) & ~word);
- return result;
-}
-
-#elif defined(__powerpc__)
-
-#ifdef __powerpc64__
-#define PPC_CNTLZL "cntlzd"
-#else
-#define PPC_CNTLZL "cntlzw"
-#endif
-#define BITS_PER_LONG (sizeof(long) * 8)
-
-static __inline__ int
-__ilog2(unsigned long x)
-{
- int lz;
-
- asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
- return BITS_PER_LONG - 1 - lz;
-}
-
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
- return __ilog2(word & -word);
-}
-
-#else /* Unoptimized */
-
-static __inline__ unsigned long
-grub_log2 (unsigned long word)
-{
- unsigned long result = 0;
-
- while (!(word & 1UL))
- {
- result++;
- word >>= 1;
- }
- return result;
-}
-#endif
#define log2 grub_log2
static __inline__ int
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_console.h
--- a/tools/libxen/include/xen_console.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/include/xen_console.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,13 @@
#include "xen_common.h"
#include "xen_console_decl.h"
#include "xen_console_protocol.h"
+#include "xen_string_string_map.h"
#include "xen_vm_decl.h"
/*
- * The console class.
- *
+ * The console class.
+ *
* A console.
*/
@@ -65,8 +66,9 @@ typedef struct xen_console_record
xen_console handle;
char *uuid;
enum xen_console_protocol protocol;
- char *uri;
+ char *location;
struct xen_vm_record_opt *vm;
+ xen_string_string_map *other_config;
} xen_console_record;
/**
@@ -191,10 +193,10 @@ xen_console_get_protocol(xen_session *se
/**
- * Get the uri field of the given console.
- */
-extern bool
-xen_console_get_uri(xen_session *session, char **result, xen_console console);
+ * Get the location field of the given console.
+ */
+extern bool
+xen_console_get_location(xen_session *session, char **result, xen_console
console);
/**
@@ -204,4 +206,35 @@ xen_console_get_vm(xen_session *session,
xen_console_get_vm(xen_session *session, xen_vm *result, xen_console console);
+/**
+ * Get the other_config field of the given console.
+ */
+extern bool
+xen_console_get_other_config(xen_session *session, xen_string_string_map
**result, xen_console console);
+
+
+/**
+ * Set the other_config field of the given console.
+ */
+extern bool
+xen_console_set_other_config(xen_session *session, xen_console console,
xen_string_string_map *other_config);
+
+
+/**
+ * Add the given key-value pair to the other_config field of the given
+ * console.
+ */
+extern bool
+xen_console_add_to_other_config(xen_session *session, xen_console console,
char *key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * other_config field of the given console. If the key is not in that Map,
+ * then do nothing.
+ */
+extern bool
+xen_console_remove_from_other_config(xen_session *session, xen_console
console, char *key);
+
+
#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_host.h
--- a/tools/libxen/include/xen_host.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/include/xen_host.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include "xen_pbd_decl.h"
#include "xen_pif_decl.h"
#include "xen_sr_decl.h"
+#include "xen_string_set.h"
#include "xen_string_string_map.h"
#include "xen_vm_decl.h"
@@ -73,6 +74,7 @@ typedef struct xen_host_record
char *name_description;
xen_string_string_map *software_version;
xen_string_string_map *other_config;
+ struct xen_string_set *supported_bootloaders;
struct xen_vm_record_opt_set *resident_vms;
xen_string_string_map *logging;
struct xen_pif_record_opt_set *pifs;
@@ -177,20 +179,6 @@ xen_host_get_by_uuid(xen_session *sessio
/**
- * Create a new host instance, and return its handle.
- */
-extern bool
-xen_host_create(xen_session *session, xen_host *result, xen_host_record
*record);
-
-
-/**
- * Destroy the specified host instance.
- */
-extern bool
-xen_host_destroy(xen_session *session, xen_host host);
-
-
-/**
* Get all the host instances with the given label.
*/
extern bool
@@ -230,6 +218,13 @@ xen_host_get_software_version(xen_sessio
*/
extern bool
xen_host_get_other_config(xen_session *session, xen_string_string_map
**result, xen_host host);
+
+
+/**
+ * Get the supported_bootloaders field of the given host.
+ */
+extern bool
+xen_host_get_supported_bootloaders(xen_session *session, struct xen_string_set
**result, xen_host host);
/**
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_internal.h
--- a/tools/libxen/include/xen_internal.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/include/xen_internal.h Thu Feb 22 10:15:29 2007 -0700
@@ -149,7 +149,10 @@ type__ ## _set *
type__ ## _set * \
type__ ## _set_alloc(size_t size) \
{ \
- return calloc(1, sizeof(type__ ## _set) + size * sizeof(type__)); \
+ type__ ## _set *result = calloc(1, sizeof(type__ ## _set) + \
+ size * sizeof(type__)); \
+ result->size = size; \
+ return result; \
} \
\
void \
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_string_set.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_string_set.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006-2007, 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_STRING_SET_H
+#define XEN_STRING_SET_H
+
+
+#include "xen_common.h"
+
+
+typedef struct xen_string_set
+{
+ size_t size;
+ char *contents[];
+} xen_string_set;
+
+
+/**
+ * Allocate a xen_string_set of the given size.
+ */
+extern xen_string_set *
+xen_string_set_alloc(size_t size);
+
+/**
+ * Free the given xen_string_set. The given set must have been allocated
+ * by this library.
+ */
+extern void
+xen_string_set_free(xen_string_set *set);
+
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vbd.h
--- a/tools/libxen/include/xen_vbd.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/include/xen_vbd.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,11 @@
#define XEN_VBD_H
#include "xen_common.h"
+#include "xen_string_string_map.h"
#include "xen_vbd_decl.h"
+#include "xen_vbd_metrics_decl.h"
#include "xen_vbd_mode.h"
+#include "xen_vbd_type.h"
#include "xen_vdi_decl.h"
#include "xen_vm_decl.h"
@@ -71,8 +74,10 @@ typedef struct xen_vbd_record
char *image;
bool bootable;
enum xen_vbd_mode mode;
- double io_read_kbs;
- double io_write_kbs;
+ enum xen_vbd_type type;
+ char *qos_algorithm_type;
+ xen_string_string_map *qos_algorithm_params;
+ struct xen_vbd_metrics_record_opt *metrics;
} xen_vbd_record;
/**
@@ -155,14 +160,14 @@ xen_vbd_record_opt_set_free(xen_vbd_reco
/**
- * Get the current state of the given VBD. !!!
+ * Get a record containing the current state of the given VBD.
*/
extern bool
xen_vbd_get_record(xen_session *session, xen_vbd_record **result, xen_vbd vbd);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the VBD instance with the specified UUID.
*/
extern bool
xen_vbd_get_by_uuid(xen_session *session, xen_vbd *result, char *uuid);
@@ -225,17 +230,31 @@ xen_vbd_get_mode(xen_session *session, e
/**
- * Get the io/read_kbs field of the given VBD.
- */
-extern bool
-xen_vbd_get_io_read_kbs(xen_session *session, double *result, xen_vbd vbd);
-
-
-/**
- * Get the io/write_kbs field of the given VBD.
- */
-extern bool
-xen_vbd_get_io_write_kbs(xen_session *session, double *result, xen_vbd vbd);
+ * Get the type field of the given VBD.
+ */
+extern bool
+xen_vbd_get_type(xen_session *session, enum xen_vbd_type *result, xen_vbd vbd);
+
+
+/**
+ * Get the qos/algorithm_type field of the given VBD.
+ */
+extern bool
+xen_vbd_get_qos_algorithm_type(xen_session *session, char **result, xen_vbd
vbd);
+
+
+/**
+ * Get the qos/algorithm_params field of the given VBD.
+ */
+extern bool
+xen_vbd_get_qos_algorithm_params(xen_session *session, xen_string_string_map
**result, xen_vbd vbd);
+
+
+/**
+ * Get the metrics field of the given VBD.
+ */
+extern bool
+xen_vbd_get_metrics(xen_session *session, xen_vbd_metrics *result, xen_vbd
vbd);
/**
@@ -257,6 +276,44 @@ xen_vbd_set_bootable(xen_session *sessio
*/
extern bool
xen_vbd_set_mode(xen_session *session, xen_vbd vbd, enum xen_vbd_mode mode);
+
+
+/**
+ * Set the type field of the given VBD.
+ */
+extern bool
+xen_vbd_set_type(xen_session *session, xen_vbd vbd, enum xen_vbd_type type);
+
+
+/**
+ * Set the qos/algorithm_type field of the given VBD.
+ */
+extern bool
+xen_vbd_set_qos_algorithm_type(xen_session *session, xen_vbd vbd, char
*algorithm_type);
+
+
+/**
+ * Set the qos/algorithm_params field of the given VBD.
+ */
+extern bool
+xen_vbd_set_qos_algorithm_params(xen_session *session, xen_vbd vbd,
xen_string_string_map *algorithm_params);
+
+
+/**
+ * Add the given key-value pair to the qos/algorithm_params field of
+ * the given VBD.
+ */
+extern bool
+xen_vbd_add_to_qos_algorithm_params(xen_session *session, xen_vbd vbd, char
*key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * qos/algorithm_params field of the given VBD. If the key is not in that
+ * Map, then do nothing.
+ */
+extern bool
+xen_vbd_remove_from_qos_algorithm_params(xen_session *session, xen_vbd vbd,
char *key);
/**
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vbd_metrics.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_vbd_metrics.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006-2007, 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_VBD_METRICS_H
+#define XEN_VBD_METRICS_H
+
+#include "xen_common.h"
+#include "xen_vbd_metrics_decl.h"
+
+
+/*
+ * The VBD_metrics class.
+ *
+ * The metrics associated with a virtual block device.
+ */
+
+
+/**
+ * Free the given xen_vbd_metrics. The given handle must have been
+ * allocated by this library.
+ */
+extern void
+xen_vbd_metrics_free(xen_vbd_metrics vbd_metrics);
+
+
+typedef struct xen_vbd_metrics_set
+{
+ size_t size;
+ xen_vbd_metrics *contents[];
+} xen_vbd_metrics_set;
+
+/**
+ * Allocate a xen_vbd_metrics_set of the given size.
+ */
+extern xen_vbd_metrics_set *
+xen_vbd_metrics_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vbd_metrics_set. The given set must have been
+ * allocated by this library.
+ */
+extern void
+xen_vbd_metrics_set_free(xen_vbd_metrics_set *set);
+
+
+typedef struct xen_vbd_metrics_record
+{
+ xen_vbd_metrics handle;
+ char *uuid;
+ double io_read_kbs;
+ double io_write_kbs;
+} xen_vbd_metrics_record;
+
+/**
+ * Allocate a xen_vbd_metrics_record.
+ */
+extern xen_vbd_metrics_record *
+xen_vbd_metrics_record_alloc(void);
+
+/**
+ * Free the given xen_vbd_metrics_record, and all referenced values.
+ * The given record must have been allocated by this library.
+ */
+extern void
+xen_vbd_metrics_record_free(xen_vbd_metrics_record *record);
+
+
+typedef struct xen_vbd_metrics_record_opt
+{
+ bool is_record;
+ union
+ {
+ xen_vbd_metrics handle;
+ xen_vbd_metrics_record *record;
+ } u;
+} xen_vbd_metrics_record_opt;
+
+/**
+ * Allocate a xen_vbd_metrics_record_opt.
+ */
+extern xen_vbd_metrics_record_opt *
+xen_vbd_metrics_record_opt_alloc(void);
+
+/**
+ * Free the given xen_vbd_metrics_record_opt, and all referenced
+ * values. The given record_opt must have been allocated by this library.
+ */
+extern void
+xen_vbd_metrics_record_opt_free(xen_vbd_metrics_record_opt *record_opt);
+
+
+typedef struct xen_vbd_metrics_record_set
+{
+ size_t size;
+ xen_vbd_metrics_record *contents[];
+} xen_vbd_metrics_record_set;
+
+/**
+ * Allocate a xen_vbd_metrics_record_set of the given size.
+ */
+extern xen_vbd_metrics_record_set *
+xen_vbd_metrics_record_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vbd_metrics_record_set, and all referenced
+ * values. The given set must have been allocated by this library.
+ */
+extern void
+xen_vbd_metrics_record_set_free(xen_vbd_metrics_record_set *set);
+
+
+
+typedef struct xen_vbd_metrics_record_opt_set
+{
+ size_t size;
+ xen_vbd_metrics_record_opt *contents[];
+} xen_vbd_metrics_record_opt_set;
+
+/**
+ * Allocate a xen_vbd_metrics_record_opt_set of the given size.
+ */
+extern xen_vbd_metrics_record_opt_set *
+xen_vbd_metrics_record_opt_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vbd_metrics_record_opt_set, and all referenced
+ * values. The given set must have been allocated by this library.
+ */
+extern void
+xen_vbd_metrics_record_opt_set_free(xen_vbd_metrics_record_opt_set *set);
+
+
+/**
+ * Get a record containing the current state of the given VBD_metrics.
+ */
+extern bool
+xen_vbd_metrics_get_record(xen_session *session, xen_vbd_metrics_record
**result, xen_vbd_metrics vbd_metrics);
+
+
+/**
+ * Get a reference to the VBD_metrics instance with the specified UUID.
+ */
+extern bool
+xen_vbd_metrics_get_by_uuid(xen_session *session, xen_vbd_metrics *result,
char *uuid);
+
+
+/**
+ * Get the uuid field of the given VBD_metrics.
+ */
+extern bool
+xen_vbd_metrics_get_uuid(xen_session *session, char **result, xen_vbd_metrics
vbd_metrics);
+
+
+/**
+ * Get the io/read_kbs field of the given VBD_metrics.
+ */
+extern bool
+xen_vbd_metrics_get_io_read_kbs(xen_session *session, double *result,
xen_vbd_metrics vbd_metrics);
+
+
+/**
+ * Get the io/write_kbs field of the given VBD_metrics.
+ */
+extern bool
+xen_vbd_metrics_get_io_write_kbs(xen_session *session, double *result,
xen_vbd_metrics vbd_metrics);
+
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vbd_metrics_decl.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_vbd_metrics_decl.h Thu Feb 22 10:15:29
2007 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006-2007, 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_VBD_METRICS_DECL_H
+#define XEN_VBD_METRICS_DECL_H
+
+typedef void *xen_vbd_metrics;
+
+struct xen_vbd_metrics_set;
+struct xen_vbd_metrics_record;
+struct xen_vbd_metrics_record_set;
+struct xen_vbd_metrics_record_opt;
+struct xen_vbd_metrics_record_opt_set;
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vbd_type.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_vbd_type.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2006-2007, 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_VBD_TYPE_H
+#define XEN_VBD_TYPE_H
+
+
+#include "xen_common.h"
+
+
+enum xen_vbd_type
+{
+ /**
+ * VBD will appear to guest as CD
+ */
+ XEN_VBD_TYPE_CD,
+
+ /**
+ * VBD will appear to guest as disk
+ */
+ XEN_VBD_TYPE_DISK
+};
+
+
+typedef struct xen_vbd_type_set
+{
+ size_t size;
+ enum xen_vbd_type contents[];
+} xen_vbd_type_set;
+
+/**
+ * Allocate a xen_vbd_type_set of the given size.
+ */
+extern xen_vbd_type_set *
+xen_vbd_type_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vbd_type_set. The given set must have been
+ * allocated by this library.
+ */
+extern void
+xen_vbd_type_set_free(xen_vbd_type_set *set);
+
+
+/**
+ * Return the name corresponding to the given code. This string must
+ * not be modified or freed.
+ */
+extern const char *
+xen_vbd_type_to_string(enum xen_vbd_type val);
+
+
+/**
+ * Return the correct code for the given string, or set the session
+ * object to failure and return an undefined value if the given string does
+ * not match a known code.
+ */
+extern enum xen_vbd_type
+xen_vbd_type_from_string(xen_session *session, const char *str);
+
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425
tools/libxen/include/xen_vbd_type_internal.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_vbd_type_internal.h Thu Feb 22 10:15:29
2007 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2007, 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
+ */
+
+
+/*
+ * Declarations of the abstract types used during demarshalling of enum
+ * xen_vbd_type. Internal to this library -- do not use from outside.
+ */
+
+
+#ifndef XEN_VBD_TYPE_INTERNAL_H
+#define XEN_VBD_TYPE_INTERNAL_H
+
+
+#include "xen_internal.h"
+
+
+extern const abstract_type xen_vbd_type_abstract_type_;
+extern const abstract_type xen_vbd_type_set_abstract_type_;
+
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vif.h
--- a/tools/libxen/include/xen_vif.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/include/xen_vif.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,9 @@
#include "xen_common.h"
#include "xen_network_decl.h"
+#include "xen_string_string_map.h"
#include "xen_vif_decl.h"
+#include "xen_vif_metrics_decl.h"
#include "xen_vm_decl.h"
@@ -69,8 +71,9 @@ typedef struct xen_vif_record
struct xen_vm_record_opt *vm;
char *mac;
int64_t mtu;
- double io_read_kbs;
- double io_write_kbs;
+ char *qos_algorithm_type;
+ xen_string_string_map *qos_algorithm_params;
+ struct xen_vif_metrics_record_opt *metrics;
} xen_vif_record;
/**
@@ -223,17 +226,24 @@ xen_vif_get_mtu(xen_session *session, in
/**
- * Get the io/read_kbs field of the given VIF.
- */
-extern bool
-xen_vif_get_io_read_kbs(xen_session *session, double *result, xen_vif vif);
-
-
-/**
- * Get the io/write_kbs field of the given VIF.
- */
-extern bool
-xen_vif_get_io_write_kbs(xen_session *session, double *result, xen_vif vif);
+ * Get the qos/algorithm_type field of the given VIF.
+ */
+extern bool
+xen_vif_get_qos_algorithm_type(xen_session *session, char **result, xen_vif
vif);
+
+
+/**
+ * Get the qos/algorithm_params field of the given VIF.
+ */
+extern bool
+xen_vif_get_qos_algorithm_params(xen_session *session, xen_string_string_map
**result, xen_vif vif);
+
+
+/**
+ * Get the metrics field of the given VIF.
+ */
+extern bool
+xen_vif_get_metrics(xen_session *session, xen_vif_metrics *result, xen_vif
vif);
/**
@@ -257,4 +267,35 @@ xen_vif_set_mtu(xen_session *session, xe
xen_vif_set_mtu(xen_session *session, xen_vif vif, int64_t mtu);
+/**
+ * Set the qos/algorithm_type field of the given VIF.
+ */
+extern bool
+xen_vif_set_qos_algorithm_type(xen_session *session, xen_vif vif, char
*algorithm_type);
+
+
+/**
+ * Set the qos/algorithm_params field of the given VIF.
+ */
+extern bool
+xen_vif_set_qos_algorithm_params(xen_session *session, xen_vif vif,
xen_string_string_map *algorithm_params);
+
+
+/**
+ * Add the given key-value pair to the qos/algorithm_params field of
+ * the given VIF.
+ */
+extern bool
+xen_vif_add_to_qos_algorithm_params(xen_session *session, xen_vif vif, char
*key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * qos/algorithm_params field of the given VIF. If the key is not in that
+ * Map, then do nothing.
+ */
+extern bool
+xen_vif_remove_from_qos_algorithm_params(xen_session *session, xen_vif vif,
char *key);
+
+
#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vif_metrics.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_vif_metrics.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006-2007, 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_VIF_METRICS_H
+#define XEN_VIF_METRICS_H
+
+#include "xen_common.h"
+#include "xen_vif_metrics_decl.h"
+
+
+/*
+ * The VIF_metrics class.
+ *
+ * The metrics associated with a virtual network device.
+ */
+
+
+/**
+ * Free the given xen_vif_metrics. The given handle must have been
+ * allocated by this library.
+ */
+extern void
+xen_vif_metrics_free(xen_vif_metrics vif_metrics);
+
+
+typedef struct xen_vif_metrics_set
+{
+ size_t size;
+ xen_vif_metrics *contents[];
+} xen_vif_metrics_set;
+
+/**
+ * Allocate a xen_vif_metrics_set of the given size.
+ */
+extern xen_vif_metrics_set *
+xen_vif_metrics_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vif_metrics_set. The given set must have been
+ * allocated by this library.
+ */
+extern void
+xen_vif_metrics_set_free(xen_vif_metrics_set *set);
+
+
+typedef struct xen_vif_metrics_record
+{
+ xen_vif_metrics handle;
+ char *uuid;
+ double io_read_kbs;
+ double io_write_kbs;
+} xen_vif_metrics_record;
+
+/**
+ * Allocate a xen_vif_metrics_record.
+ */
+extern xen_vif_metrics_record *
+xen_vif_metrics_record_alloc(void);
+
+/**
+ * Free the given xen_vif_metrics_record, and all referenced values.
+ * The given record must have been allocated by this library.
+ */
+extern void
+xen_vif_metrics_record_free(xen_vif_metrics_record *record);
+
+
+typedef struct xen_vif_metrics_record_opt
+{
+ bool is_record;
+ union
+ {
+ xen_vif_metrics handle;
+ xen_vif_metrics_record *record;
+ } u;
+} xen_vif_metrics_record_opt;
+
+/**
+ * Allocate a xen_vif_metrics_record_opt.
+ */
+extern xen_vif_metrics_record_opt *
+xen_vif_metrics_record_opt_alloc(void);
+
+/**
+ * Free the given xen_vif_metrics_record_opt, and all referenced
+ * values. The given record_opt must have been allocated by this library.
+ */
+extern void
+xen_vif_metrics_record_opt_free(xen_vif_metrics_record_opt *record_opt);
+
+
+typedef struct xen_vif_metrics_record_set
+{
+ size_t size;
+ xen_vif_metrics_record *contents[];
+} xen_vif_metrics_record_set;
+
+/**
+ * Allocate a xen_vif_metrics_record_set of the given size.
+ */
+extern xen_vif_metrics_record_set *
+xen_vif_metrics_record_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vif_metrics_record_set, and all referenced
+ * values. The given set must have been allocated by this library.
+ */
+extern void
+xen_vif_metrics_record_set_free(xen_vif_metrics_record_set *set);
+
+
+
+typedef struct xen_vif_metrics_record_opt_set
+{
+ size_t size;
+ xen_vif_metrics_record_opt *contents[];
+} xen_vif_metrics_record_opt_set;
+
+/**
+ * Allocate a xen_vif_metrics_record_opt_set of the given size.
+ */
+extern xen_vif_metrics_record_opt_set *
+xen_vif_metrics_record_opt_set_alloc(size_t size);
+
+/**
+ * Free the given xen_vif_metrics_record_opt_set, and all referenced
+ * values. The given set must have been allocated by this library.
+ */
+extern void
+xen_vif_metrics_record_opt_set_free(xen_vif_metrics_record_opt_set *set);
+
+
+/**
+ * Get a record containing the current state of the given VIF_metrics.
+ */
+extern bool
+xen_vif_metrics_get_record(xen_session *session, xen_vif_metrics_record
**result, xen_vif_metrics vif_metrics);
+
+
+/**
+ * Get a reference to the VIF_metrics instance with the specified UUID.
+ */
+extern bool
+xen_vif_metrics_get_by_uuid(xen_session *session, xen_vif_metrics *result,
char *uuid);
+
+
+/**
+ * Get the uuid field of the given VIF_metrics.
+ */
+extern bool
+xen_vif_metrics_get_uuid(xen_session *session, char **result, xen_vif_metrics
vif_metrics);
+
+
+/**
+ * Get the io/read_kbs field of the given VIF_metrics.
+ */
+extern bool
+xen_vif_metrics_get_io_read_kbs(xen_session *session, double *result,
xen_vif_metrics vif_metrics);
+
+
+/**
+ * Get the io/write_kbs field of the given VIF_metrics.
+ */
+extern bool
+xen_vif_metrics_get_io_write_kbs(xen_session *session, double *result,
xen_vif_metrics vif_metrics);
+
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vif_metrics_decl.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_vif_metrics_decl.h Thu Feb 22 10:15:29
2007 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006-2007, 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_VIF_METRICS_DECL_H
+#define XEN_VIF_METRICS_DECL_H
+
+typedef void *xen_vif_metrics;
+
+struct xen_vif_metrics_set;
+struct xen_vif_metrics_record;
+struct xen_vif_metrics_record_set;
+struct xen_vif_metrics_record_opt;
+struct xen_vif_metrics_record_opt_set;
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/include/xen_vm_metrics.h
--- a/tools/libxen/include/xen_vm_metrics.h Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/include/xen_vm_metrics.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,6 @@
#include "xen_common.h"
#include "xen_int_float_map.h"
-#include "xen_vm_decl.h"
#include "xen_vm_metrics_decl.h"
@@ -64,7 +63,6 @@ typedef struct xen_vm_metrics_record
{
xen_vm_metrics handle;
char *uuid;
- struct xen_vm_record_opt *vm;
int64_t memory_actual;
int64_t vcpus_number;
xen_int_float_map *vcpus_utilisation;
@@ -171,13 +169,6 @@ xen_vm_metrics_get_uuid(xen_session *ses
/**
- * Get the VM field of the given VM_metrics.
- */
-extern bool
-xen_vm_metrics_get_vm(xen_session *session, xen_vm *result, xen_vm_metrics
vm_metrics);
-
-
-/**
* Get the memory/actual field of the given VM_metrics.
*/
extern bool
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_common.c
--- a/tools/libxen/src/xen_common.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/src/xen_common.c Thu Feb 22 10:15:29 2007 -0700
@@ -989,10 +989,10 @@ static void parse_failure(xen_session *s
char **c = (char **)error_descriptions->contents;
int n = error_descriptions->size;
- char **strings = malloc(3 * sizeof(char *));
+ char **strings = malloc(n * sizeof(char *));
for (int i = 0; i < n; i++)
{
- strings[i] = xen_strdup_(c[i]);
+ strings[i] = c[i];
}
session->error_description_count = n;
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_console.c
--- a/tools/libxen/src/xen_console.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/src/xen_console.c Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
#include "xen_console.h"
#include "xen_console_protocol_internal.h"
#include "xen_internal.h"
+#include "xen_string_string_map.h"
#include "xen_vm.h"
@@ -44,12 +45,15 @@ static const struct_member xen_console_r
{ .key = "protocol",
.type = &xen_console_protocol_abstract_type_,
.offset = offsetof(xen_console_record, protocol) },
- { .key = "uri",
+ { .key = "location",
.type = &abstract_type_string,
- .offset = offsetof(xen_console_record, uri) },
+ .offset = offsetof(xen_console_record, location) },
{ .key = "VM",
.type = &abstract_type_ref,
- .offset = offsetof(xen_console_record, vm) }
+ .offset = offsetof(xen_console_record, vm) },
+ { .key = "other_config",
+ .type = &abstract_type_string_string_map,
+ .offset = offsetof(xen_console_record, other_config) }
};
const abstract_type xen_console_record_abstract_type_ =
@@ -71,8 +75,9 @@ xen_console_record_free(xen_console_reco
}
free(record->handle);
free(record->uuid);
- free(record->uri);
+ free(record->location);
xen_vm_record_opt_free(record->vm);
+ xen_string_string_map_free(record->other_config);
free(record);
}
@@ -164,18 +169,18 @@ xen_console_get_protocol(xen_session *se
bool
-xen_console_get_uri(xen_session *session, char **result, xen_console console)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = console }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("console.get_uri");
+xen_console_get_location(xen_session *session, char **result, xen_console
console)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = console }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("console.get_location");
return session->ok;
}
@@ -198,6 +203,73 @@ xen_console_get_vm(xen_session *session,
bool
+xen_console_get_other_config(xen_session *session, xen_string_string_map
**result, xen_console console)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = console }
+ };
+
+ abstract_type result_type = abstract_type_string_string_map;
+
+ *result = NULL;
+ XEN_CALL_("console.get_other_config");
+ return session->ok;
+}
+
+
+bool
+xen_console_set_other_config(xen_session *session, xen_console console,
xen_string_string_map *other_config)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = console },
+ { .type = &abstract_type_string_string_map,
+ .u.set_val = (arbitrary_set *)other_config }
+ };
+
+ xen_call_(session, "console.set_other_config", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_console_add_to_other_config(xen_session *session, xen_console console,
char *key, char *value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = console },
+ { .type = &abstract_type_string,
+ .u.string_val = key },
+ { .type = &abstract_type_string,
+ .u.string_val = value }
+ };
+
+ xen_call_(session, "console.add_to_other_config", param_values, 3, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_console_remove_from_other_config(xen_session *session, xen_console
console, char *key)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = console },
+ { .type = &abstract_type_string,
+ .u.string_val = key }
+ };
+
+ xen_call_(session, "console.remove_from_other_config", param_values, 2,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_console_get_uuid(xen_session *session, char **result, xen_console console)
{
*result = session->ok ? xen_strdup_((char *)console) : NULL;
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_host.c
--- a/tools/libxen/src/xen_host.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/src/xen_host.c Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -58,6 +58,9 @@ static const struct_member xen_host_reco
{ .key = "other_config",
.type = &abstract_type_string_string_map,
.offset = offsetof(xen_host_record, other_config) },
+ { .key = "supported_bootloaders",
+ .type = &abstract_type_string_set,
+ .offset = offsetof(xen_host_record, supported_bootloaders) },
{ .key = "resident_VMs",
.type = &abstract_type_ref_set,
.offset = offsetof(xen_host_record, resident_vms) },
@@ -107,6 +110,7 @@ xen_host_record_free(xen_host_record *re
free(record->name_description);
xen_string_string_map_free(record->software_version);
xen_string_string_map_free(record->other_config);
+ xen_string_set_free(record->supported_bootloaders);
xen_vm_record_opt_set_free(record->resident_vms);
xen_string_string_map_free(record->logging);
xen_pif_record_opt_set_free(record->pifs);
@@ -160,37 +164,6 @@ xen_host_get_by_uuid(xen_session *sessio
bool
-xen_host_create(xen_session *session, xen_host *result, xen_host_record
*record)
-{
- abstract_value param_values[] =
- {
- { .type = &xen_host_record_abstract_type_,
- .u.struct_val = record }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("host.create");
- return session->ok;
-}
-
-
-bool
-xen_host_destroy(xen_session *session, xen_host host)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = host }
- };
-
- xen_call_(session, "host.destroy", param_values, 1, NULL, NULL);
- return session->ok;
-}
-
-
-bool
xen_host_get_by_name_label(xen_session *session, struct xen_host_set **result,
char *label)
{
abstract_value param_values[] =
@@ -271,6 +244,23 @@ xen_host_get_other_config(xen_session *s
*result = NULL;
XEN_CALL_("host.get_other_config");
+ return session->ok;
+}
+
+
+bool
+xen_host_get_supported_bootloaders(xen_session *session, struct xen_string_set
**result, xen_host host)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = host }
+ };
+
+ abstract_type result_type = abstract_type_string_set;
+
+ *result = NULL;
+ XEN_CALL_("host.get_supported_bootloaders");
return session->ok;
}
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_string_set.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_string_set.c Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006-2007, 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 "xen_internal.h"
+#include "xen_string_set.h"
+
+
+xen_string_set *
+xen_string_set_alloc(size_t size)
+{
+ xen_string_set *result = calloc(1, sizeof(xen_string_set) +
+ size * sizeof(char *));
+ result->size = size;
+ return result;
+}
+
+void
+xen_string_set_free(xen_string_set *set)
+{
+ if (set == NULL)
+ {
+ return;
+ }
+ size_t n = set->size;
+ for (size_t i = 0; i < n; i++)
+ {
+ free(set->contents[i]);
+ }
+
+ free(set);
+}
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_string_set.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_string_set.h Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006-2007, 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_STRING_SET_H
+#define XEN_STRING_SET_H
+
+
+#include "xen_common.h"
+
+
+typedef struct xen_string_set
+{
+ size_t size;
+ char *contents[];
+} xen_string_set;
+
+
+/**
+ * Allocate a xen_string_set of the given size.
+ */
+extern xen_string_set *
+xen_string_set_alloc(size_t size);
+
+/**
+ * Free the given xen_string_set. The given set must have been allocated
+ * by this library.
+ */
+extern void
+xen_string_set_free(xen_string_set *set);
+
+
+#endif
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_vbd.c
--- a/tools/libxen/src/xen_vbd.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/src/xen_vbd.c Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,8 +22,11 @@
#include "xen_common.h"
#include "xen_internal.h"
+#include "xen_string_string_map.h"
#include "xen_vbd.h"
+#include "xen_vbd_metrics.h"
#include "xen_vbd_mode_internal.h"
+#include "xen_vbd_type_internal.h"
#include "xen_vdi.h"
#include "xen_vm.h"
@@ -60,12 +63,18 @@ static const struct_member xen_vbd_recor
{ .key = "mode",
.type = &xen_vbd_mode_abstract_type_,
.offset = offsetof(xen_vbd_record, mode) },
- { .key = "io_read_kbs",
- .type = &abstract_type_float,
- .offset = offsetof(xen_vbd_record, io_read_kbs) },
- { .key = "io_write_kbs",
- .type = &abstract_type_float,
- .offset = offsetof(xen_vbd_record, io_write_kbs) }
+ { .key = "type",
+ .type = &xen_vbd_type_abstract_type_,
+ .offset = offsetof(xen_vbd_record, type) },
+ { .key = "qos_algorithm_type",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vbd_record, qos_algorithm_type) },
+ { .key = "qos_algorithm_params",
+ .type = &abstract_type_string_string_map,
+ .offset = offsetof(xen_vbd_record, qos_algorithm_params) },
+ { .key = "metrics",
+ .type = &abstract_type_ref,
+ .offset = offsetof(xen_vbd_record, metrics) }
};
const abstract_type xen_vbd_record_abstract_type_ =
@@ -90,6 +99,9 @@ xen_vbd_record_free(xen_vbd_record *reco
xen_vm_record_opt_free(record->vm);
xen_vdi_record_opt_free(record->vdi);
free(record->device);
+ free(record->qos_algorithm_type);
+ xen_string_string_map_free(record->qos_algorithm_params);
+ xen_vbd_metrics_record_opt_free(record->metrics);
free(record);
}
@@ -242,41 +254,73 @@ xen_vbd_get_mode(xen_session *session, e
};
abstract_type result_type = xen_vbd_mode_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VBD.get_mode");
- *result = xen_vbd_mode_from_string(session, result_str);
- return session->ok;
-}
-
-
-bool
-xen_vbd_get_io_read_kbs(xen_session *session, double *result, xen_vbd vbd)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vbd }
- };
-
- abstract_type result_type = abstract_type_float;
-
- XEN_CALL_("VBD.get_io_read_kbs");
- return session->ok;
-}
-
-
-bool
-xen_vbd_get_io_write_kbs(xen_session *session, double *result, xen_vbd vbd)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vbd }
- };
-
- abstract_type result_type = abstract_type_float;
-
- XEN_CALL_("VBD.get_io_write_kbs");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_get_type(xen_session *session, enum xen_vbd_type *result, xen_vbd vbd)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd }
+ };
+
+ abstract_type result_type = xen_vbd_type_abstract_type_;
+ XEN_CALL_("VBD.get_type");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_get_qos_algorithm_type(xen_session *session, char **result, xen_vbd
vbd)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VBD.get_qos_algorithm_type");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_get_qos_algorithm_params(xen_session *session, xen_string_string_map
**result, xen_vbd vbd)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd }
+ };
+
+ abstract_type result_type = abstract_type_string_string_map;
+
+ *result = NULL;
+ XEN_CALL_("VBD.get_qos_algorithm_params");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_get_metrics(xen_session *session, xen_vbd_metrics *result, xen_vbd vbd)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VBD.get_metrics");
return session->ok;
}
@@ -330,6 +374,88 @@ xen_vbd_set_mode(xen_session *session, x
bool
+xen_vbd_set_type(xen_session *session, xen_vbd vbd, enum xen_vbd_type type)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd },
+ { .type = &xen_vbd_type_abstract_type_,
+ .u.string_val = xen_vbd_type_to_string(type) }
+ };
+
+ xen_call_(session, "VBD.set_type", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vbd_set_qos_algorithm_type(xen_session *session, xen_vbd vbd, char
*algorithm_type)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd },
+ { .type = &abstract_type_string,
+ .u.string_val = algorithm_type }
+ };
+
+ xen_call_(session, "VBD.set_qos_algorithm_type", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vbd_set_qos_algorithm_params(xen_session *session, xen_vbd vbd,
xen_string_string_map *algorithm_params)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd },
+ { .type = &abstract_type_string_string_map,
+ .u.set_val = (arbitrary_set *)algorithm_params }
+ };
+
+ xen_call_(session, "VBD.set_qos_algorithm_params", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vbd_add_to_qos_algorithm_params(xen_session *session, xen_vbd vbd, char
*key, char *value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd },
+ { .type = &abstract_type_string,
+ .u.string_val = key },
+ { .type = &abstract_type_string,
+ .u.string_val = value }
+ };
+
+ xen_call_(session, "VBD.add_to_qos_algorithm_params", param_values, 3,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vbd_remove_from_qos_algorithm_params(xen_session *session, xen_vbd vbd,
char *key)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd },
+ { .type = &abstract_type_string,
+ .u.string_val = key }
+ };
+
+ xen_call_(session, "VBD.remove_from_qos_algorithm_params", param_values,
2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_vbd_media_change(xen_session *session, xen_vbd vbd, xen_vdi vdi)
{
abstract_value param_values[] =
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_vbd_metrics.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_vbd_metrics.c Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006-2007, 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 <stddef.h>
+#include <stdlib.h>
+
+#include "xen_common.h"
+#include "xen_internal.h"
+#include "xen_vbd_metrics.h"
+
+
+XEN_FREE(xen_vbd_metrics)
+XEN_SET_ALLOC_FREE(xen_vbd_metrics)
+XEN_ALLOC(xen_vbd_metrics_record)
+XEN_SET_ALLOC_FREE(xen_vbd_metrics_record)
+XEN_ALLOC(xen_vbd_metrics_record_opt)
+XEN_RECORD_OPT_FREE(xen_vbd_metrics)
+XEN_SET_ALLOC_FREE(xen_vbd_metrics_record_opt)
+
+
+static const struct_member xen_vbd_metrics_record_struct_members[] =
+ {
+ { .key = "uuid",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vbd_metrics_record, uuid) },
+ { .key = "io_read_kbs",
+ .type = &abstract_type_float,
+ .offset = offsetof(xen_vbd_metrics_record, io_read_kbs) },
+ { .key = "io_write_kbs",
+ .type = &abstract_type_float,
+ .offset = offsetof(xen_vbd_metrics_record, io_write_kbs) }
+ };
+
+const abstract_type xen_vbd_metrics_record_abstract_type_ =
+ {
+ .typename = STRUCT,
+ .struct_size = sizeof(xen_vbd_metrics_record),
+ .member_count =
+ sizeof(xen_vbd_metrics_record_struct_members) /
sizeof(struct_member),
+ .members = xen_vbd_metrics_record_struct_members
+ };
+
+
+void
+xen_vbd_metrics_record_free(xen_vbd_metrics_record *record)
+{
+ if (record == NULL)
+ {
+ return;
+ }
+ free(record->handle);
+ free(record->uuid);
+ free(record);
+}
+
+
+bool
+xen_vbd_metrics_get_record(xen_session *session, xen_vbd_metrics_record
**result, xen_vbd_metrics vbd_metrics)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd_metrics }
+ };
+
+ abstract_type result_type = xen_vbd_metrics_record_abstract_type_;
+
+ *result = NULL;
+ XEN_CALL_("VBD_metrics.get_record");
+
+ if (session->ok)
+ {
+ (*result)->handle = xen_strdup_((*result)->uuid);
+ }
+
+ return session->ok;
+}
+
+
+bool
+xen_vbd_metrics_get_by_uuid(xen_session *session, xen_vbd_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_("VBD_metrics.get_by_uuid");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_metrics_get_io_read_kbs(xen_session *session, double *result,
xen_vbd_metrics vbd_metrics)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd_metrics }
+ };
+
+ abstract_type result_type = abstract_type_float;
+
+ XEN_CALL_("VBD_metrics.get_io_read_kbs");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_metrics_get_io_write_kbs(xen_session *session, double *result,
xen_vbd_metrics vbd_metrics)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vbd_metrics }
+ };
+
+ abstract_type result_type = abstract_type_float;
+
+ XEN_CALL_("VBD_metrics.get_io_write_kbs");
+ return session->ok;
+}
+
+
+bool
+xen_vbd_metrics_get_uuid(xen_session *session, char **result, xen_vbd_metrics
vbd_metrics)
+{
+ *result = session->ok ? xen_strdup_((char *)vbd_metrics) : NULL;
+ return session->ok;
+}
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_vbd_type.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_vbd_type.c Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2006-2007, 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 <string.h>
+
+#include "xen_internal.h"
+#include "xen_vbd_type.h"
+#include "xen_vbd_type_internal.h"
+
+
+/*
+ * Maintain this in the same order as the enum declaration!
+ */
+static const char *lookup_table[] =
+{
+ "CD",
+ "Disk"
+};
+
+
+extern xen_vbd_type_set *
+xen_vbd_type_set_alloc(size_t size)
+{
+ return calloc(1, sizeof(xen_vbd_type_set) +
+ size * sizeof(enum xen_vbd_type));
+}
+
+
+extern void
+xen_vbd_type_set_free(xen_vbd_type_set *set)
+{
+ free(set);
+}
+
+
+const char *
+xen_vbd_type_to_string(enum xen_vbd_type val)
+{
+ return lookup_table[val];
+}
+
+
+extern enum xen_vbd_type
+xen_vbd_type_from_string(xen_session *session, const char *str)
+{
+ return ENUM_LOOKUP(session, str, lookup_table);
+}
+
+
+const abstract_type xen_vbd_type_abstract_type_ =
+ {
+ .typename = ENUM,
+ .enum_marshaller =
+ (const char *(*)(int))&xen_vbd_type_to_string,
+ .enum_demarshaller =
+ (int (*)(xen_session *, const char *))&xen_vbd_type_from_string
+ };
+
+
+const abstract_type xen_vbd_type_set_abstract_type_ =
+ {
+ .typename = SET,
+ .child = &xen_vbd_type_abstract_type_
+ };
+
+
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_vif.c
--- a/tools/libxen/src/xen_vif.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/src/xen_vif.c Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,9 @@
#include "xen_common.h"
#include "xen_internal.h"
#include "xen_network.h"
+#include "xen_string_string_map.h"
#include "xen_vif.h"
+#include "xen_vif_metrics.h"
#include "xen_vm.h"
@@ -56,12 +58,15 @@ static const struct_member xen_vif_recor
{ .key = "MTU",
.type = &abstract_type_int,
.offset = offsetof(xen_vif_record, mtu) },
- { .key = "io_read_kbs",
- .type = &abstract_type_float,
- .offset = offsetof(xen_vif_record, io_read_kbs) },
- { .key = "io_write_kbs",
- .type = &abstract_type_float,
- .offset = offsetof(xen_vif_record, io_write_kbs) }
+ { .key = "qos_algorithm_type",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vif_record, qos_algorithm_type) },
+ { .key = "qos_algorithm_params",
+ .type = &abstract_type_string_string_map,
+ .offset = offsetof(xen_vif_record, qos_algorithm_params) },
+ { .key = "metrics",
+ .type = &abstract_type_ref,
+ .offset = offsetof(xen_vif_record, metrics) }
};
const abstract_type xen_vif_record_abstract_type_ =
@@ -87,6 +92,9 @@ xen_vif_record_free(xen_vif_record *reco
xen_network_record_opt_free(record->network);
xen_vm_record_opt_free(record->vm);
free(record->mac);
+ free(record->qos_algorithm_type);
+ xen_string_string_map_free(record->qos_algorithm_params);
+ xen_vif_metrics_record_opt_free(record->metrics);
free(record);
}
@@ -247,33 +255,52 @@ xen_vif_get_mtu(xen_session *session, in
bool
-xen_vif_get_io_read_kbs(xen_session *session, double *result, xen_vif vif)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vif }
- };
-
- abstract_type result_type = abstract_type_float;
-
- XEN_CALL_("VIF.get_io_read_kbs");
- return session->ok;
-}
-
-
-bool
-xen_vif_get_io_write_kbs(xen_session *session, double *result, xen_vif vif)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vif }
- };
-
- abstract_type result_type = abstract_type_float;
-
- XEN_CALL_("VIF.get_io_write_kbs");
+xen_vif_get_qos_algorithm_type(xen_session *session, char **result, xen_vif
vif)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VIF.get_qos_algorithm_type");
+ return session->ok;
+}
+
+
+bool
+xen_vif_get_qos_algorithm_params(xen_session *session, xen_string_string_map
**result, xen_vif vif)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif }
+ };
+
+ abstract_type result_type = abstract_type_string_string_map;
+
+ *result = NULL;
+ XEN_CALL_("VIF.get_qos_algorithm_params");
+ return session->ok;
+}
+
+
+bool
+xen_vif_get_metrics(xen_session *session, xen_vif_metrics *result, xen_vif vif)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VIF.get_metrics");
return session->ok;
}
@@ -327,6 +354,72 @@ xen_vif_set_mtu(xen_session *session, xe
bool
+xen_vif_set_qos_algorithm_type(xen_session *session, xen_vif vif, char
*algorithm_type)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif },
+ { .type = &abstract_type_string,
+ .u.string_val = algorithm_type }
+ };
+
+ xen_call_(session, "VIF.set_qos_algorithm_type", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vif_set_qos_algorithm_params(xen_session *session, xen_vif vif,
xen_string_string_map *algorithm_params)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif },
+ { .type = &abstract_type_string_string_map,
+ .u.set_val = (arbitrary_set *)algorithm_params }
+ };
+
+ xen_call_(session, "VIF.set_qos_algorithm_params", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vif_add_to_qos_algorithm_params(xen_session *session, xen_vif vif, char
*key, char *value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif },
+ { .type = &abstract_type_string,
+ .u.string_val = key },
+ { .type = &abstract_type_string,
+ .u.string_val = value }
+ };
+
+ xen_call_(session, "VIF.add_to_qos_algorithm_params", param_values, 3,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vif_remove_from_qos_algorithm_params(xen_session *session, xen_vif vif,
char *key)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif },
+ { .type = &abstract_type_string,
+ .u.string_val = key }
+ };
+
+ xen_call_(session, "VIF.remove_from_qos_algorithm_params", param_values,
2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_vif_get_uuid(xen_session *session, char **result, xen_vif vif)
{
*result = session->ok ? xen_strdup_((char *)vif) : NULL;
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_vif_metrics.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_vif_metrics.c Thu Feb 22 10:15:29 2007 -0700
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006-2007, 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 <stddef.h>
+#include <stdlib.h>
+
+#include "xen_common.h"
+#include "xen_internal.h"
+#include "xen_vif_metrics.h"
+
+
+XEN_FREE(xen_vif_metrics)
+XEN_SET_ALLOC_FREE(xen_vif_metrics)
+XEN_ALLOC(xen_vif_metrics_record)
+XEN_SET_ALLOC_FREE(xen_vif_metrics_record)
+XEN_ALLOC(xen_vif_metrics_record_opt)
+XEN_RECORD_OPT_FREE(xen_vif_metrics)
+XEN_SET_ALLOC_FREE(xen_vif_metrics_record_opt)
+
+
+static const struct_member xen_vif_metrics_record_struct_members[] =
+ {
+ { .key = "uuid",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vif_metrics_record, uuid) },
+ { .key = "io_read_kbs",
+ .type = &abstract_type_float,
+ .offset = offsetof(xen_vif_metrics_record, io_read_kbs) },
+ { .key = "io_write_kbs",
+ .type = &abstract_type_float,
+ .offset = offsetof(xen_vif_metrics_record, io_write_kbs) }
+ };
+
+const abstract_type xen_vif_metrics_record_abstract_type_ =
+ {
+ .typename = STRUCT,
+ .struct_size = sizeof(xen_vif_metrics_record),
+ .member_count =
+ sizeof(xen_vif_metrics_record_struct_members) /
sizeof(struct_member),
+ .members = xen_vif_metrics_record_struct_members
+ };
+
+
+void
+xen_vif_metrics_record_free(xen_vif_metrics_record *record)
+{
+ if (record == NULL)
+ {
+ return;
+ }
+ free(record->handle);
+ free(record->uuid);
+ free(record);
+}
+
+
+bool
+xen_vif_metrics_get_record(xen_session *session, xen_vif_metrics_record
**result, xen_vif_metrics vif_metrics)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif_metrics }
+ };
+
+ abstract_type result_type = xen_vif_metrics_record_abstract_type_;
+
+ *result = NULL;
+ XEN_CALL_("VIF_metrics.get_record");
+
+ if (session->ok)
+ {
+ (*result)->handle = xen_strdup_((*result)->uuid);
+ }
+
+ return session->ok;
+}
+
+
+bool
+xen_vif_metrics_get_by_uuid(xen_session *session, xen_vif_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_("VIF_metrics.get_by_uuid");
+ return session->ok;
+}
+
+
+bool
+xen_vif_metrics_get_io_read_kbs(xen_session *session, double *result,
xen_vif_metrics vif_metrics)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif_metrics }
+ };
+
+ abstract_type result_type = abstract_type_float;
+
+ XEN_CALL_("VIF_metrics.get_io_read_kbs");
+ return session->ok;
+}
+
+
+bool
+xen_vif_metrics_get_io_write_kbs(xen_session *session, double *result,
xen_vif_metrics vif_metrics)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vif_metrics }
+ };
+
+ abstract_type result_type = abstract_type_float;
+
+ XEN_CALL_("VIF_metrics.get_io_write_kbs");
+ return session->ok;
+}
+
+
+bool
+xen_vif_metrics_get_uuid(xen_session *session, char **result, xen_vif_metrics
vif_metrics)
+{
+ *result = session->ok ? xen_strdup_((char *)vif_metrics) : NULL;
+ return session->ok;
+}
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/src/xen_vm_metrics.c
--- a/tools/libxen/src/xen_vm_metrics.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/src/xen_vm_metrics.c Thu Feb 22 10:15:29 2007 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, XenSource Inc.
+ * Copyright (c) 2006-2007, XenSource Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#include "xen_common.h"
#include "xen_int_float_map.h"
#include "xen_internal.h"
-#include "xen_vm.h"
#include "xen_vm_metrics.h"
@@ -41,9 +40,6 @@ static const struct_member xen_vm_metric
{ .key = "uuid",
.type = &abstract_type_string,
.offset = offsetof(xen_vm_metrics_record, uuid) },
- { .key = "VM",
- .type = &abstract_type_ref,
- .offset = offsetof(xen_vm_metrics_record, vm) },
{ .key = "memory_actual",
.type = &abstract_type_int,
.offset = offsetof(xen_vm_metrics_record, memory_actual) },
@@ -74,7 +70,6 @@ xen_vm_metrics_record_free(xen_vm_metric
}
free(record->handle);
free(record->uuid);
- xen_vm_record_opt_free(record->vm);
xen_int_float_map_free(record->vcpus_utilisation);
free(record);
}
@@ -121,23 +116,6 @@ xen_vm_metrics_get_by_uuid(xen_session *
bool
-xen_vm_metrics_get_vm(xen_session *session, xen_vm *result, xen_vm_metrics
vm_metrics)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm_metrics }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("VM_metrics.get_VM");
- return session->ok;
-}
-
-
-bool
xen_vm_metrics_get_memory_actual(xen_session *session, int64_t *result,
xen_vm_metrics vm_metrics)
{
abstract_value param_values[] =
diff -r 9364bea18bc4 -r 202eb735b425 tools/libxen/test/test_bindings.c
--- a/tools/libxen/test/test_bindings.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/libxen/test/test_bindings.c Thu Feb 22 10:15:29 2007 -0700
@@ -31,6 +31,7 @@
#include "xen_vdi.h"
#include "xen_console.h"
#include "xen_vm.h"
+#include "xen_vm_metrics.h"
static void usage()
@@ -61,6 +62,7 @@ typedef struct
static xen_vm create_new_vm(xen_session *session, bool hvm);
static void print_vm_power_state(xen_session *session, xen_vm vm);
+static void print_vm_metrics(xen_session *session, xen_vm vm);
static size_t
@@ -220,6 +222,22 @@ int main(int argc, char **argv)
return 1;
}
+ xen_string_set *supported_bootloaders;
+ if (!xen_host_get_supported_bootloaders(session, &supported_bootloaders,
+ host))
+ {
+ print_error(session);
+ free(dmesg);
+ xen_string_string_map_free(versions);
+ xen_host_free(host);
+ xen_vm_record_free(vm_record);
+ xen_uuid_bytes_free(vm_uuid_bytes);
+ xen_uuid_free(vm_uuid);
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
printf("%s.\n", vm_uuid);
fprintf(stderr, "In bytes, the VM UUID is ");
@@ -239,29 +257,39 @@ int main(int argc, char **argv)
printf("Host dmesg follows:\n%s\n\n", dmesg);
+ printf("Host supports the following bootloaders:");
+ for (size_t i = 0; i < supported_bootloaders->size; i++)
+ {
+ printf(" %s", supported_bootloaders->contents[i]);
+ }
+ printf("\n");
+
printf("%s.\n", vm_record->uuid);
printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
-
- for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++)
- {
- printf("%"PRId64" -> %lf.\n",
- vm_record->vcpus_utilisation->contents[i].key,
- vm_record->vcpus_utilisation->contents[i].val);
- }
xen_uuid_bytes_free(vm_uuid_bytes);
xen_uuid_free(vm_uuid);
- xen_vm_free(vm);
xen_vm_record_free(vm_record);
xen_host_free(host);
xen_string_string_map_free(versions);
free(dmesg);
-
+ xen_string_set_free(supported_bootloaders);
+
+ print_vm_metrics(session, vm);
+ if (!session->ok)
+ {
+ /* Error has been logged, just clean up. */
+ xen_vm_free(vm);
+ CLEANUP;
+ return 1;
+ }
+
+ xen_vm_free(vm);
xen_vm new_vm = create_new_vm(session, true);
if (!session->ok)
@@ -323,7 +351,6 @@ static xen_vm create_new_vm(xen_session
.memory_static_min = 128,
.vcpus_policy = "credit",
.vcpus_params = vcpus_params,
- .vcpus_number = 2,
.actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
.actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
.actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
@@ -519,3 +546,35 @@ static void print_vm_power_state(xen_ses
xen_uuid_free(vm_uuid);
}
+
+
+/**
+ * Print the metrics for the given VM.
+ */
+static void print_vm_metrics(xen_session *session, xen_vm vm)
+{
+ xen_vm_metrics vm_metrics;
+ if (!xen_vm_get_metrics(session, &vm_metrics, vm))
+ {
+ print_error(session);
+ return;
+ }
+
+ xen_vm_metrics_record *vm_metrics_record;
+ if (!xen_vm_metrics_get_record(session, &vm_metrics_record, vm_metrics))
+ {
+ xen_vm_metrics_free(vm_metrics);
+ print_error(session);
+ return;
+ }
+
+ for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
+ {
+ printf("%"PRId64" -> %lf.\n",
+ vm_metrics_record->vcpus_utilisation->contents[i].key,
+ vm_metrics_record->vcpus_utilisation->contents[i].val);
+ }
+
+ xen_vm_metrics_record_free(vm_metrics_record);
+ xen_vm_metrics_free(vm_metrics);
+}
diff -r 9364bea18bc4 -r 202eb735b425 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/python/xen/xend/XendAPI.py Thu Feb 22 10:15:29 2007 -0700
@@ -141,11 +141,11 @@ def _is_valid_ref(ref, validator):
def _is_valid_ref(ref, validator):
return type(ref) == str and validator(ref)
-def _check_ref(validator, errcode, func, api, session, ref, *args, **kwargs):
+def _check_ref(validator, clas, func, api, session, ref, *args, **kwargs):
if _is_valid_ref(ref, validator):
return func(api, session, ref, *args, **kwargs)
else:
- return xen_api_error([errcode, ref])
+ return xen_api_error(['HANDLE_INVALID', clas, ref])
def valid_host(func):
@@ -156,7 +156,7 @@ def valid_host(func):
"""
return lambda *args, **kwargs: \
_check_ref(XendNode.instance().is_valid_host,
- 'HOST_HANDLE_INVALID', func, *args, **kwargs)
+ 'host', func, *args, **kwargs)
def valid_host_metrics(func):
"""Decorator to verify if host_metrics_ref is valid before calling
@@ -167,7 +167,7 @@ def valid_host_metrics(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: r == XendNode.instance().host_metrics_uuid,
- 'HOST_METRICS_HANDLE_INVALID', func, *args, **kwargs)
+ 'host_metrics', func, *args, **kwargs)
def valid_host_cpu(func):
"""Decorator to verify if host_cpu_ref is valid before calling method.
@@ -177,7 +177,7 @@ def valid_host_cpu(func):
"""
return lambda *args, **kwargs: \
_check_ref(XendNode.instance().is_valid_cpu,
- 'HOST_CPU_HANDLE_INVALID', func, *args, **kwargs)
+ 'host_cpu', func, *args, **kwargs)
def valid_vm(func):
"""Decorator to verify if vm_ref is valid before calling method.
@@ -187,7 +187,7 @@ def valid_vm(func):
"""
return lambda *args, **kwargs: \
_check_ref(XendDomain.instance().is_valid_vm,
- 'VM_HANDLE_INVALID', func, *args, **kwargs)
+ 'VM', func, *args, **kwargs)
def valid_network(func):
"""Decorator to verify if network_ref is valid before calling method.
@@ -197,7 +197,7 @@ def valid_network(func):
"""
return lambda *args, **kwargs: \
_check_ref(XendNode.instance().is_valid_network,
- 'NETWORK_HANDLE_INVALID', func, *args, **kwargs)
+ 'network', func, *args, **kwargs)
def valid_vbd(func):
"""Decorator to verify if vbd_ref is valid before calling method.
@@ -207,7 +207,17 @@ def valid_vbd(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
- 'VBD_HANDLE_INVALID', func, *args, **kwargs)
+ 'VBD', func, *args, **kwargs)
+
+def valid_vbd_metrics(func):
+ """Decorator to verify if ref is valid before calling method.
+
+ @param func: function with params: (self, session, ref, ...)
+ @rtype: callable object
+ """
+ return lambda *args, **kwargs: \
+ _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
+ 'VBD_metrics', func, *args, **kwargs)
def valid_vif(func):
"""Decorator to verify if vif_ref is valid before calling method.
@@ -217,7 +227,17 @@ def valid_vif(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
- 'VIF_HANDLE_INVALID', func, *args, **kwargs)
+ 'VIF', func, *args, **kwargs)
+
+def valid_vif_metrics(func):
+ """Decorator to verify if ref is valid before calling method.
+
+ @param func: function with params: (self, session, ref, ...)
+ @rtype: callable object
+ """
+ return lambda *args, **kwargs: \
+ _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
+ 'VIF_metrics', func, *args, **kwargs)
def valid_vdi(func):
"""Decorator to verify if vdi_ref is valid before calling method.
@@ -227,7 +247,7 @@ def valid_vdi(func):
"""
return lambda *args, **kwargs: \
_check_ref(XendNode.instance().is_valid_vdi,
- 'VDI_HANDLE_INVALID', func, *args, **kwargs)
+ 'VDI', func, *args, **kwargs)
def valid_vtpm(func):
"""Decorator to verify if vtpm_ref is valid before calling method.
@@ -237,7 +257,7 @@ def valid_vtpm(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
- 'VTPM_HANDLE_INVALID', func, *args, **kwargs)
+ 'VTPM', func, *args, **kwargs)
def valid_console(func):
@@ -249,7 +269,7 @@ def valid_console(func):
return lambda *args, **kwargs: \
_check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
r),
- 'CONSOLE_HANDLE_INVALID', func, *args, **kwargs)
+ 'console', func, *args, **kwargs)
def valid_sr(func):
"""Decorator to verify if sr_ref is valid before calling method.
@@ -259,7 +279,7 @@ def valid_sr(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: XendNode.instance().is_valid_sr,
- 'SR_HANDLE_INVALID', func, *args, **kwargs)
+ 'SR', func, *args, **kwargs)
def valid_pif(func):
"""Decorator to verify if pif_ref is valid before calling
@@ -270,7 +290,7 @@ def valid_pif(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: r in XendNode.instance().pifs,
- 'PIF_HANDLE_INVALID', func, *args, **kwargs)
+ 'PIF', func, *args, **kwargs)
def valid_pif_metrics(func):
"""Decorator to verify if pif_metrics_ref is valid before calling
@@ -281,7 +301,7 @@ def valid_pif_metrics(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: r in XendNode.instance().pif_metrics,
- 'PIF_METRICS_HANDLE_INVALID', func, *args, **kwargs)
+ 'PIF_metrics', func, *args, **kwargs)
def valid_task(func):
"""Decorator to verify if task_ref is valid before calling
@@ -292,7 +312,7 @@ def valid_task(func):
"""
return lambda *args, **kwargs: \
_check_ref(XendTaskManager.get_task,
- 'TASK_HANDLE_INVALID', func, *args, **kwargs)
+ 'task', func, *args, **kwargs)
def valid_debug(func):
"""Decorator to verify if task_ref is valid before calling
@@ -303,7 +323,7 @@ def valid_debug(func):
"""
return lambda *args, **kwargs: \
_check_ref(lambda r: r in XendAPI._debug,
- 'TASK_HANDLE_INVALID', func, *args, **kwargs)
+ 'debug', func, *args, **kwargs)
# -----------------------------
# Bridge to Legacy XM API calls
@@ -378,7 +398,9 @@ class XendAPI(object):
'network' : valid_network,
'VM' : valid_vm,
'VBD' : valid_vbd,
+ 'VBD_metrics' : valid_vbd_metrics,
'VIF' : valid_vif,
+ 'VIF_metrics' : valid_vif_metrics,
'VDI' : valid_vdi,
'VTPM' : valid_vtpm,
'console' : valid_console,
@@ -604,7 +626,8 @@ class XendAPI(object):
host_attr_ro = ['software_version',
'resident_VMs',
'host_CPUs',
- 'metrics']
+ 'metrics',
+ 'supported_bootloaders']
host_attr_rw = ['name_label',
'name_description',
@@ -656,10 +679,10 @@ class XendAPI(object):
return xen_api_success(XendNode.instance().get_host_cpu_refs())
def host_get_metrics(self, _, ref):
return xen_api_success(XendNode.instance().host_metrics_uuid)
+ def host_get_supported_bootloaders(self, session, host_ref):
+ return xen_api_success(['pygrub'])
# object methods
- def host_destroy(self, session, host_ref):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
def host_disable(self, session, host_ref):
XendDomain.instance().set_allow_new_domains(False)
return xen_api_success_void()
@@ -687,14 +710,13 @@ class XendAPI(object):
'software_version': node.xen_version(),
'resident_VMs': dom.get_domain_refs(),
'host_CPUs': node.get_host_cpu_refs(),
- 'metrics': node.host_metrics_uuid}
+ 'metrics': node.host_metrics_uuid,
+ 'supported_bootloaders': 'pygrub'}
return xen_api_success(record)
# class methods
def host_get_all(self, session):
return xen_api_success((XendNode.instance().uuid,))
- def host_create(self, session, struct):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
def host_get_by_name_label(self, session, name):
if XendNode.instance().name == name:
return xen_api_success((XendNode.instance().uuid,))
@@ -908,7 +930,7 @@ class XendAPI(object):
return xen_api_success(
node.PIF_create_VLAN(ref, network, vlan))
else:
- return xen_api_error(['NETWORK_HANDLE_INVALID', network])
+ return xen_api_error(['HANDLE_INVALID', 'network', network])
except NetworkAlreadyConnected, exn:
return xen_api_error(['NETWORK_ALREADY_CONNECTED',
network, exn.pif_uuid])
@@ -1352,7 +1374,7 @@ class XendAPI(object):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
if not xeninfo:
- return xen_api_error(['VM_HANDLE_INVALID', vm_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VM', vm_ref])
record = {
'uuid': xeninfo.get_uuid(),
@@ -1450,8 +1472,7 @@ class XendAPI(object):
# Xen API: Class VBD
# ----------------------------------------------------------------
- VBD_attr_ro = ['io_read_kbs',
- 'io_write_kbs']
+ VBD_attr_ro = ['metrics']
VBD_attr_rw = ['VM',
'VDI',
'device',
@@ -1469,10 +1490,10 @@ class XendAPI(object):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
if not vm:
- return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
if not cfg:
- return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
self.Base_attr_ro + self.Base_attr_rw
@@ -1481,7 +1502,9 @@ class XendAPI(object):
for k in cfg.keys():
if k in valid_vbd_keys:
return_cfg[k] = cfg[k]
-
+
+ return_cfg['metrics'] = vbd_ref
+
return xen_api_success(return_cfg)
def VBD_media_change(self, session, vbd_ref, vdi_ref):
@@ -1491,7 +1514,7 @@ class XendAPI(object):
def VBD_create(self, session, vbd_struct):
xendom = XendDomain.instance()
if not xendom.is_valid_vm(vbd_struct['VM']):
- return xen_api_error(['VM_HANDLE_INVALID', vbd_struct['VM']])
+ return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
vbd_ref = ''
@@ -1500,7 +1523,7 @@ class XendAPI(object):
vdi_ref = vbd_struct.get('VDI')
vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
if not vdi:
- return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
vdi_image = vdi.get_location()
vbd_ref = XendTask.log_progress(0, 100,
dom.create_vbd,
@@ -1516,17 +1539,21 @@ class XendAPI(object):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
if not vm:
- return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
return xen_api_success_void()
- # attributes (rw)
def _VBD_get(self, vbd_ref, prop):
return xen_api_success(
XendDomain.instance().get_dev_property_by_uuid(
'vbd', vbd_ref, prop))
+ # attributes (ro)
+ def VBD_get_metrics(self, _, vbd_ref):
+ return xen_api_success(vbd_ref)
+
+ # attributes (rw)
def VBD_get_VM(self, session, vbd_ref):
return self._VBD_get(vbd_ref, 'VM')
@@ -1544,12 +1571,6 @@ class XendAPI(object):
def VBD_get_type(self, session, vbd_ref):
return self._VBD_get(vbd_ref, 'type')
-
- def VBD_get_io_read_kbs(self, session, vbd_ref):
- return self._VBD_get(vbd_ref, 'io_read_kbs')
-
- def VBD_get_io_write_kbs(self, session, vbd_ref):
- return self._VBD_get(vbd_ref, 'io_write_kbs')
def VBD_set_bootable(self, session, vbd_ref, bootable):
bootable = bool(bootable)
@@ -1565,11 +1586,34 @@ class XendAPI(object):
vbds = reduce(lambda x, y: x + y, vbds)
return xen_api_success(vbds)
+
+ # Xen API: Class VBD_metrics
+ # ----------------------------------------------------------------
+
+ VBD_metrics_attr_ro = ['io_read_kbs',
+ 'io_write_kbs']
+ VBD_metrics_attr_rw = []
+ VBD_methods = []
+
+ def VBD_metrics_get_record(self, _, ref):
+ vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
+ if not vm:
+ return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
+ return xen_api_success(
+ { 'io_read_kbs' : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
+ 'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs')
})
+
+ def VBD_metrics_get_io_read_kbs(self, _, ref):
+ return self._VBD_get(ref, 'io_read_kbs')
+
+ def VBD_metrics_get_io_write_kbs(self, session, ref):
+ return self._VBD_get(ref, 'io_write_kbs')
+
+
# Xen API: Class VIF
# ----------------------------------------------------------------
- VIF_attr_ro = ['io_read_kbs',
- 'io_write_kbs']
+ VIF_attr_ro = ['metrics']
VIF_attr_rw = ['device',
'network',
'VM',
@@ -1586,10 +1630,10 @@ class XendAPI(object):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
if not vm:
- return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
cfg = vm.get_dev_xenapi_config('vif', vif_ref)
if not cfg:
- return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
self.Base_attr_ro + self.Base_attr_rw
@@ -1599,6 +1643,8 @@ class XendAPI(object):
if k in valid_vif_keys:
return_cfg[k] = cfg[k]
+ return_cfg['metrics'] = vif_ref
+
return xen_api_success(return_cfg)
# class methods
@@ -1613,48 +1659,40 @@ class XendAPI(object):
except XendError:
return xen_api_error(XEND_ERROR_TODO)
else:
- return xen_api_error(['VM_HANDLE_INVALID', vif_struct['VM']])
+ return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
def VIF_destroy(self, session, vif_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
if not vm:
- return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
vm.destroy_vif(vif_ref)
return xen_api_success_void()
+ def _VIF_get(self, ref, prop):
+ return xen_api_success(
+ XendDomain.instance().get_dev_property_by_uuid('vif', ref, prop))
+
# getters/setters
+ def VIF_get_metrics(self, _, vif_ref):
+ return xen_api_success(vif_ref)
+
def VIF_get_VM(self, session, vif_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
return xen_api_success(vm.get_uuid())
def VIF_get_MTU(self, session, vif_ref):
- xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
- 'MTU'))
+ return self._VIF_get(vif_ref, 'MTU')
+
def VIF_get_MAC(self, session, vif_ref):
- xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
- 'MAC'))
+ return self._VIF_get(vif_ref, 'MAC')
def VIF_get_device(self, session, vif_ref):
- xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
- 'device'))
+ return self._VIF_get(vif_ref, 'device')
- def VIF_get_io_read_kbs(self, session, vif_ref):
- xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
- 'io_read_kbs'))
-
- def VIF_get_io_write_kbs(self, session, vif_ref):
- xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
- 'io_write_kbs'))
-
def VIF_get_all(self, session):
xendom = XendDomain.instance()
vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
@@ -1662,6 +1700,29 @@ class XendAPI(object):
return xen_api_success(vifs)
+ # Xen API: Class VIF_metrics
+ # ----------------------------------------------------------------
+
+ VIF_metrics_attr_ro = ['io_read_kbs',
+ 'io_write_kbs']
+ VIF_metrics_attr_rw = []
+ VIF_methods = []
+
+ def VIF_metrics_get_record(self, _, ref):
+ vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
+ if not vm:
+ return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
+ return xen_api_success(
+ { 'io_read_kbs' : vm.get_dev_property('vif', ref, 'io_read_kbs'),
+ 'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs')
})
+
+ def VIF_metrics_get_io_read_kbs(self, _, ref):
+ return self._VIF_get(ref, 'io_read_kbs')
+
+ def VIF_metrics_get_io_write_kbs(self, session, ref):
+ return self._VIF_get(ref, 'io_write_kbs')
+
+
# Xen API: Class VDI
# ----------------------------------------------------------------
VDI_attr_ro = ['VBDs',
@@ -1766,7 +1827,7 @@ class XendAPI(object):
sr_ref = vdi_struct.get('SR')
xennode = XendNode.instance()
if not xennode.is_valid_sr(sr_ref):
- return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
+ return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
return xen_api_success(vdi_uuid)
@@ -1797,10 +1858,10 @@ class XendAPI(object):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
if not vm:
- return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
if not cfg:
- return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
self.Base_attr_ro + self.Base_attr_rw
return_cfg = {}
@@ -1815,10 +1876,10 @@ class XendAPI(object):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
if not vm:
- return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
if not cfg:
- return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
+ return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
if not cfg.has_key('backend'):
return xen_api_error(['VTPM backend not set'])
return xen_api_success(cfg['backend'])
@@ -1841,7 +1902,7 @@ class XendAPI(object):
tpmif.destroy_vtpmstate(dom.getName())
return xen_api_success(True)
else:
- return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
+ return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
# class methods
def VTPM_create(self, session, vtpm_struct):
@@ -1855,7 +1916,7 @@ class XendAPI(object):
except XendError:
return xen_api_error(XEND_ERROR_TODO)
else:
- return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
+ return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
def VTPM_get_all(self, session):
xendom = XendDomain.instance()
@@ -1897,10 +1958,10 @@ class XendAPI(object):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('console', console_ref)
if not vm:
- return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
+ return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
cfg = vm.get_dev_xenapi_config('console', console_ref)
if not cfg:
- return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
+ return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
self.Base_attr_ro + self.Base_attr_rw
@@ -1915,7 +1976,8 @@ class XendAPI(object):
def console_create(self, session, console_struct):
xendom = XendDomain.instance()
if not xendom.is_valid_vm(console_struct['VM']):
- return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']])
+ return xen_api_error(['HANDLE_INVALID', 'VM',
+ console_struct['VM']])
dom = xendom.get_vm_by_uuid(console_struct['VM'])
try:
@@ -1972,7 +2034,7 @@ class XendAPI(object):
sr = XendNode.instance().get_sr(sr_ref)
if sr:
return xen_api_success(sr.get_record())
- return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
+ return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
# Attribute acceess
diff -r 9364bea18bc4 -r 202eb735b425 tools/python/xen/xm/messages/en/xen-xm.po
--- a/tools/python/xen/xm/messages/en/xen-xm.po Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/python/xen/xm/messages/en/xen-xm.po Thu Feb 22 10:15:29 2007 -0700
@@ -19,7 +19,7 @@ msgid ""
msgid ""
msgstr ""
"Project-Id-Version: Xen-xm 3.0\n"
-"PO-Revision-Date: 2007-01-31 12:34+0000\n"
+"PO-Revision-Date: 2007-02-20 15:22+0000\n"
"Last-Translator: Ewan Mellor <ewan@xxxxxxxxxxxxx>\n"
"Language-Team: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>\n"
"MIME-Version: 1.0\n"
@@ -44,44 +44,8 @@ msgid "VALUE_NOT_SUPPORTED"
msgid "VALUE_NOT_SUPPORTED"
msgstr "Value \"%(2)s\" for %(1)s is not supported by this server. The server
said \"%(3)s\"."
-msgid "HOST_CPU_HANDLE_INVALID"
-msgstr "The host_cpu handle %(1)s is invalid."
-
-msgid "HOST_HANDLE_INVALID"
-msgstr "The host handle %(1)s is invalid."
-
-msgid "HOST_METRICS_HANDLE_INVALID"
-msgstr "The host_metrics 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."
-
-msgid "TASK_HANDLE_INVALID"
-msgstr "The task handle %(1)s is invalid."
-
-msgid "VBD_HANDLE_INVALID"
-msgstr "The VBD handle %(1)s is invalid."
-
-msgid "VDI_HANDLE_INVALID"
-msgstr "The VDI handle %(1)s is invalid."
-
-msgid "VIF_HANDLE_INVALID"
-msgstr "The VIF handle %(1)s is invalid."
-
-msgid "VM_HANDLE_INVALID"
-msgstr "The VM handle %(1)s is invalid."
-
-msgid "VM_METRICS_HANDLE_INVALID"
-msgstr "The VM_metrics handle %(1)s is invalid."
-
-msgid "VTPM_HANDLE_INVALID"
-msgstr "The VTPM handle %(1)s is invalid."
+msgid "HANDLE_INVALID"
+msgstr "The %(1)s handle %(2)s is invalid."
msgid "OPERATION_NOT_ALLOWED"
msgstr "You attempted an operation that was not allowed."
diff -r 9364bea18bc4 -r 202eb735b425 tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c Thu Feb 22 09:42:13 2007 -0700
+++ b/tools/tests/test_x86_emulator.c Thu Feb 22 10:15:29 2007 -0700
@@ -43,7 +43,7 @@ static int read(
case 4: *val = *(u32 *)addr; break;
case 8: *val = *(unsigned long *)addr; break;
}
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
static int write(
@@ -61,7 +61,7 @@ static int write(
case 4: *(u32 *)addr = (u32)val; break;
case 8: *(unsigned long *)addr = val; break;
}
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
static int cmpxchg(
@@ -80,7 +80,7 @@ static int cmpxchg(
case 4: *(u32 *)addr = (u32)new; break;
case 8: *(unsigned long *)addr = new; break;
}
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
static int cmpxchg8b(
@@ -95,7 +95,7 @@ static int cmpxchg8b(
unsigned long addr = offset;
((unsigned long *)addr)[0] = new_lo;
((unsigned long *)addr)[1] = new_hi;
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
static struct x86_emulate_ops emulops = {
@@ -138,7 +138,7 @@ int main(int argc, char **argv)
regs.eax = (unsigned long)res;
*res = 0x7FFFFFFF;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x92345677) ||
(regs.eflags != 0xa94) ||
(regs.eip != (unsigned long)&instr[2]) )
@@ -152,7 +152,7 @@ int main(int argc, char **argv)
regs.ecx = 0x12345678;
regs.eax = 0x7FFFFFFF;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(regs.ecx != 0x12345678) ||
(regs.eax != 0x92345677) ||
(regs.eflags != 0xa94) ||
@@ -171,7 +171,7 @@ int main(int argc, char **argv)
#endif
regs.eax = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x92345677) ||
(regs.ecx != 0x8000000FUL) ||
(regs.eip != (unsigned long)&instr[2]) )
@@ -185,7 +185,7 @@ int main(int argc, char **argv)
regs.ecx = ~0UL;
regs.eax = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x92345677) ||
(regs.ecx != 0x92345677UL) ||
(regs.eip != (unsigned long)&instr[2]) )
@@ -200,7 +200,7 @@ int main(int argc, char **argv)
regs.ecx = 0xAA;
regs.ebx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x923456AA) ||
(regs.eflags != 0x244) ||
(regs.eax != 0x92345677UL) ||
@@ -216,7 +216,7 @@ int main(int argc, char **argv)
regs.ecx = 0xFF;
regs.ebx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x923456AA) ||
((regs.eflags&0x240) != 0x200) ||
(regs.eax != 0xAABBCCAA) ||
@@ -232,7 +232,7 @@ int main(int argc, char **argv)
regs.ecx = 0x12345678;
regs.eax = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x12345678) ||
(regs.eflags != 0x200) ||
(regs.ecx != 0x923456AA) ||
@@ -249,7 +249,7 @@ int main(int argc, char **argv)
regs.ecx = 0xDDEEFF00L;
regs.ebx = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0xDDEEFF00) ||
(regs.eflags != 0x244) ||
(regs.eax != 0x923456AAUL) ||
@@ -266,7 +266,7 @@ int main(int argc, char **argv)
regs.esi = (unsigned long)res + 0;
regs.edi = (unsigned long)res + 2;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x44554455) ||
(regs.eflags != 0x200) ||
(regs.ecx != 22) ||
@@ -283,7 +283,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x2233445D) ||
((regs.eflags&0x201) != 0x201) ||
(regs.eip != (unsigned long)&instr[4]) )
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
regs.eax = -32;
regs.edi = (unsigned long)(res+1);
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x2233445E) ||
((regs.eflags&0x201) != 0x201) ||
(regs.eip != (unsigned long)&instr[3]) )
@@ -318,7 +318,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(res[0] != 0x9999AAAA) ||
(res[1] != 0xCCCCFFFF) ||
((regs.eflags&0x240) != 0x240) ||
@@ -332,7 +332,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)res;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(res[0] != 0x9999AAAA) ||
(res[1] != 0xCCCCFFFF) ||
(regs.eax != 0x9999AAAA) ||
@@ -350,7 +350,7 @@ int main(int argc, char **argv)
regs.eax = (unsigned long)res;
*res = 0x82;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x82) ||
(regs.ecx != 0xFFFFFF82) ||
((regs.eflags&0x240) != 0x200) ||
@@ -366,7 +366,7 @@ int main(int argc, char **argv)
regs.eax = (unsigned long)res;
*res = 0x1234aa82;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x1234aa82) ||
(regs.ecx != 0xaa82) ||
((regs.eflags&0x240) != 0x200) ||
@@ -382,7 +382,7 @@ int main(int argc, char **argv)
regs.eax = 0x12345678;
*res = 0x11111111;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(*res != 0x11116789) ||
(regs.eax != 0x12341111) ||
((regs.eflags&0x240) != 0x200) ||
@@ -396,7 +396,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x00000000;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(regs.eax != 0x0000ffff) ||
((regs.eflags&0x240) != 0x200) ||
(regs.eip != (unsigned long)&instr[2]) )
@@ -410,7 +410,7 @@ int main(int argc, char **argv)
regs.eax = 0x12345678;
regs.ebp = 0xaaaaaaaa;
rc = x86_emulate(&ctxt, &emulops);
- if ( (rc != 0) ||
+ if ( (rc != X86EMUL_OKAY) ||
(regs.eax != 0xaaaaaab2) ||
((regs.eflags&0x240) != 0x200) ||
(regs.eip != (unsigned long)&instr[3]) )
@@ -454,7 +454,7 @@ int main(int argc, char **argv)
bcdres_emul |= (regs.eflags & EFLG_SF) ? 0x400 : 0;
bcdres_emul |= (regs.eflags & EFLG_CF) ? 0x200 : 0;
bcdres_emul |= (regs.eflags & EFLG_AF) ? 0x100 : 0;
- if ( (rc != 0) || (regs.eax > 255) ||
+ if ( (rc != X86EMUL_OKAY) || (regs.eax > 255) ||
(regs.eip != (unsigned long)&instr[1]) )
goto fail;
@@ -501,7 +501,7 @@ int main(int argc, char **argv)
if ( (i++ & 8191) == 0 )
printf(".");
rc = x86_emulate(&ctxt, &emulops);
- if ( rc != 0 )
+ if ( rc != X86EMUL_OKAY )
{
printf("failed at %%eip == %08x\n", (unsigned int)regs.eip);
return 1;
diff -r 9364bea18bc4 -r 202eb735b425 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/acm/acm_chinesewall_hooks.c Thu Feb 22 10:15:29 2007 -0700
@@ -194,19 +194,18 @@ chwall_init_state(struct acm_chwall_poli
int violation = 0, i, j;
struct chwall_ssid *chwall_ssid;
ssidref_t chwall_ssidref;
- struct domain **pd;
-
- write_lock(&domlist_lock);
+ struct domain *d;
+
+ spin_lock(&domlist_update_lock);
/* go through all domains and adjust policy as if this domain was started
now */
- pd = &domain_list;
- for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list)
+ for_each_domain ( d )
{
chwall_ssid =
GET_SSIDP(ACM_CHINESE_WALL_POLICY,
- (struct acm_ssid_domain *) (*pd)->ssid);
+ (struct acm_ssid_domain *)d->ssid);
chwall_ssidref = chwall_ssid->chwall_ssidref;
traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
- __func__, (*pd)->domain_id, chwall_ssidref);
+ __func__, d->domain_id, chwall_ssidref);
/* a) adjust types ref-count for running domains */
for (i = 0; i < chwall_buf->chwall_max_types; i++)
running_types[i] +=
@@ -247,7 +246,7 @@ chwall_init_state(struct acm_chwall_poli
}
}
out:
- write_unlock(&domlist_lock);
+ spin_unlock(&domlist_update_lock);
return violation;
/* returning "violation != 0" means that the currently running set of
domains would
* not be possible if the new policy had been enforced before starting
them; for chinese
diff -r 9364bea18bc4 -r 202eb735b425 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c Thu Feb 22 09:42:13
2007 -0700
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c Thu Feb 22 10:15:29
2007 -0700
@@ -175,36 +175,37 @@ ste_init_state(struct acm_ste_policy_buf
int violation = 1;
struct ste_ssid *ste_ssid, *ste_rssid;
ssidref_t ste_ssidref, ste_rssidref;
- struct domain **pd, *rdom;
+ struct domain *d, *rdom;
domid_t rdomid;
struct grant_entry sha_copy;
int port, i;
- read_lock(&domlist_lock); /* go by domain? or directly by global?
event/grant list */
+ rcu_read_lock(&domlist_read_lock);
+ /* go by domain? or directly by global? event/grant list */
/* go through all domains and adjust policy as if this domain was started
now */
- pd = &domain_list;
- for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
+ for_each_domain ( d )
+ {
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
- (struct acm_ssid_domain *)(*pd)->ssid);
+ (struct acm_ssid_domain *)d->ssid);
ste_ssidref = ste_ssid->ste_ssidref;
traceprintk("%s: validating policy for eventch domain %x
(ste-Ref=%x).\n",
- __func__, (*pd)->domain_id, ste_ssidref);
+ __func__, d->domain_id, ste_ssidref);
/* a) check for event channel conflicts */
for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
- spin_lock(&(*pd)->evtchn_lock);
- if ((*pd)->evtchn[port] == NULL) {
- spin_unlock(&(*pd)->evtchn_lock);
+ spin_lock(&d->evtchn_lock);
+ if (d->evtchn[port] == NULL) {
+ spin_unlock(&d->evtchn_lock);
continue;
}
- if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) {
- rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom;
+ if (d->evtchn[port]->state == ECS_INTERDOMAIN) {
+ rdom = d->evtchn[port]->u.interdomain.remote_dom;
rdomid = rdom->domain_id;
/* rdom now has remote domain */
ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)(rdom->ssid));
ste_rssidref = ste_rssid->ste_ssidref;
- } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) {
- rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid;
+ } else if (d->evtchn[port]->state == ECS_UNBOUND) {
+ rdomid = d->evtchn[port]->u.unbound.remote_domid;
if ((rdom = get_domain_by_id(rdomid)) == NULL) {
printk("%s: Error finding domain to id %x!\n", __func__,
rdomid);
goto out;
@@ -215,36 +216,36 @@ ste_init_state(struct acm_ste_policy_buf
ste_rssidref = ste_rssid->ste_ssidref;
put_domain(rdom);
} else {
- spin_unlock(&(*pd)->evtchn_lock);
+ spin_unlock(&d->evtchn_lock);
continue; /* port unused */
}
- spin_unlock(&(*pd)->evtchn_lock);
+ spin_unlock(&d->evtchn_lock);
/* rdom now has remote domain */
ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)(rdom->ssid));
ste_rssidref = ste_rssid->ste_ssidref;
traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x
(rssidref %x) used (port %x).\n",
- __func__, (*pd)->domain_id, ste_ssidref,
rdom->domain_id, ste_rssidref, port);
+ __func__, d->domain_id, ste_ssidref, rdom->domain_id,
ste_rssidref, port);
/* check whether on subj->ssid, obj->ssid share a common type*/
if (!have_common_type(ste_ssidref, ste_rssidref)) {
printkd("%s: Policy violation in event channel domain %x ->
domain %x.\n",
- __func__, (*pd)->domain_id, rdomid);
+ __func__, d->domain_id, rdomid);
goto out;
}
}
/* b) check for grant table conflicts on shared pages */
- spin_lock(&(*pd)->grant_table->lock);
- for ( i = 0; i < nr_grant_entries((*pd)->grant_table); i++ ) {
+ spin_lock(&d->grant_table->lock);
+ for ( i = 0; i < nr_grant_entries(d->grant_table); i++ ) {
#define SPP (PAGE_SIZE / sizeof(struct grant_entry))
- sha_copy = (*pd)->grant_table->shared[i/SPP][i%SPP];
+ sha_copy = d->grant_table->shared[i/SPP][i%SPP];
if ( sha_copy.flags ) {
printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu)
frame:(%lx)\n",
- __func__, (*pd)->domain_id, i, sha_copy.flags,
sha_copy.domid,
+ __func__, d->domain_id, i, sha_copy.flags,
sha_copy.domid,
(unsigned long)sha_copy.frame);
rdomid = sha_copy.domid;
if ((rdom = get_domain_by_id(rdomid)) == NULL) {
- spin_unlock(&(*pd)->grant_table->lock);
+ spin_unlock(&d->grant_table->lock);
printkd("%s: domain not found ERROR!\n", __func__);
goto out;
};
@@ -254,18 +255,18 @@ ste_init_state(struct acm_ste_policy_buf
ste_rssidref = ste_rssid->ste_ssidref;
put_domain(rdom);
if (!have_common_type(ste_ssidref, ste_rssidref)) {
- spin_unlock(&(*pd)->grant_table->lock);
+ spin_unlock(&d->grant_table->lock);
printkd("%s: Policy violation in grant table sharing
domain %x -> domain %x.\n",
- __func__, (*pd)->domain_id, rdomid);
+ __func__, d->domain_id, rdomid);
goto out;
}
}
}
- spin_unlock(&(*pd)->grant_table->lock);
+ spin_unlock(&d->grant_table->lock);
}
violation = 0;
out:
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
return violation;
/* returning "violation != 0" means that existing sharing between domains
would not
* have been allowed if the new policy had been enforced before the
sharing; for ste,
@@ -281,7 +282,7 @@ ste_set_policy(u8 *buf, u32 buf_size)
struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer
*)buf;
void *ssidrefsbuf;
struct ste_ssid *ste_ssid;
- struct domain **pd;
+ struct domain *d;
int i;
if (buf_size < sizeof(struct acm_ste_policy_buffer))
@@ -326,15 +327,14 @@ ste_set_policy(u8 *buf, u32 buf_size)
ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
/* clear all ste caches */
- read_lock(&domlist_lock);
- pd = &domain_list;
- for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
+ rcu_read_lock(&domlist_read_lock);
+ for_each_domain ( d ) {
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
- (struct acm_ssid_domain *)(*pd)->ssid);
+ (struct acm_ssid_domain *)(d)->ssid);
for (i=0; i<ACM_TE_CACHE_SIZE; i++)
ste_ssid->ste_cache[i].valid = ACM_STE_free;
}
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
return ACM_OK;
error_free:
@@ -436,14 +436,14 @@ clean_id_from_cache(domid_t id)
{
struct ste_ssid *ste_ssid;
int i;
- struct domain **pd;
+ struct domain *d;
struct acm_ssid_domain *ssid;
printkd("deleting cache for dom %x.\n", id);
- read_lock(&domlist_lock); /* look through caches of all domains */
- pd = &domain_list;
- for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
- ssid = (struct acm_ssid_domain *)((*pd)->ssid);
+ rcu_read_lock(&domlist_read_lock);
+ /* look through caches of all domains */
+ for_each_domain ( d ) {
+ ssid = (struct acm_ssid_domain *)(d->ssid);
if (ssid == NULL)
continue; /* hanging domain structure, no ssid any more ... */
@@ -459,7 +459,7 @@ clean_id_from_cache(domid_t id)
ste_ssid->ste_cache[i].valid = ACM_STE_free;
}
out:
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
}
/***************************
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/ia64/linux-xen/mca.c Thu Feb 22 10:15:29 2007 -0700
@@ -790,6 +790,7 @@ init_handler_platform (pal_min_state_are
/* this route is for dump routine */
unw_init_running(try_crashdump, pt);
} else {
+ rcu_read_lock(&domlist_read_lock);
for_each_domain(d) {
for_each_vcpu(d, v) {
printk("Backtrace of current vcpu "
@@ -798,6 +799,7 @@ init_handler_platform (pal_min_state_are
show_stack(v, NULL);
}
}
+ rcu_read_unlock(&domlist_read_lock);
}
}
unw_init_running(freeze_cpu_osinit, NULL);
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/ia64/linux-xen/perfmon.c
--- a/xen/arch/ia64/linux-xen/perfmon.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/ia64/linux-xen/perfmon.c Thu Feb 22 10:15:29 2007 -0700
@@ -7225,7 +7225,6 @@ DEFINE_PER_CPU(pfm_context_t*, xenpfm_co
/*
* note: some functions mask interrupt with this lock held
* so that this lock can't be locked from interrupt handler.
- * lock order domlist_lock => xenpfm_context_lock
*/
DEFINE_SPINLOCK(xenpfm_context_lock);
@@ -7507,10 +7506,8 @@ xenpfm_context_unload(void)
arg.error[cpu] = 0;
BUG_ON(in_irq());
- read_lock(&domlist_lock);
spin_lock(&xenpfm_context_lock);
error = xenpfm_start_stop_locked(0);
- read_unlock(&domlist_lock);
if (error) {
spin_unlock(&xenpfm_context_lock);
return error;
@@ -7688,10 +7685,11 @@ xenpfm_start_stop_locked(int is_start)
while (atomic_read(&arg.started) != cpus)
cpu_relax();
- for_each_domain(d) {
+ rcu_read_lock(&domlist_read_lock);
+ for_each_domain(d)
for_each_vcpu(d, v)
xenpfm_start_stop_vcpu(v, is_start);
- }
+ rcu_read_unlock(&domlist_read_lock);
arg.error[smp_processor_id()] = __xenpfm_start_stop(is_start);
atomic_inc(&arg.finished);
@@ -7716,11 +7714,9 @@ xenpfm_start_stop(int is_start)
int error;
BUG_ON(in_irq());
- read_lock(&domlist_lock);
spin_lock(&xenpfm_context_lock);
- error =xenpfm_start_stop_locked(is_start);
+ error = xenpfm_start_stop_locked(is_start);
spin_unlock(&xenpfm_context_lock);
- read_unlock(&domlist_lock);
return error;
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/powerpc/audit.c
--- a/xen/arch/powerpc/audit.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/powerpc/audit.c Thu Feb 22 10:15:29 2007 -0700
@@ -34,8 +34,10 @@ void audit_domains(void)
void audit_domains(void)
{
struct domain *d;
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
audit_domain(d);
+ rcu_read_unlock(&domlist_read_lock);
}
void audit_domains_key(unsigned char key)
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/domctl.c Thu Feb 22 10:15:29 2007 -0700
@@ -441,6 +441,10 @@ void arch_get_info_guest(struct vcpu *v,
XLAT_vcpu_guest_context(c.cmp, &v->arch.guest_context);
#endif
+ c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
+ if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
+ c(flags |= VGCF_i387_valid);
+
if ( is_hvm_vcpu(v) )
{
if ( !IS_COMPAT(v->domain) )
@@ -464,23 +468,21 @@ void arch_get_info_guest(struct vcpu *v,
/* IOPL privileges are virtualised: merge back into returned eflags. */
BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0);
c(user_regs.eflags |= v->arch.iopl << 12);
- }
-
- c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
- if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
- c(flags |= VGCF_i387_valid);
- if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
- c(flags |= VGCF_in_kernel);
-
- if ( !IS_COMPAT(v->domain) )
- c.nat->ctrlreg[3] =
xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
-#ifdef CONFIG_COMPAT
- else
- {
- l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table));
- c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
- }
-#endif
+
+ if ( !IS_COMPAT(v->domain) )
+ c.nat->ctrlreg[3] = xen_pfn_to_cr3(
+ pagetable_get_pfn(v->arch.guest_table));
+#ifdef CONFIG_COMPAT
+ else
+ {
+ l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table));
+ c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
+ }
+#endif
+
+ if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
+ c(flags |= VGCF_in_kernel);
+ }
c(vm_assist = v->domain->vm_assist);
#undef c
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/extable.c
--- a/xen/arch/x86/extable.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/extable.c Thu Feb 22 10:15:29 2007 -0700
@@ -1,13 +1,8 @@
#include <xen/config.h>
+#include <xen/perfc.h>
#include <xen/spinlock.h>
#include <asm/uaccess.h>
-
-#ifdef PERF_COUNTERS
-#include <xen/sched.h>
-#include <xen/perfc.h>
-#include <asm/current.h>
-#endif
extern struct exception_table_entry __start___ex_table[];
extern struct exception_table_entry __stop___ex_table[];
@@ -74,10 +69,10 @@ search_pre_exception_table(struct cpu_us
unsigned long addr = (unsigned long)regs->eip;
unsigned long fixup = search_one_table(
__start___pre_ex_table, __stop___pre_ex_table-1, addr);
- dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
-#ifdef PERF_COUNTERS
if ( fixup )
+ {
+ dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
perfc_incrc(exception_fixed);
-#endif
+ }
return fixup;
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/hvm/io.c Thu Feb 22 10:15:29 2007 -0700
@@ -533,6 +533,7 @@ static void hvm_mmio_assist(struct cpu_u
break;
case INSTR_LODS:
+ set_reg_value(size, 0, 0, regs, p->data);
sign = p->df ? -1 : 1;
regs->esi += sign * p->count * p->size;
if (mmio_opp->flags & REPZ)
@@ -553,6 +554,7 @@ static void hvm_mmio_assist(struct cpu_u
diff = (unsigned long) p->data & value;
set_reg_value(size, index, 0, regs, diff);
}
+ break;
case INSTR_ADD:
if (src & REGISTER) {
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/hvm/platform.c Thu Feb 22 10:15:29 2007 -0700
@@ -1136,6 +1136,7 @@ void handle_mmio(unsigned long gpa)
* Since the source is always in (contiguous) mmio space we don't
* need to break it up into pages.
*/
+ mmio_op->operand[0] = mk_operand(op_size, 0, 0, REGISTER);
send_mmio_req(IOREQ_TYPE_COPY, gpa,
GET_REPEAT_COUNT(), op_size, 0, IOREQ_READ, df, 0);
break;
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/hvm/svm/vmcb.c Thu Feb 22 10:15:29 2007 -0700
@@ -330,6 +330,9 @@ static void vmcb_dump(unsigned char ch)
struct vcpu *v;
printk("*********** VMCB Areas **************\n");
+
+ rcu_read_lock(&domlist_read_lock);
+
for_each_domain ( d )
{
if ( !is_hvm_domain(d) )
@@ -341,6 +344,8 @@ static void vmcb_dump(unsigned char ch)
svm_dump_vmcb("key_handler", v->arch.hvm_svm.vmcb);
}
}
+
+ rcu_read_unlock(&domlist_read_lock);
printk("**************************************\n");
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Thu Feb 22 10:15:29 2007 -0700
@@ -567,6 +567,9 @@ static void vmcs_dump(unsigned char ch)
struct vcpu *v;
printk("*********** VMCS Areas **************\n");
+
+ rcu_read_lock(&domlist_read_lock);
+
for_each_domain ( d )
{
if ( !is_hvm_domain(d) )
@@ -581,6 +584,8 @@ static void vmcs_dump(unsigned char ch)
}
}
+ rcu_read_unlock(&domlist_read_lock);
+
printk("**************************************\n");
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Feb 22 10:15:29 2007 -0700
@@ -696,7 +696,7 @@ static void vmx_store_cpu_guest_regs(
{
crs[0] = v->arch.hvm_vmx.cpu_shadow_cr0;
crs[2] = v->arch.hvm_vmx.cpu_cr2;
- crs[3] = __vmread(GUEST_CR3);
+ crs[3] = v->arch.hvm_vmx.cpu_cr3;
crs[4] = v->arch.hvm_vmx.cpu_shadow_cr4;
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/mm.c Thu Feb 22 10:15:29 2007 -0700
@@ -3151,10 +3151,10 @@ static int ptwr_emulated_read(
if ( (rc = copy_from_user((void *)val, (void *)addr, bytes)) != 0 )
{
propagate_page_fault(addr + bytes - rc, 0); /* read fault */
- return X86EMUL_PROPAGATE_FAULT;
- }
-
- return X86EMUL_CONTINUE;
+ return X86EMUL_EXCEPTION;
+ }
+
+ return X86EMUL_OKAY;
}
static int ptwr_emulated_update(
@@ -3190,7 +3190,7 @@ static int ptwr_emulated_update(
if ( (rc = copy_from_user(&full, (void *)addr, sizeof(paddr_t))) != 0 )
{
propagate_page_fault(addr+sizeof(paddr_t)-rc, 0); /* read fault */
- return X86EMUL_PROPAGATE_FAULT;
+ return X86EMUL_EXCEPTION;
}
/* Mask out bits provided by caller. */
full &= ~((((paddr_t)1 << (bytes*8)) - 1) << (offset*8));
@@ -3273,7 +3273,7 @@ static int ptwr_emulated_update(
/* Finally, drop the old PTE. */
put_page_from_l1e(gl1e_to_ml1e(d, ol1e), d);
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
static int ptwr_emulated_write(
@@ -3333,6 +3333,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
struct page_info *page;
l1_pgentry_t pte;
struct ptwr_emulate_ctxt ptwr_ctxt;
+ int rc;
LOCK_BIGLOCK(d);
@@ -3357,7 +3358,9 @@ int ptwr_do_page_fault(struct vcpu *v, u
IS_COMPAT(d) ? 32 : BITS_PER_LONG;
ptwr_ctxt.cr2 = addr;
ptwr_ctxt.pte = pte;
- if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
+
+ rc = x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops);
+ if ( rc == X86EMUL_UNHANDLEABLE )
goto bail;
UNLOCK_BIGLOCK(d);
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/mm/shadow/common.c Thu Feb 22 10:15:29 2007 -0700
@@ -191,7 +191,7 @@ static int hvm_translate_linear_addr(
gpf:
/* Inject #GP(0). */
hvm_inject_exception(TRAP_gp_fault, 0, 0);
- return X86EMUL_PROPAGATE_FAULT;
+ return X86EMUL_EXCEPTION;
}
static int
@@ -216,7 +216,7 @@ hvm_read(enum x86_segment seg,
// In this case, that is only a user vs supervisor access check.
//
if ( (rc = hvm_copy_from_guest_virt(val, addr, bytes)) == 0 )
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
/* If we got here, there was nothing mapped here, or a bad GFN
* was mapped here. This should never happen: we're here because
@@ -226,7 +226,7 @@ hvm_read(enum x86_segment seg,
if ( access_type == hvm_access_insn_fetch )
errcode |= PFEC_insn_fetch;
hvm_inject_exception(TRAP_page_fault, errcode, addr + bytes - rc);
- return X86EMUL_PROPAGATE_FAULT;
+ return X86EMUL_EXCEPTION;
}
static int
@@ -259,7 +259,7 @@ hvm_emulate_insn_fetch(enum x86_segment
/* Hit the cache. Simple memcpy. */
*val = 0;
memcpy(val, &sh_ctxt->insn_buf[insn_off], bytes);
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
static int
@@ -352,10 +352,10 @@ pv_emulate_read(enum x86_segment seg,
if ( (rc = copy_from_user((void *)val, (void *)offset, bytes)) != 0 )
{
propagate_page_fault(offset + bytes - rc, 0); /* read fault */
- return X86EMUL_PROPAGATE_FAULT;
- }
-
- return X86EMUL_CONTINUE;
+ return X86EMUL_EXCEPTION;
+ }
+
+ return X86EMUL_OKAY;
}
static int
@@ -890,13 +890,17 @@ static void shadow_blow_all_tables(unsig
{
struct domain *d;
printk("'%c' pressed -> blowing all shadow tables\n", c);
+ rcu_read_lock(&domlist_read_lock);
for_each_domain(d)
+ {
if ( shadow_mode_enabled(d) && d->vcpu[0] != NULL )
{
shadow_lock(d);
shadow_blow_tables(d);
shadow_unlock(d);
}
+ }
+ rcu_read_unlock(&domlist_read_lock);
}
/* Register this function in the Xen console keypress table */
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c Thu Feb 22 10:15:29 2007 -0700
@@ -2911,8 +2911,16 @@ static int sh_page_fault(struct vcpu *v,
* page is no longer a page table. This behaviour differs from native, but
* it seems very unlikely that any OS grants user access to page tables.
*/
- if ( (regs->error_code & PFEC_user_mode) ||
- x86_emulate(&emul_ctxt.ctxt, emul_ops) )
+ r = X86EMUL_UNHANDLEABLE;
+ if ( !(regs->error_code & PFEC_user_mode) )
+ r = x86_emulate(&emul_ctxt.ctxt, emul_ops);
+
+ /*
+ * NB. We do not unshadow on X86EMUL_EXCEPTION. It's not clear that it
+ * would be a good unshadow hint. If we *do* decide to unshadow-on-fault
+ * then it must be 'failable': we cannot require the unshadow to succeed.
+ */
+ if ( r == X86EMUL_UNHANDLEABLE )
{
SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n",
mfn_x(gmfn));
@@ -3956,7 +3964,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
- return X86EMUL_PROPAGATE_FAULT;
+ return X86EMUL_EXCEPTION;
skip = safe_not_to_verify_write(mfn, addr, src, bytes);
memcpy(addr, src, bytes);
@@ -3968,7 +3976,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
sh_unmap_domain_page(addr);
shadow_audit_tables(v);
- return X86EMUL_CONTINUE;
+ return X86EMUL_OKAY;
}
int
@@ -3979,7 +3987,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
mfn_t mfn;
void *addr;
unsigned long prev;
- int rv = X86EMUL_CONTINUE, skip;
+ int rv = X86EMUL_OKAY, skip;
ASSERT(shadow_locked_by_me(v->domain));
ASSERT(bytes <= sizeof(unsigned long));
@@ -3988,7 +3996,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
return X86EMUL_UNHANDLEABLE;
if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
- return X86EMUL_PROPAGATE_FAULT;
+ return X86EMUL_EXCEPTION;
skip = safe_not_to_verify_write(mfn, &new, &old, bytes);
@@ -4032,7 +4040,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
mfn_t mfn;
void *addr;
u64 old, new, prev;
- int rv = X86EMUL_CONTINUE, skip;
+ int rv = X86EMUL_OKAY, skip;
ASSERT(shadow_locked_by_me(v->domain));
@@ -4040,7 +4048,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
return X86EMUL_UNHANDLEABLE;
if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
- return X86EMUL_PROPAGATE_FAULT;
+ return X86EMUL_EXCEPTION;
old = (((u64) old_hi) << 32) | (u64) old_lo;
new = (((u64) new_hi) << 32) | (u64) new_lo;
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/time.c Thu Feb 22 10:15:29 2007 -0700
@@ -720,10 +720,10 @@ void do_settime(unsigned long secs, unsi
wc_nsec = _wc_nsec = (u32)y;
spin_unlock(&wc_lock);
- read_lock(&domlist_lock);
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
update_domain_wallclock_time(d);
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
}
static void local_time_calibration(void *unused)
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/traps.c Thu Feb 22 10:15:29 2007 -0700
@@ -618,39 +618,77 @@ static int emulate_forced_invalid_op(str
asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
{
- int rc;
+ struct bug_frame bug;
+ struct bug_frame_str bug_str;
+ char *filename, *predicate, *eip = (char *)regs->eip;
+ int rc, id, lineno;
DEBUGGER_trap_entry(TRAP_invalid_op, regs);
- if ( unlikely(!guest_mode(regs)) )
- {
- struct bug_frame bug;
- if ( (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
- (memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) == 0) &&
- (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) &&
- (bug.ret == 0xc2) )
- {
- char *filename = (char *)bug.filename;
- unsigned int line = bug.line & 0x7fff;
- int is_bug = !(bug.line & 0x8000);
- printk("Xen %s at %.50s:%d\n",
- is_bug ? "BUG" : "State Dump", filename, line);
- if ( !is_bug )
- {
- show_execution_state(regs);
- regs->eip += sizeof(bug);
- return EXCRET_fault_fixed;
- }
- }
+ if ( likely(guest_mode(regs)) )
+ {
+ if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
+ return rc;
+ return do_guest_trap(TRAP_invalid_op, regs, 0);
+ }
+
+ if ( !is_kernel(eip) ||
+ __copy_from_user(&bug, eip, sizeof(bug)) ||
+ memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) ||
+ (bug.ret != 0xc2) )
+ goto die;
+
+ id = bug.id & 3;
+ if ( id == BUGFRAME_rsvd )
+ goto die;
+
+ if ( id == BUGFRAME_dump )
+ {
+ show_execution_state(regs);
+ regs->eip += sizeof(bug);
+ return EXCRET_fault_fixed;
+ }
+
+ /* BUG() or ASSERT(): decode the filename pointer and line number. */
+ ASSERT((id == BUGFRAME_bug) || (id == BUGFRAME_assert));
+ eip += sizeof(bug);
+ if ( !is_kernel(eip) ||
+ __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
+ memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
+ goto die;
+
+ filename = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
+ lineno = bug.id >> 2;
+
+ if ( id == BUGFRAME_bug )
+ {
+ printk("Xen BUG at %.50s:%d\n", filename, lineno);
DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
show_execution_state(regs);
- panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
- }
-
- if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
- return rc;
-
- return do_guest_trap(TRAP_invalid_op, regs, 0);
+ panic("Xen BUG at %.50s:%d\n", filename, lineno);
+ }
+
+ /* ASSERT(): decode the predicate string pointer. */
+ ASSERT(id == BUGFRAME_assert);
+ eip += sizeof(bug_str);
+ if ( !is_kernel(eip) ||
+ __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
+ memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
+ goto die;
+
+ predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
+ printk("Assertion '%s' failed at %.50s:%d\n",
+ predicate, filename, lineno);
+ DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+ show_execution_state(regs);
+ panic("Assertion '%s' failed at %.50s:%d\n",
+ predicate, filename, lineno);
+
+ die:
+ DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+ show_execution_state(regs);
+ panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
+ return 0;
}
asmlinkage int do_int3(struct cpu_user_regs *regs)
@@ -877,6 +915,9 @@ static int fixup_page_fault(unsigned lon
return 0;
}
+ ASSERT(!in_irq());
+ ASSERT(regs->eflags & X86_EFLAGS_IF);
+
if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) &&
guest_kernel_mode(v, regs) &&
/* Do not check if access-protection fault since the page may
@@ -903,8 +944,6 @@ asmlinkage int do_page_fault(struct cpu_
{
unsigned long addr, fixup;
int rc;
-
- ASSERT(!in_irq());
addr = read_cr2();
@@ -1916,6 +1955,8 @@ void unset_nmi_callback(void)
asmlinkage int math_state_restore(struct cpu_user_regs *regs)
{
+ BUG_ON(!guest_mode(regs));
+
setup_fpu(current);
if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS )
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/x86_32/entry.S Thu Feb 22 10:15:29 2007 -0700
@@ -424,7 +424,7 @@ handle_exception:
testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%esp)
jz exception_with_ints_disabled
sti # re-enable interrupts
- xorl %eax,%eax
+1: xorl %eax,%eax
movw UREGS_entry_vector(%esp),%ax
movl %esp,%edx
pushl %edx # push the cpu_user_regs pointer
@@ -451,7 +451,7 @@ exception_with_ints_disabled:
call search_pre_exception_table
addl $4,%esp
testl %eax,%eax # no fixup code for faulting EIP?
- jz FATAL_exception_with_ints_disabled
+ jz 1b
movl %eax,UREGS_eip(%esp)
movl %esp,%esi
subl $4,%esp
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/x86_64/entry.S Thu Feb 22 10:15:29 2007 -0700
@@ -362,7 +362,7 @@ ENTRY(handle_exception)
testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp)
jz exception_with_ints_disabled
sti
- movq %rsp,%rdi
+1: movq %rsp,%rdi
movl UREGS_entry_vector(%rsp),%eax
leaq exception_table(%rip),%rdx
GET_CURRENT(%rbx)
@@ -388,7 +388,7 @@ exception_with_ints_disabled:
movq %rsp,%rdi
call search_pre_exception_table
testq %rax,%rax # no fixup code for faulting EIP?
- jz FATAL_exception_with_ints_disabled
+ jz 1b
movq %rax,UREGS_rip(%rsp)
subq $8,UREGS_rsp(%rsp) # add ec/ev to previous stack frame
testb $15,UREGS_rsp(%rsp) # return %rsp is now aligned?
diff -r 9364bea18bc4 -r 202eb735b425 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/arch/x86/x86_emulate.c Thu Feb 22 10:15:29 2007 -0700
@@ -464,10 +464,10 @@ do{ __asm__ __volatile__ (
#define mode_64bit() (def_ad_bytes == 8)
-#define fail_if(p) \
-do { \
- rc = (p) ? X86EMUL_UNHANDLEABLE : 0; \
- if ( rc ) goto done; \
+#define fail_if(p) \
+do { \
+ rc = (p) ? X86EMUL_UNHANDLEABLE : X86EMUL_OKAY; \
+ if ( rc ) goto done; \
} while (0)
/* In future we will be able to generate arbitrary exceptions. */
@@ -726,7 +726,7 @@ x86_emulate(
uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes;
unsigned int lock_prefix = 0, rep_prefix = 0;
- int rc = 0;
+ int rc = X86EMUL_OKAY;
struct operand src, dst;
/* Data operand effective address (usually computed from ModRM). */
@@ -742,7 +742,7 @@ x86_emulate(
{
op_bytes = def_op_bytes = 4;
#ifndef __x86_64__
- return -1;
+ return X86EMUL_UNHANDLEABLE;
#endif
}
@@ -1593,7 +1593,7 @@ x86_emulate(
*ctxt->regs = _regs;
done:
- return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+ return rc;
special_insn:
dst.type = OP_NONE;
@@ -2383,5 +2383,5 @@ x86_emulate(
}
printk("\n");
#endif
- return -1;
+ return X86EMUL_UNHANDLEABLE;
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/common/domain.c
--- a/xen/common/domain.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/common/domain.c Thu Feb 22 10:15:29 2007 -0700
@@ -24,13 +24,18 @@
#include <xen/shutdown.h>
#include <xen/percpu.h>
#include <xen/multicall.h>
+#include <xen/rcupdate.h>
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
-/* Both these structures are protected by the domlist_lock. */
-DEFINE_RWLOCK(domlist_lock);
-struct domain *domain_hash[DOMAIN_HASH_SIZE];
+/* Protect updates/reads (resp.) of domain_list and domain_hash. */
+DEFINE_SPINLOCK(domlist_update_lock);
+DEFINE_RCU_READ_LOCK(domlist_read_lock);
+
+#define DOMAIN_HASH_SIZE 256
+#define DOMAIN_HASH(_id) ((int)(_id)&(DOMAIN_HASH_SIZE-1))
+static struct domain *domain_hash[DOMAIN_HASH_SIZE];
struct domain *domain_list;
struct domain *dom0;
@@ -174,16 +179,20 @@ struct domain *domain_create(domid_t dom
if ( !is_idle_domain(d) )
{
- write_lock(&domlist_lock);
+ spin_lock(&domlist_update_lock);
pd = &domain_list; /* NB. domain_list maintained in order of domid. */
for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list )
if ( (*pd)->domain_id > d->domain_id )
break;
d->next_in_list = *pd;
- *pd = d;
d->next_in_hashbucket = domain_hash[DOMAIN_HASH(domid)];
- domain_hash[DOMAIN_HASH(domid)] = d;
- write_unlock(&domlist_lock);
+ /* Two rcu assignments are not atomic
+ * Readers may see inconsistent domlist and hash table
+ * That is OK as long as each RCU reader-side critical section uses
+ * only one or them */
+ rcu_assign_pointer(*pd, d);
+ rcu_assign_pointer(domain_hash[DOMAIN_HASH(domid)], d);
+ spin_unlock(&domlist_update_lock);
}
return d;
@@ -207,9 +216,11 @@ struct domain *get_domain_by_id(domid_t
{
struct domain *d;
- read_lock(&domlist_lock);
- d = domain_hash[DOMAIN_HASH(dom)];
- while ( d != NULL )
+ rcu_read_lock(&domlist_read_lock);
+
+ for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
+ d != NULL;
+ d = rcu_dereference(d->next_in_hashbucket) )
{
if ( d->domain_id == dom )
{
@@ -217,11 +228,31 @@ struct domain *get_domain_by_id(domid_t
d = NULL;
break;
}
- d = d->next_in_hashbucket;
- }
- read_unlock(&domlist_lock);
+ }
+
+ rcu_read_unlock(&domlist_read_lock);
return d;
+}
+
+
+struct domain *find_domain_rcu_lock(domid_t dom)
+{
+ struct domain *d;
+
+ rcu_read_lock(&domlist_read_lock);
+
+ for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
+ d != NULL;
+ d = rcu_dereference(d->next_in_hashbucket) )
+ {
+ if ( d->domain_id == dom )
+ return d;
+ }
+
+ rcu_read_unlock(&domlist_read_lock);
+
+ return NULL;
}
@@ -314,6 +345,23 @@ void domain_pause_for_debugger(void)
send_guest_global_virq(dom0, VIRQ_DEBUGGER);
}
+/* Complete domain destroy after RCU readers are not holding
+ old references */
+static void complete_domain_destroy(struct rcu_head *head)
+{
+ struct domain *d = container_of(head, struct domain, rcu);
+
+ rangeset_domain_destroy(d);
+
+ evtchn_destroy(d);
+ grant_table_destroy(d);
+
+ arch_domain_destroy(d);
+
+ free_domain(d);
+
+ send_guest_global_virq(dom0, VIRQ_DOM_EXC);
+}
/* Release resources belonging to task @p. */
void domain_destroy(struct domain *d)
@@ -331,27 +379,19 @@ void domain_destroy(struct domain *d)
return;
/* Delete from task list and task hashtable. */
- write_lock(&domlist_lock);
+ spin_lock(&domlist_update_lock);
pd = &domain_list;
while ( *pd != d )
pd = &(*pd)->next_in_list;
- *pd = d->next_in_list;
+ rcu_assign_pointer(*pd, d->next_in_list);
pd = &domain_hash[DOMAIN_HASH(d->domain_id)];
while ( *pd != d )
pd = &(*pd)->next_in_hashbucket;
- *pd = d->next_in_hashbucket;
- write_unlock(&domlist_lock);
-
- rangeset_domain_destroy(d);
-
- evtchn_destroy(d);
- grant_table_destroy(d);
-
- arch_domain_destroy(d);
-
- free_domain(d);
-
- send_guest_global_virq(dom0, VIRQ_DOM_EXC);
+ rcu_assign_pointer(*pd, d->next_in_hashbucket);
+ spin_unlock(&domlist_update_lock);
+
+ /* schedule RCU asynchronous completion of domain destroy */
+ call_rcu(&d->rcu, complete_domain_destroy);
}
static void vcpu_pause_setup(struct vcpu *v)
diff -r 9364bea18bc4 -r 202eb735b425 xen/common/domctl.c
--- a/xen/common/domctl.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/common/domctl.c Thu Feb 22 10:15:29 2007 -0700
@@ -17,6 +17,7 @@
#include <xen/trace.h>
#include <xen/console.h>
#include <xen/iocap.h>
+#include <xen/rcupdate.h>
#include <xen/guest_access.h>
#include <xen/bitmap.h>
#include <asm/current.h>
@@ -140,12 +141,12 @@ static unsigned int default_vcpu0_locati
cpumask_t cpu_exclude_map;
/* Do an initial CPU placement. Pick the least-populated CPU. */
- read_lock(&domlist_lock);
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
for_each_vcpu ( d, v )
if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
cnt[v->processor]++;
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
/*
* If we're on a HT system, we only auto-allocate to a non-primary HT. We
@@ -480,7 +481,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( dom == DOMID_SELF )
dom = current->domain->domain_id;
- read_lock(&domlist_lock);
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
{
@@ -490,12 +491,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d == NULL) || !get_domain(d) )
{
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
ret = -ESRCH;
break;
}
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
getdomaininfo(d, &op->u.getdomaininfo);
diff -r 9364bea18bc4 -r 202eb735b425 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/common/keyhandler.c Thu Feb 22 10:15:29 2007 -0700
@@ -145,7 +145,7 @@ static void dump_domains(unsigned char k
printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
(u32)(now>>32), (u32)now);
- read_lock(&domlist_lock);
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
{
@@ -196,7 +196,7 @@ static void dump_domains(unsigned char k
}
}
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
}
static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
diff -r 9364bea18bc4 -r 202eb735b425 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/common/sched_sedf.c Thu Feb 22 10:15:29 2007 -0700
@@ -1277,6 +1277,7 @@ static void sedf_dump_cpu_state(int i)
loop = 0;
printk("\nnot on Q\n");
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
{
for_each_vcpu(d, ed)
@@ -1288,6 +1289,7 @@ static void sedf_dump_cpu_state(int i)
}
}
}
+ rcu_read_unlock(&domlist_read_lock);
}
@@ -1298,8 +1300,9 @@ static int sedf_adjust_weights(struct xe
struct domain *d;
int sumw[NR_CPUS] = { 0 };
s_time_t sumt[NR_CPUS] = { 0 };
-
+
/* Sum across all weights. */
+ rcu_read_lock(&domlist_read_lock);
for_each_domain( d )
{
for_each_vcpu( d, p )
@@ -1323,8 +1326,10 @@ static int sedf_adjust_weights(struct xe
}
}
}
+ rcu_read_unlock(&domlist_read_lock);
/* Adjust all slices (and periods) to the new weight. */
+ rcu_read_lock(&domlist_read_lock);
for_each_domain( d )
{
for_each_vcpu ( d, p )
@@ -1341,6 +1346,7 @@ static int sedf_adjust_weights(struct xe
}
}
}
+ rcu_read_unlock(&domlist_read_lock);
return 0;
}
diff -r 9364bea18bc4 -r 202eb735b425 xen/common/sysctl.c
--- a/xen/common/sysctl.c Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/common/sysctl.c Thu Feb 22 10:15:29 2007 -0700
@@ -78,7 +78,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
struct xen_domctl_getdomaininfo info;
u32 num_domains = 0;
- read_lock(&domlist_lock);
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
{
@@ -106,7 +106,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
num_domains++;
}
- read_unlock(&domlist_lock);
+ rcu_read_unlock(&domlist_read_lock);
if ( ret != 0 )
break;
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/asm-x86/bug.h
--- a/xen/include/asm-x86/bug.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/asm-x86/bug.h Thu Feb 22 10:15:29 2007 -0700
@@ -7,7 +7,15 @@
#include <asm/x86_32/bug.h>
#endif
-#define BUG() __BUG(__FILE__, __LINE__)
-#define dump_execution_state() __BUG(__FILE__, __LINE__ | 0x8000)
+struct bug_frame {
+ unsigned char ud2[2];
+ unsigned char ret;
+ unsigned short id; /* BUGFRAME_??? */
+} __attribute__((packed));
+
+#define BUGFRAME_dump 0
+#define BUGFRAME_bug 1
+#define BUGFRAME_assert 2
+#define BUGFRAME_rsvd 3
#endif /* __X86_BUG_H__ */
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/asm-x86/event.h
--- a/xen/include/asm-x86/event.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/asm-x86/event.h Thu Feb 22 10:15:29 2007 -0700
@@ -10,6 +10,7 @@
#define __ASM_EVENT_H__
#include <xen/shared.h>
+#include <asm/hvm/irq.h> /* cpu_has_pending_irq() */
static inline void vcpu_kick(struct vcpu *v)
{
@@ -37,9 +38,9 @@ static inline int local_events_need_deli
static inline int local_events_need_delivery(void)
{
struct vcpu *v = current;
- /* Note: Bitwise operations result in fast code with no branches. */
- return (!!vcpu_info(v, evtchn_upcall_pending) &
- !vcpu_info(v, evtchn_upcall_mask));
+ return ((vcpu_info(v, evtchn_upcall_pending) &&
+ !vcpu_info(v, evtchn_upcall_mask)) ||
+ (is_hvm_vcpu(v) && cpu_has_pending_irq(v)));
}
static inline int local_event_delivery_is_enabled(void)
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/asm-x86/x86_32/bug.h
--- a/xen/include/asm-x86/x86_32/bug.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/asm-x86/x86_32/bug.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,19 +1,28 @@
#ifndef __X86_32_BUG_H__
#define __X86_32_BUG_H__
-struct bug_frame {
- unsigned char ud2[2];
+struct bug_frame_str {
unsigned char mov[1];
- unsigned long filename;
- unsigned char ret;
- unsigned short line;
+ unsigned long str;
} __attribute__((packed));
-
#define BUG_MOV_STR "\xbc"
-#define __BUG(file, line) \
+#define dump_execution_state() \
asm volatile ( \
- "ud2 ; .byte 0xbc ; .long %c1 ; ret $%c0" \
- : : "i" (line), "i" (file) )
+ "ud2 ; ret $%c0" \
+ : : "i" (BUGFRAME_dump) )
+
+#define BUG() \
+ asm volatile ( \
+ "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \
+ : : "i" (BUGFRAME_bug | (__LINE__<<2)), \
+ "i" (__FILE__) )
+
+#define assert_failed(p) \
+ asm volatile ( \
+ "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1" \
+ " ; .byte 0xbc ; .long %c2" \
+ : : "i" (BUGFRAME_assert | (__LINE__<<2)), \
+ "i" (__FILE__), "i" (#p) )
#endif /* __X86_32_BUG_H__ */
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/asm-x86/x86_64/bug.h
--- a/xen/include/asm-x86/x86_64/bug.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/asm-x86/x86_64/bug.h Thu Feb 22 10:15:29 2007 -0700
@@ -1,19 +1,28 @@
#ifndef __X86_64_BUG_H__
#define __X86_64_BUG_H__
-struct bug_frame {
- unsigned char ud2[2];
+struct bug_frame_str {
unsigned char mov[2];
- unsigned long filename;
- unsigned char ret;
- unsigned short line;
+ unsigned long str;
} __attribute__((packed));
-
#define BUG_MOV_STR "\x48\xbc"
-#define __BUG(file, line) \
+#define dump_execution_state() \
asm volatile ( \
- "ud2 ; .byte 0x48,0xbc ; .quad %c1 ; ret $%c0" \
- : : "i" (line), "i" (file) )
+ "ud2 ; ret $%c0" \
+ : : "i" (BUGFRAME_dump) )
+
+#define BUG() \
+ asm volatile ( \
+ "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \
+ : : "i" (BUGFRAME_bug | (__LINE__<<2)), \
+ "i" (__FILE__) )
+
+#define assert_failed(p) \
+ asm volatile ( \
+ "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1" \
+ " ; .byte 0x48,0xbc ; .quad %c2" \
+ : : "i" (BUGFRAME_assert | (__LINE__<<2)), \
+ "i" (__FILE__), "i" (#p) )
#endif /* __X86_64_BUG_H__ */
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/asm-x86/x86_emulate.h
--- a/xen/include/asm-x86/x86_emulate.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/asm-x86/x86_emulate.h Thu Feb 22 10:15:29 2007 -0700
@@ -46,26 +46,32 @@ enum x86_segment {
};
/*
+ * Return codes from state-accessor functions and from x86_emulate().
+ */
+ /* Completed successfully. State modified appropriately. */
+#define X86EMUL_OKAY 0
+ /* Unhandleable access or emulation. No state modified. */
+#define X86EMUL_UNHANDLEABLE 1
+ /* Exception raised and requires delivery. */
+#define X86EMUL_EXCEPTION 2
+ /* Retry the emulation for some reason. No state modified. */
+#define X86EMUL_RETRY 3
+ /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
+#define X86EMUL_CMPXCHG_FAILED 3
+
+/*
* These operations represent the instruction emulator's interface to memory.
*
* NOTES:
* 1. If the access fails (cannot emulate, or a standard access faults) then
* it is up to the memop to propagate the fault to the guest VM via
* some out-of-band mechanism, unknown to the emulator. The memop signals
- * failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
+ * failure by returning X86EMUL_EXCEPTION to the emulator, which will
* then immediately bail.
* 2. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
* cmpxchg8b_emulated need support 8-byte accesses.
* 3. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
*/
-/* Access completed successfully: continue emulation as normal. */
-#define X86EMUL_CONTINUE 0
-/* Access is unhandleable: bail from emulation and return error to caller. */
-#define X86EMUL_UNHANDLEABLE 1
-/* Terminate emulation but return success to the caller. */
-#define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
-#define X86EMUL_RETRY_INSTR 2 /* retry the instruction for some reason */
-#define X86EMUL_CMPXCHG_FAILED 2 /* cmpxchg did not see expected value */
struct x86_emulate_ops
{
/*
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/xen/lib.h Thu Feb 22 10:15:29 2007 -0700
@@ -16,18 +16,20 @@ void __bug(char *file, int line) __attri
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
+#ifndef assert_failed
+#define assert_failed(p) \
+do { \
+ printk("Assertion '%s' failed, line %d, file %s\n", #p , \
+ __LINE__, __FILE__); \
+ BUG(); \
+} while (0)
+#endif
+
#ifndef NDEBUG
-#define ASSERT(_p) \
- do { \
- if ( unlikely(!(_p)) ) \
- { \
- printk("Assertion '%s' failed, line %d, file %s\n", #_p , \
- __LINE__, __FILE__); \
- BUG(); \
- } \
- } while ( 0 )
+#define ASSERT(p) \
+ do { if ( unlikely(!(p)) ) assert_failed(p); } while (0)
#else
-#define ASSERT(_p) ((void)0)
+#define ASSERT(p) ((void)0)
#endif
#define SWAP(_a, _b) \
diff -r 9364bea18bc4 -r 202eb735b425 xen/include/xen/rcupdate.h
--- a/xen/include/xen/rcupdate.h Thu Feb 22 09:42:13 2007 -0700
+++ b/xen/include/xen/rcupdate.h Thu Feb 22 10:15:29 2007 -0700
@@ -111,6 +111,59 @@ int rcu_pending(int cpu);
int rcu_pending(int cpu);
int rcu_needs_cpu(int cpu);
+/*
+ * Dummy lock type for passing to rcu_read_{lock,unlock}. Currently exists
+ * only to document the reason for rcu_read_lock() critical sections.
+ */
+struct _rcu_read_lock {};
+typedef struct _rcu_read_lock rcu_read_lock_t;
+#define DEFINE_RCU_READ_LOCK(x) rcu_read_lock_t x
+
+/**
+ * rcu_read_lock - mark the beginning of an RCU read-side critical section.
+ *
+ * When call_rcu() is invoked
+ * on one CPU while other CPUs are within RCU read-side critical
+ * sections, invocation of the corresponding RCU callback is deferred
+ * until after the all the other CPUs exit their critical sections.
+ *
+ * Note, however, that RCU callbacks are permitted to run concurrently
+ * with RCU read-side critical sections. One way that this can happen
+ * is via the following sequence of events: (1) CPU 0 enters an RCU
+ * read-side critical section, (2) CPU 1 invokes call_rcu() to register
+ * an RCU callback, (3) CPU 0 exits the RCU read-side critical section,
+ * (4) CPU 2 enters a RCU read-side critical section, (5) the RCU
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|