ia64/xen-unstable

changeset 14067:202eb735b425

merge with xen-unstable.hg
author awilliam@xenbuild2.aw
date Thu Feb 22 10:15:29 2007 -0700 (2007-02-22)
parents 9364bea18bc4 f62a052384a5
children 707a696e840d 6510cb03aae1
files
line diff
     1.1 --- a/docs/xen-api/xenapi-datamodel.tex	Thu Feb 22 09:42:13 2007 -0700
     1.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Thu Feb 22 10:15:29 2007 -0700
     1.3 @@ -31,11 +31,13 @@ Name & Description \\
     1.4  {\tt host\_cpu} & A physical CPU \\
     1.5  {\tt network} & A virtual network \\
     1.6  {\tt VIF} & A virtual network interface \\
     1.7 +{\tt VIF\_metrics} & The metrics associated with a virtual network device \\
     1.8  {\tt PIF} & A physical network interface (note separate VLANs are represented as several PIFs) \\
     1.9  {\tt PIF\_metrics} & The metrics associated with a physical network interface \\
    1.10  {\tt SR} & A storage repository \\
    1.11  {\tt VDI} & A virtual disk image \\
    1.12  {\tt VBD} & A virtual block device \\
    1.13 +{\tt VBD\_metrics} & The metrics associated with a virtual block device \\
    1.14  {\tt PBD} & The physical block devices through which hosts access SRs \\
    1.15  {\tt crashdump} & A VM crashdump \\
    1.16  {\tt VTPM} & A virtual TPM device \\
    1.17 @@ -61,7 +63,6 @@ VIF.VM & VM.VIFs & one-to-many\\
    1.18  VIF.network & network.VIFs & one-to-many\\
    1.19  host.metrics & host\_metrics.host & one-to-one\\
    1.20  PIF.metrics & PIF\_metrics.PIF & one-to-one\\
    1.21 -VM.metrics & VM\_metrics.VM & one-to-one\\
    1.22  PIF.host & host.PIFs & one-to-many\\
    1.23  PIF.network & network.PIFs & one-to-many\\
    1.24  SR.VDIs & VDI.SR & many-to-one\\
    1.25 @@ -1076,8 +1077,6 @@ Quals & Field & Type & Description \\
    1.26  $\mathit{RW}$ &  {\tt VCPUs/params} & (string $\rightarrow$ string) Map & configuration parameters for the selected VCPU policy \\
    1.27  $\mathit{RW}$ &  {\tt VCPUs/max} & int & Max number of VCPUs \\
    1.28  $\mathit{RW}$ &  {\tt VCPUs/at\_startup} & int & Boot number of VCPUs \\
    1.29 -$\mathit{RO}_\mathit{ins}$ &  {\tt VCPUs/number} & int & Current number of VCPUs \\
    1.30 -$\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\
    1.31  $\mathit{RW}$ &  {\tt actions/after\_shutdown} & on\_normal\_exit & action to take after the guest has shutdown itself \\
    1.32  $\mathit{RW}$ &  {\tt actions/after\_reboot} & on\_normal\_exit & action to take after the guest has rebooted itself \\
    1.33  $\mathit{RW}$ &  {\tt actions/after\_crash} & on\_crash\_behaviour & action to take if the guest crashes \\
    1.34 @@ -1102,7 +1101,7 @@ Quals & Field & Type & Description \\
    1.35  $\mathit{RO}_\mathit{run}$ &  {\tt tools\_version} & (string $\rightarrow$ string) Map & versions of installed paravirtualised drivers \\
    1.36  $\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
    1.37  $\mathit{RO}_\mathit{run}$ &  {\tt is\_control\_domain} & bool & true if this is a control domain (domain 0 or a driver domain) \\
    1.38 -$\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & VM\_metrics ref & metrics associated with this VM. \\
    1.39 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VM\_metrics ref & metrics associated with this VM. \\
    1.40  \hline
    1.41  \end{longtable}
    1.42  \subsection{Additional RPCs associated with class: VM}
    1.43 @@ -2548,70 +2547,6 @@ void
    1.44  \vspace{0.3cm}
    1.45  \vspace{0.3cm}
    1.46  \vspace{0.3cm}
    1.47 -\subsubsection{RPC name:~get\_VCPUs\_number}
    1.48 -
    1.49 -{\bf Overview:} 
    1.50 -Get the VCPUs/number field of the given VM.
    1.51 -
    1.52 - \noindent {\bf Signature:} 
    1.53 -\begin{verbatim} int get_VCPUs_number (session_id s, VM ref self)\end{verbatim}
    1.54 -
    1.55 -
    1.56 -\noindent{\bf Arguments:}
    1.57 -
    1.58 - 
    1.59 -\vspace{0.3cm}
    1.60 -\begin{tabular}{|c|c|p{7cm}|}
    1.61 - \hline
    1.62 -{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.63 -{\tt VM ref } & self & reference to the object \\ \hline 
    1.64 -
    1.65 -\end{tabular}
    1.66 -
    1.67 -\vspace{0.3cm}
    1.68 -
    1.69 - \noindent {\bf Return Type:} 
    1.70 -{\tt 
    1.71 -int
    1.72 -}
    1.73 -
    1.74 -
    1.75 -value of the field
    1.76 -\vspace{0.3cm}
    1.77 -\vspace{0.3cm}
    1.78 -\vspace{0.3cm}
    1.79 -\subsubsection{RPC name:~get\_VCPUs\_utilisation}
    1.80 -
    1.81 -{\bf Overview:} 
    1.82 -Get the VCPUs/utilisation field of the given VM.
    1.83 -
    1.84 - \noindent {\bf Signature:} 
    1.85 -\begin{verbatim} ((int -> float) Map) get_VCPUs_utilisation (session_id s, VM ref self)\end{verbatim}
    1.86 -
    1.87 -
    1.88 -\noindent{\bf Arguments:}
    1.89 -
    1.90 - 
    1.91 -\vspace{0.3cm}
    1.92 -\begin{tabular}{|c|c|p{7cm}|}
    1.93 - \hline
    1.94 -{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.95 -{\tt VM ref } & self & reference to the object \\ \hline 
    1.96 -
    1.97 -\end{tabular}
    1.98 -
    1.99 -\vspace{0.3cm}
   1.100 -
   1.101 - \noindent {\bf Return Type:} 
   1.102 -{\tt 
   1.103 -(int $\rightarrow$ float) Map
   1.104 -}
   1.105 -
   1.106 -
   1.107 -value of the field
   1.108 -\vspace{0.3cm}
   1.109 -\vspace{0.3cm}
   1.110 -\vspace{0.3cm}
   1.111  \subsubsection{RPC name:~get\_actions\_after\_shutdown}
   1.112  
   1.113  {\bf Overview:} 
   1.114 @@ -4273,7 +4208,6 @@ The metrics associated with a VM.}} \\
   1.115  Quals & Field & Type & Description \\
   1.116  \hline
   1.117  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   1.118 -$\mathit{RO}_\mathit{ins}$ &  {\tt VM} & VM ref & VM to which these metrics apply \\
   1.119  $\mathit{RO}_\mathit{run}$ &  {\tt memory/actual} & int & Guest's actual memory (bytes) \\
   1.120  $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/number} & int & Current number of VCPUs \\
   1.121  $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\
   1.122 @@ -4312,38 +4246,6 @@ value of the field
   1.123  \vspace{0.3cm}
   1.124  \vspace{0.3cm}
   1.125  \vspace{0.3cm}
   1.126 -\subsubsection{RPC name:~get\_VM}
   1.127 -
   1.128 -{\bf Overview:} 
   1.129 -Get the VM field of the given VM\_metrics.
   1.130 -
   1.131 - \noindent {\bf Signature:} 
   1.132 -\begin{verbatim} (VM ref) get_VM (session_id s, VM_metrics ref self)\end{verbatim}
   1.133 -
   1.134 -
   1.135 -\noindent{\bf Arguments:}
   1.136 -
   1.137 - 
   1.138 -\vspace{0.3cm}
   1.139 -\begin{tabular}{|c|c|p{7cm}|}
   1.140 - \hline
   1.141 -{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.142 -{\tt VM\_metrics ref } & self & reference to the object \\ \hline 
   1.143 -
   1.144 -\end{tabular}
   1.145 -
   1.146 -\vspace{0.3cm}
   1.147 -
   1.148 - \noindent {\bf Return Type:} 
   1.149 -{\tt 
   1.150 -VM ref
   1.151 -}
   1.152 -
   1.153 -
   1.154 -value of the field
   1.155 -\vspace{0.3cm}
   1.156 -\vspace{0.3cm}
   1.157 -\vspace{0.3cm}
   1.158  \subsubsection{RPC name:~get\_memory\_actual}
   1.159  
   1.160  {\bf Overview:} 
   1.161 @@ -4522,6 +4424,7 @@ Quals & Field & Type & Description \\
   1.162  $\mathit{RW}$ &  {\tt name/description} & string & a notes field containg human-readable description \\
   1.163  $\mathit{RO}_\mathit{run}$ &  {\tt software\_version} & (string $\rightarrow$ string) Map & version strings \\
   1.164  $\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
   1.165 +$\mathit{RO}_\mathit{run}$ &  {\tt supported\_bootloaders} & string Set & a list of the bootloaders installed on the machine \\
   1.166  $\mathit{RO}_\mathit{run}$ &  {\tt resident\_VMs} & (VM ref) Set & list of VMs currently resident on host \\
   1.167  $\mathit{RW}$ &  {\tt logging} & (string $\rightarrow$ string) Map & logging configuration \\
   1.168  $\mathit{RO}_\mathit{run}$ &  {\tt PIFs} & (PIF ref) Set & physical network interfaces \\
   1.169 @@ -5050,6 +4953,38 @@ void
   1.170  \vspace{0.3cm}
   1.171  \vspace{0.3cm}
   1.172  \vspace{0.3cm}
   1.173 +\subsubsection{RPC name:~get\_supported\_bootloaders}
   1.174 +
   1.175 +{\bf Overview:} 
   1.176 +Get the supported\_bootloaders field of the given host.
   1.177 +
   1.178 + \noindent {\bf Signature:} 
   1.179 +\begin{verbatim} (string Set) get_supported_bootloaders (session_id s, host ref self)\end{verbatim}
   1.180 +
   1.181 +
   1.182 +\noindent{\bf Arguments:}
   1.183 +
   1.184 + 
   1.185 +\vspace{0.3cm}
   1.186 +\begin{tabular}{|c|c|p{7cm}|}
   1.187 + \hline
   1.188 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.189 +{\tt host ref } & self & reference to the object \\ \hline 
   1.190 +
   1.191 +\end{tabular}
   1.192 +
   1.193 +\vspace{0.3cm}
   1.194 +
   1.195 + \noindent {\bf Return Type:} 
   1.196 +{\tt 
   1.197 +string Set
   1.198 +}
   1.199 +
   1.200 +
   1.201 +value of the field
   1.202 +\vspace{0.3cm}
   1.203 +\vspace{0.3cm}
   1.204 +\vspace{0.3cm}
   1.205  \subsubsection{RPC name:~get\_resident\_VMs}
   1.206  
   1.207  {\bf Overview:} 
   1.208 @@ -5479,70 +5414,6 @@ value of the field
   1.209  \vspace{0.3cm}
   1.210  \vspace{0.3cm}
   1.211  \vspace{0.3cm}
   1.212 -\subsubsection{RPC name:~create}
   1.213 -
   1.214 -{\bf Overview:} 
   1.215 -Create a new host instance, and return its handle.
   1.216 -
   1.217 - \noindent {\bf Signature:} 
   1.218 -\begin{verbatim} (host ref) create (session_id s, host record args)\end{verbatim}
   1.219 -
   1.220 -
   1.221 -\noindent{\bf Arguments:}
   1.222 -
   1.223 - 
   1.224 -\vspace{0.3cm}
   1.225 -\begin{tabular}{|c|c|p{7cm}|}
   1.226 - \hline
   1.227 -{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.228 -{\tt host record } & args & All constructor arguments \\ \hline 
   1.229 -
   1.230 -\end{tabular}
   1.231 -
   1.232 -\vspace{0.3cm}
   1.233 -
   1.234 - \noindent {\bf Return Type:} 
   1.235 -{\tt 
   1.236 -host ref
   1.237 -}
   1.238 -
   1.239 -
   1.240 -reference to the newly created object
   1.241 -\vspace{0.3cm}
   1.242 -\vspace{0.3cm}
   1.243 -\vspace{0.3cm}
   1.244 -\subsubsection{RPC name:~destroy}
   1.245 -
   1.246 -{\bf Overview:} 
   1.247 -Destroy the specified host instance.
   1.248 -
   1.249 - \noindent {\bf Signature:} 
   1.250 -\begin{verbatim} void destroy (session_id s, host ref self)\end{verbatim}
   1.251 -
   1.252 -
   1.253 -\noindent{\bf Arguments:}
   1.254 -
   1.255 - 
   1.256 -\vspace{0.3cm}
   1.257 -\begin{tabular}{|c|c|p{7cm}|}
   1.258 - \hline
   1.259 -{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.260 -{\tt host ref } & self & reference to the object \\ \hline 
   1.261 -
   1.262 -\end{tabular}
   1.263 -
   1.264 -\vspace{0.3cm}
   1.265 -
   1.266 - \noindent {\bf Return Type:} 
   1.267 -{\tt 
   1.268 -void
   1.269 -}
   1.270 -
   1.271 -
   1.272 -
   1.273 -\vspace{0.3cm}
   1.274 -\vspace{0.3cm}
   1.275 -\vspace{0.3cm}
   1.276  \subsubsection{RPC name:~get\_by\_uuid}
   1.277  
   1.278  {\bf Overview:} 
   1.279 @@ -6808,8 +6679,9 @@ Quals & Field & Type & Description \\
   1.280  $\mathit{RO}_\mathit{ins}$ &  {\tt VM} & VM ref & virtual machine to which this vif is connected \\
   1.281  $\mathit{RW}$ &  {\tt MAC} & string & ethernet MAC address of virtual interface, as exposed to guest \\
   1.282  $\mathit{RW}$ &  {\tt MTU} & int & MTU in octets \\
   1.283 -$\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
   1.284 -$\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
   1.285 +$\mathit{RW}$ &  {\tt qos/algorithm\_type} & string & QoS algorithm to use \\
   1.286 +$\mathit{RW}$ &  {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & Paramters for chosen QoS algorithm \\
   1.287 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VIF\_metrics ref & metrics associated with this VIF. \\
   1.288  \hline
   1.289  \end{longtable}
   1.290  \subsection{Additional RPCs associated with class: VIF}
   1.291 @@ -7107,13 +6979,13 @@ void
   1.292  \vspace{0.3cm}
   1.293  \vspace{0.3cm}
   1.294  \vspace{0.3cm}
   1.295 -\subsubsection{RPC name:~get\_io\_read\_kbs}
   1.296 -
   1.297 -{\bf Overview:} 
   1.298 -Get the io/read\_kbs field of the given VIF.
   1.299 -
   1.300 - \noindent {\bf Signature:} 
   1.301 -\begin{verbatim} float get_io_read_kbs (session_id s, VIF ref self)\end{verbatim}
   1.302 +\subsubsection{RPC name:~get\_qos\_algorithm\_type}
   1.303 +
   1.304 +{\bf Overview:} 
   1.305 +Get the qos/algorithm\_type field of the given VIF.
   1.306 +
   1.307 + \noindent {\bf Signature:} 
   1.308 +\begin{verbatim} string get_qos_algorithm_type (session_id s, VIF ref self)\end{verbatim}
   1.309  
   1.310  
   1.311  \noindent{\bf Arguments:}
   1.312 @@ -7131,21 +7003,21 @@ Get the io/read\_kbs field of the given 
   1.313  
   1.314   \noindent {\bf Return Type:} 
   1.315  {\tt 
   1.316 -float
   1.317 -}
   1.318 -
   1.319 -
   1.320 -value of the field
   1.321 -\vspace{0.3cm}
   1.322 -\vspace{0.3cm}
   1.323 -\vspace{0.3cm}
   1.324 -\subsubsection{RPC name:~get\_io\_write\_kbs}
   1.325 -
   1.326 -{\bf Overview:} 
   1.327 -Get the io/write\_kbs field of the given VIF.
   1.328 -
   1.329 - \noindent {\bf Signature:} 
   1.330 -\begin{verbatim} float get_io_write_kbs (session_id s, VIF ref self)\end{verbatim}
   1.331 +string
   1.332 +}
   1.333 +
   1.334 +
   1.335 +value of the field
   1.336 +\vspace{0.3cm}
   1.337 +\vspace{0.3cm}
   1.338 +\vspace{0.3cm}
   1.339 +\subsubsection{RPC name:~set\_qos\_algorithm\_type}
   1.340 +
   1.341 +{\bf Overview:} 
   1.342 +Set the qos/algorithm\_type field of the given VIF.
   1.343 +
   1.344 + \noindent {\bf Signature:} 
   1.345 +\begin{verbatim} void set_qos_algorithm_type (session_id s, VIF ref self, string value)\end{verbatim}
   1.346  
   1.347  
   1.348  \noindent{\bf Arguments:}
   1.349 @@ -7157,13 +7029,186 @@ Get the io/write\_kbs field of the given
   1.350  {\bf type} & {\bf name} & {\bf description} \\ \hline
   1.351  {\tt VIF ref } & self & reference to the object \\ \hline 
   1.352  
   1.353 -\end{tabular}
   1.354 -
   1.355 -\vspace{0.3cm}
   1.356 -
   1.357 - \noindent {\bf Return Type:} 
   1.358 -{\tt 
   1.359 -float
   1.360 +{\tt string } & value & New value to set \\ \hline 
   1.361 +
   1.362 +\end{tabular}
   1.363 +
   1.364 +\vspace{0.3cm}
   1.365 +
   1.366 + \noindent {\bf Return Type:} 
   1.367 +{\tt 
   1.368 +void
   1.369 +}
   1.370 +
   1.371 +
   1.372 +
   1.373 +\vspace{0.3cm}
   1.374 +\vspace{0.3cm}
   1.375 +\vspace{0.3cm}
   1.376 +\subsubsection{RPC name:~get\_qos\_algorithm\_params}
   1.377 +
   1.378 +{\bf Overview:} 
   1.379 +Get the qos/algorithm\_params field of the given VIF.
   1.380 +
   1.381 + \noindent {\bf Signature:} 
   1.382 +\begin{verbatim} ((string -> string) Map) get_qos_algorithm_params (session_id s, VIF ref self)\end{verbatim}
   1.383 +
   1.384 +
   1.385 +\noindent{\bf Arguments:}
   1.386 +
   1.387 + 
   1.388 +\vspace{0.3cm}
   1.389 +\begin{tabular}{|c|c|p{7cm}|}
   1.390 + \hline
   1.391 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.392 +{\tt VIF ref } & self & reference to the object \\ \hline 
   1.393 +
   1.394 +\end{tabular}
   1.395 +
   1.396 +\vspace{0.3cm}
   1.397 +
   1.398 + \noindent {\bf Return Type:} 
   1.399 +{\tt 
   1.400 +(string $\rightarrow$ string) Map
   1.401 +}
   1.402 +
   1.403 +
   1.404 +value of the field
   1.405 +\vspace{0.3cm}
   1.406 +\vspace{0.3cm}
   1.407 +\vspace{0.3cm}
   1.408 +\subsubsection{RPC name:~set\_qos\_algorithm\_params}
   1.409 +
   1.410 +{\bf Overview:} 
   1.411 +Set the qos/algorithm\_params field of the given VIF.
   1.412 +
   1.413 + \noindent {\bf Signature:} 
   1.414 +\begin{verbatim} void set_qos_algorithm_params (session_id s, VIF ref self, (string -> string) Map value)\end{verbatim}
   1.415 +
   1.416 +
   1.417 +\noindent{\bf Arguments:}
   1.418 +
   1.419 + 
   1.420 +\vspace{0.3cm}
   1.421 +\begin{tabular}{|c|c|p{7cm}|}
   1.422 + \hline
   1.423 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.424 +{\tt VIF ref } & self & reference to the object \\ \hline 
   1.425 +
   1.426 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
   1.427 +
   1.428 +\end{tabular}
   1.429 +
   1.430 +\vspace{0.3cm}
   1.431 +
   1.432 + \noindent {\bf Return Type:} 
   1.433 +{\tt 
   1.434 +void
   1.435 +}
   1.436 +
   1.437 +
   1.438 +
   1.439 +\vspace{0.3cm}
   1.440 +\vspace{0.3cm}
   1.441 +\vspace{0.3cm}
   1.442 +\subsubsection{RPC name:~add\_to\_qos\_algorithm\_params}
   1.443 +
   1.444 +{\bf Overview:} 
   1.445 +Add the given key-value pair to the qos/algorithm\_params field of the
   1.446 +given VIF.
   1.447 +
   1.448 + \noindent {\bf Signature:} 
   1.449 +\begin{verbatim} void add_to_qos_algorithm_params (session_id s, VIF ref self, string key, string value)\end{verbatim}
   1.450 +
   1.451 +
   1.452 +\noindent{\bf Arguments:}
   1.453 +
   1.454 + 
   1.455 +\vspace{0.3cm}
   1.456 +\begin{tabular}{|c|c|p{7cm}|}
   1.457 + \hline
   1.458 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.459 +{\tt VIF ref } & self & reference to the object \\ \hline 
   1.460 +
   1.461 +{\tt string } & key & Key to add \\ \hline 
   1.462 +
   1.463 +{\tt string } & value & Value to add \\ \hline 
   1.464 +
   1.465 +\end{tabular}
   1.466 +
   1.467 +\vspace{0.3cm}
   1.468 +
   1.469 + \noindent {\bf Return Type:} 
   1.470 +{\tt 
   1.471 +void
   1.472 +}
   1.473 +
   1.474 +
   1.475 +
   1.476 +\vspace{0.3cm}
   1.477 +\vspace{0.3cm}
   1.478 +\vspace{0.3cm}
   1.479 +\subsubsection{RPC name:~remove\_from\_qos\_algorithm\_params}
   1.480 +
   1.481 +{\bf Overview:} 
   1.482 +Remove the given key and its corresponding value from the
   1.483 +qos/algorithm\_params field of the given VIF.  If the key is not in that
   1.484 +Map, then do nothing.
   1.485 +
   1.486 + \noindent {\bf Signature:} 
   1.487 +\begin{verbatim} void remove_from_qos_algorithm_params (session_id s, VIF ref self, string key)\end{verbatim}
   1.488 +
   1.489 +
   1.490 +\noindent{\bf Arguments:}
   1.491 +
   1.492 + 
   1.493 +\vspace{0.3cm}
   1.494 +\begin{tabular}{|c|c|p{7cm}|}
   1.495 + \hline
   1.496 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.497 +{\tt VIF ref } & self & reference to the object \\ \hline 
   1.498 +
   1.499 +{\tt string } & key & Key to remove \\ \hline 
   1.500 +
   1.501 +\end{tabular}
   1.502 +
   1.503 +\vspace{0.3cm}
   1.504 +
   1.505 + \noindent {\bf Return Type:} 
   1.506 +{\tt 
   1.507 +void
   1.508 +}
   1.509 +
   1.510 +
   1.511 +
   1.512 +\vspace{0.3cm}
   1.513 +\vspace{0.3cm}
   1.514 +\vspace{0.3cm}
   1.515 +\subsubsection{RPC name:~get\_metrics}
   1.516 +
   1.517 +{\bf Overview:} 
   1.518 +Get the metrics field of the given VIF.
   1.519 +
   1.520 + \noindent {\bf Signature:} 
   1.521 +\begin{verbatim} (VIF_metrics ref) get_metrics (session_id s, VIF ref self)\end{verbatim}
   1.522 +
   1.523 +
   1.524 +\noindent{\bf Arguments:}
   1.525 +
   1.526 + 
   1.527 +\vspace{0.3cm}
   1.528 +\begin{tabular}{|c|c|p{7cm}|}
   1.529 + \hline
   1.530 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.531 +{\tt VIF ref } & self & reference to the object \\ \hline 
   1.532 +
   1.533 +\end{tabular}
   1.534 +
   1.535 +\vspace{0.3cm}
   1.536 +
   1.537 + \noindent {\bf Return Type:} 
   1.538 +{\tt 
   1.539 +VIF\_metrics ref
   1.540  }
   1.541  
   1.542  
   1.543 @@ -7302,6 +7347,185 @@ all fields from the object
   1.544  
   1.545  \vspace{1cm}
   1.546  \newpage
   1.547 +\section{Class: VIF\_metrics}
   1.548 +\subsection{Fields for class: VIF\_metrics}
   1.549 +\begin{longtable}{|lllp{0.38\textwidth}|}
   1.550 +\hline
   1.551 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VIF\_metrics} \\
   1.552 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
   1.553 +The metrics associated with a virtual network device.}} \\
   1.554 +\hline
   1.555 +Quals & Field & Type & Description \\
   1.556 +\hline
   1.557 +$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
   1.558 +$\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
   1.559 +$\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
   1.560 +\hline
   1.561 +\end{longtable}
   1.562 +\subsection{Additional RPCs associated with class: VIF\_metrics}
   1.563 +\subsubsection{RPC name:~get\_uuid}
   1.564 +
   1.565 +{\bf Overview:} 
   1.566 +Get the uuid field of the given VIF\_metrics.
   1.567 +
   1.568 + \noindent {\bf Signature:} 
   1.569 +\begin{verbatim} string get_uuid (session_id s, VIF_metrics ref self)\end{verbatim}
   1.570 +
   1.571 +
   1.572 +\noindent{\bf Arguments:}
   1.573 +
   1.574 + 
   1.575 +\vspace{0.3cm}
   1.576 +\begin{tabular}{|c|c|p{7cm}|}
   1.577 + \hline
   1.578 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.579 +{\tt VIF\_metrics ref } & self & reference to the object \\ \hline 
   1.580 +
   1.581 +\end{tabular}
   1.582 +
   1.583 +\vspace{0.3cm}
   1.584 +
   1.585 + \noindent {\bf Return Type:} 
   1.586 +{\tt 
   1.587 +string
   1.588 +}
   1.589 +
   1.590 +
   1.591 +value of the field
   1.592 +\vspace{0.3cm}
   1.593 +\vspace{0.3cm}
   1.594 +\vspace{0.3cm}
   1.595 +\subsubsection{RPC name:~get\_io\_read\_kbs}
   1.596 +
   1.597 +{\bf Overview:} 
   1.598 +Get the io/read\_kbs field of the given VIF\_metrics.
   1.599 +
   1.600 + \noindent {\bf Signature:} 
   1.601 +\begin{verbatim} float get_io_read_kbs (session_id s, VIF_metrics ref self)\end{verbatim}
   1.602 +
   1.603 +
   1.604 +\noindent{\bf Arguments:}
   1.605 +
   1.606 + 
   1.607 +\vspace{0.3cm}
   1.608 +\begin{tabular}{|c|c|p{7cm}|}
   1.609 + \hline
   1.610 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.611 +{\tt VIF\_metrics ref } & self & reference to the object \\ \hline 
   1.612 +
   1.613 +\end{tabular}
   1.614 +
   1.615 +\vspace{0.3cm}
   1.616 +
   1.617 + \noindent {\bf Return Type:} 
   1.618 +{\tt 
   1.619 +float
   1.620 +}
   1.621 +
   1.622 +
   1.623 +value of the field
   1.624 +\vspace{0.3cm}
   1.625 +\vspace{0.3cm}
   1.626 +\vspace{0.3cm}
   1.627 +\subsubsection{RPC name:~get\_io\_write\_kbs}
   1.628 +
   1.629 +{\bf Overview:} 
   1.630 +Get the io/write\_kbs field of the given VIF\_metrics.
   1.631 +
   1.632 + \noindent {\bf Signature:} 
   1.633 +\begin{verbatim} float get_io_write_kbs (session_id s, VIF_metrics ref self)\end{verbatim}
   1.634 +
   1.635 +
   1.636 +\noindent{\bf Arguments:}
   1.637 +
   1.638 + 
   1.639 +\vspace{0.3cm}
   1.640 +\begin{tabular}{|c|c|p{7cm}|}
   1.641 + \hline
   1.642 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.643 +{\tt VIF\_metrics ref } & self & reference to the object \\ \hline 
   1.644 +
   1.645 +\end{tabular}
   1.646 +
   1.647 +\vspace{0.3cm}
   1.648 +
   1.649 + \noindent {\bf Return Type:} 
   1.650 +{\tt 
   1.651 +float
   1.652 +}
   1.653 +
   1.654 +
   1.655 +value of the field
   1.656 +\vspace{0.3cm}
   1.657 +\vspace{0.3cm}
   1.658 +\vspace{0.3cm}
   1.659 +\subsubsection{RPC name:~get\_by\_uuid}
   1.660 +
   1.661 +{\bf Overview:} 
   1.662 +Get a reference to the VIF\_metrics instance with the specified UUID.
   1.663 +
   1.664 + \noindent {\bf Signature:} 
   1.665 +\begin{verbatim} (VIF_metrics ref) get_by_uuid (session_id s, string uuid)\end{verbatim}
   1.666 +
   1.667 +
   1.668 +\noindent{\bf Arguments:}
   1.669 +
   1.670 + 
   1.671 +\vspace{0.3cm}
   1.672 +\begin{tabular}{|c|c|p{7cm}|}
   1.673 + \hline
   1.674 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.675 +{\tt string } & uuid & UUID of object to return \\ \hline 
   1.676 +
   1.677 +\end{tabular}
   1.678 +
   1.679 +\vspace{0.3cm}
   1.680 +
   1.681 + \noindent {\bf Return Type:} 
   1.682 +{\tt 
   1.683 +VIF\_metrics ref
   1.684 +}
   1.685 +
   1.686 +
   1.687 +reference to the object
   1.688 +\vspace{0.3cm}
   1.689 +\vspace{0.3cm}
   1.690 +\vspace{0.3cm}
   1.691 +\subsubsection{RPC name:~get\_record}
   1.692 +
   1.693 +{\bf Overview:} 
   1.694 +Get a record containing the current state of the given VIF\_metrics.
   1.695 +
   1.696 + \noindent {\bf Signature:} 
   1.697 +\begin{verbatim} (VIF_metrics record) get_record (session_id s, VIF_metrics ref self)\end{verbatim}
   1.698 +
   1.699 +
   1.700 +\noindent{\bf Arguments:}
   1.701 +
   1.702 + 
   1.703 +\vspace{0.3cm}
   1.704 +\begin{tabular}{|c|c|p{7cm}|}
   1.705 + \hline
   1.706 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.707 +{\tt VIF\_metrics ref } & self & reference to the object \\ \hline 
   1.708 +
   1.709 +\end{tabular}
   1.710 +
   1.711 +\vspace{0.3cm}
   1.712 +
   1.713 + \noindent {\bf Return Type:} 
   1.714 +{\tt 
   1.715 +VIF\_metrics record
   1.716 +}
   1.717 +
   1.718 +
   1.719 +all fields from the object
   1.720 +\vspace{0.3cm}
   1.721 +\vspace{0.3cm}
   1.722 +\vspace{0.3cm}
   1.723 +
   1.724 +\vspace{1cm}
   1.725 +\newpage
   1.726  \section{Class: PIF}
   1.727  \subsection{Fields for class: PIF}
   1.728  \begin{longtable}{|lllp{0.38\textwidth}|}
   1.729 @@ -9562,8 +9786,9 @@ Quals & Field & Type & Description \\
   1.730  $\mathit{RW}$ &  {\tt bootable} & bool & true if this VBD is bootable \\
   1.731  $\mathit{RW}$ &  {\tt mode} & vbd\_mode & the mode the VBD should be mounted with \\
   1.732  $\mathit{RW}$ &  {\tt type} & vbd\_type & how the VBD will appear to the guest (e.g. disk or CD) \\
   1.733 -$\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
   1.734 -$\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
   1.735 +$\mathit{RW}$ &  {\tt qos/algorithm\_type} & string & QoS algorithm to use \\
   1.736 +$\mathit{RW}$ &  {\tt qos/algorithm\_params} & (string $\rightarrow$ string) Map & Paramters for chosen QoS algorithm \\
   1.737 +$\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VBD\_metrics ref & metrics associated with this VBD. \\
   1.738  \hline
   1.739  \end{longtable}
   1.740  \subsection{Additional RPCs associated with class: VBD}
   1.741 @@ -9962,13 +10187,13 @@ void
   1.742  \vspace{0.3cm}
   1.743  \vspace{0.3cm}
   1.744  \vspace{0.3cm}
   1.745 -\subsubsection{RPC name:~get\_io\_read\_kbs}
   1.746 -
   1.747 -{\bf Overview:} 
   1.748 -Get the io/read\_kbs field of the given VBD.
   1.749 -
   1.750 - \noindent {\bf Signature:} 
   1.751 -\begin{verbatim} float get_io_read_kbs (session_id s, VBD ref self)\end{verbatim}
   1.752 +\subsubsection{RPC name:~get\_qos\_algorithm\_type}
   1.753 +
   1.754 +{\bf Overview:} 
   1.755 +Get the qos/algorithm\_type field of the given VBD.
   1.756 +
   1.757 + \noindent {\bf Signature:} 
   1.758 +\begin{verbatim} string get_qos_algorithm_type (session_id s, VBD ref self)\end{verbatim}
   1.759  
   1.760  
   1.761  \noindent{\bf Arguments:}
   1.762 @@ -9986,21 +10211,21 @@ Get the io/read\_kbs field of the given 
   1.763  
   1.764   \noindent {\bf Return Type:} 
   1.765  {\tt 
   1.766 -float
   1.767 -}
   1.768 -
   1.769 -
   1.770 -value of the field
   1.771 -\vspace{0.3cm}
   1.772 -\vspace{0.3cm}
   1.773 -\vspace{0.3cm}
   1.774 -\subsubsection{RPC name:~get\_io\_write\_kbs}
   1.775 -
   1.776 -{\bf Overview:} 
   1.777 -Get the io/write\_kbs field of the given VBD.
   1.778 -
   1.779 - \noindent {\bf Signature:} 
   1.780 -\begin{verbatim} float get_io_write_kbs (session_id s, VBD ref self)\end{verbatim}
   1.781 +string
   1.782 +}
   1.783 +
   1.784 +
   1.785 +value of the field
   1.786 +\vspace{0.3cm}
   1.787 +\vspace{0.3cm}
   1.788 +\vspace{0.3cm}
   1.789 +\subsubsection{RPC name:~set\_qos\_algorithm\_type}
   1.790 +
   1.791 +{\bf Overview:} 
   1.792 +Set the qos/algorithm\_type field of the given VBD.
   1.793 +
   1.794 + \noindent {\bf Signature:} 
   1.795 +\begin{verbatim} void set_qos_algorithm_type (session_id s, VBD ref self, string value)\end{verbatim}
   1.796  
   1.797  
   1.798  \noindent{\bf Arguments:}
   1.799 @@ -10012,13 +10237,186 @@ Get the io/write\_kbs field of the given
   1.800  {\bf type} & {\bf name} & {\bf description} \\ \hline
   1.801  {\tt VBD ref } & self & reference to the object \\ \hline 
   1.802  
   1.803 -\end{tabular}
   1.804 -
   1.805 -\vspace{0.3cm}
   1.806 -
   1.807 - \noindent {\bf Return Type:} 
   1.808 -{\tt 
   1.809 -float
   1.810 +{\tt string } & value & New value to set \\ \hline 
   1.811 +
   1.812 +\end{tabular}
   1.813 +
   1.814 +\vspace{0.3cm}
   1.815 +
   1.816 + \noindent {\bf Return Type:} 
   1.817 +{\tt 
   1.818 +void
   1.819 +}
   1.820 +
   1.821 +
   1.822 +
   1.823 +\vspace{0.3cm}
   1.824 +\vspace{0.3cm}
   1.825 +\vspace{0.3cm}
   1.826 +\subsubsection{RPC name:~get\_qos\_algorithm\_params}
   1.827 +
   1.828 +{\bf Overview:} 
   1.829 +Get the qos/algorithm\_params field of the given VBD.
   1.830 +
   1.831 + \noindent {\bf Signature:} 
   1.832 +\begin{verbatim} ((string -> string) Map) get_qos_algorithm_params (session_id s, VBD ref self)\end{verbatim}
   1.833 +
   1.834 +
   1.835 +\noindent{\bf Arguments:}
   1.836 +
   1.837 + 
   1.838 +\vspace{0.3cm}
   1.839 +\begin{tabular}{|c|c|p{7cm}|}
   1.840 + \hline
   1.841 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.842 +{\tt VBD ref } & self & reference to the object \\ \hline 
   1.843 +
   1.844 +\end{tabular}
   1.845 +
   1.846 +\vspace{0.3cm}
   1.847 +
   1.848 + \noindent {\bf Return Type:} 
   1.849 +{\tt 
   1.850 +(string $\rightarrow$ string) Map
   1.851 +}
   1.852 +
   1.853 +
   1.854 +value of the field
   1.855 +\vspace{0.3cm}
   1.856 +\vspace{0.3cm}
   1.857 +\vspace{0.3cm}
   1.858 +\subsubsection{RPC name:~set\_qos\_algorithm\_params}
   1.859 +
   1.860 +{\bf Overview:} 
   1.861 +Set the qos/algorithm\_params field of the given VBD.
   1.862 +
   1.863 + \noindent {\bf Signature:} 
   1.864 +\begin{verbatim} void set_qos_algorithm_params (session_id s, VBD ref self, (string -> string) Map value)\end{verbatim}
   1.865 +
   1.866 +
   1.867 +\noindent{\bf Arguments:}
   1.868 +
   1.869 + 
   1.870 +\vspace{0.3cm}
   1.871 +\begin{tabular}{|c|c|p{7cm}|}
   1.872 + \hline
   1.873 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.874 +{\tt VBD ref } & self & reference to the object \\ \hline 
   1.875 +
   1.876 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
   1.877 +
   1.878 +\end{tabular}
   1.879 +
   1.880 +\vspace{0.3cm}
   1.881 +
   1.882 + \noindent {\bf Return Type:} 
   1.883 +{\tt 
   1.884 +void
   1.885 +}
   1.886 +
   1.887 +
   1.888 +
   1.889 +\vspace{0.3cm}
   1.890 +\vspace{0.3cm}
   1.891 +\vspace{0.3cm}
   1.892 +\subsubsection{RPC name:~add\_to\_qos\_algorithm\_params}
   1.893 +
   1.894 +{\bf Overview:} 
   1.895 +Add the given key-value pair to the qos/algorithm\_params field of the
   1.896 +given VBD.
   1.897 +
   1.898 + \noindent {\bf Signature:} 
   1.899 +\begin{verbatim} void add_to_qos_algorithm_params (session_id s, VBD ref self, string key, string value)\end{verbatim}
   1.900 +
   1.901 +
   1.902 +\noindent{\bf Arguments:}
   1.903 +
   1.904 + 
   1.905 +\vspace{0.3cm}
   1.906 +\begin{tabular}{|c|c|p{7cm}|}
   1.907 + \hline
   1.908 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.909 +{\tt VBD ref } & self & reference to the object \\ \hline 
   1.910 +
   1.911 +{\tt string } & key & Key to add \\ \hline 
   1.912 +
   1.913 +{\tt string } & value & Value to add \\ \hline 
   1.914 +
   1.915 +\end{tabular}
   1.916 +
   1.917 +\vspace{0.3cm}
   1.918 +
   1.919 + \noindent {\bf Return Type:} 
   1.920 +{\tt 
   1.921 +void
   1.922 +}
   1.923 +
   1.924 +
   1.925 +
   1.926 +\vspace{0.3cm}
   1.927 +\vspace{0.3cm}
   1.928 +\vspace{0.3cm}
   1.929 +\subsubsection{RPC name:~remove\_from\_qos\_algorithm\_params}
   1.930 +
   1.931 +{\bf Overview:} 
   1.932 +Remove the given key and its corresponding value from the
   1.933 +qos/algorithm\_params field of the given VBD.  If the key is not in that
   1.934 +Map, then do nothing.
   1.935 +
   1.936 + \noindent {\bf Signature:} 
   1.937 +\begin{verbatim} void remove_from_qos_algorithm_params (session_id s, VBD ref self, string key)\end{verbatim}
   1.938 +
   1.939 +
   1.940 +\noindent{\bf Arguments:}
   1.941 +
   1.942 + 
   1.943 +\vspace{0.3cm}
   1.944 +\begin{tabular}{|c|c|p{7cm}|}
   1.945 + \hline
   1.946 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.947 +{\tt VBD ref } & self & reference to the object \\ \hline 
   1.948 +
   1.949 +{\tt string } & key & Key to remove \\ \hline 
   1.950 +
   1.951 +\end{tabular}
   1.952 +
   1.953 +\vspace{0.3cm}
   1.954 +
   1.955 + \noindent {\bf Return Type:} 
   1.956 +{\tt 
   1.957 +void
   1.958 +}
   1.959 +
   1.960 +
   1.961 +
   1.962 +\vspace{0.3cm}
   1.963 +\vspace{0.3cm}
   1.964 +\vspace{0.3cm}
   1.965 +\subsubsection{RPC name:~get\_metrics}
   1.966 +
   1.967 +{\bf Overview:} 
   1.968 +Get the metrics field of the given VBD.
   1.969 +
   1.970 + \noindent {\bf Signature:} 
   1.971 +\begin{verbatim} (VBD_metrics ref) get_metrics (session_id s, VBD ref self)\end{verbatim}
   1.972 +
   1.973 +
   1.974 +\noindent{\bf Arguments:}
   1.975 +
   1.976 + 
   1.977 +\vspace{0.3cm}
   1.978 +\begin{tabular}{|c|c|p{7cm}|}
   1.979 + \hline
   1.980 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.981 +{\tt VBD ref } & self & reference to the object \\ \hline 
   1.982 +
   1.983 +\end{tabular}
   1.984 +
   1.985 +\vspace{0.3cm}
   1.986 +
   1.987 + \noindent {\bf Return Type:} 
   1.988 +{\tt 
   1.989 +VBD\_metrics ref
   1.990  }
   1.991  
   1.992  
   1.993 @@ -10157,6 +10555,185 @@ all fields from the object
   1.994  
   1.995  \vspace{1cm}
   1.996  \newpage
   1.997 +\section{Class: VBD\_metrics}
   1.998 +\subsection{Fields for class: VBD\_metrics}
   1.999 +\begin{longtable}{|lllp{0.38\textwidth}|}
  1.1000 +\hline
  1.1001 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VBD\_metrics} \\
  1.1002 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
  1.1003 +The metrics associated with a virtual block device.}} \\
  1.1004 +\hline
  1.1005 +Quals & Field & Type & Description \\
  1.1006 +\hline
  1.1007 +$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
  1.1008 +$\mathit{RO}_\mathit{run}$ &  {\tt io/read\_kbs} & float & Read bandwidth (KiB/s) \\
  1.1009 +$\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
  1.1010 +\hline
  1.1011 +\end{longtable}
  1.1012 +\subsection{Additional RPCs associated with class: VBD\_metrics}
  1.1013 +\subsubsection{RPC name:~get\_uuid}
  1.1014 +
  1.1015 +{\bf Overview:} 
  1.1016 +Get the uuid field of the given VBD\_metrics.
  1.1017 +
  1.1018 + \noindent {\bf Signature:} 
  1.1019 +\begin{verbatim} string get_uuid (session_id s, VBD_metrics ref self)\end{verbatim}
  1.1020 +
  1.1021 +
  1.1022 +\noindent{\bf Arguments:}
  1.1023 +
  1.1024 + 
  1.1025 +\vspace{0.3cm}
  1.1026 +\begin{tabular}{|c|c|p{7cm}|}
  1.1027 + \hline
  1.1028 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1029 +{\tt VBD\_metrics ref } & self & reference to the object \\ \hline 
  1.1030 +
  1.1031 +\end{tabular}
  1.1032 +
  1.1033 +\vspace{0.3cm}
  1.1034 +
  1.1035 + \noindent {\bf Return Type:} 
  1.1036 +{\tt 
  1.1037 +string
  1.1038 +}
  1.1039 +
  1.1040 +
  1.1041 +value of the field
  1.1042 +\vspace{0.3cm}
  1.1043 +\vspace{0.3cm}
  1.1044 +\vspace{0.3cm}
  1.1045 +\subsubsection{RPC name:~get\_io\_read\_kbs}
  1.1046 +
  1.1047 +{\bf Overview:} 
  1.1048 +Get the io/read\_kbs field of the given VBD\_metrics.
  1.1049 +
  1.1050 + \noindent {\bf Signature:} 
  1.1051 +\begin{verbatim} float get_io_read_kbs (session_id s, VBD_metrics ref self)\end{verbatim}
  1.1052 +
  1.1053 +
  1.1054 +\noindent{\bf Arguments:}
  1.1055 +
  1.1056 + 
  1.1057 +\vspace{0.3cm}
  1.1058 +\begin{tabular}{|c|c|p{7cm}|}
  1.1059 + \hline
  1.1060 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1061 +{\tt VBD\_metrics ref } & self & reference to the object \\ \hline 
  1.1062 +
  1.1063 +\end{tabular}
  1.1064 +
  1.1065 +\vspace{0.3cm}
  1.1066 +
  1.1067 + \noindent {\bf Return Type:} 
  1.1068 +{\tt 
  1.1069 +float
  1.1070 +}
  1.1071 +
  1.1072 +
  1.1073 +value of the field
  1.1074 +\vspace{0.3cm}
  1.1075 +\vspace{0.3cm}
  1.1076 +\vspace{0.3cm}
  1.1077 +\subsubsection{RPC name:~get\_io\_write\_kbs}
  1.1078 +
  1.1079 +{\bf Overview:} 
  1.1080 +Get the io/write\_kbs field of the given VBD\_metrics.
  1.1081 +
  1.1082 + \noindent {\bf Signature:} 
  1.1083 +\begin{verbatim} float get_io_write_kbs (session_id s, VBD_metrics ref self)\end{verbatim}
  1.1084 +
  1.1085 +
  1.1086 +\noindent{\bf Arguments:}
  1.1087 +
  1.1088 + 
  1.1089 +\vspace{0.3cm}
  1.1090 +\begin{tabular}{|c|c|p{7cm}|}
  1.1091 + \hline
  1.1092 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1093 +{\tt VBD\_metrics ref } & self & reference to the object \\ \hline 
  1.1094 +
  1.1095 +\end{tabular}
  1.1096 +
  1.1097 +\vspace{0.3cm}
  1.1098 +
  1.1099 + \noindent {\bf Return Type:} 
  1.1100 +{\tt 
  1.1101 +float
  1.1102 +}
  1.1103 +
  1.1104 +
  1.1105 +value of the field
  1.1106 +\vspace{0.3cm}
  1.1107 +\vspace{0.3cm}
  1.1108 +\vspace{0.3cm}
  1.1109 +\subsubsection{RPC name:~get\_by\_uuid}
  1.1110 +
  1.1111 +{\bf Overview:} 
  1.1112 +Get a reference to the VBD\_metrics instance with the specified UUID.
  1.1113 +
  1.1114 + \noindent {\bf Signature:} 
  1.1115 +\begin{verbatim} (VBD_metrics ref) get_by_uuid (session_id s, string uuid)\end{verbatim}
  1.1116 +
  1.1117 +
  1.1118 +\noindent{\bf Arguments:}
  1.1119 +
  1.1120 + 
  1.1121 +\vspace{0.3cm}
  1.1122 +\begin{tabular}{|c|c|p{7cm}|}
  1.1123 + \hline
  1.1124 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1125 +{\tt string } & uuid & UUID of object to return \\ \hline 
  1.1126 +
  1.1127 +\end{tabular}
  1.1128 +
  1.1129 +\vspace{0.3cm}
  1.1130 +
  1.1131 + \noindent {\bf Return Type:} 
  1.1132 +{\tt 
  1.1133 +VBD\_metrics ref
  1.1134 +}
  1.1135 +
  1.1136 +
  1.1137 +reference to the object
  1.1138 +\vspace{0.3cm}
  1.1139 +\vspace{0.3cm}
  1.1140 +\vspace{0.3cm}
  1.1141 +\subsubsection{RPC name:~get\_record}
  1.1142 +
  1.1143 +{\bf Overview:} 
  1.1144 +Get a record containing the current state of the given VBD\_metrics.
  1.1145 +
  1.1146 + \noindent {\bf Signature:} 
  1.1147 +\begin{verbatim} (VBD_metrics record) get_record (session_id s, VBD_metrics ref self)\end{verbatim}
  1.1148 +
  1.1149 +
  1.1150 +\noindent{\bf Arguments:}
  1.1151 +
  1.1152 + 
  1.1153 +\vspace{0.3cm}
  1.1154 +\begin{tabular}{|c|c|p{7cm}|}
  1.1155 + \hline
  1.1156 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1157 +{\tt VBD\_metrics ref } & self & reference to the object \\ \hline 
  1.1158 +
  1.1159 +\end{tabular}
  1.1160 +
  1.1161 +\vspace{0.3cm}
  1.1162 +
  1.1163 + \noindent {\bf Return Type:} 
  1.1164 +{\tt 
  1.1165 +VBD\_metrics record
  1.1166 +}
  1.1167 +
  1.1168 +
  1.1169 +all fields from the object
  1.1170 +\vspace{0.3cm}
  1.1171 +\vspace{0.3cm}
  1.1172 +\vspace{0.3cm}
  1.1173 +
  1.1174 +\vspace{1cm}
  1.1175 +\newpage
  1.1176  \section{Class: PBD}
  1.1177  \subsection{Fields for class: PBD}
  1.1178  \begin{longtable}{|lllp{0.38\textwidth}|}
  1.1179 @@ -10985,8 +11562,9 @@ Quals & Field & Type & Description \\
  1.1180  \hline
  1.1181  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
  1.1182  $\mathit{RO}_\mathit{run}$ &  {\tt protocol} & console\_protocol & the protocol used by this console \\
  1.1183 -$\mathit{RO}_\mathit{run}$ &  {\tt uri} & string & URI for the console service \\
  1.1184 +$\mathit{RO}_\mathit{run}$ &  {\tt location} & string & URI for the console service \\
  1.1185  $\mathit{RO}_\mathit{run}$ &  {\tt VM} & VM ref & VM to which this console is attached \\
  1.1186 +$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
  1.1187  \hline
  1.1188  \end{longtable}
  1.1189  \subsection{Additional RPCs associated with class: console}
  1.1190 @@ -11054,13 +11632,13 @@ value of the field
  1.1191  \vspace{0.3cm}
  1.1192  \vspace{0.3cm}
  1.1193  \vspace{0.3cm}
  1.1194 -\subsubsection{RPC name:~get\_uri}
  1.1195 -
  1.1196 -{\bf Overview:} 
  1.1197 -Get the uri field of the given console.
  1.1198 -
  1.1199 - \noindent {\bf Signature:} 
  1.1200 -\begin{verbatim} string get_uri (session_id s, console ref self)\end{verbatim}
  1.1201 +\subsubsection{RPC name:~get\_location}
  1.1202 +
  1.1203 +{\bf Overview:} 
  1.1204 +Get the location field of the given console.
  1.1205 +
  1.1206 + \noindent {\bf Signature:} 
  1.1207 +\begin{verbatim} string get_location (session_id s, console ref self)\end{verbatim}
  1.1208  
  1.1209  
  1.1210  \noindent{\bf Arguments:}
  1.1211 @@ -11118,6 +11696,145 @@ value of the field
  1.1212  \vspace{0.3cm}
  1.1213  \vspace{0.3cm}
  1.1214  \vspace{0.3cm}
  1.1215 +\subsubsection{RPC name:~get\_other\_config}
  1.1216 +
  1.1217 +{\bf Overview:} 
  1.1218 +Get the other\_config field of the given console.
  1.1219 +
  1.1220 + \noindent {\bf Signature:} 
  1.1221 +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, console ref self)\end{verbatim}
  1.1222 +
  1.1223 +
  1.1224 +\noindent{\bf Arguments:}
  1.1225 +
  1.1226 + 
  1.1227 +\vspace{0.3cm}
  1.1228 +\begin{tabular}{|c|c|p{7cm}|}
  1.1229 + \hline
  1.1230 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1231 +{\tt console ref } & self & reference to the object \\ \hline 
  1.1232 +
  1.1233 +\end{tabular}
  1.1234 +
  1.1235 +\vspace{0.3cm}
  1.1236 +
  1.1237 + \noindent {\bf Return Type:} 
  1.1238 +{\tt 
  1.1239 +(string $\rightarrow$ string) Map
  1.1240 +}
  1.1241 +
  1.1242 +
  1.1243 +value of the field
  1.1244 +\vspace{0.3cm}
  1.1245 +\vspace{0.3cm}
  1.1246 +\vspace{0.3cm}
  1.1247 +\subsubsection{RPC name:~set\_other\_config}
  1.1248 +
  1.1249 +{\bf Overview:} 
  1.1250 +Set the other\_config field of the given console.
  1.1251 +
  1.1252 + \noindent {\bf Signature:} 
  1.1253 +\begin{verbatim} void set_other_config (session_id s, console ref self, (string -> string) Map value)\end{verbatim}
  1.1254 +
  1.1255 +
  1.1256 +\noindent{\bf Arguments:}
  1.1257 +
  1.1258 + 
  1.1259 +\vspace{0.3cm}
  1.1260 +\begin{tabular}{|c|c|p{7cm}|}
  1.1261 + \hline
  1.1262 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1263 +{\tt console ref } & self & reference to the object \\ \hline 
  1.1264 +
  1.1265 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
  1.1266 +
  1.1267 +\end{tabular}
  1.1268 +
  1.1269 +\vspace{0.3cm}
  1.1270 +
  1.1271 + \noindent {\bf Return Type:} 
  1.1272 +{\tt 
  1.1273 +void
  1.1274 +}
  1.1275 +
  1.1276 +
  1.1277 +
  1.1278 +\vspace{0.3cm}
  1.1279 +\vspace{0.3cm}
  1.1280 +\vspace{0.3cm}
  1.1281 +\subsubsection{RPC name:~add\_to\_other\_config}
  1.1282 +
  1.1283 +{\bf Overview:} 
  1.1284 +Add the given key-value pair to the other\_config field of the given
  1.1285 +console.
  1.1286 +
  1.1287 + \noindent {\bf Signature:} 
  1.1288 +\begin{verbatim} void add_to_other_config (session_id s, console ref self, string key, string value)\end{verbatim}
  1.1289 +
  1.1290 +
  1.1291 +\noindent{\bf Arguments:}
  1.1292 +
  1.1293 + 
  1.1294 +\vspace{0.3cm}
  1.1295 +\begin{tabular}{|c|c|p{7cm}|}
  1.1296 + \hline
  1.1297 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1298 +{\tt console ref } & self & reference to the object \\ \hline 
  1.1299 +
  1.1300 +{\tt string } & key & Key to add \\ \hline 
  1.1301 +
  1.1302 +{\tt string } & value & Value to add \\ \hline 
  1.1303 +
  1.1304 +\end{tabular}
  1.1305 +
  1.1306 +\vspace{0.3cm}
  1.1307 +
  1.1308 + \noindent {\bf Return Type:} 
  1.1309 +{\tt 
  1.1310 +void
  1.1311 +}
  1.1312 +
  1.1313 +
  1.1314 +
  1.1315 +\vspace{0.3cm}
  1.1316 +\vspace{0.3cm}
  1.1317 +\vspace{0.3cm}
  1.1318 +\subsubsection{RPC name:~remove\_from\_other\_config}
  1.1319 +
  1.1320 +{\bf Overview:} 
  1.1321 +Remove the given key and its corresponding value from the other\_config
  1.1322 +field of the given console.  If the key is not in that Map, then do
  1.1323 +nothing.
  1.1324 +
  1.1325 + \noindent {\bf Signature:} 
  1.1326 +\begin{verbatim} void remove_from_other_config (session_id s, console ref self, string key)\end{verbatim}
  1.1327 +
  1.1328 +
  1.1329 +\noindent{\bf Arguments:}
  1.1330 +
  1.1331 + 
  1.1332 +\vspace{0.3cm}
  1.1333 +\begin{tabular}{|c|c|p{7cm}|}
  1.1334 + \hline
  1.1335 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  1.1336 +{\tt console ref } & self & reference to the object \\ \hline 
  1.1337 +
  1.1338 +{\tt string } & key & Key to remove \\ \hline 
  1.1339 +
  1.1340 +\end{tabular}
  1.1341 +
  1.1342 +\vspace{0.3cm}
  1.1343 +
  1.1344 + \noindent {\bf Return Type:} 
  1.1345 +{\tt 
  1.1346 +void
  1.1347 +}
  1.1348 +
  1.1349 +
  1.1350 +
  1.1351 +\vspace{0.3cm}
  1.1352 +\vspace{0.3cm}
  1.1353 +\vspace{0.3cm}
  1.1354  \subsubsection{RPC name:~create}
  1.1355  
  1.1356  {\bf Overview:} 
  1.1357 @@ -11767,34 +12484,15 @@ Each possible error code is documented i
  1.1358  
  1.1359  \subsection{Error Codes}
  1.1360  
  1.1361 -\subsubsection{HOST\_CPU\_HANDLE\_INVALID}
  1.1362 -
  1.1363 -You gave an invalid host\_cpu handle.  The host\_cpu may have recently been
  1.1364 -deleted.  The handle parameter echoes the bad value given.
  1.1365 +\subsubsection{HANDLE\_INVALID}
  1.1366 +
  1.1367 +You gave an invalid handle.  The object may have recently been deleted. 
  1.1368 +The class parameter gives the type of reference given, and the handle
  1.1369 +parameter echoes the bad value given.
  1.1370  
  1.1371  \vspace{0.3cm}
  1.1372  {\bf Signature:}
  1.1373 -\begin{verbatim}HOST_CPU_HANDLE_INVALID(handle)\end{verbatim}
  1.1374 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1375 -
  1.1376 -\subsubsection{HOST\_HANDLE\_INVALID}
  1.1377 -
  1.1378 -You gave an invalid host handle.  The host may have recently been deleted. 
  1.1379 -The handle parameter echoes the bad value given.
  1.1380 -
  1.1381 -\vspace{0.3cm}
  1.1382 -{\bf Signature:}
  1.1383 -\begin{verbatim}HOST_HANDLE_INVALID(handle)\end{verbatim}
  1.1384 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1385 -
  1.1386 -\subsubsection{HOST\_METRICS\_HANDLE\_INVALID}
  1.1387 -
  1.1388 -You gave an invalid host\_metrics handle.  The host\_metrics may have
  1.1389 -recently been deleted.  The handle parameter echoes the bad value given.
  1.1390 -
  1.1391 -\vspace{0.3cm}
  1.1392 -{\bf Signature:}
  1.1393 -\begin{verbatim}HOST_METRICS_HANDLE_INVALID(handle)\end{verbatim}
  1.1394 +\begin{verbatim}HANDLE_INVALID(class, handle)\end{verbatim}
  1.1395  \begin{center}\rule{10em}{0.1pt}\end{center}
  1.1396  
  1.1397  \subsubsection{INTERNAL\_ERROR}
  1.1398 @@ -11854,18 +12552,7 @@ already attached to some other PIF, and 
  1.1399  You attempted an operation that was not allowed.
  1.1400  
  1.1401  \vspace{0.3cm}
  1.1402 -{\bf Signature:}
  1.1403 -\begin{verbatim}OPERATION_NOT_ALLOWED()\end{verbatim}
  1.1404 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1405 -
  1.1406 -\subsubsection{PIF\_HANDLE\_INVALID}
  1.1407 -
  1.1408 -You gave an invalid PIF handle.  The PIF may have recently been deleted. 
  1.1409 -The handle parameter echoes the bad value given.
  1.1410 -
  1.1411 -\vspace{0.3cm}
  1.1412 -{\bf Signature:}
  1.1413 -\begin{verbatim}PIF_HANDLE_INVALID(handle)\end{verbatim}
  1.1414 +No parameters.
  1.1415  \begin{center}\rule{10em}{0.1pt}\end{center}
  1.1416  
  1.1417  \subsubsection{PIF\_IS\_PHYSICAL}
  1.1418 @@ -11879,16 +12566,6 @@ PIF handle you gave.
  1.1419  \begin{verbatim}PIF_IS_PHYSICAL(PIF)\end{verbatim}
  1.1420  \begin{center}\rule{10em}{0.1pt}\end{center}
  1.1421  
  1.1422 -\subsubsection{PIF\_METRICS\_HANDLE\_INVALID}
  1.1423 -
  1.1424 -You gave an invalid PIF\_metrics handle.  The PIF\_metrics may have
  1.1425 -recently been deleted.  The handle parameter echoes the bad value given.
  1.1426 -
  1.1427 -\vspace{0.3cm}
  1.1428 -{\bf Signature:}
  1.1429 -\begin{verbatim}PIF_METRICS_HANDLE_INVALID(handle)\end{verbatim}
  1.1430 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1431 -
  1.1432  \subsubsection{SESSION\_AUTHENTICATION\_FAILED}
  1.1433  
  1.1434  The credentials given by the user are incorrect, so access has been denied,
  1.1435 @@ -11910,26 +12587,6 @@ current connection.  The handle paramete
  1.1436  \begin{verbatim}SESSION_INVALID(handle)\end{verbatim}
  1.1437  \begin{center}\rule{10em}{0.1pt}\end{center}
  1.1438  
  1.1439 -\subsubsection{SR\_HANDLE\_INVALID}
  1.1440 -
  1.1441 -You gave an invalid SR handle.  The SR may have recently been deleted.  The
  1.1442 -handle parameter echoes the bad value given.
  1.1443 -
  1.1444 -\vspace{0.3cm}
  1.1445 -{\bf Signature:}
  1.1446 -\begin{verbatim}SR_HANDLE_INVALID(handle)\end{verbatim}
  1.1447 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1448 -
  1.1449 -\subsubsection{TASK\_HANDLE\_INVALID}
  1.1450 -
  1.1451 -You gave an invalid task handle.  The task may have recently been deleted. 
  1.1452 -The handle parameter echoes the bad value given.
  1.1453 -
  1.1454 -\vspace{0.3cm}
  1.1455 -{\bf Signature:}
  1.1456 -\begin{verbatim}TASK_HANDLE_INVALID(handle)\end{verbatim}
  1.1457 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1458 -
  1.1459  \subsubsection{VALUE\_NOT\_SUPPORTED}
  1.1460  
  1.1461  You attempted to set a value that is not supported by this implementation. 
  1.1462 @@ -11941,36 +12598,6 @@ returned.  Also returned is a developer-
  1.1463  \begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim}
  1.1464  \begin{center}\rule{10em}{0.1pt}\end{center}
  1.1465  
  1.1466 -\subsubsection{VBD\_HANDLE\_INVALID}
  1.1467 -
  1.1468 -You gave an invalid VBD handle.  The VBD may have recently been deleted. 
  1.1469 -The handle parameter echoes the bad value given.
  1.1470 -
  1.1471 -\vspace{0.3cm}
  1.1472 -{\bf Signature:}
  1.1473 -\begin{verbatim}VBD_HANDLE_INVALID(handle)\end{verbatim}
  1.1474 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1475 -
  1.1476 -\subsubsection{VDI\_HANDLE\_INVALID}
  1.1477 -
  1.1478 -You gave an invalid VDI handle.  The VDI may have recently been deleted. 
  1.1479 -The handle parameter echoes the bad value given.
  1.1480 -
  1.1481 -\vspace{0.3cm}
  1.1482 -{\bf Signature:}
  1.1483 -\begin{verbatim}VDI_HANDLE_INVALID(handle)\end{verbatim}
  1.1484 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1485 -
  1.1486 -\subsubsection{VIF\_HANDLE\_INVALID}
  1.1487 -
  1.1488 -You gave an invalid VIF handle.  The VIF may have recently been deleted. 
  1.1489 -The handle parameter echoes the bad value given.
  1.1490 -
  1.1491 -\vspace{0.3cm}
  1.1492 -{\bf Signature:}
  1.1493 -\begin{verbatim}VIF_HANDLE_INVALID(handle)\end{verbatim}
  1.1494 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1495 -
  1.1496  \subsubsection{VLAN\_TAG\_INVALID}
  1.1497  
  1.1498  You tried to create a VLAN, but the tag you gave was invalid -- it mmust be
  1.1499 @@ -11993,36 +12620,6 @@ expected and actual VM state at the time
  1.1500  \begin{verbatim}VM_BAD_POWER_STATE(vm, expected, actual)\end{verbatim}
  1.1501  \begin{center}\rule{10em}{0.1pt}\end{center}
  1.1502  
  1.1503 -\subsubsection{VM\_HANDLE\_INVALID}
  1.1504 -
  1.1505 -You gave an invalid VM handle.  The VM may have recently been deleted.  The
  1.1506 -handle parameter echoes the bad value given.
  1.1507 -
  1.1508 -\vspace{0.3cm}
  1.1509 -{\bf Signature:}
  1.1510 -\begin{verbatim}VM_HANDLE_INVALID(handle)\end{verbatim}
  1.1511 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1512 -
  1.1513 -\subsubsection{VM\_METRICS\_HANDLE\_INVALID}
  1.1514 -
  1.1515 -You gave an invalid VM\_metrics handle.  The VM\_metrics may have recently
  1.1516 -been deleted.  The handle parameter echoes the bad value given.
  1.1517 -
  1.1518 -\vspace{0.3cm}
  1.1519 -{\bf Signature:}
  1.1520 -\begin{verbatim}VM_METRICS_HANDLE_INVALID(handle)\end{verbatim}
  1.1521 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1522 -
  1.1523 -\subsubsection{VTPM\_HANDLE\_INVALID}
  1.1524 -
  1.1525 -You gave an invalid VTPM handle.  The VTPM may have recently been deleted. 
  1.1526 -The handle parameter echoes the bad value given.
  1.1527 -
  1.1528 -\vspace{0.3cm}
  1.1529 -{\bf Signature:}
  1.1530 -\begin{verbatim}VTPM_HANDLE_INVALID(handle)\end{verbatim}
  1.1531 -\begin{center}\rule{10em}{0.1pt}\end{center}
  1.1532 -
  1.1533  
  1.1534  
  1.1535  \newpage
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Thu Feb 22 09:42:13 2007 -0700
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Thu Feb 22 10:15:29 2007 -0700
     2.3 @@ -491,6 +491,11 @@ static void dispatch_rw_block_io(blkif_t
     2.4  	for (i = 0; i < nbio; i++)
     2.5  		submit_bio(operation, biolist[i]);
     2.6  
     2.7 +	if (operation == READ)
     2.8 +		blkif->st_rd_sect += preq.nr_sects;
     2.9 +	else if (operation == WRITE)
    2.10 +		blkif->st_wr_sect += preq.nr_sects;
    2.11 +
    2.12  	return;
    2.13  
    2.14   fail_put_bio:
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Thu Feb 22 09:42:13 2007 -0700
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Thu Feb 22 10:15:29 2007 -0700
     3.3 @@ -88,6 +88,8 @@ typedef struct blkif_st {
     3.4  	int                 st_wr_req;
     3.5  	int                 st_oo_req;
     3.6  	int                 st_br_req;
     3.7 +	int                 st_rd_sect;
     3.8 +	int                 st_wr_sect;
     3.9  
    3.10  	wait_queue_head_t waiting_to_free;
    3.11  
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Thu Feb 22 09:42:13 2007 -0700
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Thu Feb 22 10:15:29 2007 -0700
     4.3 @@ -111,16 +111,20 @@ static void update_blkif_status(blkif_t 
     4.4  	}								\
     4.5  	DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
     4.6  
     4.7 -VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
     4.8 -VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
     4.9 -VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
    4.10 -VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
    4.11 +VBD_SHOW(oo_req,  "%d\n", be->blkif->st_oo_req);
    4.12 +VBD_SHOW(rd_req,  "%d\n", be->blkif->st_rd_req);
    4.13 +VBD_SHOW(wr_req,  "%d\n", be->blkif->st_wr_req);
    4.14 +VBD_SHOW(br_req,  "%d\n", be->blkif->st_br_req);
    4.15 +VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
    4.16 +VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
    4.17  
    4.18  static struct attribute *vbdstat_attrs[] = {
    4.19  	&dev_attr_oo_req.attr,
    4.20  	&dev_attr_rd_req.attr,
    4.21  	&dev_attr_wr_req.attr,
    4.22  	&dev_attr_br_req.attr,
    4.23 +	&dev_attr_rd_sect.attr,
    4.24 +	&dev_attr_wr_sect.attr,
    4.25  	NULL
    4.26  };
    4.27  
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Thu Feb 22 09:42:13 2007 -0700
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Thu Feb 22 10:15:29 2007 -0700
     5.3 @@ -1195,7 +1195,7 @@ static void dispatch_rw_block_io(blkif_t
     5.4  	int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
     5.5  	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
     5.6  	unsigned int nseg;
     5.7 -	int ret, i;
     5.8 +	int ret, i, nr_sects = 0;
     5.9  	tap_blkif_t *info;
    5.10  	uint64_t sector;
    5.11  	blkif_request_t *target;
    5.12 @@ -1291,6 +1291,9 @@ static void dispatch_rw_block_io(blkif_t
    5.13  					  req->seg[i].gref, blkif->domid);
    5.14  			op++;
    5.15  		}
    5.16 +
    5.17 +		nr_sects += (req->seg[i].last_sect - 
    5.18 +			     req->seg[i].first_sect + 1);
    5.19  	}
    5.20  
    5.21  	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
    5.22 @@ -1403,6 +1406,12 @@ static void dispatch_rw_block_io(blkif_t
    5.23  	target->id = usr_idx;
    5.24  	wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
    5.25  	info->ufe_ring.req_prod_pvt++;
    5.26 +
    5.27 +	if (operation == READ)
    5.28 +		blkif->st_rd_sect += nr_sects;
    5.29 +	else if (operation == WRITE)
    5.30 +		blkif->st_wr_sect += nr_sects;
    5.31 +
    5.32  	return;
    5.33  
    5.34   fail_flush:
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Thu Feb 22 09:42:13 2007 -0700
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Thu Feb 22 10:15:29 2007 -0700
     6.3 @@ -76,6 +76,8 @@ typedef struct blkif_st {
     6.4  	int                 st_rd_req;
     6.5  	int                 st_wr_req;
     6.6  	int                 st_oo_req;
     6.7 +	int                 st_rd_sect;
     6.8 +	int                 st_wr_sect;
     6.9  
    6.10  	wait_queue_head_t waiting_to_free;
    6.11  
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Thu Feb 22 09:42:13 2007 -0700
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Thu Feb 22 10:15:29 2007 -0700
     7.3 @@ -47,6 +47,7 @@ struct backend_info
     7.4  	blkif_t *blkif;
     7.5  	struct xenbus_watch backend_watch;
     7.6  	int xenbus_id;
     7.7 +	int group_added;
     7.8  };
     7.9  
    7.10  
    7.11 @@ -112,6 +113,80 @@ static int blktap_name(blkif_t *blkif, c
    7.12  	return 0;
    7.13  }
    7.14  
    7.15 +/****************************************************************
    7.16 + *  sysfs interface for VBD I/O requests
    7.17 + */
    7.18 +
    7.19 +#define VBD_SHOW(name, format, args...)					\
    7.20 +	static ssize_t show_##name(struct device *_dev,			\
    7.21 +				   struct device_attribute *attr,	\
    7.22 +				   char *buf)				\
    7.23 +	{								\
    7.24 +		struct xenbus_device *dev = to_xenbus_device(_dev);	\
    7.25 +		struct backend_info *be = dev->dev.driver_data;		\
    7.26 +									\
    7.27 +		return sprintf(buf, format, ##args);			\
    7.28 +	}								\
    7.29 +	DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
    7.30 +
    7.31 +VBD_SHOW(tap_oo_req,  "%d\n", be->blkif->st_oo_req);
    7.32 +VBD_SHOW(tap_rd_req,  "%d\n", be->blkif->st_rd_req);
    7.33 +VBD_SHOW(tap_wr_req,  "%d\n", be->blkif->st_wr_req);
    7.34 +VBD_SHOW(tap_rd_sect, "%d\n", be->blkif->st_rd_sect);
    7.35 +VBD_SHOW(tap_wr_sect, "%d\n", be->blkif->st_wr_sect);
    7.36 +
    7.37 +static struct attribute *tapstat_attrs[] = {
    7.38 +	&dev_attr_tap_oo_req.attr,
    7.39 +	&dev_attr_tap_rd_req.attr,
    7.40 +	&dev_attr_tap_wr_req.attr,
    7.41 +	&dev_attr_tap_rd_sect.attr,
    7.42 +	&dev_attr_tap_wr_sect.attr,
    7.43 +	NULL
    7.44 +};
    7.45 +
    7.46 +static struct attribute_group tapstat_group = {
    7.47 +	.name = "statistics",
    7.48 +	.attrs = tapstat_attrs,
    7.49 +};
    7.50 +
    7.51 +int xentap_sysfs_addif(struct xenbus_device *dev)
    7.52 +{
    7.53 +	int err;
    7.54 +	struct backend_info *be = dev->dev.driver_data;
    7.55 +	err = sysfs_create_group(&dev->dev.kobj, &tapstat_group);
    7.56 +	if (!err)
    7.57 +		be->group_added = 1;
    7.58 +	return err;
    7.59 +}
    7.60 +
    7.61 +void xentap_sysfs_delif(struct xenbus_device *dev)
    7.62 +{
    7.63 +	sysfs_remove_group(&dev->dev.kobj, &tapstat_group);
    7.64 +}
    7.65 +
    7.66 +static int blktap_remove(struct xenbus_device *dev)
    7.67 +{
    7.68 +	struct backend_info *be = dev->dev.driver_data;
    7.69 +
    7.70 +	if (be->backend_watch.node) {
    7.71 +		unregister_xenbus_watch(&be->backend_watch);
    7.72 +		kfree(be->backend_watch.node);
    7.73 +		be->backend_watch.node = NULL;
    7.74 +	}
    7.75 +	if (be->blkif) {
    7.76 +		if (be->blkif->xenblkd)
    7.77 +			kthread_stop(be->blkif->xenblkd);
    7.78 +		signal_tapdisk(be->blkif->dev_num);
    7.79 +		tap_blkif_free(be->blkif);
    7.80 +		be->blkif = NULL;
    7.81 +	}
    7.82 +	if (be->group_added)
    7.83 +		xentap_sysfs_delif(be->dev);
    7.84 +	kfree(be);
    7.85 +	dev->dev.driver_data = NULL;
    7.86 +	return 0;
    7.87 +}
    7.88 +
    7.89  static void tap_update_blkif_status(blkif_t *blkif)
    7.90  { 
    7.91  	int err;
    7.92 @@ -137,6 +212,13 @@ static void tap_update_blkif_status(blki
    7.93  		return;
    7.94  	}
    7.95  
    7.96 +	err = xentap_sysfs_addif(blkif->be->dev);
    7.97 +	if (err) {
    7.98 +		xenbus_dev_fatal(blkif->be->dev, err, 
    7.99 +				 "creating sysfs entries");
   7.100 +		return;
   7.101 +	}
   7.102 +
   7.103  	blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name);
   7.104  	if (IS_ERR(blkif->xenblkd)) {
   7.105  		err = PTR_ERR(blkif->xenblkd);
   7.106 @@ -146,27 +228,6 @@ static void tap_update_blkif_status(blki
   7.107  	}
   7.108  }
   7.109  
   7.110 -static int blktap_remove(struct xenbus_device *dev)
   7.111 -{
   7.112 -	struct backend_info *be = dev->dev.driver_data;
   7.113 -
   7.114 -	if (be->backend_watch.node) {
   7.115 -		unregister_xenbus_watch(&be->backend_watch);
   7.116 -		kfree(be->backend_watch.node);
   7.117 -		be->backend_watch.node = NULL;
   7.118 -	}
   7.119 -	if (be->blkif) {
   7.120 -		if (be->blkif->xenblkd)
   7.121 -			kthread_stop(be->blkif->xenblkd);
   7.122 -		signal_tapdisk(be->blkif->dev_num);
   7.123 -		tap_blkif_free(be->blkif);
   7.124 -		be->blkif = NULL;
   7.125 -	}
   7.126 -	kfree(be);
   7.127 -	dev->dev.driver_data = NULL;
   7.128 -	return 0;
   7.129 -}
   7.130 -
   7.131  /**
   7.132   * Entry point to this code when a new device is created.  Allocate
   7.133   * the basic structures, and watch the store waiting for the
     8.1 --- a/tools/libfsimage/Makefile	Thu Feb 22 09:42:13 2007 -0700
     8.2 +++ b/tools/libfsimage/Makefile	Thu Feb 22 10:15:29 2007 -0700
     8.3 @@ -1,7 +1,7 @@
     8.4  XEN_ROOT = ../..
     8.5  include $(XEN_ROOT)/tools/Rules.mk
     8.6  
     8.7 -SUBDIRS-y = common ufs reiserfs
     8.8 +SUBDIRS-y = common ufs reiserfs iso9660 fat
     8.9  SUBDIRS-y += $(shell ./check-libext2fs)
    8.10  
    8.11  .PHONY: all
     9.1 --- a/tools/libfsimage/common/fsimage_grub.c	Thu Feb 22 09:42:13 2007 -0700
     9.2 +++ b/tools/libfsimage/common/fsimage_grub.c	Thu Feb 22 10:15:29 2007 -0700
     9.3 @@ -122,6 +122,84 @@ fsig_disk_read_junk(void)
     9.4  	return (&disk_read_junk);
     9.5  }
     9.6  
     9.7 +#if defined(__i386__) || defined(__x86_64__)
     9.8 +
     9.9 +#ifdef __amd64
    9.10 +#define BSF "bsfq"
    9.11 +#else
    9.12 +#define BSF "bsfl"
    9.13 +#endif
    9.14 +unsigned long
    9.15 +fsig_log2 (unsigned long word)
    9.16 +{
    9.17 +  __asm__ (BSF " %1,%0"
    9.18 +	   : "=r" (word)
    9.19 +	   : "r" (word));
    9.20 +  return word;
    9.21 +}
    9.22 +
    9.23 +#elif defined(__ia64__)
    9.24 +
    9.25 +#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
    9.26 +# define ia64_popcnt(x) __builtin_popcountl(x)
    9.27 +#else
    9.28 +# define ia64_popcnt(x)                                     \
    9.29 +  ({                                                        \
    9.30 +    __u64 ia64_intri_res;                                   \
    9.31 +    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
    9.32 +    ia64_intri_res;                                         \
    9.33 +  })
    9.34 +#endif
    9.35 +
    9.36 +unsigned long
    9.37 +fsig_log2 (unsigned long word)
    9.38 +{
    9.39 +  unsigned long result;
    9.40 +
    9.41 +  result = ia64_popcnt((word - 1) & ~word);
    9.42 +  return result;
    9.43 +}
    9.44 +
    9.45 +#elif defined(__powerpc__)
    9.46 +
    9.47 +#ifdef __powerpc64__
    9.48 +#define PPC_CNTLZL "cntlzd"
    9.49 +#else
    9.50 +#define PPC_CNTLZL "cntlzw"
    9.51 +#endif
    9.52 +#define BITS_PER_LONG (sizeof(long) * 8)
    9.53 +
    9.54 +static int
    9.55 +__ilog2(unsigned long x)
    9.56 +{
    9.57 +  int lz;
    9.58 +
    9.59 +  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
    9.60 +  return BITS_PER_LONG - 1 - lz;
    9.61 +}
    9.62 +
    9.63 +unsigned long
    9.64 +fsig_log2 (unsigned long word)
    9.65 +{
    9.66 +  return __ilog2(word & -word);
    9.67 +}
    9.68 +
    9.69 +#else /* Unoptimized */
    9.70 +
    9.71 +unsigned long
    9.72 +fsig_log2 (unsigned long word)
    9.73 +{
    9.74 +  unsigned long result = 0;
    9.75 +
    9.76 +  while (!(word & 1UL))
    9.77 +    {
    9.78 +      result++;
    9.79 +      word >>= 1;
    9.80 +    }
    9.81 +  return result;
    9.82 +}
    9.83 +#endif
    9.84 +
    9.85  int
    9.86  fsig_devread(fsi_file_t *ffi, unsigned int sector, unsigned int offset,
    9.87      unsigned int bufsize, char *buf)
    10.1 --- a/tools/libfsimage/common/fsimage_grub.h	Thu Feb 22 09:42:13 2007 -0700
    10.2 +++ b/tools/libfsimage/common/fsimage_grub.h	Thu Feb 22 10:15:29 2007 -0700
    10.3 @@ -57,17 +57,20 @@ typedef struct fsig_plugin_ops {
    10.4  #define	disk_read_func (*fsig_disk_read_junk())
    10.5  #define	disk_read_hook (*fsig_disk_read_junk())
    10.6  #define	print_possibilities 0
    10.7 +#define	noisy_printf
    10.8  
    10.9  #define	grub_memset memset
   10.10  #define	grub_memmove memmove
   10.11 +#define grub_log2 fsig_log2
   10.12  
   10.13  extern char **fsig_disk_read_junk(void);
   10.14 +unsigned long fsig_log2(unsigned long);
   10.15  
   10.16  #define	ERR_FSYS_CORRUPT 1
   10.17 +#define	ERR_OUTSIDE_PART 1
   10.18  #define	ERR_SYMLINK_LOOP 1
   10.19  #define	ERR_FILELENGTH 1
   10.20  #define	ERR_BAD_FILETYPE 1
   10.21 -#define	ERR_BAD_FILETYPE 1
   10.22  #define	ERR_FILE_NOT_FOUND 1
   10.23  
   10.24  fsi_plugin_ops_t *fsig_init(fsi_plugin_t *, fsig_plugin_ops_t *);
    11.1 --- a/tools/libfsimage/common/mapfile-GNU	Thu Feb 22 09:42:13 2007 -0700
    11.2 +++ b/tools/libfsimage/common/mapfile-GNU	Thu Feb 22 10:15:29 2007 -0700
    11.3 @@ -20,6 +20,7 @@ VERSION {
    11.4  			fsig_init;
    11.5  			fsig_devread;
    11.6  			fsig_substring;
    11.7 +			fsig_log2;
    11.8  			fsig_fs_buf;
    11.9  			fsig_file_alloc;
   11.10  			fsig_file_buf;
    12.1 --- a/tools/libfsimage/common/mapfile-SunOS	Thu Feb 22 09:42:13 2007 -0700
    12.2 +++ b/tools/libfsimage/common/mapfile-SunOS	Thu Feb 22 10:15:29 2007 -0700
    12.3 @@ -19,6 +19,7 @@ libfsimage.so.1.0 {
    12.4  		fsig_init;
    12.5  		fsig_devread;
    12.6  		fsig_substring;
    12.7 +		fsig_log2;
    12.8  		fsig_fs_buf;
    12.9  		fsig_file_alloc;
   12.10  		fsig_file_buf;
    13.1 --- a/tools/libfsimage/ext2fs/fsys_ext2fs.c	Thu Feb 22 09:42:13 2007 -0700
    13.2 +++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c	Thu Feb 22 10:15:29 2007 -0700
    13.3 @@ -191,7 +191,7 @@ struct ext2_dir_entry
    13.4  
    13.5  
    13.6  /* ext2/super.c */
    13.7 -#define log2(n) ffz(~(n))
    13.8 +#define log2(n) grub_log2(n)
    13.9  
   13.10  #define EXT2_SUPER_MAGIC      0xEF53	/* include/linux/ext2_fs.h */
   13.11  #define EXT2_ROOT_INO              2	/* include/linux/ext2_fs.h */
   13.12 @@ -232,93 +232,6 @@ struct ext2_dir_entry
   13.13  #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
   13.14  #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
   13.15  
   13.16 -#if defined(__i386__) || defined(__x86_64__)
   13.17 -/* include/asm-i386/bitops.h */
   13.18 -/*
   13.19 - * ffz = Find First Zero in word. Undefined if no zero exists,
   13.20 - * so code should check against ~0UL first..
   13.21 - */
   13.22 -#ifdef __amd64
   13.23 -#define BSF "bsfq"
   13.24 -#else
   13.25 -#define BSF "bsfl"
   13.26 -#endif
   13.27 -static __inline__ unsigned long
   13.28 -ffz (unsigned long word)
   13.29 -{
   13.30 -  __asm__ (BSF " %1,%0"
   13.31 -:	   "=r" (word)
   13.32 -:	   "r" (~word));
   13.33 -  return word;
   13.34 -}
   13.35 -
   13.36 -#elif defined(__ia64__)
   13.37 -
   13.38 -typedef unsigned long __u64;
   13.39 -
   13.40 -#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
   13.41 -# define ia64_popcnt(x) __builtin_popcountl(x)
   13.42 -#else
   13.43 -# define ia64_popcnt(x)                                     \
   13.44 -  ({                                                        \
   13.45 -    __u64 ia64_intri_res;                                   \
   13.46 -    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
   13.47 -    ia64_intri_res;                                         \
   13.48 -  })
   13.49 -#endif
   13.50 -
   13.51 -static __inline__ unsigned long
   13.52 -ffz (unsigned long word)
   13.53 -{
   13.54 -  unsigned long result;
   13.55 -
   13.56 -  result = ia64_popcnt(word & (~word - 1));
   13.57 -  return result;
   13.58 -}
   13.59 -
   13.60 -#elif defined(__powerpc__)
   13.61 -
   13.62 -#ifdef __powerpc64__
   13.63 -#define PPC_CNTLZL "cntlzd"
   13.64 -#else
   13.65 -#define PPC_CNTLZL "cntlzw"
   13.66 -#endif
   13.67 -#define BITS_PER_LONG (sizeof(long) * 8)
   13.68 -
   13.69 -static __inline__ int
   13.70 -__ilog2(unsigned long x)
   13.71 -{
   13.72 -  int lz;
   13.73 -
   13.74 -  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
   13.75 -  return BITS_PER_LONG - 1 - lz;
   13.76 -}
   13.77 -
   13.78 -static __inline__ unsigned long
   13.79 -ffz (unsigned long word)
   13.80 -{
   13.81 -  if ((word = ~word) == 0)
   13.82 -    return BITS_PER_LONG;
   13.83 -  return __ilog2(word & -word);
   13.84 -}
   13.85 -
   13.86 -#else /* Unoptimized */
   13.87 -
   13.88 -static __inline__ unsigned long
   13.89 -ffz (unsigned long word)
   13.90 -{
   13.91 -  unsigned long result;
   13.92 -
   13.93 -  result = 0;
   13.94 -  while(word & 1)
   13.95 -    {
   13.96 -      result++;
   13.97 -      word >>= 1;
   13.98 -    }
   13.99 -  return result;
  13.100 -}
  13.101 -#endif
  13.102 -
  13.103  /* check filesystem types and read superblock into memory buffer */
  13.104  int
  13.105  ext2fs_mount (fsi_file_t *ffi, const char *options)
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/libfsimage/fat/Makefile	Thu Feb 22 10:15:29 2007 -0700
    14.3 @@ -0,0 +1,13 @@
    14.4 +XEN_ROOT = ../../..
    14.5 +
    14.6 +LIB_SRCS-y = fsys_fat.c
    14.7 +
    14.8 +FS = fat
    14.9 +
   14.10 +.PHONY: all
   14.11 +all: fs-all
   14.12 +
   14.13 +.PHONY: install
   14.14 +install: fs-install
   14.15 +
   14.16 +include $(XEN_ROOT)/tools/libfsimage/Rules.mk
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/libfsimage/fat/fat.h	Thu Feb 22 10:15:29 2007 -0700
    15.3 @@ -0,0 +1,100 @@
    15.4 +/*
    15.5 + *  GRUB  --  GRand Unified Bootloader
    15.6 + *  Copyright (C) 2001  Free Software Foundation, Inc.
    15.7 + *
    15.8 + *  This program is free software; you can redistribute it and/or modify
    15.9 + *  it under the terms of the GNU General Public License as published by
   15.10 + *  the Free Software Foundation; either version 2 of the License, or
   15.11 + *  (at your option) any later version.
   15.12 + *
   15.13 + *  This program is distributed in the hope that it will be useful,
   15.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.16 + *  GNU General Public License for more details.
   15.17 + *
   15.18 + *  You should have received a copy of the GNU General Public License
   15.19 + *  along with this program; if not, write to the Free Software
   15.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   15.21 + */
   15.22 +
   15.23 +
   15.24 +/*
   15.25 + *  Defines for the FAT BIOS Parameter Block (embedded in the first block
   15.26 + *  of the partition.
   15.27 + */
   15.28 +
   15.29 +typedef __signed__ char __s8;
   15.30 +typedef unsigned char __u8;
   15.31 +typedef __signed__ short __s16;
   15.32 +typedef unsigned short __u16;
   15.33 +typedef __signed__ int __s32;
   15.34 +typedef unsigned int __u32;
   15.35 +
   15.36 +/* Note that some shorts are not aligned, and must therefore
   15.37 + * be declared as array of two bytes.
   15.38 + */
   15.39 +struct fat_bpb {
   15.40 +	__s8	ignored[3];	/* Boot strap short or near jump */
   15.41 +	__s8	system_id[8];	/* Name - can be used to special case
   15.42 +				   partition manager volumes */
   15.43 +	__u8	bytes_per_sect[2];	/* bytes per logical sector */
   15.44 +	__u8	sects_per_clust;/* sectors/cluster */
   15.45 +	__u8	reserved_sects[2];	/* reserved sectors */
   15.46 +	__u8	num_fats;	/* number of FATs */
   15.47 +	__u8	dir_entries[2];	/* root directory entries */
   15.48 +	__u8	short_sectors[2];	/* number of sectors */
   15.49 +	__u8	media;		/* media code (unused) */
   15.50 +	__u16	fat_length;	/* sectors/FAT */
   15.51 +	__u16	secs_track;	/* sectors per track */
   15.52 +	__u16	heads;		/* number of heads */
   15.53 +	__u32	hidden;		/* hidden sectors (unused) */
   15.54 +	__u32	long_sectors;	/* number of sectors (if short_sectors == 0) */
   15.55 +
   15.56 +	/* The following fields are only used by FAT32 */
   15.57 +	__u32	fat32_length;	/* sectors/FAT */
   15.58 +	__u16	flags;		/* bit 8: fat mirroring, low 4: active fat */
   15.59 +	__u8	version[2];	/* major, minor filesystem version */
   15.60 +	__u32	root_cluster;	/* first cluster in root directory */
   15.61 +	__u16	info_sector;	/* filesystem info sector */
   15.62 +	__u16	backup_boot;	/* backup boot sector */
   15.63 +	__u16	reserved2[6];	/* Unused */
   15.64 +};
   15.65 +
   15.66 +#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
   15.67 +
   15.68 +/*
   15.69 + *  Defines how to differentiate a 12-bit and 16-bit FAT.
   15.70 + */
   15.71 +
   15.72 +#define FAT_MAX_12BIT_CLUST       4087	/* 4085 + 2 */
   15.73 +
   15.74 +/*
   15.75 + *  Defines for the file "attribute" byte
   15.76 + */
   15.77 +
   15.78 +#define FAT_ATTRIB_OK_MASK        0x37
   15.79 +#define FAT_ATTRIB_NOT_OK_MASK    0xC8
   15.80 +#define FAT_ATTRIB_DIR            0x10
   15.81 +#define FAT_ATTRIB_LONGNAME       0x0F
   15.82 +
   15.83 +/*
   15.84 + *  Defines for FAT directory entries
   15.85 + */
   15.86 +
   15.87 +#define FAT_DIRENTRY_LENGTH       32
   15.88 +
   15.89 +#define FAT_DIRENTRY_ATTRIB(entry) \
   15.90 +  (*((unsigned char *) (entry+11)))
   15.91 +#define FAT_DIRENTRY_VALID(entry) \
   15.92 +  ( ((*((unsigned char *) entry)) != 0) \
   15.93 +    && ((*((unsigned char *) entry)) != 0xE5) \
   15.94 +    && !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) )
   15.95 +#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \
   15.96 +  ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16))
   15.97 +#define FAT_DIRENTRY_FILELENGTH(entry) \
   15.98 +  (*((unsigned long *) (entry+28)))
   15.99 +
  15.100 +#define FAT_LONGDIR_ID(entry) \
  15.101 +  (*((unsigned char *) (entry)))
  15.102 +#define FAT_LONGDIR_ALIASCHECKSUM(entry) \
  15.103 +  (*((unsigned char *) (entry+13)))
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/libfsimage/fat/fsys_fat.c	Thu Feb 22 10:15:29 2007 -0700
    16.3 @@ -0,0 +1,485 @@
    16.4 +/*
    16.5 + *  GRUB  --  GRand Unified Bootloader
    16.6 + *  Copyright (C) 2000,2001,2005   Free Software Foundation, Inc.
    16.7 + *
    16.8 + *  This program is free software; you can redistribute it and/or modify
    16.9 + *  it under the terms of the GNU General Public License as published by
   16.10 + *  the Free Software Foundation; either version 2 of the License, or
   16.11 + *  (at your option) any later version.
   16.12 + *
   16.13 + *  This program is distributed in the hope that it will be useful,
   16.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.16 + *  GNU General Public License for more details.
   16.17 + *
   16.18 + *  You should have received a copy of the GNU General Public License
   16.19 + *  along with this program; if not, write to the Free Software
   16.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   16.21 + */
   16.22 +
   16.23 +#include <limits.h>
   16.24 +#include <fsimage_grub.h>
   16.25 +#include "fat.h"
   16.26 +
   16.27 +struct fat_superblock 
   16.28 +{
   16.29 +  int fat_offset;
   16.30 +  int fat_length;
   16.31 +  int fat_size;
   16.32 +  int root_offset;
   16.33 +  int root_max;
   16.34 +  int data_offset;
   16.35 +  
   16.36 +  int num_sectors;
   16.37 +  int num_clust;
   16.38 +  int clust_eof_marker;
   16.39 +  int sects_per_clust;
   16.40 +  int sectsize_bits;
   16.41 +  int clustsize_bits;
   16.42 +  int root_cluster;
   16.43 +  
   16.44 +  int cached_fat;
   16.45 +  int file_cluster;
   16.46 +  int current_cluster_num;
   16.47 +  int current_cluster;
   16.48 +};
   16.49 +
   16.50 +/* pointer(s) into filesystem info buffer for DOS stuff */
   16.51 +#define FAT_SUPER ( (struct fat_superblock *) \
   16.52 + 		    ( FSYS_BUF + 32256) )/* 512 bytes long */
   16.53 +#define FAT_BUF   ( FSYS_BUF + 30208 )	/* 4 sector FAT buffer */
   16.54 +#define NAME_BUF  ( FSYS_BUF + 29184 )	/* Filename buffer (833 bytes) */
   16.55 +
   16.56 +#define FAT_CACHE_SIZE 2048
   16.57 +
   16.58 +#define log2 grub_log2
   16.59 +
   16.60 +int
   16.61 +fat_mount (fsi_file_t *ffi, const char *options)
   16.62 +{
   16.63 +  struct fat_bpb bpb;
   16.64 +  __u32 magic, first_fat;
   16.65 +  
   16.66 +  /* Read bpb */
   16.67 +  if (! devread (ffi, 0, 0, sizeof (bpb), (char *) &bpb))
   16.68 +    return 0;
   16.69 +
   16.70 +  /* Check if the number of sectors per cluster is zero here, to avoid
   16.71 +     zero division.  */
   16.72 +  if (bpb.sects_per_clust == 0)
   16.73 +    return 0;
   16.74 +  
   16.75 +  FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect));
   16.76 +  FAT_SUPER->clustsize_bits
   16.77 +    = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust);
   16.78 +  
   16.79 +  /* Fill in info about super block */
   16.80 +  FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) 
   16.81 +    ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors;
   16.82 +  
   16.83 +  /* FAT offset and length */
   16.84 +  FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects);
   16.85 +  FAT_SUPER->fat_length = 
   16.86 +    bpb.fat_length ? bpb.fat_length : bpb.fat32_length;
   16.87 +  
   16.88 +  /* Rootdir offset and length for FAT12/16 */
   16.89 +  FAT_SUPER->root_offset = 
   16.90 +    FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length;
   16.91 +  FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries);
   16.92 +  
   16.93 +  /* Data offset and number of clusters */
   16.94 +  FAT_SUPER->data_offset = 
   16.95 +    FAT_SUPER->root_offset
   16.96 +    + ((FAT_SUPER->root_max - 1) >> FAT_SUPER->sectsize_bits) + 1;
   16.97 +  FAT_SUPER->num_clust = 
   16.98 +    2 + ((FAT_SUPER->num_sectors - FAT_SUPER->data_offset) 
   16.99 +	 / bpb.sects_per_clust);
  16.100 +  FAT_SUPER->sects_per_clust = bpb.sects_per_clust;
  16.101 +  
  16.102 +  if (!bpb.fat_length)
  16.103 +    {
  16.104 +      /* This is a FAT32 */
  16.105 +      if (FAT_CVT_U16(bpb.dir_entries))
  16.106 + 	return 0;
  16.107 +      
  16.108 +      if (bpb.flags & 0x0080)
  16.109 +	{
  16.110 +	  /* FAT mirroring is disabled, get active FAT */
  16.111 +	  int active_fat = bpb.flags & 0x000f;
  16.112 +	  if (active_fat >= bpb.num_fats)
  16.113 +	    return 0;
  16.114 +	  FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
  16.115 +	}
  16.116 +      
  16.117 +      FAT_SUPER->fat_size = 8;
  16.118 +      FAT_SUPER->root_cluster = bpb.root_cluster;
  16.119 +
  16.120 +      /* Yes the following is correct.  FAT32 should be called FAT28 :) */
  16.121 +      FAT_SUPER->clust_eof_marker = 0xffffff8;
  16.122 +    } 
  16.123 +  else 
  16.124 +    {
  16.125 +      if (!FAT_SUPER->root_max)
  16.126 + 	return 0;
  16.127 +      
  16.128 +      FAT_SUPER->root_cluster = -1;
  16.129 +      if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST) 
  16.130 +	{
  16.131 +	  FAT_SUPER->fat_size = 4;
  16.132 +	  FAT_SUPER->clust_eof_marker = 0xfff8;
  16.133 +	} 
  16.134 +      else
  16.135 +	{
  16.136 +	  FAT_SUPER->fat_size = 3;
  16.137 +	  FAT_SUPER->clust_eof_marker = 0xff8;
  16.138 +	}
  16.139 +    }
  16.140 +
  16.141 +  /* Now do some sanity checks */
  16.142 +  
  16.143 +  if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
  16.144 +      || FAT_CVT_U16(bpb.bytes_per_sect) != SECTOR_SIZE
  16.145 +      || bpb.sects_per_clust != (1 << (FAT_SUPER->clustsize_bits
  16.146 + 				       - FAT_SUPER->sectsize_bits))
  16.147 +      || FAT_SUPER->num_clust <= 2
  16.148 +      || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * SECTOR_SIZE)
  16.149 + 	  > FAT_SUPER->fat_length))
  16.150 +    return 0;
  16.151 +  
  16.152 +  /* kbs: Media check on first FAT entry [ported from PUPA] */
  16.153 +
  16.154 +  if (!devread(ffi, FAT_SUPER->fat_offset, 0,
  16.155 +               sizeof(first_fat), (char *)&first_fat))
  16.156 +    return 0;
  16.157 +
  16.158 +  if (FAT_SUPER->fat_size == 8)
  16.159 +    {
  16.160 +      first_fat &= 0x0fffffff;
  16.161 +      magic = 0x0fffff00;
  16.162 +    }
  16.163 +  else if (FAT_SUPER->fat_size == 4)
  16.164 +    {
  16.165 +      first_fat &= 0x0000ffff;
  16.166 +      magic = 0xff00;
  16.167 +    }
  16.168 +  else
  16.169 +    {
  16.170 +      first_fat &= 0x00000fff;
  16.171 +      magic = 0x0f00;
  16.172 +    }
  16.173 +
  16.174 +  /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
  16.175 +     descriptor, even if it is a so-called superfloppy (e.g. an USB key).
  16.176 +     The check may be too strict for this kind of stupid BIOSes, as
  16.177 +     they overwrite the media descriptor.  */
  16.178 +  if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
  16.179 +    return 0;
  16.180 +
  16.181 +  FAT_SUPER->cached_fat = - 2 * FAT_CACHE_SIZE;
  16.182 +  return 1;
  16.183 +}
  16.184 +
  16.185 +int
  16.186 +fat_read (fsi_file_t *ffi, char *buf, int len)
  16.187 +{
  16.188 +  int logical_clust;
  16.189 +  int offset;
  16.190 +  int ret = 0;
  16.191 +  int size;
  16.192 +  
  16.193 +  if (FAT_SUPER->file_cluster < 0)
  16.194 +    {
  16.195 +      /* root directory for fat16 */
  16.196 +      size = FAT_SUPER->root_max - filepos;
  16.197 +      if (size > len)
  16.198 + 	size = len;
  16.199 +      if (!devread(ffi, FAT_SUPER->root_offset, filepos, size, buf))
  16.200 + 	return 0;
  16.201 +      filepos += size;
  16.202 +      return size;
  16.203 +    }
  16.204 +  
  16.205 +  logical_clust = filepos >> FAT_SUPER->clustsize_bits;
  16.206 +  offset = (filepos & ((1 << FAT_SUPER->clustsize_bits) - 1));
  16.207 +  if (logical_clust < FAT_SUPER->current_cluster_num)
  16.208 +    {
  16.209 +      FAT_SUPER->current_cluster_num = 0;
  16.210 +      FAT_SUPER->current_cluster = FAT_SUPER->file_cluster;
  16.211 +    }
  16.212 +  
  16.213 +  while (len > 0)
  16.214 +    {
  16.215 +      int sector;
  16.216 +      while (logical_clust > FAT_SUPER->current_cluster_num)
  16.217 +	{
  16.218 +	  /* calculate next cluster */
  16.219 +	  int fat_entry = 
  16.220 +	    FAT_SUPER->current_cluster * FAT_SUPER->fat_size;
  16.221 +	  int next_cluster;
  16.222 +	  int cached_pos = (fat_entry - FAT_SUPER->cached_fat);
  16.223 +	  
  16.224 +	  if (cached_pos < 0 || 
  16.225 +	      (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE)
  16.226 +	    {
  16.227 +	      FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1));
  16.228 +	      cached_pos = (fat_entry - FAT_SUPER->cached_fat);
  16.229 +	      sector = FAT_SUPER->fat_offset
  16.230 +		+ FAT_SUPER->cached_fat / (2*SECTOR_SIZE);
  16.231 +	      if (!devread (ffi, sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
  16.232 +		return 0;
  16.233 +	    }
  16.234 +	  next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1));
  16.235 +	  if (FAT_SUPER->fat_size == 3)
  16.236 +	    {
  16.237 +	      if (cached_pos & 1)
  16.238 +		next_cluster >>= 4;
  16.239 +	      next_cluster &= 0xFFF;
  16.240 +	    }
  16.241 +	  else if (FAT_SUPER->fat_size == 4)
  16.242 +	    next_cluster &= 0xFFFF;
  16.243 +	  
  16.244 +	  if (next_cluster >= FAT_SUPER->clust_eof_marker)
  16.245 +	    return ret;
  16.246 +	  if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust)
  16.247 +	    {
  16.248 +	      errnum = ERR_FSYS_CORRUPT;
  16.249 +	      return 0;
  16.250 +	    }
  16.251 +	  
  16.252 +	  FAT_SUPER->current_cluster = next_cluster;
  16.253 +	  FAT_SUPER->current_cluster_num++;
  16.254 +	}
  16.255 +      
  16.256 +      sector = FAT_SUPER->data_offset +
  16.257 +	((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits
  16.258 + 					      - FAT_SUPER->sectsize_bits));
  16.259 +      size = (1 << FAT_SUPER->clustsize_bits) - offset;
  16.260 +      if (size > len)
  16.261 +	size = len;
  16.262 +      
  16.263 +      disk_read_func = disk_read_hook;
  16.264 +      
  16.265 +      devread(ffi, sector, offset, size, buf);
  16.266 +      
  16.267 +      disk_read_func = NULL;
  16.268 +      
  16.269 +      len -= size;
  16.270 +      buf += size;
  16.271 +      ret += size;
  16.272 +      filepos += size;
  16.273 +      logical_clust++;
  16.274 +      offset = 0;
  16.275 +    }
  16.276 +  return errnum ? 0 : ret;
  16.277 +}
  16.278 +
  16.279 +int
  16.280 +fat_dir (fsi_file_t *ffi, char *dirname)
  16.281 +{
  16.282 +  char *rest, ch, dir_buf[FAT_DIRENTRY_LENGTH];
  16.283 +  char *filename = (char *) NAME_BUF;
  16.284 +  int attrib = FAT_ATTRIB_DIR;
  16.285 +#ifndef STAGE1_5
  16.286 +  int do_possibilities = 0;
  16.287 +#endif
  16.288 +  
  16.289 +  /* XXX I18N:
  16.290 +   * the positions 2,4,6 etc are high bytes of a 16 bit unicode char 
  16.291 +   */
  16.292 +  static unsigned char longdir_pos[] = 
  16.293 +  { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
  16.294 +  int slot = -2;
  16.295 +  int alias_checksum = -1;
  16.296 +  
  16.297 +  FAT_SUPER->file_cluster = FAT_SUPER->root_cluster;
  16.298 +  filepos = 0;
  16.299 +  FAT_SUPER->current_cluster_num = INT_MAX;
  16.300 +  
  16.301 +  /* main loop to find desired directory entry */
  16.302 + loop:
  16.303 +  
  16.304 +  /* if we have a real file (and we're not just printing possibilities),
  16.305 +     then this is where we want to exit */
  16.306 +  
  16.307 +  if (!*dirname || isspace (*dirname))
  16.308 +    {
  16.309 +      if (attrib & FAT_ATTRIB_DIR)
  16.310 +	{
  16.311 +	  errnum = ERR_BAD_FILETYPE;
  16.312 +	  return 0;
  16.313 +	}
  16.314 +      
  16.315 +      return 1;
  16.316 +    }
  16.317 +  
  16.318 +  /* continue with the file/directory name interpretation */
  16.319 +  
  16.320 +  while (*dirname == '/')
  16.321 +    dirname++;
  16.322 +  
  16.323 +  if (!(attrib & FAT_ATTRIB_DIR))
  16.324 +    {
  16.325 +      errnum = ERR_BAD_FILETYPE;
  16.326 +      return 0;
  16.327 +    }
  16.328 +  /* Directories don't have a file size */
  16.329 +  filemax = INT_MAX;
  16.330 +  
  16.331 +  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
  16.332 +  
  16.333 +  *rest = 0;
  16.334 +  
  16.335 +# ifndef STAGE1_5
  16.336 +  if (print_possibilities && ch != '/')
  16.337 +    do_possibilities = 1;
  16.338 +# endif
  16.339 +  
  16.340 +  while (1)
  16.341 +    {
  16.342 +      if (fat_read (ffi, dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH
  16.343 +	  || dir_buf[0] == 0)
  16.344 +	{
  16.345 +	  if (!errnum)
  16.346 +	    {
  16.347 +# ifndef STAGE1_5
  16.348 +	      if (print_possibilities < 0)
  16.349 +		{
  16.350 +#if 0
  16.351 +		  putchar ('\n');
  16.352 +#endif
  16.353 +		  return 1;
  16.354 +		}
  16.355 +# endif /* STAGE1_5 */
  16.356 +	      
  16.357 +	      errnum = ERR_FILE_NOT_FOUND;
  16.358 +	      *rest = ch;
  16.359 +	    }
  16.360 +	  
  16.361 +	  return 0;
  16.362 +	}
  16.363 +      
  16.364 +      if (FAT_DIRENTRY_ATTRIB (dir_buf) == FAT_ATTRIB_LONGNAME)
  16.365 +	{
  16.366 +	  /* This is a long filename.  The filename is build from back
  16.367 +	   * to front and may span multiple entries.  To bind these
  16.368 +	   * entries together they all contain the same checksum over
  16.369 +	   * the short alias.
  16.370 +	   *
  16.371 +	   * The id field tells if this is the first entry (the last
  16.372 +	   * part) of the long filename, and also at which offset this
  16.373 +	   * belongs.
  16.374 +	   *
  16.375 +	   * We just write the part of the long filename this entry
  16.376 +	   * describes and continue with the next dir entry.
  16.377 +	   */
  16.378 +	  int i, offset;
  16.379 +	  unsigned char id = FAT_LONGDIR_ID(dir_buf);
  16.380 +	  
  16.381 +	  if ((id & 0x40)) 
  16.382 +	    {
  16.383 +	      id &= 0x3f;
  16.384 +	      slot = id;
  16.385 +	      filename[slot * 13] = 0;
  16.386 +	      alias_checksum = FAT_LONGDIR_ALIASCHECKSUM(dir_buf);
  16.387 +	    } 
  16.388 +	  
  16.389 +	  if (id != slot || slot == 0
  16.390 +	      || alias_checksum != FAT_LONGDIR_ALIASCHECKSUM(dir_buf))
  16.391 +	    {
  16.392 +	      alias_checksum = -1;
  16.393 +	      continue;
  16.394 +	    }
  16.395 +	  
  16.396 +	  slot--;
  16.397 +	  offset = slot * 13;
  16.398 +	  
  16.399 +	  for (i=0; i < 13; i++)
  16.400 +	    filename[offset+i] = dir_buf[longdir_pos[i]];
  16.401 +	  continue;
  16.402 +	}
  16.403 +      
  16.404 +      if (!FAT_DIRENTRY_VALID (dir_buf))
  16.405 +	continue;
  16.406 +      
  16.407 +      if (alias_checksum != -1 && slot == 0)
  16.408 +	{
  16.409 +	  int i;
  16.410 +	  unsigned char sum;
  16.411 +	  
  16.412 +	  slot = -2;
  16.413 +	  for (sum = 0, i = 0; i< 11; i++)
  16.414 +	    sum = ((sum >> 1) | (sum << 7)) + dir_buf[i];
  16.415 +	  
  16.416 +	  if (sum == alias_checksum)
  16.417 +	    {
  16.418 +# ifndef STAGE1_5
  16.419 +	      if (do_possibilities)
  16.420 +		goto print_filename;
  16.421 +# endif /* STAGE1_5 */
  16.422 +	      
  16.423 +	      if (substring (dirname, filename) == 0)
  16.424 +		break;
  16.425 +	    }
  16.426 +	}
  16.427 +      
  16.428 +      /* XXX convert to 8.3 filename format here */
  16.429 +      {
  16.430 +	int i, j, c;
  16.431 +	
  16.432 +	for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i]))
  16.433 +	       && !isspace (c); i++);
  16.434 +	
  16.435 +	filename[i++] = '.';
  16.436 +	
  16.437 +	for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j]))
  16.438 +	       && !isspace (c); j++);
  16.439 +	
  16.440 +	if (j == 0)
  16.441 +	  i--;
  16.442 +	
  16.443 +	filename[i + j] = 0;
  16.444 +      }
  16.445 +      
  16.446 +# ifndef STAGE1_5
  16.447 +      if (do_possibilities)
  16.448 +	{
  16.449 +	print_filename:
  16.450 +	  if (substring (dirname, filename) <= 0)
  16.451 +	    {
  16.452 +	      if (print_possibilities > 0)
  16.453 +		print_possibilities = -print_possibilities;
  16.454 +	      print_a_completion (filename);
  16.455 +	    }
  16.456 +	  continue;
  16.457 +	}
  16.458 +# endif /* STAGE1_5 */
  16.459 +      
  16.460 +      if (substring (dirname, filename) == 0)
  16.461 +	break;
  16.462 +    }
  16.463 +  
  16.464 +  *(dirname = rest) = ch;
  16.465 +  
  16.466 +  attrib = FAT_DIRENTRY_ATTRIB (dir_buf);
  16.467 +  filemax = FAT_DIRENTRY_FILELENGTH (dir_buf);
  16.468 +  filepos = 0;
  16.469 +  FAT_SUPER->file_cluster = FAT_DIRENTRY_FIRST_CLUSTER (dir_buf);
  16.470 +  FAT_SUPER->current_cluster_num = INT_MAX;
  16.471 +  
  16.472 +  /* go back to main loop at top of function */
  16.473 +  goto loop;
  16.474 +}
  16.475 +
  16.476 +fsi_plugin_ops_t *
  16.477 +fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
  16.478 +{
  16.479 +	static fsig_plugin_ops_t ops = {
  16.480 +		FSIMAGE_PLUGIN_VERSION,
  16.481 +		.fpo_mount = fat_mount,
  16.482 +		.fpo_dir = fat_dir,
  16.483 +		.fpo_read = fat_read
  16.484 +	};
  16.485 +
  16.486 +	*name = "fat";
  16.487 +	return (fsig_init(fp, &ops));
  16.488 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/libfsimage/iso9660/Makefile	Thu Feb 22 10:15:29 2007 -0700
    17.3 @@ -0,0 +1,15 @@
    17.4 +XEN_ROOT = ../../..
    17.5 +
    17.6 +LIB_SRCS-y = fsys_iso9660.c
    17.7 +
    17.8 +FS = iso9660
    17.9 +
   17.10 +.PHONY: all
   17.11 +all: fs-all
   17.12 +
   17.13 +.PHONY: install
   17.14 +install: fs-install
   17.15 +
   17.16 +fsys_iso9660.c: iso9660.h
   17.17 +
   17.18 +include $(XEN_ROOT)/tools/libfsimage/Rules.mk
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/libfsimage/iso9660/fsys_iso9660.c	Thu Feb 22 10:15:29 2007 -0700
    18.3 @@ -0,0 +1,463 @@
    18.4 +/*
    18.5 + *  ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
    18.6 + *  including Rock Ridge Extensions support
    18.7 + *
    18.8 + *  Copyright (C) 1998, 1999  Kousuke Takai  <tak@kmc.kyoto-u.ac.jp>
    18.9 + *
   18.10 + *  This program is free software; you can redistribute it and/or modify
   18.11 + *  it under the terms of the GNU General Public License as published by
   18.12 + *  the Free Software Foundation; either version 2 of the License, or
   18.13 + *  (at your option) any later version.
   18.14 + *
   18.15 + *  This program is distributed in the hope that it will be useful,
   18.16 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.17 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.18 + *  GNU General Public License for more details.
   18.19 + *
   18.20 + *  You should have received a copy of the GNU General Public License
   18.21 + *  along with this program; if not, write to the Free Software
   18.22 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18.23 + */
   18.24 +/*
   18.25 + *  References:
   18.26 + *	linux/fs/isofs/rock.[ch]
   18.27 + *	mkisofs-1.11.1/diag/isoinfo.c
   18.28 + *	mkisofs-1.11.1/iso9660.h
   18.29 + *		(all are written by Eric Youngdale)
   18.30 + *
   18.31 + *  Modifications by:
   18.32 + *	Leonid Lisovskiy   <lly@pisem.net>	2003
   18.33 + */
   18.34 +
   18.35 +#include <fsimage_grub.h>
   18.36 +#include <limits.h>
   18.37 +
   18.38 +#include "iso9660.h"
   18.39 +
   18.40 +#define	MAXINT INT_MAX
   18.41 +
   18.42 +/* iso9660 super-block data in memory */
   18.43 +struct iso_sb_info {
   18.44 +  unsigned long vol_sector;
   18.45 +
   18.46 +};
   18.47 +
   18.48 +/* iso fs inode data in memory */
   18.49 +struct iso_inode_info {
   18.50 +  unsigned long file_start;
   18.51 +};
   18.52 +
   18.53 +#define ISO_SUPER	\
   18.54 +    ((struct iso_sb_info *)(FSYS_BUF))
   18.55 +#define INODE		\
   18.56 +    ((struct iso_inode_info *)(FSYS_BUF+sizeof(struct iso_sb_info)))
   18.57 +#define PRIMDESC        ((struct iso_primary_descriptor *)(FSYS_BUF + 2048))
   18.58 +#define DIRREC          ((struct iso_directory_record *)(FSYS_BUF + 4096))
   18.59 +#define RRCONT_BUF      ((unsigned char *)(FSYS_BUF + 6144))
   18.60 +#define NAME_BUF        ((unsigned char *)(FSYS_BUF + 8192))
   18.61 +
   18.62 +
   18.63 +#define log2 grub_log2
   18.64 +
   18.65 +static int
   18.66 +iso9660_devread (fsi_file_t *ffi, int sector, int byte_offset, int byte_len, char *buf)
   18.67 +{
   18.68 +  static int read_count = 0, threshold = 2;
   18.69 +  unsigned short sector_size_lg2 = log2(512 /*buf_geom.sector_size*/);
   18.70 +
   18.71 +  /*
   18.72 +   * We have to use own devread() function since BIOS return wrong geometry
   18.73 +   */
   18.74 +  if (sector < 0)
   18.75 +    {
   18.76 +      errnum = ERR_OUTSIDE_PART;
   18.77 +      return 0;
   18.78 +    }
   18.79 +  if (byte_len <= 0)
   18.80 +    return 1;
   18.81 +
   18.82 +#if 0
   18.83 +  sector += (byte_offset >> sector_size_lg2);
   18.84 +  byte_offset &= (buf_geom.sector_size - 1);
   18.85 +  asm volatile ("shl%L0 %1,%0"
   18.86 +		: "=r"(sector)
   18.87 +		: "Ic"((int8_t)(ISO_SECTOR_BITS - sector_size_lg2)),
   18.88 +		"0"(sector));
   18.89 +#else
   18.90 +  sector = (sector * 4) + (byte_offset >> sector_size_lg2);
   18.91 +  byte_offset &= 511;
   18.92 +#endif
   18.93 +
   18.94 +#if !defined(STAGE1_5)
   18.95 +  if (disk_read_hook && debug)
   18.96 +    printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
   18.97 +#endif /* !STAGE1_5 */
   18.98 +
   18.99 +  read_count += (byte_len >> 9);
  18.100 +  if ((read_count >> 11) > threshold) {
  18.101 +	noisy_printf(".");
  18.102 +	threshold += 2;	/* one dot every 2 MB */
  18.103 +  }
  18.104 +  return devread(ffi, sector, byte_offset, byte_len, buf);
  18.105 +}
  18.106 +
  18.107 +int
  18.108 +iso9660_mount (fsi_file_t *ffi, const char *options)
  18.109 +{
  18.110 +  unsigned int sector;
  18.111 +
  18.112 +  /*
  18.113 +   *  Because there is no defined slice type ID for ISO-9660 filesystem,
  18.114 +   *  this test will pass only either (1) if entire disk is used, or
  18.115 +   *  (2) if current partition is BSD style sub-partition whose ID is
  18.116 +   *  ISO-9660.
  18.117 +   */
  18.118 +#if 0
  18.119 +  if ((current_partition != 0xFFFFFF)
  18.120 +      && !IS_PC_SLICE_TYPE_BSD_WITH_FS(current_slice, FS_ISO9660))
  18.121 +    return 0;
  18.122 +#endif
  18.123 +
  18.124 +  /*
  18.125 +   *  Currently, only FIRST session of MultiSession disks are supported !!!
  18.126 +   */
  18.127 +  for (sector = 16 ; sector < 32 ; sector++)
  18.128 +    {
  18.129 +      if (!iso9660_devread(ffi, sector, 0, sizeof(*PRIMDESC), (char *)PRIMDESC)) 
  18.130 +	break;
  18.131 +      /* check ISO_VD_PRIMARY and ISO_STANDARD_ID */
  18.132 +      if (PRIMDESC->type.l == ISO_VD_PRIMARY
  18.133 +	  && !memcmp(PRIMDESC->id, ISO_STANDARD_ID, sizeof(PRIMDESC->id)))
  18.134 +	{
  18.135 +	  ISO_SUPER->vol_sector = sector;
  18.136 +	  INODE->file_start = 0;
  18.137 +#if 0
  18.138 +	  fsmax = PRIMDESC->volume_space_size.l;
  18.139 +#endif
  18.140 +	  return 1;
  18.141 +	}
  18.142 +    }
  18.143 +
  18.144 +  return 0;
  18.145 +}
  18.146 +
  18.147 +int
  18.148 +iso9660_dir (fsi_file_t *ffi, char *dirname)
  18.149 +{
  18.150 +  struct iso_directory_record *idr;
  18.151 +  RR_ptr_t rr_ptr;
  18.152 +  struct rock_ridge *ce_ptr;
  18.153 +  unsigned int pathlen;
  18.154 +  int size;
  18.155 +  unsigned int extent;
  18.156 +  unsigned char file_type;
  18.157 +  unsigned int rr_len;
  18.158 +  unsigned char rr_flag;
  18.159 +
  18.160 +  idr = &PRIMDESC->root_directory_record;
  18.161 +  INODE->file_start = 0;
  18.162 +
  18.163 +  do
  18.164 +    {
  18.165 +      while (*dirname == '/')	/* skip leading slashes */
  18.166 +	dirname++;
  18.167 +      /* pathlen = strcspn(dirname, "/\n\t "); */
  18.168 +      for (pathlen = 0 ;
  18.169 +	   dirname[pathlen]
  18.170 +	     && !isspace(dirname[pathlen]) && dirname[pathlen] != '/' ;
  18.171 +	   pathlen++)
  18.172 +	;
  18.173 +
  18.174 +      size = idr->size.l;
  18.175 +      extent = idr->extent.l;
  18.176 +
  18.177 +      while (size > 0)
  18.178 +	{
  18.179 +	  if (!iso9660_devread(ffi, extent, 0, ISO_SECTOR_SIZE, (char *)DIRREC))
  18.180 +	    {
  18.181 +	      errnum = ERR_FSYS_CORRUPT;
  18.182 +	      return 0;
  18.183 +	    }
  18.184 +	  extent++;
  18.185 +
  18.186 +	  idr = (struct iso_directory_record *)DIRREC;
  18.187 +	  for (; idr->length.l > 0;
  18.188 +	       idr = (struct iso_directory_record *)((char *)idr + idr->length.l) )
  18.189 +	    {
  18.190 +	      const char *name = (const char *)idr->name;
  18.191 +	      unsigned int name_len = idr->name_len.l;
  18.192 +
  18.193 +	      file_type = (idr->flags.l & 2) ? ISO_DIRECTORY : ISO_REGULAR;
  18.194 +	      if (name_len == 1)
  18.195 +		{
  18.196 +		  if ((name[0] == 0) ||	/* self */
  18.197 +		      (name[0] == 1)) 	/* parent */
  18.198 +		    continue;
  18.199 +		}
  18.200 +	      if (name_len > 2 && CHECK2(name + name_len - 2, ';', '1'))
  18.201 +		{
  18.202 +		  name_len -= 2;	/* truncate trailing file version */
  18.203 +		  if (name_len > 1 && name[name_len - 1] == '.')
  18.204 +		    name_len--;		/* truncate trailing dot */
  18.205 +		}
  18.206 +
  18.207 +	      /*
  18.208 +	       *  Parse Rock-Ridge extension
  18.209 +	       */
  18.210 +	      rr_len = (idr->length.l - idr->name_len.l
  18.211 +			- sizeof(struct iso_directory_record)
  18.212 +			+ sizeof(idr->name));
  18.213 +	      rr_ptr.ptr = ((char *)idr + idr->name_len.l
  18.214 +			    + sizeof(struct iso_directory_record)
  18.215 +			    - sizeof(idr->name));
  18.216 +	      if (rr_ptr.i & 1)
  18.217 +		rr_ptr.i++, rr_len--;
  18.218 +	      ce_ptr = NULL;
  18.219 +	      rr_flag = RR_FLAG_NM | RR_FLAG_PX /*| RR_FLAG_SL*/;
  18.220 +
  18.221 +	      while (rr_len >= 4)
  18.222 +		{
  18.223 +		  if (rr_ptr.rr->version != 1)
  18.224 +		    {
  18.225 +#ifndef STAGE1_5
  18.226 +		      if (debug)
  18.227 +			printf(
  18.228 +			       "Non-supported version (%d) RockRidge chunk "
  18.229 +			       "`%c%c'\n", rr_ptr.rr->version,
  18.230 +			       rr_ptr.rr->signature & 0xFF,
  18.231 +			       rr_ptr.rr->signature >> 8);
  18.232 +#endif
  18.233 +		    }
  18.234 +		  else
  18.235 +		    {
  18.236 +		      switch (rr_ptr.rr->signature)
  18.237 +			{
  18.238 +			case RRMAGIC('R', 'R'):
  18.239 +			  if ( rr_ptr.rr->len >= (4+sizeof(struct RR)))
  18.240 +			    rr_flag &= rr_ptr.rr->u.rr.flags.l;
  18.241 +			  break;
  18.242 +			case RRMAGIC('N', 'M'):
  18.243 +			  name = (const char *)rr_ptr.rr->u.nm.name;
  18.244 +			  name_len = rr_ptr.rr->len - (4+sizeof(struct NM));
  18.245 +			  rr_flag &= ~RR_FLAG_NM;
  18.246 +			  break;
  18.247 +			case RRMAGIC('P', 'X'):
  18.248 +			  if (rr_ptr.rr->len >= (4+sizeof(struct PX)))
  18.249 +			    {
  18.250 +			      file_type = ((rr_ptr.rr->u.px.mode.l & POSIX_S_IFMT)
  18.251 +					   == POSIX_S_IFREG
  18.252 +					   ? ISO_REGULAR
  18.253 +					   : ((rr_ptr.rr->u.px.mode.l & POSIX_S_IFMT)
  18.254 +					      == POSIX_S_IFDIR
  18.255 +					      ? ISO_DIRECTORY : ISO_OTHER));
  18.256 +			      rr_flag &= ~RR_FLAG_PX;
  18.257 +			    }
  18.258 +			  break;
  18.259 +			case RRMAGIC('C', 'E'):
  18.260 +			  if (rr_ptr.rr->len >= (4+sizeof(struct CE)))
  18.261 +			    ce_ptr = rr_ptr.rr;
  18.262 +			  break;
  18.263 +#if 0		// RockRidge symlinks are not supported yet
  18.264 +			case RRMAGIC('S', 'L'):
  18.265 +			  {
  18.266 +			    int slen;
  18.267 +			    unsigned char rootflag, prevflag;
  18.268 +			    char *rpnt = NAME_BUF+1024;
  18.269 +			    struct SL_component *slp;
  18.270 +
  18.271 +			    slen = rr_ptr.rr->len - (4+1);
  18.272 +			    slp = &rr_ptr.rr->u.sl.link;
  18.273 +			    while (slen > 1)
  18.274 +			      {
  18.275 +				rootflag = 0;
  18.276 +				switch (slp->flags.l)
  18.277 +				  {
  18.278 +				  case 0:
  18.279 +				    memcpy(rpnt, slp->text, slp->len);
  18.280 +				    rpnt += slp->len;
  18.281 +				    break;
  18.282 +				  case 4:
  18.283 +				    *rpnt++ = '.';
  18.284 +				    /* fallthru */
  18.285 +				  case 2:
  18.286 +				    *rpnt++ = '.';
  18.287 +				    break;
  18.288 +				  case 8:
  18.289 +				    rootflag = 1;
  18.290 +				    *rpnt++ = '/';
  18.291 +				    break;
  18.292 +				  default:
  18.293 +				    printf("Symlink component flag not implemented (%d)\n",
  18.294 +					   slp->flags.l);
  18.295 +				    slen = 0;
  18.296 +				    break;
  18.297 +				  }
  18.298 +				slen -= slp->len + 2;
  18.299 +				prevflag = slp->flags.l;
  18.300 +				slp = (struct SL_component *) ((char *) slp + slp->len + 2);
  18.301 +
  18.302 +				if (slen < 2)
  18.303 +				  {
  18.304 +				    /*
  18.305 +				     * If there is another SL record, and this component
  18.306 +				     * record isn't continued, then add a slash.
  18.307 +				     */
  18.308 +				    if ((!rootflag) && (rr_ptr.rr->u.sl.flags.l & 1) && !(prevflag & 1))
  18.309 +				      *rpnt++='/';
  18.310 +				    break;
  18.311 +				  }
  18.312 +
  18.313 +				/*
  18.314 +				 * If this component record isn't continued, then append a '/'.
  18.315 +				 */
  18.316 +				if (!rootflag && !(prevflag & 1))
  18.317 +				  *rpnt++ = '/';
  18.318 +			      }
  18.319 +			    *rpnt++ = '\0';
  18.320 +			    grub_putstr(NAME_BUF+1024);// debug print!
  18.321 +			  }
  18.322 +			  rr_flag &= ~RR_FLAG_SL;
  18.323 +			  break;
  18.324 +#endif
  18.325 +			default:
  18.326 +			  break;
  18.327 +			}
  18.328 +		    }
  18.329 +		  if (!rr_flag)
  18.330 +		    /*
  18.331 +		     * There is no more extension we expects...
  18.332 +		     */
  18.333 +		    break;
  18.334 +
  18.335 +		  rr_len -= rr_ptr.rr->len;
  18.336 +		  rr_ptr.ptr += rr_ptr.rr->len;
  18.337 +		  if (rr_len < 4 && ce_ptr != NULL)
  18.338 +		    {
  18.339 +		      /* preserve name before loading new extent. */
  18.340 +		      if( RRCONT_BUF <= (unsigned char *)name
  18.341 +			  && (unsigned char *)name < RRCONT_BUF + ISO_SECTOR_SIZE )
  18.342 +			{
  18.343 +			  memcpy(NAME_BUF, name, name_len);
  18.344 +			  name = (const char *)NAME_BUF;
  18.345 +			}
  18.346 +		      rr_ptr.ptr = (char *)RRCONT_BUF + ce_ptr->u.ce.offset.l;
  18.347 +		      rr_len = ce_ptr->u.ce.size.l;
  18.348 +		      if (!iso9660_devread(ffi, ce_ptr->u.ce.extent.l, 0, ISO_SECTOR_SIZE, (char *)RRCONT_BUF))
  18.349 +			{
  18.350 +			  errnum = 0;	/* this is not fatal. */
  18.351 +			  break;
  18.352 +			}
  18.353 +		      ce_ptr = NULL;
  18.354 +		    }
  18.355 +		} /* rr_len >= 4 */
  18.356 +
  18.357 +	      filemax = MAXINT;
  18.358 +	      if (name_len >= pathlen
  18.359 +		  && !memcmp(name, dirname, pathlen))
  18.360 +		{
  18.361 +		  if (dirname[pathlen] == '/' || !print_possibilities)
  18.362 +		    {
  18.363 +		      /*
  18.364 +		       *  DIRNAME is directory component of pathname,
  18.365 +		       *  or we are to open a file.
  18.366 +		       */
  18.367 +		      if (pathlen == name_len)
  18.368 +			{
  18.369 +			  if (dirname[pathlen] == '/')
  18.370 +			    {
  18.371 +			      if (file_type != ISO_DIRECTORY)
  18.372 +				{
  18.373 +				  errnum = ERR_BAD_FILETYPE;
  18.374 +				  return 0;
  18.375 +				}
  18.376 +			      goto next_dir_level;
  18.377 +			    }
  18.378 +			  if (file_type != ISO_REGULAR)
  18.379 +			    {
  18.380 +			      errnum = ERR_BAD_FILETYPE;
  18.381 +			      return 0;
  18.382 +			    }
  18.383 +			  INODE->file_start = idr->extent.l;
  18.384 +			  filepos = 0;
  18.385 +			  filemax = idr->size.l;
  18.386 +			  return 1;
  18.387 +			}
  18.388 +		    }
  18.389 +		  else	/* Completion */
  18.390 +		    {
  18.391 +#ifndef STAGE1_5
  18.392 +		      if (print_possibilities > 0)
  18.393 +			print_possibilities = -print_possibilities;
  18.394 +		      memcpy(NAME_BUF, name, name_len);
  18.395 +		      NAME_BUF[name_len] = '\0';
  18.396 +		      print_a_completion (NAME_BUF);
  18.397 +#endif
  18.398 +		    }
  18.399 +		}
  18.400 +	    } /* for */
  18.401 +
  18.402 +	  size -= ISO_SECTOR_SIZE;
  18.403 +	} /* size>0 */
  18.404 +
  18.405 +      if (dirname[pathlen] == '/' || print_possibilities >= 0)
  18.406 +	{
  18.407 +	  errnum = ERR_FILE_NOT_FOUND;
  18.408 +	  return 0;
  18.409 +	}
  18.410 +
  18.411 +    next_dir_level:
  18.412 +      dirname += pathlen;
  18.413 +
  18.414 +    } while (*dirname == '/');
  18.415 +
  18.416 +  return 1;
  18.417 +}
  18.418 +
  18.419 +int
  18.420 +iso9660_read (fsi_file_t *ffi, char *buf, int len)
  18.421 +{
  18.422 +  int sector, blkoffset, size, ret;
  18.423 +
  18.424 +  if (INODE->file_start == 0)
  18.425 +    return 0;
  18.426 +
  18.427 +  ret = 0;
  18.428 +  blkoffset = filepos & (ISO_SECTOR_SIZE - 1);
  18.429 +  sector = filepos >> ISO_SECTOR_BITS;
  18.430 +  while (len > 0)
  18.431 +    {
  18.432 +      size = ISO_SECTOR_SIZE - blkoffset;
  18.433 +      if (size > len)
  18.434 +        size = len;
  18.435 +
  18.436 +      disk_read_func = disk_read_hook;
  18.437 +
  18.438 +      if (!iso9660_devread(ffi, INODE->file_start + sector, blkoffset, size, buf))
  18.439 +	return 0;
  18.440 +
  18.441 +      disk_read_func = NULL;
  18.442 +
  18.443 +      len -= size;
  18.444 +      buf += size;
  18.445 +      ret += size;
  18.446 +      filepos += size;
  18.447 +      sector++;
  18.448 +      blkoffset = 0;
  18.449 +    }
  18.450 +
  18.451 +  return ret;
  18.452 +}
  18.453 +
  18.454 +fsi_plugin_ops_t *
  18.455 +fsi_init_plugin(int version, fsi_plugin_t *fp, const char **name)
  18.456 +{
  18.457 +	static fsig_plugin_ops_t ops = {
  18.458 +		FSIMAGE_PLUGIN_VERSION,
  18.459 +		.fpo_mount = iso9660_mount,
  18.460 +		.fpo_dir = iso9660_dir,
  18.461 +		.fpo_read = iso9660_read
  18.462 +	};
  18.463 +
  18.464 +	*name = "iso9660";
  18.465 +	return (fsig_init(fp, &ops));
  18.466 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/libfsimage/iso9660/iso9660.h	Thu Feb 22 10:15:29 2007 -0700
    19.3 @@ -0,0 +1,219 @@
    19.4 +/*
    19.5 + *  ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
    19.6 + *  including Rock Ridge Extensions support
    19.7 + *
    19.8 + *  Copyright (C) 1998, 1999  Kousuke Takai  <tak@kmc.kyoto-u.ac.jp>
    19.9 + *
   19.10 + *  This program is free software; you can redistribute it and/or modify
   19.11 + *  it under the terms of the GNU General Public License as published by
   19.12 + *  the Free Software Foundation; either version 2 of the License, or
   19.13 + *  (at your option) any later version.
   19.14 + *
   19.15 + *  This program is distributed in the hope that it will be useful,
   19.16 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.17 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.18 + *  GNU General Public License for more details.
   19.19 + *
   19.20 + *  You should have received a copy of the GNU General Public License
   19.21 + *  along with this program; if not, write to the Free Software
   19.22 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   19.23 + */
   19.24 +/*
   19.25 + *  References:
   19.26 + *	linux/fs/isofs/rock.[ch]
   19.27 + *	mkisofs-1.11.1/diag/isoinfo.c
   19.28 + *	mkisofs-1.11.1/iso9660.h
   19.29 + *		(all are written by Eric Youngdale)
   19.30 + */
   19.31 +
   19.32 +#ifndef _ISO9660_H_
   19.33 +#define _ISO9660_H_
   19.34 +
   19.35 +#define ISO_SECTOR_BITS              (11)
   19.36 +#define ISO_SECTOR_SIZE              (1<<ISO_SECTOR_BITS)
   19.37 +
   19.38 +#define	ISO_REGULAR	1	/* regular file	*/
   19.39 +#define	ISO_DIRECTORY	2	/* directory	*/
   19.40 +#define	ISO_OTHER	0	/* other file (with Rock Ridge) */
   19.41 +
   19.42 +#define	RR_FLAG_PX	0x01	/* have POSIX file attributes */
   19.43 +#define RR_FLAG_PN	0x02	/* POSIX devices */
   19.44 +#define RR_FLAG_SL	0x04	/* Symbolic link */
   19.45 +#define	RR_FLAG_NM	0x08	/* have alternate file name   */
   19.46 +#define RR_FLAG_CL	0x10	/* Child link */
   19.47 +#define RR_FLAG_PL	0x20	/* Parent link */
   19.48 +#define RR_FLAG_RE	0x40	/* Relocation directory */
   19.49 +#define RR_FLAG_TF	0x80	/* Timestamps */
   19.50 +
   19.51 +/* POSIX file attributes for Rock Ridge extensions */
   19.52 +#define	POSIX_S_IFMT	0xF000
   19.53 +#define	POSIX_S_IFREG	0x8000
   19.54 +#define	POSIX_S_IFDIR	0x4000
   19.55 +
   19.56 +/* volume descriptor types */
   19.57 +#define ISO_VD_PRIMARY 1
   19.58 +#define ISO_VD_END 255
   19.59 +
   19.60 +#define ISO_STANDARD_ID "CD001"
   19.61 +
   19.62 +#ifndef ASM_FILE
   19.63 +
   19.64 +#ifndef __sun
   19.65 +#ifndef	__BIT_TYPES_DEFINED__
   19.66 +typedef		 int	 int8_t	__attribute__((mode(QI)));
   19.67 +typedef unsigned int   u_int8_t	__attribute__((mode(QI)));
   19.68 +typedef		 int	int16_t	__attribute__((mode(HI)));
   19.69 +typedef unsigned int  u_int16_t	__attribute__((mode(HI)));
   19.70 +typedef		 int	int32_t	__attribute__((mode(SI)));
   19.71 +typedef unsigned int  u_int32_t	__attribute__((mode(SI)));
   19.72 +#endif
   19.73 +#else
   19.74 +#ifndef GRUB_UTIL
   19.75 +typedef		 char  int8_t;
   19.76 +typedef		 short int16_t;
   19.77 +typedef		 int   int32_t;
   19.78 +#endif /* ! GRUB_UTIL */
   19.79 +typedef unsigned char  u_int8_t;
   19.80 +typedef unsigned short u_int16_t;
   19.81 +typedef unsigned int   u_int32_t;
   19.82 +#endif /* __sun */
   19.83 +
   19.84 +typedef	union {
   19.85 +  u_int8_t l,b;
   19.86 +}	iso_8bit_t;
   19.87 +
   19.88 +struct __iso_16bit {
   19.89 +  u_int16_t l, b;
   19.90 +} __attribute__ ((packed));
   19.91 +typedef	struct __iso_16bit iso_16bit_t;
   19.92 +
   19.93 +struct __iso_32bit {
   19.94 +  u_int32_t l, b;
   19.95 +} __attribute__ ((packed));
   19.96 +typedef	struct __iso_32bit iso_32bit_t;
   19.97 +
   19.98 +typedef u_int8_t		iso_date_t[7];
   19.99 +
  19.100 +struct iso_directory_record {
  19.101 +  iso_8bit_t	length;
  19.102 +  iso_8bit_t	ext_attr_length;
  19.103 +  iso_32bit_t	extent;
  19.104 +  iso_32bit_t	size;
  19.105 +  iso_date_t	date;
  19.106 +  iso_8bit_t	flags;
  19.107 +  iso_8bit_t	file_unit_size;
  19.108 +  iso_8bit_t	interleave;
  19.109 +  iso_16bit_t	volume_seq_number;
  19.110 +  iso_8bit_t	name_len;
  19.111 +  u_int8_t	name[1];
  19.112 +} __attribute__ ((packed));
  19.113 +
  19.114 +struct iso_primary_descriptor {
  19.115 +  iso_8bit_t	type;
  19.116 +  u_int8_t	id[5];
  19.117 +  iso_8bit_t	version;
  19.118 +  u_int8_t	_unused1[1];
  19.119 +  u_int8_t	system_id[32];
  19.120 +  u_int8_t	volume_id[32];
  19.121 +  u_int8_t	_unused2[8];
  19.122 +  iso_32bit_t	volume_space_size;
  19.123 +  u_int8_t	_unused3[32];
  19.124 +  iso_16bit_t	volume_set_size;
  19.125 +  iso_16bit_t	volume_seq_number;
  19.126 +  iso_16bit_t	logical_block_size;
  19.127 +  iso_32bit_t	path_table_size;
  19.128 +  u_int8_t	type_l_path_table[4];
  19.129 +  u_int8_t	opt_type_l_path_table[4];
  19.130 +  u_int8_t	type_m_path_table[4];
  19.131 +  u_int8_t	opt_type_m_path_table[4];
  19.132 +  struct iso_directory_record root_directory_record;
  19.133 +  u_int8_t	volume_set_id[128];
  19.134 +  u_int8_t	publisher_id[128];
  19.135 +  u_int8_t	preparer_id[128];
  19.136 +  u_int8_t	application_id[128];
  19.137 +  u_int8_t	copyright_file_id[37];
  19.138 +  u_int8_t	abstract_file_id[37];
  19.139 +  u_int8_t	bibliographic_file_id[37];
  19.140 +  u_int8_t	creation_date[17];
  19.141 +  u_int8_t	modification_date[17];
  19.142 +  u_int8_t	expiration_date[17];
  19.143 +  u_int8_t	effective_date[17];
  19.144 +  iso_8bit_t	file_structure_version;
  19.145 +  u_int8_t	_unused4[1];
  19.146 +  u_int8_t	application_data[512];
  19.147 +  u_int8_t	_unused5[653];
  19.148 +} __attribute__ ((packed));
  19.149 +
  19.150 +struct rock_ridge {
  19.151 +  u_int16_t	signature;
  19.152 +  u_int8_t	len;
  19.153 +  u_int8_t	version;
  19.154 +  union {
  19.155 +    struct SP {
  19.156 +      u_int16_t	magic;
  19.157 +      u_int8_t	skip;
  19.158 +    } sp;
  19.159 +    struct CE {
  19.160 +      iso_32bit_t	extent;
  19.161 +      iso_32bit_t	offset;
  19.162 +      iso_32bit_t	size;
  19.163 +    } ce;
  19.164 +    struct ER {
  19.165 +      u_int8_t	len_id;
  19.166 +      u_int8_t	len_des;
  19.167 +      u_int8_t	len_src;
  19.168 +      u_int8_t	ext_ver;
  19.169 +      u_int8_t	data[0];
  19.170 +    } er;
  19.171 +    struct RR {
  19.172 +      iso_8bit_t	flags;
  19.173 +    } rr;
  19.174 +    struct PX {
  19.175 +      iso_32bit_t	mode;
  19.176 +      iso_32bit_t	nlink;
  19.177 +      iso_32bit_t	uid;
  19.178 +      iso_32bit_t	gid;
  19.179 +    } px;
  19.180 +    struct PN {
  19.181 +      iso_32bit_t	dev_high;
  19.182 +      iso_32bit_t	dev_low;
  19.183 +    } pn;
  19.184 +    struct SL {
  19.185 +      iso_8bit_t flags;
  19.186 +      struct SL_component {
  19.187 +	iso_8bit_t	flags;
  19.188 +	u_int8_t		len;
  19.189 +	u_int8_t		text[0];
  19.190 +      } link;
  19.191 +    } sl;
  19.192 +    struct NM {
  19.193 +      iso_8bit_t	flags;
  19.194 +      u_int8_t	name[0];
  19.195 +    } nm;
  19.196 +    struct CL {
  19.197 +      iso_32bit_t	location;
  19.198 +    } cl;
  19.199 +    struct PL {
  19.200 +      iso_32bit_t	location;
  19.201 +    } pl;
  19.202 +    struct TF {
  19.203 +      iso_8bit_t	flags;
  19.204 +      iso_date_t	times[0];
  19.205 +    } tf;
  19.206 +  } u;
  19.207 +} __attribute__ ((packed));
  19.208 +
  19.209 +typedef	union RR_ptr {
  19.210 +  struct rock_ridge *rr;
  19.211 +  char		  *ptr;
  19.212 +  int		   i;
  19.213 +} RR_ptr_t;
  19.214 +
  19.215 +#define	RRMAGIC(c1, c2)	((c1)|(c2) << 8)
  19.216 +
  19.217 +#define	CHECK2(ptr, c1, c2) \
  19.218 +	(*(unsigned short *)(ptr) == (((c1) | (c2) << 8) & 0xFFFF))
  19.219 +
  19.220 +#endif /* !ASM_FILE */
  19.221 +
  19.222 +#endif /* _ISO9660_H_ */
    20.1 --- a/tools/libfsimage/reiserfs/fsys_reiserfs.c	Thu Feb 22 09:42:13 2007 -0700
    20.2 +++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c	Thu Feb 22 10:15:29 2007 -0700
    20.3 @@ -363,83 +363,6 @@ struct fsys_reiser_info
    20.4  #define JOURNAL_START    ((__u32 *) (INFO + 1))
    20.5  #define JOURNAL_END      ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
    20.6  
    20.7 -#if defined(__i386__) || defined(__x86_64__)
    20.8 -
    20.9 -#ifdef __amd64
   20.10 -#define BSF "bsfq"
   20.11 -#else
   20.12 -#define BSF "bsfl"
   20.13 -#endif
   20.14 -static __inline__ unsigned long
   20.15 -grub_log2 (unsigned long word)
   20.16 -{
   20.17 -  __asm__ (BSF " %1,%0"
   20.18 -	   : "=r" (word)
   20.19 -	   : "r" (word));
   20.20 -  return word;
   20.21 -}
   20.22 -
   20.23 -#elif defined(__ia64__)
   20.24 -
   20.25 -#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
   20.26 -# define ia64_popcnt(x) __builtin_popcountl(x)
   20.27 -#else
   20.28 -# define ia64_popcnt(x)                                     \
   20.29 -  ({                                                        \
   20.30 -    __u64 ia64_intri_res;                                   \
   20.31 -    asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
   20.32 -    ia64_intri_res;                                         \
   20.33 -  })
   20.34 -#endif
   20.35 -
   20.36 -static __inline__ unsigned long
   20.37 -grub_log2 (unsigned long word)
   20.38 -{
   20.39 -  unsigned long result;
   20.40 -
   20.41 -  result = ia64_popcnt((word - 1) & ~word);
   20.42 -  return result;
   20.43 -}
   20.44 -
   20.45 -#elif defined(__powerpc__)
   20.46 -
   20.47 -#ifdef __powerpc64__
   20.48 -#define PPC_CNTLZL "cntlzd"
   20.49 -#else
   20.50 -#define PPC_CNTLZL "cntlzw"
   20.51 -#endif
   20.52 -#define BITS_PER_LONG (sizeof(long) * 8)
   20.53 -
   20.54 -static __inline__ int
   20.55 -__ilog2(unsigned long x)
   20.56 -{
   20.57 -  int lz;
   20.58 -
   20.59 -  asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (x));
   20.60 -  return BITS_PER_LONG - 1 - lz;
   20.61 -}
   20.62 -
   20.63 -static __inline__ unsigned long
   20.64 -grub_log2 (unsigned long word)
   20.65 -{
   20.66 -  return __ilog2(word & -word);
   20.67 -}
   20.68 -
   20.69 -#else /* Unoptimized */
   20.70 -
   20.71 -static __inline__ unsigned long
   20.72 -grub_log2 (unsigned long word)
   20.73 -{
   20.74 -  unsigned long result = 0;
   20.75 -
   20.76 -  while (!(word & 1UL))
   20.77 -    {
   20.78 -      result++;
   20.79 -      word >>= 1;
   20.80 -    }
   20.81 -  return result;
   20.82 -}
   20.83 -#endif
   20.84  #define log2 grub_log2
   20.85  
   20.86  static __inline__ int
    21.1 --- a/tools/libxen/include/xen_console.h	Thu Feb 22 09:42:13 2007 -0700
    21.2 +++ b/tools/libxen/include/xen_console.h	Thu Feb 22 10:15:29 2007 -0700
    21.3 @@ -1,5 +1,5 @@
    21.4  /*
    21.5 - * Copyright (c) 2006, XenSource Inc.
    21.6 + * Copyright (c) 2006-2007, XenSource Inc.
    21.7   *
    21.8   * This library is free software; you can redistribute it and/or
    21.9   * modify it under the terms of the GNU Lesser General Public
   21.10 @@ -22,12 +22,13 @@
   21.11  #include "xen_common.h"
   21.12  #include "xen_console_decl.h"
   21.13  #include "xen_console_protocol.h"
   21.14 +#include "xen_string_string_map.h"
   21.15  #include "xen_vm_decl.h"
   21.16  
   21.17  
   21.18  /*
   21.19 - * The console class. 
   21.20 - *  
   21.21 + * The console class.
   21.22 + * 
   21.23   * A console.
   21.24   */
   21.25  
   21.26 @@ -65,8 +66,9 @@ typedef struct xen_console_record
   21.27      xen_console handle;
   21.28      char *uuid;
   21.29      enum xen_console_protocol protocol;
   21.30 -    char *uri;
   21.31 +    char *location;
   21.32      struct xen_vm_record_opt *vm;
   21.33 +    xen_string_string_map *other_config;
   21.34  } xen_console_record;
   21.35  
   21.36  /**
   21.37 @@ -191,10 +193,10 @@ xen_console_get_protocol(xen_session *se
   21.38  
   21.39  
   21.40  /**
   21.41 - * Get the uri field of the given console.
   21.42 + * Get the location field of the given console.
   21.43   */
   21.44  extern bool
   21.45 -xen_console_get_uri(xen_session *session, char **result, xen_console console);
   21.46 +xen_console_get_location(xen_session *session, char **result, xen_console console);
   21.47  
   21.48  
   21.49  /**
   21.50 @@ -204,4 +206,35 @@ extern bool
   21.51  xen_console_get_vm(xen_session *session, xen_vm *result, xen_console console);
   21.52  
   21.53  
   21.54 +/**
   21.55 + * Get the other_config field of the given console.
   21.56 + */
   21.57 +extern bool
   21.58 +xen_console_get_other_config(xen_session *session, xen_string_string_map **result, xen_console console);
   21.59 +
   21.60 +
   21.61 +/**
   21.62 + * Set the other_config field of the given console.
   21.63 + */
   21.64 +extern bool
   21.65 +xen_console_set_other_config(xen_session *session, xen_console console, xen_string_string_map *other_config);
   21.66 +
   21.67 +
   21.68 +/**
   21.69 + * Add the given key-value pair to the other_config field of the given
   21.70 + * console.
   21.71 + */
   21.72 +extern bool
   21.73 +xen_console_add_to_other_config(xen_session *session, xen_console console, char *key, char *value);
   21.74 +
   21.75 +
   21.76 +/**
   21.77 + * Remove the given key and its corresponding value from the
   21.78 + * other_config field of the given console.  If the key is not in that Map,
   21.79 + * then do nothing.
   21.80 + */
   21.81 +extern bool
   21.82 +xen_console_remove_from_other_config(xen_session *session, xen_console console, char *key);
   21.83 +
   21.84 +
   21.85  #endif
    22.1 --- a/tools/libxen/include/xen_host.h	Thu Feb 22 09:42:13 2007 -0700
    22.2 +++ b/tools/libxen/include/xen_host.h	Thu Feb 22 10:15:29 2007 -0700
    22.3 @@ -1,5 +1,5 @@
    22.4  /*
    22.5 - * Copyright (c) 2006, XenSource Inc.
    22.6 + * Copyright (c) 2006-2007, XenSource Inc.
    22.7   *
    22.8   * This library is free software; you can redistribute it and/or
    22.9   * modify it under the terms of the GNU Lesser General Public
   22.10 @@ -26,6 +26,7 @@
   22.11  #include "xen_pbd_decl.h"
   22.12  #include "xen_pif_decl.h"
   22.13  #include "xen_sr_decl.h"
   22.14 +#include "xen_string_set.h"
   22.15  #include "xen_string_string_map.h"
   22.16  #include "xen_vm_decl.h"
   22.17  
   22.18 @@ -73,6 +74,7 @@ typedef struct xen_host_record
   22.19      char *name_description;
   22.20      xen_string_string_map *software_version;
   22.21      xen_string_string_map *other_config;
   22.22 +    struct xen_string_set *supported_bootloaders;
   22.23      struct xen_vm_record_opt_set *resident_vms;
   22.24      xen_string_string_map *logging;
   22.25      struct xen_pif_record_opt_set *pifs;
   22.26 @@ -177,20 +179,6 @@ xen_host_get_by_uuid(xen_session *sessio
   22.27  
   22.28  
   22.29  /**
   22.30 - * Create a new host instance, and return its handle.
   22.31 - */
   22.32 -extern bool
   22.33 -xen_host_create(xen_session *session, xen_host *result, xen_host_record *record);
   22.34 -
   22.35 -
   22.36 -/**
   22.37 - * Destroy the specified host instance.
   22.38 - */
   22.39 -extern bool
   22.40 -xen_host_destroy(xen_session *session, xen_host host);
   22.41 -
   22.42 -
   22.43 -/**
   22.44   * Get all the host instances with the given label.
   22.45   */
   22.46  extern bool
   22.47 @@ -233,6 +221,13 @@ xen_host_get_other_config(xen_session *s
   22.48  
   22.49  
   22.50  /**
   22.51 + * Get the supported_bootloaders field of the given host.
   22.52 + */
   22.53 +extern bool
   22.54 +xen_host_get_supported_bootloaders(xen_session *session, struct xen_string_set **result, xen_host host);
   22.55 +
   22.56 +
   22.57 +/**
   22.58   * Get the resident_VMs field of the given host.
   22.59   */
   22.60  extern bool
    23.1 --- a/tools/libxen/include/xen_internal.h	Thu Feb 22 09:42:13 2007 -0700
    23.2 +++ b/tools/libxen/include/xen_internal.h	Thu Feb 22 10:15:29 2007 -0700
    23.3 @@ -149,7 +149,10 @@ type__ ## _free(type__ handle)          
    23.4  type__ ## _set *                                                        \
    23.5  type__ ## _set_alloc(size_t size)                                       \
    23.6  {                                                                       \
    23.7 -    return calloc(1, sizeof(type__ ## _set) + size * sizeof(type__));   \
    23.8 +    type__ ## _set *result = calloc(1, sizeof(type__ ## _set) +         \
    23.9 +                                    size * sizeof(type__));             \
   23.10 +    result->size = size;                                                \
   23.11 +    return result;                                                      \
   23.12  }                                                                       \
   23.13                                                                          \
   23.14  void                                                                    \
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/libxen/include/xen_string_set.h	Thu Feb 22 10:15:29 2007 -0700
    24.3 @@ -0,0 +1,47 @@
    24.4 +/*
    24.5 + * Copyright (c) 2006-2007, XenSource Inc.
    24.6 + *
    24.7 + * This library is free software; you can redistribute it and/or
    24.8 + * modify it under the terms of the GNU Lesser General Public
    24.9 + * License as published by the Free Software Foundation; either
   24.10 + * version 2.1 of the License, or (at your option) any later version.
   24.11 + *
   24.12 + * This library is distributed in the hope that it will be useful,
   24.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   24.15 + * Lesser General Public License for more details.
   24.16 + *
   24.17 + * You should have received a copy of the GNU Lesser General Public
   24.18 + * License along with this library; if not, write to the Free Software
   24.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   24.20 + */
   24.21 +
   24.22 +#ifndef XEN_STRING_SET_H
   24.23 +#define XEN_STRING_SET_H
   24.24 +
   24.25 +
   24.26 +#include "xen_common.h"
   24.27 +
   24.28 +
   24.29 +typedef struct xen_string_set
   24.30 +{
   24.31 +    size_t size;
   24.32 +    char *contents[];
   24.33 +} xen_string_set;
   24.34 +
   24.35 +
   24.36 +/**
   24.37 + * Allocate a xen_string_set of the given size.
   24.38 + */
   24.39 +extern xen_string_set *
   24.40 +xen_string_set_alloc(size_t size);
   24.41 +
   24.42 +/**
   24.43 + * Free the given xen_string_set.  The given set must have been allocated
   24.44 + * by this library.
   24.45 + */
   24.46 +extern void
   24.47 +xen_string_set_free(xen_string_set *set);
   24.48 +
   24.49 +
   24.50 +#endif
    25.1 --- a/tools/libxen/include/xen_vbd.h	Thu Feb 22 09:42:13 2007 -0700
    25.2 +++ b/tools/libxen/include/xen_vbd.h	Thu Feb 22 10:15:29 2007 -0700
    25.3 @@ -1,5 +1,5 @@
    25.4  /*
    25.5 - * Copyright (c) 2006, XenSource Inc.
    25.6 + * Copyright (c) 2006-2007, XenSource Inc.
    25.7   *
    25.8   * This library is free software; you can redistribute it and/or
    25.9   * modify it under the terms of the GNU Lesser General Public
   25.10 @@ -20,8 +20,11 @@
   25.11  #define XEN_VBD_H
   25.12  
   25.13  #include "xen_common.h"
   25.14 +#include "xen_string_string_map.h"
   25.15  #include "xen_vbd_decl.h"
   25.16 +#include "xen_vbd_metrics_decl.h"
   25.17  #include "xen_vbd_mode.h"
   25.18 +#include "xen_vbd_type.h"
   25.19  #include "xen_vdi_decl.h"
   25.20  #include "xen_vm_decl.h"
   25.21  
   25.22 @@ -71,8 +74,10 @@ typedef struct xen_vbd_record
   25.23      char *image;
   25.24      bool bootable;
   25.25      enum xen_vbd_mode mode;
   25.26 -    double io_read_kbs;
   25.27 -    double io_write_kbs;
   25.28 +    enum xen_vbd_type type;
   25.29 +    char *qos_algorithm_type;
   25.30 +    xen_string_string_map *qos_algorithm_params;
   25.31 +    struct xen_vbd_metrics_record_opt *metrics;
   25.32  } xen_vbd_record;
   25.33  
   25.34  /**
   25.35 @@ -155,14 +160,14 @@ xen_vbd_record_opt_set_free(xen_vbd_reco
   25.36  
   25.37  
   25.38  /**
   25.39 - * Get the current state of the given VBD.  !!!
   25.40 + * Get a record containing the current state of the given VBD.
   25.41   */
   25.42  extern bool
   25.43  xen_vbd_get_record(xen_session *session, xen_vbd_record **result, xen_vbd vbd);
   25.44  
   25.45  
   25.46  /**
   25.47 - * Get a reference to the object with the specified UUID.  !!!
   25.48 + * Get a reference to the VBD instance with the specified UUID.
   25.49   */
   25.50  extern bool
   25.51  xen_vbd_get_by_uuid(xen_session *session, xen_vbd *result, char *uuid);
   25.52 @@ -225,17 +230,31 @@ xen_vbd_get_mode(xen_session *session, e
   25.53  
   25.54  
   25.55  /**
   25.56 - * Get the io/read_kbs field of the given VBD.
   25.57 + * Get the type field of the given VBD.
   25.58   */
   25.59  extern bool
   25.60 -xen_vbd_get_io_read_kbs(xen_session *session, double *result, xen_vbd vbd);
   25.61 +xen_vbd_get_type(xen_session *session, enum xen_vbd_type *result, xen_vbd vbd);
   25.62  
   25.63  
   25.64  /**
   25.65 - * Get the io/write_kbs field of the given VBD.
   25.66 + * Get the qos/algorithm_type field of the given VBD.
   25.67   */
   25.68  extern bool
   25.69 -xen_vbd_get_io_write_kbs(xen_session *session, double *result, xen_vbd vbd);
   25.70 +xen_vbd_get_qos_algorithm_type(xen_session *session, char **result, xen_vbd vbd);
   25.71 +
   25.72 +
   25.73 +/**
   25.74 + * Get the qos/algorithm_params field of the given VBD.
   25.75 + */
   25.76 +extern bool
   25.77 +xen_vbd_get_qos_algorithm_params(xen_session *session, xen_string_string_map **result, xen_vbd vbd);
   25.78 +
   25.79 +
   25.80 +/**
   25.81 + * Get the metrics field of the given VBD.
   25.82 + */
   25.83 +extern bool
   25.84 +xen_vbd_get_metrics(xen_session *session, xen_vbd_metrics *result, xen_vbd vbd);
   25.85  
   25.86  
   25.87  /**
   25.88 @@ -260,6 +279,44 @@ xen_vbd_set_mode(xen_session *session, x
   25.89  
   25.90  
   25.91  /**
   25.92 + * Set the type field of the given VBD.
   25.93 + */
   25.94 +extern bool
   25.95 +xen_vbd_set_type(xen_session *session, xen_vbd vbd, enum xen_vbd_type type);
   25.96 +
   25.97 +
   25.98 +/**
   25.99 + * Set the qos/algorithm_type field of the given VBD.
  25.100 + */
  25.101 +extern bool
  25.102 +xen_vbd_set_qos_algorithm_type(xen_session *session, xen_vbd vbd, char *algorithm_type);
  25.103 +
  25.104 +
  25.105 +/**
  25.106 + * Set the qos/algorithm_params field of the given VBD.
  25.107 + */
  25.108 +extern bool
  25.109 +xen_vbd_set_qos_algorithm_params(xen_session *session, xen_vbd vbd, xen_string_string_map *algorithm_params);
  25.110 +
  25.111 +
  25.112 +/**
  25.113 + * Add the given key-value pair to the qos/algorithm_params field of
  25.114 + * the given VBD.
  25.115 + */
  25.116 +extern bool
  25.117 +xen_vbd_add_to_qos_algorithm_params(xen_session *session, xen_vbd vbd, char *key, char *value);
  25.118 +
  25.119 +
  25.120 +/**
  25.121 + * Remove the given key and its corresponding value from the
  25.122 + * qos/algorithm_params field of the given VBD.  If the key is not in that
  25.123 + * Map, then do nothing.
  25.124 + */
  25.125 +extern bool
  25.126 +xen_vbd_remove_from_qos_algorithm_params(xen_session *session, xen_vbd vbd, char *key);
  25.127 +
  25.128 +
  25.129 +/**
  25.130   * Change the media in the device for CDROM-like devices only. For
  25.131   * other devices, detach the VBD and attach a new one
  25.132   */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/libxen/include/xen_vbd_metrics.h	Thu Feb 22 10:15:29 2007 -0700
    26.3 @@ -0,0 +1,183 @@
    26.4 +/*
    26.5 + * Copyright (c) 2006-2007, XenSource Inc.
    26.6 + *
    26.7 + * This library is free software; you can redistribute it and/or
    26.8 + * modify it under the terms of the GNU Lesser General Public
    26.9 + * License as published by the Free Software Foundation; either
   26.10 + * version 2.1 of the License, or (at your option) any later version.
   26.11 + *
   26.12 + * This library is distributed in the hope that it will be useful,
   26.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   26.15 + * Lesser General Public License for more details.
   26.16 + *
   26.17 + * You should have received a copy of the GNU Lesser General Public
   26.18 + * License along with this library; if not, write to the Free Software
   26.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   26.20 + */
   26.21 +
   26.22 +#ifndef XEN_VBD_METRICS_H
   26.23 +#define XEN_VBD_METRICS_H
   26.24 +
   26.25 +#include "xen_common.h"
   26.26 +#include "xen_vbd_metrics_decl.h"
   26.27 +
   26.28 +
   26.29 +/*
   26.30 + * The VBD_metrics class.
   26.31 + * 
   26.32 + * The metrics associated with a virtual block device.
   26.33 + */
   26.34 +
   26.35 +
   26.36 +/**
   26.37 + * Free the given xen_vbd_metrics.  The given handle must have been
   26.38 + * allocated by this library.
   26.39 + */
   26.40 +extern void
   26.41 +xen_vbd_metrics_free(xen_vbd_metrics vbd_metrics);
   26.42 +
   26.43 +
   26.44 +typedef struct xen_vbd_metrics_set
   26.45 +{
   26.46 +    size_t size;
   26.47 +    xen_vbd_metrics *contents[];
   26.48 +} xen_vbd_metrics_set;
   26.49 +
   26.50 +/**
   26.51 + * Allocate a xen_vbd_metrics_set of the given size.
   26.52 + */
   26.53 +extern xen_vbd_metrics_set *
   26.54 +xen_vbd_metrics_set_alloc(size_t size);
   26.55 +
   26.56 +/**
   26.57 + * Free the given xen_vbd_metrics_set.  The given set must have been
   26.58 + * allocated by this library.
   26.59 + */
   26.60 +extern void
   26.61 +xen_vbd_metrics_set_free(xen_vbd_metrics_set *set);
   26.62 +
   26.63 +
   26.64 +typedef struct xen_vbd_metrics_record
   26.65 +{
   26.66 +    xen_vbd_metrics handle;
   26.67 +    char *uuid;
   26.68 +    double io_read_kbs;
   26.69 +    double io_write_kbs;
   26.70 +} xen_vbd_metrics_record;
   26.71 +
   26.72 +/**
   26.73 + * Allocate a xen_vbd_metrics_record.
   26.74 + */
   26.75 +extern xen_vbd_metrics_record *
   26.76 +xen_vbd_metrics_record_alloc(void);
   26.77 +
   26.78 +/**
   26.79 + * Free the given xen_vbd_metrics_record, and all referenced values. 
   26.80 + * The given record must have been allocated by this library.
   26.81 + */
   26.82 +extern void
   26.83 +xen_vbd_metrics_record_free(xen_vbd_metrics_record *record);
   26.84 +
   26.85 +
   26.86 +typedef struct xen_vbd_metrics_record_opt
   26.87 +{
   26.88 +    bool is_record;
   26.89 +    union
   26.90 +    {
   26.91 +        xen_vbd_metrics handle;
   26.92 +        xen_vbd_metrics_record *record;
   26.93 +    } u;
   26.94 +} xen_vbd_metrics_record_opt;
   26.95 +
   26.96 +/**
   26.97 + * Allocate a xen_vbd_metrics_record_opt.
   26.98 + */
   26.99 +extern xen_vbd_metrics_record_opt *
  26.100 +xen_vbd_metrics_record_opt_alloc(void);
  26.101 +
  26.102 +/**
  26.103 + * Free the given xen_vbd_metrics_record_opt, and all referenced
  26.104 + * values.  The given record_opt must have been allocated by this library.
  26.105 + */
  26.106 +extern void
  26.107 +xen_vbd_metrics_record_opt_free(xen_vbd_metrics_record_opt *record_opt);
  26.108 +
  26.109 +
  26.110 +typedef struct xen_vbd_metrics_record_set
  26.111 +{
  26.112 +    size_t size;
  26.113 +    xen_vbd_metrics_record *contents[];
  26.114 +} xen_vbd_metrics_record_set;
  26.115 +
  26.116 +/**
  26.117 + * Allocate a xen_vbd_metrics_record_set of the given size.
  26.118 + */
  26.119 +extern xen_vbd_metrics_record_set *
  26.120 +xen_vbd_metrics_record_set_alloc(size_t size);
  26.121 +
  26.122 +/**
  26.123 + * Free the given xen_vbd_metrics_record_set, and all referenced
  26.124 + * values.  The given set must have been allocated by this library.
  26.125 + */
  26.126 +extern void
  26.127 +xen_vbd_metrics_record_set_free(xen_vbd_metrics_record_set *set);
  26.128 +
  26.129 +
  26.130 +
  26.131 +typedef struct xen_vbd_metrics_record_opt_set
  26.132 +{
  26.133 +    size_t size;
  26.134 +    xen_vbd_metrics_record_opt *contents[];
  26.135 +} xen_vbd_metrics_record_opt_set;
  26.136 +
  26.137 +/**
  26.138 + * Allocate a xen_vbd_metrics_record_opt_set of the given size.
  26.139 + */
  26.140 +extern xen_vbd_metrics_record_opt_set *
  26.141 +xen_vbd_metrics_record_opt_set_alloc(size_t size);
  26.142 +
  26.143 +/**
  26.144 + * Free the given xen_vbd_metrics_record_opt_set, and all referenced
  26.145 + * values.  The given set must have been allocated by this library.
  26.146 + */
  26.147 +extern void
  26.148 +xen_vbd_metrics_record_opt_set_free(xen_vbd_metrics_record_opt_set *set);
  26.149 +
  26.150 +
  26.151 +/**
  26.152 + * Get a record containing the current state of the given VBD_metrics.
  26.153 + */
  26.154 +extern bool
  26.155 +xen_vbd_metrics_get_record(xen_session *session, xen_vbd_metrics_record **result, xen_vbd_metrics vbd_metrics);
  26.156 +
  26.157 +
  26.158 +/**
  26.159 + * Get a reference to the VBD_metrics instance with the specified UUID.
  26.160 + */
  26.161 +extern bool
  26.162 +xen_vbd_metrics_get_by_uuid(xen_session *session, xen_vbd_metrics *result, char *uuid);
  26.163 +
  26.164 +
  26.165 +/**
  26.166 + * Get the uuid field of the given VBD_metrics.
  26.167 + */
  26.168 +extern bool
  26.169 +xen_vbd_metrics_get_uuid(xen_session *session, char **result, xen_vbd_metrics vbd_metrics);
  26.170 +
  26.171 +
  26.172 +/**
  26.173 + * Get the io/read_kbs field of the given VBD_metrics.
  26.174 + */
  26.175 +extern bool
  26.176 +xen_vbd_metrics_get_io_read_kbs(xen_session *session, double *result, xen_vbd_metrics vbd_metrics);
  26.177 +
  26.178 +
  26.179 +/**
  26.180 + * Get the io/write_kbs field of the given VBD_metrics.
  26.181 + */
  26.182 +extern bool
  26.183 +xen_vbd_metrics_get_io_write_kbs(xen_session *session, double *result, xen_vbd_metrics vbd_metrics);
  26.184 +
  26.185 +
  26.186 +#endif
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/libxen/include/xen_vbd_metrics_decl.h	Thu Feb 22 10:15:29 2007 -0700
    27.3 @@ -0,0 +1,30 @@
    27.4 +/*
    27.5 + * Copyright (c) 2006-2007, XenSource Inc.
    27.6 + *
    27.7 + * This library is free software; you can redistribute it and/or
    27.8 + * modify it under the terms of the GNU Lesser General Public
    27.9 + * License as published by the Free Software Foundation; either
   27.10 + * version 2.1 of the License, or (at your option) any later version.
   27.11 + *
   27.12 + * This library is distributed in the hope that it will be useful,
   27.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   27.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   27.15 + * Lesser General Public License for more details.
   27.16 + *
   27.17 + * You should have received a copy of the GNU Lesser General Public
   27.18 + * License along with this library; if not, write to the Free Software
   27.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   27.20 + */
   27.21 +
   27.22 +#ifndef XEN_VBD_METRICS_DECL_H
   27.23 +#define XEN_VBD_METRICS_DECL_H
   27.24 +
   27.25 +typedef void *xen_vbd_metrics;
   27.26 +
   27.27 +struct xen_vbd_metrics_set;
   27.28 +struct xen_vbd_metrics_record;
   27.29 +struct xen_vbd_metrics_record_set;
   27.30 +struct xen_vbd_metrics_record_opt;
   27.31 +struct xen_vbd_metrics_record_opt_set;
   27.32 +
   27.33 +#endif
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/tools/libxen/include/xen_vbd_type.h	Thu Feb 22 10:15:29 2007 -0700
    28.3 @@ -0,0 +1,77 @@
    28.4 +/*
    28.5 + * Copyright (c) 2006-2007, XenSource Inc.
    28.6 + *
    28.7 + * This library is free software; you can redistribute it and/or
    28.8 + * modify it under the terms of the GNU Lesser General Public
    28.9 + * License as published by the Free Software Foundation; either
   28.10 + * version 2.1 of the License, or (at your option) any later version.
   28.11 + *
   28.12 + * This library is distributed in the hope that it will be useful,
   28.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   28.15 + * Lesser General Public License for more details.
   28.16 + *
   28.17 + * You should have received a copy of the GNU Lesser General Public
   28.18 + * License along with this library; if not, write to the Free Software
   28.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   28.20 + */
   28.21 +
   28.22 +#ifndef XEN_VBD_TYPE_H
   28.23 +#define XEN_VBD_TYPE_H
   28.24 +
   28.25 +
   28.26 +#include "xen_common.h"
   28.27 +
   28.28 +
   28.29 +enum xen_vbd_type
   28.30 +{
   28.31 +    /**
   28.32 +     * VBD will appear to guest as CD
   28.33 +     */
   28.34 +    XEN_VBD_TYPE_CD,
   28.35 +
   28.36 +    /**
   28.37 +     * VBD will appear to guest as disk
   28.38 +     */
   28.39 +    XEN_VBD_TYPE_DISK
   28.40 +};
   28.41 +
   28.42 +
   28.43 +typedef struct xen_vbd_type_set
   28.44 +{
   28.45 +    size_t size;
   28.46 +    enum xen_vbd_type contents[];
   28.47 +} xen_vbd_type_set;
   28.48 +
   28.49 +/**
   28.50 + * Allocate a xen_vbd_type_set of the given size.
   28.51 + */
   28.52 +extern xen_vbd_type_set *
   28.53 +xen_vbd_type_set_alloc(size_t size);
   28.54 +
   28.55 +/**
   28.56 + * Free the given xen_vbd_type_set.  The given set must have been
   28.57 + * allocated by this library.
   28.58 + */
   28.59 +extern void
   28.60 +xen_vbd_type_set_free(xen_vbd_type_set *set);
   28.61 +
   28.62 +
   28.63 +/**
   28.64 + * Return the name corresponding to the given code.  This string must
   28.65 + * not be modified or freed.
   28.66 + */
   28.67 +extern const char *
   28.68 +xen_vbd_type_to_string(enum xen_vbd_type val);
   28.69 +
   28.70 +
   28.71 +/**
   28.72 + * Return the correct code for the given string, or set the session
   28.73 + * object to failure and return an undefined value if the given string does
   28.74 + * not match a known code.
   28.75 + */
   28.76 +extern enum xen_vbd_type
   28.77 +xen_vbd_type_from_string(xen_session *session, const char *str);
   28.78 +
   28.79 +
   28.80 +#endif
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/tools/libxen/include/xen_vbd_type_internal.h	Thu Feb 22 10:15:29 2007 -0700
    29.3 @@ -0,0 +1,37 @@
    29.4 +/*
    29.5 + * Copyright (c) 2006-2007, XenSource Inc.
    29.6 + *
    29.7 + * This library is free software; you can redistribute it and/or
    29.8 + * modify it under the terms of the GNU Lesser General Public
    29.9 + * License as published by the Free Software Foundation; either
   29.10 + * version 2.1 of the License, or (at your option) any later version.
   29.11 + *
   29.12 + * This library is distributed in the hope that it will be useful,
   29.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   29.15 + * Lesser General Public License for more details.
   29.16 + *
   29.17 + * You should have received a copy of the GNU Lesser General Public
   29.18 + * License along with this library; if not, write to the Free Software
   29.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   29.20 + */
   29.21 +
   29.22 +
   29.23 +/*
   29.24 + * Declarations of the abstract types used during demarshalling of enum
   29.25 + * xen_vbd_type.  Internal to this library -- do not use from outside.
   29.26 + */
   29.27 +
   29.28 +
   29.29 +#ifndef XEN_VBD_TYPE_INTERNAL_H
   29.30 +#define XEN_VBD_TYPE_INTERNAL_H
   29.31 +
   29.32 +
   29.33 +#include "xen_internal.h"
   29.34 +
   29.35 +
   29.36 +extern const abstract_type xen_vbd_type_abstract_type_;
   29.37 +extern const abstract_type xen_vbd_type_set_abstract_type_;
   29.38 +
   29.39 +
   29.40 +#endif
    30.1 --- a/tools/libxen/include/xen_vif.h	Thu Feb 22 09:42:13 2007 -0700
    30.2 +++ b/tools/libxen/include/xen_vif.h	Thu Feb 22 10:15:29 2007 -0700
    30.3 @@ -1,5 +1,5 @@
    30.4  /*
    30.5 - * Copyright (c) 2006, XenSource Inc.
    30.6 + * Copyright (c) 2006-2007, XenSource Inc.
    30.7   *
    30.8   * This library is free software; you can redistribute it and/or
    30.9   * modify it under the terms of the GNU Lesser General Public
   30.10 @@ -21,7 +21,9 @@
   30.11  
   30.12  #include "xen_common.h"
   30.13  #include "xen_network_decl.h"
   30.14 +#include "xen_string_string_map.h"
   30.15  #include "xen_vif_decl.h"
   30.16 +#include "xen_vif_metrics_decl.h"
   30.17  #include "xen_vm_decl.h"
   30.18  
   30.19  
   30.20 @@ -69,8 +71,9 @@ typedef struct xen_vif_record
   30.21      struct xen_vm_record_opt *vm;
   30.22      char *mac;
   30.23      int64_t mtu;
   30.24 -    double io_read_kbs;
   30.25 -    double io_write_kbs;
   30.26 +    char *qos_algorithm_type;
   30.27 +    xen_string_string_map *qos_algorithm_params;
   30.28 +    struct xen_vif_metrics_record_opt *metrics;
   30.29  } xen_vif_record;
   30.30  
   30.31  /**
   30.32 @@ -223,17 +226,24 @@ xen_vif_get_mtu(xen_session *session, in
   30.33  
   30.34  
   30.35  /**
   30.36 - * Get the io/read_kbs field of the given VIF.
   30.37 + * Get the qos/algorithm_type field of the given VIF.
   30.38   */
   30.39  extern bool
   30.40 -xen_vif_get_io_read_kbs(xen_session *session, double *result, xen_vif vif);
   30.41 +xen_vif_get_qos_algorithm_type(xen_session *session, char **result, xen_vif vif);
   30.42  
   30.43  
   30.44  /**
   30.45 - * Get the io/write_kbs field of the given VIF.
   30.46 + * Get the qos/algorithm_params field of the given VIF.
   30.47   */
   30.48  extern bool
   30.49 -xen_vif_get_io_write_kbs(xen_session *session, double *result, xen_vif vif);
   30.50 +xen_vif_get_qos_algorithm_params(xen_session *session, xen_string_string_map **result, xen_vif vif);
   30.51 +
   30.52 +
   30.53 +/**
   30.54 + * Get the metrics field of the given VIF.
   30.55 + */
   30.56 +extern bool
   30.57 +xen_vif_get_metrics(xen_session *session, xen_vif_metrics *result, xen_vif vif);
   30.58  
   30.59  
   30.60  /**
   30.61 @@ -257,4 +267,35 @@ extern bool
   30.62  xen_vif_set_mtu(xen_session *session, xen_vif vif, int64_t mtu);
   30.63  
   30.64  
   30.65 +/**
   30.66 + * Set the qos/algorithm_type field of the given VIF.
   30.67 + */
   30.68 +extern bool
   30.69 +xen_vif_set_qos_algorithm_type(xen_session *session, xen_vif vif, char *algorithm_type);
   30.70 +
   30.71 +
   30.72 +/**
   30.73 + * Set the qos/algorithm_params field of the given VIF.
   30.74 + */
   30.75 +extern bool
   30.76 +xen_vif_set_qos_algorithm_params(xen_session *session, xen_vif vif, xen_string_string_map *algorithm_params);
   30.77 +
   30.78 +
   30.79 +/**
   30.80 + * Add the given key-value pair to the qos/algorithm_params field of
   30.81 + * the given VIF.
   30.82 + */
   30.83 +extern bool
   30.84 +xen_vif_add_to_qos_algorithm_params(xen_session *session, xen_vif vif, char *key, char *value);
   30.85 +
   30.86 +
   30.87 +/**
   30.88 + * Remove the given key and its corresponding value from the
   30.89 + * qos/algorithm_params field of the given VIF.  If the key is not in that
   30.90 + * Map, then do nothing.
   30.91 + */
   30.92 +extern bool
   30.93 +xen_vif_remove_from_qos_algorithm_params(xen_session *session, xen_vif vif, char *key);
   30.94 +
   30.95 +
   30.96  #endif
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/libxen/include/xen_vif_metrics.h	Thu Feb 22 10:15:29 2007 -0700
    31.3 @@ -0,0 +1,183 @@
    31.4 +/*
    31.5 + * Copyright (c) 2006-2007, XenSource Inc.
    31.6 + *
    31.7 + * This library is free software; you can redistribute it and/or
    31.8 + * modify it under the terms of the GNU Lesser General Public
    31.9 + * License as published by the Free Software Foundation; either
   31.10 + * version 2.1 of the License, or (at your option) any later version.
   31.11 + *
   31.12 + * This library is distributed in the hope that it will be useful,
   31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   31.15 + * Lesser General Public License for more details.
   31.16 + *
   31.17 + * You should have received a copy of the GNU Lesser General Public
   31.18 + * License along with this library; if not, write to the Free Software
   31.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   31.20 + */
   31.21 +
   31.22 +#ifndef XEN_VIF_METRICS_H
   31.23 +#define XEN_VIF_METRICS_H
   31.24 +
   31.25 +#include "xen_common.h"
   31.26 +#include "xen_vif_metrics_decl.h"
   31.27 +
   31.28 +
   31.29 +/*
   31.30 + * The VIF_metrics class.
   31.31 + * 
   31.32 + * The metrics associated with a virtual network device.
   31.33 + */
   31.34 +
   31.35 +
   31.36 +/**
   31.37 + * Free the given xen_vif_metrics.  The given handle must have been
   31.38 + * allocated by this library.
   31.39 + */
   31.40 +extern void
   31.41 +xen_vif_metrics_free(xen_vif_metrics vif_metrics);
   31.42 +
   31.43 +
   31.44 +typedef struct xen_vif_metrics_set
   31.45 +{
   31.46 +    size_t size;
   31.47 +    xen_vif_metrics *contents[];
   31.48 +} xen_vif_metrics_set;
   31.49 +
   31.50 +/**
   31.51 + * Allocate a xen_vif_metrics_set of the given size.
   31.52 + */
   31.53 +extern xen_vif_metrics_set *
   31.54 +xen_vif_metrics_set_alloc(size_t size);
   31.55 +
   31.56 +/**
   31.57 + * Free the given xen_vif_metrics_set.  The given set must have been
   31.58 + * allocated by this library.
   31.59 + */
   31.60 +extern void
   31.61 +xen_vif_metrics_set_free(xen_vif_metrics_set *set);
   31.62 +
   31.63 +
   31.64 +typedef struct xen_vif_metrics_record
   31.65 +{
   31.66 +    xen_vif_metrics handle;
   31.67 +    char *uuid;
   31.68 +    double io_read_kbs;
   31.69 +    double io_write_kbs;
   31.70 +} xen_vif_metrics_record;
   31.71 +
   31.72 +/**
   31.73 + * Allocate a xen_vif_metrics_record.
   31.74 + */
   31.75 +extern xen_vif_metrics_record *
   31.76 +xen_vif_metrics_record_alloc(void);
   31.77 +
   31.78 +/**
   31.79 + * Free the given xen_vif_metrics_record, and all referenced values. 
   31.80 + * The given record must have been allocated by this library.
   31.81 + */
   31.82 +extern void
   31.83 +xen_vif_metrics_record_free(xen_vif_metrics_record *record);
   31.84 +
   31.85 +
   31.86 +typedef struct xen_vif_metrics_record_opt
   31.87 +{
   31.88 +    bool is_record;
   31.89 +    union
   31.90 +    {
   31.91 +        xen_vif_metrics handle;
   31.92 +        xen_vif_metrics_record *record;
   31.93 +    } u;
   31.94 +} xen_vif_metrics_record_opt;
   31.95 +
   31.96 +/**
   31.97 + * Allocate a xen_vif_metrics_record_opt.
   31.98 + */
   31.99 +extern xen_vif_metrics_record_opt *
  31.100 +xen_vif_metrics_record_opt_alloc(void);
  31.101 +
  31.102 +/**
  31.103 + * Free the given xen_vif_metrics_record_opt, and all referenced
  31.104 + * values.  The given record_opt must have been allocated by this library.
  31.105 + */
  31.106 +extern void
  31.107 +xen_vif_metrics_record_opt_free(xen_vif_metrics_record_opt *record_opt);
  31.108 +
  31.109 +
  31.110 +typedef struct xen_vif_metrics_record_set
  31.111 +{
  31.112 +    size_t size;
  31.113 +    xen_vif_metrics_record *contents[];
  31.114 +} xen_vif_metrics_record_set;
  31.115 +
  31.116 +/**
  31.117 + * Allocate a xen_vif_metrics_record_set of the given size.
  31.118 + */
  31.119 +extern xen_vif_metrics_record_set *
  31.120 +xen_vif_metrics_record_set_alloc(size_t size);
  31.121 +
  31.122 +/**
  31.123 + * Free the given xen_vif_metrics_record_set, and all referenced
  31.124 + * values.  The given set must have been allocated by this library.
  31.125 + */
  31.126 +extern void
  31.127 +xen_vif_metrics_record_set_free(xen_vif_metrics_record_set *set);
  31.128 +
  31.129 +
  31.130 +
  31.131 +typedef struct xen_vif_metrics_record_opt_set
  31.132 +{
  31.133 +    size_t size;
  31.134 +    xen_vif_metrics_record_opt *contents[];
  31.135 +} xen_vif_metrics_record_opt_set;
  31.136 +
  31.137 +/**
  31.138 + * Allocate a xen_vif_metrics_record_opt_set of the given size.
  31.139 + */
  31.140 +extern xen_vif_metrics_record_opt_set *
  31.141 +xen_vif_metrics_record_opt_set_alloc(size_t size);
  31.142 +
  31.143 +/**
  31.144 + * Free the given xen_vif_metrics_record_opt_set, and all referenced
  31.145 + * values.  The given set must have been allocated by this library.
  31.146 + */
  31.147 +extern void
  31.148 +xen_vif_metrics_record_opt_set_free(xen_vif_metrics_record_opt_set *set);
  31.149 +
  31.150 +
  31.151 +/**
  31.152 + * Get a record containing the current state of the given VIF_metrics.
  31.153 + */
  31.154 +extern bool
  31.155 +xen_vif_metrics_get_record(xen_session *session, xen_vif_metrics_record **result, xen_vif_metrics vif_metrics);
  31.156 +
  31.157 +
  31.158 +/**
  31.159 + * Get a reference to the VIF_metrics instance with the specified UUID.
  31.160 + */
  31.161 +extern bool
  31.162 +xen_vif_metrics_get_by_uuid(xen_session *session, xen_vif_metrics *result, char *uuid);
  31.163 +
  31.164 +
  31.165 +/**
  31.166 + * Get the uuid field of the given VIF_metrics.
  31.167 + */
  31.168 +extern bool
  31.169 +xen_vif_metrics_get_uuid(xen_session *session, char **result, xen_vif_metrics vif_metrics);
  31.170 +
  31.171 +
  31.172 +/**
  31.173 + * Get the io/read_kbs field of the given VIF_metrics.
  31.174 + */
  31.175 +extern bool
  31.176 +xen_vif_metrics_get_io_read_kbs(xen_session *session, double *result, xen_vif_metrics vif_metrics);
  31.177 +
  31.178 +
  31.179 +/**
  31.180 + * Get the io/write_kbs field of the given VIF_metrics.
  31.181 + */
  31.182 +extern bool
  31.183 +xen_vif_metrics_get_io_write_kbs(xen_session *session, double *result, xen_vif_metrics vif_metrics);
  31.184 +
  31.185 +
  31.186 +#endif
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/libxen/include/xen_vif_metrics_decl.h	Thu Feb 22 10:15:29 2007 -0700
    32.3 @@ -0,0 +1,30 @@
    32.4 +/*
    32.5 + * Copyright (c) 2006-2007, XenSource Inc.
    32.6 + *
    32.7 + * This library is free software; you can redistribute it and/or
    32.8 + * modify it under the terms of the GNU Lesser General Public
    32.9 + * License as published by the Free Software Foundation; either
   32.10 + * version 2.1 of the License, or (at your option) any later version.
   32.11 + *
   32.12 + * This library is distributed in the hope that it will be useful,
   32.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   32.15 + * Lesser General Public License for more details.
   32.16 + *
   32.17 + * You should have received a copy of the GNU Lesser General Public
   32.18 + * License along with this library; if not, write to the Free Software
   32.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   32.20 + */
   32.21 +
   32.22 +#ifndef XEN_VIF_METRICS_DECL_H
   32.23 +#define XEN_VIF_METRICS_DECL_H
   32.24 +
   32.25 +typedef void *xen_vif_metrics;
   32.26 +
   32.27 +struct xen_vif_metrics_set;
   32.28 +struct xen_vif_metrics_record;
   32.29 +struct xen_vif_metrics_record_set;
   32.30 +struct xen_vif_metrics_record_opt;
   32.31 +struct xen_vif_metrics_record_opt_set;
   32.32 +
   32.33 +#endif
    33.1 --- a/tools/libxen/include/xen_vm_metrics.h	Thu Feb 22 09:42:13 2007 -0700
    33.2 +++ b/tools/libxen/include/xen_vm_metrics.h	Thu Feb 22 10:15:29 2007 -0700
    33.3 @@ -1,5 +1,5 @@
    33.4  /*
    33.5 - * Copyright (c) 2006, XenSource Inc.
    33.6 + * Copyright (c) 2006-2007, XenSource Inc.
    33.7   *
    33.8   * This library is free software; you can redistribute it and/or
    33.9   * modify it under the terms of the GNU Lesser General Public
   33.10 @@ -21,7 +21,6 @@
   33.11  
   33.12  #include "xen_common.h"
   33.13  #include "xen_int_float_map.h"
   33.14 -#include "xen_vm_decl.h"
   33.15  #include "xen_vm_metrics_decl.h"
   33.16  
   33.17  
   33.18 @@ -64,7 +63,6 @@ typedef struct xen_vm_metrics_record
   33.19  {
   33.20      xen_vm_metrics handle;
   33.21      char *uuid;
   33.22 -    struct xen_vm_record_opt *vm;
   33.23      int64_t memory_actual;
   33.24      int64_t vcpus_number;
   33.25      xen_int_float_map *vcpus_utilisation;
   33.26 @@ -171,13 +169,6 @@ xen_vm_metrics_get_uuid(xen_session *ses
   33.27  
   33.28  
   33.29  /**
   33.30 - * Get the VM field of the given VM_metrics.
   33.31 - */
   33.32 -extern bool
   33.33 -xen_vm_metrics_get_vm(xen_session *session, xen_vm *result, xen_vm_metrics vm_metrics);
   33.34 -
   33.35 -
   33.36 -/**
   33.37   * Get the memory/actual field of the given VM_metrics.
   33.38   */
   33.39  extern bool
    34.1 --- a/tools/libxen/src/xen_common.c	Thu Feb 22 09:42:13 2007 -0700
    34.2 +++ b/tools/libxen/src/xen_common.c	Thu Feb 22 10:15:29 2007 -0700
    34.3 @@ -989,10 +989,10 @@ static void parse_failure(xen_session *s
    34.4          char **c = (char **)error_descriptions->contents;
    34.5          int n = error_descriptions->size;
    34.6  
    34.7 -        char **strings = malloc(3 * sizeof(char *));
    34.8 +        char **strings = malloc(n * sizeof(char *));
    34.9          for (int i = 0; i < n; i++)
   34.10          {
   34.11 -            strings[i] = xen_strdup_(c[i]);
   34.12 +            strings[i] = c[i];
   34.13          }
   34.14  
   34.15          session->error_description_count = n;
    35.1 --- a/tools/libxen/src/xen_console.c	Thu Feb 22 09:42:13 2007 -0700
    35.2 +++ b/tools/libxen/src/xen_console.c	Thu Feb 22 10:15:29 2007 -0700
    35.3 @@ -1,5 +1,5 @@
    35.4  /*
    35.5 - * Copyright (c) 2006, XenSource Inc.
    35.6 + * Copyright (c) 2006-2007, XenSource Inc.
    35.7   *
    35.8   * This library is free software; you can redistribute it and/or
    35.9   * modify it under the terms of the GNU Lesser General Public
   35.10 @@ -24,6 +24,7 @@
   35.11  #include "xen_console.h"
   35.12  #include "xen_console_protocol_internal.h"
   35.13  #include "xen_internal.h"
   35.14 +#include "xen_string_string_map.h"
   35.15  #include "xen_vm.h"
   35.16  
   35.17  
   35.18 @@ -44,12 +45,15 @@ static const struct_member xen_console_r
   35.19          { .key = "protocol",
   35.20            .type = &xen_console_protocol_abstract_type_,
   35.21            .offset = offsetof(xen_console_record, protocol) },
   35.22 -        { .key = "uri",
   35.23 +        { .key = "location",
   35.24            .type = &abstract_type_string,
   35.25 -          .offset = offsetof(xen_console_record, uri) },
   35.26 +          .offset = offsetof(xen_console_record, location) },
   35.27          { .key = "VM",
   35.28            .type = &abstract_type_ref,
   35.29 -          .offset = offsetof(xen_console_record, vm) }
   35.30 +          .offset = offsetof(xen_console_record, vm) },
   35.31 +        { .key = "other_config",
   35.32 +          .type = &abstract_type_string_string_map,
   35.33 +          .offset = offsetof(xen_console_record, other_config) }
   35.34      };
   35.35  
   35.36  const abstract_type xen_console_record_abstract_type_ =
   35.37 @@ -71,8 +75,9 @@ xen_console_record_free(xen_console_reco
   35.38      }
   35.39      free(record->handle);
   35.40      free(record->uuid);
   35.41 -    free(record->uri);
   35.42 +    free(record->location);
   35.43      xen_vm_record_opt_free(record->vm);
   35.44 +    xen_string_string_map_free(record->other_config);
   35.45      free(record);
   35.46  }
   35.47  
   35.48 @@ -164,7 +169,7 @@ xen_console_get_protocol(xen_session *se
   35.49  
   35.50  
   35.51  bool
   35.52 -xen_console_get_uri(xen_session *session, char **result, xen_console console)
   35.53 +xen_console_get_location(xen_session *session, char **result, xen_console console)
   35.54  {
   35.55      abstract_value param_values[] =
   35.56          {
   35.57 @@ -175,7 +180,7 @@ xen_console_get_uri(xen_session *session
   35.58      abstract_type result_type = abstract_type_string;
   35.59  
   35.60      *result = NULL;
   35.61 -    XEN_CALL_("console.get_uri");
   35.62 +    XEN_CALL_("console.get_location");
   35.63      return session->ok;
   35.64  }
   35.65  
   35.66 @@ -198,6 +203,73 @@ xen_console_get_vm(xen_session *session,
   35.67  
   35.68  
   35.69  bool
   35.70 +xen_console_get_other_config(xen_session *session, xen_string_string_map **result, xen_console console)
   35.71 +{
   35.72 +    abstract_value param_values[] =
   35.73 +        {
   35.74 +            { .type = &abstract_type_string,
   35.75 +              .u.string_val = console }
   35.76 +        };
   35.77 +
   35.78 +    abstract_type result_type = abstract_type_string_string_map;
   35.79 +
   35.80 +    *result = NULL;
   35.81 +    XEN_CALL_("console.get_other_config");
   35.82 +    return session->ok;
   35.83 +}
   35.84 +
   35.85 +
   35.86 +bool
   35.87 +xen_console_set_other_config(xen_session *session, xen_console console, xen_string_string_map *other_config)
   35.88 +{
   35.89 +    abstract_value param_values[] =
   35.90 +        {
   35.91 +            { .type = &abstract_type_string,
   35.92 +              .u.string_val = console },
   35.93 +            { .type = &abstract_type_string_string_map,
   35.94 +              .u.set_val = (arbitrary_set *)other_config }
   35.95 +        };
   35.96 +
   35.97 +    xen_call_(session, "console.set_other_config", param_values, 2, NULL, NULL);
   35.98 +    return session->ok;
   35.99 +}
  35.100 +
  35.101 +
  35.102 +bool
  35.103 +xen_console_add_to_other_config(xen_session *session, xen_console console, char *key, char *value)
  35.104 +{
  35.105 +    abstract_value param_values[] =
  35.106 +        {
  35.107 +            { .type = &abstract_type_string,
  35.108 +              .u.string_val = console },
  35.109 +            { .type = &abstract_type_string,
  35.110 +              .u.string_val = key },
  35.111 +            { .type = &abstract_type_string,
  35.112 +              .u.string_val = value }
  35.113 +        };
  35.114 +
  35.115 +    xen_call_(session, "console.add_to_other_config", param_values, 3, NULL, NULL);
  35.116 +    return session->ok;
  35.117 +}
  35.118 +
  35.119 +
  35.120 +bool
  35.121 +xen_console_remove_from_other_config(xen_session *session, xen_console console, char *key)
  35.122 +{
  35.123 +    abstract_value param_values[] =
  35.124 +        {
  35.125 +            { .type = &abstract_type_string,
  35.126 +              .u.string_val = console },
  35.127 +            { .type = &abstract_type_string,
  35.128 +              .u.string_val = key }
  35.129 +        };
  35.130 +
  35.131 +    xen_call_(session, "console.remove_from_other_config", param_values, 2, NULL, NULL);
  35.132 +    return session->ok;
  35.133 +}
  35.134 +
  35.135 +
  35.136 +bool
  35.137  xen_console_get_uuid(xen_session *session, char **result, xen_console console)
  35.138  {
  35.139      *result = session->ok ? xen_strdup_((char *)console) : NULL;
    36.1 --- a/tools/libxen/src/xen_host.c	Thu Feb 22 09:42:13 2007 -0700
    36.2 +++ b/tools/libxen/src/xen_host.c	Thu Feb 22 10:15:29 2007 -0700
    36.3 @@ -1,5 +1,5 @@
    36.4  /*
    36.5 - * Copyright (c) 2006, XenSource Inc.
    36.6 + * Copyright (c) 2006-2007, XenSource Inc.
    36.7   *
    36.8   * This library is free software; you can redistribute it and/or
    36.9   * modify it under the terms of the GNU Lesser General Public
   36.10 @@ -58,6 +58,9 @@ static const struct_member xen_host_reco
   36.11          { .key = "other_config",
   36.12            .type = &abstract_type_string_string_map,
   36.13            .offset = offsetof(xen_host_record, other_config) },
   36.14 +        { .key = "supported_bootloaders",
   36.15 +          .type = &abstract_type_string_set,
   36.16 +          .offset = offsetof(xen_host_record, supported_bootloaders) },
   36.17          { .key = "resident_VMs",
   36.18            .type = &abstract_type_ref_set,
   36.19            .offset = offsetof(xen_host_record, resident_vms) },
   36.20 @@ -107,6 +110,7 @@ xen_host_record_free(xen_host_record *re
   36.21      free(record->name_description);
   36.22      xen_string_string_map_free(record->software_version);
   36.23      xen_string_string_map_free(record->other_config);
   36.24 +    xen_string_set_free(record->supported_bootloaders);
   36.25      xen_vm_record_opt_set_free(record->resident_vms);
   36.26      xen_string_string_map_free(record->logging);
   36.27      xen_pif_record_opt_set_free(record->pifs);
   36.28 @@ -160,37 +164,6 @@ xen_host_get_by_uuid(xen_session *sessio
   36.29  
   36.30  
   36.31  bool
   36.32 -xen_host_create(xen_session *session, xen_host *result, xen_host_record *record)
   36.33 -{
   36.34 -    abstract_value param_values[] =
   36.35 -        {
   36.36 -            { .type = &xen_host_record_abstract_type_,
   36.37 -              .u.struct_val = record }
   36.38 -        };
   36.39 -
   36.40 -    abstract_type result_type = abstract_type_string;
   36.41 -
   36.42 -    *result = NULL;
   36.43 -    XEN_CALL_("host.create");
   36.44 -    return session->ok;
   36.45 -}
   36.46 -
   36.47 -
   36.48 -bool
   36.49 -xen_host_destroy(xen_session *session, xen_host host)
   36.50 -{
   36.51 -    abstract_value param_values[] =
   36.52 -        {
   36.53 -            { .type = &abstract_type_string,
   36.54 -              .u.string_val = host }
   36.55 -        };
   36.56 -
   36.57 -    xen_call_(session, "host.destroy", param_values, 1, NULL, NULL);
   36.58 -    return session->ok;
   36.59 -}
   36.60 -
   36.61 -
   36.62 -bool
   36.63  xen_host_get_by_name_label(xen_session *session, struct xen_host_set **result, char *label)
   36.64  {
   36.65      abstract_value param_values[] =
   36.66 @@ -276,6 +249,23 @@ xen_host_get_other_config(xen_session *s
   36.67  
   36.68  
   36.69  bool
   36.70 +xen_host_get_supported_bootloaders(xen_session *session, struct xen_string_set **result, xen_host host)
   36.71 +{
   36.72 +    abstract_value param_values[] =
   36.73 +        {
   36.74 +            { .type = &abstract_type_string,
   36.75 +              .u.string_val = host }
   36.76 +        };
   36.77 +
   36.78 +    abstract_type result_type = abstract_type_string_set;
   36.79 +
   36.80 +    *result = NULL;
   36.81 +    XEN_CALL_("host.get_supported_bootloaders");
   36.82 +    return session->ok;
   36.83 +}
   36.84 +
   36.85 +
   36.86 +bool
   36.87  xen_host_get_resident_vms(xen_session *session, struct xen_vm_set **result, xen_host host)
   36.88  {
   36.89      abstract_value param_values[] =
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/libxen/src/xen_string_set.c	Thu Feb 22 10:15:29 2007 -0700
    37.3 @@ -0,0 +1,47 @@
    37.4 +/*
    37.5 + * Copyright (c) 2006-2007, XenSource Inc.
    37.6 + *
    37.7 + * This library is free software; you can redistribute it and/or
    37.8 + * modify it under the terms of the GNU Lesser General Public
    37.9 + * License as published by the Free Software Foundation; either
   37.10 + * version 2.1 of the License, or (at your option) any later version.
   37.11 + *
   37.12 + * This library is distributed in the hope that it will be useful,
   37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   37.15 + * Lesser General Public License for more details.
   37.16 + *
   37.17 + * You should have received a copy of the GNU Lesser General Public
   37.18 + * License along with this library; if not, write to the Free Software
   37.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   37.20 + */
   37.21 +
   37.22 +
   37.23 +#include "xen_internal.h"
   37.24 +#include "xen_string_set.h"
   37.25 +
   37.26 +
   37.27 +xen_string_set *
   37.28 +xen_string_set_alloc(size_t size)
   37.29 +{
   37.30 +    xen_string_set *result = calloc(1, sizeof(xen_string_set) +
   37.31 +                                    size * sizeof(char *));
   37.32 +    result->size = size;
   37.33 +    return result;
   37.34 +}
   37.35 +
   37.36 +void
   37.37 +xen_string_set_free(xen_string_set *set)
   37.38 +{
   37.39 +    if (set == NULL)
   37.40 +    {
   37.41 +        return;
   37.42 +    }
   37.43 +    size_t n = set->size;
   37.44 +    for (size_t i = 0; i < n; i++)
   37.45 +    {
   37.46 +       free(set->contents[i]);
   37.47 +    }
   37.48 +
   37.49 +    free(set);
   37.50 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tools/libxen/src/xen_string_set.h	Thu Feb 22 10:15:29 2007 -0700
    38.3 @@ -0,0 +1,47 @@
    38.4 +/*
    38.5 + * Copyright (c) 2006-2007, XenSource Inc.
    38.6 + *
    38.7 + * This library is free software; you can redistribute it and/or
    38.8 + * modify it under the terms of the GNU Lesser General Public
    38.9 + * License as published by the Free Software Foundation; either
   38.10 + * version 2.1 of the License, or (at your option) any later version.
   38.11 + *
   38.12 + * This library is distributed in the hope that it will be useful,
   38.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   38.15 + * Lesser General Public License for more details.
   38.16 + *
   38.17 + * You should have received a copy of the GNU Lesser General Public
   38.18 + * License along with this library; if not, write to the Free Software
   38.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   38.20 + */
   38.21 +
   38.22 +#ifndef XEN_STRING_SET_H
   38.23 +#define XEN_STRING_SET_H
   38.24 +
   38.25 +
   38.26 +#include "xen_common.h"
   38.27 +
   38.28 +
   38.29 +typedef struct xen_string_set
   38.30 +{
   38.31 +    size_t size;
   38.32 +    char *contents[];
   38.33 +} xen_string_set;
   38.34 +
   38.35 +
   38.36 +/**
   38.37 + * Allocate a xen_string_set of the given size.
   38.38 + */
   38.39 +extern xen_string_set *
   38.40 +xen_string_set_alloc(size_t size);
   38.41 +
   38.42 +/**
   38.43 + * Free the given xen_string_set.  The given set must have been allocated
   38.44 + * by this library.
   38.45 + */
   38.46 +extern void
   38.47 +xen_string_set_free(xen_string_set *set);
   38.48 +
   38.49 +
   38.50 +#endif
    39.1 --- a/tools/libxen/src/xen_vbd.c	Thu Feb 22 09:42:13 2007 -0700
    39.2 +++ b/tools/libxen/src/xen_vbd.c	Thu Feb 22 10:15:29 2007 -0700
    39.3 @@ -1,5 +1,5 @@
    39.4  /*
    39.5 - * Copyright (c) 2006, XenSource Inc.
    39.6 + * Copyright (c) 2006-2007, XenSource Inc.
    39.7   *
    39.8   * This library is free software; you can redistribute it and/or
    39.9   * modify it under the terms of the GNU Lesser General Public
   39.10 @@ -22,8 +22,11 @@
   39.11  
   39.12  #include "xen_common.h"
   39.13  #include "xen_internal.h"
   39.14 +#include "xen_string_string_map.h"
   39.15  #include "xen_vbd.h"
   39.16 +#include "xen_vbd_metrics.h"
   39.17  #include "xen_vbd_mode_internal.h"
   39.18 +#include "xen_vbd_type_internal.h"
   39.19  #include "xen_vdi.h"
   39.20  #include "xen_vm.h"
   39.21  
   39.22 @@ -60,12 +63,18 @@ static const struct_member xen_vbd_recor
   39.23          { .key = "mode",
   39.24            .type = &xen_vbd_mode_abstract_type_,
   39.25            .offset = offsetof(xen_vbd_record, mode) },
   39.26 -        { .key = "io_read_kbs",
   39.27 -          .type = &abstract_type_float,
   39.28 -          .offset = offsetof(xen_vbd_record, io_read_kbs) },
   39.29 -        { .key = "io_write_kbs",
   39.30 -          .type = &abstract_type_float,
   39.31 -          .offset = offsetof(xen_vbd_record, io_write_kbs) }
   39.32 +        { .key = "type",
   39.33 +          .type = &xen_vbd_type_abstract_type_,
   39.34 +          .offset = offsetof(xen_vbd_record, type) },
   39.35 +        { .key = "qos_algorithm_type",
   39.36 +          .type = &abstract_type_string,
   39.37 +          .offset = offsetof(xen_vbd_record, qos_algorithm_type) },
   39.38 +        { .key = "qos_algorithm_params",
   39.39 +          .type = &abstract_type_string_string_map,
   39.40 +          .offset = offsetof(xen_vbd_record, qos_algorithm_params) },
   39.41 +        { .key = "metrics",
   39.42 +          .type = &abstract_type_ref,
   39.43 +          .offset = offsetof(xen_vbd_record, metrics) }
   39.44      };
   39.45  
   39.46  const abstract_type xen_vbd_record_abstract_type_ =
   39.47 @@ -90,6 +99,9 @@ xen_vbd_record_free(xen_vbd_record *reco
   39.48      xen_vm_record_opt_free(record->vm);
   39.49      xen_vdi_record_opt_free(record->vdi);
   39.50      free(record->device);
   39.51 +    free(record->qos_algorithm_type);
   39.52 +    xen_string_string_map_free(record->qos_algorithm_params);
   39.53 +    xen_vbd_metrics_record_opt_free(record->metrics);
   39.54      free(record);
   39.55  }
   39.56  
   39.57 @@ -242,15 +254,13 @@ xen_vbd_get_mode(xen_session *session, e
   39.58          };
   39.59  
   39.60      abstract_type result_type = xen_vbd_mode_abstract_type_;
   39.61 -    char *result_str = NULL;
   39.62      XEN_CALL_("VBD.get_mode");
   39.63 -    *result = xen_vbd_mode_from_string(session, result_str);
   39.64      return session->ok;
   39.65  }
   39.66  
   39.67  
   39.68  bool
   39.69 -xen_vbd_get_io_read_kbs(xen_session *session, double *result, xen_vbd vbd)
   39.70 +xen_vbd_get_type(xen_session *session, enum xen_vbd_type *result, xen_vbd vbd)
   39.71  {
   39.72      abstract_value param_values[] =
   39.73          {
   39.74 @@ -258,15 +268,14 @@ xen_vbd_get_io_read_kbs(xen_session *ses
   39.75                .u.string_val = vbd }
   39.76          };
   39.77  
   39.78 -    abstract_type result_type = abstract_type_float;
   39.79 -
   39.80 -    XEN_CALL_("VBD.get_io_read_kbs");
   39.81 +    abstract_type result_type = xen_vbd_type_abstract_type_;
   39.82 +    XEN_CALL_("VBD.get_type");
   39.83      return session->ok;
   39.84  }
   39.85  
   39.86  
   39.87  bool
   39.88 -xen_vbd_get_io_write_kbs(xen_session *session, double *result, xen_vbd vbd)
   39.89 +xen_vbd_get_qos_algorithm_type(xen_session *session, char **result, xen_vbd vbd)
   39.90  {
   39.91      abstract_value param_values[] =
   39.92          {
   39.93 @@ -274,9 +283,44 @@ xen_vbd_get_io_write_kbs(xen_session *se
   39.94                .u.string_val = vbd }
   39.95          };
   39.96  
   39.97 -    abstract_type result_type = abstract_type_float;
   39.98 +    abstract_type result_type = abstract_type_string;
   39.99  
  39.100 -    XEN_CALL_("VBD.get_io_write_kbs");
  39.101 +    *result = NULL;
  39.102 +    XEN_CALL_("VBD.get_qos_algorithm_type");
  39.103 +    return session->ok;
  39.104 +}
  39.105 +
  39.106 +
  39.107 +bool
  39.108 +xen_vbd_get_qos_algorithm_params(xen_session *session, xen_string_string_map **result, xen_vbd vbd)
  39.109 +{
  39.110 +    abstract_value param_values[] =
  39.111 +        {
  39.112 +            { .type = &abstract_type_string,
  39.113 +              .u.string_val = vbd }
  39.114 +        };
  39.115 +
  39.116 +    abstract_type result_type = abstract_type_string_string_map;
  39.117 +
  39.118 +    *result = NULL;
  39.119 +    XEN_CALL_("VBD.get_qos_algorithm_params");
  39.120 +    return session->ok;
  39.121 +}
  39.122 +
  39.123 +
  39.124 +bool
  39.125 +xen_vbd_get_metrics(xen_session *session, xen_vbd_metrics *result, xen_vbd vbd)
  39.126 +{
  39.127 +    abstract_value param_values[] =
  39.128 +        {
  39.129 +            { .type = &abstract_type_string,
  39.130 +              .u.string_val = vbd }
  39.131 +        };
  39.132 +
  39.133 +    abstract_type result_type = abstract_type_string;
  39.134 +
  39.135 +    *result = NULL;
  39.136 +    XEN_CALL_("VBD.get_metrics");
  39.137      return session->ok;
  39.138  }
  39.139  
  39.140 @@ -330,6 +374,88 @@ xen_vbd_set_mode(xen_session *session, x
  39.141  
  39.142  
  39.143  bool
  39.144 +xen_vbd_set_type(xen_session *session, xen_vbd vbd, enum xen_vbd_type type)
  39.145 +{
  39.146 +    abstract_value param_values[] =
  39.147 +        {
  39.148 +            { .type = &abstract_type_string,
  39.149 +              .u.string_val = vbd },
  39.150 +            { .type = &xen_vbd_type_abstract_type_,
  39.151 +              .u.string_val = xen_vbd_type_to_string(type) }
  39.152 +        };
  39.153 +
  39.154 +    xen_call_(session, "VBD.set_type", param_values, 2, NULL, NULL);
  39.155 +    return session->ok;
  39.156 +}
  39.157 +
  39.158 +
  39.159 +bool
  39.160 +xen_vbd_set_qos_algorithm_type(xen_session *session, xen_vbd vbd, char *algorithm_type)
  39.161 +{
  39.162 +    abstract_value param_values[] =
  39.163 +        {
  39.164 +            { .type = &abstract_type_string,
  39.165 +              .u.string_val = vbd },
  39.166 +            { .type = &abstract_type_string,
  39.167 +              .u.string_val = algorithm_type }
  39.168 +        };
  39.169 +
  39.170 +    xen_call_(session, "VBD.set_qos_algorithm_type", param_values, 2, NULL, NULL);
  39.171 +    return session->ok;
  39.172 +}
  39.173 +
  39.174 +
  39.175 +bool
  39.176 +xen_vbd_set_qos_algorithm_params(xen_session *session, xen_vbd vbd, xen_string_string_map *algorithm_params)
  39.177 +{
  39.178 +    abstract_value param_values[] =
  39.179 +        {
  39.180 +            { .type = &abstract_type_string,
  39.181 +              .u.string_val = vbd },
  39.182 +            { .type = &abstract_type_string_string_map,
  39.183 +              .u.set_val = (arbitrary_set *)algorithm_params }
  39.184 +        };
  39.185 +
  39.186 +    xen_call_(session, "VBD.set_qos_algorithm_params", param_values, 2, NULL, NULL);
  39.187 +    return session->ok;
  39.188 +}
  39.189 +
  39.190 +
  39.191 +bool
  39.192 +xen_vbd_add_to_qos_algorithm_params(xen_session *session, xen_vbd vbd, char *key, char *value)
  39.193 +{
  39.194 +    abstract_value param_values[] =
  39.195 +        {
  39.196 +            { .type = &abstract_type_string,
  39.197 +              .u.string_val = vbd },
  39.198 +            { .type = &abstract_type_string,
  39.199 +              .u.string_val = key },
  39.200 +            { .type = &abstract_type_string,
  39.201 +              .u.string_val = value }
  39.202 +        };
  39.203 +
  39.204 +    xen_call_(session, "VBD.add_to_qos_algorithm_params", param_values, 3, NULL, NULL);
  39.205 +    return session->ok;
  39.206 +}
  39.207 +
  39.208 +
  39.209 +bool
  39.210 +xen_vbd_remove_from_qos_algorithm_params(xen_session *session, xen_vbd vbd, char *key)
  39.211 +{
  39.212 +    abstract_value param_values[] =
  39.213 +        {
  39.214 +            { .type = &abstract_type_string,
  39.215 +              .u.string_val = vbd },
  39.216 +            { .type = &abstract_type_string,
  39.217 +              .u.string_val = key }
  39.218 +        };
  39.219 +
  39.220 +    xen_call_(session, "VBD.remove_from_qos_algorithm_params", param_values, 2, NULL, NULL);
  39.221 +    return session->ok;
  39.222 +}
  39.223 +
  39.224 +
  39.225 +bool
  39.226  xen_vbd_media_change(xen_session *session, xen_vbd vbd, xen_vdi vdi)
  39.227  {
  39.228      abstract_value param_values[] =
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tools/libxen/src/xen_vbd_metrics.c	Thu Feb 22 10:15:29 2007 -0700
    40.3 @@ -0,0 +1,150 @@
    40.4 +/*
    40.5 + * Copyright (c) 2006-2007, XenSource Inc.
    40.6 + *
    40.7 + * This library is free software; you can redistribute it and/or
    40.8 + * modify it under the terms of the GNU Lesser General Public
    40.9 + * License as published by the Free Software Foundation; either
   40.10 + * version 2.1 of the License, or (at your option) any later version.
   40.11 + *
   40.12 + * This library is distributed in the hope that it will be useful,
   40.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   40.15 + * Lesser General Public License for more details.
   40.16 + *
   40.17 + * You should have received a copy of the GNU Lesser General Public
   40.18 + * License along with this library; if not, write to the Free Software
   40.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   40.20 + */
   40.21 +
   40.22 +
   40.23 +#include <stddef.h>
   40.24 +#include <stdlib.h>
   40.25 +
   40.26 +#include "xen_common.h"
   40.27 +#include "xen_internal.h"
   40.28 +#include "xen_vbd_metrics.h"
   40.29 +
   40.30 +
   40.31 +XEN_FREE(xen_vbd_metrics)
   40.32 +XEN_SET_ALLOC_FREE(xen_vbd_metrics)
   40.33 +XEN_ALLOC(xen_vbd_metrics_record)
   40.34 +XEN_SET_ALLOC_FREE(xen_vbd_metrics_record)
   40.35 +XEN_ALLOC(xen_vbd_metrics_record_opt)
   40.36 +XEN_RECORD_OPT_FREE(xen_vbd_metrics)
   40.37 +XEN_SET_ALLOC_FREE(xen_vbd_metrics_record_opt)
   40.38 +
   40.39 +
   40.40 +static const struct_member xen_vbd_metrics_record_struct_members[] =
   40.41 +    {
   40.42 +        { .key = "uuid",
   40.43 +          .type = &abstract_type_string,
   40.44 +          .offset = offsetof(xen_vbd_metrics_record, uuid) },
   40.45 +        { .key = "io_read_kbs",
   40.46 +          .type = &abstract_type_float,
   40.47 +          .offset = offsetof(xen_vbd_metrics_record, io_read_kbs) },
   40.48 +        { .key = "io_write_kbs",
   40.49 +          .type = &abstract_type_float,
   40.50 +          .offset = offsetof(xen_vbd_metrics_record, io_write_kbs) }
   40.51 +    };
   40.52 +
   40.53 +const abstract_type xen_vbd_metrics_record_abstract_type_ =
   40.54 +    {
   40.55 +       .typename = STRUCT,
   40.56 +       .struct_size = sizeof(xen_vbd_metrics_record),
   40.57 +       .member_count =
   40.58 +           sizeof(xen_vbd_metrics_record_struct_members) / sizeof(struct_member),
   40.59 +       .members = xen_vbd_metrics_record_struct_members
   40.60 +    };
   40.61 +
   40.62 +
   40.63 +void
   40.64 +xen_vbd_metrics_record_free(xen_vbd_metrics_record *record)
   40.65 +{
   40.66 +    if (record == NULL)
   40.67 +    {
   40.68 +        return;
   40.69 +    }
   40.70 +    free(record->handle);
   40.71 +    free(record->uuid);
   40.72 +    free(record);
   40.73 +}
   40.74 +
   40.75 +
   40.76 +bool
   40.77 +xen_vbd_metrics_get_record(xen_session *session, xen_vbd_metrics_record **result, xen_vbd_metrics vbd_metrics)
   40.78 +{
   40.79 +    abstract_value param_values[] =
   40.80 +        {
   40.81 +            { .type = &abstract_type_string,
   40.82 +              .u.string_val = vbd_metrics }
   40.83 +        };
   40.84 +
   40.85 +    abstract_type result_type = xen_vbd_metrics_record_abstract_type_;
   40.86 +
   40.87 +    *result = NULL;
   40.88 +    XEN_CALL_("VBD_metrics.get_record");
   40.89 +
   40.90 +    if (session->ok)
   40.91 +    {
   40.92 +       (*result)->handle = xen_strdup_((*result)->uuid);
   40.93 +    }
   40.94 +
   40.95 +    return session->ok;
   40.96 +}
   40.97 +
   40.98 +
   40.99 +bool
  40.100 +xen_vbd_metrics_get_by_uuid(xen_session *session, xen_vbd_metrics *result, char *uuid)
  40.101 +{
  40.102 +    abstract_value param_values[] =
  40.103 +        {
  40.104 +            { .type = &abstract_type_string,
  40.105 +              .u.string_val = uuid }
  40.106 +        };
  40.107 +
  40.108 +    abstract_type result_type = abstract_type_string;
  40.109 +
  40.110 +    *result = NULL;
  40.111 +    XEN_CALL_("VBD_metrics.get_by_uuid");
  40.112 +    return session->ok;
  40.113 +}
  40.114 +
  40.115 +
  40.116 +bool
  40.117 +xen_vbd_metrics_get_io_read_kbs(xen_session *session, double *result, xen_vbd_metrics vbd_metrics)
  40.118 +{
  40.119 +    abstract_value param_values[] =
  40.120 +        {
  40.121 +            { .type = &abstract_type_string,
  40.122 +              .u.string_val = vbd_metrics }
  40.123 +        };
  40.124 +
  40.125 +    abstract_type result_type = abstract_type_float;
  40.126 +
  40.127 +    XEN_CALL_("VBD_metrics.get_io_read_kbs");
  40.128 +    return session->ok;
  40.129 +}
  40.130 +
  40.131 +
  40.132 +bool
  40.133 +xen_vbd_metrics_get_io_write_kbs(xen_session *session, double *result, xen_vbd_metrics vbd_metrics)
  40.134 +{
  40.135 +    abstract_value param_values[] =
  40.136 +        {
  40.137 +            { .type = &abstract_type_string,
  40.138 +              .u.string_val = vbd_metrics }
  40.139 +        };
  40.140 +
  40.141 +    abstract_type result_type = abstract_type_float;
  40.142 +
  40.143 +    XEN_CALL_("VBD_metrics.get_io_write_kbs");
  40.144 +    return session->ok;
  40.145 +}
  40.146 +
  40.147 +
  40.148 +bool
  40.149 +xen_vbd_metrics_get_uuid(xen_session *session, char **result, xen_vbd_metrics vbd_metrics)
  40.150 +{
  40.151 +    *result = session->ok ? xen_strdup_((char *)vbd_metrics) : NULL;
  40.152 +    return session->ok;
  40.153 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/tools/libxen/src/xen_vbd_type.c	Thu Feb 22 10:15:29 2007 -0700
    41.3 @@ -0,0 +1,81 @@
    41.4 +/*
    41.5 + * Copyright (c) 2006-2007, XenSource Inc.
    41.6 + *
    41.7 + * This library is free software; you can redistribute it and/or
    41.8 + * modify it under the terms of the GNU Lesser General Public
    41.9 + * License as published by the Free Software Foundation; either
   41.10 + * version 2.1 of the License, or (at your option) any later version.
   41.11 + *
   41.12 + * This library is distributed in the hope that it will be useful,
   41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   41.15 + * Lesser General Public License for more details.
   41.16 + *
   41.17 + * You should have received a copy of the GNU Lesser General Public
   41.18 + * License along with this library; if not, write to the Free Software
   41.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   41.20 + */
   41.21 +
   41.22 +#include <string.h>
   41.23 +
   41.24 +#include "xen_internal.h"
   41.25 +#include "xen_vbd_type.h"
   41.26 +#include "xen_vbd_type_internal.h"
   41.27 +
   41.28 +
   41.29 +/*
   41.30 + * Maintain this in the same order as the enum declaration!
   41.31 + */
   41.32 +static const char *lookup_table[] =
   41.33 +{
   41.34 +    "CD",
   41.35 +    "Disk"
   41.36 +};
   41.37 +
   41.38 +
   41.39 +extern xen_vbd_type_set *
   41.40 +xen_vbd_type_set_alloc(size_t size)
   41.41 +{
   41.42 +    return calloc(1, sizeof(xen_vbd_type_set) +
   41.43 +                  size * sizeof(enum xen_vbd_type));
   41.44 +}
   41.45 +
   41.46 +
   41.47 +extern void
   41.48 +xen_vbd_type_set_free(xen_vbd_type_set *set)
   41.49 +{
   41.50 +    free(set);
   41.51 +}
   41.52 +
   41.53 +
   41.54 +const char *
   41.55 +xen_vbd_type_to_string(enum xen_vbd_type val)
   41.56 +{
   41.57 +    return lookup_table[val];
   41.58 +}
   41.59 +
   41.60 +
   41.61 +extern enum xen_vbd_type
   41.62 +xen_vbd_type_from_string(xen_session *session, const char *str)
   41.63 +{
   41.64 +    return ENUM_LOOKUP(session, str, lookup_table);
   41.65 +}
   41.66 +
   41.67 +
   41.68 +const abstract_type xen_vbd_type_abstract_type_ =
   41.69 +    {
   41.70 +        .typename = ENUM,
   41.71 +        .enum_marshaller =
   41.72 +             (const char *(*)(int))&xen_vbd_type_to_string,
   41.73 +        .enum_demarshaller =
   41.74 +             (int (*)(xen_session *, const char *))&xen_vbd_type_from_string
   41.75 +    };
   41.76 +
   41.77 +
   41.78 +const abstract_type xen_vbd_type_set_abstract_type_ =
   41.79 +    {
   41.80 +        .typename = SET,
   41.81 +        .child = &xen_vbd_type_abstract_type_
   41.82 +    };
   41.83 +
   41.84 +
    42.1 --- a/tools/libxen/src/xen_vif.c	Thu Feb 22 09:42:13 2007 -0700
    42.2 +++ b/tools/libxen/src/xen_vif.c	Thu Feb 22 10:15:29 2007 -0700
    42.3 @@ -1,5 +1,5 @@
    42.4  /*
    42.5 - * Copyright (c) 2006, XenSource Inc.
    42.6 + * Copyright (c) 2006-2007, XenSource Inc.
    42.7   *
    42.8   * This library is free software; you can redistribute it and/or
    42.9   * modify it under the terms of the GNU Lesser General Public
   42.10 @@ -23,7 +23,9 @@
   42.11  #include "xen_common.h"
   42.12  #include "xen_internal.h"
   42.13  #include "xen_network.h"
   42.14 +#include "xen_string_string_map.h"
   42.15  #include "xen_vif.h"
   42.16 +#include "xen_vif_metrics.h"
   42.17  #include "xen_vm.h"
   42.18  
   42.19  
   42.20 @@ -56,12 +58,15 @@ static const struct_member xen_vif_recor
   42.21          { .key = "MTU",
   42.22            .type = &abstract_type_int,
   42.23            .offset = offsetof(xen_vif_record, mtu) },
   42.24 -        { .key = "io_read_kbs",
   42.25 -          .type = &abstract_type_float,
   42.26 -          .offset = offsetof(xen_vif_record, io_read_kbs) },
   42.27 -        { .key = "io_write_kbs",
   42.28 -          .type = &abstract_type_float,
   42.29 -          .offset = offsetof(xen_vif_record, io_write_kbs) }
   42.30 +        { .key = "qos_algorithm_type",
   42.31 +          .type = &abstract_type_string,
   42.32 +          .offset = offsetof(xen_vif_record, qos_algorithm_type) },
   42.33 +        { .key = "qos_algorithm_params",
   42.34 +          .type = &abstract_type_string_string_map,
   42.35 +          .offset = offsetof(xen_vif_record, qos_algorithm_params) },
   42.36 +        { .key = "metrics",
   42.37 +          .type = &abstract_type_ref,
   42.38 +          .offset = offsetof(xen_vif_record, metrics) }
   42.39      };
   42.40  
   42.41  const abstract_type xen_vif_record_abstract_type_ =
   42.42 @@ -87,6 +92,9 @@ xen_vif_record_free(xen_vif_record *reco
   42.43      xen_network_record_opt_free(record->network);
   42.44      xen_vm_record_opt_free(record->vm);
   42.45      free(record->mac);
   42.46 +    free(record->qos_algorithm_type);
   42.47 +    xen_string_string_map_free(record->qos_algorithm_params);
   42.48 +    xen_vif_metrics_record_opt_free(record->metrics);
   42.49      free(record);
   42.50  }
   42.51  
   42.52 @@ -247,7 +255,7 @@ xen_vif_get_mtu(xen_session *session, in
   42.53  
   42.54  
   42.55  bool
   42.56 -xen_vif_get_io_read_kbs(xen_session *session, double *result, xen_vif vif)
   42.57 +xen_vif_get_qos_algorithm_type(xen_session *session, char **result, xen_vif vif)
   42.58  {
   42.59      abstract_value param_values[] =
   42.60          {
   42.61 @@ -255,15 +263,16 @@ xen_vif_get_io_read_kbs(xen_session *ses
   42.62                .u.string_val = vif }
   42.63          };
   42.64  
   42.65 -    abstract_type result_type = abstract_type_float;
   42.66 +    abstract_type result_type = abstract_type_string;
   42.67  
   42.68 -    XEN_CALL_("VIF.get_io_read_kbs");
   42.69 +    *result = NULL;
   42.70 +    XEN_CALL_("VIF.get_qos_algorithm_type");
   42.71      return session->ok;
   42.72  }
   42.73  
   42.74  
   42.75  bool
   42.76 -xen_vif_get_io_write_kbs(xen_session *session, double *result, xen_vif vif)
   42.77 +xen_vif_get_qos_algorithm_params(xen_session *session, xen_string_string_map **result, xen_vif vif)
   42.78  {
   42.79      abstract_value param_values[] =
   42.80          {
   42.81 @@ -271,9 +280,27 @@ xen_vif_get_io_write_kbs(xen_session *se
   42.82                .u.string_val = vif }
   42.83          };
   42.84  
   42.85 -    abstract_type result_type = abstract_type_float;
   42.86 +    abstract_type result_type = abstract_type_string_string_map;
   42.87  
   42.88 -    XEN_CALL_("VIF.get_io_write_kbs");
   42.89 +    *result = NULL;
   42.90 +    XEN_CALL_("VIF.get_qos_algorithm_params");
   42.91 +    return session->ok;
   42.92 +}
   42.93 +
   42.94 +
   42.95 +bool
   42.96 +xen_vif_get_metrics(xen_session *session, xen_vif_metrics *result, xen_vif vif)
   42.97 +{
   42.98 +    abstract_value param_values[] =
   42.99 +        {
  42.100 +            { .type = &abstract_type_string,
  42.101 +              .u.string_val = vif }
  42.102 +        };
  42.103 +
  42.104 +    abstract_type result_type = abstract_type_string;
  42.105 +
  42.106 +    *result = NULL;
  42.107 +    XEN_CALL_("VIF.get_metrics");
  42.108      return session->ok;
  42.109  }
  42.110  
  42.111 @@ -327,6 +354,72 @@ xen_vif_set_mtu(xen_session *session, xe
  42.112  
  42.113  
  42.114  bool
  42.115 +xen_vif_set_qos_algorithm_type(xen_session *session, xen_vif vif, char *algorithm_type)
  42.116 +{
  42.117 +    abstract_value param_values[] =
  42.118 +        {
  42.119 +            { .type = &abstract_type_string,
  42.120 +              .u.string_val = vif },
  42.121 +            { .type = &abstract_type_string,
  42.122 +              .u.string_val = algorithm_type }
  42.123 +        };
  42.124 +
  42.125 +    xen_call_(session, "VIF.set_qos_algorithm_type", param_values, 2, NULL, NULL);
  42.126 +    return session->ok;
  42.127 +}
  42.128 +
  42.129 +
  42.130 +bool
  42.131 +xen_vif_set_qos_algorithm_params(xen_session *session, xen_vif vif, xen_string_string_map *algorithm_params)
  42.132 +{
  42.133 +    abstract_value param_values[] =
  42.134 +        {
  42.135 +            { .type = &abstract_type_string,
  42.136 +              .u.string_val = vif },
  42.137 +            { .type = &abstract_type_string_string_map,
  42.138 +              .u.set_val = (arbitrary_set *)algorithm_params }
  42.139 +        };
  42.140 +
  42.141 +    xen_call_(session, "VIF.set_qos_algorithm_params", param_values, 2, NULL, NULL);
  42.142 +    return session->ok;
  42.143 +}
  42.144 +
  42.145 +
  42.146 +bool
  42.147 +xen_vif_add_to_qos_algorithm_params(xen_session *session, xen_vif vif, char *key, char *value)
  42.148 +{
  42.149 +    abstract_value param_values[] =
  42.150 +        {
  42.151 +            { .type = &abstract_type_string,
  42.152 +              .u.string_val = vif },
  42.153 +            { .type = &abstract_type_string,
  42.154 +              .u.string_val = key },
  42.155 +            { .type = &abstract_type_string,
  42.156 +              .u.string_val = value }
  42.157 +        };
  42.158 +
  42.159 +    xen_call_(session, "VIF.add_to_qos_algorithm_params", param_values, 3, NULL, NULL);
  42.160 +    return session->ok;
  42.161 +}
  42.162 +
  42.163 +
  42.164 +bool
  42.165 +xen_vif_remove_from_qos_algorithm_params(xen_session *session, xen_vif vif, char *key)
  42.166 +{
  42.167 +    abstract_value param_values[] =
  42.168 +        {
  42.169 +            { .type = &abstract_type_string,
  42.170 +              .u.string_val = vif },
  42.171 +            { .type = &abstract_type_string,
  42.172 +              .u.string_val = key }
  42.173 +        };
  42.174 +
  42.175 +    xen_call_(session, "VIF.remove_from_qos_algorithm_params", param_values, 2, NULL, NULL);
  42.176 +    return session->ok;
  42.177 +}
  42.178 +
  42.179 +
  42.180 +bool
  42.181  xen_vif_get_uuid(xen_session *session, char **result, xen_vif vif)
  42.182  {
  42.183      *result = session->ok ? xen_strdup_((char *)vif) : NULL;
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tools/libxen/src/xen_vif_metrics.c	Thu Feb 22 10:15:29 2007 -0700
    43.3 @@ -0,0 +1,150 @@
    43.4 +/*
    43.5 + * Copyright (c) 2006-2007, XenSource Inc.
    43.6 + *
    43.7 + * This library is free software; you can redistribute it and/or
    43.8 + * modify it under the terms of the GNU Lesser General Public
    43.9 + * License as published by the Free Software Foundation; either
   43.10 + * version 2.1 of the License, or (at your option) any later version.
   43.11 + *
   43.12 + * This library is distributed in the hope that it will be useful,
   43.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   43.15 + * Lesser General Public License for more details.
   43.16 + *
   43.17 + * You should have received a copy of the GNU Lesser General Public
   43.18 + * License along with this library; if not, write to the Free Software
   43.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   43.20 + */
   43.21 +
   43.22 +
   43.23 +#include <stddef.h>
   43.24 +#include <stdlib.h>
   43.25 +
   43.26 +#include "xen_common.h"
   43.27 +#include "xen_internal.h"
   43.28 +#include "xen_vif_metrics.h"
   43.29 +
   43.30 +
   43.31 +XEN_FREE(xen_vif_metrics)
   43.32 +XEN_SET_ALLOC_FREE(xen_vif_metrics)
   43.33 +XEN_ALLOC(xen_vif_metrics_record)
   43.34 +XEN_SET_ALLOC_FREE(xen_vif_metrics_record)
   43.35 +XEN_ALLOC(xen_vif_metrics_record_opt)
   43.36 +XEN_RECORD_OPT_FREE(xen_vif_metrics)
   43.37 +XEN_SET_ALLOC_FREE(xen_vif_metrics_record_opt)
   43.38 +
   43.39 +
   43.40 +static const struct_member xen_vif_metrics_record_struct_members[] =
   43.41 +    {
   43.42 +        { .key = "uuid",
   43.43 +          .type = &abstract_type_string,
   43.44 +          .offset = offsetof(xen_vif_metrics_record, uuid) },
   43.45 +        { .key = "io_read_kbs",
   43.46 +          .type = &abstract_type_float,
   43.47 +          .offset = offsetof(xen_vif_metrics_record, io_read_kbs) },
   43.48 +        { .key = "io_write_kbs",
   43.49 +          .type = &abstract_type_float,
   43.50 +          .offset = offsetof(xen_vif_metrics_record, io_write_kbs) }
   43.51 +    };
   43.52 +
   43.53 +const abstract_type xen_vif_metrics_record_abstract_type_ =
   43.54 +    {
   43.55 +       .typename = STRUCT,
   43.56 +       .struct_size = sizeof(xen_vif_metrics_record),
   43.57 +       .member_count =
   43.58 +           sizeof(xen_vif_metrics_record_struct_members) / sizeof(struct_member),
   43.59 +       .members = xen_vif_metrics_record_struct_members
   43.60 +    };
   43.61 +
   43.62 +
   43.63 +void
   43.64 +xen_vif_metrics_record_free(xen_vif_metrics_record *record)
   43.65 +{
   43.66 +    if (record == NULL)
   43.67 +    {
   43.68 +        return;
   43.69 +    }
   43.70 +    free(record->handle);
   43.71 +    free(record->uuid);
   43.72 +    free(record);
   43.73 +}
   43.74 +
   43.75 +
   43.76 +bool
   43.77 +xen_vif_metrics_get_record(xen_session *session, xen_vif_metrics_record **result, xen_vif_metrics vif_metrics)
   43.78 +{
   43.79 +    abstract_value param_values[] =
   43.80 +        {
   43.81 +            { .type = &abstract_type_string,
   43.82 +              .u.string_val = vif_metrics }
   43.83 +        };
   43.84 +
   43.85 +    abstract_type result_type = xen_vif_metrics_record_abstract_type_;
   43.86 +
   43.87 +    *result = NULL;
   43.88 +    XEN_CALL_("VIF_metrics.get_record");
   43.89 +
   43.90 +    if (session->ok)
   43.91 +    {
   43.92 +       (*result)->handle = xen_strdup_((*result)->uuid);
   43.93 +    }
   43.94 +
   43.95 +    return session->ok;
   43.96 +}
   43.97 +
   43.98 +
   43.99 +bool
  43.100 +xen_vif_metrics_get_by_uuid(xen_session *session, xen_vif_metrics *result, char *uuid)
  43.101 +{
  43.102 +    abstract_value param_values[] =
  43.103 +        {
  43.104 +            { .type = &abstract_type_string,
  43.105 +              .u.string_val = uuid }
  43.106 +        };
  43.107 +
  43.108 +    abstract_type result_type = abstract_type_string;
  43.109 +
  43.110 +    *result = NULL;
  43.111 +    XEN_CALL_("VIF_metrics.get_by_uuid");
  43.112 +    return session->ok;
  43.113 +}
  43.114 +
  43.115 +
  43.116 +bool
  43.117 +xen_vif_metrics_get_io_read_kbs(xen_session *session, double *result, xen_vif_metrics vif_metrics)
  43.118 +{
  43.119 +    abstract_value param_values[] =
  43.120 +        {
  43.121 +            { .type = &abstract_type_string,
  43.122 +              .u.string_val = vif_metrics }
  43.123 +        };
  43.124 +
  43.125 +    abstract_type result_type = abstract_type_float;
  43.126 +
  43.127 +    XEN_CALL_("VIF_metrics.get_io_read_kbs");
  43.128 +    return session->ok;
  43.129 +}
  43.130 +
  43.131 +
  43.132 +bool
  43.133 +xen_vif_metrics_get_io_write_kbs(xen_session *session, double *result, xen_vif_metrics vif_metrics)
  43.134 +{
  43.135 +    abstract_value param_values[] =
  43.136 +        {
  43.137 +            { .type = &abstract_type_string,
  43.138 +              .u.string_val = vif_metrics }
  43.139 +        };
  43.140 +
  43.141 +    abstract_type result_type = abstract_type_float;
  43.142 +
  43.143 +    XEN_CALL_("VIF_metrics.get_io_write_kbs");
  43.144 +    return session->ok;
  43.145 +}
  43.146 +
  43.147 +
  43.148 +bool
  43.149 +xen_vif_metrics_get_uuid(xen_session *session, char **result, xen_vif_metrics vif_metrics)
  43.150 +{
  43.151 +    *result = session->ok ? xen_strdup_((char *)vif_metrics) : NULL;
  43.152 +    return session->ok;
  43.153 +}
    44.1 --- a/tools/libxen/src/xen_vm_metrics.c	Thu Feb 22 09:42:13 2007 -0700
    44.2 +++ b/tools/libxen/src/xen_vm_metrics.c	Thu Feb 22 10:15:29 2007 -0700
    44.3 @@ -1,5 +1,5 @@
    44.4  /*
    44.5 - * Copyright (c) 2006, XenSource Inc.
    44.6 + * Copyright (c) 2006-2007, XenSource Inc.
    44.7   *
    44.8   * This library is free software; you can redistribute it and/or
    44.9   * modify it under the terms of the GNU Lesser General Public
   44.10 @@ -23,7 +23,6 @@
   44.11  #include "xen_common.h"
   44.12  #include "xen_int_float_map.h"
   44.13  #include "xen_internal.h"
   44.14 -#include "xen_vm.h"
   44.15  #include "xen_vm_metrics.h"
   44.16  
   44.17  
   44.18 @@ -41,9 +40,6 @@ static const struct_member xen_vm_metric
   44.19          { .key = "uuid",
   44.20            .type = &abstract_type_string,
   44.21            .offset = offsetof(xen_vm_metrics_record, uuid) },
   44.22 -        { .key = "VM",
   44.23 -          .type = &abstract_type_ref,
   44.24 -          .offset = offsetof(xen_vm_metrics_record, vm) },
   44.25          { .key = "memory_actual",
   44.26            .type = &abstract_type_int,
   44.27            .offset = offsetof(xen_vm_metrics_record, memory_actual) },
   44.28 @@ -74,7 +70,6 @@ xen_vm_metrics_record_free(xen_vm_metric
   44.29      }
   44.30      free(record->handle);
   44.31      free(record->uuid);
   44.32 -    xen_vm_record_opt_free(record->vm);
   44.33      xen_int_float_map_free(record->vcpus_utilisation);
   44.34      free(record);
   44.35  }
   44.36 @@ -121,23 +116,6 @@ xen_vm_metrics_get_by_uuid(xen_session *
   44.37  
   44.38  
   44.39  bool
   44.40 -xen_vm_metrics_get_vm(xen_session *session, xen_vm *result, xen_vm_metrics vm_metrics)
   44.41 -{
   44.42 -    abstract_value param_values[] =
   44.43 -        {
   44.44 -            { .type = &abstract_type_string,
   44.45 -              .u.string_val = vm_metrics }
   44.46 -        };
   44.47 -
   44.48 -    abstract_type result_type = abstract_type_string;
   44.49 -
   44.50 -    *result = NULL;
   44.51 -    XEN_CALL_("VM_metrics.get_VM");
   44.52 -    return session->ok;
   44.53 -}
   44.54 -
   44.55 -
   44.56 -bool
   44.57  xen_vm_metrics_get_memory_actual(xen_session *session, int64_t *result, xen_vm_metrics vm_metrics)
   44.58  {
   44.59      abstract_value param_values[] =
    45.1 --- a/tools/libxen/test/test_bindings.c	Thu Feb 22 09:42:13 2007 -0700
    45.2 +++ b/tools/libxen/test/test_bindings.c	Thu Feb 22 10:15:29 2007 -0700
    45.3 @@ -31,6 +31,7 @@
    45.4  #include "xen_vdi.h"
    45.5  #include "xen_console.h"
    45.6  #include "xen_vm.h"
    45.7 +#include "xen_vm_metrics.h"
    45.8  
    45.9  
   45.10  static void usage()
   45.11 @@ -61,6 +62,7 @@ typedef struct
   45.12  
   45.13  static xen_vm create_new_vm(xen_session *session, bool hvm);
   45.14  static void print_vm_power_state(xen_session *session, xen_vm vm);
   45.15 +static void print_vm_metrics(xen_session *session, xen_vm vm);
   45.16  
   45.17  
   45.18  static size_t
   45.19 @@ -220,6 +222,22 @@ int main(int argc, char **argv)
   45.20          return 1;
   45.21      }
   45.22  
   45.23 +    xen_string_set *supported_bootloaders;
   45.24 +    if (!xen_host_get_supported_bootloaders(session, &supported_bootloaders,
   45.25 +                                            host))
   45.26 +    {
   45.27 +        print_error(session);
   45.28 +        free(dmesg);
   45.29 +        xen_string_string_map_free(versions);
   45.30 +        xen_host_free(host);
   45.31 +        xen_vm_record_free(vm_record);
   45.32 +        xen_uuid_bytes_free(vm_uuid_bytes);
   45.33 +        xen_uuid_free(vm_uuid);
   45.34 +        xen_vm_free(vm);
   45.35 +        CLEANUP;
   45.36 +        return 1;
   45.37 +    }
   45.38 +
   45.39      printf("%s.\n", vm_uuid);
   45.40  
   45.41      fprintf(stderr, "In bytes, the VM UUID is ");
   45.42 @@ -239,29 +257,39 @@ int main(int argc, char **argv)
   45.43  
   45.44      printf("Host dmesg follows:\n%s\n\n", dmesg);
   45.45  
   45.46 +    printf("Host supports the following bootloaders:");
   45.47 +    for (size_t i = 0; i < supported_bootloaders->size; i++)
   45.48 +    {
   45.49 +        printf(" %s", supported_bootloaders->contents[i]);
   45.50 +    }
   45.51 +    printf("\n");
   45.52 +
   45.53      printf("%s.\n", vm_record->uuid);
   45.54  
   45.55      printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
   45.56  
   45.57      printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
   45.58  
   45.59 -    for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++)
   45.60 -    {
   45.61 -        printf("%"PRId64" -> %lf.\n",
   45.62 -               vm_record->vcpus_utilisation->contents[i].key,
   45.63 -               vm_record->vcpus_utilisation->contents[i].val);
   45.64 -    }
   45.65 -
   45.66      xen_uuid_bytes_free(vm_uuid_bytes);
   45.67      xen_uuid_free(vm_uuid);
   45.68 -    xen_vm_free(vm);
   45.69  
   45.70      xen_vm_record_free(vm_record);
   45.71  
   45.72      xen_host_free(host);
   45.73      xen_string_string_map_free(versions);
   45.74      free(dmesg);
   45.75 +    xen_string_set_free(supported_bootloaders);
   45.76  
   45.77 +    print_vm_metrics(session, vm);
   45.78 +    if (!session->ok)
   45.79 +    {
   45.80 +        /* Error has been logged, just clean up. */
   45.81 +        xen_vm_free(vm);
   45.82 +        CLEANUP;
   45.83 +        return 1;
   45.84 +    }
   45.85 +
   45.86 +    xen_vm_free(vm);
   45.87  
   45.88      xen_vm new_vm = create_new_vm(session, true);
   45.89      if (!session->ok)
   45.90 @@ -323,7 +351,6 @@ static xen_vm create_new_vm(xen_session 
   45.91              .memory_static_min = 128,
   45.92              .vcpus_policy = "credit",
   45.93              .vcpus_params = vcpus_params,
   45.94 -            .vcpus_number = 2,
   45.95              .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
   45.96              .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
   45.97              .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
   45.98 @@ -519,3 +546,35 @@ static void print_vm_power_state(xen_ses
   45.99  
  45.100      xen_uuid_free(vm_uuid);
  45.101  }
  45.102 +
  45.103 +
  45.104 +/**
  45.105 + * Print the metrics for the given VM.
  45.106 + */
  45.107 +static void print_vm_metrics(xen_session *session, xen_vm vm)
  45.108 +{
  45.109 +    xen_vm_metrics vm_metrics;
  45.110 +    if (!xen_vm_get_metrics(session, &vm_metrics, vm))
  45.111 +    {
  45.112 +        print_error(session);
  45.113 +        return;
  45.114 +    }
  45.115 +
  45.116 +    xen_vm_metrics_record *vm_metrics_record;
  45.117 +    if (!xen_vm_metrics_get_record(session, &vm_metrics_record, vm_metrics))
  45.118 +    {
  45.119 +        xen_vm_metrics_free(vm_metrics);
  45.120 +        print_error(session);
  45.121 +        return;
  45.122 +    }
  45.123 +
  45.124 +    for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
  45.125 +    {
  45.126 +        printf("%"PRId64" -> %lf.\n",
  45.127 +               vm_metrics_record->vcpus_utilisation->contents[i].key,
  45.128 +               vm_metrics_record->vcpus_utilisation->contents[i].val);
  45.129 +    }
  45.130 +
  45.131 +    xen_vm_metrics_record_free(vm_metrics_record);
  45.132 +    xen_vm_metrics_free(vm_metrics);
  45.133 +}
    46.1 --- a/tools/python/xen/xend/XendAPI.py	Thu Feb 22 09:42:13 2007 -0700
    46.2 +++ b/tools/python/xen/xend/XendAPI.py	Thu Feb 22 10:15:29 2007 -0700
    46.3 @@ -141,11 +141,11 @@ def session_required(func):
    46.4  def _is_valid_ref(ref, validator):
    46.5      return type(ref) == str and validator(ref)
    46.6  
    46.7 -def _check_ref(validator, errcode, func, api, session, ref, *args, **kwargs):
    46.8 +def _check_ref(validator, clas, func, api, session, ref, *args, **kwargs):
    46.9      if _is_valid_ref(ref, validator):
   46.10          return func(api, session, ref, *args, **kwargs)
   46.11      else:
   46.12 -        return xen_api_error([errcode, ref])
   46.13 +        return xen_api_error(['HANDLE_INVALID', clas, ref])
   46.14  
   46.15  
   46.16  def valid_host(func):
   46.17 @@ -156,7 +156,7 @@ def valid_host(func):
   46.18      """
   46.19      return lambda *args, **kwargs: \
   46.20             _check_ref(XendNode.instance().is_valid_host,
   46.21 -                      'HOST_HANDLE_INVALID', func, *args, **kwargs)
   46.22 +                      'host', func, *args, **kwargs)
   46.23  
   46.24  def valid_host_metrics(func):
   46.25      """Decorator to verify if host_metrics_ref is valid before calling
   46.26 @@ -167,7 +167,7 @@ def valid_host_metrics(func):
   46.27      """
   46.28      return lambda *args, **kwargs: \
   46.29             _check_ref(lambda r: r == XendNode.instance().host_metrics_uuid,
   46.30 -                      'HOST_METRICS_HANDLE_INVALID', func, *args, **kwargs)
   46.31 +                      'host_metrics', func, *args, **kwargs)
   46.32  
   46.33  def valid_host_cpu(func):
   46.34      """Decorator to verify if host_cpu_ref is valid before calling method.
   46.35 @@ -177,7 +177,7 @@ def valid_host_cpu(func):
   46.36      """    
   46.37      return lambda *args, **kwargs: \
   46.38             _check_ref(XendNode.instance().is_valid_cpu,
   46.39 -                      'HOST_CPU_HANDLE_INVALID', func, *args, **kwargs)
   46.40 +                      'host_cpu', func, *args, **kwargs)
   46.41  
   46.42  def valid_vm(func):
   46.43      """Decorator to verify if vm_ref is valid before calling method.
   46.44 @@ -187,7 +187,7 @@ def valid_vm(func):
   46.45      """    
   46.46      return lambda *args, **kwargs: \
   46.47             _check_ref(XendDomain.instance().is_valid_vm,
   46.48 -                      'VM_HANDLE_INVALID', func, *args, **kwargs)
   46.49 +                      'VM', func, *args, **kwargs)
   46.50  
   46.51  def valid_network(func):
   46.52      """Decorator to verify if network_ref is valid before calling method.
   46.53 @@ -197,7 +197,7 @@ def valid_network(func):
   46.54      """    
   46.55      return lambda *args, **kwargs: \
   46.56             _check_ref(XendNode.instance().is_valid_network,
   46.57 -                      'NETWORK_HANDLE_INVALID', func, *args, **kwargs)
   46.58 +                      'network', func, *args, **kwargs)
   46.59  
   46.60  def valid_vbd(func):
   46.61      """Decorator to verify if vbd_ref is valid before calling method.
   46.62 @@ -207,7 +207,17 @@ def valid_vbd(func):
   46.63      """    
   46.64      return lambda *args, **kwargs: \
   46.65             _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
   46.66 -                      'VBD_HANDLE_INVALID', func, *args, **kwargs)
   46.67 +                      'VBD', func, *args, **kwargs)
   46.68 +
   46.69 +def valid_vbd_metrics(func):
   46.70 +    """Decorator to verify if ref is valid before calling method.
   46.71 +
   46.72 +    @param func: function with params: (self, session, ref, ...)
   46.73 +    @rtype: callable object
   46.74 +    """    
   46.75 +    return lambda *args, **kwargs: \
   46.76 +           _check_ref(lambda r: XendDomain.instance().is_valid_dev('vbd', r),
   46.77 +                      'VBD_metrics', func, *args, **kwargs)
   46.78  
   46.79  def valid_vif(func):
   46.80      """Decorator to verify if vif_ref is valid before calling method.
   46.81 @@ -217,7 +227,17 @@ def valid_vif(func):
   46.82      """
   46.83      return lambda *args, **kwargs: \
   46.84             _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
   46.85 -                      'VIF_HANDLE_INVALID', func, *args, **kwargs)
   46.86 +                      'VIF', func, *args, **kwargs)
   46.87 +
   46.88 +def valid_vif_metrics(func):
   46.89 +    """Decorator to verify if ref is valid before calling method.
   46.90 +
   46.91 +    @param func: function with params: (self, session, ref, ...)
   46.92 +    @rtype: callable object
   46.93 +    """    
   46.94 +    return lambda *args, **kwargs: \
   46.95 +           _check_ref(lambda r: XendDomain.instance().is_valid_dev('vif', r),
   46.96 +                      'VIF_metrics', func, *args, **kwargs)
   46.97  
   46.98  def valid_vdi(func):
   46.99      """Decorator to verify if vdi_ref is valid before calling method.
  46.100 @@ -227,7 +247,7 @@ def valid_vdi(func):
  46.101      """
  46.102      return lambda *args, **kwargs: \
  46.103             _check_ref(XendNode.instance().is_valid_vdi,
  46.104 -                      'VDI_HANDLE_INVALID', func, *args, **kwargs)
  46.105 +                      'VDI', func, *args, **kwargs)
  46.106  
  46.107  def valid_vtpm(func):
  46.108      """Decorator to verify if vtpm_ref is valid before calling method.
  46.109 @@ -237,7 +257,7 @@ def valid_vtpm(func):
  46.110      """
  46.111      return lambda *args, **kwargs: \
  46.112             _check_ref(lambda r: XendDomain.instance().is_valid_dev('vtpm', r),
  46.113 -                      'VTPM_HANDLE_INVALID', func, *args, **kwargs)
  46.114 +                      'VTPM', func, *args, **kwargs)
  46.115  
  46.116  
  46.117  def valid_console(func):
  46.118 @@ -249,7 +269,7 @@ def valid_console(func):
  46.119      return lambda *args, **kwargs: \
  46.120             _check_ref(lambda r: XendDomain.instance().is_valid_dev('console',
  46.121                                                                     r),
  46.122 -                      'CONSOLE_HANDLE_INVALID', func, *args, **kwargs)
  46.123 +                      'console', func, *args, **kwargs)
  46.124  
  46.125  def valid_sr(func):
  46.126      """Decorator to verify if sr_ref is valid before calling method.
  46.127 @@ -259,7 +279,7 @@ def valid_sr(func):
  46.128      """
  46.129      return lambda *args, **kwargs: \
  46.130             _check_ref(lambda r: XendNode.instance().is_valid_sr,
  46.131 -                      'SR_HANDLE_INVALID', func, *args, **kwargs)
  46.132 +                      'SR', func, *args, **kwargs)
  46.133  
  46.134  def valid_pif(func):
  46.135      """Decorator to verify if pif_ref is valid before calling
  46.136 @@ -270,7 +290,7 @@ def valid_pif(func):
  46.137      """
  46.138      return lambda *args, **kwargs: \
  46.139             _check_ref(lambda r: r in XendNode.instance().pifs,
  46.140 -                      'PIF_HANDLE_INVALID', func, *args, **kwargs)
  46.141 +                      'PIF', func, *args, **kwargs)
  46.142  
  46.143  def valid_pif_metrics(func):
  46.144      """Decorator to verify if pif_metrics_ref is valid before calling
  46.145 @@ -281,7 +301,7 @@ def valid_pif_metrics(func):
  46.146      """
  46.147      return lambda *args, **kwargs: \
  46.148             _check_ref(lambda r: r in XendNode.instance().pif_metrics,
  46.149 -                      'PIF_METRICS_HANDLE_INVALID', func, *args, **kwargs)
  46.150 +                      'PIF_metrics', func, *args, **kwargs)
  46.151  
  46.152  def valid_task(func):
  46.153      """Decorator to verify if task_ref is valid before calling
  46.154 @@ -292,7 +312,7 @@ def valid_task(func):
  46.155      """
  46.156      return lambda *args, **kwargs: \
  46.157             _check_ref(XendTaskManager.get_task,
  46.158 -                      'TASK_HANDLE_INVALID', func, *args, **kwargs)
  46.159 +                      'task', func, *args, **kwargs)
  46.160  
  46.161  def valid_debug(func):
  46.162      """Decorator to verify if task_ref is valid before calling
  46.163 @@ -303,7 +323,7 @@ def valid_debug(func):
  46.164      """
  46.165      return lambda *args, **kwargs: \
  46.166             _check_ref(lambda r: r in XendAPI._debug,
  46.167 -                      'TASK_HANDLE_INVALID', func, *args, **kwargs)
  46.168 +                      'debug', func, *args, **kwargs)
  46.169  
  46.170  # -----------------------------
  46.171  # Bridge to Legacy XM API calls
  46.172 @@ -378,7 +398,9 @@ class XendAPI(object):
  46.173              'network'      : valid_network,
  46.174              'VM'           : valid_vm,
  46.175              'VBD'          : valid_vbd,
  46.176 +            'VBD_metrics'  : valid_vbd_metrics,
  46.177              'VIF'          : valid_vif,
  46.178 +            'VIF_metrics'  : valid_vif_metrics,
  46.179              'VDI'          : valid_vdi,
  46.180              'VTPM'         : valid_vtpm,
  46.181              'console'      : valid_console,
  46.182 @@ -604,7 +626,8 @@ class XendAPI(object):
  46.183      host_attr_ro = ['software_version',
  46.184                      'resident_VMs',
  46.185                      'host_CPUs',
  46.186 -                    'metrics']
  46.187 +                    'metrics',
  46.188 +                    'supported_bootloaders']
  46.189      
  46.190      host_attr_rw = ['name_label',
  46.191                      'name_description',
  46.192 @@ -656,10 +679,10 @@ class XendAPI(object):
  46.193          return xen_api_success(XendNode.instance().get_host_cpu_refs())
  46.194      def host_get_metrics(self, _, ref):
  46.195          return xen_api_success(XendNode.instance().host_metrics_uuid)
  46.196 +    def host_get_supported_bootloaders(self, session, host_ref):
  46.197 +        return xen_api_success(['pygrub'])
  46.198  
  46.199      # object methods
  46.200 -    def host_destroy(self, session, host_ref):
  46.201 -        return xen_api_error(XEND_ERROR_UNSUPPORTED)    
  46.202      def host_disable(self, session, host_ref):
  46.203          XendDomain.instance().set_allow_new_domains(False)
  46.204          return xen_api_success_void()
  46.205 @@ -687,14 +710,13 @@ class XendAPI(object):
  46.206                    'software_version': node.xen_version(),
  46.207                    'resident_VMs': dom.get_domain_refs(),
  46.208                    'host_CPUs': node.get_host_cpu_refs(),
  46.209 -                  'metrics': node.host_metrics_uuid}
  46.210 +                  'metrics': node.host_metrics_uuid,
  46.211 +                  'supported_bootloaders': 'pygrub'}
  46.212          return xen_api_success(record)
  46.213  
  46.214      # class methods
  46.215      def host_get_all(self, session):
  46.216          return xen_api_success((XendNode.instance().uuid,))
  46.217 -    def host_create(self, session, struct):
  46.218 -        return xen_api_error(XEND_ERROR_UNSUPPORTED)
  46.219      def host_get_by_name_label(self, session, name):
  46.220          if XendNode.instance().name == name:
  46.221              return xen_api_success((XendNode.instance().uuid,))
  46.222 @@ -908,7 +930,7 @@ class XendAPI(object):
  46.223                  return xen_api_success(
  46.224                      node.PIF_create_VLAN(ref, network, vlan))
  46.225              else:
  46.226 -                return xen_api_error(['NETWORK_HANDLE_INVALID', network])
  46.227 +                return xen_api_error(['HANDLE_INVALID', 'network', network])
  46.228          except NetworkAlreadyConnected, exn:
  46.229              return xen_api_error(['NETWORK_ALREADY_CONNECTED',
  46.230                                    network, exn.pif_uuid])
  46.231 @@ -1352,7 +1374,7 @@ class XendAPI(object):
  46.232          xendom = XendDomain.instance()
  46.233          xeninfo = xendom.get_vm_by_uuid(vm_ref)
  46.234          if not xeninfo:
  46.235 -            return xen_api_error(['VM_HANDLE_INVALID', vm_ref])
  46.236 +            return xen_api_error(['HANDLE_INVALID', 'VM', vm_ref])
  46.237          
  46.238          record = {
  46.239              'uuid': xeninfo.get_uuid(),
  46.240 @@ -1450,8 +1472,7 @@ class XendAPI(object):
  46.241      # Xen API: Class VBD
  46.242      # ----------------------------------------------------------------
  46.243  
  46.244 -    VBD_attr_ro = ['io_read_kbs',
  46.245 -                   'io_write_kbs']
  46.246 +    VBD_attr_ro = ['metrics']
  46.247      VBD_attr_rw = ['VM',
  46.248                     'VDI',
  46.249                     'device',
  46.250 @@ -1469,10 +1490,10 @@ class XendAPI(object):
  46.251          xendom = XendDomain.instance()
  46.252          vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
  46.253          if not vm:
  46.254 -            return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
  46.255 +            return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
  46.256          cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
  46.257          if not cfg:
  46.258 -            return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
  46.259 +            return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
  46.260  
  46.261          valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
  46.262                           self.Base_attr_ro + self.Base_attr_rw
  46.263 @@ -1481,7 +1502,9 @@ class XendAPI(object):
  46.264          for k in cfg.keys():
  46.265              if k in valid_vbd_keys:
  46.266                  return_cfg[k] = cfg[k]
  46.267 -                
  46.268 +
  46.269 +        return_cfg['metrics'] = vbd_ref
  46.270 +
  46.271          return xen_api_success(return_cfg)
  46.272  
  46.273      def VBD_media_change(self, session, vbd_ref, vdi_ref):
  46.274 @@ -1491,7 +1514,7 @@ class XendAPI(object):
  46.275      def VBD_create(self, session, vbd_struct):
  46.276          xendom = XendDomain.instance()
  46.277          if not xendom.is_valid_vm(vbd_struct['VM']):
  46.278 -            return xen_api_error(['VM_HANDLE_INVALID', vbd_struct['VM']])
  46.279 +            return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
  46.280          
  46.281          dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
  46.282          vbd_ref = ''
  46.283 @@ -1500,7 +1523,7 @@ class XendAPI(object):
  46.284              vdi_ref = vbd_struct.get('VDI')
  46.285              vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
  46.286              if not vdi:
  46.287 -                return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
  46.288 +                return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
  46.289              vdi_image = vdi.get_location()
  46.290              vbd_ref = XendTask.log_progress(0, 100,
  46.291                                              dom.create_vbd,
  46.292 @@ -1516,17 +1539,21 @@ class XendAPI(object):
  46.293          xendom = XendDomain.instance()
  46.294          vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
  46.295          if not vm:
  46.296 -            return xen_api_error(['VBD_HANDLE_INVALID', vbd_ref])
  46.297 +            return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
  46.298  
  46.299          XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
  46.300          return xen_api_success_void()
  46.301  
  46.302 -    # attributes (rw)
  46.303      def _VBD_get(self, vbd_ref, prop):
  46.304          return xen_api_success(
  46.305              XendDomain.instance().get_dev_property_by_uuid(
  46.306              'vbd', vbd_ref, prop))
  46.307  
  46.308 +    # attributes (ro)
  46.309 +    def VBD_get_metrics(self, _, vbd_ref):
  46.310 +        return xen_api_success(vbd_ref)
  46.311 +
  46.312 +    # attributes (rw)
  46.313      def VBD_get_VM(self, session, vbd_ref):
  46.314          return self._VBD_get(vbd_ref, 'VM')
  46.315      
  46.316 @@ -1545,12 +1572,6 @@ class XendAPI(object):
  46.317      def VBD_get_type(self, session, vbd_ref):
  46.318          return self._VBD_get(vbd_ref, 'type')
  46.319  
  46.320 -    def VBD_get_io_read_kbs(self, session, vbd_ref):
  46.321 -        return self._VBD_get(vbd_ref, 'io_read_kbs')
  46.322 -    
  46.323 -    def VBD_get_io_write_kbs(self, session, vbd_ref):
  46.324 -        return self._VBD_get(vbd_ref, 'io_write_kbs')
  46.325 -
  46.326      def VBD_set_bootable(self, session, vbd_ref, bootable):
  46.327          bootable = bool(bootable)
  46.328          xd = XendDomain.instance()
  46.329 @@ -1565,11 +1586,34 @@ class XendAPI(object):
  46.330          vbds = reduce(lambda x, y: x + y, vbds)
  46.331          return xen_api_success(vbds)
  46.332  
  46.333 +
  46.334 +    # Xen API: Class VBD_metrics
  46.335 +    # ----------------------------------------------------------------
  46.336 +
  46.337 +    VBD_metrics_attr_ro = ['io_read_kbs',
  46.338 +                           'io_write_kbs']
  46.339 +    VBD_metrics_attr_rw = []
  46.340 +    VBD_methods = []
  46.341 +
  46.342 +    def VBD_metrics_get_record(self, _, ref):
  46.343 +        vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
  46.344 +        if not vm:
  46.345 +            return xen_api_error(['HANDLE_INVALID', 'VBD_metrics', ref])
  46.346 +        return xen_api_success(
  46.347 +            { 'io_read_kbs'  : vm.get_dev_property('vbd', ref, 'io_read_kbs'),
  46.348 +              'io_write_kbs' : vm.get_dev_property('vbd', ref, 'io_write_kbs') })
  46.349 +
  46.350 +    def VBD_metrics_get_io_read_kbs(self, _, ref):
  46.351 +        return self._VBD_get(ref, 'io_read_kbs')
  46.352 +    
  46.353 +    def VBD_metrics_get_io_write_kbs(self, session, ref):
  46.354 +        return self._VBD_get(ref, 'io_write_kbs')
  46.355 +
  46.356 +
  46.357      # Xen API: Class VIF
  46.358      # ----------------------------------------------------------------
  46.359  
  46.360 -    VIF_attr_ro = ['io_read_kbs',
  46.361 -                   'io_write_kbs']
  46.362 +    VIF_attr_ro = ['metrics']
  46.363      VIF_attr_rw = ['device',
  46.364                     'network',
  46.365                     'VM',
  46.366 @@ -1586,10 +1630,10 @@ class XendAPI(object):
  46.367          xendom = XendDomain.instance()
  46.368          vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
  46.369          if not vm:
  46.370 -            return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
  46.371 +            return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
  46.372          cfg = vm.get_dev_xenapi_config('vif', vif_ref)
  46.373          if not cfg:
  46.374 -            return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
  46.375 +            return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
  46.376          
  46.377          valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
  46.378                           self.Base_attr_ro + self.Base_attr_rw
  46.379 @@ -1599,6 +1643,8 @@ class XendAPI(object):
  46.380              if k in valid_vif_keys:
  46.381                  return_cfg[k] = cfg[k]
  46.382              
  46.383 +        return_cfg['metrics'] = vif_ref
  46.384 +
  46.385          return xen_api_success(return_cfg)
  46.386  
  46.387      # class methods
  46.388 @@ -1613,48 +1659,40 @@ class XendAPI(object):
  46.389              except XendError:
  46.390                  return xen_api_error(XEND_ERROR_TODO)
  46.391          else:
  46.392 -            return xen_api_error(['VM_HANDLE_INVALID', vif_struct['VM']])
  46.393 +            return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
  46.394  
  46.395  
  46.396      def VIF_destroy(self, session, vif_ref):
  46.397          xendom = XendDomain.instance()
  46.398          vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
  46.399          if not vm:
  46.400 -            return xen_api_error(['VIF_HANDLE_INVALID', vif_ref])
  46.401 +            return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref])
  46.402  
  46.403          vm.destroy_vif(vif_ref)
  46.404          return xen_api_success_void()
  46.405  
  46.406 +    def _VIF_get(self, ref, prop):
  46.407 +        return xen_api_success(
  46.408 +            XendDomain.instance().get_dev_property_by_uuid('vif', ref, prop))
  46.409 +
  46.410      # getters/setters
  46.411 +    def VIF_get_metrics(self, _, vif_ref):
  46.412 +        return xen_api_success(vif_ref)
  46.413 +
  46.414      def VIF_get_VM(self, session, vif_ref):
  46.415          xendom = XendDomain.instance()        
  46.416          vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)        
  46.417          return xen_api_success(vm.get_uuid())
  46.418      
  46.419      def VIF_get_MTU(self, session, vif_ref):
  46.420 -        xendom = XendDomain.instance()
  46.421 -        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
  46.422 -                                                               'MTU'))
  46.423 +        return self._VIF_get(vif_ref, 'MTU')
  46.424 +    
  46.425      def VIF_get_MAC(self, session, vif_ref):
  46.426 -        xendom = XendDomain.instance()
  46.427 -        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
  46.428 -                                                               'MAC'))
  46.429 +        return self._VIF_get(vif_ref, 'MAC')
  46.430  
  46.431      def VIF_get_device(self, session, vif_ref):
  46.432 -        xendom = XendDomain.instance()
  46.433 -        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
  46.434 -                                                               'device'))
  46.435 +        return self._VIF_get(vif_ref, 'device')
  46.436   
  46.437 -    def VIF_get_io_read_kbs(self, session, vif_ref):
  46.438 -        xendom = XendDomain.instance()
  46.439 -        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
  46.440 -                                                               'io_read_kbs'))
  46.441 -
  46.442 -    def VIF_get_io_write_kbs(self, session, vif_ref):
  46.443 -        xendom = XendDomain.instance()
  46.444 -        return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
  46.445 -                                                               'io_write_kbs'))
  46.446 -
  46.447      def VIF_get_all(self, session):
  46.448          xendom = XendDomain.instance()
  46.449          vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
  46.450 @@ -1662,6 +1700,29 @@ class XendAPI(object):
  46.451          return xen_api_success(vifs)
  46.452  
  46.453      
  46.454 +    # Xen API: Class VIF_metrics
  46.455 +    # ----------------------------------------------------------------
  46.456 +
  46.457 +    VIF_metrics_attr_ro = ['io_read_kbs',
  46.458 +                           'io_write_kbs']
  46.459 +    VIF_metrics_attr_rw = []
  46.460 +    VIF_methods = []
  46.461 +
  46.462 +    def VIF_metrics_get_record(self, _, ref):
  46.463 +        vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
  46.464 +        if not vm:
  46.465 +            return xen_api_error(['HANDLE_INVALID', 'VIF_metrics', ref])
  46.466 +        return xen_api_success(
  46.467 +            { 'io_read_kbs'  : vm.get_dev_property('vif', ref, 'io_read_kbs'),
  46.468 +              'io_write_kbs' : vm.get_dev_property('vif', ref, 'io_write_kbs') })
  46.469 +
  46.470 +    def VIF_metrics_get_io_read_kbs(self, _, ref):
  46.471 +        return self._VIF_get(ref, 'io_read_kbs')
  46.472 +    
  46.473 +    def VIF_metrics_get_io_write_kbs(self, session, ref):
  46.474 +        return self._VIF_get(ref, 'io_write_kbs')
  46.475 +
  46.476 +
  46.477      # Xen API: Class VDI
  46.478      # ----------------------------------------------------------------
  46.479      VDI_attr_ro = ['VBDs',
  46.480 @@ -1766,7 +1827,7 @@ class XendAPI(object):
  46.481          sr_ref = vdi_struct.get('SR')
  46.482          xennode = XendNode.instance()
  46.483          if not xennode.is_valid_sr(sr_ref):
  46.484 -            return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
  46.485 +            return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
  46.486  
  46.487          vdi_uuid = xennode.srs[sr_ref].create_vdi(vdi_struct)
  46.488          return xen_api_success(vdi_uuid)
  46.489 @@ -1797,10 +1858,10 @@ class XendAPI(object):
  46.490          xendom = XendDomain.instance()
  46.491          vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
  46.492          if not vm:
  46.493 -            return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
  46.494 +            return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
  46.495          cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
  46.496          if not cfg:
  46.497 -            return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
  46.498 +            return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
  46.499          valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
  46.500                            self.Base_attr_ro + self.Base_attr_rw
  46.501          return_cfg = {}
  46.502 @@ -1815,10 +1876,10 @@ class XendAPI(object):
  46.503          xendom = XendDomain.instance()
  46.504          vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
  46.505          if not vm:
  46.506 -            return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
  46.507 +            return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
  46.508          cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
  46.509          if not cfg:
  46.510 -            return xen_api_error(['VTPM_HANDLE_INVALID', vtpm_ref])
  46.511 +            return xen_api_error(['HANDLE_INVALID', 'VTPM', vtpm_ref])
  46.512          if not cfg.has_key('backend'):
  46.513              return xen_api_error(['VTPM backend not set'])
  46.514          return xen_api_success(cfg['backend'])
  46.515 @@ -1841,7 +1902,7 @@ class XendAPI(object):
  46.516              tpmif.destroy_vtpmstate(dom.getName())
  46.517              return xen_api_success(True)
  46.518          else:
  46.519 -            return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
  46.520 +            return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
  46.521  
  46.522      # class methods
  46.523      def VTPM_create(self, session, vtpm_struct):
  46.524 @@ -1855,7 +1916,7 @@ class XendAPI(object):
  46.525              except XendError:
  46.526                  return xen_api_error(XEND_ERROR_TODO)
  46.527          else:
  46.528 -            return xen_api_error(['VM_HANDLE_INVALID', vtpm_struct['VM']])
  46.529 +            return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
  46.530  
  46.531      def VTPM_get_all(self, session):
  46.532          xendom = XendDomain.instance()
  46.533 @@ -1897,10 +1958,10 @@ class XendAPI(object):
  46.534          xendom = XendDomain.instance()
  46.535          vm = xendom.get_vm_with_dev_uuid('console', console_ref)
  46.536          if not vm:
  46.537 -            return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
  46.538 +            return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
  46.539          cfg = vm.get_dev_xenapi_config('console', console_ref)
  46.540          if not cfg:
  46.541 -            return xen_api_error(['CONSOLE_HANDLE_INVALID', console_ref])
  46.542 +            return xen_api_error(['HANDLE_INVALID', 'console', console_ref])
  46.543          
  46.544          valid_console_keys = self.console_attr_ro + self.console_attr_rw + \
  46.545                               self.Base_attr_ro + self.Base_attr_rw
  46.546 @@ -1915,7 +1976,8 @@ class XendAPI(object):
  46.547      def console_create(self, session, console_struct):
  46.548          xendom = XendDomain.instance()
  46.549          if not xendom.is_valid_vm(console_struct['VM']):
  46.550 -            return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']])
  46.551 +            return xen_api_error(['HANDLE_INVALID', 'VM',
  46.552 +                                  console_struct['VM']])
  46.553          
  46.554          dom = xendom.get_vm_by_uuid(console_struct['VM'])
  46.555          try:
  46.556 @@ -1972,7 +2034,7 @@ class XendAPI(object):
  46.557          sr = XendNode.instance().get_sr(sr_ref)
  46.558          if sr:
  46.559              return xen_api_success(sr.get_record())
  46.560 -        return xen_api_error(['SR_HANDLE_INVALID', sr_ref])
  46.561 +        return xen_api_error(['HANDLE_INVALID', 'SR', sr_ref])
  46.562  
  46.563      # Attribute acceess
  46.564  
    47.1 --- a/tools/python/xen/xm/messages/en/xen-xm.po	Thu Feb 22 09:42:13 2007 -0700
    47.2 +++ b/tools/python/xen/xm/messages/en/xen-xm.po	Thu Feb 22 10:15:29 2007 -0700
    47.3 @@ -19,7 +19,7 @@
    47.4  msgid ""
    47.5  msgstr ""
    47.6  "Project-Id-Version: Xen-xm 3.0\n"
    47.7 -"PO-Revision-Date: 2007-01-31 12:34+0000\n"
    47.8 +"PO-Revision-Date: 2007-02-20 15:22+0000\n"
    47.9  "Last-Translator: Ewan Mellor <ewan@xensource.com>\n"
   47.10  "Language-Team: xen-devel <xen-devel@lists.xensource.com>\n"
   47.11  "MIME-Version: 1.0\n"
   47.12 @@ -44,44 +44,8 @@ msgstr "Permission denied."
   47.13  msgid "VALUE_NOT_SUPPORTED"
   47.14  msgstr "Value \"%(2)s\" for %(1)s is not supported by this server.  The server said \"%(3)s\"."
   47.15  
   47.16 -msgid "HOST_CPU_HANDLE_INVALID"
   47.17 -msgstr "The host_cpu handle %(1)s is invalid."
   47.18 -
   47.19 -msgid "HOST_HANDLE_INVALID"
   47.20 -msgstr "The host handle %(1)s is invalid."
   47.21 -
   47.22 -msgid "HOST_METRICS_HANDLE_INVALID"
   47.23 -msgstr "The host_metrics handle %(1)s is invalid."
   47.24 -
   47.25 -msgid "PIF_HANDLE_INVALID"
   47.26 -msgstr "The PIF handle %(1)s is invalid."
   47.27 -
   47.28 -msgid "PIF_METRICS_HANDLE_INVALID"
   47.29 -msgstr "The PIF_METRICS handle %(1)s is invalid."
   47.30 -
   47.31 -msgid "SR_HANDLE_INVALID"
   47.32 -msgstr "The SR handle %(1)s is invalid."
   47.33 -
   47.34 -msgid "TASK_HANDLE_INVALID"
   47.35 -msgstr "The task handle %(1)s is invalid."
   47.36 -
   47.37 -msgid "VBD_HANDLE_INVALID"
   47.38 -msgstr "The VBD handle %(1)s is invalid."
   47.39 -
   47.40 -msgid "VDI_HANDLE_INVALID"
   47.41 -msgstr "The VDI handle %(1)s is invalid."
   47.42 -
   47.43 -msgid "VIF_HANDLE_INVALID"
   47.44 -msgstr "The VIF handle %(1)s is invalid."
   47.45 -
   47.46 -msgid "VM_HANDLE_INVALID"
   47.47 -msgstr "The VM handle %(1)s is invalid."
   47.48 -
   47.49 -msgid "VM_METRICS_HANDLE_INVALID"
   47.50 -msgstr "The VM_metrics handle %(1)s is invalid."
   47.51 -
   47.52 -msgid "VTPM_HANDLE_INVALID"
   47.53 -msgstr "The VTPM handle %(1)s is invalid."
   47.54 +msgid "HANDLE_INVALID"
   47.55 +msgstr "The %(1)s handle %(2)s is invalid."
   47.56  
   47.57  msgid "OPERATION_NOT_ALLOWED"
   47.58  msgstr "You attempted an operation that was not allowed."
    48.1 --- a/tools/tests/test_x86_emulator.c	Thu Feb 22 09:42:13 2007 -0700
    48.2 +++ b/tools/tests/test_x86_emulator.c	Thu Feb 22 10:15:29 2007 -0700
    48.3 @@ -43,7 +43,7 @@ static int read(
    48.4      case 4: *val = *(u32 *)addr; break;
    48.5      case 8: *val = *(unsigned long *)addr; break;
    48.6      }
    48.7 -    return X86EMUL_CONTINUE;
    48.8 +    return X86EMUL_OKAY;
    48.9  }
   48.10  
   48.11  static int write(
   48.12 @@ -61,7 +61,7 @@ static int write(
   48.13      case 4: *(u32 *)addr = (u32)val; break;
   48.14      case 8: *(unsigned long *)addr = val; break;
   48.15      }
   48.16 -    return X86EMUL_CONTINUE;
   48.17 +    return X86EMUL_OKAY;
   48.18  }
   48.19  
   48.20  static int cmpxchg(
   48.21 @@ -80,7 +80,7 @@ static int cmpxchg(
   48.22      case 4: *(u32 *)addr = (u32)new; break;
   48.23      case 8: *(unsigned long *)addr = new; break;
   48.24      }
   48.25 -    return X86EMUL_CONTINUE;
   48.26 +    return X86EMUL_OKAY;
   48.27  }
   48.28  
   48.29  static int cmpxchg8b(
   48.30 @@ -95,7 +95,7 @@ static int cmpxchg8b(
   48.31      unsigned long addr = offset;
   48.32      ((unsigned long *)addr)[0] = new_lo;
   48.33      ((unsigned long *)addr)[1] = new_hi;
   48.34 -    return X86EMUL_CONTINUE;
   48.35 +    return X86EMUL_OKAY;
   48.36  }
   48.37  
   48.38  static struct x86_emulate_ops emulops = {
   48.39 @@ -138,7 +138,7 @@ int main(int argc, char **argv)
   48.40      regs.eax    = (unsigned long)res;
   48.41      *res        = 0x7FFFFFFF;
   48.42      rc = x86_emulate(&ctxt, &emulops);
   48.43 -    if ( (rc != 0) || 
   48.44 +    if ( (rc != X86EMUL_OKAY) || 
   48.45           (*res != 0x92345677) || 
   48.46           (regs.eflags != 0xa94) ||
   48.47           (regs.eip != (unsigned long)&instr[2]) )
   48.48 @@ -152,7 +152,7 @@ int main(int argc, char **argv)
   48.49      regs.ecx    = 0x12345678;
   48.50      regs.eax    = 0x7FFFFFFF;
   48.51      rc = x86_emulate(&ctxt, &emulops);
   48.52 -    if ( (rc != 0) || 
   48.53 +    if ( (rc != X86EMUL_OKAY) || 
   48.54           (regs.ecx != 0x12345678) ||
   48.55           (regs.eax != 0x92345677) ||
   48.56           (regs.eflags != 0xa94) ||
   48.57 @@ -171,7 +171,7 @@ int main(int argc, char **argv)
   48.58  #endif
   48.59      regs.eax    = (unsigned long)res;
   48.60      rc = x86_emulate(&ctxt, &emulops);
   48.61 -    if ( (rc != 0) || 
   48.62 +    if ( (rc != X86EMUL_OKAY) || 
   48.63           (*res != 0x92345677) || 
   48.64           (regs.ecx != 0x8000000FUL) ||
   48.65           (regs.eip != (unsigned long)&instr[2]) )
   48.66 @@ -185,7 +185,7 @@ int main(int argc, char **argv)
   48.67      regs.ecx    = ~0UL;
   48.68      regs.eax    = (unsigned long)res;
   48.69      rc = x86_emulate(&ctxt, &emulops);
   48.70 -    if ( (rc != 0) || 
   48.71 +    if ( (rc != X86EMUL_OKAY) || 
   48.72           (*res != 0x92345677) || 
   48.73           (regs.ecx != 0x92345677UL) ||
   48.74           (regs.eip != (unsigned long)&instr[2]) )
   48.75 @@ -200,7 +200,7 @@ int main(int argc, char **argv)
   48.76      regs.ecx    = 0xAA;
   48.77      regs.ebx    = (unsigned long)res;
   48.78      rc = x86_emulate(&ctxt, &emulops);
   48.79 -    if ( (rc != 0) || 
   48.80 +    if ( (rc != X86EMUL_OKAY) || 
   48.81           (*res != 0x923456AA) || 
   48.82           (regs.eflags != 0x244) ||
   48.83           (regs.eax != 0x92345677UL) ||
   48.84 @@ -216,7 +216,7 @@ int main(int argc, char **argv)
   48.85      regs.ecx    = 0xFF;
   48.86      regs.ebx    = (unsigned long)res;
   48.87      rc = x86_emulate(&ctxt, &emulops);
   48.88 -    if ( (rc != 0) || 
   48.89 +    if ( (rc != X86EMUL_OKAY) || 
   48.90           (*res != 0x923456AA) || 
   48.91           ((regs.eflags&0x240) != 0x200) ||
   48.92           (regs.eax != 0xAABBCCAA) ||
   48.93 @@ -232,7 +232,7 @@ int main(int argc, char **argv)
   48.94      regs.ecx    = 0x12345678;
   48.95      regs.eax    = (unsigned long)res;
   48.96      rc = x86_emulate(&ctxt, &emulops);
   48.97 -    if ( (rc != 0) || 
   48.98 +    if ( (rc != X86EMUL_OKAY) || 
   48.99           (*res != 0x12345678) || 
  48.100           (regs.eflags != 0x200) ||
  48.101           (regs.ecx != 0x923456AA) ||
  48.102 @@ -249,7 +249,7 @@ int main(int argc, char **argv)
  48.103      regs.ecx    = 0xDDEEFF00L;
  48.104      regs.ebx    = (unsigned long)res;
  48.105      rc = x86_emulate(&ctxt, &emulops);
  48.106 -    if ( (rc != 0) || 
  48.107 +    if ( (rc != X86EMUL_OKAY) || 
  48.108           (*res != 0xDDEEFF00) || 
  48.109           (regs.eflags != 0x244) ||
  48.110           (regs.eax != 0x923456AAUL) ||
  48.111 @@ -266,7 +266,7 @@ int main(int argc, char **argv)
  48.112      regs.esi    = (unsigned long)res + 0;
  48.113      regs.edi    = (unsigned long)res + 2;
  48.114      rc = x86_emulate(&ctxt, &emulops);
  48.115 -    if ( (rc != 0) || 
  48.116 +    if ( (rc != X86EMUL_OKAY) || 
  48.117           (*res != 0x44554455) ||
  48.118           (regs.eflags != 0x200) ||
  48.119           (regs.ecx != 22) || 
  48.120 @@ -283,7 +283,7 @@ int main(int argc, char **argv)
  48.121      regs.eip    = (unsigned long)&instr[0];
  48.122      regs.edi    = (unsigned long)res;
  48.123      rc = x86_emulate(&ctxt, &emulops);
  48.124 -    if ( (rc != 0) ||
  48.125 +    if ( (rc != X86EMUL_OKAY) ||
  48.126           (*res != 0x2233445D) ||
  48.127           ((regs.eflags&0x201) != 0x201) ||
  48.128           (regs.eip != (unsigned long)&instr[4]) )
  48.129 @@ -298,7 +298,7 @@ int main(int argc, char **argv)
  48.130      regs.eax    = -32;
  48.131      regs.edi    = (unsigned long)(res+1);
  48.132      rc = x86_emulate(&ctxt, &emulops);
  48.133 -    if ( (rc != 0) ||
  48.134 +    if ( (rc != X86EMUL_OKAY) ||
  48.135           (*res != 0x2233445E) ||
  48.136           ((regs.eflags&0x201) != 0x201) ||
  48.137           (regs.eip != (unsigned long)&instr[3]) )
  48.138 @@ -318,7 +318,7 @@ int main(int argc, char **argv)
  48.139      regs.eip    = (unsigned long)&instr[0];
  48.140      regs.edi    = (unsigned long)res;
  48.141      rc = x86_emulate(&ctxt, &emulops);
  48.142 -    if ( (rc != 0) ||
  48.143 +    if ( (rc != X86EMUL_OKAY) ||
  48.144           (res[0] != 0x9999AAAA) ||
  48.145           (res[1] != 0xCCCCFFFF) ||
  48.146           ((regs.eflags&0x240) != 0x240) ||
  48.147 @@ -332,7 +332,7 @@ int main(int argc, char **argv)
  48.148      regs.eip    = (unsigned long)&instr[0];
  48.149      regs.edi    = (unsigned long)res;
  48.150      rc = x86_emulate(&ctxt, &emulops);
  48.151 -    if ( (rc != 0) || 
  48.152 +    if ( (rc != X86EMUL_OKAY) || 
  48.153           (res[0] != 0x9999AAAA) ||
  48.154           (res[1] != 0xCCCCFFFF) ||
  48.155           (regs.eax != 0x9999AAAA) ||
  48.156 @@ -350,7 +350,7 @@ int main(int argc, char **argv)
  48.157      regs.eax    = (unsigned long)res;
  48.158      *res        = 0x82;
  48.159      rc = x86_emulate(&ctxt, &emulops);
  48.160 -    if ( (rc != 0) ||
  48.161 +    if ( (rc != X86EMUL_OKAY) ||
  48.162           (*res != 0x82) ||
  48.163           (regs.ecx != 0xFFFFFF82) ||
  48.164           ((regs.eflags&0x240) != 0x200) ||
  48.165 @@ -366,7 +366,7 @@ int main(int argc, char **argv)
  48.166      regs.eax    = (unsigned long)res;
  48.167      *res        = 0x1234aa82;
  48.168      rc = x86_emulate(&ctxt, &emulops);
  48.169 -    if ( (rc != 0) ||
  48.170 +    if ( (rc != X86EMUL_OKAY) ||
  48.171           (*res != 0x1234aa82) ||
  48.172           (regs.ecx != 0xaa82) ||
  48.173           ((regs.eflags&0x240) != 0x200) ||
  48.174 @@ -382,7 +382,7 @@ int main(int argc, char **argv)
  48.175      regs.eax    = 0x12345678;
  48.176      *res        = 0x11111111;
  48.177      rc = x86_emulate(&ctxt, &emulops);
  48.178 -    if ( (rc != 0) ||
  48.179 +    if ( (rc != X86EMUL_OKAY) ||
  48.180           (*res != 0x11116789) ||
  48.181           (regs.eax != 0x12341111) ||
  48.182           ((regs.eflags&0x240) != 0x200) ||
  48.183 @@ -396,7 +396,7 @@ int main(int argc, char **argv)
  48.184      regs.eip    = (unsigned long)&instr[0];
  48.185      regs.eax    = 0x00000000;
  48.186      rc = x86_emulate(&ctxt, &emulops);
  48.187 -    if ( (rc != 0) ||
  48.188 +    if ( (rc != X86EMUL_OKAY) ||
  48.189           (regs.eax != 0x0000ffff) ||
  48.190           ((regs.eflags&0x240) != 0x200) ||
  48.191           (regs.eip != (unsigned long)&instr[2]) )
  48.192 @@ -410,7 +410,7 @@ int main(int argc, char **argv)
  48.193      regs.eax    = 0x12345678;
  48.194      regs.ebp    = 0xaaaaaaaa;
  48.195      rc = x86_emulate(&ctxt, &emulops);
  48.196 -    if ( (rc != 0) ||
  48.197 +    if ( (rc != X86EMUL_OKAY) ||
  48.198           (regs.eax != 0xaaaaaab2) ||
  48.199           ((regs.eflags&0x240) != 0x200) ||
  48.200           (regs.eip != (unsigned long)&instr[3]) )
  48.201 @@ -454,7 +454,7 @@ int main(int argc, char **argv)
  48.202          bcdres_emul |= (regs.eflags & EFLG_SF) ? 0x400 : 0;
  48.203          bcdres_emul |= (regs.eflags & EFLG_CF) ? 0x200 : 0;
  48.204          bcdres_emul |= (regs.eflags & EFLG_AF) ? 0x100 : 0;
  48.205 -        if ( (rc != 0) || (regs.eax > 255) ||
  48.206 +        if ( (rc != X86EMUL_OKAY) || (regs.eax > 255) ||
  48.207               (regs.eip != (unsigned long)&instr[1]) )
  48.208              goto fail;
  48.209  
  48.210 @@ -501,7 +501,7 @@ int main(int argc, char **argv)
  48.211          if ( (i++ & 8191) == 0 )
  48.212              printf(".");
  48.213          rc = x86_emulate(&ctxt, &emulops);
  48.214 -        if ( rc != 0 )
  48.215 +        if ( rc != X86EMUL_OKAY )
  48.216          {
  48.217              printf("failed at %%eip == %08x\n", (unsigned int)regs.eip);
  48.218              return 1;
    49.1 --- a/xen/acm/acm_chinesewall_hooks.c	Thu Feb 22 09:42:13 2007 -0700
    49.2 +++ b/xen/acm/acm_chinesewall_hooks.c	Thu Feb 22 10:15:29 2007 -0700
    49.3 @@ -194,19 +194,18 @@ chwall_init_state(struct acm_chwall_poli
    49.4      int violation = 0, i, j;
    49.5      struct chwall_ssid *chwall_ssid;
    49.6      ssidref_t chwall_ssidref;
    49.7 -    struct domain **pd;
    49.8 +    struct domain *d;
    49.9  
   49.10 -    write_lock(&domlist_lock);
   49.11 +    spin_lock(&domlist_update_lock);
   49.12      /* go through all domains and adjust policy as if this domain was started now */
   49.13 -    pd = &domain_list;
   49.14 -    for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list)
   49.15 +    for_each_domain ( d )
   49.16      {
   49.17          chwall_ssid =
   49.18              GET_SSIDP(ACM_CHINESE_WALL_POLICY,
   49.19 -                      (struct acm_ssid_domain *) (*pd)->ssid);
   49.20 +                      (struct acm_ssid_domain *)d->ssid);
   49.21          chwall_ssidref = chwall_ssid->chwall_ssidref;
   49.22          traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
   49.23 -                    __func__, (*pd)->domain_id, chwall_ssidref);
   49.24 +                    __func__, d->domain_id, chwall_ssidref);
   49.25          /* a) adjust types ref-count for running domains */
   49.26          for (i = 0; i < chwall_buf->chwall_max_types; i++)
   49.27              running_types[i] +=
   49.28 @@ -247,7 +246,7 @@ chwall_init_state(struct acm_chwall_poli
   49.29          }
   49.30      }
   49.31   out:
   49.32 -    write_unlock(&domlist_lock);
   49.33 +    spin_unlock(&domlist_update_lock);
   49.34      return violation;
   49.35      /* returning "violation != 0" means that the currently running set of domains would
   49.36       * not be possible if the new policy had been enforced before starting them; for chinese
    50.1 --- a/xen/acm/acm_simple_type_enforcement_hooks.c	Thu Feb 22 09:42:13 2007 -0700
    50.2 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c	Thu Feb 22 10:15:29 2007 -0700
    50.3 @@ -175,36 +175,37 @@ ste_init_state(struct acm_ste_policy_buf
    50.4      int violation = 1;
    50.5      struct ste_ssid *ste_ssid, *ste_rssid;
    50.6      ssidref_t ste_ssidref, ste_rssidref;
    50.7 -    struct domain **pd, *rdom;
    50.8 +    struct domain *d, *rdom;
    50.9      domid_t rdomid;
   50.10      struct grant_entry sha_copy;
   50.11      int port, i;
   50.12  
   50.13 -    read_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */
   50.14 +    rcu_read_lock(&domlist_read_lock);
   50.15 +    /* go by domain? or directly by global? event/grant list */
   50.16      /* go through all domains and adjust policy as if this domain was started now */
   50.17 -    pd = &domain_list;
   50.18 -    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
   50.19 +    for_each_domain ( d )
   50.20 +    {
   50.21          ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
   50.22 -                             (struct acm_ssid_domain *)(*pd)->ssid);
   50.23 +                             (struct acm_ssid_domain *)d->ssid);
   50.24          ste_ssidref = ste_ssid->ste_ssidref;
   50.25          traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n",
   50.26 -                    __func__, (*pd)->domain_id, ste_ssidref);
   50.27 +                    __func__, d->domain_id, ste_ssidref);
   50.28          /* a) check for event channel conflicts */
   50.29          for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
   50.30 -            spin_lock(&(*pd)->evtchn_lock);
   50.31 -            if ((*pd)->evtchn[port] == NULL) {
   50.32 -                spin_unlock(&(*pd)->evtchn_lock);
   50.33 +            spin_lock(&d->evtchn_lock);
   50.34 +            if (d->evtchn[port] == NULL) {
   50.35 +                spin_unlock(&d->evtchn_lock);
   50.36                  continue;
   50.37              }
   50.38 -            if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) {
   50.39 -                rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom;
   50.40 +            if (d->evtchn[port]->state == ECS_INTERDOMAIN) {
   50.41 +                rdom = d->evtchn[port]->u.interdomain.remote_dom;
   50.42                  rdomid = rdom->domain_id;
   50.43                  /* rdom now has remote domain */
   50.44                  ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
   50.45                                        (struct acm_ssid_domain *)(rdom->ssid));
   50.46                  ste_rssidref = ste_rssid->ste_ssidref;
   50.47 -            } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) {
   50.48 -                rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid;
   50.49 +            } else if (d->evtchn[port]->state == ECS_UNBOUND) {
   50.50 +                rdomid = d->evtchn[port]->u.unbound.remote_domid;
   50.51                  if ((rdom = get_domain_by_id(rdomid)) == NULL) {
   50.52                      printk("%s: Error finding domain to id %x!\n", __func__, rdomid);
   50.53                      goto out;
   50.54 @@ -215,36 +216,36 @@ ste_init_state(struct acm_ste_policy_buf
   50.55                  ste_rssidref = ste_rssid->ste_ssidref;
   50.56                  put_domain(rdom);
   50.57              } else {
   50.58 -                spin_unlock(&(*pd)->evtchn_lock);
   50.59 +                spin_unlock(&d->evtchn_lock);
   50.60                  continue; /* port unused */
   50.61              }
   50.62 -            spin_unlock(&(*pd)->evtchn_lock);
   50.63 +            spin_unlock(&d->evtchn_lock);
   50.64  
   50.65              /* rdom now has remote domain */
   50.66              ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
   50.67                                    (struct acm_ssid_domain *)(rdom->ssid));
   50.68              ste_rssidref = ste_rssid->ste_ssidref;
   50.69              traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", 
   50.70 -                        __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port);  
   50.71 +                        __func__, d->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port);  
   50.72              /* check whether on subj->ssid, obj->ssid share a common type*/
   50.73              if (!have_common_type(ste_ssidref, ste_rssidref)) {
   50.74                  printkd("%s: Policy violation in event channel domain %x -> domain %x.\n",
   50.75 -                        __func__, (*pd)->domain_id, rdomid);
   50.76 +                        __func__, d->domain_id, rdomid);
   50.77                  goto out;
   50.78              }
   50.79          } 
   50.80          /* b) check for grant table conflicts on shared pages */
   50.81 -        spin_lock(&(*pd)->grant_table->lock);
   50.82 -        for ( i = 0; i < nr_grant_entries((*pd)->grant_table); i++ ) {
   50.83 +        spin_lock(&d->grant_table->lock);
   50.84 +        for ( i = 0; i < nr_grant_entries(d->grant_table); i++ ) {
   50.85  #define SPP (PAGE_SIZE / sizeof(struct grant_entry))
   50.86 -            sha_copy = (*pd)->grant_table->shared[i/SPP][i%SPP];
   50.87 +            sha_copy = d->grant_table->shared[i/SPP][i%SPP];
   50.88              if ( sha_copy.flags ) {
   50.89                  printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n",
   50.90 -                        __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid, 
   50.91 +                        __func__, d->domain_id, i, sha_copy.flags, sha_copy.domid, 
   50.92                          (unsigned long)sha_copy.frame);
   50.93                  rdomid = sha_copy.domid;
   50.94                  if ((rdom = get_domain_by_id(rdomid)) == NULL) {
   50.95 -                    spin_unlock(&(*pd)->grant_table->lock);
   50.96 +                    spin_unlock(&d->grant_table->lock);
   50.97                      printkd("%s: domain not found ERROR!\n", __func__);
   50.98                      goto out;
   50.99                  };
  50.100 @@ -254,18 +255,18 @@ ste_init_state(struct acm_ste_policy_buf
  50.101                  ste_rssidref = ste_rssid->ste_ssidref;
  50.102                  put_domain(rdom);
  50.103                  if (!have_common_type(ste_ssidref, ste_rssidref)) {
  50.104 -                    spin_unlock(&(*pd)->grant_table->lock);
  50.105 +                    spin_unlock(&d->grant_table->lock);
  50.106                      printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n",
  50.107 -                            __func__, (*pd)->domain_id, rdomid);
  50.108 +                            __func__, d->domain_id, rdomid);
  50.109                      goto out;
  50.110                  }
  50.111              }
  50.112          }
  50.113 -        spin_unlock(&(*pd)->grant_table->lock);
  50.114 +        spin_unlock(&d->grant_table->lock);
  50.115      }
  50.116      violation = 0;
  50.117   out:
  50.118 -    read_unlock(&domlist_lock);
  50.119 +    rcu_read_unlock(&domlist_read_lock);
  50.120      return violation;
  50.121      /* returning "violation != 0" means that existing sharing between domains would not 
  50.122       * have been allowed if the new policy had been enforced before the sharing; for ste, 
  50.123 @@ -281,7 +282,7 @@ ste_set_policy(u8 *buf, u32 buf_size)
  50.124      struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf;
  50.125      void *ssidrefsbuf;
  50.126      struct ste_ssid *ste_ssid;
  50.127 -    struct domain **pd;
  50.128 +    struct domain *d;
  50.129      int i;
  50.130  
  50.131      if (buf_size < sizeof(struct acm_ste_policy_buffer))
  50.132 @@ -326,15 +327,14 @@ ste_set_policy(u8 *buf, u32 buf_size)
  50.133      ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
  50.134  
  50.135      /* clear all ste caches */
  50.136 -    read_lock(&domlist_lock);
  50.137 -    pd = &domain_list;
  50.138 -    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  50.139 +    rcu_read_lock(&domlist_read_lock);
  50.140 +    for_each_domain ( d ) {
  50.141          ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  50.142 -                             (struct acm_ssid_domain *)(*pd)->ssid);
  50.143 +                             (struct acm_ssid_domain *)(d)->ssid);
  50.144          for (i=0; i<ACM_TE_CACHE_SIZE; i++)
  50.145              ste_ssid->ste_cache[i].valid = ACM_STE_free;
  50.146      }
  50.147 -    read_unlock(&domlist_lock);
  50.148 +    rcu_read_unlock(&domlist_read_lock);
  50.149      return ACM_OK;
  50.150  
  50.151   error_free:
  50.152 @@ -436,14 +436,14 @@ clean_id_from_cache(domid_t id)
  50.153  {
  50.154      struct ste_ssid *ste_ssid;
  50.155      int i;
  50.156 -    struct domain **pd;
  50.157 +    struct domain *d;
  50.158      struct acm_ssid_domain *ssid;
  50.159  
  50.160      printkd("deleting cache for dom %x.\n", id);
  50.161 -    read_lock(&domlist_lock); /* look through caches of all domains */
  50.162 -    pd = &domain_list;
  50.163 -    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  50.164 -        ssid = (struct acm_ssid_domain *)((*pd)->ssid);
  50.165 +    rcu_read_lock(&domlist_read_lock);
  50.166 +    /* look through caches of all domains */
  50.167 +    for_each_domain ( d ) {
  50.168 +        ssid = (struct acm_ssid_domain *)(d->ssid);
  50.169  
  50.170          if (ssid == NULL)
  50.171              continue; /* hanging domain structure, no ssid any more ... */
  50.172 @@ -459,7 +459,7 @@ clean_id_from_cache(domid_t id)
  50.173                  ste_ssid->ste_cache[i].valid = ACM_STE_free;
  50.174      }
  50.175   out:
  50.176 -    read_unlock(&domlist_lock);
  50.177 +    rcu_read_unlock(&domlist_read_lock);
  50.178  }
  50.179  
  50.180  /***************************
    51.1 --- a/xen/arch/ia64/linux-xen/mca.c	Thu Feb 22 09:42:13 2007 -0700
    51.2 +++ b/xen/arch/ia64/linux-xen/mca.c	Thu Feb 22 10:15:29 2007 -0700
    51.3 @@ -790,6 +790,7 @@ init_handler_platform (pal_min_state_are
    51.4  			/* this route is for dump routine */
    51.5  			unw_init_running(try_crashdump, pt);
    51.6  		} else {
    51.7 +			rcu_read_lock(&domlist_read_lock);
    51.8  			for_each_domain(d) {
    51.9  				for_each_vcpu(d, v) {
   51.10  					printk("Backtrace of current vcpu "
   51.11 @@ -798,6 +799,7 @@ init_handler_platform (pal_min_state_are
   51.12  					show_stack(v, NULL);
   51.13  				}
   51.14  			}
   51.15 +			rcu_read_unlock(&domlist_read_lock);
   51.16  		}
   51.17  	}
   51.18  	unw_init_running(freeze_cpu_osinit, NULL);
    52.1 --- a/xen/arch/ia64/linux-xen/perfmon.c	Thu Feb 22 09:42:13 2007 -0700
    52.2 +++ b/xen/arch/ia64/linux-xen/perfmon.c	Thu Feb 22 10:15:29 2007 -0700
    52.3 @@ -7225,7 +7225,6 @@ DEFINE_PER_CPU(pfm_context_t*, xenpfm_co
    52.4  /*
    52.5   * note: some functions mask interrupt with this lock held
    52.6   * so that this lock can't be locked from interrupt handler.
    52.7 - * lock order domlist_lock => xenpfm_context_lock
    52.8   */
    52.9  DEFINE_SPINLOCK(xenpfm_context_lock);
   52.10  
   52.11 @@ -7507,10 +7506,8 @@ xenpfm_context_unload(void)
   52.12  		arg.error[cpu] = 0;
   52.13  
   52.14  	BUG_ON(in_irq());
   52.15 -	read_lock(&domlist_lock);
   52.16  	spin_lock(&xenpfm_context_lock);
   52.17  	error = xenpfm_start_stop_locked(0);
   52.18 -	read_unlock(&domlist_lock);
   52.19  	if (error) {
   52.20  		spin_unlock(&xenpfm_context_lock);
   52.21  		return error;
   52.22 @@ -7688,10 +7685,11 @@ xenpfm_start_stop_locked(int is_start)
   52.23  	while (atomic_read(&arg.started) != cpus)
   52.24  		cpu_relax();
   52.25  
   52.26 -	for_each_domain(d) {
   52.27 +	rcu_read_lock(&domlist_read_lock);
   52.28 +	for_each_domain(d)
   52.29  		for_each_vcpu(d, v)
   52.30  			xenpfm_start_stop_vcpu(v, is_start);
   52.31 -	}
   52.32 +	rcu_read_unlock(&domlist_read_lock);
   52.33  
   52.34  	arg.error[smp_processor_id()] = __xenpfm_start_stop(is_start);
   52.35  	atomic_inc(&arg.finished);
   52.36 @@ -7716,11 +7714,9 @@ xenpfm_start_stop(int is_start)
   52.37  	int error;
   52.38  	
   52.39  	BUG_ON(in_irq());
   52.40 -	read_lock(&domlist_lock);
   52.41  	spin_lock(&xenpfm_context_lock);
   52.42 -	error =xenpfm_start_stop_locked(is_start);
   52.43 +	error = xenpfm_start_stop_locked(is_start);
   52.44  	spin_unlock(&xenpfm_context_lock);
   52.45 -	read_unlock(&domlist_lock);
   52.46  
   52.47  	return error;
   52.48  }
    53.1 --- a/xen/arch/powerpc/audit.c	Thu Feb 22 09:42:13 2007 -0700
    53.2 +++ b/xen/arch/powerpc/audit.c	Thu Feb 22 10:15:29 2007 -0700
    53.3 @@ -34,8 +34,10 @@ void audit_domain(struct domain *d)
    53.4  void audit_domains(void)
    53.5  {
    53.6      struct domain *d;
    53.7 +    rcu_read_lock(&domlist_read_lock);
    53.8      for_each_domain ( d )
    53.9          audit_domain(d);
   53.10 +    rcu_read_unlock(&domlist_read_lock);
   53.11  }
   53.12  
   53.13  void audit_domains_key(unsigned char key)
    54.1 --- a/xen/arch/x86/domctl.c	Thu Feb 22 09:42:13 2007 -0700
    54.2 +++ b/xen/arch/x86/domctl.c	Thu Feb 22 10:15:29 2007 -0700
    54.3 @@ -441,6 +441,10 @@ void arch_get_info_guest(struct vcpu *v,
    54.4          XLAT_vcpu_guest_context(c.cmp, &v->arch.guest_context);
    54.5  #endif
    54.6  
    54.7 +    c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
    54.8 +    if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
    54.9 +        c(flags |= VGCF_i387_valid);
   54.10 +
   54.11      if ( is_hvm_vcpu(v) )
   54.12      {
   54.13          if ( !IS_COMPAT(v->domain) )
   54.14 @@ -464,23 +468,21 @@ void arch_get_info_guest(struct vcpu *v,
   54.15          /* IOPL privileges are virtualised: merge back into returned eflags. */
   54.16          BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0);
   54.17          c(user_regs.eflags |= v->arch.iopl << 12);
   54.18 -    }
   54.19 -
   54.20 -    c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
   54.21 -    if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
   54.22 -        c(flags |= VGCF_i387_valid);
   54.23 -    if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
   54.24 -        c(flags |= VGCF_in_kernel);
   54.25  
   54.26 -    if ( !IS_COMPAT(v->domain) )
   54.27 -        c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
   54.28 +        if ( !IS_COMPAT(v->domain) )
   54.29 +            c.nat->ctrlreg[3] = xen_pfn_to_cr3(
   54.30 +                pagetable_get_pfn(v->arch.guest_table));
   54.31  #ifdef CONFIG_COMPAT
   54.32 -    else
   54.33 -    {
   54.34 -        l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table));
   54.35 -        c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
   54.36 +        else
   54.37 +        {
   54.38 +            l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table));
   54.39 +            c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
   54.40 +        }
   54.41 +#endif
   54.42 +
   54.43 +        if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
   54.44 +            c(flags |= VGCF_in_kernel);
   54.45      }
   54.46 -#endif
   54.47  
   54.48      c(vm_assist = v->domain->vm_assist);
   54.49  #undef c
    55.1 --- a/xen/arch/x86/extable.c	Thu Feb 22 09:42:13 2007 -0700
    55.2 +++ b/xen/arch/x86/extable.c	Thu Feb 22 10:15:29 2007 -0700
    55.3 @@ -1,14 +1,9 @@
    55.4  
    55.5  #include <xen/config.h>
    55.6 +#include <xen/perfc.h>
    55.7  #include <xen/spinlock.h>
    55.8  #include <asm/uaccess.h>
    55.9  
   55.10 -#ifdef PERF_COUNTERS
   55.11 -#include <xen/sched.h>
   55.12 -#include <xen/perfc.h>
   55.13 -#include <asm/current.h>
   55.14 -#endif
   55.15 -
   55.16  extern struct exception_table_entry __start___ex_table[];
   55.17  extern struct exception_table_entry __stop___ex_table[];
   55.18  extern struct exception_table_entry __start___pre_ex_table[];
   55.19 @@ -74,10 +69,10 @@ search_pre_exception_table(struct cpu_us
   55.20      unsigned long addr = (unsigned long)regs->eip;
   55.21      unsigned long fixup = search_one_table(
   55.22          __start___pre_ex_table, __stop___pre_ex_table-1, addr);
   55.23 -    dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
   55.24 -#ifdef PERF_COUNTERS
   55.25      if ( fixup )
   55.26 +    {
   55.27 +        dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
   55.28          perfc_incrc(exception_fixed);
   55.29 -#endif
   55.30 +    }
   55.31      return fixup;
   55.32  }
    56.1 --- a/xen/arch/x86/hvm/io.c	Thu Feb 22 09:42:13 2007 -0700
    56.2 +++ b/xen/arch/x86/hvm/io.c	Thu Feb 22 10:15:29 2007 -0700
    56.3 @@ -533,6 +533,7 @@ static void hvm_mmio_assist(struct cpu_u
    56.4          break;
    56.5  
    56.6      case INSTR_LODS:
    56.7 +        set_reg_value(size, 0, 0, regs, p->data);
    56.8          sign = p->df ? -1 : 1;
    56.9          regs->esi += sign * p->count * p->size;
   56.10          if (mmio_opp->flags & REPZ)
   56.11 @@ -553,6 +554,7 @@ static void hvm_mmio_assist(struct cpu_u
   56.12              diff = (unsigned long) p->data & value;
   56.13              set_reg_value(size, index, 0, regs, diff);
   56.14          }
   56.15 +        break;
   56.16  
   56.17      case INSTR_ADD:
   56.18          if (src & REGISTER) {
    57.1 --- a/xen/arch/x86/hvm/platform.c	Thu Feb 22 09:42:13 2007 -0700
    57.2 +++ b/xen/arch/x86/hvm/platform.c	Thu Feb 22 10:15:29 2007 -0700
    57.3 @@ -1136,6 +1136,7 @@ void handle_mmio(unsigned long gpa)
    57.4           * Since the source is always in (contiguous) mmio space we don't
    57.5           * need to break it up into pages.
    57.6           */
    57.7 +        mmio_op->operand[0] = mk_operand(op_size, 0, 0, REGISTER);
    57.8          send_mmio_req(IOREQ_TYPE_COPY, gpa,
    57.9                        GET_REPEAT_COUNT(), op_size, 0, IOREQ_READ, df, 0);
   57.10          break;
    58.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Thu Feb 22 09:42:13 2007 -0700
    58.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Thu Feb 22 10:15:29 2007 -0700
    58.3 @@ -330,6 +330,9 @@ static void vmcb_dump(unsigned char ch)
    58.4      struct vcpu *v;
    58.5      
    58.6      printk("*********** VMCB Areas **************\n");
    58.7 +
    58.8 +    rcu_read_lock(&domlist_read_lock);
    58.9 +
   58.10      for_each_domain ( d )
   58.11      {
   58.12          if ( !is_hvm_domain(d) )
   58.13 @@ -342,6 +345,8 @@ static void vmcb_dump(unsigned char ch)
   58.14          }
   58.15      }
   58.16  
   58.17 +    rcu_read_unlock(&domlist_read_lock);
   58.18 +
   58.19      printk("**************************************\n");
   58.20  }
   58.21  
    59.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu Feb 22 09:42:13 2007 -0700
    59.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu Feb 22 10:15:29 2007 -0700
    59.3 @@ -567,6 +567,9 @@ static void vmcs_dump(unsigned char ch)
    59.4      struct vcpu *v;
    59.5      
    59.6      printk("*********** VMCS Areas **************\n");
    59.7 +
    59.8 +    rcu_read_lock(&domlist_read_lock);
    59.9 +
   59.10      for_each_domain ( d )
   59.11      {
   59.12          if ( !is_hvm_domain(d) )
   59.13 @@ -581,6 +584,8 @@ static void vmcs_dump(unsigned char ch)
   59.14          }
   59.15      }
   59.16  
   59.17 +    rcu_read_unlock(&domlist_read_lock);
   59.18 +
   59.19      printk("**************************************\n");
   59.20  }
   59.21  
    60.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 22 09:42:13 2007 -0700
    60.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 22 10:15:29 2007 -0700
    60.3 @@ -696,7 +696,7 @@ static void vmx_store_cpu_guest_regs(
    60.4      {
    60.5          crs[0] = v->arch.hvm_vmx.cpu_shadow_cr0;
    60.6          crs[2] = v->arch.hvm_vmx.cpu_cr2;
    60.7 -        crs[3] = __vmread(GUEST_CR3);
    60.8 +        crs[3] = v->arch.hvm_vmx.cpu_cr3;
    60.9          crs[4] = v->arch.hvm_vmx.cpu_shadow_cr4;
   60.10      }
   60.11  
    61.1 --- a/xen/arch/x86/mm.c	Thu Feb 22 09:42:13 2007 -0700
    61.2 +++ b/xen/arch/x86/mm.c	Thu Feb 22 10:15:29 2007 -0700
    61.3 @@ -3151,10 +3151,10 @@ static int ptwr_emulated_read(
    61.4      if ( (rc = copy_from_user((void *)val, (void *)addr, bytes)) != 0 )
    61.5      {
    61.6          propagate_page_fault(addr + bytes - rc, 0); /* read fault */
    61.7 -        return X86EMUL_PROPAGATE_FAULT;
    61.8 +        return X86EMUL_EXCEPTION;
    61.9      }
   61.10  
   61.11 -    return X86EMUL_CONTINUE;
   61.12 +    return X86EMUL_OKAY;
   61.13  }
   61.14  
   61.15  static int ptwr_emulated_update(
   61.16 @@ -3190,7 +3190,7 @@ static int ptwr_emulated_update(
   61.17          if ( (rc = copy_from_user(&full, (void *)addr, sizeof(paddr_t))) != 0 )
   61.18          {
   61.19              propagate_page_fault(addr+sizeof(paddr_t)-rc, 0); /* read fault */
   61.20 -            return X86EMUL_PROPAGATE_FAULT;
   61.21 +            return X86EMUL_EXCEPTION;
   61.22          }
   61.23          /* Mask out bits provided by caller. */
   61.24          full &= ~((((paddr_t)1 << (bytes*8)) - 1) << (offset*8));
   61.25 @@ -3273,7 +3273,7 @@ static int ptwr_emulated_update(
   61.26      /* Finally, drop the old PTE. */
   61.27      put_page_from_l1e(gl1e_to_ml1e(d, ol1e), d);
   61.28  
   61.29 -    return X86EMUL_CONTINUE;
   61.30 +    return X86EMUL_OKAY;
   61.31  }
   61.32  
   61.33  static int ptwr_emulated_write(
   61.34 @@ -3333,6 +3333,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
   61.35      struct page_info *page;
   61.36      l1_pgentry_t      pte;
   61.37      struct ptwr_emulate_ctxt ptwr_ctxt;
   61.38 +    int rc;
   61.39  
   61.40      LOCK_BIGLOCK(d);
   61.41  
   61.42 @@ -3357,7 +3358,9 @@ int ptwr_do_page_fault(struct vcpu *v, u
   61.43          IS_COMPAT(d) ? 32 : BITS_PER_LONG;
   61.44      ptwr_ctxt.cr2 = addr;
   61.45      ptwr_ctxt.pte = pte;
   61.46 -    if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
   61.47 +
   61.48 +    rc = x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops);
   61.49 +    if ( rc == X86EMUL_UNHANDLEABLE )
   61.50          goto bail;
   61.51  
   61.52      UNLOCK_BIGLOCK(d);
    62.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Feb 22 09:42:13 2007 -0700
    62.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Feb 22 10:15:29 2007 -0700
    62.3 @@ -191,7 +191,7 @@ static int hvm_translate_linear_addr(
    62.4   gpf:
    62.5      /* Inject #GP(0). */
    62.6      hvm_inject_exception(TRAP_gp_fault, 0, 0);
    62.7 -    return X86EMUL_PROPAGATE_FAULT;
    62.8 +    return X86EMUL_EXCEPTION;
    62.9  }
   62.10  
   62.11  static int
   62.12 @@ -216,7 +216,7 @@ hvm_read(enum x86_segment seg,
   62.13      //        In this case, that is only a user vs supervisor access check.
   62.14      //
   62.15      if ( (rc = hvm_copy_from_guest_virt(val, addr, bytes)) == 0 )
   62.16 -        return X86EMUL_CONTINUE;
   62.17 +        return X86EMUL_OKAY;
   62.18  
   62.19      /* If we got here, there was nothing mapped here, or a bad GFN 
   62.20       * was mapped here.  This should never happen: we're here because
   62.21 @@ -226,7 +226,7 @@ hvm_read(enum x86_segment seg,
   62.22      if ( access_type == hvm_access_insn_fetch )
   62.23          errcode |= PFEC_insn_fetch;
   62.24      hvm_inject_exception(TRAP_page_fault, errcode, addr + bytes - rc);
   62.25 -    return X86EMUL_PROPAGATE_FAULT;
   62.26 +    return X86EMUL_EXCEPTION;
   62.27  }
   62.28  
   62.29  static int
   62.30 @@ -259,7 +259,7 @@ hvm_emulate_insn_fetch(enum x86_segment 
   62.31      /* Hit the cache. Simple memcpy. */
   62.32      *val = 0;
   62.33      memcpy(val, &sh_ctxt->insn_buf[insn_off], bytes);
   62.34 -    return X86EMUL_CONTINUE;
   62.35 +    return X86EMUL_OKAY;
   62.36  }
   62.37  
   62.38  static int
   62.39 @@ -352,10 +352,10 @@ pv_emulate_read(enum x86_segment seg,
   62.40      if ( (rc = copy_from_user((void *)val, (void *)offset, bytes)) != 0 )
   62.41      {
   62.42          propagate_page_fault(offset + bytes - rc, 0); /* read fault */
   62.43 -        return X86EMUL_PROPAGATE_FAULT;
   62.44 +        return X86EMUL_EXCEPTION;
   62.45      }
   62.46  
   62.47 -    return X86EMUL_CONTINUE;
   62.48 +    return X86EMUL_OKAY;
   62.49  }
   62.50  
   62.51  static int
   62.52 @@ -890,13 +890,17 @@ static void shadow_blow_all_tables(unsig
   62.53  {
   62.54      struct domain *d;
   62.55      printk("'%c' pressed -> blowing all shadow tables\n", c);
   62.56 +    rcu_read_lock(&domlist_read_lock);
   62.57      for_each_domain(d)
   62.58 +    {
   62.59          if ( shadow_mode_enabled(d) && d->vcpu[0] != NULL )
   62.60          {
   62.61              shadow_lock(d);
   62.62              shadow_blow_tables(d);
   62.63              shadow_unlock(d);
   62.64          }
   62.65 +    }
   62.66 +    rcu_read_unlock(&domlist_read_lock);
   62.67  }
   62.68  
   62.69  /* Register this function in the Xen console keypress table */
    63.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 09:42:13 2007 -0700
    63.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 10:15:29 2007 -0700
    63.3 @@ -2911,8 +2911,16 @@ static int sh_page_fault(struct vcpu *v,
    63.4       * page is no longer a page table. This behaviour differs from native, but
    63.5       * it seems very unlikely that any OS grants user access to page tables.
    63.6       */
    63.7 -    if ( (regs->error_code & PFEC_user_mode) ||
    63.8 -         x86_emulate(&emul_ctxt.ctxt, emul_ops) )
    63.9 +    r = X86EMUL_UNHANDLEABLE;
   63.10 +    if ( !(regs->error_code & PFEC_user_mode) )
   63.11 +        r = x86_emulate(&emul_ctxt.ctxt, emul_ops);
   63.12 +
   63.13 +    /*
   63.14 +     * NB. We do not unshadow on X86EMUL_EXCEPTION. It's not clear that it
   63.15 +     * would be a good unshadow hint. If we *do* decide to unshadow-on-fault
   63.16 +     * then it must be 'failable': we cannot require the unshadow to succeed.
   63.17 +     */
   63.18 +    if ( r == X86EMUL_UNHANDLEABLE )
   63.19      {
   63.20          SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", 
   63.21                         mfn_x(gmfn));
   63.22 @@ -3956,7 +3964,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
   63.23      ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
   63.24  
   63.25      if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
   63.26 -        return X86EMUL_PROPAGATE_FAULT;
   63.27 +        return X86EMUL_EXCEPTION;
   63.28  
   63.29      skip = safe_not_to_verify_write(mfn, addr, src, bytes);
   63.30      memcpy(addr, src, bytes);
   63.31 @@ -3968,7 +3976,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
   63.32  
   63.33      sh_unmap_domain_page(addr);
   63.34      shadow_audit_tables(v);
   63.35 -    return X86EMUL_CONTINUE;
   63.36 +    return X86EMUL_OKAY;
   63.37  }
   63.38  
   63.39  int
   63.40 @@ -3979,7 +3987,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
   63.41      mfn_t mfn;
   63.42      void *addr;
   63.43      unsigned long prev;
   63.44 -    int rv = X86EMUL_CONTINUE, skip;
   63.45 +    int rv = X86EMUL_OKAY, skip;
   63.46  
   63.47      ASSERT(shadow_locked_by_me(v->domain));
   63.48      ASSERT(bytes <= sizeof(unsigned long));
   63.49 @@ -3988,7 +3996,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
   63.50          return X86EMUL_UNHANDLEABLE;
   63.51  
   63.52      if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
   63.53 -        return X86EMUL_PROPAGATE_FAULT;
   63.54 +        return X86EMUL_EXCEPTION;
   63.55  
   63.56      skip = safe_not_to_verify_write(mfn, &new, &old, bytes);
   63.57  
   63.58 @@ -4032,7 +4040,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
   63.59      mfn_t mfn;
   63.60      void *addr;
   63.61      u64 old, new, prev;
   63.62 -    int rv = X86EMUL_CONTINUE, skip;
   63.63 +    int rv = X86EMUL_OKAY, skip;
   63.64  
   63.65      ASSERT(shadow_locked_by_me(v->domain));
   63.66  
   63.67 @@ -4040,7 +4048,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
   63.68          return X86EMUL_UNHANDLEABLE;
   63.69  
   63.70      if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
   63.71 -        return X86EMUL_PROPAGATE_FAULT;
   63.72 +        return X86EMUL_EXCEPTION;
   63.73  
   63.74      old = (((u64) old_hi) << 32) | (u64) old_lo;
   63.75      new = (((u64) new_hi) << 32) | (u64) new_lo;
    64.1 --- a/xen/arch/x86/time.c	Thu Feb 22 09:42:13 2007 -0700
    64.2 +++ b/xen/arch/x86/time.c	Thu Feb 22 10:15:29 2007 -0700
    64.3 @@ -720,10 +720,10 @@ void do_settime(unsigned long secs, unsi
    64.4      wc_nsec = _wc_nsec = (u32)y;
    64.5      spin_unlock(&wc_lock);
    64.6  
    64.7 -    read_lock(&domlist_lock);
    64.8 +    rcu_read_lock(&domlist_read_lock);
    64.9      for_each_domain ( d )
   64.10          update_domain_wallclock_time(d);
   64.11 -    read_unlock(&domlist_lock);
   64.12 +    rcu_read_unlock(&domlist_read_lock);
   64.13  }
   64.14  
   64.15  static void local_time_calibration(void *unused)
    65.1 --- a/xen/arch/x86/traps.c	Thu Feb 22 09:42:13 2007 -0700
    65.2 +++ b/xen/arch/x86/traps.c	Thu Feb 22 10:15:29 2007 -0700
    65.3 @@ -618,39 +618,77 @@ static int emulate_forced_invalid_op(str
    65.4  
    65.5  asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
    65.6  {
    65.7 -    int rc;
    65.8 +    struct bug_frame bug;
    65.9 +    struct bug_frame_str bug_str;
   65.10 +    char *filename, *predicate, *eip = (char *)regs->eip;
   65.11 +    int rc, id, lineno;
   65.12  
   65.13      DEBUGGER_trap_entry(TRAP_invalid_op, regs);
   65.14  
   65.15 -    if ( unlikely(!guest_mode(regs)) )
   65.16 +    if ( likely(guest_mode(regs)) )
   65.17      {
   65.18 -        struct bug_frame bug;
   65.19 -        if ( (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
   65.20 -             (memcmp(bug.ud2, "\xf\xb",    sizeof(bug.ud2)) == 0) &&
   65.21 -             (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) &&
   65.22 -             (bug.ret == 0xc2) )
   65.23 -        {
   65.24 -            char *filename = (char *)bug.filename;
   65.25 -            unsigned int line = bug.line & 0x7fff;
   65.26 -            int is_bug = !(bug.line & 0x8000);
   65.27 -            printk("Xen %s at %.50s:%d\n",
   65.28 -                   is_bug ? "BUG" : "State Dump", filename, line);
   65.29 -            if ( !is_bug )
   65.30 -            {
   65.31 -                show_execution_state(regs);
   65.32 -                regs->eip += sizeof(bug);
   65.33 -                return EXCRET_fault_fixed;
   65.34 -            }
   65.35 -        }
   65.36 +        if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
   65.37 +            return rc;
   65.38 +        return do_guest_trap(TRAP_invalid_op, regs, 0);
   65.39 +    }
   65.40 +
   65.41 +    if ( !is_kernel(eip) ||
   65.42 +         __copy_from_user(&bug, eip, sizeof(bug)) ||
   65.43 +         memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) ||
   65.44 +         (bug.ret != 0xc2) )
   65.45 +        goto die;
   65.46 +
   65.47 +    id = bug.id & 3;
   65.48 +    if ( id == BUGFRAME_rsvd )
   65.49 +        goto die;
   65.50 +
   65.51 +    if ( id == BUGFRAME_dump )
   65.52 +    {
   65.53 +        show_execution_state(regs);
   65.54 +        regs->eip += sizeof(bug);
   65.55 +        return EXCRET_fault_fixed;
   65.56 +    }
   65.57 +
   65.58 +    /* BUG() or ASSERT(): decode the filename pointer and line number. */
   65.59 +    ASSERT((id == BUGFRAME_bug) || (id == BUGFRAME_assert));
   65.60 +    eip += sizeof(bug);
   65.61 +    if ( !is_kernel(eip) ||
   65.62 +         __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
   65.63 +         memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
   65.64 +        goto die;
   65.65 +
   65.66 +    filename = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
   65.67 +    lineno   = bug.id >> 2;
   65.68 +
   65.69 +    if ( id == BUGFRAME_bug )
   65.70 +    {
   65.71 +        printk("Xen BUG at %.50s:%d\n", filename, lineno);
   65.72          DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
   65.73          show_execution_state(regs);
   65.74 -        panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
   65.75 +        panic("Xen BUG at %.50s:%d\n", filename, lineno);
   65.76      }
   65.77  
   65.78 -    if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
   65.79 -        return rc;
   65.80 +    /* ASSERT(): decode the predicate string pointer. */
   65.81 +    ASSERT(id == BUGFRAME_assert);
   65.82 +    eip += sizeof(bug_str);
   65.83 +    if ( !is_kernel(eip) ||
   65.84 +         __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
   65.85 +         memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
   65.86 +        goto die;
   65.87  
   65.88 -    return do_guest_trap(TRAP_invalid_op, regs, 0);
   65.89 +    predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
   65.90 +    printk("Assertion '%s' failed at %.50s:%d\n",
   65.91 +           predicate, filename, lineno);
   65.92 +    DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
   65.93 +    show_execution_state(regs);
   65.94 +    panic("Assertion '%s' failed at %.50s:%d\n",
   65.95 +          predicate, filename, lineno);
   65.96 +
   65.97 + die:
   65.98 +    DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
   65.99 +    show_execution_state(regs);
  65.100 +    panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
  65.101 +    return 0;
  65.102  }
  65.103  
  65.104  asmlinkage int do_int3(struct cpu_user_regs *regs)
  65.105 @@ -877,6 +915,9 @@ static int fixup_page_fault(unsigned lon
  65.106          return 0;
  65.107      }
  65.108  
  65.109 +    ASSERT(!in_irq());
  65.110 +    ASSERT(regs->eflags & X86_EFLAGS_IF);
  65.111 +
  65.112      if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) &&
  65.113           guest_kernel_mode(v, regs) &&
  65.114           /* Do not check if access-protection fault since the page may 
  65.115 @@ -904,8 +945,6 @@ asmlinkage int do_page_fault(struct cpu_
  65.116      unsigned long addr, fixup;
  65.117      int rc;
  65.118  
  65.119 -    ASSERT(!in_irq());
  65.120 -
  65.121      addr = read_cr2();
  65.122  
  65.123      DEBUGGER_trap_entry(TRAP_page_fault, regs);
  65.124 @@ -1916,6 +1955,8 @@ void unset_nmi_callback(void)
  65.125  
  65.126  asmlinkage int math_state_restore(struct cpu_user_regs *regs)
  65.127  {
  65.128 +    BUG_ON(!guest_mode(regs));
  65.129 +
  65.130      setup_fpu(current);
  65.131  
  65.132      if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS )
    66.1 --- a/xen/arch/x86/x86_32/entry.S	Thu Feb 22 09:42:13 2007 -0700
    66.2 +++ b/xen/arch/x86/x86_32/entry.S	Thu Feb 22 10:15:29 2007 -0700
    66.3 @@ -424,7 +424,7 @@ handle_exception:
    66.4          testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%esp)
    66.5          jz    exception_with_ints_disabled
    66.6          sti                             # re-enable interrupts
    66.7 -        xorl  %eax,%eax
    66.8 +1:      xorl  %eax,%eax
    66.9          movw  UREGS_entry_vector(%esp),%ax
   66.10          movl  %esp,%edx
   66.11          pushl %edx                      # push the cpu_user_regs pointer
   66.12 @@ -451,7 +451,7 @@ exception_with_ints_disabled:
   66.13          call  search_pre_exception_table
   66.14          addl  $4,%esp
   66.15          testl %eax,%eax                 # no fixup code for faulting EIP?
   66.16 -        jz    FATAL_exception_with_ints_disabled
   66.17 +        jz    1b
   66.18          movl  %eax,UREGS_eip(%esp)
   66.19          movl  %esp,%esi
   66.20          subl  $4,%esp
    67.1 --- a/xen/arch/x86/x86_64/entry.S	Thu Feb 22 09:42:13 2007 -0700
    67.2 +++ b/xen/arch/x86/x86_64/entry.S	Thu Feb 22 10:15:29 2007 -0700
    67.3 @@ -362,7 +362,7 @@ ENTRY(handle_exception)
    67.4          testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp)
    67.5          jz    exception_with_ints_disabled
    67.6          sti
    67.7 -        movq  %rsp,%rdi
    67.8 +1:      movq  %rsp,%rdi
    67.9          movl  UREGS_entry_vector(%rsp),%eax
   67.10          leaq  exception_table(%rip),%rdx
   67.11          GET_CURRENT(%rbx)
   67.12 @@ -388,7 +388,7 @@ exception_with_ints_disabled:
   67.13          movq  %rsp,%rdi
   67.14          call  search_pre_exception_table
   67.15          testq %rax,%rax                 # no fixup code for faulting EIP?
   67.16 -        jz    FATAL_exception_with_ints_disabled
   67.17 +        jz    1b
   67.18          movq  %rax,UREGS_rip(%rsp)
   67.19          subq  $8,UREGS_rsp(%rsp)        # add ec/ev to previous stack frame
   67.20          testb $15,UREGS_rsp(%rsp)       # return %rsp is now aligned?
    68.1 --- a/xen/arch/x86/x86_emulate.c	Thu Feb 22 09:42:13 2007 -0700
    68.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Feb 22 10:15:29 2007 -0700
    68.3 @@ -464,10 +464,10 @@ do{ __asm__ __volatile__ (              
    68.4  
    68.5  #define mode_64bit() (def_ad_bytes == 8)
    68.6  
    68.7 -#define fail_if(p)                              \
    68.8 -do {                                            \
    68.9 -    rc = (p) ? X86EMUL_UNHANDLEABLE : 0;        \
   68.10 -    if ( rc ) goto done;                        \
   68.11 +#define fail_if(p)                                      \
   68.12 +do {                                                    \
   68.13 +    rc = (p) ? X86EMUL_UNHANDLEABLE : X86EMUL_OKAY;     \
   68.14 +    if ( rc ) goto done;                                \
   68.15  } while (0)
   68.16  
   68.17  /* In future we will be able to generate arbitrary exceptions. */
   68.18 @@ -726,7 +726,7 @@ x86_emulate(
   68.19      uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   68.20      unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes;
   68.21      unsigned int lock_prefix = 0, rep_prefix = 0;
   68.22 -    int rc = 0;
   68.23 +    int rc = X86EMUL_OKAY;
   68.24      struct operand src, dst;
   68.25  
   68.26      /* Data operand effective address (usually computed from ModRM). */
   68.27 @@ -742,7 +742,7 @@ x86_emulate(
   68.28      {
   68.29          op_bytes = def_op_bytes = 4;
   68.30  #ifndef __x86_64__
   68.31 -        return -1;
   68.32 +        return X86EMUL_UNHANDLEABLE;
   68.33  #endif
   68.34      }
   68.35  
   68.36 @@ -1593,7 +1593,7 @@ x86_emulate(
   68.37      *ctxt->regs = _regs;
   68.38  
   68.39   done:
   68.40 -    return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
   68.41 +    return rc;
   68.42  
   68.43   special_insn:
   68.44      dst.type = OP_NONE;
   68.45 @@ -2383,5 +2383,5 @@ x86_emulate(
   68.46      }
   68.47      printk("\n");
   68.48  #endif
   68.49 -    return -1;
   68.50 +    return X86EMUL_UNHANDLEABLE;
   68.51  }
    69.1 --- a/xen/common/domain.c	Thu Feb 22 09:42:13 2007 -0700
    69.2 +++ b/xen/common/domain.c	Thu Feb 22 10:15:29 2007 -0700
    69.3 @@ -24,13 +24,18 @@
    69.4  #include <xen/shutdown.h>
    69.5  #include <xen/percpu.h>
    69.6  #include <xen/multicall.h>
    69.7 +#include <xen/rcupdate.h>
    69.8  #include <asm/debugger.h>
    69.9  #include <public/sched.h>
   69.10  #include <public/vcpu.h>
   69.11  
   69.12 -/* Both these structures are protected by the domlist_lock. */
   69.13 -DEFINE_RWLOCK(domlist_lock);
   69.14 -struct domain *domain_hash[DOMAIN_HASH_SIZE];
   69.15 +/* Protect updates/reads (resp.) of domain_list and domain_hash. */
   69.16 +DEFINE_SPINLOCK(domlist_update_lock);
   69.17 +DEFINE_RCU_READ_LOCK(domlist_read_lock);
   69.18 +
   69.19 +#define DOMAIN_HASH_SIZE 256
   69.20 +#define DOMAIN_HASH(_id) ((int)(_id)&(DOMAIN_HASH_SIZE-1))
   69.21 +static struct domain *domain_hash[DOMAIN_HASH_SIZE];
   69.22  struct domain *domain_list;
   69.23  
   69.24  struct domain *dom0;
   69.25 @@ -174,16 +179,20 @@ struct domain *domain_create(domid_t dom
   69.26  
   69.27      if ( !is_idle_domain(d) )
   69.28      {
   69.29 -        write_lock(&domlist_lock);
   69.30 +        spin_lock(&domlist_update_lock);
   69.31          pd = &domain_list; /* NB. domain_list maintained in order of domid. */
   69.32          for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list )
   69.33              if ( (*pd)->domain_id > d->domain_id )
   69.34                  break;
   69.35          d->next_in_list = *pd;
   69.36 -        *pd = d;
   69.37          d->next_in_hashbucket = domain_hash[DOMAIN_HASH(domid)];
   69.38 -        domain_hash[DOMAIN_HASH(domid)] = d;
   69.39 -        write_unlock(&domlist_lock);
   69.40 +        /* Two rcu assignments are not atomic 
   69.41 +         * Readers may see inconsistent domlist and hash table
   69.42 +         * That is OK as long as each RCU reader-side critical section uses
   69.43 +         * only one or them  */
   69.44 +        rcu_assign_pointer(*pd, d);
   69.45 +        rcu_assign_pointer(domain_hash[DOMAIN_HASH(domid)], d);
   69.46 +        spin_unlock(&domlist_update_lock);
   69.47      }
   69.48  
   69.49      return d;
   69.50 @@ -207,9 +216,11 @@ struct domain *get_domain_by_id(domid_t 
   69.51  {
   69.52      struct domain *d;
   69.53  
   69.54 -    read_lock(&domlist_lock);
   69.55 -    d = domain_hash[DOMAIN_HASH(dom)];
   69.56 -    while ( d != NULL )
   69.57 +    rcu_read_lock(&domlist_read_lock);
   69.58 +
   69.59 +    for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
   69.60 +          d != NULL;
   69.61 +          d = rcu_dereference(d->next_in_hashbucket) )
   69.62      {
   69.63          if ( d->domain_id == dom )
   69.64          {
   69.65 @@ -217,14 +228,34 @@ struct domain *get_domain_by_id(domid_t 
   69.66                  d = NULL;
   69.67              break;
   69.68          }
   69.69 -        d = d->next_in_hashbucket;
   69.70      }
   69.71 -    read_unlock(&domlist_lock);
   69.72 +
   69.73 +    rcu_read_unlock(&domlist_read_lock);
   69.74  
   69.75      return d;
   69.76  }
   69.77  
   69.78  
   69.79 +struct domain *find_domain_rcu_lock(domid_t dom)
   69.80 +{
   69.81 +    struct domain *d;
   69.82 +
   69.83 +    rcu_read_lock(&domlist_read_lock);
   69.84 +
   69.85 +    for ( d = rcu_dereference(domain_hash[DOMAIN_HASH(dom)]);
   69.86 +          d != NULL;
   69.87 +          d = rcu_dereference(d->next_in_hashbucket) )
   69.88 +    {
   69.89 +        if ( d->domain_id == dom )
   69.90 +            return d;
   69.91 +    }
   69.92 +
   69.93 +    rcu_read_unlock(&domlist_read_lock);
   69.94 +
   69.95 +    return NULL;
   69.96 +}
   69.97 +
   69.98 +
   69.99  void domain_kill(struct domain *d)
  69.100  {
  69.101      domain_pause(d);
  69.102 @@ -314,6 +345,23 @@ void domain_pause_for_debugger(void)
  69.103      send_guest_global_virq(dom0, VIRQ_DEBUGGER);
  69.104  }
  69.105  
  69.106 +/* Complete domain destroy after RCU readers are not holding 
  69.107 +   old references */
  69.108 +static void complete_domain_destroy(struct rcu_head *head)
  69.109 +{
  69.110 +    struct domain *d = container_of(head, struct domain, rcu);
  69.111 +
  69.112 +    rangeset_domain_destroy(d);
  69.113 +
  69.114 +    evtchn_destroy(d);
  69.115 +    grant_table_destroy(d);
  69.116 +
  69.117 +    arch_domain_destroy(d);
  69.118 +
  69.119 +    free_domain(d);
  69.120 +
  69.121 +    send_guest_global_virq(dom0, VIRQ_DOM_EXC);
  69.122 +}
  69.123  
  69.124  /* Release resources belonging to task @p. */
  69.125  void domain_destroy(struct domain *d)
  69.126 @@ -331,27 +379,19 @@ void domain_destroy(struct domain *d)
  69.127          return;
  69.128  
  69.129      /* Delete from task list and task hashtable. */
  69.130 -    write_lock(&domlist_lock);
  69.131 +    spin_lock(&domlist_update_lock);
  69.132      pd = &domain_list;
  69.133      while ( *pd != d ) 
  69.134          pd = &(*pd)->next_in_list;
  69.135 -    *pd = d->next_in_list;
  69.136 +    rcu_assign_pointer(*pd, d->next_in_list);
  69.137      pd = &domain_hash[DOMAIN_HASH(d->domain_id)];
  69.138      while ( *pd != d ) 
  69.139          pd = &(*pd)->next_in_hashbucket;
  69.140 -    *pd = d->next_in_hashbucket;
  69.141 -    write_unlock(&domlist_lock);
  69.142 -
  69.143 -    rangeset_domain_destroy(d);
  69.144 +    rcu_assign_pointer(*pd, d->next_in_hashbucket);
  69.145 +    spin_unlock(&domlist_update_lock);
  69.146  
  69.147 -    evtchn_destroy(d);
  69.148 -    grant_table_destroy(d);
  69.149 -
  69.150 -    arch_domain_destroy(d);
  69.151 -
  69.152 -    free_domain(d);
  69.153 -
  69.154 -    send_guest_global_virq(dom0, VIRQ_DOM_EXC);
  69.155 +    /* schedule RCU asynchronous completion of domain destroy */
  69.156 +    call_rcu(&d->rcu, complete_domain_destroy);
  69.157  }
  69.158  
  69.159  static void vcpu_pause_setup(struct vcpu *v)
    70.1 --- a/xen/common/domctl.c	Thu Feb 22 09:42:13 2007 -0700
    70.2 +++ b/xen/common/domctl.c	Thu Feb 22 10:15:29 2007 -0700
    70.3 @@ -17,6 +17,7 @@
    70.4  #include <xen/trace.h>
    70.5  #include <xen/console.h>
    70.6  #include <xen/iocap.h>
    70.7 +#include <xen/rcupdate.h>
    70.8  #include <xen/guest_access.h>
    70.9  #include <xen/bitmap.h>
   70.10  #include <asm/current.h>
   70.11 @@ -140,12 +141,12 @@ static unsigned int default_vcpu0_locati
   70.12      cpumask_t      cpu_exclude_map;
   70.13  
   70.14      /* Do an initial CPU placement. Pick the least-populated CPU. */
   70.15 -    read_lock(&domlist_lock);
   70.16 +    rcu_read_lock(&domlist_read_lock);
   70.17      for_each_domain ( d )
   70.18          for_each_vcpu ( d, v )
   70.19          if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
   70.20              cnt[v->processor]++;
   70.21 -    read_unlock(&domlist_lock);
   70.22 +    rcu_read_unlock(&domlist_read_lock);
   70.23  
   70.24      /*
   70.25       * If we're on a HT system, we only auto-allocate to a non-primary HT. We 
   70.26 @@ -480,7 +481,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   70.27          if ( dom == DOMID_SELF )
   70.28              dom = current->domain->domain_id;
   70.29  
   70.30 -        read_lock(&domlist_lock);
   70.31 +        rcu_read_lock(&domlist_read_lock);
   70.32  
   70.33          for_each_domain ( d )
   70.34          {
   70.35 @@ -490,12 +491,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   70.36  
   70.37          if ( (d == NULL) || !get_domain(d) )
   70.38          {
   70.39 -            read_unlock(&domlist_lock);
   70.40 +            rcu_read_unlock(&domlist_read_lock);
   70.41              ret = -ESRCH;
   70.42              break;
   70.43          }
   70.44  
   70.45 -        read_unlock(&domlist_lock);
   70.46 +        rcu_read_unlock(&domlist_read_lock);
   70.47  
   70.48          getdomaininfo(d, &op->u.getdomaininfo);
   70.49  
    71.1 --- a/xen/common/keyhandler.c	Thu Feb 22 09:42:13 2007 -0700
    71.2 +++ b/xen/common/keyhandler.c	Thu Feb 22 10:15:29 2007 -0700
    71.3 @@ -145,7 +145,7 @@ static void dump_domains(unsigned char k
    71.4      printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
    71.5             (u32)(now>>32), (u32)now);
    71.6  
    71.7 -    read_lock(&domlist_lock);
    71.8 +    rcu_read_lock(&domlist_read_lock);
    71.9  
   71.10      for_each_domain ( d )
   71.11      {
   71.12 @@ -196,7 +196,7 @@ static void dump_domains(unsigned char k
   71.13          }
   71.14      }
   71.15  
   71.16 -    read_unlock(&domlist_lock);
   71.17 +    rcu_read_unlock(&domlist_read_lock);
   71.18  }
   71.19  
   71.20  static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
    72.1 --- a/xen/common/sched_sedf.c	Thu Feb 22 09:42:13 2007 -0700
    72.2 +++ b/xen/common/sched_sedf.c	Thu Feb 22 10:15:29 2007 -0700
    72.3 @@ -1277,6 +1277,7 @@ static void sedf_dump_cpu_state(int i)
    72.4      loop = 0;
    72.5      printk("\nnot on Q\n");
    72.6  
    72.7 +    rcu_read_lock(&domlist_read_lock);
    72.8      for_each_domain ( d )
    72.9      {
   72.10          for_each_vcpu(d, ed)
   72.11 @@ -1288,6 +1289,7 @@ static void sedf_dump_cpu_state(int i)
   72.12              }
   72.13          }
   72.14      }
   72.15 +    rcu_read_unlock(&domlist_read_lock);
   72.16  }
   72.17  
   72.18  
   72.19 @@ -1298,8 +1300,9 @@ static int sedf_adjust_weights(struct xe
   72.20      struct domain      *d;
   72.21      int                 sumw[NR_CPUS] = { 0 };
   72.22      s_time_t            sumt[NR_CPUS] = { 0 };
   72.23 - 
   72.24 +
   72.25      /* Sum across all weights. */
   72.26 +    rcu_read_lock(&domlist_read_lock);
   72.27      for_each_domain( d )
   72.28      {
   72.29          for_each_vcpu( d, p )
   72.30 @@ -1323,8 +1326,10 @@ static int sedf_adjust_weights(struct xe
   72.31              }
   72.32          }
   72.33      }
   72.34 +    rcu_read_unlock(&domlist_read_lock);
   72.35  
   72.36      /* Adjust all slices (and periods) to the new weight. */
   72.37 +    rcu_read_lock(&domlist_read_lock);
   72.38      for_each_domain( d )
   72.39      {
   72.40          for_each_vcpu ( d, p )
   72.41 @@ -1341,6 +1346,7 @@ static int sedf_adjust_weights(struct xe
   72.42              }
   72.43          }
   72.44      }
   72.45 +    rcu_read_unlock(&domlist_read_lock);
   72.46  
   72.47      return 0;
   72.48  }
    73.1 --- a/xen/common/sysctl.c	Thu Feb 22 09:42:13 2007 -0700
    73.2 +++ b/xen/common/sysctl.c	Thu Feb 22 10:15:29 2007 -0700
    73.3 @@ -78,7 +78,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
    73.4          struct xen_domctl_getdomaininfo info;
    73.5          u32 num_domains = 0;
    73.6  
    73.7 -        read_lock(&domlist_lock);
    73.8 +        rcu_read_lock(&domlist_read_lock);
    73.9  
   73.10          for_each_domain ( d )
   73.11          {
   73.12 @@ -106,7 +106,7 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
   73.13              num_domains++;
   73.14          }
   73.15          
   73.16 -        read_unlock(&domlist_lock);
   73.17 +        rcu_read_unlock(&domlist_read_lock);
   73.18          
   73.19          if ( ret != 0 )
   73.20              break;
    74.1 --- a/xen/include/asm-x86/bug.h	Thu Feb 22 09:42:13 2007 -0700
    74.2 +++ b/xen/include/asm-x86/bug.h	Thu Feb 22 10:15:29 2007 -0700
    74.3 @@ -7,7 +7,15 @@
    74.4  #include <asm/x86_32/bug.h>
    74.5  #endif
    74.6  
    74.7 -#define BUG()                  __BUG(__FILE__, __LINE__)
    74.8 -#define dump_execution_state() __BUG(__FILE__, __LINE__ | 0x8000)
    74.9 +struct bug_frame {
   74.10 +    unsigned char ud2[2];
   74.11 +    unsigned char ret;
   74.12 +    unsigned short id; /* BUGFRAME_??? */
   74.13 +} __attribute__((packed));
   74.14 +
   74.15 +#define BUGFRAME_dump   0
   74.16 +#define BUGFRAME_bug    1
   74.17 +#define BUGFRAME_assert 2
   74.18 +#define BUGFRAME_rsvd   3
   74.19  
   74.20  #endif /* __X86_BUG_H__ */
    75.1 --- a/xen/include/asm-x86/event.h	Thu Feb 22 09:42:13 2007 -0700
    75.2 +++ b/xen/include/asm-x86/event.h	Thu Feb 22 10:15:29 2007 -0700
    75.3 @@ -10,6 +10,7 @@
    75.4  #define __ASM_EVENT_H__
    75.5  
    75.6  #include <xen/shared.h>
    75.7 +#include <asm/hvm/irq.h> /* cpu_has_pending_irq() */
    75.8  
    75.9  static inline void vcpu_kick(struct vcpu *v)
   75.10  {
   75.11 @@ -37,9 +38,9 @@ static inline void vcpu_mark_events_pend
   75.12  static inline int local_events_need_delivery(void)
   75.13  {
   75.14      struct vcpu *v = current;
   75.15 -    /* Note: Bitwise operations result in fast code with no branches. */
   75.16 -    return (!!vcpu_info(v, evtchn_upcall_pending) &
   75.17 -             !vcpu_info(v, evtchn_upcall_mask));
   75.18 +    return ((vcpu_info(v, evtchn_upcall_pending) &&
   75.19 +             !vcpu_info(v, evtchn_upcall_mask)) ||
   75.20 +            (is_hvm_vcpu(v) && cpu_has_pending_irq(v)));
   75.21  }
   75.22  
   75.23  static inline int local_event_delivery_is_enabled(void)
    76.1 --- a/xen/include/asm-x86/x86_32/bug.h	Thu Feb 22 09:42:13 2007 -0700
    76.2 +++ b/xen/include/asm-x86/x86_32/bug.h	Thu Feb 22 10:15:29 2007 -0700
    76.3 @@ -1,19 +1,28 @@
    76.4  #ifndef __X86_32_BUG_H__
    76.5  #define __X86_32_BUG_H__
    76.6  
    76.7 -struct bug_frame {
    76.8 -    unsigned char ud2[2];
    76.9 +struct bug_frame_str {
   76.10      unsigned char mov[1];
   76.11 -    unsigned long filename;
   76.12 -    unsigned char ret;
   76.13 -    unsigned short line;
   76.14 +    unsigned long str;
   76.15  } __attribute__((packed));
   76.16 -
   76.17  #define BUG_MOV_STR "\xbc"
   76.18  
   76.19 -#define __BUG(file, line)                               \
   76.20 +#define dump_execution_state()                          \
   76.21      asm volatile (                                      \
   76.22 -        "ud2 ; .byte 0xbc ; .long %c1 ; ret $%c0"       \
   76.23 -        : : "i" (line), "i" (file) )
   76.24 +        "ud2 ; ret $%c0"                                \
   76.25 +        : : "i" (BUGFRAME_dump) )
   76.26 +
   76.27 +#define BUG()                                           \
   76.28 +    asm volatile (                                      \
   76.29 +        "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1"       \
   76.30 +        : : "i" (BUGFRAME_bug | (__LINE__<<2)),         \
   76.31 +            "i" (__FILE__) )
   76.32 +
   76.33 +#define assert_failed(p)                                \
   76.34 +    asm volatile (                                      \
   76.35 +        "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1"       \
   76.36 +        " ; .byte 0xbc ; .long %c2"                     \
   76.37 +        : : "i" (BUGFRAME_assert | (__LINE__<<2)),      \
   76.38 +            "i" (__FILE__), "i" (#p) )
   76.39  
   76.40  #endif /* __X86_32_BUG_H__ */
    77.1 --- a/xen/include/asm-x86/x86_64/bug.h	Thu Feb 22 09:42:13 2007 -0700
    77.2 +++ b/xen/include/asm-x86/x86_64/bug.h	Thu Feb 22 10:15:29 2007 -0700
    77.3 @@ -1,19 +1,28 @@
    77.4  #ifndef __X86_64_BUG_H__
    77.5  #define __X86_64_BUG_H__
    77.6  
    77.7 -struct bug_frame {
    77.8 -    unsigned char ud2[2];
    77.9 +struct bug_frame_str {
   77.10      unsigned char mov[2];
   77.11 -    unsigned long filename;
   77.12 -    unsigned char ret;
   77.13 -    unsigned short line;
   77.14 +    unsigned long str;
   77.15  } __attribute__((packed));
   77.16 -
   77.17  #define BUG_MOV_STR "\x48\xbc"
   77.18  
   77.19 -#define __BUG(file, line)                               \
   77.20 +#define dump_execution_state()                          \
   77.21      asm volatile (                                      \
   77.22 -        "ud2 ; .byte 0x48,0xbc ; .quad %c1 ; ret $%c0"  \
   77.23 -        : : "i" (line), "i" (file) )
   77.24 +        "ud2 ; ret $%c0"                                \
   77.25 +        : : "i" (BUGFRAME_dump) )
   77.26 +
   77.27 +#define BUG()                                           \
   77.28 +    asm volatile (                                      \
   77.29 +        "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1"  \
   77.30 +        : : "i" (BUGFRAME_bug | (__LINE__<<2)),         \
   77.31 +            "i" (__FILE__) )
   77.32 +
   77.33 +#define assert_failed(p)                                \
   77.34 +    asm volatile (                                      \
   77.35 +        "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1"  \
   77.36 +        " ; .byte 0x48,0xbc ; .quad %c2"                \
   77.37 +        : : "i" (BUGFRAME_assert | (__LINE__<<2)),      \
   77.38 +            "i" (__FILE__), "i" (#p) )
   77.39  
   77.40  #endif /* __X86_64_BUG_H__ */
    78.1 --- a/xen/include/asm-x86/x86_emulate.h	Thu Feb 22 09:42:13 2007 -0700
    78.2 +++ b/xen/include/asm-x86/x86_emulate.h	Thu Feb 22 10:15:29 2007 -0700
    78.3 @@ -46,26 +46,32 @@ enum x86_segment {
    78.4  };
    78.5  
    78.6  /*
    78.7 + * Return codes from state-accessor functions and from x86_emulate().
    78.8 + */
    78.9 + /* Completed successfully. State modified appropriately. */
   78.10 +#define X86EMUL_OKAY           0
   78.11 + /* Unhandleable access or emulation. No state modified. */
   78.12 +#define X86EMUL_UNHANDLEABLE   1
   78.13 + /* Exception raised and requires delivery. */
   78.14 +#define X86EMUL_EXCEPTION      2
   78.15 + /* Retry the emulation for some reason. No state modified. */
   78.16 +#define X86EMUL_RETRY          3
   78.17 + /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
   78.18 +#define X86EMUL_CMPXCHG_FAILED 3
   78.19 +
   78.20 +/*
   78.21   * These operations represent the instruction emulator's interface to memory.
   78.22   * 
   78.23   * NOTES:
   78.24   *  1. If the access fails (cannot emulate, or a standard access faults) then
   78.25   *     it is up to the memop to propagate the fault to the guest VM via
   78.26   *     some out-of-band mechanism, unknown to the emulator. The memop signals
   78.27 - *     failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
   78.28 + *     failure by returning X86EMUL_EXCEPTION to the emulator, which will
   78.29   *     then immediately bail.
   78.30   *  2. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
   78.31   *     cmpxchg8b_emulated need support 8-byte accesses.
   78.32   *  3. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
   78.33   */
   78.34 -/* Access completed successfully: continue emulation as normal. */
   78.35 -#define X86EMUL_CONTINUE        0
   78.36 -/* Access is unhandleable: bail from emulation and return error to caller. */
   78.37 -#define X86EMUL_UNHANDLEABLE    1
   78.38 -/* Terminate emulation but return success to the caller. */
   78.39 -#define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
   78.40 -#define X86EMUL_RETRY_INSTR     2 /* retry the instruction for some reason */
   78.41 -#define X86EMUL_CMPXCHG_FAILED  2 /* cmpxchg did not see expected value */
   78.42  struct x86_emulate_ops
   78.43  {
   78.44      /*
    79.1 --- a/xen/include/xen/lib.h	Thu Feb 22 09:42:13 2007 -0700
    79.2 +++ b/xen/include/xen/lib.h	Thu Feb 22 10:15:29 2007 -0700
    79.3 @@ -16,18 +16,20 @@ void __bug(char *file, int line) __attri
    79.4  /* Force a compilation error if condition is true */
    79.5  #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
    79.6  
    79.7 +#ifndef assert_failed
    79.8 +#define assert_failed(p)                                        \
    79.9 +do {                                                            \
   79.10 +    printk("Assertion '%s' failed, line %d, file %s\n", #p ,    \
   79.11 +                   __LINE__, __FILE__);                         \
   79.12 +    BUG();                                                      \
   79.13 +} while (0)
   79.14 +#endif
   79.15 +
   79.16  #ifndef NDEBUG
   79.17 -#define ASSERT(_p)                                                      \
   79.18 -    do {                                                                \
   79.19 -        if ( unlikely(!(_p)) )                                          \
   79.20 -        {                                                               \
   79.21 -            printk("Assertion '%s' failed, line %d, file %s\n", #_p ,   \
   79.22 -                   __LINE__, __FILE__);                                 \
   79.23 -            BUG();                                                      \
   79.24 -        }                                                               \
   79.25 -    } while ( 0 )
   79.26 +#define ASSERT(p) \
   79.27 +    do { if ( unlikely(!(p)) ) assert_failed(p); } while (0)
   79.28  #else
   79.29 -#define ASSERT(_p) ((void)0)
   79.30 +#define ASSERT(p) ((void)0)
   79.31  #endif
   79.32  
   79.33  #define SWAP(_a, _b) \
    80.1 --- a/xen/include/xen/rcupdate.h	Thu Feb 22 09:42:13 2007 -0700
    80.2 +++ b/xen/include/xen/rcupdate.h	Thu Feb 22 10:15:29 2007 -0700
    80.3 @@ -111,6 +111,59 @@ extern struct rcu_ctrlblk rcu_ctrlblk;
    80.4  int rcu_pending(int cpu);
    80.5  int rcu_needs_cpu(int cpu);
    80.6  
    80.7 +/*
    80.8 + * Dummy lock type for passing to rcu_read_{lock,unlock}. Currently exists
    80.9 + * only to document the reason for rcu_read_lock() critical sections.
   80.10 + */
   80.11 +struct _rcu_read_lock {};
   80.12 +typedef struct _rcu_read_lock rcu_read_lock_t;
   80.13 +#define DEFINE_RCU_READ_LOCK(x) rcu_read_lock_t x
   80.14 +
   80.15 +/**
   80.16 + * rcu_read_lock - mark the beginning of an RCU read-side critical section.
   80.17 + *
   80.18 + * When call_rcu() is invoked
   80.19 + * on one CPU while other CPUs are within RCU read-side critical
   80.20 + * sections, invocation of the corresponding RCU callback is deferred
   80.21 + * until after the all the other CPUs exit their critical sections.
   80.22 + *
   80.23 + * Note, however, that RCU callbacks are permitted to run concurrently
   80.24 + * with RCU read-side critical sections.  One way that this can happen
   80.25 + * is via the following sequence of events: (1) CPU 0 enters an RCU
   80.26 + * read-side critical section, (2) CPU 1 invokes call_rcu() to register
   80.27 + * an RCU callback, (3) CPU 0 exits the RCU read-side critical section,
   80.28 + * (4) CPU 2 enters a RCU read-side critical section, (5) the RCU
   80.29 + * callback is invoked.  This is legal, because the RCU read-side critical
   80.30 + * section that was running concurrently with the call_rcu() (and which
   80.31 + * therefore might be referencing something that the corresponding RCU
   80.32 + * callback would free up) has completed before the corresponding
   80.33 + * RCU callback is invoked.
   80.34 + *
   80.35 + * RCU read-side critical sections may be nested.  Any deferred actions
   80.36 + * will be deferred until the outermost RCU read-side critical section
   80.37 + * completes.
   80.38 + *
   80.39 + * It is illegal to block while in an RCU read-side critical section.
   80.40 + */
   80.41 +#define rcu_read_lock(x)       do { } while (0)
   80.42 +
   80.43 +/**
   80.44 + * rcu_read_unlock - marks the end of an RCU read-side critical section.
   80.45 + *
   80.46 + * See rcu_read_lock() for more information.
   80.47 + */
   80.48 +#define rcu_read_unlock(x)     do { } while (0)
   80.49 +
   80.50 +/*
   80.51 + * So where is rcu_write_lock()?  It does not exist, as there is no
   80.52 + * way for writers to lock out RCU readers.  This is a feature, not
   80.53 + * a bug -- this property is what provides RCU's performance benefits.
   80.54 + * Of course, writers must coordinate with each other.  The normal
   80.55 + * spinlock primitives work well for this, but any other technique may be
   80.56 + * used as well.  RCU does not care how the writers keep out of each
   80.57 + * others' way, as long as they do so.
   80.58 + */
   80.59 +
   80.60  /**
   80.61   * rcu_dereference - fetch an RCU-protected pointer in an
   80.62   * RCU read-side critical section.  This pointer may later
    81.1 --- a/xen/include/xen/sched.h	Thu Feb 22 09:42:13 2007 -0700
    81.2 +++ b/xen/include/xen/sched.h	Thu Feb 22 10:15:29 2007 -0700
    81.3 @@ -16,6 +16,7 @@
    81.4  #include <xen/rangeset.h>
    81.5  #include <asm/domain.h>
    81.6  #include <xen/xenoprof.h>
    81.7 +#include <xen/rcupdate.h>
    81.8  #include <xen/irq.h>
    81.9  
   81.10  #ifdef CONFIG_COMPAT
   81.11 @@ -24,7 +25,6 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_in
   81.12  #endif
   81.13  
   81.14  extern unsigned long volatile jiffies;
   81.15 -extern rwlock_t domlist_lock;
   81.16  
   81.17  /* A global pointer to the initial domain (DOM0). */
   81.18  extern struct domain *dom0;
   81.19 @@ -193,6 +193,8 @@ struct domain
   81.20      /* OProfile support. */
   81.21      struct xenoprof *xenoprof;
   81.22      int32_t time_offset_seconds;
   81.23 +
   81.24 +    struct rcu_head rcu;
   81.25  };
   81.26  
   81.27  struct domain_setup_info
   81.28 @@ -267,6 +269,21 @@ int construct_dom0(
   81.29      unsigned long initrd_start, unsigned long initrd_len,
   81.30      char *cmdline);
   81.31  
   81.32 +/*
   81.33 + * find_domain_rcu_lock() is more efficient than get_domain_by_id().
   81.34 + * This is the preferred function if the returned domain reference
   81.35 + * is short lived,  but it cannot be used if the domain reference needs 
   81.36 + * to be kept beyond the current scope (e.g., across a softirq).
   81.37 + * The returned domain reference must be discarded using domain_rcu_unlock().
   81.38 + */
   81.39 +struct domain *find_domain_rcu_lock(domid_t dom);
   81.40 +
   81.41 +/* Finish a RCU critical region started by find_domain_rcu_lock(). */
   81.42 +static inline void domain_rcu_unlock(struct domain *d)
   81.43 +{
   81.44 +    rcu_read_unlock(&domlist_read_lock);
   81.45 +}
   81.46 +
   81.47  struct domain *get_domain_by_id(domid_t dom);
   81.48  void domain_destroy(struct domain *d);
   81.49  void domain_kill(struct domain *d);
   81.50 @@ -356,16 +373,17 @@ unsigned long hypercall_create_continuat
   81.51          local_events_need_delivery()            \
   81.52      ))
   81.53  
   81.54 -/* This domain_hash and domain_list are protected by the domlist_lock. */
   81.55 -#define DOMAIN_HASH_SIZE 256
   81.56 -#define DOMAIN_HASH(_id) ((int)(_id)&(DOMAIN_HASH_SIZE-1))
   81.57 -extern struct domain *domain_hash[DOMAIN_HASH_SIZE];
   81.58 +/* Protect updates/reads (resp.) of domain_list and domain_hash. */
   81.59 +extern spinlock_t domlist_update_lock;
   81.60 +extern rcu_read_lock_t domlist_read_lock;
   81.61 +
   81.62  extern struct domain *domain_list;
   81.63  
   81.64 +/* Caller must hold the domlist_read_lock or domlist_update_lock. */
   81.65  #define for_each_domain(_d)                     \
   81.66 - for ( (_d) = domain_list;                      \
   81.67 + for ( (_d) = rcu_dereference(domain_list);     \
   81.68         (_d) != NULL;                            \
   81.69 -       (_d) = (_d)->next_in_list )
   81.70 +       (_d) = rcu_dereference((_d)->next_in_list )) \
   81.71  
   81.72  #define for_each_vcpu(_d,_v)                    \
   81.73   for ( (_v) = (_d)->vcpu[0];                    \