[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |