ia64/xen-unstable
changeset 12774:d603aed5ad6d
merge with xen-unstable.hg
author | awilliam@xenbuild.aw |
---|---|
date | Mon Dec 04 08:24:41 2006 -0700 (2006-12-04) |
parents | 6fdbf173142d 275a8f9a0710 |
children | e729184b5c0e |
files | xen/arch/ia64/xen/Makefile xen/arch/x86/hvm/vmx/io.c xen/include/xen/softirq.h |
line diff
1.1 --- a/.hgignore Sat Dec 02 15:19:50 2006 -0700 1.2 +++ b/.hgignore Mon Dec 04 08:24:41 2006 -0700 1.3 @@ -158,6 +158,8 @@ 1.4 ^tools/xcutils/xc_restore$ 1.5 ^tools/xcutils/xc_save$ 1.6 ^tools/xcutils/readnotes$ 1.7 +^tools/xenfb/sdlfb$ 1.8 +^tools/xenfb/vncfb$ 1.9 ^tools/xenmon/xentrace_setmask$ 1.10 ^tools/xenmon/xenbaked$ 1.11 ^tools/xenstat/xentop/xentop$
2.1 --- a/Config.mk Sat Dec 02 15:19:50 2006 -0700 2.2 +++ b/Config.mk Mon Dec 04 08:24:41 2006 -0700 2.3 @@ -69,8 +69,8 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_ 2.4 2.5 # Optional components 2.6 XENSTAT_XENTOP ?= y 2.7 - 2.8 VTPM_TOOLS ?= n 2.9 LIBXENAPI_BINDINGS ?= n 2.10 +XENFB_TOOLS ?= n 2.11 2.12 -include $(XEN_ROOT)/.config
3.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32 Sat Dec 02 15:19:50 2006 -0700 3.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 Mon Dec 04 08:24:41 2006 -0700 3.3 @@ -179,6 +179,7 @@ CONFIG_HZ_100=y 3.4 # CONFIG_HZ_250 is not set 3.5 # CONFIG_HZ_1000 is not set 3.6 CONFIG_HZ=100 3.7 +CONFIG_KEXEC=y 3.8 # CONFIG_CRASH_DUMP is not set 3.9 CONFIG_PHYSICAL_START=0x100000 3.10
4.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64 Sat Dec 02 15:19:50 2006 -0700 4.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 Mon Dec 04 08:24:41 2006 -0700 4.3 @@ -126,6 +126,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y 4.4 # CONFIG_SPARSEMEM_STATIC is not set 4.5 CONFIG_SPLIT_PTLOCK_CPUS=4096 4.6 CONFIG_SWIOTLB=y 4.7 +CONFIG_KEXEC=y 4.8 # CONFIG_CRASH_DUMP is not set 4.9 CONFIG_PHYSICAL_START=0x100000 4.10 CONFIG_SECCOMP=y
5.1 --- a/buildconfigs/linux-defconfig_xen_x86_32 Sat Dec 02 15:19:50 2006 -0700 5.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Mon Dec 04 08:24:41 2006 -0700 5.3 @@ -184,6 +184,7 @@ CONFIG_MTRR=y 5.4 CONFIG_REGPARM=y 5.5 CONFIG_SECCOMP=y 5.6 CONFIG_HZ_100=y 5.7 +CONFIG_KEXEC=y 5.8 # CONFIG_HZ_250 is not set 5.9 # CONFIG_HZ_1000 is not set 5.10 CONFIG_HZ=100 5.11 @@ -2776,6 +2777,7 @@ CONFIG_NTFS_FS=m 5.12 # 5.13 CONFIG_PROC_FS=y 5.14 CONFIG_PROC_KCORE=y 5.15 +# CONFIG_PROC_VMCORE is not set 5.16 CONFIG_SYSFS=y 5.17 CONFIG_TMPFS=y 5.18 # CONFIG_HUGETLB_PAGE is not set
6.1 --- a/buildconfigs/linux-defconfig_xen_x86_64 Sat Dec 02 15:19:50 2006 -0700 6.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64 Mon Dec 04 08:24:41 2006 -0700 6.3 @@ -139,6 +139,7 @@ CONFIG_SWIOTLB=y 6.4 CONFIG_PHYSICAL_START=0x100000 6.5 CONFIG_SECCOMP=y 6.6 CONFIG_HZ_100=y 6.7 +CONFIG_KEXEC=y 6.8 # CONFIG_HZ_250 is not set 6.9 # CONFIG_HZ_1000 is not set 6.10 CONFIG_HZ=100
7.1 --- a/docs/xen-api/presentation.tex Sat Dec 02 15:19:50 2006 -0700 7.2 +++ b/docs/xen-api/presentation.tex Mon Dec 04 08:24:41 2006 -0700 7.3 @@ -131,9 +131,6 @@ of that class that has the specified {\t 7.4 ``{\tt get\_by\_name\_label(name)}'' RPC that returns a set of objects of that 7.5 class that have the specified {\tt label}. 7.6 7.7 -\item Each class has a ``{\tt to\_XML()}'' RPC that serialises the 7.8 -state of all fields as an XML string. 7.9 - 7.10 \item Each class has a ``{\tt destroy(Ref x)}'' RPC that explicitly deletes 7.11 the persistent object specified by {\tt x} from the system. This is a 7.12 non-cascading delete -- if the object being removed is referenced by another 7.13 @@ -144,6 +141,6 @@ object then the {\tt destroy} call will 7.14 \subsection{Additional RPCs} 7.15 7.16 As well as the RPCs enumerated above, some classes have additional RPCs 7.17 -associated with them. For example, the {\tt VM} class have RPCs for cloning, 7.18 +associated with them. For example, the {\tt VM} class has RPCs for cloning, 7.19 suspending, starting etc. Such additional RPCs are described explicitly 7.20 in the API reference.
8.1 --- a/docs/xen-api/todo.tex Sat Dec 02 15:19:50 2006 -0700 8.2 +++ b/docs/xen-api/todo.tex Mon Dec 04 08:24:41 2006 -0700 8.3 @@ -35,6 +35,8 @@ code, potential error description, but o 8.4 \item Clarify behaviour of progress field on asyncrhonous request polling when 8.5 that request fails. 8.6 8.7 +\item Clarify which calls have asynchronous counterparts by marking them as such in the reference. (Individual getters and setters are too small and quick to justify having async versions) 8.8 + 8.9 \end{itemize} 8.10 8.11 \subsection{Content}
9.1 --- a/docs/xen-api/wire-protocol.tex Sat Dec 02 15:19:50 2006 -0700 9.2 +++ b/docs/xen-api/wire-protocol.tex Mon Dec 04 08:24:41 2006 -0700 9.3 @@ -21,9 +21,9 @@ primitive XML-RPC types. 9.4 In our API Reference we specify the signatures of API functions in the following 9.5 style: 9.6 \begin{verbatim} 9.7 - (ref_vm Set) Host.ListAllVMs() 9.8 + (ref_vm Set) VM.get_all() 9.9 \end{verbatim} 9.10 -This specifies that the function with name {\tt Host.ListAllVMs} takes 9.11 +This specifies that the function with name {\tt VM.get\_all} takes 9.12 no parameters and returns a Set of {\tt ref\_vm}s. 9.13 These types are mapped onto XML-RPC types in a straight-forward manner: 9.14 \begin{itemize} 9.15 @@ -105,8 +105,8 @@ In the case where {\tt Status} is set to 9.16 the struct contains a second element named {\tt ErrorDescription}: 9.17 \begin{itemize} 9.18 \item The element of the struct named {\tt ErrorDescription} contains 9.19 -an array of string values. The first element of the array represents an error code; 9.20 -the remainder of the array represents error parameters relating to that code. 9.21 +an array of string values. The first element of the array is an XML-RPC 32-bit {\tt i4} and represents an error code; 9.22 +the remainder of the array are strings representing error parameters relating to that code. 9.23 \end{itemize} 9.24 9.25 For example, an XML-RPC return value from the {\tt Host.ListAllVMs} function above 9.26 @@ -161,19 +161,19 @@ A session can be terminated with the {\t 9.27 9.28 \subsection{Synchronous and Asynchronous invocation} 9.29 9.30 -Each method call (apart from those on ``Session'' and ``Task'' objects) 9.31 +Each method call (apart from methods on ``Session'' and ``Task'' objects 9.32 +and ``getters'' and ``setters'' derived from fields) 9.33 can be made either synchronously or asynchronously. 9.34 A synchronous RPC call blocks until the 9.35 return value is received; the return value of a synchronous RPC call is 9.36 exactly as specified in Section~\ref{synchronous-result}. 9.37 9.38 -Each of the methods specified in the API Reference is synchronous. 9.39 -However, although not listed explicitly in this document, each 9.40 -method call has an asynchronous analogue in the {\tt Async} 9.41 -namespace. For example, synchronous call {\tt VM.Install(...)} 9.42 +Only synchronous API calls are listed explicitly in this document. 9.43 +All asynchronous versions are in the special {\tt Async} namespace. 9.44 +For example, synchronous call {\tt VM.clone(...)} 9.45 (described in Chapter~\ref{api-reference}) 9.46 has an asynchronous counterpart, {\tt 9.47 -Async.VM.Install(...)}, that is non-blocking. 9.48 +Async.VM.clone(...)}, that is non-blocking. 9.49 9.50 Instead of returning its result directly, an asynchronous RPC call 9.51 returns a {\tt task-id}; this identifier is subsequently used 9.52 @@ -186,39 +186,14 @@ is wrapped in an XML-RPC struct with a { 9.53 The {\tt task-id} is provided in the {\tt Value} field if {\tt Status} is set to 9.54 {\tt Success}. 9.55 9.56 -Two special RPC calls are provided to poll the status of 9.57 -asynchronous calls: 9.58 +The RPC call 9.59 \begin{verbatim} 9.60 - Array<task_id> Async.Task.GetAllTasks (session_id s) 9.61 - task_status Async.Task.GetStatus (session_id s, task_id t) 9.62 -\end{verbatim} 9.63 - 9.64 -{\tt Async.Task.GetAllTasks} returns a set of the currently 9.65 -executing asynchronous tasks belong to the current user\footnote{ 9.66 -% 9.67 -The current user is determined by the username that was provided 9.68 -to {\tt Session.Login}. 9.69 -% 9.70 -}. 9.71 - 9.72 -{\tt Async.Task.GetStatus} returns a {\tt task\_status} result. 9.73 -This is an XML-RPC struct with three elements: 9.74 -\begin{itemize} 9.75 - \item The first element is named {\tt Progress} and contains 9.76 -an {\tt Integer} between 0 and 100 representing the estimated percentage of 9.77 -the task currently completed. 9.78 - \item The second element is named {\tt ETA} and contains a {\tt DateTime} 9.79 -representing the estimated time the task will be complete. 9.80 - \item The third element is named {\tt Result}. If {\tt Progress} 9.81 -is not 100 then {\tt Result} contains the empty string. If {\tt Progress} 9.82 -{\em is\/} set to 100, then {\tt Result} contains the function's return 9.83 -result (as specified in Section~\ref{synchronous-result})\footnote{ 9.84 -% 9.85 -Recall that this itself is a struct potentially containing status, errorcode, 9.86 -value fields etc. 9.87 -% 9.88 -}. 9.89 -\end{itemize} 9.90 + (ref_task Set) Task.get_all(session_id s) 9.91 +\end{verbatim} 9.92 +returns a set of all task IDs known to the system. The status (including any 9.93 +returned result and error codes) of these tasks 9.94 +can then be queried by accessing the fields of the Task object in the usual way. 9.95 +Note that, in order to get a consistent snapshot of a task's state, it is advisable to call the ``get\_record'' function. 9.96 9.97 \section{Example interactive session} 9.98 9.99 @@ -267,7 +242,8 @@ Next, the user may acquire a list of all 9.100 \begin{verbatim} 9.101 >>> all_vms = xen.VM.do_list(session)['Value'] 9.102 >>> all_vms 9.103 -['b7b92d9e-d442-4710-92a5-ab039fd7d89b', '23e1e837-abbf-4675-b077-d4007989b0cc', '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e'] 9.104 +['b7b92d9e-d442-4710-92a5-ab039fd7d89b', '23e1e837-abbf-4675-b077-d4007989b0cc', 9.105 + '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e'] 9.106 \end{verbatim} 9.107 9.108 Note the VM references are internally UUIDs. Once a reference to a VM has been acquired a lifecycle operation may be invoked:
10.1 --- a/docs/xen-api/xenapi-datamodel-graph.dot Sat Dec 02 15:19:50 2006 -0700 10.2 +++ b/docs/xen-api/xenapi-datamodel-graph.dot Mon Dec 04 08:24:41 2006 -0700 10.3 @@ -1,5 +1,5 @@ 10.4 digraph g{ 10.5 -node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM [ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ] network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR [ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [ URL="VTPM.html" ] user [ URL="user.html" ] debug [ URL="debug.html" ]; 10.6 +node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM [ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ] network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR [ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [ URL="VTPM.html" ] console [ URL="console.html" ] user [ URL="user.html" ] debug [ URL="debug.html" ]; 10.7 session -> host [ label="this_host(1)" ] 10.8 session -> user [ label="this_user(1)" ] 10.9 host -> VM [ color="blue", arrowhead="crow", arrowtail="none" ] 10.10 @@ -14,4 +14,5 @@ VDI -> VDI [ color="blue", arrowhead="no 10.11 VBD -> VM [ color="blue", arrowhead="none", arrowtail="crow" ] 10.12 VTPM -> VM [ label="backend(1)" ] 10.13 VTPM -> VM [ color="blue", arrowhead="none", arrowtail="crow" ] 10.14 +console -> VM [ color="blue", arrowhead="none", arrowtail="crow" ] 10.15 }
11.1 --- a/docs/xen-api/xenapi-datamodel.tex Sat Dec 02 15:19:50 2006 -0700 11.2 +++ b/docs/xen-api/xenapi-datamodel.tex Mon Dec 04 08:24:41 2006 -0700 11.3 @@ -34,6 +34,7 @@ Name & Description \\ 11.4 {\tt VDI} & A virtual disk image \\ 11.5 {\tt VBD} & A virtual block device \\ 11.6 {\tt VTPM} & A virtual TPM device \\ 11.7 +{\tt console} & A console \\ 11.8 {\tt user} & A user of the system \\ 11.9 {\tt debug} & A basic class for testing \\ 11.10 \hline 11.11 @@ -54,6 +55,7 @@ PIF.host & host.PIFs & one-to-many\\ 11.12 PIF.network & network.PIFs & one-to-many\\ 11.13 SR.VDIs & VDI.SR & many-to-one\\ 11.14 VTPM.VM & VM.VTPMs & one-to-many\\ 11.15 +console.VM & VM.consoles & one-to-many\\ 11.16 host.resident\_VMs & VM.resident\_on & many-to-one\\ 11.17 host.host\_CPUs & host\_cpu.host & many-to-one\\ 11.18 \hline 11.19 @@ -99,6 +101,16 @@ The following enumeration types are used 11.20 11.21 \begin{longtable}{|ll|} 11.22 \hline 11.23 +{\tt enum console\_protocol} & \\ 11.24 +\hline 11.25 +\hspace{0.5cm}{\tt vt100} & VT100 terminal \\ 11.26 +\hspace{0.5cm}{\tt rfb} & Remote FrameBuffer protocol (as used in VNC) \\ 11.27 +\hspace{0.5cm}{\tt rdp} & Remote Desktop Protocol \\ 11.28 +\hline 11.29 +\end{longtable} 11.30 + 11.31 +\begin{longtable}{|ll|} 11.32 +\hline 11.33 {\tt enum vdi\_type} & \\ 11.34 \hline 11.35 \hspace{0.5cm}{\tt system} & a disk that may be replaced on upgrade \\ 11.36 @@ -947,6 +959,7 @@ Quals & Field & Type & Description \\ 11.37 $\mathit{RW}$ & {\tt actions/after\_reboot} & on\_normal\_exit & action to take after the guest has rebooted itself \\ 11.38 $\mathit{RW}$ & {\tt actions/after\_suspend} & on\_normal\_exit & action to take after the guest has suspended itself \\ 11.39 $\mathit{RW}$ & {\tt actions/after\_crash} & on\_crash\_behaviour & action to take if the guest crashes \\ 11.40 +$\mathit{RO}_\mathit{run}$ & {\tt consoles} & (console ref) Set & virtual console devices \\ 11.41 $\mathit{RO}_\mathit{run}$ & {\tt VIFs} & (VIF ref) Set & virtual network interfaces \\ 11.42 $\mathit{RO}_\mathit{run}$ & {\tt VBDs} & (VBD ref) Set & virtual block devices \\ 11.43 $\mathit{RO}_\mathit{run}$ & {\tt VTPMs} & (VTPM ref) Set & virtual TPMs \\ 11.44 @@ -2631,6 +2644,38 @@ void 11.45 \vspace{0.3cm} 11.46 \vspace{0.3cm} 11.47 \vspace{0.3cm} 11.48 +\subsubsection{RPC name:~get\_consoles} 11.49 + 11.50 +{\bf Overview:} 11.51 +Get the consoles field of the given VM. 11.52 + 11.53 + \noindent {\bf Signature:} 11.54 +\begin{verbatim} ((console ref) Set) get_consoles (session_id s, VM ref self)\end{verbatim} 11.55 + 11.56 + 11.57 +\noindent{\bf Arguments:} 11.58 + 11.59 + 11.60 +\vspace{0.3cm} 11.61 +\begin{tabular}{|c|c|p{7cm}|} 11.62 + \hline 11.63 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.64 +{\tt VM ref } & self & object instance \\ \hline 11.65 + 11.66 +\end{tabular} 11.67 + 11.68 +\vspace{0.3cm} 11.69 + 11.70 + \noindent {\bf Return Type:} 11.71 +{\tt 11.72 +(console ref) Set 11.73 +} 11.74 + 11.75 + 11.76 +value of the field 11.77 +\vspace{0.3cm} 11.78 +\vspace{0.3cm} 11.79 +\vspace{0.3cm} 11.80 \subsubsection{RPC name:~get\_VIFs} 11.81 11.82 {\bf Overview:} 11.83 @@ -9187,6 +9232,281 @@ all fields from the object 11.84 11.85 \vspace{1cm} 11.86 \newpage 11.87 +\section{Class: console} 11.88 +\subsection{Fields for class: console} 11.89 +\begin{longtable}{|lllp{0.38\textwidth}|} 11.90 +\hline 11.91 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf console} \\ 11.92 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A console}} \\ 11.93 +\hline 11.94 +Quals & Field & Type & Description \\ 11.95 +\hline 11.96 +$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ 11.97 +$\mathit{RO}_\mathit{run}$ & {\tt protocol} & console\_protocol & the protocol used by this console \\ 11.98 +$\mathit{RO}_\mathit{run}$ & {\tt uri} & string & URI for the console service \\ 11.99 +$\mathit{RO}_\mathit{run}$ & {\tt VM} & VM ref & VM to which this console is attached \\ 11.100 +\hline 11.101 +\end{longtable} 11.102 +\subsection{Additional RPCs associated with class: console} 11.103 +\subsubsection{RPC name:~get\_record} 11.104 + 11.105 +{\bf Overview:} 11.106 +Get the current state of the given console. 11.107 + 11.108 + \noindent {\bf Signature:} 11.109 +\begin{verbatim} (console record) get_record (session_id s, console ref self)\end{verbatim} 11.110 + 11.111 + 11.112 +\noindent{\bf Arguments:} 11.113 + 11.114 + 11.115 +\vspace{0.3cm} 11.116 +\begin{tabular}{|c|c|p{7cm}|} 11.117 + \hline 11.118 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.119 +{\tt console ref } & self & reference to the object \\ \hline 11.120 + 11.121 +\end{tabular} 11.122 + 11.123 +\vspace{0.3cm} 11.124 + 11.125 + \noindent {\bf Return Type:} 11.126 +{\tt 11.127 +console record 11.128 +} 11.129 + 11.130 + 11.131 +all fields from the object 11.132 +\vspace{0.3cm} 11.133 +\vspace{0.3cm} 11.134 +\vspace{0.3cm} 11.135 +\subsubsection{RPC name:~get\_by\_uuid} 11.136 + 11.137 +{\bf Overview:} 11.138 +Get a reference to the object with the specified UUID. 11.139 + 11.140 + \noindent {\bf Signature:} 11.141 +\begin{verbatim} (console ref) get_by_uuid (session_id s, string uuid)\end{verbatim} 11.142 + 11.143 + 11.144 +\noindent{\bf Arguments:} 11.145 + 11.146 + 11.147 +\vspace{0.3cm} 11.148 +\begin{tabular}{|c|c|p{7cm}|} 11.149 + \hline 11.150 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.151 +{\tt string } & uuid & UUID of object to return \\ \hline 11.152 + 11.153 +\end{tabular} 11.154 + 11.155 +\vspace{0.3cm} 11.156 + 11.157 + \noindent {\bf Return Type:} 11.158 +{\tt 11.159 +console ref 11.160 +} 11.161 + 11.162 + 11.163 +reference to the object 11.164 +\vspace{0.3cm} 11.165 +\vspace{0.3cm} 11.166 +\vspace{0.3cm} 11.167 +\subsubsection{RPC name:~create} 11.168 + 11.169 +{\bf Overview:} 11.170 +Create a new console instance, and return its handle. 11.171 + 11.172 + \noindent {\bf Signature:} 11.173 +\begin{verbatim} (console ref) create (session_id s, console record args)\end{verbatim} 11.174 + 11.175 + 11.176 +\noindent{\bf Arguments:} 11.177 + 11.178 + 11.179 +\vspace{0.3cm} 11.180 +\begin{tabular}{|c|c|p{7cm}|} 11.181 + \hline 11.182 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.183 +{\tt console record } & args & All constructor arguments \\ \hline 11.184 + 11.185 +\end{tabular} 11.186 + 11.187 +\vspace{0.3cm} 11.188 + 11.189 + \noindent {\bf Return Type:} 11.190 +{\tt 11.191 +console ref 11.192 +} 11.193 + 11.194 + 11.195 +reference to the newly created object 11.196 +\vspace{0.3cm} 11.197 +\vspace{0.3cm} 11.198 +\vspace{0.3cm} 11.199 +\subsubsection{RPC name:~destroy} 11.200 + 11.201 +{\bf Overview:} 11.202 +Destroy the specified console instance. 11.203 + 11.204 + \noindent {\bf Signature:} 11.205 +\begin{verbatim} void destroy (session_id s, console ref self)\end{verbatim} 11.206 + 11.207 + 11.208 +\noindent{\bf Arguments:} 11.209 + 11.210 + 11.211 +\vspace{0.3cm} 11.212 +\begin{tabular}{|c|c|p{7cm}|} 11.213 + \hline 11.214 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.215 +{\tt console ref } & self & object instance \\ \hline 11.216 + 11.217 +\end{tabular} 11.218 + 11.219 +\vspace{0.3cm} 11.220 + 11.221 + \noindent {\bf Return Type:} 11.222 +{\tt 11.223 +void 11.224 +} 11.225 + 11.226 + 11.227 + 11.228 +\vspace{0.3cm} 11.229 +\vspace{0.3cm} 11.230 +\vspace{0.3cm} 11.231 +\subsubsection{RPC name:~get\_uuid} 11.232 + 11.233 +{\bf Overview:} 11.234 +Get the uuid field of the given console. 11.235 + 11.236 + \noindent {\bf Signature:} 11.237 +\begin{verbatim} string get_uuid (session_id s, console ref self)\end{verbatim} 11.238 + 11.239 + 11.240 +\noindent{\bf Arguments:} 11.241 + 11.242 + 11.243 +\vspace{0.3cm} 11.244 +\begin{tabular}{|c|c|p{7cm}|} 11.245 + \hline 11.246 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.247 +{\tt console ref } & self & object instance \\ \hline 11.248 + 11.249 +\end{tabular} 11.250 + 11.251 +\vspace{0.3cm} 11.252 + 11.253 + \noindent {\bf Return Type:} 11.254 +{\tt 11.255 +string 11.256 +} 11.257 + 11.258 + 11.259 +value of the field 11.260 +\vspace{0.3cm} 11.261 +\vspace{0.3cm} 11.262 +\vspace{0.3cm} 11.263 +\subsubsection{RPC name:~get\_protocol} 11.264 + 11.265 +{\bf Overview:} 11.266 +Get the protocol field of the given console. 11.267 + 11.268 + \noindent {\bf Signature:} 11.269 +\begin{verbatim} (console_protocol) get_protocol (session_id s, console ref self)\end{verbatim} 11.270 + 11.271 + 11.272 +\noindent{\bf Arguments:} 11.273 + 11.274 + 11.275 +\vspace{0.3cm} 11.276 +\begin{tabular}{|c|c|p{7cm}|} 11.277 + \hline 11.278 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.279 +{\tt console ref } & self & object instance \\ \hline 11.280 + 11.281 +\end{tabular} 11.282 + 11.283 +\vspace{0.3cm} 11.284 + 11.285 + \noindent {\bf Return Type:} 11.286 +{\tt 11.287 +console\_protocol 11.288 +} 11.289 + 11.290 + 11.291 +value of the field 11.292 +\vspace{0.3cm} 11.293 +\vspace{0.3cm} 11.294 +\vspace{0.3cm} 11.295 +\subsubsection{RPC name:~get\_uri} 11.296 + 11.297 +{\bf Overview:} 11.298 +Get the uri field of the given console. 11.299 + 11.300 + \noindent {\bf Signature:} 11.301 +\begin{verbatim} string get_uri (session_id s, console ref self)\end{verbatim} 11.302 + 11.303 + 11.304 +\noindent{\bf Arguments:} 11.305 + 11.306 + 11.307 +\vspace{0.3cm} 11.308 +\begin{tabular}{|c|c|p{7cm}|} 11.309 + \hline 11.310 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.311 +{\tt console ref } & self & object instance \\ \hline 11.312 + 11.313 +\end{tabular} 11.314 + 11.315 +\vspace{0.3cm} 11.316 + 11.317 + \noindent {\bf Return Type:} 11.318 +{\tt 11.319 +string 11.320 +} 11.321 + 11.322 + 11.323 +value of the field 11.324 +\vspace{0.3cm} 11.325 +\vspace{0.3cm} 11.326 +\vspace{0.3cm} 11.327 +\subsubsection{RPC name:~get\_VM} 11.328 + 11.329 +{\bf Overview:} 11.330 +Get the VM field of the given console. 11.331 + 11.332 + \noindent {\bf Signature:} 11.333 +\begin{verbatim} (VM ref) get_VM (session_id s, console ref self)\end{verbatim} 11.334 + 11.335 + 11.336 +\noindent{\bf Arguments:} 11.337 + 11.338 + 11.339 +\vspace{0.3cm} 11.340 +\begin{tabular}{|c|c|p{7cm}|} 11.341 + \hline 11.342 +{\bf type} & {\bf name} & {\bf description} \\ \hline 11.343 +{\tt console ref } & self & object instance \\ \hline 11.344 + 11.345 +\end{tabular} 11.346 + 11.347 +\vspace{0.3cm} 11.348 + 11.349 + \noindent {\bf Return Type:} 11.350 +{\tt 11.351 +VM ref 11.352 +} 11.353 + 11.354 + 11.355 +value of the field 11.356 +\vspace{0.3cm} 11.357 +\vspace{0.3cm} 11.358 +\vspace{0.3cm} 11.359 + 11.360 +\vspace{1cm} 11.361 +\newpage 11.362 \section{Class: user} 11.363 \subsection{Fields for class: user} 11.364 \begin{longtable}{|lllp{0.38\textwidth}|}
12.1 --- a/extras/mini-os/events.c Sat Dec 02 15:19:50 2006 -0700 12.2 +++ b/extras/mini-os/events.c Mon Dec 04 08:24:41 2006 -0700 12.3 @@ -31,26 +31,27 @@ typedef struct _ev_action_t { 12.4 u32 count; 12.5 } ev_action_t; 12.6 12.7 - 12.8 static ev_action_t ev_actions[NR_EVS]; 12.9 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data); 12.10 12.11 +static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))]; 12.12 + 12.13 void unbind_all_ports(void) 12.14 { 12.15 int i; 12.16 12.17 - for(i=0;i<NR_EVS;i++) 12.18 - { 12.19 - if(ev_actions[i].handler != default_handler) 12.20 - { 12.21 - struct evtchn_close close; 12.22 - mask_evtchn(i); 12.23 - close.port = i; 12.24 - HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); 12.25 - } 12.26 - } 12.27 + for (i = 0; i < NR_EVS; i++) 12.28 + { 12.29 + if (test_and_clear_bit(i, bound_ports)) 12.30 + { 12.31 + struct evtchn_close close; 12.32 + mask_evtchn(i); 12.33 + close.port = i; 12.34 + HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); 12.35 + } 12.36 + } 12.37 } 12.38 - 12.39 + 12.40 /* 12.41 * Demux events to different handlers. 12.42 */ 12.43 @@ -114,6 +115,7 @@ int bind_virq(uint32_t virq, evtchn_hand 12.44 printk("Failed to bind virtual IRQ %d\n", virq); 12.45 return 1; 12.46 } 12.47 + set_bit(op.port,bound_ports); 12.48 bind_evtchn(op.port, handler, data); 12.49 return 0; 12.50 } 12.51 @@ -188,6 +190,7 @@ int evtchn_bind_interdomain(domid_t pal, 12.52 int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op); 12.53 if (err) 12.54 return err; 12.55 + set_bit(op.local_port,bound_ports); 12.56 evtchn_port_t port = op.local_port; 12.57 clear_evtchn(port); /* Without, handler gets invoked now! */ 12.58 *local_port = bind_evtchn(port, handler, data);
13.1 --- a/extras/mini-os/include/events.h Sat Dec 02 15:19:50 2006 -0700 13.2 +++ b/extras/mini-os/include/events.h Mon Dec 04 08:24:41 2006 -0700 13.3 @@ -36,6 +36,7 @@ int evtchn_alloc_unbound(domid_t pal, ev 13.4 int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port, 13.5 evtchn_handler_t handler, void *data, 13.6 evtchn_port_t *local_port); 13.7 +void unbind_all_ports(void); 13.8 13.9 static inline int notify_remote_via_evtchn(evtchn_port_t port) 13.10 {
14.1 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig Sat Dec 02 15:19:50 2006 -0700 14.2 +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Mon Dec 04 08:24:41 2006 -0700 14.3 @@ -726,7 +726,7 @@ source kernel/Kconfig.hz 14.4 14.5 config KEXEC 14.6 bool "kexec system call (EXPERIMENTAL)" 14.7 - depends on EXPERIMENTAL && !X86_XEN 14.8 + depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST 14.9 help 14.10 kexec is a system call that implements the ability to shutdown your 14.11 current kernel, and to start another kernel. It is like a reboot
15.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sat Dec 02 15:19:50 2006 -0700 15.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon Dec 04 08:24:41 2006 -0700 15.3 @@ -69,6 +69,10 @@ 15.4 #include "setup_arch_pre.h" 15.5 #include <bios_ebda.h> 15.6 15.7 +#ifdef CONFIG_XEN 15.8 +#include <xen/interface/kexec.h> 15.9 +#endif 15.10 + 15.11 /* Forward Declaration. */ 15.12 void __init find_max_pfn(void); 15.13 15.14 @@ -943,6 +947,7 @@ static void __init parse_cmdline_early ( 15.15 * after a kernel panic. 15.16 */ 15.17 else if (!memcmp(from, "crashkernel=", 12)) { 15.18 +#ifndef CONFIG_XEN 15.19 unsigned long size, base; 15.20 size = memparse(from+12, &from); 15.21 if (*from == '@') { 15.22 @@ -953,6 +958,10 @@ static void __init parse_cmdline_early ( 15.23 crashk_res.start = base; 15.24 crashk_res.end = base + size - 1; 15.25 } 15.26 +#else 15.27 + printk("Ignoring crashkernel command line, " 15.28 + "parameter will be supplied by xen\n"); 15.29 +#endif 15.30 } 15.31 #endif 15.32 #ifdef CONFIG_PROC_VMCORE 15.33 @@ -1322,10 +1331,14 @@ void __init setup_bootmem_allocator(void 15.34 } 15.35 #endif 15.36 #ifdef CONFIG_KEXEC 15.37 +#ifdef CONFIG_XEN 15.38 + xen_machine_kexec_setup_resources(); 15.39 +#else 15.40 if (crashk_res.start != crashk_res.end) 15.41 reserve_bootmem(crashk_res.start, 15.42 crashk_res.end - crashk_res.start + 1); 15.43 #endif 15.44 +#endif 15.45 15.46 if (!xen_feature(XENFEAT_auto_translated_physmap)) 15.47 phys_to_machine_mapping = 15.48 @@ -1389,7 +1402,11 @@ legacy_init_iomem_resources(struct e820e 15.49 request_resource(res, data_resource); 15.50 #endif 15.51 #ifdef CONFIG_KEXEC 15.52 - request_resource(res, &crashk_res); 15.53 + if (crashk_res.start != crashk_res.end) 15.54 + request_resource(res, &crashk_res); 15.55 +#ifdef CONFIG_XEN 15.56 + xen_machine_kexec_register_resources(res); 15.57 +#endif 15.58 #endif 15.59 } 15.60 } 15.61 @@ -1850,9 +1867,11 @@ void __init setup_arch(char **cmdline_p) 15.62 #endif 15.63 #endif 15.64 } else { 15.65 - extern int console_use_vt; 15.66 - console_use_vt = 0; 15.67 +#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) 15.68 + conswitchp = &dummy_con; 15.69 +#endif 15.70 } 15.71 + xencons_early_setup(); 15.72 } 15.73 15.74 static int
16.1 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Sat Dec 02 15:19:50 2006 -0700 16.2 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Mon Dec 04 08:24:41 2006 -0700 16.3 @@ -550,14 +550,16 @@ setup_arch (char **cmdline_p) 16.4 xen_start_info->nr_pages, xen_start_info->flags); 16.5 16.6 if (!is_initial_xendomain()) { 16.7 - extern int console_use_vt; 16.8 +#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE) 16.9 conswitchp = NULL; 16.10 - console_use_vt = 0; 16.11 +#endif 16.12 } 16.13 } 16.14 + xencons_early_setup(); 16.15 #endif 16.16 #endif 16.17 16.18 + 16.19 /* enable IA-64 Machine Check Abort Handling unless disabled */ 16.20 if (!strstr(saved_command_line, "nomca")) 16.21 ia64_mca_init();
17.1 --- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig Sat Dec 02 15:19:50 2006 -0700 17.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig Mon Dec 04 08:24:41 2006 -0700 17.3 @@ -435,7 +435,7 @@ config X86_MCE_AMD 17.4 17.5 config KEXEC 17.6 bool "kexec system call (EXPERIMENTAL)" 17.7 - depends on EXPERIMENTAL && !X86_64_XEN 17.8 + depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST 17.9 help 17.10 kexec is a system call that implements the ability to shutdown your 17.11 current kernel, and to start another kernel. It is like a reboot
18.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Sat Dec 02 15:19:50 2006 -0700 18.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Mon Dec 04 08:24:41 2006 -0700 18.3 @@ -260,7 +260,11 @@ void __init e820_reserve_resources(struc 18.4 request_resource(res, &data_resource); 18.5 #endif 18.6 #ifdef CONFIG_KEXEC 18.7 - request_resource(res, &crashk_res); 18.8 + if (crashk_res.start != crashk_res.end) 18.9 + request_resource(res, &crashk_res); 18.10 +#ifdef CONFIG_XEN 18.11 + xen_machine_kexec_register_resources(res); 18.12 +#endif 18.13 #endif 18.14 } 18.15 }
19.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Sat Dec 02 15:19:50 2006 -0700 19.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon Dec 04 08:24:41 2006 -0700 19.3 @@ -80,6 +80,10 @@ 19.4 #include <asm/mach-xen/setup_arch_post.h> 19.5 #include <xen/interface/memory.h> 19.6 19.7 +#ifdef CONFIG_XEN 19.8 +#include <xen/interface/kexec.h> 19.9 +#endif 19.10 + 19.11 extern unsigned long start_pfn; 19.12 extern struct edid_info edid_info; 19.13 19.14 @@ -450,6 +454,7 @@ static __init void parse_cmdline_early ( 19.15 * after a kernel panic. 19.16 */ 19.17 else if (!memcmp(from, "crashkernel=", 12)) { 19.18 +#ifndef CONFIG_XEN 19.19 unsigned long size, base; 19.20 size = memparse(from+12, &from); 19.21 if (*from == '@') { 19.22 @@ -460,6 +465,10 @@ static __init void parse_cmdline_early ( 19.23 crashk_res.start = base; 19.24 crashk_res.end = base + size - 1; 19.25 } 19.26 +#else 19.27 + printk("Ignoring crashkernel command line, " 19.28 + "parameter will be supplied by xen\n"); 19.29 +#endif 19.30 } 19.31 #endif 19.32 19.33 @@ -812,11 +821,15 @@ void __init setup_arch(char **cmdline_p) 19.34 #endif 19.35 #endif /* !CONFIG_XEN */ 19.36 #ifdef CONFIG_KEXEC 19.37 +#ifdef CONFIG_XEN 19.38 + xen_machine_kexec_setup_resources(); 19.39 +#else 19.40 if (crashk_res.start != crashk_res.end) { 19.41 reserve_bootmem(crashk_res.start, 19.42 crashk_res.end - crashk_res.start + 1); 19.43 } 19.44 #endif 19.45 +#endif 19.46 19.47 paging_init(); 19.48 #ifdef CONFIG_X86_LOCAL_APIC 19.49 @@ -970,10 +983,12 @@ void __init setup_arch(char **cmdline_p) 19.50 #endif 19.51 #endif 19.52 } else { 19.53 - extern int console_use_vt; 19.54 - console_use_vt = 0; 19.55 - } 19.56 +#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE) 19.57 + conswitchp = &dummy_con; 19.58 +#endif 19.59 + } 19.60 } 19.61 + xencons_early_setup(); 19.62 #else /* CONFIG_XEN */ 19.63 19.64 #ifdef CONFIG_VT
20.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Sat Dec 02 15:19:50 2006 -0700 20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon Dec 04 08:24:41 2006 -0700 20.3 @@ -172,6 +172,29 @@ config XEN_NETDEV_FRONTEND 20.4 dedicated device-driver domain, or your master control domain 20.5 (domain 0), then you almost certainly want to say Y here. 20.6 20.7 +config XEN_FRAMEBUFFER 20.8 + tristate "Framebuffer-device frontend driver" 20.9 + depends on XEN && FB 20.10 + select FB_CFB_FILLRECT 20.11 + select FB_CFB_COPYAREA 20.12 + select FB_CFB_IMAGEBLIT 20.13 + default y 20.14 + help 20.15 + The framebuffer-device frontend drivers allows the kernel to create a 20.16 + virtual framebuffer. This framebuffer can be viewed in another 20.17 + domain. Unless this domain has access to a real video card, you 20.18 + probably want to say Y here. 20.19 + 20.20 +config XEN_KEYBOARD 20.21 + tristate "Keyboard-device frontend driver" 20.22 + depends on XEN && XEN_FRAMEBUFFER && INPUT 20.23 + default y 20.24 + help 20.25 + The keyboard-device frontend driver allows the kernel to create a 20.26 + virtual keyboard. This keyboard can then be driven by another 20.27 + domain. If you've said Y to CONFIG_XEN_FRAMEBUFFER, you probably 20.28 + want to say Y here. 20.29 + 20.30 config XEN_SCRUB_PAGES 20.31 bool "Scrub memory before freeing it to Xen" 20.32 default y
21.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile Sat Dec 02 15:19:50 2006 -0700 21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Mon Dec 04 08:24:41 2006 -0700 21.3 @@ -15,3 +15,5 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blk 21.4 obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/ 21.5 obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/ 21.6 obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/ 21.7 +obj-$(CONFIG_XEN_FRAMEBUFFER) += fbfront/ 21.8 +obj-$(CONFIG_XEN_KEYBOARD) += fbfront/
22.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Sat Dec 02 15:19:50 2006 -0700 22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Dec 04 08:24:41 2006 -0700 22.3 @@ -359,7 +359,7 @@ static void blkfront_closing(struct xenb 22.4 DPRINTK("blkfront_closing: %s removed\n", dev->nodename); 22.5 22.6 if (info->rq == NULL) 22.7 - return; 22.8 + goto out; 22.9 22.10 spin_lock_irqsave(&blkif_io_lock, flags); 22.11 /* No more blkif_request(). */ 22.12 @@ -373,6 +373,7 @@ static void blkfront_closing(struct xenb 22.13 22.14 xlvbd_del(info); 22.15 22.16 + out: 22.17 xenbus_frontend_closed(dev); 22.18 } 22.19
23.1 --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c Sat Dec 02 15:19:50 2006 -0700 23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c Mon Dec 04 08:24:41 2006 -0700 23.3 @@ -147,7 +147,7 @@ static inline int uncached_access(struct 23.4 return 0; 23.5 } 23.6 23.7 -static int mmap_mem(struct file * file, struct vm_area_struct * vma) 23.8 +static int xen_mmap_mem(struct file * file, struct vm_area_struct * vma) 23.9 { 23.10 size_t size = vma->vm_end - vma->vm_start; 23.11 23.12 @@ -200,6 +200,6 @@ struct file_operations mem_fops = { 23.13 .llseek = memory_lseek, 23.14 .read = read_mem, 23.15 .write = write_mem, 23.16 - .mmap = mmap_mem, 23.17 + .mmap = xen_mmap_mem, 23.18 .open = open_mem, 23.19 };
24.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Sat Dec 02 15:19:50 2006 -0700 24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon Dec 04 08:24:41 2006 -0700 24.3 @@ -57,6 +57,7 @@ 24.4 #include <xen/interface/event_channel.h> 24.5 #include <asm/hypervisor.h> 24.6 #include <xen/evtchn.h> 24.7 +#include <xen/xenbus.h> 24.8 #include <xen/xencons.h> 24.9 24.10 /* 24.11 @@ -65,14 +66,14 @@ 24.12 * 'xencons=tty' [XC_TTY]: Console attached to '/dev/tty[0-9]+'. 24.13 * 'xencons=ttyS' [XC_SERIAL]: Console attached to '/dev/ttyS[0-9]+'. 24.14 * 'xencons=xvc' [XC_XVC]: Console attached to '/dev/xvc0'. 24.15 - * [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY. 24.16 + * default: DOM0 -> XC_SERIAL ; all others -> XC_TTY. 24.17 * 24.18 * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses 24.19 * warnings from standard distro startup scripts. 24.20 */ 24.21 static enum { 24.22 - XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL, XC_XVC 24.23 -} xc_mode = XC_DEFAULT; 24.24 + XC_OFF, XC_TTY, XC_SERIAL, XC_XVC 24.25 +} xc_mode; 24.26 static int xc_num = -1; 24.27 24.28 /* /dev/xvc0 device number allocated by lanana.org. */ 24.29 @@ -84,17 +85,32 @@ static unsigned long sysrq_requested; 24.30 extern int sysrq_enabled; 24.31 #endif 24.32 24.33 +void xencons_early_setup(void) 24.34 +{ 24.35 + extern int console_use_vt; 24.36 + 24.37 + if (is_initial_xendomain()) { 24.38 + xc_mode = XC_SERIAL; 24.39 + } else { 24.40 + xc_mode = XC_TTY; 24.41 + console_use_vt = 0; 24.42 + } 24.43 +} 24.44 + 24.45 static int __init xencons_setup(char *str) 24.46 { 24.47 char *q; 24.48 int n; 24.49 + extern int console_use_vt; 24.50 24.51 + console_use_vt = 1; 24.52 if (!strncmp(str, "ttyS", 4)) { 24.53 xc_mode = XC_SERIAL; 24.54 str += 4; 24.55 } else if (!strncmp(str, "tty", 3)) { 24.56 xc_mode = XC_TTY; 24.57 str += 3; 24.58 + console_use_vt = 0; 24.59 } else if (!strncmp(str, "xvc", 3)) { 24.60 xc_mode = XC_XVC; 24.61 str += 3; 24.62 @@ -192,14 +208,10 @@ static int __init xen_console_init(void) 24.63 goto out; 24.64 24.65 if (is_initial_xendomain()) { 24.66 - if (xc_mode == XC_DEFAULT) 24.67 - xc_mode = XC_SERIAL; 24.68 kcons_info.write = kcons_write_dom0; 24.69 } else { 24.70 if (!xen_start_info->console.domU.evtchn) 24.71 goto out; 24.72 - if (xc_mode == XC_DEFAULT) 24.73 - xc_mode = XC_TTY; 24.74 kcons_info.write = kcons_write; 24.75 } 24.76
25.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Sat Dec 02 15:19:50 2006 -0700 25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Mon Dec 04 08:24:41 2006 -0700 25.3 @@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o 25.4 obj-$(CONFIG_XEN_SKBUFF) += skbuff.o 25.5 obj-$(CONFIG_XEN_REBOOT) += reboot.o machine_reboot.o 25.6 obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o 25.7 +obj-$(CONFIG_KEXEC) += machine_kexec.o
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c Mon Dec 04 08:24:41 2006 -0700 26.3 @@ -0,0 +1,184 @@ 26.4 +/* 26.5 + * drivers/xen/core/machine_kexec.c 26.6 + * handle transition of Linux booting another kernel 26.7 + */ 26.8 + 26.9 +#include <linux/kexec.h> 26.10 +#include <xen/interface/kexec.h> 26.11 +#include <linux/mm.h> 26.12 +#include <linux/bootmem.h> 26.13 +#include <asm/hypercall.h> 26.14 + 26.15 +extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, 26.16 + struct kimage *image); 26.17 + 26.18 +int xen_max_nr_phys_cpus; 26.19 +struct resource xen_hypervisor_res; 26.20 +struct resource *xen_phys_cpus; 26.21 + 26.22 +void xen_machine_kexec_setup_resources(void) 26.23 +{ 26.24 + xen_kexec_range_t range; 26.25 + struct resource *res; 26.26 + int err, k = 0; 26.27 + 26.28 + if (!is_initial_xendomain()) 26.29 + return; 26.30 + 26.31 + /* determine maximum number of physical cpus */ 26.32 + 26.33 + while (1) { 26.34 + memset(&range, 0, sizeof(range)); 26.35 + range.range = KEXEC_RANGE_MA_CPU; 26.36 + range.nr = k; 26.37 + 26.38 + /* 26.39 + * Anything other than EINVAL or success indictates 26.40 + * that we are not running on a hypervisor which 26.41 + * supports kexec. 26.42 + */ 26.43 + err = HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range); 26.44 + if (err == -EINVAL) 26.45 + break; 26.46 + else if (err) 26.47 + return; 26.48 + 26.49 + k++; 26.50 + } 26.51 + 26.52 + xen_max_nr_phys_cpus = k; 26.53 + 26.54 + /* allocate xen_phys_cpus */ 26.55 + 26.56 + xen_phys_cpus = alloc_bootmem_low(k * sizeof(struct resource)); 26.57 + BUG_ON(!xen_phys_cpus); 26.58 + 26.59 + /* fill in xen_phys_cpus with per-cpu crash note information */ 26.60 + 26.61 + for (k = 0; k < xen_max_nr_phys_cpus; k++) { 26.62 + memset(&range, 0, sizeof(range)); 26.63 + range.range = KEXEC_RANGE_MA_CPU; 26.64 + range.nr = k; 26.65 + 26.66 + if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) 26.67 + BUG(); 26.68 + 26.69 + res = xen_phys_cpus + k; 26.70 + 26.71 + memset(res, 0, sizeof(*res)); 26.72 + res->name = "Crash note"; 26.73 + res->start = range.start; 26.74 + res->end = range.start + range.size - 1; 26.75 + res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; 26.76 + } 26.77 + 26.78 + /* fill in xen_hypervisor_res with hypervisor machine address range */ 26.79 + 26.80 + memset(&range, 0, sizeof(range)); 26.81 + range.range = KEXEC_RANGE_MA_XEN; 26.82 + 26.83 + if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) 26.84 + BUG(); 26.85 + 26.86 + xen_hypervisor_res.name = "Hypervisor code and data"; 26.87 + xen_hypervisor_res.start = range.start; 26.88 + xen_hypervisor_res.end = range.start + range.size - 1; 26.89 + xen_hypervisor_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM; 26.90 + 26.91 + /* fill in crashk_res if range is reserved by hypervisor */ 26.92 + 26.93 + memset(&range, 0, sizeof(range)); 26.94 + range.range = KEXEC_RANGE_MA_CRASH; 26.95 + 26.96 + if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) 26.97 + BUG(); 26.98 + 26.99 + if (range.size) { 26.100 + crashk_res.start = range.start; 26.101 + crashk_res.end = range.start + range.size - 1; 26.102 + } 26.103 +} 26.104 + 26.105 +void xen_machine_kexec_register_resources(struct resource *res) 26.106 +{ 26.107 + int k; 26.108 + 26.109 + request_resource(res, &xen_hypervisor_res); 26.110 + 26.111 + for (k = 0; k < xen_max_nr_phys_cpus; k++) 26.112 + request_resource(res, xen_phys_cpus + k); 26.113 + 26.114 +} 26.115 + 26.116 +static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image) 26.117 +{ 26.118 + machine_kexec_setup_load_arg(xki, image); 26.119 + 26.120 + xki->indirection_page = image->head; 26.121 + xki->start_address = image->start; 26.122 +} 26.123 + 26.124 +/* 26.125 + * Load the image into xen so xen can kdump itself 26.126 + * This might have been done in prepare, but prepare 26.127 + * is currently called too early. It might make sense 26.128 + * to move prepare, but for now, just add an extra hook. 26.129 + */ 26.130 +int xen_machine_kexec_load(struct kimage *image) 26.131 +{ 26.132 + xen_kexec_load_t xkl; 26.133 + 26.134 + memset(&xkl, 0, sizeof(xkl)); 26.135 + xkl.type = image->type; 26.136 + setup_load_arg(&xkl.image, image); 26.137 + return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl); 26.138 +} 26.139 + 26.140 +/* 26.141 + * Unload the image that was stored by machine_kexec_load() 26.142 + * This might have been done in machine_kexec_cleanup() but it 26.143 + * is called too late, and its possible xen could try and kdump 26.144 + * using resources that have been freed. 26.145 + */ 26.146 +void xen_machine_kexec_unload(struct kimage *image) 26.147 +{ 26.148 + xen_kexec_load_t xkl; 26.149 + 26.150 + memset(&xkl, 0, sizeof(xkl)); 26.151 + xkl.type = image->type; 26.152 + HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl); 26.153 +} 26.154 + 26.155 +/* 26.156 + * Do not allocate memory (or fail in any way) in machine_kexec(). 26.157 + * We are past the point of no return, committed to rebooting now. 26.158 + * 26.159 + * This has the hypervisor move to the prefered reboot CPU, 26.160 + * stop all CPUs and kexec. That is it combines machine_shutdown() 26.161 + * and machine_kexec() in Linux kexec terms. 26.162 + */ 26.163 +NORET_TYPE void xen_machine_kexec(struct kimage *image) 26.164 +{ 26.165 + xen_kexec_exec_t xke; 26.166 + 26.167 + memset(&xke, 0, sizeof(xke)); 26.168 + xke.type = image->type; 26.169 + HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke); 26.170 + panic("KEXEC_CMD_kexec hypercall should not return\n"); 26.171 +} 26.172 + 26.173 +void machine_shutdown(void) 26.174 +{ 26.175 + /* do nothing */ 26.176 +} 26.177 + 26.178 + 26.179 +/* 26.180 + * Local variables: 26.181 + * c-file-style: "linux" 26.182 + * indent-tabs-mode: t 26.183 + * c-indent-level: 8 26.184 + * c-basic-offset: 8 26.185 + * tab-width: 8 26.186 + * End: 26.187 + */
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/Makefile Mon Dec 04 08:24:41 2006 -0700 27.3 @@ -0,0 +1,2 @@ 27.4 +obj-$(CONFIG_XEN_FRAMEBUFFER) := xenfb.o 27.5 +obj-$(CONFIG_XEN_KEYBOARD) += xenkbd.o
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c Mon Dec 04 08:24:41 2006 -0700 28.3 @@ -0,0 +1,682 @@ 28.4 +/* 28.5 + * linux/drivers/video/xenfb.c -- Xen para-virtual frame buffer device 28.6 + * 28.7 + * Copyright (C) 2005-2006 Anthony Liguori <aliguori@us.ibm.com> 28.8 + * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com> 28.9 + * 28.10 + * Based on linux/drivers/video/q40fb.c 28.11 + * 28.12 + * This file is subject to the terms and conditions of the GNU General Public 28.13 + * License. See the file COPYING in the main directory of this archive for 28.14 + * more details. 28.15 + */ 28.16 + 28.17 +/* 28.18 + * TODO: 28.19 + * 28.20 + * Switch to grant tables when they become capable of dealing with the 28.21 + * frame buffer. 28.22 + */ 28.23 + 28.24 +#include <linux/kernel.h> 28.25 +#include <linux/errno.h> 28.26 +#include <linux/fb.h> 28.27 +#include <linux/module.h> 28.28 +#include <linux/vmalloc.h> 28.29 +#include <linux/mm.h> 28.30 +#include <asm/hypervisor.h> 28.31 +#include <xen/evtchn.h> 28.32 +#include <xen/interface/io/fbif.h> 28.33 +#include <xen/xenbus.h> 28.34 +#include <linux/kthread.h> 28.35 + 28.36 +struct xenfb_mapping 28.37 +{ 28.38 + struct list_head link; 28.39 + struct vm_area_struct *vma; 28.40 + atomic_t map_refs; 28.41 + int faults; 28.42 + struct xenfb_info *info; 28.43 +}; 28.44 + 28.45 +struct xenfb_info 28.46 +{ 28.47 + struct task_struct *kthread; 28.48 + wait_queue_head_t wq; 28.49 + 28.50 + unsigned char *fb; 28.51 + struct fb_info *fb_info; 28.52 + struct timer_list refresh; 28.53 + int dirty; 28.54 + int x1, y1, x2, y2; /* dirty rectangle, 28.55 + protected by mm_lock */ 28.56 + spinlock_t mm_lock; 28.57 + int nr_pages; 28.58 + struct page **pages; 28.59 + struct list_head mappings; /* protected by mm_lock */ 28.60 + 28.61 + unsigned evtchn; 28.62 + int irq; 28.63 + struct xenfb_page *page; 28.64 + unsigned long *mfns; 28.65 + int update_wanted; /* XENFB_TYPE_UPDATE wanted */ 28.66 + 28.67 + struct xenbus_device *xbdev; 28.68 +}; 28.69 + 28.70 +static int xenfb_fps = 20; 28.71 +static unsigned long xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8; 28.72 + 28.73 +static int xenfb_remove(struct xenbus_device *); 28.74 +static void xenfb_init_shared_page(struct xenfb_info *); 28.75 +static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *); 28.76 +static void xenfb_disconnect_backend(struct xenfb_info *); 28.77 + 28.78 +static void xenfb_do_update(struct xenfb_info *info, 28.79 + int x, int y, int w, int h) 28.80 +{ 28.81 + union xenfb_out_event event; 28.82 + __u32 prod; 28.83 + 28.84 + event.type = XENFB_TYPE_UPDATE; 28.85 + event.update.x = x; 28.86 + event.update.y = y; 28.87 + event.update.width = w; 28.88 + event.update.height = h; 28.89 + 28.90 + prod = info->page->out_prod; 28.91 + /* caller ensures !xenfb_queue_full() */ 28.92 + mb(); /* ensure ring space available */ 28.93 + XENFB_OUT_RING_REF(info->page, prod) = event; 28.94 + wmb(); /* ensure ring contents visible */ 28.95 + info->page->out_prod = prod + 1; 28.96 + 28.97 + notify_remote_via_evtchn(info->evtchn); 28.98 +} 28.99 + 28.100 +static int xenfb_queue_full(struct xenfb_info *info) 28.101 +{ 28.102 + __u32 cons, prod; 28.103 + 28.104 + prod = info->page->out_prod; 28.105 + cons = info->page->out_cons; 28.106 + return prod - cons == XENFB_OUT_RING_LEN; 28.107 +} 28.108 + 28.109 +static void xenfb_update_screen(struct xenfb_info *info) 28.110 +{ 28.111 + unsigned long flags; 28.112 + int y1, y2, x1, x2; 28.113 + struct xenfb_mapping *map; 28.114 + 28.115 + if (!info->update_wanted) 28.116 + return; 28.117 + if (xenfb_queue_full(info)) 28.118 + return; 28.119 + 28.120 + spin_lock_irqsave(&info->mm_lock, flags); 28.121 + 28.122 + y1 = info->y1; 28.123 + y2 = info->y2; 28.124 + x1 = info->x1; 28.125 + x2 = info->x2; 28.126 + info->x1 = info->y1 = INT_MAX; 28.127 + info->x2 = info->y2 = 0; 28.128 + 28.129 + list_for_each_entry(map, &info->mappings, link) { 28.130 + if (!map->faults) 28.131 + continue; 28.132 + zap_page_range(map->vma, map->vma->vm_start, 28.133 + map->vma->vm_end - map->vma->vm_start, NULL); 28.134 + map->faults = 0; 28.135 + } 28.136 + 28.137 + spin_unlock_irqrestore(&info->mm_lock, flags); 28.138 + 28.139 + xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1); 28.140 +} 28.141 + 28.142 +static int xenfb_thread(void *data) 28.143 +{ 28.144 + struct xenfb_info *info = data; 28.145 + 28.146 + while (!kthread_should_stop()) { 28.147 + if (info->dirty) { 28.148 + info->dirty = 0; 28.149 + xenfb_update_screen(info); 28.150 + } 28.151 + wait_event_interruptible(info->wq, 28.152 + kthread_should_stop() || info->dirty); 28.153 + try_to_freeze(); 28.154 + } 28.155 + return 0; 28.156 +} 28.157 + 28.158 +static int xenfb_setcolreg(unsigned regno, unsigned red, unsigned green, 28.159 + unsigned blue, unsigned transp, 28.160 + struct fb_info *info) 28.161 +{ 28.162 + u32 v; 28.163 + 28.164 + if (regno > info->cmap.len) 28.165 + return 1; 28.166 + 28.167 + red >>= (16 - info->var.red.length); 28.168 + green >>= (16 - info->var.green.length); 28.169 + blue >>= (16 - info->var.blue.length); 28.170 + 28.171 + v = (red << info->var.red.offset) | 28.172 + (green << info->var.green.offset) | 28.173 + (blue << info->var.blue.offset); 28.174 + 28.175 + /* FIXME is this sane? check against xxxfb_setcolreg()! */ 28.176 + switch (info->var.bits_per_pixel) { 28.177 + case 16: 28.178 + case 24: 28.179 + case 32: 28.180 + ((u32 *)info->pseudo_palette)[regno] = v; 28.181 + break; 28.182 + } 28.183 + 28.184 + return 0; 28.185 +} 28.186 + 28.187 +static void xenfb_timer(unsigned long data) 28.188 +{ 28.189 + struct xenfb_info *info = (struct xenfb_info *)data; 28.190 + info->dirty = 1; 28.191 + wake_up(&info->wq); 28.192 +} 28.193 + 28.194 +static void __xenfb_refresh(struct xenfb_info *info, 28.195 + int x1, int y1, int w, int h) 28.196 +{ 28.197 + int y2, x2; 28.198 + 28.199 + y2 = y1 + h; 28.200 + x2 = x1 + w; 28.201 + 28.202 + if (info->y1 > y1) 28.203 + info->y1 = y1; 28.204 + if (info->y2 < y2) 28.205 + info->y2 = y2; 28.206 + if (info->x1 > x1) 28.207 + info->x1 = x1; 28.208 + if (info->x2 < x2) 28.209 + info->x2 = x2; 28.210 + 28.211 + if (timer_pending(&info->refresh)) 28.212 + return; 28.213 + 28.214 + mod_timer(&info->refresh, jiffies + HZ/xenfb_fps); 28.215 +} 28.216 + 28.217 +static void xenfb_refresh(struct xenfb_info *info, 28.218 + int x1, int y1, int w, int h) 28.219 +{ 28.220 + unsigned long flags; 28.221 + 28.222 + spin_lock_irqsave(&info->mm_lock, flags); 28.223 + __xenfb_refresh(info, x1, y1, w, h); 28.224 + spin_unlock_irqrestore(&info->mm_lock, flags); 28.225 +} 28.226 + 28.227 +static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) 28.228 +{ 28.229 + struct xenfb_info *info = p->par; 28.230 + 28.231 + cfb_fillrect(p, rect); 28.232 + xenfb_refresh(info, rect->dx, rect->dy, rect->width, rect->height); 28.233 +} 28.234 + 28.235 +static void xenfb_imageblit(struct fb_info *p, const struct fb_image *image) 28.236 +{ 28.237 + struct xenfb_info *info = p->par; 28.238 + 28.239 + cfb_imageblit(p, image); 28.240 + xenfb_refresh(info, image->dx, image->dy, image->width, image->height); 28.241 +} 28.242 + 28.243 +static void xenfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 28.244 +{ 28.245 + struct xenfb_info *info = p->par; 28.246 + 28.247 + cfb_copyarea(p, area); 28.248 + xenfb_refresh(info, area->dx, area->dy, area->width, area->height); 28.249 +} 28.250 + 28.251 +static void xenfb_vm_open(struct vm_area_struct *vma) 28.252 +{ 28.253 + struct xenfb_mapping *map = vma->vm_private_data; 28.254 + atomic_inc(&map->map_refs); 28.255 +} 28.256 + 28.257 +static void xenfb_vm_close(struct vm_area_struct *vma) 28.258 +{ 28.259 + struct xenfb_mapping *map = vma->vm_private_data; 28.260 + struct xenfb_info *info = map->info; 28.261 + unsigned long flags; 28.262 + 28.263 + spin_lock_irqsave(&info->mm_lock, flags); 28.264 + if (atomic_dec_and_test(&map->map_refs)) { 28.265 + list_del(&map->link); 28.266 + kfree(map); 28.267 + } 28.268 + spin_unlock_irqrestore(&info->mm_lock, flags); 28.269 +} 28.270 + 28.271 +static struct page *xenfb_vm_nopage(struct vm_area_struct *vma, 28.272 + unsigned long vaddr, int *type) 28.273 +{ 28.274 + struct xenfb_mapping *map = vma->vm_private_data; 28.275 + struct xenfb_info *info = map->info; 28.276 + int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT; 28.277 + unsigned long flags; 28.278 + struct page *page; 28.279 + int y1, y2; 28.280 + 28.281 + if (pgnr >= info->nr_pages) 28.282 + return NOPAGE_SIGBUS; 28.283 + 28.284 + spin_lock_irqsave(&info->mm_lock, flags); 28.285 + page = info->pages[pgnr]; 28.286 + get_page(page); 28.287 + map->faults++; 28.288 + 28.289 + y1 = pgnr * PAGE_SIZE / info->fb_info->fix.line_length; 28.290 + y2 = (pgnr * PAGE_SIZE + PAGE_SIZE - 1) / info->fb_info->fix.line_length; 28.291 + if (y2 > info->fb_info->var.yres) 28.292 + y2 = info->fb_info->var.yres; 28.293 + __xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1); 28.294 + spin_unlock_irqrestore(&info->mm_lock, flags); 28.295 + 28.296 + if (type) 28.297 + *type = VM_FAULT_MINOR; 28.298 + 28.299 + return page; 28.300 +} 28.301 + 28.302 +static struct vm_operations_struct xenfb_vm_ops = { 28.303 + .open = xenfb_vm_open, 28.304 + .close = xenfb_vm_close, 28.305 + .nopage = xenfb_vm_nopage, 28.306 +}; 28.307 + 28.308 +static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma) 28.309 +{ 28.310 + struct xenfb_info *info = fb_info->par; 28.311 + unsigned long flags; 28.312 + struct xenfb_mapping *map; 28.313 + int map_pages; 28.314 + 28.315 + if (!(vma->vm_flags & VM_WRITE)) 28.316 + return -EINVAL; 28.317 + if (!(vma->vm_flags & VM_SHARED)) 28.318 + return -EINVAL; 28.319 + if (vma->vm_pgoff != 0) 28.320 + return -EINVAL; 28.321 + 28.322 + map_pages = (vma->vm_end - vma->vm_start + PAGE_SIZE-1) >> PAGE_SHIFT; 28.323 + if (map_pages > info->nr_pages) 28.324 + return -EINVAL; 28.325 + 28.326 + map = kzalloc(sizeof(*map), GFP_KERNEL); 28.327 + if (map == NULL) 28.328 + return -ENOMEM; 28.329 + 28.330 + map->vma = vma; 28.331 + map->faults = 0; 28.332 + map->info = info; 28.333 + atomic_set(&map->map_refs, 1); 28.334 + 28.335 + spin_lock_irqsave(&info->mm_lock, flags); 28.336 + list_add(&map->link, &info->mappings); 28.337 + spin_unlock_irqrestore(&info->mm_lock, flags); 28.338 + 28.339 + vma->vm_ops = &xenfb_vm_ops; 28.340 + vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED); 28.341 + vma->vm_private_data = map; 28.342 + 28.343 + return 0; 28.344 +} 28.345 + 28.346 +static struct fb_ops xenfb_fb_ops = { 28.347 + .owner = THIS_MODULE, 28.348 + .fb_setcolreg = xenfb_setcolreg, 28.349 + .fb_fillrect = xenfb_fillrect, 28.350 + .fb_copyarea = xenfb_copyarea, 28.351 + .fb_imageblit = xenfb_imageblit, 28.352 + .fb_mmap = xenfb_mmap, 28.353 +}; 28.354 + 28.355 +static irqreturn_t xenfb_event_handler(int rq, void *dev_id, 28.356 + struct pt_regs *regs) 28.357 +{ 28.358 + /* 28.359 + * No in events recognized, simply ignore them all. 28.360 + * If you need to recognize some, see xenbkd's input_handler() 28.361 + * for how to do that. 28.362 + */ 28.363 + struct xenfb_info *info = dev_id; 28.364 + struct xenfb_page *page = info->page; 28.365 + 28.366 + if (page->in_cons != page->in_prod) { 28.367 + info->page->in_cons = info->page->in_prod; 28.368 + notify_remote_via_evtchn(info->evtchn); 28.369 + } 28.370 + return IRQ_HANDLED; 28.371 +} 28.372 + 28.373 +static unsigned long vmalloc_to_mfn(void *address) 28.374 +{ 28.375 + return pfn_to_mfn(vmalloc_to_pfn(address)); 28.376 +} 28.377 + 28.378 +static int __devinit xenfb_probe(struct xenbus_device *dev, 28.379 + const struct xenbus_device_id *id) 28.380 +{ 28.381 + struct xenfb_info *info; 28.382 + struct fb_info *fb_info; 28.383 + int ret; 28.384 + 28.385 + info = kzalloc(sizeof(*info), GFP_KERNEL); 28.386 + if (info == NULL) { 28.387 + xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); 28.388 + return -ENOMEM; 28.389 + } 28.390 + dev->dev.driver_data = info; 28.391 + info->xbdev = dev; 28.392 + info->irq = -1; 28.393 + info->x1 = info->y1 = INT_MAX; 28.394 + spin_lock_init(&info->mm_lock); 28.395 + init_waitqueue_head(&info->wq); 28.396 + init_timer(&info->refresh); 28.397 + info->refresh.function = xenfb_timer; 28.398 + info->refresh.data = (unsigned long)info; 28.399 + INIT_LIST_HEAD(&info->mappings); 28.400 + 28.401 + info->fb = vmalloc(xenfb_mem_len); 28.402 + if (info->fb == NULL) 28.403 + goto error_nomem; 28.404 + memset(info->fb, 0, xenfb_mem_len); 28.405 + 28.406 + info->nr_pages = (xenfb_mem_len + PAGE_SIZE - 1) >> PAGE_SHIFT; 28.407 + 28.408 + info->pages = kmalloc(sizeof(struct page *) * info->nr_pages, 28.409 + GFP_KERNEL); 28.410 + if (info->pages == NULL) 28.411 + goto error_nomem; 28.412 + 28.413 + info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages); 28.414 + if (!info->mfns) 28.415 + goto error_nomem; 28.416 + 28.417 + /* set up shared page */ 28.418 + info->page = (void *)__get_free_page(GFP_KERNEL); 28.419 + if (!info->page) 28.420 + goto error_nomem; 28.421 + 28.422 + xenfb_init_shared_page(info); 28.423 + 28.424 + fb_info = framebuffer_alloc(sizeof(u32) * 256, NULL); 28.425 + /* see fishy hackery below */ 28.426 + if (fb_info == NULL) 28.427 + goto error_nomem; 28.428 + 28.429 + /* FIXME fishy hackery */ 28.430 + fb_info->pseudo_palette = fb_info->par; 28.431 + fb_info->par = info; 28.432 + /* /FIXME */ 28.433 + fb_info->screen_base = info->fb; 28.434 + 28.435 + fb_info->fbops = &xenfb_fb_ops; 28.436 + fb_info->var.xres_virtual = fb_info->var.xres = info->page->width; 28.437 + fb_info->var.yres_virtual = fb_info->var.yres = info->page->height; 28.438 + fb_info->var.bits_per_pixel = info->page->depth; 28.439 + 28.440 + fb_info->var.red = (struct fb_bitfield){16, 8, 0}; 28.441 + fb_info->var.green = (struct fb_bitfield){8, 8, 0}; 28.442 + fb_info->var.blue = (struct fb_bitfield){0, 8, 0}; 28.443 + 28.444 + fb_info->var.activate = FB_ACTIVATE_NOW; 28.445 + fb_info->var.height = -1; 28.446 + fb_info->var.width = -1; 28.447 + fb_info->var.vmode = FB_VMODE_NONINTERLACED; 28.448 + 28.449 + fb_info->fix.visual = FB_VISUAL_TRUECOLOR; 28.450 + fb_info->fix.line_length = info->page->line_length; 28.451 + fb_info->fix.smem_start = 0; 28.452 + fb_info->fix.smem_len = xenfb_mem_len; 28.453 + strcpy(fb_info->fix.id, "xen"); 28.454 + fb_info->fix.type = FB_TYPE_PACKED_PIXELS; 28.455 + fb_info->fix.accel = FB_ACCEL_NONE; 28.456 + 28.457 + fb_info->flags = FBINFO_FLAG_DEFAULT; 28.458 + 28.459 + ret = fb_alloc_cmap(&fb_info->cmap, 256, 0); 28.460 + if (ret < 0) { 28.461 + framebuffer_release(fb_info); 28.462 + xenbus_dev_fatal(dev, ret, "fb_alloc_cmap"); 28.463 + goto error; 28.464 + } 28.465 + 28.466 + ret = register_framebuffer(fb_info); 28.467 + if (ret) { 28.468 + fb_dealloc_cmap(&info->fb_info->cmap); 28.469 + framebuffer_release(fb_info); 28.470 + xenbus_dev_fatal(dev, ret, "register_framebuffer"); 28.471 + goto error; 28.472 + } 28.473 + info->fb_info = fb_info; 28.474 + 28.475 + /* FIXME should this be delayed until backend XenbusStateConnected? */ 28.476 + info->kthread = kthread_run(xenfb_thread, info, "xenfb thread"); 28.477 + if (IS_ERR(info->kthread)) { 28.478 + ret = PTR_ERR(info->kthread); 28.479 + info->kthread = NULL; 28.480 + xenbus_dev_fatal(dev, ret, "register_framebuffer"); 28.481 + goto error; 28.482 + } 28.483 + 28.484 + ret = xenfb_connect_backend(dev, info); 28.485 + if (ret < 0) 28.486 + goto error; 28.487 + 28.488 + return 0; 28.489 + 28.490 + error_nomem: 28.491 + ret = -ENOMEM; 28.492 + xenbus_dev_fatal(dev, ret, "allocating device memory"); 28.493 + error: 28.494 + xenfb_remove(dev); 28.495 + return ret; 28.496 +} 28.497 + 28.498 +static int xenfb_resume(struct xenbus_device *dev) 28.499 +{ 28.500 + struct xenfb_info *info = dev->dev.driver_data; 28.501 + 28.502 + xenfb_disconnect_backend(info); 28.503 + xenfb_init_shared_page(info); 28.504 + return xenfb_connect_backend(dev, info); 28.505 +} 28.506 + 28.507 +static int xenfb_remove(struct xenbus_device *dev) 28.508 +{ 28.509 + struct xenfb_info *info = dev->dev.driver_data; 28.510 + 28.511 + del_timer(&info->refresh); 28.512 + if (info->kthread) 28.513 + kthread_stop(info->kthread); 28.514 + xenfb_disconnect_backend(info); 28.515 + if (info->fb_info) { 28.516 + unregister_framebuffer(info->fb_info); 28.517 + fb_dealloc_cmap(&info->fb_info->cmap); 28.518 + framebuffer_release(info->fb_info); 28.519 + } 28.520 + free_page((unsigned long)info->page); 28.521 + vfree(info->mfns); 28.522 + kfree(info->pages); 28.523 + vfree(info->fb); 28.524 + kfree(info); 28.525 + 28.526 + return 0; 28.527 +} 28.528 + 28.529 +static void xenfb_init_shared_page(struct xenfb_info *info) 28.530 +{ 28.531 + int i; 28.532 + 28.533 + for (i = 0; i < info->nr_pages; i++) 28.534 + info->pages[i] = vmalloc_to_page(info->fb + i * PAGE_SIZE); 28.535 + 28.536 + for (i = 0; i < info->nr_pages; i++) 28.537 + info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE); 28.538 + 28.539 + info->page->pd[0] = vmalloc_to_mfn(info->mfns); 28.540 + info->page->pd[1] = 0; 28.541 + info->page->width = XENFB_WIDTH; 28.542 + info->page->height = XENFB_HEIGHT; 28.543 + info->page->depth = XENFB_DEPTH; 28.544 + info->page->line_length = (info->page->depth / 8) * info->page->width; 28.545 + info->page->mem_length = xenfb_mem_len; 28.546 + info->page->in_cons = info->page->in_prod = 0; 28.547 + info->page->out_cons = info->page->out_prod = 0; 28.548 +} 28.549 + 28.550 +static int xenfb_connect_backend(struct xenbus_device *dev, 28.551 + struct xenfb_info *info) 28.552 +{ 28.553 + int ret; 28.554 + struct xenbus_transaction xbt; 28.555 + 28.556 + ret = xenbus_alloc_evtchn(dev, &info->evtchn); 28.557 + if (ret) 28.558 + return ret; 28.559 + ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler, 28.560 + 0, "xenfb", info); 28.561 + if (ret < 0) { 28.562 + xenbus_free_evtchn(dev, info->evtchn); 28.563 + xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); 28.564 + return ret; 28.565 + } 28.566 + info->irq = ret; 28.567 + 28.568 + again: 28.569 + ret = xenbus_transaction_start(&xbt); 28.570 + if (ret) { 28.571 + xenbus_dev_fatal(dev, ret, "starting transaction"); 28.572 + return ret; 28.573 + } 28.574 + ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", 28.575 + virt_to_mfn(info->page)); 28.576 + if (ret) 28.577 + goto error_xenbus; 28.578 + ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", 28.579 + info->evtchn); 28.580 + if (ret) 28.581 + goto error_xenbus; 28.582 + ret = xenbus_printf(xbt, dev->nodename, "feature-update", "1"); 28.583 + if (ret) 28.584 + goto error_xenbus; 28.585 + ret = xenbus_transaction_end(xbt, 0); 28.586 + if (ret) { 28.587 + if (ret == -EAGAIN) 28.588 + goto again; 28.589 + xenbus_dev_fatal(dev, ret, "completing transaction"); 28.590 + return ret; 28.591 + } 28.592 + 28.593 + xenbus_switch_state(dev, XenbusStateInitialised); 28.594 + return 0; 28.595 + 28.596 + error_xenbus: 28.597 + xenbus_transaction_end(xbt, 1); 28.598 + xenbus_dev_fatal(dev, ret, "writing xenstore"); 28.599 + return ret; 28.600 +} 28.601 + 28.602 +static void xenfb_disconnect_backend(struct xenfb_info *info) 28.603 +{ 28.604 + if (info->irq >= 0) 28.605 + unbind_from_irqhandler(info->irq, info); 28.606 + info->irq = -1; 28.607 +} 28.608 + 28.609 +static void xenfb_backend_changed(struct xenbus_device *dev, 28.610 + enum xenbus_state backend_state) 28.611 +{ 28.612 + struct xenfb_info *info = dev->dev.driver_data; 28.613 + int val; 28.614 + 28.615 + switch (backend_state) { 28.616 + case XenbusStateInitialising: 28.617 + case XenbusStateInitialised: 28.618 + case XenbusStateUnknown: 28.619 + case XenbusStateClosed: 28.620 + break; 28.621 + 28.622 + case XenbusStateInitWait: 28.623 + InitWait: 28.624 + xenbus_switch_state(dev, XenbusStateConnected); 28.625 + break; 28.626 + 28.627 + case XenbusStateConnected: 28.628 + /* 28.629 + * Work around xenbus race condition: If backend goes 28.630 + * through InitWait to Connected fast enough, we can 28.631 + * get Connected twice here. 28.632 + */ 28.633 + if (dev->state != XenbusStateConnected) 28.634 + goto InitWait; /* no InitWait seen yet, fudge it */ 28.635 + 28.636 + if (xenbus_scanf(XBT_NIL, info->xbdev->otherend, 28.637 + "request-update", "%d", &val) < 0) 28.638 + val = 0; 28.639 + if (val) 28.640 + info->update_wanted = 1; 28.641 + break; 28.642 + 28.643 + case XenbusStateClosing: 28.644 + // FIXME is this safe in any dev->state? 28.645 + xenbus_frontend_closed(dev); 28.646 + break; 28.647 + } 28.648 +} 28.649 + 28.650 +static struct xenbus_device_id xenfb_ids[] = { 28.651 + { "vfb" }, 28.652 + { "" } 28.653 +}; 28.654 + 28.655 +static struct xenbus_driver xenfb = { 28.656 + .name = "vfb", 28.657 + .owner = THIS_MODULE, 28.658 + .ids = xenfb_ids, 28.659 + .probe = xenfb_probe, 28.660 + .remove = xenfb_remove, 28.661 + .resume = xenfb_resume, 28.662 + .otherend_changed = xenfb_backend_changed, 28.663 +}; 28.664 + 28.665 +static int __init xenfb_init(void) 28.666 +{ 28.667 + if (!is_running_on_xen()) 28.668 + return -ENODEV; 28.669 + 28.670 + /* Nothing to do if running in dom0. */ 28.671 + if (is_initial_xendomain()) 28.672 + return -ENODEV; 28.673 + 28.674 + return xenbus_register_frontend(&xenfb); 28.675 +} 28.676 + 28.677 +static void __exit xenfb_cleanup(void) 28.678 +{ 28.679 + return xenbus_unregister_driver(&xenfb); 28.680 +} 28.681 + 28.682 +module_init(xenfb_init); 28.683 +module_exit(xenfb_cleanup); 28.684 + 28.685 +MODULE_LICENSE("GPL");
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Mon Dec 04 08:24:41 2006 -0700 29.3 @@ -0,0 +1,300 @@ 29.4 +/* 29.5 + * linux/drivers/input/keyboard/xenkbd.c -- Xen para-virtual input device 29.6 + * 29.7 + * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com> 29.8 + * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com> 29.9 + * 29.10 + * Based on linux/drivers/input/mouse/sermouse.c 29.11 + * 29.12 + * This file is subject to the terms and conditions of the GNU General Public 29.13 + * License. See the file COPYING in the main directory of this archive for 29.14 + * more details. 29.15 + */ 29.16 + 29.17 +/* 29.18 + * TODO: 29.19 + * 29.20 + * Switch to grant tables together with xenfb.c. 29.21 + */ 29.22 + 29.23 +#include <linux/kernel.h> 29.24 +#include <linux/errno.h> 29.25 +#include <linux/module.h> 29.26 +#include <linux/input.h> 29.27 +#include <asm/hypervisor.h> 29.28 +#include <xen/evtchn.h> 29.29 +#include <xen/interface/io/fbif.h> 29.30 +#include <xen/interface/io/kbdif.h> 29.31 +#include <xen/xenbus.h> 29.32 + 29.33 +struct xenkbd_info 29.34 +{ 29.35 + struct input_dev *dev; 29.36 + struct xenkbd_page *page; 29.37 + unsigned evtchn; 29.38 + int irq; 29.39 + struct xenbus_device *xbdev; 29.40 +}; 29.41 + 29.42 +static int xenkbd_remove(struct xenbus_device *); 29.43 +static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *); 29.44 +static void xenkbd_disconnect_backend(struct xenkbd_info *); 29.45 + 29.46 +/* 29.47 + * Note: if you need to send out events, see xenfb_do_update() for how 29.48 + * to do that. 29.49 + */ 29.50 + 29.51 +static irqreturn_t input_handler(int rq, void *dev_id, struct pt_regs *regs) 29.52 +{ 29.53 + struct xenkbd_info *info = dev_id; 29.54 + struct xenkbd_page *page = info->page; 29.55 + __u32 cons, prod; 29.56 + 29.57 + prod = page->in_prod; 29.58 + if (prod == page->out_cons) 29.59 + return IRQ_HANDLED; 29.60 + rmb(); /* ensure we see ring contents up to prod */ 29.61 + for (cons = page->in_cons; cons != prod; cons++) { 29.62 + union xenkbd_in_event *event; 29.63 + event = &XENKBD_IN_RING_REF(page, cons); 29.64 + 29.65 + switch (event->type) { 29.66 + case XENKBD_TYPE_MOTION: 29.67 + input_report_rel(info->dev, REL_X, event->motion.rel_x); 29.68 + input_report_rel(info->dev, REL_Y, event->motion.rel_y); 29.69 + break; 29.70 + case XENKBD_TYPE_KEY: 29.71 + input_report_key(info->dev, event->key.keycode, event->key.pressed); 29.72 + break; 29.73 + case XENKBD_TYPE_POS: 29.74 + input_report_abs(info->dev, ABS_X, event->pos.abs_x); 29.75 + input_report_abs(info->dev, ABS_Y, event->pos.abs_y); 29.76 + break; 29.77 + } 29.78 + } 29.79 + input_sync(info->dev); 29.80 + mb(); /* ensure we got ring contents */ 29.81 + page->in_cons = cons; 29.82 + notify_remote_via_evtchn(info->evtchn); 29.83 + 29.84 + return IRQ_HANDLED; 29.85 +} 29.86 + 29.87 +int __devinit xenkbd_probe(struct xenbus_device *dev, 29.88 + const struct xenbus_device_id *id) 29.89 +{ 29.90 + int ret, i; 29.91 + struct xenkbd_info *info; 29.92 + struct input_dev *input_dev; 29.93 + 29.94 + info = kzalloc(sizeof(*info), GFP_KERNEL); 29.95 + if (!info) { 29.96 + xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); 29.97 + return -ENOMEM; 29.98 + } 29.99 + dev->dev.driver_data = info; 29.100 + info->xbdev = dev; 29.101 + 29.102 + info->page = (void *)__get_free_page(GFP_KERNEL); 29.103 + if (!info->page) 29.104 + goto error_nomem; 29.105 + info->page->in_cons = info->page->in_prod = 0; 29.106 + info->page->out_cons = info->page->out_prod = 0; 29.107 + 29.108 + input_dev = input_allocate_device(); 29.109 + if (!input_dev) 29.110 + goto error_nomem; 29.111 + 29.112 + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); 29.113 + input_dev->keybit[LONG(BTN_MOUSE)] 29.114 + = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 29.115 + /* TODO additional buttons */ 29.116 + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); 29.117 + 29.118 + /* FIXME not sure this is quite right */ 29.119 + for (i = 0; i < 256; i++) 29.120 + set_bit(i, input_dev->keybit); 29.121 + 29.122 + input_dev->name = "Xen Virtual Keyboard/Mouse"; 29.123 + 29.124 + input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0); 29.125 + input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0); 29.126 + 29.127 + ret = input_register_device(input_dev); 29.128 + if (ret) { 29.129 + input_free_device(input_dev); 29.130 + xenbus_dev_fatal(dev, ret, "input_register_device"); 29.131 + goto error; 29.132 + } 29.133 + info->dev = input_dev; 29.134 + 29.135 + ret = xenkbd_connect_backend(dev, info); 29.136 + if (ret < 0) 29.137 + goto error; 29.138 + 29.139 + return 0; 29.140 + 29.141 + error_nomem: 29.142 + ret = -ENOMEM; 29.143 + xenbus_dev_fatal(dev, ret, "allocating device memory"); 29.144 + error: 29.145 + xenkbd_remove(dev); 29.146 + return ret; 29.147 +} 29.148 + 29.149 +static int xenkbd_resume(struct xenbus_device *dev) 29.150 +{ 29.151 + struct xenkbd_info *info = dev->dev.driver_data; 29.152 + 29.153 + xenkbd_disconnect_backend(info); 29.154 + return xenkbd_connect_backend(dev, info); 29.155 +} 29.156 + 29.157 +static int xenkbd_remove(struct xenbus_device *dev) 29.158 +{ 29.159 + struct xenkbd_info *info = dev->dev.driver_data; 29.160 + 29.161 + xenkbd_disconnect_backend(info); 29.162 + input_unregister_device(info->dev); 29.163 + free_page((unsigned long)info->page); 29.164 + kfree(info); 29.165 + return 0; 29.166 +} 29.167 + 29.168 +static int xenkbd_connect_backend(struct xenbus_device *dev, 29.169 + struct xenkbd_info *info) 29.170 +{ 29.171 + int ret; 29.172 + struct xenbus_transaction xbt; 29.173 + 29.174 + ret = xenbus_alloc_evtchn(dev, &info->evtchn); 29.175 + if (ret) 29.176 + return ret; 29.177 + ret = bind_evtchn_to_irqhandler(info->evtchn, input_handler, 0, 29.178 + "xenkbd", info); 29.179 + if (ret < 0) { 29.180 + xenbus_free_evtchn(dev, info->evtchn); 29.181 + xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); 29.182 + return ret; 29.183 + } 29.184 + info->irq = ret; 29.185 + 29.186 + again: 29.187 + ret = xenbus_transaction_start(&xbt); 29.188 + if (ret) { 29.189 + xenbus_dev_fatal(dev, ret, "starting transaction"); 29.190 + return ret; 29.191 + } 29.192 + ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", 29.193 + virt_to_mfn(info->page)); 29.194 + if (ret) 29.195 + goto error_xenbus; 29.196 + ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", 29.197 + info->evtchn); 29.198 + if (ret) 29.199 + goto error_xenbus; 29.200 + ret = xenbus_transaction_end(xbt, 0); 29.201 + if (ret) { 29.202 + if (ret == -EAGAIN) 29.203 + goto again; 29.204 + xenbus_dev_fatal(dev, ret, "completing transaction"); 29.205 + return ret; 29.206 + } 29.207 + 29.208 + xenbus_switch_state(dev, XenbusStateInitialised); 29.209 + return 0; 29.210 + 29.211 + error_xenbus: 29.212 + xenbus_transaction_end(xbt, 1); 29.213 + xenbus_dev_fatal(dev, ret, "writing xenstore"); 29.214 + return ret; 29.215 +} 29.216 + 29.217 +static void xenkbd_disconnect_backend(struct xenkbd_info *info) 29.218 +{ 29.219 + if (info->irq >= 0) 29.220 + unbind_from_irqhandler(info->irq, info); 29.221 + info->irq = -1; 29.222 +} 29.223 + 29.224 +static void xenkbd_backend_changed(struct xenbus_device *dev, 29.225 + enum xenbus_state backend_state) 29.226 +{ 29.227 + struct xenkbd_info *info = dev->dev.driver_data; 29.228 + int ret, val; 29.229 + 29.230 + switch (backend_state) { 29.231 + case XenbusStateInitialising: 29.232 + case XenbusStateInitialised: 29.233 + case XenbusStateUnknown: 29.234 + case XenbusStateClosed: 29.235 + break; 29.236 + 29.237 + case XenbusStateInitWait: 29.238 + InitWait: 29.239 + ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend, 29.240 + "feature-abs-pointer", "%d", &val); 29.241 + if (ret < 0) 29.242 + val = 0; 29.243 + if (val) { 29.244 + ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, 29.245 + "request-abs-pointer", "1"); 29.246 + if (ret) 29.247 + ; /* FIXME */ 29.248 + } 29.249 + xenbus_switch_state(dev, XenbusStateConnected); 29.250 + break; 29.251 + 29.252 + case XenbusStateConnected: 29.253 + /* 29.254 + * Work around xenbus race condition: If backend goes 29.255 + * through InitWait to Connected fast enough, we can 29.256 + * get Connected twice here. 29.257 + */ 29.258 + if (dev->state != XenbusStateConnected) 29.259 + goto InitWait; /* no InitWait seen yet, fudge it */ 29.260 + break; 29.261 + 29.262 + case XenbusStateClosing: 29.263 + xenbus_frontend_closed(dev); 29.264 + break; 29.265 + } 29.266 +} 29.267 + 29.268 +static struct xenbus_device_id xenkbd_ids[] = { 29.269 + { "vkbd" }, 29.270 + { "" } 29.271 +}; 29.272 + 29.273 +static struct xenbus_driver xenkbd = { 29.274 + .name = "vkbd", 29.275 + .owner = THIS_MODULE, 29.276 + .ids = xenkbd_ids, 29.277 + .probe = xenkbd_probe, 29.278 + .remove = xenkbd_remove, 29.279 + .resume = xenkbd_resume, 29.280 + .otherend_changed = xenkbd_backend_changed, 29.281 +}; 29.282 + 29.283 +static int __init xenkbd_init(void) 29.284 +{ 29.285 + if (!is_running_on_xen()) 29.286 + return -ENODEV; 29.287 + 29.288 + /* Nothing to do if running in dom0. */ 29.289 + if (is_initial_xendomain()) 29.290 + return -ENODEV; 29.291 + 29.292 + return xenbus_register_frontend(&xenkbd); 29.293 +} 29.294 + 29.295 +static void __exit xenkbd_cleanup(void) 29.296 +{ 29.297 + return xenbus_unregister_driver(&xenkbd); 29.298 +} 29.299 + 29.300 +module_init(xenkbd_init); 29.301 +module_exit(xenkbd_cleanup); 29.302 + 29.303 +MODULE_LICENSE("GPL");
30.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Sat Dec 02 15:19:50 2006 -0700 30.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Mon Dec 04 08:24:41 2006 -0700 30.3 @@ -395,5 +395,13 @@ HYPERVISOR_xenoprof_op( 30.4 return _hypercall2(int, xenoprof_op, op, arg); 30.5 } 30.6 30.7 +static inline int 30.8 +HYPERVISOR_kexec_op( 30.9 + unsigned long op, void *args) 30.10 +{ 30.11 + return _hypercall2(int, kexec_op, op, args); 30.12 +} 30.13 + 30.14 + 30.15 30.16 #endif /* __HYPERCALL_H__ */
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/agp.h Mon Dec 04 08:24:41 2006 -0700 31.3 @@ -0,0 +1,35 @@ 31.4 +#ifndef AGP_H 31.5 +#define AGP_H 1 31.6 + 31.7 +#include <asm/cacheflush.h> 31.8 +#include <asm/system.h> 31.9 + 31.10 +/* 31.11 + * Functions to keep the agpgart mappings coherent. 31.12 + * The GART gives the CPU a physical alias of memory. The alias is 31.13 + * mapped uncacheable. Make sure there are no conflicting mappings 31.14 + * with different cachability attributes for the same page. 31.15 + */ 31.16 + 31.17 +int map_page_into_agp(struct page *page); 31.18 +int unmap_page_from_agp(struct page *page); 31.19 +#define flush_agp_mappings() global_flush_tlb() 31.20 + 31.21 +/* Could use CLFLUSH here if the cpu supports it. But then it would 31.22 + need to be called for each cacheline of the whole page so it may not be 31.23 + worth it. Would need a page for it. */ 31.24 +#define flush_agp_cache() wbinvd() 31.25 + 31.26 +/* Convert a physical address to an address suitable for the GART. */ 31.27 +#define phys_to_gart(x) phys_to_machine(x) 31.28 +#define gart_to_phys(x) machine_to_phys(x) 31.29 + 31.30 +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ 31.31 +#define alloc_gatt_pages(order) ({ \ 31.32 + char *_t; dma_addr_t _d; \ 31.33 + _t = dma_alloc_coherent(NULL,PAGE_SIZE<<(order),&_d,GFP_KERNEL); \ 31.34 + _t; }) 31.35 +#define free_gatt_pages(table, order) \ 31.36 + dma_free_coherent(NULL,PAGE_SIZE<<(order),(table),virt_to_bus(table)) 31.37 + 31.38 +#endif
32.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Sat Dec 02 15:19:50 2006 -0700 32.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Mon Dec 04 08:24:41 2006 -0700 32.3 @@ -396,4 +396,11 @@ HYPERVISOR_xenoprof_op( 32.4 return _hypercall2(int, xenoprof_op, op, arg); 32.5 } 32.6 32.7 +static inline int 32.8 +HYPERVISOR_kexec_op( 32.9 + unsigned long op, void *args) 32.10 +{ 32.11 + return _hypercall2(int, kexec_op, op, args); 32.12 +} 32.13 + 32.14 #endif /* __HYPERCALL_H__ */
33.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h Sat Dec 02 15:19:50 2006 -0700 33.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h Mon Dec 04 08:24:41 2006 -0700 33.3 @@ -90,6 +90,8 @@ extern unsigned long profile_pc(struct p 33.4 #define profile_pc(regs) instruction_pointer(regs) 33.5 #endif 33.6 33.7 +#include <linux/compiler.h> 33.8 + 33.9 void signal_fault(struct pt_regs *regs, void __user *frame, char *where); 33.10 33.11 struct task_struct;
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/xenoprof.h Mon Dec 04 08:24:41 2006 -0700 34.3 @@ -0,0 +1,1 @@ 34.4 +#include <asm-i386/mach-xen/asm/xenoprof.h>
35.1 --- a/linux-2.6-xen-sparse/include/xen/xencons.h Sat Dec 02 15:19:50 2006 -0700 35.2 +++ b/linux-2.6-xen-sparse/include/xen/xencons.h Mon Dec 04 08:24:41 2006 -0700 35.3 @@ -14,4 +14,6 @@ void xencons_tx(void); 35.4 int xencons_ring_init(void); 35.5 int xencons_ring_send(const char *data, unsigned len); 35.6 35.7 +void xencons_early_setup(void); 35.8 + 35.9 #endif /* __ASM_XENCONS_H__ */
36.1 --- a/linux-2.6-xen-sparse/mm/memory.c Sat Dec 02 15:19:50 2006 -0700 36.2 +++ b/linux-2.6-xen-sparse/mm/memory.c Mon Dec 04 08:24:41 2006 -0700 36.3 @@ -882,6 +882,7 @@ unsigned long zap_page_range(struct vm_a 36.4 tlb_finish_mmu(tlb, address, end); 36.5 return end; 36.6 } 36.7 +EXPORT_SYMBOL(zap_page_range); 36.8 36.9 /* 36.10 * Do a quick page-table lookup for a single page.
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch Mon Dec 04 08:24:41 2006 -0700 37.3 @@ -0,0 +1,62 @@ 37.4 +From: Eric W. Biederman <ebiederm@xmission.com> 37.5 +Date: Sun, 30 Jul 2006 10:03:20 +0000 (-0700) 37.6 +Subject: [PATCH] machine_kexec.c: Fix the description of segment handling 37.7 +X-Git-Tag: v2.6.18-rc4 37.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2a8a3d5b65e86ec1dfef7d268c64a909eab94af7 37.9 + 37.10 +[PATCH] machine_kexec.c: Fix the description of segment handling 37.11 + 37.12 +One of my original comments in machine_kexec was unclear 37.13 +and this should fix it. 37.14 + 37.15 +Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> 37.16 +Cc: Andi Kleen <ak@muc.de> 37.17 +Acked-by: Horms <horms@verge.net.au> 37.18 +Signed-off-by: Andrew Morton <akpm@osdl.org> 37.19 +Signed-off-by: Linus Torvalds <torvalds@osdl.org> 37.20 +--- 37.21 + 37.22 +--- a/arch/i386/kernel/machine_kexec.c 37.23 ++++ b/arch/i386/kernel/machine_kexec.c 37.24 +@@ -189,14 +189,11 @@ NORET_TYPE void machine_kexec(struct kim 37.25 + memcpy((void *)reboot_code_buffer, relocate_new_kernel, 37.26 + relocate_new_kernel_size); 37.27 + 37.28 +- /* The segment registers are funny things, they are 37.29 +- * automatically loaded from a table, in memory wherever you 37.30 +- * set them to a specific selector, but this table is never 37.31 +- * accessed again you set the segment to a different selector. 37.32 +- * 37.33 +- * The more common model is are caches where the behide 37.34 +- * the scenes work is done, but is also dropped at arbitrary 37.35 +- * times. 37.36 ++ /* The segment registers are funny things, they have both a 37.37 ++ * visible and an invisible part. Whenever the visible part is 37.38 ++ * set to a specific selector, the invisible part is loaded 37.39 ++ * with from a table in memory. At no other time is the 37.40 ++ * descriptor table in memory accessed. 37.41 + * 37.42 + * I take advantage of this here by force loading the 37.43 + * segments, before I zap the gdt with an invalid value. 37.44 +--- a/arch/x86_64/kernel/machine_kexec.c 37.45 ++++ b/arch/x86_64/kernel/machine_kexec.c 37.46 +@@ -207,14 +207,11 @@ NORET_TYPE void machine_kexec(struct kim 37.47 + __flush_tlb(); 37.48 + 37.49 + 37.50 +- /* The segment registers are funny things, they are 37.51 +- * automatically loaded from a table, in memory wherever you 37.52 +- * set them to a specific selector, but this table is never 37.53 +- * accessed again unless you set the segment to a different selector. 37.54 +- * 37.55 +- * The more common model are caches where the behide 37.56 +- * the scenes work is done, but is also dropped at arbitrary 37.57 +- * times. 37.58 ++ /* The segment registers are funny things, they have both a 37.59 ++ * visible and an invisible part. Whenever the visible part is 37.60 ++ * set to a specific selector, the invisible part is loaded 37.61 ++ * with from a table in memory. At no other time is the 37.62 ++ * descriptor table in memory accessed. 37.63 + * 37.64 + * I take advantage of this here by force loading the 37.65 + * segments, before I zap the gdt with an invalid value.
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch Mon Dec 04 08:24:41 2006 -0700 38.3 @@ -0,0 +1,93 @@ 38.4 +From: Tobias Klauser <tklauser@nuerscht.ch> 38.5 +Date: Mon, 26 Jun 2006 16:57:34 +0000 (+0200) 38.6 +Subject: Storage class should be first 38.7 +X-Git-Tag: v2.6.18-rc1 38.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2efe55a9cec8418f0e0cde3dc3787a42fddc4411 38.9 + 38.10 +Storage class should be first 38.11 + 38.12 +Storage class should be before const 38.13 + 38.14 +Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch> 38.15 +Signed-off-by: Adrian Bunk <bunk@stusta.de> 38.16 +--- 38.17 + 38.18 +--- a/arch/i386/kernel/machine_kexec.c 38.19 ++++ b/arch/i386/kernel/machine_kexec.c 38.20 +@@ -133,9 +133,9 @@ typedef asmlinkage NORET_TYPE void (*rel 38.21 + unsigned long start_address, 38.22 + unsigned int has_pae) ATTRIB_NORET; 38.23 + 38.24 +-const extern unsigned char relocate_new_kernel[]; 38.25 ++extern const unsigned char relocate_new_kernel[]; 38.26 + extern void relocate_new_kernel_end(void); 38.27 +-const extern unsigned int relocate_new_kernel_size; 38.28 ++extern const unsigned int relocate_new_kernel_size; 38.29 + 38.30 + /* 38.31 + * A architecture hook called to validate the 38.32 +--- a/arch/powerpc/kernel/machine_kexec_32.c 38.33 ++++ b/arch/powerpc/kernel/machine_kexec_32.c 38.34 +@@ -30,8 +30,8 @@ typedef NORET_TYPE void (*relocate_new_k 38.35 + */ 38.36 + void default_machine_kexec(struct kimage *image) 38.37 + { 38.38 +- const extern unsigned char relocate_new_kernel[]; 38.39 +- const extern unsigned int relocate_new_kernel_size; 38.40 ++ extern const unsigned char relocate_new_kernel[]; 38.41 ++ extern const unsigned int relocate_new_kernel_size; 38.42 + unsigned long page_list; 38.43 + unsigned long reboot_code_buffer, reboot_code_buffer_phys; 38.44 + relocate_new_kernel_t rnk; 38.45 +--- a/arch/ppc/kernel/machine_kexec.c 38.46 ++++ b/arch/ppc/kernel/machine_kexec.c 38.47 +@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k 38.48 + unsigned long reboot_code_buffer, 38.49 + unsigned long start_address) ATTRIB_NORET; 38.50 + 38.51 +-const extern unsigned char relocate_new_kernel[]; 38.52 +-const extern unsigned int relocate_new_kernel_size; 38.53 ++extern const unsigned char relocate_new_kernel[]; 38.54 ++extern const unsigned int relocate_new_kernel_size; 38.55 + 38.56 + void machine_shutdown(void) 38.57 + { 38.58 +--- a/arch/s390/kernel/machine_kexec.c 38.59 ++++ b/arch/s390/kernel/machine_kexec.c 38.60 +@@ -27,8 +27,8 @@ static void kexec_halt_all_cpus(void *); 38.61 + 38.62 + typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long); 38.63 + 38.64 +-const extern unsigned char relocate_kernel[]; 38.65 +-const extern unsigned long long relocate_kernel_len; 38.66 ++extern const unsigned char relocate_kernel[]; 38.67 ++extern const unsigned long long relocate_kernel_len; 38.68 + 38.69 + int 38.70 + machine_kexec_prepare(struct kimage *image) 38.71 +--- a/arch/sh/kernel/machine_kexec.c 38.72 ++++ b/arch/sh/kernel/machine_kexec.c 38.73 +@@ -25,8 +25,8 @@ typedef NORET_TYPE void (*relocate_new_k 38.74 + unsigned long start_address, 38.75 + unsigned long vbr_reg) ATTRIB_NORET; 38.76 + 38.77 +-const extern unsigned char relocate_new_kernel[]; 38.78 +-const extern unsigned int relocate_new_kernel_size; 38.79 ++extern const unsigned char relocate_new_kernel[]; 38.80 ++extern const unsigned int relocate_new_kernel_size; 38.81 + extern void *gdb_vbr_vector; 38.82 + 38.83 + /* 38.84 +--- a/arch/x86_64/kernel/machine_kexec.c 38.85 ++++ b/arch/x86_64/kernel/machine_kexec.c 38.86 +@@ -149,8 +149,8 @@ typedef NORET_TYPE void (*relocate_new_k 38.87 + unsigned long start_address, 38.88 + unsigned long pgtable) ATTRIB_NORET; 38.89 + 38.90 +-const extern unsigned char relocate_new_kernel[]; 38.91 +-const extern unsigned long relocate_new_kernel_size; 38.92 ++extern const unsigned char relocate_new_kernel[]; 38.93 ++extern const unsigned long relocate_new_kernel_size; 38.94 + 38.95 + int machine_kexec_prepare(struct kimage *image) 38.96 + {
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch Mon Dec 04 08:24:41 2006 -0700 39.3 @@ -0,0 +1,401 @@ 39.4 +From: Magnus Damm <magnus@valinux.co.jp> 39.5 +Date: Tue, 26 Sep 2006 08:52:38 +0000 (+0200) 39.6 +Subject: [PATCH] i386: Avoid overwriting the current pgd (V4, i386) 39.7 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3566561bfadffcb5dbc85d576be80c0dbf2cccc9 39.8 + 39.9 +[PATCH] i386: Avoid overwriting the current pgd (V4, i386) 39.10 + 39.11 +kexec: Avoid overwriting the current pgd (V4, i386) 39.12 + 39.13 +This patch upgrades the i386-specific kexec code to avoid overwriting the 39.14 +current pgd. Overwriting the current pgd is bad when CONFIG_CRASH_DUMP is used 39.15 +to start a secondary kernel that dumps the memory of the previous kernel. 39.16 + 39.17 +The code introduces a new set of page tables. These tables are used to provide 39.18 +an executable identity mapping without overwriting the current pgd. 39.19 + 39.20 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp> 39.21 +Signed-off-by: Andi Kleen <ak@suse.de> 39.22 +--- 39.23 + 39.24 +--- a/arch/i386/kernel/machine_kexec.c 39.25 ++++ b/arch/i386/kernel/machine_kexec.c 39.26 +@@ -21,70 +21,13 @@ 39.27 + #include <asm/system.h> 39.28 + 39.29 + #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) 39.30 +- 39.31 +-#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 39.32 +-#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 39.33 +-#define L2_ATTR (_PAGE_PRESENT) 39.34 +- 39.35 +-#define LEVEL0_SIZE (1UL << 12UL) 39.36 +- 39.37 +-#ifndef CONFIG_X86_PAE 39.38 +-#define LEVEL1_SIZE (1UL << 22UL) 39.39 +-static u32 pgtable_level1[1024] PAGE_ALIGNED; 39.40 +- 39.41 +-static void identity_map_page(unsigned long address) 39.42 +-{ 39.43 +- unsigned long level1_index, level2_index; 39.44 +- u32 *pgtable_level2; 39.45 +- 39.46 +- /* Find the current page table */ 39.47 +- pgtable_level2 = __va(read_cr3()); 39.48 +- 39.49 +- /* Find the indexes of the physical address to identity map */ 39.50 +- level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; 39.51 +- level2_index = address / LEVEL1_SIZE; 39.52 +- 39.53 +- /* Identity map the page table entry */ 39.54 +- pgtable_level1[level1_index] = address | L0_ATTR; 39.55 +- pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; 39.56 +- 39.57 +- /* Flush the tlb so the new mapping takes effect. 39.58 +- * Global tlb entries are not flushed but that is not an issue. 39.59 +- */ 39.60 +- load_cr3(pgtable_level2); 39.61 +-} 39.62 +- 39.63 +-#else 39.64 +-#define LEVEL1_SIZE (1UL << 21UL) 39.65 +-#define LEVEL2_SIZE (1UL << 30UL) 39.66 +-static u64 pgtable_level1[512] PAGE_ALIGNED; 39.67 +-static u64 pgtable_level2[512] PAGE_ALIGNED; 39.68 +- 39.69 +-static void identity_map_page(unsigned long address) 39.70 +-{ 39.71 +- unsigned long level1_index, level2_index, level3_index; 39.72 +- u64 *pgtable_level3; 39.73 +- 39.74 +- /* Find the current page table */ 39.75 +- pgtable_level3 = __va(read_cr3()); 39.76 +- 39.77 +- /* Find the indexes of the physical address to identity map */ 39.78 +- level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; 39.79 +- level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE; 39.80 +- level3_index = address / LEVEL2_SIZE; 39.81 +- 39.82 +- /* Identity map the page table entry */ 39.83 +- pgtable_level1[level1_index] = address | L0_ATTR; 39.84 +- pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; 39.85 +- set_64bit(&pgtable_level3[level3_index], 39.86 +- __pa(pgtable_level2) | L2_ATTR); 39.87 +- 39.88 +- /* Flush the tlb so the new mapping takes effect. 39.89 +- * Global tlb entries are not flushed but that is not an issue. 39.90 +- */ 39.91 +- load_cr3(pgtable_level3); 39.92 +-} 39.93 ++static u32 kexec_pgd[1024] PAGE_ALIGNED; 39.94 ++#ifdef CONFIG_X86_PAE 39.95 ++static u32 kexec_pmd0[1024] PAGE_ALIGNED; 39.96 ++static u32 kexec_pmd1[1024] PAGE_ALIGNED; 39.97 + #endif 39.98 ++static u32 kexec_pte0[1024] PAGE_ALIGNED; 39.99 ++static u32 kexec_pte1[1024] PAGE_ALIGNED; 39.100 + 39.101 + static void set_idt(void *newidt, __u16 limit) 39.102 + { 39.103 +@@ -128,16 +71,6 @@ static void load_segments(void) 39.104 + #undef __STR 39.105 + } 39.106 + 39.107 +-typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( 39.108 +- unsigned long indirection_page, 39.109 +- unsigned long reboot_code_buffer, 39.110 +- unsigned long start_address, 39.111 +- unsigned int has_pae) ATTRIB_NORET; 39.112 +- 39.113 +-extern const unsigned char relocate_new_kernel[]; 39.114 +-extern void relocate_new_kernel_end(void); 39.115 +-extern const unsigned int relocate_new_kernel_size; 39.116 +- 39.117 + /* 39.118 + * A architecture hook called to validate the 39.119 + * proposed image and prepare the control pages 39.120 +@@ -170,25 +103,29 @@ void machine_kexec_cleanup(struct kimage 39.121 + */ 39.122 + NORET_TYPE void machine_kexec(struct kimage *image) 39.123 + { 39.124 +- unsigned long page_list; 39.125 +- unsigned long reboot_code_buffer; 39.126 +- 39.127 +- relocate_new_kernel_t rnk; 39.128 ++ unsigned long page_list[PAGES_NR]; 39.129 ++ void *control_page; 39.130 + 39.131 + /* Interrupts aren't acceptable while we reboot */ 39.132 + local_irq_disable(); 39.133 + 39.134 +- /* Compute some offsets */ 39.135 +- reboot_code_buffer = page_to_pfn(image->control_code_page) 39.136 +- << PAGE_SHIFT; 39.137 +- page_list = image->head; 39.138 +- 39.139 +- /* Set up an identity mapping for the reboot_code_buffer */ 39.140 +- identity_map_page(reboot_code_buffer); 39.141 +- 39.142 +- /* copy it out */ 39.143 +- memcpy((void *)reboot_code_buffer, relocate_new_kernel, 39.144 +- relocate_new_kernel_size); 39.145 ++ control_page = page_address(image->control_code_page); 39.146 ++ memcpy(control_page, relocate_kernel, PAGE_SIZE); 39.147 ++ 39.148 ++ page_list[PA_CONTROL_PAGE] = __pa(control_page); 39.149 ++ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; 39.150 ++ page_list[PA_PGD] = __pa(kexec_pgd); 39.151 ++ page_list[VA_PGD] = (unsigned long)kexec_pgd; 39.152 ++#ifdef CONFIG_X86_PAE 39.153 ++ page_list[PA_PMD_0] = __pa(kexec_pmd0); 39.154 ++ page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; 39.155 ++ page_list[PA_PMD_1] = __pa(kexec_pmd1); 39.156 ++ page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; 39.157 ++#endif 39.158 ++ page_list[PA_PTE_0] = __pa(kexec_pte0); 39.159 ++ page_list[VA_PTE_0] = (unsigned long)kexec_pte0; 39.160 ++ page_list[PA_PTE_1] = __pa(kexec_pte1); 39.161 ++ page_list[VA_PTE_1] = (unsigned long)kexec_pte1; 39.162 + 39.163 + /* The segment registers are funny things, they have both a 39.164 + * visible and an invisible part. Whenever the visible part is 39.165 +@@ -207,8 +144,8 @@ NORET_TYPE void machine_kexec(struct kim 39.166 + set_idt(phys_to_virt(0),0); 39.167 + 39.168 + /* now call it */ 39.169 +- rnk = (relocate_new_kernel_t) reboot_code_buffer; 39.170 +- (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); 39.171 ++ relocate_kernel((unsigned long)image->head, (unsigned long)page_list, 39.172 ++ image->start, cpu_has_pae); 39.173 + } 39.174 + 39.175 + /* crashkernel=size@addr specifies the location to reserve for 39.176 +--- a/arch/i386/kernel/relocate_kernel.S 39.177 ++++ b/arch/i386/kernel/relocate_kernel.S 39.178 +@@ -7,16 +7,138 @@ 39.179 + */ 39.180 + 39.181 + #include <linux/linkage.h> 39.182 ++#include <asm/page.h> 39.183 ++#include <asm/kexec.h> 39.184 ++ 39.185 ++/* 39.186 ++ * Must be relocatable PIC code callable as a C function 39.187 ++ */ 39.188 ++ 39.189 ++#define PTR(x) (x << 2) 39.190 ++#define PAGE_ALIGNED (1 << PAGE_SHIFT) 39.191 ++#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */ 39.192 ++#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */ 39.193 ++ 39.194 ++ .text 39.195 ++ .align PAGE_ALIGNED 39.196 ++ .globl relocate_kernel 39.197 ++relocate_kernel: 39.198 ++ movl 8(%esp), %ebp /* list of pages */ 39.199 ++ 39.200 ++#ifdef CONFIG_X86_PAE 39.201 ++ /* map the control page at its virtual address */ 39.202 ++ 39.203 ++ movl PTR(VA_PGD)(%ebp), %edi 39.204 ++ movl PTR(VA_CONTROL_PAGE)(%ebp), %eax 39.205 ++ andl $0xc0000000, %eax 39.206 ++ shrl $27, %eax 39.207 ++ addl %edi, %eax 39.208 ++ 39.209 ++ movl PTR(PA_PMD_0)(%ebp), %edx 39.210 ++ orl $PAE_PGD_ATTR, %edx 39.211 ++ movl %edx, (%eax) 39.212 ++ 39.213 ++ movl PTR(VA_PMD_0)(%ebp), %edi 39.214 ++ movl PTR(VA_CONTROL_PAGE)(%ebp), %eax 39.215 ++ andl $0x3fe00000, %eax 39.216 ++ shrl $18, %eax 39.217 ++ addl %edi, %eax 39.218 ++ 39.219 ++ movl PTR(PA_PTE_0)(%ebp), %edx 39.220 ++ orl $PAGE_ATTR, %edx 39.221 ++ movl %edx, (%eax) 39.222 ++ 39.223 ++ movl PTR(VA_PTE_0)(%ebp), %edi 39.224 ++ movl PTR(VA_CONTROL_PAGE)(%ebp), %eax 39.225 ++ andl $0x001ff000, %eax 39.226 ++ shrl $9, %eax 39.227 ++ addl %edi, %eax 39.228 ++ 39.229 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %edx 39.230 ++ orl $PAGE_ATTR, %edx 39.231 ++ movl %edx, (%eax) 39.232 ++ 39.233 ++ /* identity map the control page at its physical address */ 39.234 ++ 39.235 ++ movl PTR(VA_PGD)(%ebp), %edi 39.236 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %eax 39.237 ++ andl $0xc0000000, %eax 39.238 ++ shrl $27, %eax 39.239 ++ addl %edi, %eax 39.240 ++ 39.241 ++ movl PTR(PA_PMD_1)(%ebp), %edx 39.242 ++ orl $PAE_PGD_ATTR, %edx 39.243 ++ movl %edx, (%eax) 39.244 ++ 39.245 ++ movl PTR(VA_PMD_1)(%ebp), %edi 39.246 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %eax 39.247 ++ andl $0x3fe00000, %eax 39.248 ++ shrl $18, %eax 39.249 ++ addl %edi, %eax 39.250 ++ 39.251 ++ movl PTR(PA_PTE_1)(%ebp), %edx 39.252 ++ orl $PAGE_ATTR, %edx 39.253 ++ movl %edx, (%eax) 39.254 ++ 39.255 ++ movl PTR(VA_PTE_1)(%ebp), %edi 39.256 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %eax 39.257 ++ andl $0x001ff000, %eax 39.258 ++ shrl $9, %eax 39.259 ++ addl %edi, %eax 39.260 ++ 39.261 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %edx 39.262 ++ orl $PAGE_ATTR, %edx 39.263 ++ movl %edx, (%eax) 39.264 ++#else 39.265 ++ /* map the control page at its virtual address */ 39.266 ++ 39.267 ++ movl PTR(VA_PGD)(%ebp), %edi 39.268 ++ movl PTR(VA_CONTROL_PAGE)(%ebp), %eax 39.269 ++ andl $0xffc00000, %eax 39.270 ++ shrl $20, %eax 39.271 ++ addl %edi, %eax 39.272 ++ 39.273 ++ movl PTR(PA_PTE_0)(%ebp), %edx 39.274 ++ orl $PAGE_ATTR, %edx 39.275 ++ movl %edx, (%eax) 39.276 ++ 39.277 ++ movl PTR(VA_PTE_0)(%ebp), %edi 39.278 ++ movl PTR(VA_CONTROL_PAGE)(%ebp), %eax 39.279 ++ andl $0x003ff000, %eax 39.280 ++ shrl $10, %eax 39.281 ++ addl %edi, %eax 39.282 ++ 39.283 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %edx 39.284 ++ orl $PAGE_ATTR, %edx 39.285 ++ movl %edx, (%eax) 39.286 ++ 39.287 ++ /* identity map the control page at its physical address */ 39.288 ++ 39.289 ++ movl PTR(VA_PGD)(%ebp), %edi 39.290 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %eax 39.291 ++ andl $0xffc00000, %eax 39.292 ++ shrl $20, %eax 39.293 ++ addl %edi, %eax 39.294 ++ 39.295 ++ movl PTR(PA_PTE_1)(%ebp), %edx 39.296 ++ orl $PAGE_ATTR, %edx 39.297 ++ movl %edx, (%eax) 39.298 ++ 39.299 ++ movl PTR(VA_PTE_1)(%ebp), %edi 39.300 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %eax 39.301 ++ andl $0x003ff000, %eax 39.302 ++ shrl $10, %eax 39.303 ++ addl %edi, %eax 39.304 ++ 39.305 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %edx 39.306 ++ orl $PAGE_ATTR, %edx 39.307 ++ movl %edx, (%eax) 39.308 ++#endif 39.309 + 39.310 +- /* 39.311 +- * Must be relocatable PIC code callable as a C function, that once 39.312 +- * it starts can not use the previous processes stack. 39.313 +- */ 39.314 +- .globl relocate_new_kernel 39.315 + relocate_new_kernel: 39.316 + /* read the arguments and say goodbye to the stack */ 39.317 + movl 4(%esp), %ebx /* page_list */ 39.318 +- movl 8(%esp), %ebp /* reboot_code_buffer */ 39.319 ++ movl 8(%esp), %ebp /* list of pages */ 39.320 + movl 12(%esp), %edx /* start address */ 39.321 + movl 16(%esp), %ecx /* cpu_has_pae */ 39.322 + 39.323 +@@ -24,11 +146,26 @@ relocate_new_kernel: 39.324 + pushl $0 39.325 + popfl 39.326 + 39.327 +- /* set a new stack at the bottom of our page... */ 39.328 +- lea 4096(%ebp), %esp 39.329 ++ /* get physical address of control page now */ 39.330 ++ /* this is impossible after page table switch */ 39.331 ++ movl PTR(PA_CONTROL_PAGE)(%ebp), %edi 39.332 ++ 39.333 ++ /* switch to new set of page tables */ 39.334 ++ movl PTR(PA_PGD)(%ebp), %eax 39.335 ++ movl %eax, %cr3 39.336 ++ 39.337 ++ /* setup a new stack at the end of the physical control page */ 39.338 ++ lea 4096(%edi), %esp 39.339 + 39.340 +- /* store the parameters back on the stack */ 39.341 +- pushl %edx /* store the start address */ 39.342 ++ /* jump to identity mapped page */ 39.343 ++ movl %edi, %eax 39.344 ++ addl $(identity_mapped - relocate_kernel), %eax 39.345 ++ pushl %eax 39.346 ++ ret 39.347 ++ 39.348 ++identity_mapped: 39.349 ++ /* store the start address on the stack */ 39.350 ++ pushl %edx 39.351 + 39.352 + /* Set cr0 to a known state: 39.353 + * 31 0 == Paging disabled 39.354 +@@ -113,8 +250,3 @@ relocate_new_kernel: 39.355 + xorl %edi, %edi 39.356 + xorl %ebp, %ebp 39.357 + ret 39.358 +-relocate_new_kernel_end: 39.359 +- 39.360 +- .globl relocate_new_kernel_size 39.361 +-relocate_new_kernel_size: 39.362 +- .long relocate_new_kernel_end - relocate_new_kernel 39.363 +--- a/include/asm-i386/kexec.h 39.364 ++++ b/include/asm-i386/kexec.h 39.365 +@@ -1,6 +1,26 @@ 39.366 + #ifndef _I386_KEXEC_H 39.367 + #define _I386_KEXEC_H 39.368 + 39.369 ++#define PA_CONTROL_PAGE 0 39.370 ++#define VA_CONTROL_PAGE 1 39.371 ++#define PA_PGD 2 39.372 ++#define VA_PGD 3 39.373 ++#define PA_PTE_0 4 39.374 ++#define VA_PTE_0 5 39.375 ++#define PA_PTE_1 6 39.376 ++#define VA_PTE_1 7 39.377 ++#ifdef CONFIG_X86_PAE 39.378 ++#define PA_PMD_0 8 39.379 ++#define VA_PMD_0 9 39.380 ++#define PA_PMD_1 10 39.381 ++#define VA_PMD_1 11 39.382 ++#define PAGES_NR 12 39.383 ++#else 39.384 ++#define PAGES_NR 8 39.385 ++#endif 39.386 ++ 39.387 ++#ifndef __ASSEMBLY__ 39.388 ++ 39.389 + #include <asm/fixmap.h> 39.390 + #include <asm/ptrace.h> 39.391 + #include <asm/string.h> 39.392 +@@ -72,5 +92,12 @@ static inline void crash_setup_regs(stru 39.393 + newregs->eip = (unsigned long)current_text_addr(); 39.394 + } 39.395 + } 39.396 ++asmlinkage NORET_TYPE void 39.397 ++relocate_kernel(unsigned long indirection_page, 39.398 ++ unsigned long control_page, 39.399 ++ unsigned long start_address, 39.400 ++ unsigned int has_pae) ATTRIB_NORET; 39.401 ++ 39.402 ++#endif /* __ASSEMBLY__ */ 39.403 + 39.404 + #endif /* _I386_KEXEC_H */
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch Mon Dec 04 08:24:41 2006 -0700 40.3 @@ -0,0 +1,375 @@ 40.4 +From: Magnus Damm <magnus@valinux.co.jp> 40.5 +Date: Tue, 26 Sep 2006 08:52:38 +0000 (+0200) 40.6 +Subject: [PATCH] Avoid overwriting the current pgd (V4, x86_64) 40.7 +X-Git-Tag: v2.6.19-rc1 40.8 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f 40.9 + 40.10 +[PATCH] Avoid overwriting the current pgd (V4, x86_64) 40.11 + 40.12 +kexec: Avoid overwriting the current pgd (V4, x86_64) 40.13 + 40.14 +This patch upgrades the x86_64-specific kexec code to avoid overwriting the 40.15 +current pgd. Overwriting the current pgd is bad when CONFIG_CRASH_DUMP is used 40.16 +to start a secondary kernel that dumps the memory of the previous kernel. 40.17 + 40.18 +The code introduces a new set of page tables. These tables are used to provide 40.19 +an executable identity mapping without overwriting the current pgd. 40.20 + 40.21 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp> 40.22 +Signed-off-by: Andi Kleen <ak@suse.de> 40.23 +--- 40.24 + 40.25 +--- a/arch/x86_64/kernel/machine_kexec.c 40.26 ++++ b/arch/x86_64/kernel/machine_kexec.c 40.27 +@@ -15,6 +15,15 @@ 40.28 + #include <asm/mmu_context.h> 40.29 + #include <asm/io.h> 40.30 + 40.31 ++#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) 40.32 ++static u64 kexec_pgd[512] PAGE_ALIGNED; 40.33 ++static u64 kexec_pud0[512] PAGE_ALIGNED; 40.34 ++static u64 kexec_pmd0[512] PAGE_ALIGNED; 40.35 ++static u64 kexec_pte0[512] PAGE_ALIGNED; 40.36 ++static u64 kexec_pud1[512] PAGE_ALIGNED; 40.37 ++static u64 kexec_pmd1[512] PAGE_ALIGNED; 40.38 ++static u64 kexec_pte1[512] PAGE_ALIGNED; 40.39 ++ 40.40 + static void init_level2_page(pmd_t *level2p, unsigned long addr) 40.41 + { 40.42 + unsigned long end_addr; 40.43 +@@ -144,32 +153,19 @@ static void load_segments(void) 40.44 + ); 40.45 + } 40.46 + 40.47 +-typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, 40.48 +- unsigned long control_code_buffer, 40.49 +- unsigned long start_address, 40.50 +- unsigned long pgtable) ATTRIB_NORET; 40.51 +- 40.52 +-extern const unsigned char relocate_new_kernel[]; 40.53 +-extern const unsigned long relocate_new_kernel_size; 40.54 +- 40.55 + int machine_kexec_prepare(struct kimage *image) 40.56 + { 40.57 +- unsigned long start_pgtable, control_code_buffer; 40.58 ++ unsigned long start_pgtable; 40.59 + int result; 40.60 + 40.61 + /* Calculate the offsets */ 40.62 + start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; 40.63 +- control_code_buffer = start_pgtable + PAGE_SIZE; 40.64 + 40.65 + /* Setup the identity mapped 64bit page table */ 40.66 + result = init_pgtable(image, start_pgtable); 40.67 + if (result) 40.68 + return result; 40.69 + 40.70 +- /* Place the code in the reboot code buffer */ 40.71 +- memcpy(__va(control_code_buffer), relocate_new_kernel, 40.72 +- relocate_new_kernel_size); 40.73 +- 40.74 + return 0; 40.75 + } 40.76 + 40.77 +@@ -184,28 +180,34 @@ void machine_kexec_cleanup(struct kimage 40.78 + */ 40.79 + NORET_TYPE void machine_kexec(struct kimage *image) 40.80 + { 40.81 +- unsigned long page_list; 40.82 +- unsigned long control_code_buffer; 40.83 +- unsigned long start_pgtable; 40.84 +- relocate_new_kernel_t rnk; 40.85 ++ unsigned long page_list[PAGES_NR]; 40.86 ++ void *control_page; 40.87 + 40.88 + /* Interrupts aren't acceptable while we reboot */ 40.89 + local_irq_disable(); 40.90 + 40.91 +- /* Calculate the offsets */ 40.92 +- page_list = image->head; 40.93 +- start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; 40.94 +- control_code_buffer = start_pgtable + PAGE_SIZE; 40.95 ++ control_page = page_address(image->control_code_page) + PAGE_SIZE; 40.96 ++ memcpy(control_page, relocate_kernel, PAGE_SIZE); 40.97 + 40.98 +- /* Set the low half of the page table to my identity mapped 40.99 +- * page table for kexec. Leave the high half pointing at the 40.100 +- * kernel pages. Don't bother to flush the global pages 40.101 +- * as that will happen when I fully switch to my identity mapped 40.102 +- * page table anyway. 40.103 +- */ 40.104 +- memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2); 40.105 +- __flush_tlb(); 40.106 ++ page_list[PA_CONTROL_PAGE] = __pa(control_page); 40.107 ++ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; 40.108 ++ page_list[PA_PGD] = __pa(kexec_pgd); 40.109 ++ page_list[VA_PGD] = (unsigned long)kexec_pgd; 40.110 ++ page_list[PA_PUD_0] = __pa(kexec_pud0); 40.111 ++ page_list[VA_PUD_0] = (unsigned long)kexec_pud0; 40.112 ++ page_list[PA_PMD_0] = __pa(kexec_pmd0); 40.113 ++ page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; 40.114 ++ page_list[PA_PTE_0] = __pa(kexec_pte0); 40.115 ++ page_list[VA_PTE_0] = (unsigned long)kexec_pte0; 40.116 ++ page_list[PA_PUD_1] = __pa(kexec_pud1); 40.117 ++ page_list[VA_PUD_1] = (unsigned long)kexec_pud1; 40.118 ++ page_list[PA_PMD_1] = __pa(kexec_pmd1); 40.119 ++ page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; 40.120 ++ page_list[PA_PTE_1] = __pa(kexec_pte1); 40.121 ++ page_list[VA_PTE_1] = (unsigned long)kexec_pte1; 40.122 + 40.123 ++ page_list[PA_TABLE_PAGE] = 40.124 ++ (unsigned long)__pa(page_address(image->control_code_page)); 40.125 + 40.126 + /* The segment registers are funny things, they have both a 40.127 + * visible and an invisible part. Whenever the visible part is 40.128 +@@ -222,9 +224,10 @@ NORET_TYPE void machine_kexec(struct kim 40.129 + */ 40.130 + set_gdt(phys_to_virt(0),0); 40.131 + set_idt(phys_to_virt(0),0); 40.132 ++ 40.133 + /* now call it */ 40.134 +- rnk = (relocate_new_kernel_t) control_code_buffer; 40.135 +- (*rnk)(page_list, control_code_buffer, image->start, start_pgtable); 40.136 ++ relocate_kernel((unsigned long)image->head, (unsigned long)page_list, 40.137 ++ image->start); 40.138 + } 40.139 + 40.140 + /* crashkernel=size@addr specifies the location to reserve for 40.141 +--- a/arch/x86_64/kernel/relocate_kernel.S 40.142 ++++ b/arch/x86_64/kernel/relocate_kernel.S 40.143 +@@ -7,31 +7,169 @@ 40.144 + */ 40.145 + 40.146 + #include <linux/linkage.h> 40.147 ++#include <asm/page.h> 40.148 ++#include <asm/kexec.h> 40.149 + 40.150 +- /* 40.151 +- * Must be relocatable PIC code callable as a C function, that once 40.152 +- * it starts can not use the previous processes stack. 40.153 +- */ 40.154 +- .globl relocate_new_kernel 40.155 ++/* 40.156 ++ * Must be relocatable PIC code callable as a C function 40.157 ++ */ 40.158 ++ 40.159 ++#define PTR(x) (x << 3) 40.160 ++#define PAGE_ALIGNED (1 << PAGE_SHIFT) 40.161 ++#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */ 40.162 ++ 40.163 ++ .text 40.164 ++ .align PAGE_ALIGNED 40.165 + .code64 40.166 ++ .globl relocate_kernel 40.167 ++relocate_kernel: 40.168 ++ /* %rdi indirection_page 40.169 ++ * %rsi page_list 40.170 ++ * %rdx start address 40.171 ++ */ 40.172 ++ 40.173 ++ /* map the control page at its virtual address */ 40.174 ++ 40.175 ++ movq $0x0000ff8000000000, %r10 /* mask */ 40.176 ++ mov $(39 - 3), %cl /* bits to shift */ 40.177 ++ movq PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */ 40.178 ++ 40.179 ++ movq %r11, %r9 40.180 ++ andq %r10, %r9 40.181 ++ shrq %cl, %r9 40.182 ++ 40.183 ++ movq PTR(VA_PGD)(%rsi), %r8 40.184 ++ addq %r8, %r9 40.185 ++ movq PTR(PA_PUD_0)(%rsi), %r8 40.186 ++ orq $PAGE_ATTR, %r8 40.187 ++ movq %r8, (%r9) 40.188 ++ 40.189 ++ shrq $9, %r10 40.190 ++ sub $9, %cl 40.191 ++ 40.192 ++ movq %r11, %r9 40.193 ++ andq %r10, %r9 40.194 ++ shrq %cl, %r9 40.195 ++ 40.196 ++ movq PTR(VA_PUD_0)(%rsi), %r8 40.197 ++ addq %r8, %r9 40.198 ++ movq PTR(PA_PMD_0)(%rsi), %r8 40.199 ++ orq $PAGE_ATTR, %r8 40.200 ++ movq %r8, (%r9) 40.201 ++ 40.202 ++ shrq $9, %r10 40.203 ++ sub $9, %cl 40.204 ++ 40.205 ++ movq %r11, %r9 40.206 ++ andq %r10, %r9 40.207 ++ shrq %cl, %r9 40.208 ++ 40.209 ++ movq PTR(VA_PMD_0)(%rsi), %r8 40.210 ++ addq %r8, %r9 40.211 ++ movq PTR(PA_PTE_0)(%rsi), %r8 40.212 ++ orq $PAGE_ATTR, %r8 40.213 ++ movq %r8, (%r9) 40.214 ++ 40.215 ++ shrq $9, %r10 40.216 ++ sub $9, %cl 40.217 ++ 40.218 ++ movq %r11, %r9 40.219 ++ andq %r10, %r9 40.220 ++ shrq %cl, %r9 40.221 ++ 40.222 ++ movq PTR(VA_PTE_0)(%rsi), %r8 40.223 ++ addq %r8, %r9 40.224 ++ movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 40.225 ++ orq $PAGE_ATTR, %r8 40.226 ++ movq %r8, (%r9) 40.227 ++ 40.228 ++ /* identity map the control page at its physical address */ 40.229 ++ 40.230 ++ movq $0x0000ff8000000000, %r10 /* mask */ 40.231 ++ mov $(39 - 3), %cl /* bits to shift */ 40.232 ++ movq PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */ 40.233 ++ 40.234 ++ movq %r11, %r9 40.235 ++ andq %r10, %r9 40.236 ++ shrq %cl, %r9 40.237 ++ 40.238 ++ movq PTR(VA_PGD)(%rsi), %r8 40.239 ++ addq %r8, %r9 40.240 ++ movq PTR(PA_PUD_1)(%rsi), %r8 40.241 ++ orq $PAGE_ATTR, %r8 40.242 ++ movq %r8, (%r9) 40.243 ++ 40.244 ++ shrq $9, %r10 40.245 ++ sub $9, %cl 40.246 ++ 40.247 ++ movq %r11, %r9 40.248 ++ andq %r10, %r9 40.249 ++ shrq %cl, %r9 40.250 ++ 40.251 ++ movq PTR(VA_PUD_1)(%rsi), %r8 40.252 ++ addq %r8, %r9 40.253 ++ movq PTR(PA_PMD_1)(%rsi), %r8 40.254 ++ orq $PAGE_ATTR, %r8 40.255 ++ movq %r8, (%r9) 40.256 ++ 40.257 ++ shrq $9, %r10 40.258 ++ sub $9, %cl 40.259 ++ 40.260 ++ movq %r11, %r9 40.261 ++ andq %r10, %r9 40.262 ++ shrq %cl, %r9 40.263 ++ 40.264 ++ movq PTR(VA_PMD_1)(%rsi), %r8 40.265 ++ addq %r8, %r9 40.266 ++ movq PTR(PA_PTE_1)(%rsi), %r8 40.267 ++ orq $PAGE_ATTR, %r8 40.268 ++ movq %r8, (%r9) 40.269 ++ 40.270 ++ shrq $9, %r10 40.271 ++ sub $9, %cl 40.272 ++ 40.273 ++ movq %r11, %r9 40.274 ++ andq %r10, %r9 40.275 ++ shrq %cl, %r9 40.276 ++ 40.277 ++ movq PTR(VA_PTE_1)(%rsi), %r8 40.278 ++ addq %r8, %r9 40.279 ++ movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 40.280 ++ orq $PAGE_ATTR, %r8 40.281 ++ movq %r8, (%r9) 40.282 ++ 40.283 + relocate_new_kernel: 40.284 +- /* %rdi page_list 40.285 +- * %rsi reboot_code_buffer 40.286 ++ /* %rdi indirection_page 40.287 ++ * %rsi page_list 40.288 + * %rdx start address 40.289 +- * %rcx page_table 40.290 +- * %r8 arg5 40.291 +- * %r9 arg6 40.292 + */ 40.293 + 40.294 + /* zero out flags, and disable interrupts */ 40.295 + pushq $0 40.296 + popfq 40.297 + 40.298 +- /* set a new stack at the bottom of our page... */ 40.299 +- lea 4096(%rsi), %rsp 40.300 ++ /* get physical address of control page now */ 40.301 ++ /* this is impossible after page table switch */ 40.302 ++ movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 40.303 ++ 40.304 ++ /* get physical address of page table now too */ 40.305 ++ movq PTR(PA_TABLE_PAGE)(%rsi), %rcx 40.306 ++ 40.307 ++ /* switch to new set of page tables */ 40.308 ++ movq PTR(PA_PGD)(%rsi), %r9 40.309 ++ movq %r9, %cr3 40.310 ++ 40.311 ++ /* setup a new stack at the end of the physical control page */ 40.312 ++ lea 4096(%r8), %rsp 40.313 ++ 40.314 ++ /* jump to identity mapped page */ 40.315 ++ addq $(identity_mapped - relocate_kernel), %r8 40.316 ++ pushq %r8 40.317 ++ ret 40.318 + 40.319 +- /* store the parameters back on the stack */ 40.320 +- pushq %rdx /* store the start address */ 40.321 ++identity_mapped: 40.322 ++ /* store the start address on the stack */ 40.323 ++ pushq %rdx 40.324 + 40.325 + /* Set cr0 to a known state: 40.326 + * 31 1 == Paging enabled 40.327 +@@ -136,8 +274,3 @@ relocate_new_kernel: 40.328 + xorq %r15, %r15 40.329 + 40.330 + ret 40.331 +-relocate_new_kernel_end: 40.332 +- 40.333 +- .globl relocate_new_kernel_size 40.334 +-relocate_new_kernel_size: 40.335 +- .quad relocate_new_kernel_end - relocate_new_kernel 40.336 +--- a/include/asm-x86_64/kexec.h 40.337 ++++ b/include/asm-x86_64/kexec.h 40.338 +@@ -1,6 +1,27 @@ 40.339 + #ifndef _X86_64_KEXEC_H 40.340 + #define _X86_64_KEXEC_H 40.341 + 40.342 ++#define PA_CONTROL_PAGE 0 40.343 ++#define VA_CONTROL_PAGE 1 40.344 ++#define PA_PGD 2 40.345 ++#define VA_PGD 3 40.346 ++#define PA_PUD_0 4 40.347 ++#define VA_PUD_0 5 40.348 ++#define PA_PMD_0 6 40.349 ++#define VA_PMD_0 7 40.350 ++#define PA_PTE_0 8 40.351 ++#define VA_PTE_0 9 40.352 ++#define PA_PUD_1 10 40.353 ++#define VA_PUD_1 11 40.354 ++#define PA_PMD_1 12 40.355 ++#define VA_PMD_1 13 40.356 ++#define PA_PTE_1 14 40.357 ++#define VA_PTE_1 15 40.358 ++#define PA_TABLE_PAGE 16 40.359 ++#define PAGES_NR 17 40.360 ++ 40.361 ++#ifndef __ASSEMBLY__ 40.362 ++ 40.363 + #include <linux/string.h> 40.364 + 40.365 + #include <asm/page.h> 40.366 +@@ -64,4 +85,12 @@ static inline void crash_setup_regs(stru 40.367 + newregs->rip = (unsigned long)current_text_addr(); 40.368 + } 40.369 + } 40.370 ++ 40.371 ++NORET_TYPE void 40.372 ++relocate_kernel(unsigned long indirection_page, 40.373 ++ unsigned long page_list, 40.374 ++ unsigned long start_address) ATTRIB_NORET; 40.375 ++ 40.376 ++#endif /* __ASSEMBLY__ */ 40.377 ++ 40.378 + #endif /* _X86_64_KEXEC_H */
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch Mon Dec 04 08:24:41 2006 -0700 41.3 @@ -0,0 +1,47 @@ 41.4 +commit dbaab49f92ff6ae6255762a948375e4036cbdbd2 41.5 +Author: Vivek Goyal <vgoyal@in.ibm.com> 41.6 +Date: Sat Oct 21 18:37:03 2006 +0200 41.7 + 41.8 + [PATCH] x86-64: Overlapping program headers in physical addr space fix 41.9 + 41.10 + o A recent change to vmlinux.ld.S file broke kexec as now resulting vmlinux 41.11 + program headers are overlapping in physical address space. 41.12 + 41.13 + o Now all the vsyscall related sections are placed after data and after 41.14 + that mostly init data sections are placed. To avoid physical overlap 41.15 + among phdrs, there are three possible solutions. 41.16 + - Place vsyscall sections also in data phdrs instead of user 41.17 + - move vsyscal sections after init data in bss. 41.18 + - create another phdrs say data.init and move all the sections 41.19 + after vsyscall into this new phdr. 41.20 + 41.21 + o This patch implements the third solution. 41.22 + 41.23 + Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> 41.24 + Signed-off-by: Andi Kleen <ak@suse.de> 41.25 + Cc: Magnus Damm <magnus@valinux.co.jp> 41.26 + Cc: Andi Kleen <ak@suse.de> 41.27 + Cc: "Eric W. Biederman" <ebiederm@xmission.com> 41.28 + Signed-off-by: Andrew Morton <akpm@osdl.org> 41.29 + 41.30 +diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S 41.31 +index b9df2ab..1283614 100644 41.32 +--- a/arch/x86_64/kernel/vmlinux.lds.S 41.33 ++++ b/arch/x86_64/kernel/vmlinux.lds.S 41.34 +@@ -17,6 +17,7 @@ PHDRS { 41.35 + text PT_LOAD FLAGS(5); /* R_E */ 41.36 + data PT_LOAD FLAGS(7); /* RWE */ 41.37 + user PT_LOAD FLAGS(7); /* RWE */ 41.38 ++ data.init PT_LOAD FLAGS(7); /* RWE */ 41.39 + note PT_NOTE FLAGS(4); /* R__ */ 41.40 + } 41.41 + SECTIONS 41.42 +@@ -131,7 +132,7 @@ SECTIONS 41.43 + . = ALIGN(8192); /* init_task */ 41.44 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { 41.45 + *(.data.init_task) 41.46 +- } :data 41.47 ++ }:data.init 41.48 + 41.49 + . = ALIGN(4096); 41.50 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/patches/linux-2.6.16.33/kexec-generic.patch Mon Dec 04 08:24:41 2006 -0700 42.3 @@ -0,0 +1,228 @@ 42.4 +--- 0001/include/linux/kexec.h 42.5 ++++ work/include/linux/kexec.h 42.6 +@@ -31,6 +31,13 @@ 42.7 + #error KEXEC_ARCH not defined 42.8 + #endif 42.9 + 42.10 ++#ifndef KEXEC_ARCH_HAS_PAGE_MACROS 42.11 ++#define kexec_page_to_pfn(page) page_to_pfn(page) 42.12 ++#define kexec_pfn_to_page(pfn) pfn_to_page(pfn) 42.13 ++#define kexec_virt_to_phys(addr) virt_to_phys(addr) 42.14 ++#define kexec_phys_to_virt(addr) phys_to_virt(addr) 42.15 ++#endif 42.16 ++ 42.17 + /* 42.18 + * This structure is used to hold the arguments that are used when loading 42.19 + * kernel binaries. 42.20 +@@ -91,6 +98,13 @@ struct kimage { 42.21 + extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; 42.22 + extern int machine_kexec_prepare(struct kimage *image); 42.23 + extern void machine_kexec_cleanup(struct kimage *image); 42.24 ++#ifdef CONFIG_XEN 42.25 ++extern int xen_machine_kexec_load(struct kimage *image); 42.26 ++extern void xen_machine_kexec_unload(struct kimage *image); 42.27 ++extern NORET_TYPE void xen_machine_kexec(struct kimage *image) ATTRIB_NORET; 42.28 ++extern void xen_machine_kexec_setup_resources(void); 42.29 ++extern void xen_machine_kexec_register_resources(struct resource *res); 42.30 ++#endif 42.31 + extern asmlinkage long sys_kexec_load(unsigned long entry, 42.32 + unsigned long nr_segments, 42.33 + struct kexec_segment __user *segments, 42.34 +--- 0001/kernel/kexec.c 42.35 ++++ work/kernel/kexec.c 42.36 +@@ -403,7 +403,7 @@ static struct page *kimage_alloc_normal_ 42.37 + pages = kimage_alloc_pages(GFP_KERNEL, order); 42.38 + if (!pages) 42.39 + break; 42.40 +- pfn = page_to_pfn(pages); 42.41 ++ pfn = kexec_page_to_pfn(pages); 42.42 + epfn = pfn + count; 42.43 + addr = pfn << PAGE_SHIFT; 42.44 + eaddr = epfn << PAGE_SHIFT; 42.45 +@@ -437,6 +437,7 @@ static struct page *kimage_alloc_normal_ 42.46 + return pages; 42.47 + } 42.48 + 42.49 ++#ifndef CONFIG_XEN 42.50 + static struct page *kimage_alloc_crash_control_pages(struct kimage *image, 42.51 + unsigned int order) 42.52 + { 42.53 +@@ -490,7 +491,7 @@ static struct page *kimage_alloc_crash_c 42.54 + } 42.55 + /* If I don't overlap any segments I have found my hole! */ 42.56 + if (i == image->nr_segments) { 42.57 +- pages = pfn_to_page(hole_start >> PAGE_SHIFT); 42.58 ++ pages = kexec_pfn_to_page(hole_start >> PAGE_SHIFT); 42.59 + break; 42.60 + } 42.61 + } 42.62 +@@ -517,6 +518,13 @@ struct page *kimage_alloc_control_pages( 42.63 + 42.64 + return pages; 42.65 + } 42.66 ++#else /* !CONFIG_XEN */ 42.67 ++struct page *kimage_alloc_control_pages(struct kimage *image, 42.68 ++ unsigned int order) 42.69 ++{ 42.70 ++ return kimage_alloc_normal_control_pages(image, order); 42.71 ++} 42.72 ++#endif 42.73 + 42.74 + static int kimage_add_entry(struct kimage *image, kimage_entry_t entry) 42.75 + { 42.76 +@@ -532,7 +540,7 @@ static int kimage_add_entry(struct kimag 42.77 + return -ENOMEM; 42.78 + 42.79 + ind_page = page_address(page); 42.80 +- *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION; 42.81 ++ *image->entry = kexec_virt_to_phys(ind_page) | IND_INDIRECTION; 42.82 + image->entry = ind_page; 42.83 + image->last_entry = ind_page + 42.84 + ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1); 42.85 +@@ -593,13 +601,13 @@ static int kimage_terminate(struct kimag 42.86 + #define for_each_kimage_entry(image, ptr, entry) \ 42.87 + for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \ 42.88 + ptr = (entry & IND_INDIRECTION)? \ 42.89 +- phys_to_virt((entry & PAGE_MASK)): ptr +1) 42.90 ++ kexec_phys_to_virt((entry & PAGE_MASK)): ptr +1) 42.91 + 42.92 + static void kimage_free_entry(kimage_entry_t entry) 42.93 + { 42.94 + struct page *page; 42.95 + 42.96 +- page = pfn_to_page(entry >> PAGE_SHIFT); 42.97 ++ page = kexec_pfn_to_page(entry >> PAGE_SHIFT); 42.98 + kimage_free_pages(page); 42.99 + } 42.100 + 42.101 +@@ -611,6 +619,10 @@ static void kimage_free(struct kimage *i 42.102 + if (!image) 42.103 + return; 42.104 + 42.105 ++#ifdef CONFIG_XEN 42.106 ++ xen_machine_kexec_unload(image); 42.107 ++#endif 42.108 ++ 42.109 + kimage_free_extra_pages(image); 42.110 + for_each_kimage_entry(image, ptr, entry) { 42.111 + if (entry & IND_INDIRECTION) { 42.112 +@@ -686,7 +698,7 @@ static struct page *kimage_alloc_page(st 42.113 + * have a match. 42.114 + */ 42.115 + list_for_each_entry(page, &image->dest_pages, lru) { 42.116 +- addr = page_to_pfn(page) << PAGE_SHIFT; 42.117 ++ addr = kexec_page_to_pfn(page) << PAGE_SHIFT; 42.118 + if (addr == destination) { 42.119 + list_del(&page->lru); 42.120 + return page; 42.121 +@@ -701,12 +713,12 @@ static struct page *kimage_alloc_page(st 42.122 + if (!page) 42.123 + return NULL; 42.124 + /* If the page cannot be used file it away */ 42.125 +- if (page_to_pfn(page) > 42.126 ++ if (kexec_page_to_pfn(page) > 42.127 + (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { 42.128 + list_add(&page->lru, &image->unuseable_pages); 42.129 + continue; 42.130 + } 42.131 +- addr = page_to_pfn(page) << PAGE_SHIFT; 42.132 ++ addr = kexec_page_to_pfn(page) << PAGE_SHIFT; 42.133 + 42.134 + /* If it is the destination page we want use it */ 42.135 + if (addr == destination) 42.136 +@@ -729,7 +741,7 @@ static struct page *kimage_alloc_page(st 42.137 + struct page *old_page; 42.138 + 42.139 + old_addr = *old & PAGE_MASK; 42.140 +- old_page = pfn_to_page(old_addr >> PAGE_SHIFT); 42.141 ++ old_page = kexec_pfn_to_page(old_addr >> PAGE_SHIFT); 42.142 + copy_highpage(page, old_page); 42.143 + *old = addr | (*old & ~PAGE_MASK); 42.144 + 42.145 +@@ -779,7 +791,7 @@ static int kimage_load_normal_segment(st 42.146 + result = -ENOMEM; 42.147 + goto out; 42.148 + } 42.149 +- result = kimage_add_page(image, page_to_pfn(page) 42.150 ++ result = kimage_add_page(image, kexec_page_to_pfn(page) 42.151 + << PAGE_SHIFT); 42.152 + if (result < 0) 42.153 + goto out; 42.154 +@@ -811,6 +823,7 @@ out: 42.155 + return result; 42.156 + } 42.157 + 42.158 ++#ifndef CONFIG_XEN 42.159 + static int kimage_load_crash_segment(struct kimage *image, 42.160 + struct kexec_segment *segment) 42.161 + { 42.162 +@@ -833,7 +846,7 @@ static int kimage_load_crash_segment(str 42.163 + char *ptr; 42.164 + size_t uchunk, mchunk; 42.165 + 42.166 +- page = pfn_to_page(maddr >> PAGE_SHIFT); 42.167 ++ page = kexec_pfn_to_page(maddr >> PAGE_SHIFT); 42.168 + if (page == 0) { 42.169 + result = -ENOMEM; 42.170 + goto out; 42.171 +@@ -881,6 +894,13 @@ static int kimage_load_segment(struct ki 42.172 + 42.173 + return result; 42.174 + } 42.175 ++#else /* CONFIG_XEN */ 42.176 ++static int kimage_load_segment(struct kimage *image, 42.177 ++ struct kexec_segment *segment) 42.178 ++{ 42.179 ++ return kimage_load_normal_segment(image, segment); 42.180 ++} 42.181 ++#endif 42.182 + 42.183 + /* 42.184 + * Exec Kernel system call: for obvious reasons only root may call it. 42.185 +@@ -991,6 +1011,11 @@ asmlinkage long sys_kexec_load(unsigned 42.186 + if (result) 42.187 + goto out; 42.188 + } 42.189 ++#ifdef CONFIG_XEN 42.190 ++ result = xen_machine_kexec_load(image); 42.191 ++ if (result) 42.192 ++ goto out; 42.193 ++#endif 42.194 + /* Install the new kernel, and Uninstall the old */ 42.195 + image = xchg(dest_image, image); 42.196 + 42.197 +@@ -1045,7 +1070,6 @@ void crash_kexec(struct pt_regs *regs) 42.198 + struct kimage *image; 42.199 + int locked; 42.200 + 42.201 +- 42.202 + /* Take the kexec_lock here to prevent sys_kexec_load 42.203 + * running on one cpu from replacing the crash kernel 42.204 + * we are using after a panic on a different cpu. 42.205 +@@ -1061,7 +1085,11 @@ void crash_kexec(struct pt_regs *regs) 42.206 + struct pt_regs fixed_regs; 42.207 + crash_setup_regs(&fixed_regs, regs); 42.208 + machine_crash_shutdown(&fixed_regs); 42.209 ++#ifdef CONFIG_XEN 42.210 ++ xen_machine_kexec(image); 42.211 ++#else 42.212 + machine_kexec(image); 42.213 ++#endif 42.214 + } 42.215 + xchg(&kexec_lock, 0); 42.216 + } 42.217 +--- 0002/kernel/sys.c 42.218 ++++ work/kernel/sys.c 42.219 +@@ -435,8 +435,12 @@ void kernel_kexec(void) 42.220 + kernel_restart_prepare(NULL); 42.221 + printk(KERN_EMERG "Starting new kernel\n"); 42.222 + machine_shutdown(); 42.223 ++#ifdef CONFIG_XEN 42.224 ++ xen_machine_kexec(image); 42.225 ++#else 42.226 + machine_kexec(image); 42.227 + #endif 42.228 ++#endif 42.229 + } 42.230 + EXPORT_SYMBOL_GPL(kernel_kexec); 42.231 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch Mon Dec 04 08:24:41 2006 -0700 43.3 @@ -0,0 +1,169 @@ 43.4 +kexec: Move asm segment handling code to the assembly file (i386) 43.5 + 43.6 +This patch moves the idt, gdt, and segment handling code from machine_kexec.c 43.7 +to relocate_kernel.S. The main reason behind this move is to avoid code 43.8 +duplication in the Xen hypervisor. With this patch all code required to kexec 43.9 +is put on the control page. 43.10 + 43.11 +On top of that this patch also counts as a cleanup - I think it is much 43.12 +nicer to write assembly directly in assembly files than wrap inline assembly 43.13 +in C functions for no apparent reason. 43.14 + 43.15 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp> 43.16 +--- 43.17 + 43.18 + Applies to 2.6.19-rc1. 43.19 + 43.20 + machine_kexec.c | 59 ----------------------------------------------------- 43.21 + relocate_kernel.S | 58 +++++++++++++++++++++++++++++++++++++++++++++++----- 43.22 + 2 files changed, 53 insertions(+), 64 deletions(-) 43.23 + 43.24 +--- 0002/arch/i386/kernel/machine_kexec.c 43.25 ++++ work/arch/i386/kernel/machine_kexec.c 2006-10-05 15:49:08.000000000 +0900 43.26 +@@ -29,48 +29,6 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED 43.27 + static u32 kexec_pte0[1024] PAGE_ALIGNED; 43.28 + static u32 kexec_pte1[1024] PAGE_ALIGNED; 43.29 + 43.30 +-static void set_idt(void *newidt, __u16 limit) 43.31 +-{ 43.32 +- struct Xgt_desc_struct curidt; 43.33 +- 43.34 +- /* ia32 supports unaliged loads & stores */ 43.35 +- curidt.size = limit; 43.36 +- curidt.address = (unsigned long)newidt; 43.37 +- 43.38 +- load_idt(&curidt); 43.39 +-}; 43.40 +- 43.41 +- 43.42 +-static void set_gdt(void *newgdt, __u16 limit) 43.43 +-{ 43.44 +- struct Xgt_desc_struct curgdt; 43.45 +- 43.46 +- /* ia32 supports unaligned loads & stores */ 43.47 +- curgdt.size = limit; 43.48 +- curgdt.address = (unsigned long)newgdt; 43.49 +- 43.50 +- load_gdt(&curgdt); 43.51 +-}; 43.52 +- 43.53 +-static void load_segments(void) 43.54 +-{ 43.55 +-#define __STR(X) #X 43.56 +-#define STR(X) __STR(X) 43.57 +- 43.58 +- __asm__ __volatile__ ( 43.59 +- "\tljmp $"STR(__KERNEL_CS)",$1f\n" 43.60 +- "\t1:\n" 43.61 +- "\tmovl $"STR(__KERNEL_DS)",%%eax\n" 43.62 +- "\tmovl %%eax,%%ds\n" 43.63 +- "\tmovl %%eax,%%es\n" 43.64 +- "\tmovl %%eax,%%fs\n" 43.65 +- "\tmovl %%eax,%%gs\n" 43.66 +- "\tmovl %%eax,%%ss\n" 43.67 +- ::: "eax", "memory"); 43.68 +-#undef STR 43.69 +-#undef __STR 43.70 +-} 43.71 +- 43.72 + /* 43.73 + * A architecture hook called to validate the 43.74 + * proposed image and prepare the control pages 43.75 +@@ -127,23 +85,6 @@ NORET_TYPE void machine_kexec(struct kim 43.76 + page_list[PA_PTE_1] = __pa(kexec_pte1); 43.77 + page_list[VA_PTE_1] = (unsigned long)kexec_pte1; 43.78 + 43.79 +- /* The segment registers are funny things, they have both a 43.80 +- * visible and an invisible part. Whenever the visible part is 43.81 +- * set to a specific selector, the invisible part is loaded 43.82 +- * with from a table in memory. At no other time is the 43.83 +- * descriptor table in memory accessed. 43.84 +- * 43.85 +- * I take advantage of this here by force loading the 43.86 +- * segments, before I zap the gdt with an invalid value. 43.87 +- */ 43.88 +- load_segments(); 43.89 +- /* The gdt & idt are now invalid. 43.90 +- * If you want to load them you must set up your own idt & gdt. 43.91 +- */ 43.92 +- set_gdt(phys_to_virt(0),0); 43.93 +- set_idt(phys_to_virt(0),0); 43.94 +- 43.95 +- /* now call it */ 43.96 + relocate_kernel((unsigned long)image->head, (unsigned long)page_list, 43.97 + image->start, cpu_has_pae); 43.98 + } 43.99 +--- 0002/arch/i386/kernel/relocate_kernel.S 43.100 ++++ work/arch/i386/kernel/relocate_kernel.S 2006-10-05 16:03:21.000000000 +0900 43.101 +@@ -154,14 +154,45 @@ relocate_new_kernel: 43.102 + movl PTR(PA_PGD)(%ebp), %eax 43.103 + movl %eax, %cr3 43.104 + 43.105 ++ /* setup idt */ 43.106 ++ movl %edi, %eax 43.107 ++ addl $(idt_48 - relocate_kernel), %eax 43.108 ++ lidtl (%eax) 43.109 ++ 43.110 ++ /* setup gdt */ 43.111 ++ movl %edi, %eax 43.112 ++ addl $(gdt - relocate_kernel), %eax 43.113 ++ movl %edi, %esi 43.114 ++ addl $((gdt_48 - relocate_kernel) + 2), %esi 43.115 ++ movl %eax, (%esi) 43.116 ++ 43.117 ++ movl %edi, %eax 43.118 ++ addl $(gdt_48 - relocate_kernel), %eax 43.119 ++ lgdtl (%eax) 43.120 ++ 43.121 ++ /* setup data segment registers */ 43.122 ++ mov $(gdt_ds - gdt), %eax 43.123 ++ mov %eax, %ds 43.124 ++ mov %eax, %es 43.125 ++ mov %eax, %fs 43.126 ++ mov %eax, %gs 43.127 ++ mov %eax, %ss 43.128 ++ 43.129 + /* setup a new stack at the end of the physical control page */ 43.130 + lea 4096(%edi), %esp 43.131 + 43.132 +- /* jump to identity mapped page */ 43.133 +- movl %edi, %eax 43.134 +- addl $(identity_mapped - relocate_kernel), %eax 43.135 +- pushl %eax 43.136 +- ret 43.137 ++ /* load new code segment and jump to identity mapped page */ 43.138 ++ movl %edi, %esi 43.139 ++ xorl %eax, %eax 43.140 ++ pushl %eax 43.141 ++ pushl %esi 43.142 ++ pushl %eax 43.143 ++ movl $(gdt_cs - gdt), %eax 43.144 ++ pushl %eax 43.145 ++ movl %edi, %eax 43.146 ++ addl $(identity_mapped - relocate_kernel),%eax 43.147 ++ pushl %eax 43.148 ++ iretl 43.149 + 43.150 + identity_mapped: 43.151 + /* store the start address on the stack */ 43.152 +@@ -250,3 +281,20 @@ identity_mapped: 43.153 + xorl %edi, %edi 43.154 + xorl %ebp, %ebp 43.155 + ret 43.156 ++ 43.157 ++ .align 16 43.158 ++gdt: 43.159 ++ .quad 0x0000000000000000 /* NULL descriptor */ 43.160 ++gdt_cs: 43.161 ++ .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ 43.162 ++gdt_ds: 43.163 ++ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ 43.164 ++gdt_end: 43.165 ++ 43.166 ++gdt_48: 43.167 ++ .word gdt_end - gdt - 1 /* limit */ 43.168 ++ .long 0 /* base - filled in by code above */ 43.169 ++ 43.170 ++idt_48: 43.171 ++ .word 0 /* limit */ 43.172 ++ .long 0 /* base */
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch Mon Dec 04 08:24:41 2006 -0700 44.3 @@ -0,0 +1,161 @@ 44.4 +kexec: Move asm segment handling code to the assembly file (x86_64) 44.5 + 44.6 +This patch moves the idt, gdt, and segment handling code from machine_kexec.c 44.7 +to relocate_kernel.S. The main reason behind this move is to avoid code 44.8 +duplication in the Xen hypervisor. With this patch all code required to kexec 44.9 +is put on the control page. 44.10 + 44.11 +On top of that this patch also counts as a cleanup - I think it is much 44.12 +nicer to write assembly directly in assembly files than wrap inline assembly 44.13 +in C functions for no apparent reason. 44.14 + 44.15 +Signed-off-by: Magnus Damm <magnus@valinux.co.jp> 44.16 +--- 44.17 + 44.18 + Applies to 2.6.19-rc1. 44.19 + 44.20 + machine_kexec.c | 58 ----------------------------------------------------- 44.21 + relocate_kernel.S | 50 +++++++++++++++++++++++++++++++++++++++++---- 44.22 + 2 files changed, 45 insertions(+), 63 deletions(-) 44.23 + 44.24 +--- 0002/arch/x86_64/kernel/machine_kexec.c 44.25 ++++ work/arch/x86_64/kernel/machine_kexec.c 2006-10-05 16:15:49.000000000 +0900 44.26 +@@ -112,47 +112,6 @@ static int init_pgtable(struct kimage *i 44.27 + return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); 44.28 + } 44.29 + 44.30 +-static void set_idt(void *newidt, u16 limit) 44.31 +-{ 44.32 +- struct desc_ptr curidt; 44.33 +- 44.34 +- /* x86-64 supports unaliged loads & stores */ 44.35 +- curidt.size = limit; 44.36 +- curidt.address = (unsigned long)newidt; 44.37 +- 44.38 +- __asm__ __volatile__ ( 44.39 +- "lidtq %0\n" 44.40 +- : : "m" (curidt) 44.41 +- ); 44.42 +-}; 44.43 +- 44.44 +- 44.45 +-static void set_gdt(void *newgdt, u16 limit) 44.46 +-{ 44.47 +- struct desc_ptr curgdt; 44.48 +- 44.49 +- /* x86-64 supports unaligned loads & stores */ 44.50 +- curgdt.size = limit; 44.51 +- curgdt.address = (unsigned long)newgdt; 44.52 +- 44.53 +- __asm__ __volatile__ ( 44.54 +- "lgdtq %0\n" 44.55 +- : : "m" (curgdt) 44.56 +- ); 44.57 +-}; 44.58 +- 44.59 +-static void load_segments(void) 44.60 +-{ 44.61 +- __asm__ __volatile__ ( 44.62 +- "\tmovl %0,%%ds\n" 44.63 +- "\tmovl %0,%%es\n" 44.64 +- "\tmovl %0,%%ss\n" 44.65 +- "\tmovl %0,%%fs\n" 44.66 +- "\tmovl %0,%%gs\n" 44.67 +- : : "a" (__KERNEL_DS) : "memory" 44.68 +- ); 44.69 +-} 44.70 +- 44.71 + int machine_kexec_prepare(struct kimage *image) 44.72 + { 44.73 + unsigned long start_pgtable; 44.74 +@@ -209,23 +168,6 @@ NORET_TYPE void machine_kexec(struct kim 44.75 + page_list[PA_TABLE_PAGE] = 44.76 + (unsigned long)__pa(page_address(image->control_code_page)); 44.77 + 44.78 +- /* The segment registers are funny things, they have both a 44.79 +- * visible and an invisible part. Whenever the visible part is 44.80 +- * set to a specific selector, the invisible part is loaded 44.81 +- * with from a table in memory. At no other time is the 44.82 +- * descriptor table in memory accessed. 44.83 +- * 44.84 +- * I take advantage of this here by force loading the 44.85 +- * segments, before I zap the gdt with an invalid value. 44.86 +- */ 44.87 +- load_segments(); 44.88 +- /* The gdt & idt are now invalid. 44.89 +- * If you want to load them you must set up your own idt & gdt. 44.90 +- */ 44.91 +- set_gdt(phys_to_virt(0),0); 44.92 +- set_idt(phys_to_virt(0),0); 44.93 +- 44.94 +- /* now call it */ 44.95 + relocate_kernel((unsigned long)image->head, (unsigned long)page_list, 44.96 + image->start); 44.97 + } 44.98 +--- 0002/arch/x86_64/kernel/relocate_kernel.S 44.99 ++++ work/arch/x86_64/kernel/relocate_kernel.S 2006-10-05 16:18:07.000000000 +0900 44.100 +@@ -159,13 +159,39 @@ relocate_new_kernel: 44.101 + movq PTR(PA_PGD)(%rsi), %r9 44.102 + movq %r9, %cr3 44.103 + 44.104 ++ /* setup idt */ 44.105 ++ movq %r8, %rax 44.106 ++ addq $(idt_80 - relocate_kernel), %rax 44.107 ++ lidtq (%rax) 44.108 ++ 44.109 ++ /* setup gdt */ 44.110 ++ movq %r8, %rax 44.111 ++ addq $(gdt - relocate_kernel), %rax 44.112 ++ movq %r8, %r9 44.113 ++ addq $((gdt_80 - relocate_kernel) + 2), %r9 44.114 ++ movq %rax, (%r9) 44.115 ++ 44.116 ++ movq %r8, %rax 44.117 ++ addq $(gdt_80 - relocate_kernel), %rax 44.118 ++ lgdtq (%rax) 44.119 ++ 44.120 ++ /* setup data segment registers */ 44.121 ++ xorl %eax, %eax 44.122 ++ movl %eax, %ds 44.123 ++ movl %eax, %es 44.124 ++ movl %eax, %fs 44.125 ++ movl %eax, %gs 44.126 ++ movl %eax, %ss 44.127 ++ 44.128 + /* setup a new stack at the end of the physical control page */ 44.129 + lea 4096(%r8), %rsp 44.130 + 44.131 +- /* jump to identity mapped page */ 44.132 +- addq $(identity_mapped - relocate_kernel), %r8 44.133 +- pushq %r8 44.134 +- ret 44.135 ++ /* load new code segment and jump to identity mapped page */ 44.136 ++ movq %r8, %rax 44.137 ++ addq $(identity_mapped - relocate_kernel), %rax 44.138 ++ pushq $(gdt_cs - gdt) 44.139 ++ pushq %rax 44.140 ++ lretq 44.141 + 44.142 + identity_mapped: 44.143 + /* store the start address on the stack */ 44.144 +@@ -272,5 +298,19 @@ identity_mapped: 44.145 + xorq %r13, %r13 44.146 + xorq %r14, %r14 44.147 + xorq %r15, %r15 44.148 +- 44.149 + ret 44.150 ++ 44.151 ++ .align 16 44.152 ++gdt: 44.153 ++ .quad 0x0000000000000000 /* NULL descriptor */ 44.154 ++gdt_cs: 44.155 ++ .quad 0x00af9a000000ffff 44.156 ++gdt_end: 44.157 ++ 44.158 ++gdt_80: 44.159 ++ .word gdt_end - gdt - 1 /* limit */ 44.160 ++ .quad 0 /* base - filled in by code above */ 44.161 ++ 44.162 ++idt_80: 44.163 ++ .word 0 /* limit */ 44.164 ++ .quad 0 /* base */
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-i386.patch Mon Dec 04 08:24:41 2006 -0700 45.3 @@ -0,0 +1,108 @@ 45.4 +--- 0001/arch/i386/kernel/crash.c 45.5 ++++ work/arch/i386/kernel/crash.c 45.6 +@@ -90,6 +90,7 @@ static void crash_save_self(struct pt_re 45.7 + crash_save_this_cpu(regs, cpu); 45.8 + } 45.9 + 45.10 ++#ifndef CONFIG_XEN 45.11 + #ifdef CONFIG_SMP 45.12 + static atomic_t waiting_for_crash_ipi; 45.13 + 45.14 +@@ -158,6 +159,7 @@ static void nmi_shootdown_cpus(void) 45.15 + /* There are no cpus to shootdown */ 45.16 + } 45.17 + #endif 45.18 ++#endif /* CONFIG_XEN */ 45.19 + 45.20 + void machine_crash_shutdown(struct pt_regs *regs) 45.21 + { 45.22 +@@ -174,10 +176,12 @@ void machine_crash_shutdown(struct pt_re 45.23 + 45.24 + /* Make a note of crashing cpu. Will be used in NMI callback.*/ 45.25 + crashing_cpu = smp_processor_id(); 45.26 ++#ifndef CONFIG_XEN 45.27 + nmi_shootdown_cpus(); 45.28 + lapic_shutdown(); 45.29 + #if defined(CONFIG_X86_IO_APIC) 45.30 + disable_IO_APIC(); 45.31 + #endif 45.32 ++#endif /* CONFIG_XEN */ 45.33 + crash_save_self(regs); 45.34 + } 45.35 +--- 0007/arch/i386/kernel/machine_kexec.c 45.36 ++++ work/arch/i386/kernel/machine_kexec.c 45.37 +@@ -19,6 +19,10 @@ 45.38 + #include <asm/desc.h> 45.39 + #include <asm/system.h> 45.40 + 45.41 ++#ifdef CONFIG_XEN 45.42 ++#include <xen/interface/kexec.h> 45.43 ++#endif 45.44 ++ 45.45 + #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) 45.46 + static u32 kexec_pgd[1024] PAGE_ALIGNED; 45.47 + #ifdef CONFIG_X86_PAE 45.48 +@@ -28,6 +32,40 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED 45.49 + static u32 kexec_pte0[1024] PAGE_ALIGNED; 45.50 + static u32 kexec_pte1[1024] PAGE_ALIGNED; 45.51 + 45.52 ++#ifdef CONFIG_XEN 45.53 ++ 45.54 ++#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT) 45.55 ++ 45.56 ++#if PAGES_NR > KEXEC_XEN_NO_PAGES 45.57 ++#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break 45.58 ++#endif 45.59 ++ 45.60 ++#if PA_CONTROL_PAGE != 0 45.61 ++#error PA_CONTROL_PAGE is non zero - Xen support will break 45.62 ++#endif 45.63 ++ 45.64 ++void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image) 45.65 ++{ 45.66 ++ void *control_page; 45.67 ++ 45.68 ++ memset(xki->page_list, 0, sizeof(xki->page_list)); 45.69 ++ 45.70 ++ control_page = page_address(image->control_code_page); 45.71 ++ memcpy(control_page, relocate_kernel, PAGE_SIZE); 45.72 ++ 45.73 ++ xki->page_list[PA_CONTROL_PAGE] = __ma(control_page); 45.74 ++ xki->page_list[PA_PGD] = __ma(kexec_pgd); 45.75 ++#ifdef CONFIG_X86_PAE 45.76 ++ xki->page_list[PA_PMD_0] = __ma(kexec_pmd0); 45.77 ++ xki->page_list[PA_PMD_1] = __ma(kexec_pmd1); 45.78 ++#endif 45.79 ++ xki->page_list[PA_PTE_0] = __ma(kexec_pte0); 45.80 ++ xki->page_list[PA_PTE_1] = __ma(kexec_pte1); 45.81 ++ 45.82 ++} 45.83 ++ 45.84 ++#endif /* CONFIG_XEN */ 45.85 ++ 45.86 + /* 45.87 + * A architecture hook called to validate the 45.88 + * proposed image and prepare the control pages 45.89 +--- 0006/include/asm-i386/kexec.h 45.90 ++++ work/include/asm-i386/kexec.h 45.91 +@@ -98,6 +98,20 @@ relocate_kernel(unsigned long indirectio 45.92 + unsigned long start_address, 45.93 + unsigned int has_pae) ATTRIB_NORET; 45.94 + 45.95 ++ 45.96 ++/* Under Xen we need to work with machine addresses. These macros give the 45.97 ++ * machine address of a certain page to the generic kexec code instead of 45.98 ++ * the pseudo physical address which would be given by the default macros. 45.99 ++ */ 45.100 ++ 45.101 ++#ifdef CONFIG_XEN 45.102 ++#define KEXEC_ARCH_HAS_PAGE_MACROS 45.103 ++#define kexec_page_to_pfn(page) pfn_to_mfn(page_to_pfn(page)) 45.104 ++#define kexec_pfn_to_page(pfn) pfn_to_page(mfn_to_pfn(pfn)) 45.105 ++#define kexec_virt_to_phys(addr) virt_to_machine(addr) 45.106 ++#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr)) 45.107 ++#endif 45.108 ++ 45.109 + #endif /* __ASSEMBLY__ */ 45.110 + 45.111 + #endif /* _I386_KEXEC_H */
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-x86_64.patch Mon Dec 04 08:24:41 2006 -0700 46.3 @@ -0,0 +1,219 @@ 46.4 +--- 0001/arch/x86_64/kernel/crash.c 46.5 ++++ work/arch/x86_64/kernel/crash.c 46.6 +@@ -92,6 +92,7 @@ static void crash_save_self(struct pt_re 46.7 + crash_save_this_cpu(regs, cpu); 46.8 + } 46.9 + 46.10 ++#ifndef CONFIG_XEN 46.11 + #ifdef CONFIG_SMP 46.12 + static atomic_t waiting_for_crash_ipi; 46.13 + 46.14 +@@ -156,6 +157,7 @@ static void nmi_shootdown_cpus(void) 46.15 + /* There are no cpus to shootdown */ 46.16 + } 46.17 + #endif 46.18 ++#endif /* CONFIG_XEN */ 46.19 + 46.20 + void machine_crash_shutdown(struct pt_regs *regs) 46.21 + { 46.22 +@@ -173,6 +175,8 @@ void machine_crash_shutdown(struct pt_re 46.23 + 46.24 + /* Make a note of crashing cpu. Will be used in NMI callback.*/ 46.25 + crashing_cpu = smp_processor_id(); 46.26 ++ 46.27 ++#ifndef CONFIG_XEN 46.28 + nmi_shootdown_cpus(); 46.29 + 46.30 + if(cpu_has_apic) 46.31 +@@ -181,6 +185,6 @@ void machine_crash_shutdown(struct pt_re 46.32 + #if defined(CONFIG_X86_IO_APIC) 46.33 + disable_IO_APIC(); 46.34 + #endif 46.35 +- 46.36 ++#endif /* CONFIG_XEN */ 46.37 + crash_save_self(regs); 46.38 + } 46.39 +--- 0010/arch/x86_64/kernel/machine_kexec.c 46.40 ++++ work/arch/x86_64/kernel/machine_kexec.c 46.41 +@@ -24,6 +24,104 @@ static u64 kexec_pud1[512] PAGE_ALIGNED; 46.42 + static u64 kexec_pmd1[512] PAGE_ALIGNED; 46.43 + static u64 kexec_pte1[512] PAGE_ALIGNED; 46.44 + 46.45 ++#ifdef CONFIG_XEN 46.46 ++ 46.47 ++/* In the case of Xen, override hypervisor functions to be able to create 46.48 ++ * a regular identity mapping page table... 46.49 ++ */ 46.50 ++ 46.51 ++#include <xen/interface/kexec.h> 46.52 ++#include <xen/interface/memory.h> 46.53 ++ 46.54 ++#define x__pmd(x) ((pmd_t) { (x) } ) 46.55 ++#define x__pud(x) ((pud_t) { (x) } ) 46.56 ++#define x__pgd(x) ((pgd_t) { (x) } ) 46.57 ++ 46.58 ++#define x_pmd_val(x) ((x).pmd) 46.59 ++#define x_pud_val(x) ((x).pud) 46.60 ++#define x_pgd_val(x) ((x).pgd) 46.61 ++ 46.62 ++static inline void x_set_pmd(pmd_t *dst, pmd_t val) 46.63 ++{ 46.64 ++ x_pmd_val(*dst) = x_pmd_val(val); 46.65 ++} 46.66 ++ 46.67 ++static inline void x_set_pud(pud_t *dst, pud_t val) 46.68 ++{ 46.69 ++ x_pud_val(*dst) = phys_to_machine(x_pud_val(val)); 46.70 ++} 46.71 ++ 46.72 ++static inline void x_pud_clear (pud_t *pud) 46.73 ++{ 46.74 ++ x_pud_val(*pud) = 0; 46.75 ++} 46.76 ++ 46.77 ++static inline void x_set_pgd(pgd_t *dst, pgd_t val) 46.78 ++{ 46.79 ++ x_pgd_val(*dst) = phys_to_machine(x_pgd_val(val)); 46.80 ++} 46.81 ++ 46.82 ++static inline void x_pgd_clear (pgd_t * pgd) 46.83 ++{ 46.84 ++ x_pgd_val(*pgd) = 0; 46.85 ++} 46.86 ++ 46.87 ++#define X__PAGE_KERNEL_LARGE_EXEC \ 46.88 ++ _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_PSE 46.89 ++#define X_KERNPG_TABLE _PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY 46.90 ++ 46.91 ++#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT) 46.92 ++ 46.93 ++#if PAGES_NR > KEXEC_XEN_NO_PAGES 46.94 ++#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break 46.95 ++#endif 46.96 ++ 46.97 ++#if PA_CONTROL_PAGE != 0 46.98 ++#error PA_CONTROL_PAGE is non zero - Xen support will break 46.99 ++#endif 46.100 ++ 46.101 ++void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image) 46.102 ++{ 46.103 ++ void *control_page; 46.104 ++ void *table_page; 46.105 ++ 46.106 ++ memset(xki->page_list, 0, sizeof(xki->page_list)); 46.107 ++ 46.108 ++ control_page = page_address(image->control_code_page) + PAGE_SIZE; 46.109 ++ memcpy(control_page, relocate_kernel, PAGE_SIZE); 46.110 ++ 46.111 ++ table_page = page_address(image->control_code_page); 46.112 ++ 46.113 ++ xki->page_list[PA_CONTROL_PAGE] = __ma(control_page); 46.114 ++ xki->page_list[PA_TABLE_PAGE] = __ma(table_page); 46.115 ++ 46.116 ++ xki->page_list[PA_PGD] = __ma(kexec_pgd); 46.117 ++ xki->page_list[PA_PUD_0] = __ma(kexec_pud0); 46.118 ++ xki->page_list[PA_PUD_1] = __ma(kexec_pud1); 46.119 ++ xki->page_list[PA_PMD_0] = __ma(kexec_pmd0); 46.120 ++ xki->page_list[PA_PMD_1] = __ma(kexec_pmd1); 46.121 ++ xki->page_list[PA_PTE_0] = __ma(kexec_pte0); 46.122 ++ xki->page_list[PA_PTE_1] = __ma(kexec_pte1); 46.123 ++} 46.124 ++ 46.125 ++#else /* CONFIG_XEN */ 46.126 ++ 46.127 ++#define x__pmd(x) __pmd(x) 46.128 ++#define x__pud(x) __pud(x) 46.129 ++#define x__pgd(x) __pgd(x) 46.130 ++ 46.131 ++#define x_set_pmd(x, y) set_pmd(x, y) 46.132 ++#define x_set_pud(x, y) set_pud(x, y) 46.133 ++#define x_set_pgd(x, y) set_pgd(x, y) 46.134 ++ 46.135 ++#define x_pud_clear(x) pud_clear(x) 46.136 ++#define x_pgd_clear(x) pgd_clear(x) 46.137 ++ 46.138 ++#define X__PAGE_KERNEL_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC 46.139 ++#define X_KERNPG_TABLE _KERNPG_TABLE 46.140 ++ 46.141 ++#endif /* CONFIG_XEN */ 46.142 ++ 46.143 + static void init_level2_page(pmd_t *level2p, unsigned long addr) 46.144 + { 46.145 + unsigned long end_addr; 46.146 +@@ -31,7 +129,7 @@ static void init_level2_page(pmd_t *leve 46.147 + addr &= PAGE_MASK; 46.148 + end_addr = addr + PUD_SIZE; 46.149 + while (addr < end_addr) { 46.150 +- set_pmd(level2p++, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC)); 46.151 ++ x_set_pmd(level2p++, x__pmd(addr | X__PAGE_KERNEL_LARGE_EXEC)); 46.152 + addr += PMD_SIZE; 46.153 + } 46.154 + } 46.155 +@@ -56,12 +154,12 @@ static int init_level3_page(struct kimag 46.156 + } 46.157 + level2p = (pmd_t *)page_address(page); 46.158 + init_level2_page(level2p, addr); 46.159 +- set_pud(level3p++, __pud(__pa(level2p) | _KERNPG_TABLE)); 46.160 ++ x_set_pud(level3p++, x__pud(__pa(level2p) | X_KERNPG_TABLE)); 46.161 + addr += PUD_SIZE; 46.162 + } 46.163 + /* clear the unused entries */ 46.164 + while (addr < end_addr) { 46.165 +- pud_clear(level3p++); 46.166 ++ x_pud_clear(level3p++); 46.167 + addr += PUD_SIZE; 46.168 + } 46.169 + out: 46.170 +@@ -92,12 +190,12 @@ static int init_level4_page(struct kimag 46.171 + if (result) { 46.172 + goto out; 46.173 + } 46.174 +- set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE)); 46.175 ++ x_set_pgd(level4p++, x__pgd(__pa(level3p) | X_KERNPG_TABLE)); 46.176 + addr += PGDIR_SIZE; 46.177 + } 46.178 + /* clear the unused entries */ 46.179 + while (addr < end_addr) { 46.180 +- pgd_clear(level4p++); 46.181 ++ x_pgd_clear(level4p++); 46.182 + addr += PGDIR_SIZE; 46.183 + } 46.184 + out: 46.185 +@@ -108,8 +206,14 @@ out: 46.186 + static int init_pgtable(struct kimage *image, unsigned long start_pgtable) 46.187 + { 46.188 + pgd_t *level4p; 46.189 ++ unsigned long x_end_pfn = end_pfn; 46.190 ++ 46.191 ++#ifdef CONFIG_XEN 46.192 ++ x_end_pfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL); 46.193 ++#endif 46.194 ++ 46.195 + level4p = (pgd_t *)__va(start_pgtable); 46.196 +- return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); 46.197 ++ return init_level4_page(image, level4p, 0, x_end_pfn << PAGE_SHIFT); 46.198 + } 46.199 + 46.200 + int machine_kexec_prepare(struct kimage *image) 46.201 +--- 0009/include/asm-x86_64/kexec.h 46.202 ++++ work/include/asm-x86_64/kexec.h 46.203 +@@ -91,6 +91,19 @@ relocate_kernel(unsigned long indirectio 46.204 + unsigned long page_list, 46.205 + unsigned long start_address) ATTRIB_NORET; 46.206 + 46.207 ++/* Under Xen we need to work with machine addresses. These macros give the 46.208 ++ * machine address of a certain page to the generic kexec code instead of 46.209 ++ * the pseudo physical address which would be given by the default macros. 46.210 ++ */ 46.211 ++ 46.212 ++#ifdef CONFIG_XEN 46.213 ++#define KEXEC_ARCH_HAS_PAGE_MACROS 46.214 ++#define kexec_page_to_pfn(page) pfn_to_mfn(page_to_pfn(page)) 46.215 ++#define kexec_pfn_to_page(pfn) pfn_to_page(mfn_to_pfn(pfn)) 46.216 ++#define kexec_virt_to_phys(addr) virt_to_machine(addr) 46.217 ++#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr)) 46.218 ++#endif 46.219 ++ 46.220 + #endif /* __ASSEMBLY__ */ 46.221 + 46.222 + #endif /* _X86_64_KEXEC_H */
47.1 --- a/patches/linux-2.6.16.33/series Sat Dec 02 15:19:50 2006 -0700 47.2 +++ b/patches/linux-2.6.16.33/series Mon Dec 04 08:24:41 2006 -0700 47.3 @@ -1,3 +1,12 @@ 47.4 +kexec-generic.patch 47.5 +git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch 47.6 +git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch 47.7 +git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch 47.8 +linux-2.6.19-rc1-kexec-move_segment_code-i386.patch 47.9 +linux-2.6.19-rc1-kexec-xen-i386.patch 47.10 +git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch 47.11 +linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch 47.12 +linux-2.6.19-rc1-kexec-xen-x86_64.patch 47.13 blktap-aio-16_03_06.patch 47.14 device_bind.patch 47.15 fix-hz-suspend.patch 47.16 @@ -22,6 +31,7 @@ xen-hotplug.patch 47.17 xenoprof-generic.patch 47.18 x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch 47.19 x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch 47.20 +git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch 47.21 x86-elfnote-as-preprocessor-macro.patch 47.22 vsnprintf.patch 47.23 kasprintf.patch
48.1 --- a/tools/Makefile Sat Dec 02 15:19:50 2006 -0700 48.2 +++ b/tools/Makefile Mon Dec 04 08:24:41 2006 -0700 48.3 @@ -19,6 +19,7 @@ SUBDIRS-y += xenstat 48.4 SUBDIRS-y += libaio 48.5 SUBDIRS-y += blktap 48.6 SUBDIRS-y += libfsimage 48.7 +SUBDIRS-$(XENFB_TOOLS) += xenfb 48.8 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen 48.9 48.10 # These don't cross-compile
49.1 --- a/tools/blktap/drivers/block-aio.c Sat Dec 02 15:19:50 2006 -0700 49.2 +++ b/tools/blktap/drivers/block-aio.c Mon Dec 04 08:24:41 2006 -0700 49.3 @@ -311,12 +311,8 @@ int tdaio_do_callbacks(struct td_state * 49.4 struct pending_aio *pio; 49.5 49.6 pio = &prv->pending_aio[(long)io->data]; 49.7 - 49.8 - if (ep->res != io->u.c.nbytes) { 49.9 - /* TODO: handle this case better. */ 49.10 - DPRINTF("AIO did less than I asked it to. \n"); 49.11 - } 49.12 - rsp += pio->cb(s, ep->res2, pio->id, pio->private); 49.13 + rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1, 49.14 + pio->id, pio->private); 49.15 49.16 prv->iocb_free[prv->iocb_free_count++] = io; 49.17 }
50.1 --- a/tools/blktap/drivers/block-qcow.c Sat Dec 02 15:19:50 2006 -0700 50.2 +++ b/tools/blktap/drivers/block-qcow.c Mon Dec 04 08:24:41 2006 -0700 50.3 @@ -1145,13 +1145,6 @@ int tdqcow_do_callbacks(struct td_state 50.4 50.5 pio = &prv->pending_aio[(long)io->data]; 50.6 50.7 - if (ep->res != io->u.c.nbytes) { 50.8 - /* TODO: handle this case better. */ 50.9 - ptr = (int *)&ep->res; 50.10 - DPRINTF("AIO did less than I asked it to " 50.11 - "[%lu,%lu,%d]\n", 50.12 - ep->res, io->u.c.nbytes, *ptr); 50.13 - } 50.14 aio_unlock(prv, pio->sector); 50.15 if (pio->id >= 0) { 50.16 if (prv->crypt_method) 50.17 @@ -1162,7 +1155,7 @@ int tdqcow_do_callbacks(struct td_state 50.18 &prv->aes_decrypt_key); 50.19 prv->nr_reqs[pio->qcow_idx]--; 50.20 if (prv->nr_reqs[pio->qcow_idx] == 0) 50.21 - rsp += pio->cb(s, ep->res2, pio->id, 50.22 + rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1, pio->id, 50.23 pio->private); 50.24 } else if (pio->id == -2) free(pio->buf); 50.25
51.1 --- a/tools/blktap/drivers/tapdisk.c Sat Dec 02 15:19:50 2006 -0700 51.2 +++ b/tools/blktap/drivers/tapdisk.c Mon Dec 04 08:24:41 2006 -0700 51.3 @@ -424,8 +424,7 @@ int send_responses(struct td_state *s, i 51.4 } 51.5 51.6 if (res != 0) { 51.7 - DPRINTF("*** request error %d! \n", res); 51.8 - return 0; 51.9 + blkif->pending_list[idx].status = BLKIF_RSP_ERROR; 51.10 } 51.11 51.12 blkif->pending_list[idx].count--;
52.1 --- a/tools/check/Makefile Sat Dec 02 15:19:50 2006 -0700 52.2 +++ b/tools/check/Makefile Mon Dec 04 08:24:41 2006 -0700 52.3 @@ -1,3 +1,5 @@ 52.4 +XEN_ROOT = ../.. 52.5 +include $(XEN_ROOT)/tools/Rules.mk 52.6 52.7 .PHONY: all 52.8 all: build 52.9 @@ -5,7 +7,7 @@ all: build 52.10 # Check this machine is OK for building on. 52.11 .PHONY: build 52.12 build: 52.13 - ./chk build 52.14 + XENFB_TOOLS=$(XENFB_TOOLS) ./chk build 52.15 52.16 # Check this machine is OK for installing on. 52.17 # DO NOT use this check from 'make install' in the parent 52.18 @@ -13,7 +15,7 @@ build: 52.19 # copy rather than actually installing. 52.20 .PHONY: install 52.21 install: 52.22 - ./chk install 52.23 + XENFB_TOOLS=$(XENFB_TOOLS) ./chk install 52.24 52.25 .PHONY: clean 52.26 clean:
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/tools/check/check_libvncserver Mon Dec 04 08:24:41 2006 -0700 53.3 @@ -0,0 +1,27 @@ 53.4 +#!/bin/sh 53.5 +# CHECK-BUILD CHECK-INSTALL 53.6 + 53.7 +if [ ! "$XENFB_TOOLS" = "y" ] 53.8 +then 53.9 + echo -n "unused, " 53.10 + exit 0 53.11 +fi 53.12 + 53.13 +RC=0 53.14 + 53.15 +LIBVNCSERVER_CONFIG="$(which libvncserver-config)" 53.16 + 53.17 +if test -z ${LIBVNCSERVER_CONFIG}; then 53.18 + RC=1 53.19 +else 53.20 + ${LIBVNCSERVER_CONFIG} --libs 2>&1 > /dev/null 53.21 + RC=$? 53.22 +fi 53.23 + 53.24 +if test $RC -ne 0; then 53.25 + echo "FAILED" 53.26 + echo " *** libvncserver-config is missing. " 53.27 + echo " *** Please install libvncserver." 53.28 +fi 53.29 + 53.30 +exit $RC
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/tools/check/check_sdl Mon Dec 04 08:24:41 2006 -0700 54.3 @@ -0,0 +1,27 @@ 54.4 +#!/bin/sh 54.5 +# CHECK-BUILD CHECK-INSTALL 54.6 + 54.7 +if [ ! "$XENFB_TOOLS" = "y" ] 54.8 +then 54.9 + echo -n "unused, " 54.10 + exit 0 54.11 +fi 54.12 + 54.13 +RC=0 54.14 + 54.15 +SDL_CONFIG="$(which sdl-config)" 54.16 + 54.17 +if test -z ${SDL_CONFIG}; then 54.18 + RC=1 54.19 +else 54.20 + ${SDL_CONFIG} --libs 2>&1 > /dev/null 54.21 + RC=$? 54.22 +fi 54.23 + 54.24 +if test $RC -ne 0; then 54.25 + echo "FAILED" 54.26 + echo " *** sdl-config is missing. " 54.27 + echo " *** Please install libsdl-dev or sdl." 54.28 +fi 54.29 + 54.30 +exit $RC
55.1 --- a/tools/firmware/vmxassist/setup.c Sat Dec 02 15:19:50 2006 -0700 55.2 +++ b/tools/firmware/vmxassist/setup.c Mon Dec 04 08:24:41 2006 -0700 55.3 @@ -66,7 +66,7 @@ struct vmx_assist_context newctx; 55.4 unsigned long memory_size; 55.5 int initialize_real_mode; 55.6 55.7 -extern char stack[], stack_top[]; 55.8 +extern char stack_top[]; 55.9 extern unsigned trap_handlers[]; 55.10 55.11 void 55.12 @@ -201,7 +201,7 @@ void 55.13 enter_real_mode(struct regs *regs) 55.14 { 55.15 /* mask off TSS busy bit */ 55.16 - gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL; 55.17 + gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL; 55.18 55.19 /* start 8086 emulation of BIOS */ 55.20 if (initialize_real_mode) { 55.21 @@ -219,8 +219,10 @@ enter_real_mode(struct regs *regs) 55.22 regs->cs = booting_vector << 8; /* AP entry point */ 55.23 regs->eip = 0; 55.24 } 55.25 - regs->uesp = 0; 55.26 - regs->uss = 0; 55.27 + 55.28 + regs->uesp = regs->uss = 0; 55.29 + regs->eax = regs->ecx = regs->edx = regs->ebx = 0; 55.30 + regs->esp = regs->ebp = regs->esi = regs->edi = 0; 55.31 55.32 /* intercept accesses to the PIC */ 55.33 setiomap(PIC_MASTER+PIC_CMD); 55.34 @@ -236,14 +238,12 @@ enter_real_mode(struct regs *regs) 55.35 55.36 /* this should get us into 16-bit mode */ 55.37 return; 55.38 - } else { 55.39 - /* go from protected to real mode */ 55.40 - regs->eflags |= EFLAGS_VM; 55.41 + } 55.42 55.43 - set_mode(regs, VM86_PROTECTED_TO_REAL); 55.44 - 55.45 - emulate(regs); 55.46 - } 55.47 + /* go from protected to real mode */ 55.48 + regs->eflags |= EFLAGS_VM; 55.49 + set_mode(regs, VM86_PROTECTED_TO_REAL); 55.50 + emulate(regs); 55.51 } 55.52 55.53 /*
56.1 --- a/tools/firmware/vmxassist/trap.S Sat Dec 02 15:19:50 2006 -0700 56.2 +++ b/tools/firmware/vmxassist/trap.S Mon Dec 04 08:24:41 2006 -0700 56.3 @@ -100,10 +100,6 @@ trap_handlers: 56.4 .code32 56.5 .align 16 56.6 common_trap: /* common trap handler */ 56.7 - pushl %gs 56.8 - pushl %fs 56.9 - pushl %ds 56.10 - pushl %es 56.11 pushal 56.12 56.13 movl $(DATA_SELECTOR), %eax /* make sure these are sane */ 56.14 @@ -114,17 +110,13 @@ common_trap: /* common trap handler * 56.15 movl %esp, %ebp 56.16 56.17 pushl %ebp 56.18 - pushl 52(%ebp) 56.19 - pushl 48(%ebp) 56.20 + pushl 36(%ebp) 56.21 + pushl 32(%ebp) 56.22 call trap /* trap(trapno, errno, regs) */ 56.23 addl $12, %esp 56.24 56.25 trap_return: 56.26 popal 56.27 - popl %es 56.28 - popl %ds 56.29 - popl %fs 56.30 - popl %gs 56.31 addl $8, %esp /* skip trapno, errno */ 56.32 iret 56.33 /* NOT REACHED */ 56.34 @@ -152,10 +144,6 @@ switch_to_real_mode: 56.35 pushl oldctx+VMX_ASSIST_CTX_EIP 56.36 pushl $-1 /* trapno, errno */ 56.37 pushl $-1 56.38 - pushl %gs 56.39 - pushl %fs 56.40 - pushl %ds 56.41 - pushl %es 56.42 pushal 56.43 56.44 movl %esp, %ebp
57.1 --- a/tools/firmware/vmxassist/util.c Sat Dec 02 15:19:50 2006 -0700 57.2 +++ b/tools/firmware/vmxassist/util.c Mon Dec 04 08:24:41 2006 -0700 57.3 @@ -62,17 +62,15 @@ dump_regs(struct regs *regs) 57.4 regs->eax, regs->ecx, regs->edx, regs->ebx); 57.5 printf("esp %8x ebp %8x esi %8x edi %8x\n", 57.6 regs->esp, regs->ebp, regs->esi, regs->edi); 57.7 - printf("es %8x ds %8x fs %8x gs %8x\n", 57.8 - regs->es, regs->ds, regs->fs, regs->gs); 57.9 printf("trapno %8x errno %8x\n", regs->trapno, regs->errno); 57.10 printf("eip %8x cs %8x eflags %8x\n", 57.11 regs->eip, regs->cs, regs->eflags); 57.12 - printf("uesp %8x uss %8x \n", 57.13 + printf("uesp %8x uss %8x\n", 57.14 regs->uesp, regs->uss); 57.15 printf("ves %8x vds %8x vfs %8x vgs %8x\n", 57.16 regs->ves, regs->vds, regs->vfs, regs->vgs); 57.17 57.18 - printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n", 57.19 + printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n\n", 57.20 (long)oldctx.cr0, get_cr2(), 57.21 (long)oldctx.cr3, (long)oldctx.cr4); 57.22 }
58.1 --- a/tools/firmware/vmxassist/vm86.c Sat Dec 02 15:19:50 2006 -0700 58.2 +++ b/tools/firmware/vmxassist/vm86.c Mon Dec 04 08:24:41 2006 -0700 58.3 @@ -376,9 +376,9 @@ segment(unsigned prefix, struct regs *re 58.4 if (prefix & SEG_SS) 58.5 seg = regs->uss; 58.6 if (prefix & SEG_FS) 58.7 - seg = regs->fs; 58.8 + seg = regs->vfs; 58.9 if (prefix & SEG_GS) 58.10 - seg = regs->gs; 58.11 + seg = regs->vgs; 58.12 return seg; 58.13 } 58.14 58.15 @@ -934,6 +934,8 @@ load_or_clear_seg(unsigned long sel, uin 58.16 static void 58.17 protected_mode(struct regs *regs) 58.18 { 58.19 + extern char stack_top[]; 58.20 + 58.21 regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM); 58.22 58.23 oldctx.eip = regs->eip; 58.24 @@ -958,12 +960,10 @@ protected_mode(struct regs *regs) 58.25 &oldctx.gs_limit, &oldctx.gs_arbytes); 58.26 58.27 /* initialize jump environment to warp back to protected mode */ 58.28 + regs->uss = DATA_SELECTOR; 58.29 + regs->uesp = stack_top; 58.30 regs->cs = CODE_SELECTOR; 58.31 - regs->ds = DATA_SELECTOR; 58.32 - regs->es = DATA_SELECTOR; 58.33 - regs->fs = DATA_SELECTOR; 58.34 - regs->gs = DATA_SELECTOR; 58.35 - regs->eip = (unsigned) &switch_to_protected_mode; 58.36 + regs->eip = (unsigned) switch_to_protected_mode; 58.37 58.38 /* this should get us into 32-bit mode */ 58.39 } 58.40 @@ -975,10 +975,6 @@ static void 58.41 real_mode(struct regs *regs) 58.42 { 58.43 regs->eflags |= EFLAGS_VM | 0x02; 58.44 - regs->ds = DATA_SELECTOR; 58.45 - regs->es = DATA_SELECTOR; 58.46 - regs->fs = DATA_SELECTOR; 58.47 - regs->gs = DATA_SELECTOR; 58.48 58.49 /* 58.50 * When we transition from protected to real-mode and we 58.51 @@ -1070,9 +1066,6 @@ set_mode(struct regs *regs, enum vm86_mo 58.52 case VM86_PROTECTED: 58.53 if (mode == VM86_REAL_TO_PROTECTED) { 58.54 protected_mode(regs); 58.55 -// printf("<VM86_PROTECTED>\n"); 58.56 - mode = newmode; 58.57 - return; 58.58 } else 58.59 panic("unexpected protected mode transition"); 58.60 break;
59.1 --- a/tools/firmware/vmxassist/vm86.h Sat Dec 02 15:19:50 2006 -0700 59.2 +++ b/tools/firmware/vmxassist/vm86.h Mon Dec 04 08:24:41 2006 -0700 59.3 @@ -34,7 +34,6 @@ 59.4 59.5 struct regs { 59.6 unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; 59.7 - unsigned es, ds, fs, gs; 59.8 unsigned trapno, errno; 59.9 unsigned eip, cs, eflags, uesp, uss; 59.10 unsigned ves, vds, vfs, vgs; 59.11 @@ -55,7 +54,6 @@ enum vm86_mode { 59.12 59.13 extern enum vm86_mode prevmode, mode; 59.14 extern struct vmx_assist_context oldctx; 59.15 -extern struct vmx_assist_context newctx; 59.16 59.17 extern void emulate(struct regs *); 59.18 extern void dump_regs(struct regs *);
60.1 --- a/tools/ioemu/hw/pci.c Sat Dec 02 15:19:50 2006 -0700 60.2 +++ b/tools/ioemu/hw/pci.c Mon Dec 04 08:24:41 2006 -0700 60.3 @@ -221,23 +221,16 @@ uint32_t pci_default_read_config(PCIDevi 60.4 uint32_t address, int len) 60.5 { 60.6 uint32_t val; 60.7 - 60.8 switch(len) { 60.9 + case 1: 60.10 + val = d->config[address]; 60.11 + break; 60.12 + case 2: 60.13 + val = le16_to_cpu(*(uint16_t *)(d->config + address)); 60.14 + break; 60.15 default: 60.16 case 4: 60.17 - if (address <= 0xfc) { 60.18 - val = le32_to_cpu(*(uint32_t *)(d->config + address)); 60.19 - break; 60.20 - } 60.21 - /* fall through */ 60.22 - case 2: 60.23 - if (address <= 0xfe) { 60.24 - val = le16_to_cpu(*(uint16_t *)(d->config + address)); 60.25 - break; 60.26 - } 60.27 - /* fall through */ 60.28 - case 1: 60.29 - val = d->config[address]; 60.30 + val = le32_to_cpu(*(uint32_t *)(d->config + address)); 60.31 break; 60.32 } 60.33 return val; 60.34 @@ -340,8 +333,7 @@ void pci_default_write_config(PCIDevice 60.35 60.36 d->config[addr] = val; 60.37 } 60.38 - if (++addr > 0xff) 60.39 - break; 60.40 + addr++; 60.41 val >>= 8; 60.42 } 60.43
61.1 --- a/tools/ioemu/hw/usb-uhci.c Sat Dec 02 15:19:50 2006 -0700 61.2 +++ b/tools/ioemu/hw/usb-uhci.c Mon Dec 04 08:24:41 2006 -0700 61.3 @@ -421,7 +421,7 @@ static int uhci_broadcast_packet(UHCISta 61.4 static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask) 61.5 { 61.6 uint8_t pid; 61.7 - uint8_t buf[1280]; 61.8 + uint8_t buf[2048]; 61.9 int len, max_len, err, ret; 61.10 61.11 if (td->ctrl & TD_CTRL_IOC) {
62.1 --- a/tools/ioemu/vl.h Sat Dec 02 15:19:50 2006 -0700 62.2 +++ b/tools/ioemu/vl.h Mon Dec 04 08:24:41 2006 -0700 62.3 @@ -650,8 +650,11 @@ typedef struct PCIIORegion { 62.4 #define PCI_MAX_LAT 0x3f /* 8 bits */ 62.5 62.6 struct PCIDevice { 62.7 - /* PCI config space */ 62.8 - uint8_t config[256]; 62.9 + /* 62.10 + * PCI config space. The 4 extra bytes are a safety buffer for guest 62.11 + * word/dword writes that can extend past byte 0xff. 62.12 + */ 62.13 + uint8_t config[256+4]; 62.14 62.15 /* the following fields are read only */ 62.16 PCIBus *bus;
63.1 --- a/tools/ioemu/vnc.c Sat Dec 02 15:19:50 2006 -0700 63.2 +++ b/tools/ioemu/vnc.c Mon Dec 04 08:24:41 2006 -0700 63.3 @@ -114,6 +114,7 @@ struct VncState 63.4 int visible_h; 63.5 63.6 int ctl_keys; /* Ctrl+Alt starts calibration */ 63.7 + int shift_keys; /* Shift / CapsLock keys */ 63.8 }; 63.9 63.10 #define DIRTY_PIXEL_BITS 64 63.11 @@ -870,9 +871,12 @@ static void do_key_event(VncState *vs, i 63.12 } else if (down) { 63.13 int qemu_keysym = 0; 63.14 63.15 - if (sym <= 128) /* normal ascii */ 63.16 + if (sym <= 128) { /* normal ascii */ 63.17 + int shifted = vs->shift_keys == 1 || vs->shift_keys == 2; 63.18 qemu_keysym = sym; 63.19 - else { 63.20 + if (sym >= 'a' && sym <= 'z' && shifted) 63.21 + qemu_keysym -= 'a' - 'A'; 63.22 + } else { 63.23 switch (sym) { 63.24 case XK_Up: qemu_keysym = QEMU_KEY_UP; break; 63.25 case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break; 63.26 @@ -903,6 +907,10 @@ static void do_key_event(VncState *vs, i 63.27 vs->ctl_keys |= 2; 63.28 break; 63.29 63.30 + case XK_Shift_L: 63.31 + vs->shift_keys |= 1; 63.32 + break; 63.33 + 63.34 default: 63.35 break; 63.36 } 63.37 @@ -916,6 +924,14 @@ static void do_key_event(VncState *vs, i 63.38 vs->ctl_keys &= ~2; 63.39 break; 63.40 63.41 + case XK_Shift_L: 63.42 + vs->shift_keys &= ~1; 63.43 + break; 63.44 + 63.45 + case XK_Caps_Lock: 63.46 + vs->shift_keys ^= 2; 63.47 + break; 63.48 + 63.49 case XK_1 ... XK_9: 63.50 if ((vs->ctl_keys & 3) != 3) 63.51 break;
64.1 --- a/tools/libxc/xc_linux.c Sat Dec 02 15:19:50 2006 -0700 64.2 +++ b/tools/libxc/xc_linux.c Mon Dec 04 08:24:41 2006 -0700 64.3 @@ -250,6 +250,15 @@ int xc_evtchn_notify(int xce_handle, evt 64.4 return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify); 64.5 } 64.6 64.7 +evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid) 64.8 +{ 64.9 + struct ioctl_evtchn_bind_unbound_port bind; 64.10 + 64.11 + bind.remote_domain = domid; 64.12 + 64.13 + return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); 64.14 +} 64.15 + 64.16 evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid, 64.17 evtchn_port_t remote_port) 64.18 {
65.1 --- a/tools/libxc/xc_solaris.c Sat Dec 02 15:19:50 2006 -0700 65.2 +++ b/tools/libxc/xc_solaris.c Mon Dec 04 08:24:41 2006 -0700 65.3 @@ -165,6 +165,15 @@ int xc_evtchn_notify(int xce_handle, evt 65.4 return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify); 65.5 } 65.6 65.7 +evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid) 65.8 +{ 65.9 + struct ioctl_evtchn_bind_unbound_port bind; 65.10 + 65.11 + bind.remote_domain = domid; 65.12 + 65.13 + return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); 65.14 +} 65.15 + 65.16 evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid, 65.17 evtchn_port_t remote_port) 65.18 {
66.1 --- a/tools/libxc/xenctrl.h Sat Dec 02 15:19:50 2006 -0700 66.2 +++ b/tools/libxc/xenctrl.h Mon Dec 04 08:24:41 2006 -0700 66.3 @@ -382,6 +382,10 @@ int xc_sched_credit_domain_get(int xc_ha 66.4 * This function allocates an unbound port. Ports are named endpoints used for 66.5 * interdomain communication. This function is most useful in opening a 66.6 * well-known port within a domain to receive events on. 66.7 + * 66.8 + * NOTE: If you are allocating a *local* unbound port, you probably want to 66.9 + * use xc_evtchn_bind_unbound_port(). This function is intended for allocating 66.10 + * ports *only* during domain creation. 66.11 * 66.12 * @parm xc_handle a handle to an open hypervisor interface 66.13 * @parm dom the ID of the local domain (the 'allocatee') 66.14 @@ -630,6 +634,12 @@ int xc_evtchn_fd(int xce_handle); 66.15 int xc_evtchn_notify(int xce_handle, evtchn_port_t port); 66.16 66.17 /* 66.18 + * Returns a new event port awaiting interdomain connection from the given 66.19 + * domain ID, or -1 on failure, in which case errno will be set appropriately. 66.20 + */ 66.21 +evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid); 66.22 + 66.23 +/* 66.24 * Returns a new event port bound to the remote port for the given domain ID, 66.25 * or -1 on failure, in which case errno will be set appropriately. 66.26 */ 66.27 @@ -661,15 +671,15 @@ evtchn_port_t xc_evtchn_pending(int xce_ 66.28 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port); 66.29 66.30 int xc_hvm_set_pci_intx_level( 66.31 - int xce_handle, domid_t dom, 66.32 + int xc_handle, domid_t dom, 66.33 uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx, 66.34 unsigned int level); 66.35 int xc_hvm_set_isa_irq_level( 66.36 - int xce_handle, domid_t dom, 66.37 + int xc_handle, domid_t dom, 66.38 uint8_t isa_irq, 66.39 unsigned int level); 66.40 66.41 int xc_hvm_set_pci_link_route( 66.42 - int xce_handle, domid_t dom, uint8_t link, uint8_t isa_irq); 66.43 + int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq); 66.44 66.45 #endif
67.1 --- a/tools/libxen/Makefile Sat Dec 02 15:19:50 2006 -0700 67.2 +++ b/tools/libxen/Makefile Mon Dec 04 08:24:41 2006 -0700 67.3 @@ -48,8 +48,8 @@ libxenapi.so.$(MAJOR).$(MINOR): $(LIBXEN 67.4 libxenapi.a: $(LIBXENAPI_OBJS) 67.5 $(AR) rcs libxenapi.a $^ 67.6 67.7 -test/test_bindings: test/test_bindings.o src/libxen.so 67.8 - $(CC) $(LDFLAGS) -o $@ $< -L src -lxen 67.9 +test/test_bindings: test/test_bindings.o libxenapi.so 67.10 + $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi 67.11 67.12 67.13 .PHONY: install
68.1 --- a/tools/libxen/README Sat Dec 02 15:19:50 2006 -0700 68.2 +++ b/tools/libxen/README Mon Dec 04 08:24:41 2006 -0700 68.3 @@ -44,11 +44,12 @@ The bindings depend upon libxml2, the XM 68.4 test program depends upon libcurl3 also. On Debian, you need the packages 68.5 libxml2-dev and libcurl3-dev. 68.6 68.7 -To compile, type make. 68.8 +To compile, type make. To compile the test also, type make 68.9 +test/test_bindings, remembering the additional dependency. 68.10 68.11 To run the test, do 68.12 68.13 -LD_LIBRARY_PATH=src ./test/test_bindings <url> <username> <password> 68.14 +LD_LIBRARY_PATH=. ./test/test_bindings <url> <username> <password> 68.15 68.16 where <url> is the fragment of the server URL that follows the http://, for 68.17 example "localhost:8005/RPC2".
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/tools/libxen/include/xen_console.h Mon Dec 04 08:24:41 2006 -0700 69.3 @@ -0,0 +1,207 @@ 69.4 +/* 69.5 + * Copyright (c) 2006, XenSource Inc. 69.6 + * 69.7 + * This library is free software; you can redistribute it and/or 69.8 + * modify it under the terms of the GNU Lesser General Public 69.9 + * License as published by the Free Software Foundation; either 69.10 + * version 2.1 of the License, or (at your option) any later version. 69.11 + * 69.12 + * This library is distributed in the hope that it will be useful, 69.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 69.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 69.15 + * Lesser General Public License for more details. 69.16 + * 69.17 + * You should have received a copy of the GNU Lesser General Public 69.18 + * License along with this library; if not, write to the Free Software 69.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 69.20 + */ 69.21 + 69.22 +#ifndef XEN_CONSOLE_H 69.23 +#define XEN_CONSOLE_H 69.24 + 69.25 +#include "xen_common.h" 69.26 +#include "xen_console_decl.h" 69.27 +#include "xen_console_protocol.h" 69.28 +#include "xen_vm_decl.h" 69.29 + 69.30 + 69.31 +/* 69.32 + * The console class. 69.33 + * 69.34 + * A console. 69.35 + */ 69.36 + 69.37 + 69.38 +/** 69.39 + * Free the given xen_console. The given handle must have been 69.40 + * allocated by this library. 69.41 + */ 69.42 +extern void 69.43 +xen_console_free(xen_console console); 69.44 + 69.45 + 69.46 +typedef struct xen_console_set 69.47 +{ 69.48 + size_t size; 69.49 + xen_console *contents[]; 69.50 +} xen_console_set; 69.51 + 69.52 +/** 69.53 + * Allocate a xen_console_set of the given size. 69.54 + */ 69.55 +extern xen_console_set * 69.56 +xen_console_set_alloc(size_t size); 69.57 + 69.58 +/** 69.59 + * Free the given xen_console_set. The given set must have been 69.60 + * allocated by this library. 69.61 + */ 69.62 +extern void 69.63 +xen_console_set_free(xen_console_set *set); 69.64 + 69.65 + 69.66 +typedef struct xen_console_record 69.67 +{ 69.68 + xen_console handle; 69.69 + char *uuid; 69.70 + enum xen_console_protocol protocol; 69.71 + char *uri; 69.72 + struct xen_vm_record_opt *vm; 69.73 +} xen_console_record; 69.74 + 69.75 +/** 69.76 + * Allocate a xen_console_record. 69.77 + */ 69.78 +extern xen_console_record * 69.79 +xen_console_record_alloc(void); 69.80 + 69.81 +/** 69.82 + * Free the given xen_console_record, and all referenced values. The 69.83 + * given record must have been allocated by this library. 69.84 + */ 69.85 +extern void 69.86 +xen_console_record_free(xen_console_record *record); 69.87 + 69.88 + 69.89 +typedef struct xen_console_record_opt 69.90 +{ 69.91 + bool is_record; 69.92 + union 69.93 + { 69.94 + xen_console handle; 69.95 + xen_console_record *record; 69.96 + } u; 69.97 +} xen_console_record_opt; 69.98 + 69.99 +/** 69.100 + * Allocate a xen_console_record_opt. 69.101 + */ 69.102 +extern xen_console_record_opt * 69.103 +xen_console_record_opt_alloc(void); 69.104 + 69.105 +/** 69.106 + * Free the given xen_console_record_opt, and all referenced values. 69.107 + * The given record_opt must have been allocated by this library. 69.108 + */ 69.109 +extern void 69.110 +xen_console_record_opt_free(xen_console_record_opt *record_opt); 69.111 + 69.112 + 69.113 +typedef struct xen_console_record_set 69.114 +{ 69.115 + size_t size; 69.116 + xen_console_record *contents[]; 69.117 +} xen_console_record_set; 69.118 + 69.119 +/** 69.120 + * Allocate a xen_console_record_set of the given size. 69.121 + */ 69.122 +extern xen_console_record_set * 69.123 +xen_console_record_set_alloc(size_t size); 69.124 + 69.125 +/** 69.126 + * Free the given xen_console_record_set, and all referenced values. 69.127 + * The given set must have been allocated by this library. 69.128 + */ 69.129 +extern void 69.130 +xen_console_record_set_free(xen_console_record_set *set); 69.131 + 69.132 + 69.133 + 69.134 +typedef struct xen_console_record_opt_set 69.135 +{ 69.136 + size_t size; 69.137 + xen_console_record_opt *contents[]; 69.138 +} xen_console_record_opt_set; 69.139 + 69.140 +/** 69.141 + * Allocate a xen_console_record_opt_set of the given size. 69.142 + */ 69.143 +extern xen_console_record_opt_set * 69.144 +xen_console_record_opt_set_alloc(size_t size); 69.145 + 69.146 +/** 69.147 + * Free the given xen_console_record_opt_set, and all referenced 69.148 + * values. The given set must have been allocated by this library. 69.149 + */ 69.150 +extern void 69.151 +xen_console_record_opt_set_free(xen_console_record_opt_set *set); 69.152 + 69.153 + 69.154 +/** 69.155 + * Get the current state of the given console. 69.156 + */ 69.157 +extern bool 69.158 +xen_console_get_record(xen_session *session, xen_console_record **result, xen_console console); 69.159 + 69.160 + 69.161 +/** 69.162 + * Get a reference to the object with the specified UUID. 69.163 + */ 69.164 +extern bool 69.165 +xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid); 69.166 + 69.167 + 69.168 +/** 69.169 + * Create a new console instance, and return its handle. 69.170 + */ 69.171 +extern bool 69.172 +xen_console_create(xen_session *session, xen_console *result, xen_console_record *record); 69.173 + 69.174 + 69.175 +/** 69.176 + * Destroy the specified console instance. 69.177 + */ 69.178 +extern bool 69.179 +xen_console_destroy(xen_session *session, xen_console console); 69.180 + 69.181 + 69.182 +/** 69.183 + * Get the uuid field of the given console. 69.184 + */ 69.185 +extern bool 69.186 +xen_console_get_uuid(xen_session *session, char **result, xen_console console); 69.187 + 69.188 + 69.189 +/** 69.190 + * Get the protocol field of the given console. 69.191 + */ 69.192 +extern bool 69.193 +xen_console_get_protocol(xen_session *session, enum xen_console_protocol *result, xen_console console); 69.194 + 69.195 + 69.196 +/** 69.197 + * Get the uri field of the given console. 69.198 + */ 69.199 +extern bool 69.200 +xen_console_get_uri(xen_session *session, char **result, xen_console console); 69.201 + 69.202 + 69.203 +/** 69.204 + * Get the VM field of the given console. 69.205 + */ 69.206 +extern bool 69.207 +xen_console_get_vm(xen_session *session, xen_vm *result, xen_console console); 69.208 + 69.209 + 69.210 +#endif
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/tools/libxen/include/xen_console_decl.h Mon Dec 04 08:24:41 2006 -0700 70.3 @@ -0,0 +1,30 @@ 70.4 +/* 70.5 + * Copyright (c) 2006, XenSource Inc. 70.6 + * 70.7 + * This library is free software; you can redistribute it and/or 70.8 + * modify it under the terms of the GNU Lesser General Public 70.9 + * License as published by the Free Software Foundation; either 70.10 + * version 2.1 of the License, or (at your option) any later version. 70.11 + * 70.12 + * This library is distributed in the hope that it will be useful, 70.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 70.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 70.15 + * Lesser General Public License for more details. 70.16 + * 70.17 + * You should have received a copy of the GNU Lesser General Public 70.18 + * License along with this library; if not, write to the Free Software 70.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 70.20 + */ 70.21 + 70.22 +#ifndef XEN_CONSOLE_DECL_H 70.23 +#define XEN_CONSOLE_DECL_H 70.24 + 70.25 +typedef void *xen_console; 70.26 + 70.27 +struct xen_console_set; 70.28 +struct xen_console_record; 70.29 +struct xen_console_record_set; 70.30 +struct xen_console_record_opt; 70.31 +struct xen_console_record_opt_set; 70.32 + 70.33 +#endif
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/tools/libxen/include/xen_console_protocol.h Mon Dec 04 08:24:41 2006 -0700 71.3 @@ -0,0 +1,82 @@ 71.4 +/* 71.5 + * Copyright (c) 2006, XenSource Inc. 71.6 + * 71.7 + * This library is free software; you can redistribute it and/or 71.8 + * modify it under the terms of the GNU Lesser General Public 71.9 + * License as published by the Free Software Foundation; either 71.10 + * version 2.1 of the License, or (at your option) any later version. 71.11 + * 71.12 + * This library is distributed in the hope that it will be useful, 71.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 71.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 71.15 + * Lesser General Public License for more details. 71.16 + * 71.17 + * You should have received a copy of the GNU Lesser General Public 71.18 + * License along with this library; if not, write to the Free Software 71.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 71.20 + */ 71.21 + 71.22 +#ifndef XEN_CONSOLE_PROTOCOL_H 71.23 +#define XEN_CONSOLE_PROTOCOL_H 71.24 + 71.25 + 71.26 +#include "xen_common.h" 71.27 + 71.28 + 71.29 +enum xen_console_protocol 71.30 +{ 71.31 + /** 71.32 + * VT100 terminal 71.33 + */ 71.34 + XEN_CONSOLE_PROTOCOL_VT100, 71.35 + 71.36 + /** 71.37 + * Remote FrameBuffer protocol (as used in VNC) 71.38 + */ 71.39 + XEN_CONSOLE_PROTOCOL_RFB, 71.40 + 71.41 + /** 71.42 + * Remote Desktop Protocol 71.43 + */ 71.44 + XEN_CONSOLE_PROTOCOL_RDP 71.45 +}; 71.46 + 71.47 + 71.48 +typedef struct xen_console_protocol_set 71.49 +{ 71.50 + size_t size; 71.51 + enum xen_console_protocol contents[]; 71.52 +} xen_console_protocol_set; 71.53 + 71.54 +/** 71.55 + * Allocate a xen_console_protocol_set of the given size. 71.56 + */ 71.57 +extern xen_console_protocol_set * 71.58 +xen_console_protocol_set_alloc(size_t size); 71.59 + 71.60 +/** 71.61 + * Free the given xen_console_protocol_set. The given set must have 71.62 + * been allocated by this library. 71.63 + */ 71.64 +extern void 71.65 +xen_console_protocol_set_free(xen_console_protocol_set *set); 71.66 + 71.67 + 71.68 +/** 71.69 + * Return the name corresponding to the given code. This string must 71.70 + * not be modified or freed. 71.71 + */ 71.72 +extern const char * 71.73 +xen_console_protocol_to_string(enum xen_console_protocol val); 71.74 + 71.75 + 71.76 +/** 71.77 + * Return the correct code for the given string, or set the session 71.78 + * object to failure and return an undefined value if the given string does 71.79 + * not match a known code. 71.80 + */ 71.81 +extern enum xen_console_protocol 71.82 +xen_console_protocol_from_string(xen_session *session, const char *str); 71.83 + 71.84 + 71.85 +#endif
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/tools/libxen/include/xen_console_protocol_internal.h Mon Dec 04 08:24:41 2006 -0700 72.3 @@ -0,0 +1,37 @@ 72.4 +/* 72.5 + * Copyright (c) 2006, XenSource Inc. 72.6 + * 72.7 + * This library is free software; you can redistribute it and/or 72.8 + * modify it under the terms of the GNU Lesser General Public 72.9 + * License as published by the Free Software Foundation; either 72.10 + * version 2.1 of the License, or (at your option) any later version. 72.11 + * 72.12 + * This library is distributed in the hope that it will be useful, 72.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 72.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 72.15 + * Lesser General Public License for more details. 72.16 + * 72.17 + * You should have received a copy of the GNU Lesser General Public 72.18 + * License along with this library; if not, write to the Free Software 72.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 72.20 + */ 72.21 + 72.22 + 72.23 +/* 72.24 + * Declarations of the abstract types used during demarshalling of enum 72.25 + * xen_console_protocol. Internal to this library -- do not use from outside. 72.26 + */ 72.27 + 72.28 + 72.29 +#ifndef XEN_CONSOLE_PROTOCOL_INTERNAL_H 72.30 +#define XEN_CONSOLE_PROTOCOL_INTERNAL_H 72.31 + 72.32 + 72.33 +#include "xen_internal.h" 72.34 + 72.35 + 72.36 +extern const abstract_type xen_console_protocol_abstract_type_; 72.37 +extern const abstract_type xen_console_protocol_set_abstract_type_; 72.38 + 72.39 + 72.40 +#endif
73.1 --- a/tools/libxen/include/xen_vm.h Sat Dec 02 15:19:50 2006 -0700 73.2 +++ b/tools/libxen/include/xen_vm.h Mon Dec 04 08:24:41 2006 -0700 73.3 @@ -21,6 +21,7 @@ 73.4 73.5 #include "xen_boot_type.h" 73.6 #include "xen_common.h" 73.7 +#include "xen_console_decl.h" 73.8 #include "xen_cpu_feature.h" 73.9 #include "xen_host_decl.h" 73.10 #include "xen_int_float_map.h" 73.11 @@ -96,6 +97,7 @@ typedef struct xen_vm_record 73.12 enum xen_on_normal_exit actions_after_reboot; 73.13 enum xen_on_normal_exit actions_after_suspend; 73.14 enum xen_on_crash_behaviour actions_after_crash; 73.15 + struct xen_console_record_opt_set *consoles; 73.16 struct xen_vif_record_opt_set *vifs; 73.17 struct xen_vbd_record_opt_set *vbds; 73.18 struct xen_vtpm_record_opt_set *vtpms; 73.19 @@ -401,6 +403,13 @@ xen_vm_get_actions_after_crash(xen_sessi 73.20 73.21 73.22 /** 73.23 + * Get the consoles field of the given VM. 73.24 + */ 73.25 +extern bool 73.26 +xen_vm_get_consoles(xen_session *session, struct xen_console_set **result, xen_vm vm); 73.27 + 73.28 + 73.29 +/** 73.30 * Get the VIFs field of the given VM. 73.31 */ 73.32 extern bool
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/tools/libxen/src/xen_console.c Mon Dec 04 08:24:41 2006 -0700 74.3 @@ -0,0 +1,207 @@ 74.4 +/* 74.5 + * Copyright (c) 2006, XenSource Inc. 74.6 + * 74.7 + * This library is free software; you can redistribute it and/or 74.8 + * modify it under the terms of the GNU Lesser General Public 74.9 + * License as published by the Free Software Foundation; either 74.10 + * version 2.1 of the License, or (at your option) any later version. 74.11 + * 74.12 + * This library is distributed in the hope that it will be useful, 74.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 74.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 74.15 + * Lesser General Public License for more details. 74.16 + * 74.17 + * You should have received a copy of the GNU Lesser General Public 74.18 + * License along with this library; if not, write to the Free Software 74.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 74.20 + */ 74.21 + 74.22 + 74.23 +#include <stddef.h> 74.24 +#include <stdlib.h> 74.25 + 74.26 +#include "xen_common.h" 74.27 +#include "xen_console.h" 74.28 +#include "xen_console_protocol_internal.h" 74.29 +#include "xen_internal.h" 74.30 +#include "xen_vm.h" 74.31 + 74.32 + 74.33 +XEN_FREE(xen_console) 74.34 +XEN_SET_ALLOC_FREE(xen_console) 74.35 +XEN_ALLOC(xen_console_record) 74.36 +XEN_SET_ALLOC_FREE(xen_console_record) 74.37 +XEN_ALLOC(xen_console_record_opt) 74.38 +XEN_RECORD_OPT_FREE(xen_console) 74.39 +XEN_SET_ALLOC_FREE(xen_console_record_opt) 74.40 + 74.41 + 74.42 +static const struct_member xen_console_record_struct_members[] = 74.43 + { 74.44 + { .key = "uuid", 74.45 + .type = &abstract_type_string, 74.46 + .offset = offsetof(xen_console_record, uuid) }, 74.47 + { .key = "protocol", 74.48 + .type = &xen_console_protocol_abstract_type_, 74.49 + .offset = offsetof(xen_console_record, protocol) }, 74.50 + { .key = "uri", 74.51 + .type = &abstract_type_string, 74.52 + .offset = offsetof(xen_console_record, uri) }, 74.53 + { .key = "VM", 74.54 + .type = &abstract_type_ref, 74.55 + .offset = offsetof(xen_console_record, vm) } 74.56 + }; 74.57 + 74.58 +const abstract_type xen_console_record_abstract_type_ = 74.59 + { 74.60 + .typename = STRUCT, 74.61 + .struct_size = sizeof(xen_console_record), 74.62 + .member_count = 74.63 + sizeof(xen_console_record_struct_members) / sizeof(struct_member), 74.64 + .members = xen_console_record_struct_members 74.65 + }; 74.66 + 74.67 + 74.68 +void 74.69 +xen_console_record_free(xen_console_record *record) 74.70 +{ 74.71 + if (record == NULL) 74.72 + { 74.73 + return; 74.74 + } 74.75 + free(record->handle); 74.76 + free(record->uuid); 74.77 + free(record->uri); 74.78 + xen_vm_record_opt_free(record->vm); 74.79 + free(record); 74.80 +} 74.81 + 74.82 + 74.83 +bool 74.84 +xen_console_get_record(xen_session *session, xen_console_record **result, xen_console console) 74.85 +{ 74.86 + abstract_value param_values[] = 74.87 + { 74.88 + { .type = &abstract_type_string, 74.89 + .u.string_val = console } 74.90 + }; 74.91 + 74.92 + abstract_type result_type = xen_console_record_abstract_type_; 74.93 + 74.94 + *result = NULL; 74.95 + XEN_CALL_("console.get_record"); 74.96 + 74.97 + if (session->ok) 74.98 + { 74.99 + (*result)->handle = xen_strdup_((*result)->uuid); 74.100 + } 74.101 + 74.102 + return session->ok; 74.103 +} 74.104 + 74.105 + 74.106 +bool 74.107 +xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid) 74.108 +{ 74.109 + abstract_value param_values[] = 74.110 + { 74.111 + { .type = &abstract_type_string, 74.112 + .u.string_val = uuid } 74.113 + }; 74.114 + 74.115 + abstract_type result_type = abstract_type_string; 74.116 + 74.117 + *result = NULL; 74.118 + XEN_CALL_("console.get_by_uuid"); 74.119 + return session->ok; 74.120 +} 74.121 + 74.122 + 74.123 +bool 74.124 +xen_console_create(xen_session *session, xen_console *result, xen_console_record *record) 74.125 +{ 74.126 + abstract_value param_values[] = 74.127 + { 74.128 + { .type = &xen_console_record_abstract_type_, 74.129 + .u.struct_val = record } 74.130 + }; 74.131 + 74.132 + abstract_type result_type = abstract_type_string; 74.133 + 74.134 + *result = NULL; 74.135 + XEN_CALL_("console.create"); 74.136 + return session->ok; 74.137 +} 74.138 + 74.139 + 74.140 +bool 74.141 +xen_console_destroy(xen_session *session, xen_console console) 74.142 +{ 74.143 + abstract_value param_values[] = 74.144 + { 74.145 + { .type = &abstract_type_string, 74.146 + .u.string_val = console } 74.147 + }; 74.148 + 74.149 + xen_call_(session, "console.destroy", param_values, 1, NULL, NULL); 74.150 + return session->ok; 74.151 +} 74.152 + 74.153 + 74.154 +bool 74.155 +xen_console_get_protocol(xen_session *session, enum xen_console_protocol *result, xen_console console) 74.156 +{ 74.157 + abstract_value param_values[] = 74.158 + { 74.159 + { .type = &abstract_type_string, 74.160 + .u.string_val = console } 74.161 + }; 74.162 + 74.163 + abstract_type result_type = xen_console_protocol_abstract_type_; 74.164 + char *result_str = NULL; 74.165 + XEN_CALL_("console.get_protocol"); 74.166 + *result = xen_console_protocol_from_string(session, result_str); 74.167 + return session->ok; 74.168 +} 74.169 + 74.170 + 74.171 +bool 74.172 +xen_console_get_uri(xen_session *session, char **result, xen_console console) 74.173 +{ 74.174 + abstract_value param_values[] = 74.175 + { 74.176 + { .type = &abstract_type_string, 74.177 + .u.string_val = console } 74.178 + }; 74.179 + 74.180 + abstract_type result_type = abstract_type_string; 74.181 + 74.182 + *result = NULL; 74.183 + XEN_CALL_("console.get_uri"); 74.184 + return session->ok; 74.185 +} 74.186 + 74.187 + 74.188 +bool 74.189 +xen_console_get_vm(xen_session *session, xen_vm *result, xen_console console) 74.190 +{ 74.191 + abstract_value param_values[] = 74.192 + { 74.193 + { .type = &abstract_type_string, 74.194 + .u.string_val = console } 74.195 + }; 74.196 + 74.197 + abstract_type result_type = abstract_type_string; 74.198 + 74.199 + *result = NULL; 74.200 + XEN_CALL_("console.get_VM"); 74.201 + return session->ok; 74.202 +} 74.203 + 74.204 + 74.205 +bool 74.206 +xen_console_get_uuid(xen_session *session, char **result, xen_console console) 74.207 +{ 74.208 + *result = session->ok ? xen_strdup_((char *)console) : NULL; 74.209 + return session->ok; 74.210 +}
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/tools/libxen/src/xen_console_protocol.c Mon Dec 04 08:24:41 2006 -0700 75.3 @@ -0,0 +1,82 @@ 75.4 +/* 75.5 + * Copyright (c) 2006, XenSource Inc. 75.6 + * 75.7 + * This library is free software; you can redistribute it and/or 75.8 + * modify it under the terms of the GNU Lesser General Public 75.9 + * License as published by the Free Software Foundation; either 75.10 + * version 2.1 of the License, or (at your option) any later version. 75.11 + * 75.12 + * This library is distributed in the hope that it will be useful, 75.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 75.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 75.15 + * Lesser General Public License for more details. 75.16 + * 75.17 + * You should have received a copy of the GNU Lesser General Public 75.18 + * License along with this library; if not, write to the Free Software 75.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 75.20 + */ 75.21 + 75.22 +#include <string.h> 75.23 + 75.24 +#include "xen_internal.h" 75.25 +#include "xen_console_protocol.h" 75.26 +#include "xen_console_protocol_internal.h" 75.27 + 75.28 + 75.29 +/* 75.30 + * Maintain this in the same order as the enum declaration! 75.31 + */ 75.32 +static const char *lookup_table[] = 75.33 +{ 75.34 + "vt100", 75.35 + "rfb", 75.36 + "rdp" 75.37 +}; 75.38 + 75.39 + 75.40 +extern xen_console_protocol_set * 75.41 +xen_console_protocol_set_alloc(size_t size) 75.42 +{ 75.43 + return calloc(1, sizeof(xen_console_protocol_set) + 75.44 + size * sizeof(enum xen_console_protocol)); 75.45 +} 75.46 + 75.47 + 75.48 +extern void 75.49 +xen_console_protocol_set_free(xen_console_protocol_set *set) 75.50 +{ 75.51 + free(set); 75.52 +} 75.53 + 75.54 + 75.55 +const char * 75.56 +xen_console_protocol_to_string(enum xen_console_protocol val) 75.57 +{ 75.58 + return lookup_table[val]; 75.59 +} 75.60 + 75.61 + 75.62 +extern enum xen_console_protocol 75.63 +xen_console_protocol_from_string(xen_session *session, const char *str) 75.64 +{ 75.65 + return ENUM_LOOKUP(session, str, lookup_table); 75.66 +} 75.67 + 75.68 + 75.69 +const abstract_type xen_console_protocol_abstract_type_ = 75.70 + { 75.71 + .typename = ENUM, 75.72 + .enum_marshaller = 75.73 + (const char *(*)(int))&xen_console_protocol_to_string, 75.74 + .enum_demarshaller = 75.75 + (int (*)(xen_session *, const char *))&xen_console_protocol_from_string 75.76 + }; 75.77 + 75.78 + 75.79 +const abstract_type xen_console_protocol_set_abstract_type_ = 75.80 + { 75.81 + .typename = SET, 75.82 + .child = &xen_console_protocol_abstract_type_ 75.83 + }; 75.84 + 75.85 +
76.1 --- a/tools/libxen/src/xen_vm.c Sat Dec 02 15:19:50 2006 -0700 76.2 +++ b/tools/libxen/src/xen_vm.c Mon Dec 04 08:24:41 2006 -0700 76.3 @@ -22,6 +22,7 @@ 76.4 76.5 #include "xen_boot_type_internal.h" 76.6 #include "xen_common.h" 76.7 +#include "xen_console.h" 76.8 #include "xen_cpu_feature.h" 76.9 #include "xen_cpu_feature_internal.h" 76.10 #include "xen_host.h" 76.11 @@ -120,6 +121,9 @@ static const struct_member xen_vm_record 76.12 { .key = "actions_after_crash", 76.13 .type = &xen_on_crash_behaviour_abstract_type_, 76.14 .offset = offsetof(xen_vm_record, actions_after_crash) }, 76.15 + { .key = "consoles", 76.16 + .type = &abstract_type_ref_set, 76.17 + .offset = offsetof(xen_vm_record, consoles) }, 76.18 { .key = "VIFs", 76.19 .type = &abstract_type_ref_set, 76.20 .offset = offsetof(xen_vm_record, vifs) }, 76.21 @@ -205,6 +209,7 @@ xen_vm_record_free(xen_vm_record *record 76.22 xen_cpu_feature_set_free(record->vcpus_features_can_use); 76.23 xen_cpu_feature_set_free(record->vcpus_features_force_on); 76.24 xen_cpu_feature_set_free(record->vcpus_features_force_off); 76.25 + xen_console_record_opt_set_free(record->consoles); 76.26 xen_vif_record_opt_set_free(record->vifs); 76.27 xen_vbd_record_opt_set_free(record->vbds); 76.28 xen_vtpm_record_opt_set_free(record->vtpms); 76.29 @@ -694,6 +699,23 @@ xen_vm_get_actions_after_crash(xen_sessi 76.30 76.31 76.32 bool 76.33 +xen_vm_get_consoles(xen_session *session, struct xen_console_set **result, xen_vm vm) 76.34 +{ 76.35 + abstract_value param_values[] = 76.36 + { 76.37 + { .type = &abstract_type_string, 76.38 + .u.string_val = vm } 76.39 + }; 76.40 + 76.41 + abstract_type result_type = abstract_type_string_set; 76.42 + 76.43 + *result = NULL; 76.44 + XEN_CALL_("VM.get_consoles"); 76.45 + return session->ok; 76.46 +} 76.47 + 76.48 + 76.49 +bool 76.50 xen_vm_get_vifs(xen_session *session, struct xen_vif_set **result, xen_vm vm) 76.51 { 76.52 abstract_value param_values[] =
77.1 --- a/tools/python/scripts/xapi.domcfg.py Sat Dec 02 15:19:50 2006 -0700 77.2 +++ b/tools/python/scripts/xapi.domcfg.py Mon Dec 04 08:24:41 2006 -0700 77.3 @@ -26,7 +26,7 @@ platform_serial = '' 77.4 platform_localtime = False 77.5 platform_clock_offset = False 77.6 platform_enable_audio = False 77.7 -builder = '' 77.8 +builder = 'linux' 77.9 boot_method = '' # this will remove the kernel/initrd ?? 77.10 kernel_kernel = '/boot/vmlinuz-2.6.16.29-xen' 77.11 kernel_initrd = '/root/initrd-2.6.16.29-xen.img'
78.1 --- a/tools/python/scripts/xapi.py Sat Dec 02 15:19:50 2006 -0700 78.2 +++ b/tools/python/scripts/xapi.py Mon Dec 04 08:24:41 2006 -0700 78.3 @@ -29,17 +29,20 @@ from getpass import getpass 78.4 MB = 1024 * 1024 78.5 78.6 HOST_INFO_FORMAT = '%-20s: %-50s' 78.7 -VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(vcpus_number)-5s'\ 78.8 +VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(VCPUs_number)-5s'\ 78.9 ' %(power_state)-10s %(uuid)-36s' 78.10 SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \ 78.11 '%(type)-10s' 78.12 VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\ 78.13 '%(sector_size)-8s' 78.14 +VBD_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(VDI)-8s '\ 78.15 + '%(image)-8s' 78.16 78.17 COMMANDS = { 78.18 'host-info': ('', 'Get Xen Host Info'), 78.19 'host-set-name': ('', 'Set host name'), 78.20 'sr-list': ('', 'List all SRs'), 78.21 + 'vbd-list': ('', 'List all VBDs'), 78.22 'vbd-create': ('<domname> <pycfg> [opts]', 78.23 'Create VBD attached to domname'), 78.24 'vdi-create': ('<pycfg> [opts]', 'Create a VDI'), 78.25 @@ -165,6 +168,13 @@ def resolve_vm(server, session, vm_name) 78.26 else: 78.27 return vm_uuid[0] 78.28 78.29 +def resolve_vdi(server, session, vdi_name): 78.30 + vdi_uuid = execute(server.VDI.get_by_name_label, session, vdi_name) 78.31 + if not vdi_uuid: 78.32 + return None 78.33 + else: 78.34 + return vdi_uuid[0] 78.35 + 78.36 # 78.37 # Actual commands 78.38 # 78.39 @@ -216,16 +226,16 @@ def xapi_vm_list(*args): 78.40 if not is_long: 78.41 print VM_LIST_FORMAT % {'name_label':'Name', 78.42 'memory_actual':'Mem', 78.43 - 'vcpus_number': 'VCPUs', 78.44 + 'VCPUs_number': 'VCPUs', 78.45 'power_state': 'State', 78.46 'uuid': 'UUID'} 78.47 78.48 for uuid in vm_uuids: 78.49 vm_info = execute(server.VM.get_record, session, uuid) 78.50 if is_long: 78.51 - vbds = vm_info['vbds'] 78.52 - vifs = vm_info['vifs'] 78.53 - vtpms = vm_info['vtpms'] 78.54 + vbds = vm_info['VBDs'] 78.55 + vifs = vm_info['VIFs'] 78.56 + vtpms = vm_info['VTPMs'] 78.57 vif_infos = [] 78.58 vbd_infos = [] 78.59 vtpm_infos = [] 78.60 @@ -238,9 +248,9 @@ def xapi_vm_list(*args): 78.61 for vtpm in vtpms: 78.62 vtpm_info = execute(server.VTPM.get_record, session, vtpm) 78.63 vtpm_infos.append(vtpm_info) 78.64 - vm_info['vbds'] = vbd_infos 78.65 - vm_info['vifs'] = vif_infos 78.66 - vm_info['vtpms'] = vtpm_infos 78.67 + vm_info['VBDs'] = vbd_infos 78.68 + vm_info['VIFs'] = vif_infos 78.69 + vm_info['VTPMs'] = vtpm_infos 78.70 pprint(vm_info) 78.71 else: 78.72 print VM_LIST_FORMAT % _stringify(vm_info) 78.73 @@ -276,7 +286,7 @@ def xapi_vm_start(*args): 78.74 server, session = _connect() 78.75 vm_uuid = resolve_vm(server, session, args[0]) 78.76 print 'Starting VM %s (%s)' % (args[0], vm_uuid) 78.77 - success = execute(server.VM.start, session, vm_uuid) 78.78 + success = execute(server.VM.start, session, vm_uuid, False) 78.79 print 'Done.' 78.80 78.81 def xapi_vm_shutdown(*args): 78.82 @@ -334,6 +344,22 @@ def xapi_vif_create(*args): 78.83 vif_uuid = execute(server.VIF.create, session, cfg) 78.84 print 'Done. (%s)' % vif_uuid 78.85 78.86 +def xapi_vbd_list(*args): 78.87 + server, session = _connect() 78.88 + domname = args[0] 78.89 + 78.90 + dom_uuid = resolve_vm(server, session, domname) 78.91 + vbds = execute(server.VM.get_VBDs, session, dom_uuid) 78.92 + 78.93 + print VBD_LIST_FORMAT % {'name_label': 'VDI Label', 78.94 + 'uuid' : 'UUID', 78.95 + 'VDI': 'VDI', 78.96 + 'image': 'Image'} 78.97 + 78.98 + for vbd in vbds: 78.99 + vbd_struct = execute(server.VBD.get_record, session, vbd) 78.100 + print VBD_LIST_FORMAT % vbd_struct 78.101 + 78.102 def xapi_vdi_list(*args): 78.103 server, session = _connect() 78.104 vdis = execute(server.VDI.get_all, session) 78.105 @@ -420,8 +446,6 @@ def xapi_vtpm_create(*args): 78.106 print "Has driver type '%s'" % driver 78.107 vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid) 78.108 print "Has vtpm record '%s'" % vtpm_rec 78.109 - vm = execute(server.VTPM.get_VM, session, vtpm_uuid) 78.110 - print "Has VM '%s'" % vm 78.111 78.112 78.113 #
79.1 --- a/tools/python/xen/lowlevel/xc/xc.c Sat Dec 02 15:19:50 2006 -0700 79.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Mon Dec 04 08:24:41 2006 -0700 79.3 @@ -392,7 +392,7 @@ static PyObject *pyxc_hvm_build(XcObject 79.4 return PyErr_SetFromErrno(xc_error); 79.5 79.6 /* Set up the HVM info table. */ 79.7 - va_map = xc_map_foreign_range(self->xc_handle, dom, PAGE_SIZE, 79.8 + va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE, 79.9 PROT_READ | PROT_WRITE, 79.10 HVM_INFO_PFN); 79.11 if ( va_map == NULL ) 79.12 @@ -407,7 +407,7 @@ static PyObject *pyxc_hvm_build(XcObject 79.13 for ( i = 0, sum = 0; i < va_hvm->length; i++ ) 79.14 sum += ((uint8_t *)va_hvm)[i]; 79.15 va_hvm->checksum = -sum; 79.16 - munmap(va_map, PAGE_SIZE); 79.17 + munmap(va_map, XC_PAGE_SIZE); 79.18 79.19 xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn); 79.20 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
80.1 --- a/tools/python/xen/util/bugtool.py Sat Dec 02 15:19:50 2006 -0700 80.2 +++ b/tools/python/xen/util/bugtool.py Mon Dec 04 08:24:41 2006 -0700 80.3 @@ -43,8 +43,9 @@ TITLE_RE = re.compile(r'<title>(.*)</tit 80.4 80.5 FILES_TO_SEND = [ '/var/log/' + x for x in 80.6 [ 'syslog', 'messages', 'debug', 80.7 - 'xen/xend.log', 'xen/xend-debug.log', 'xen/xenstored-trace.log', 80.8 - 'xen/xen-hotplug.log' ] ] 80.9 + 'xen/xend-debug.log', 'xen/xenstored-trace.log', 80.10 + 'xen/xen-hotplug.log', 'xen/xend.log' ] + 80.11 + [ 'xen/xend.log.%d' % z for z in range(1,6) ] ] 80.12 #FILES_TO_SEND = [ ] 80.13 80.14
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/tools/python/xen/util/mkdir.py Mon Dec 04 08:24:41 2006 -0700 81.3 @@ -0,0 +1,44 @@ 81.4 +#============================================================================ 81.5 +# This library is free software; you can redistribute it and/or modify 81.6 +# it under the terms of the GNU Lesser General Public License as published by 81.7 +# the Free Software Foundation; either version 2.1 of the License, or 81.8 +# (at your option) any later version. 81.9 +# 81.10 +# This library is distributed in the hope that it will be useful, 81.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 81.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 81.13 +# GNU Lesser General Public License for more details. 81.14 +# 81.15 +# You should have received a copy of the GNU Lesser General Public License 81.16 +# along with this library; if not, write to the Free Software 81.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 81.18 +#============================================================================ 81.19 +# Copyright (c) 2006 XenSource Inc. 81.20 +#============================================================================ 81.21 + 81.22 +import errno 81.23 +import os 81.24 +import os.path 81.25 +import stat 81.26 + 81.27 + 81.28 +def parents(dir, perms, enforcePermissions = False): 81.29 + """ 81.30 + Ensure that the given directory exists, creating it if necessary, but not 81.31 + complaining if it's already there. 81.32 + 81.33 + @param dir The directory name. 81.34 + @param perms One of the stat.S_ constants. 81.35 + @param enforcePermissions Enforce our ownership and the given permissions, 81.36 + even if the directory pre-existed with different ones. 81.37 + """ 81.38 + # Catch the exception here, rather than checking for the directory's 81.39 + # existence first, to avoid races. 81.40 + try: 81.41 + os.makedirs(dir, perms) 81.42 + except OSError, exn: 81.43 + if exn.args[0] != errno.EEXIST or not os.path.isdir(dir): 81.44 + raise 81.45 + if enforcePermissions: 81.46 + os.chown(dir, os.geteuid(), os.getegid()) 81.47 + os.chmod(dir, stat.S_IRWXU)
82.1 --- a/tools/python/xen/util/xmlrpclib2.py Sat Dec 02 15:19:50 2006 -0700 82.2 +++ b/tools/python/xen/util/xmlrpclib2.py Mon Dec 04 08:24:41 2006 -0700 82.3 @@ -30,6 +30,8 @@ from SimpleXMLRPCServer import SimpleXML 82.4 import SocketServer 82.5 import xmlrpclib, socket, os, stat 82.6 82.7 +import mkdir 82.8 + 82.9 from xen.web import connection 82.10 from xen.xend.XendLogging import log 82.11 82.12 @@ -234,14 +236,9 @@ class UnixXMLRPCServer(TCPXMLRPCServer): 82.13 address_family = socket.AF_UNIX 82.14 82.15 def __init__(self, addr, allowed, logRequests = 1): 82.16 - parent = os.path.dirname(addr) 82.17 - if os.path.exists(parent): 82.18 - os.chown(parent, os.geteuid(), os.getegid()) 82.19 - os.chmod(parent, stat.S_IRWXU) 82.20 - if self.allow_reuse_address and os.path.exists(addr): 82.21 - os.unlink(addr) 82.22 - else: 82.23 - os.makedirs(parent, stat.S_IRWXU) 82.24 + mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True) 82.25 + if self.allow_reuse_address and os.path.exists(addr): 82.26 + os.unlink(addr) 82.27 82.28 TCPXMLRPCServer.__init__(self, addr, allowed, 82.29 UnixXMLRPCRequestHandler, logRequests)
83.1 --- a/tools/python/xen/web/unix.py Sat Dec 02 15:19:50 2006 -0700 83.2 +++ b/tools/python/xen/web/unix.py Mon Dec 04 08:24:41 2006 -0700 83.3 @@ -22,6 +22,8 @@ import os.path 83.4 import socket 83.5 import stat 83.6 83.7 +from xen.util import mkdir 83.8 + 83.9 import connection 83.10 83.11 83.12 @@ -30,13 +32,9 @@ def bind(path): 83.13 created such that only the current user may access it.""" 83.14 83.15 parent = os.path.dirname(path) 83.16 - if os.path.exists(parent): 83.17 - os.chown(parent, os.geteuid(), os.getegid()) 83.18 - os.chmod(parent, stat.S_IRWXU) 83.19 - if os.path.exists(path): 83.20 - os.unlink(path) 83.21 - else: 83.22 - os.makedirs(parent, stat.S_IRWXU) 83.23 + mkdir.parents(parent, stat.S_IRWXU, True) 83.24 + if os.path.exists(path): 83.25 + os.unlink(path) 83.26 83.27 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 83.28 sock.bind(path)
84.1 --- a/tools/python/xen/xend/XendAPI.py Sat Dec 02 15:19:50 2006 -0700 84.2 +++ b/tools/python/xen/xend/XendAPI.py Mon Dec 04 08:24:41 2006 -0700 84.3 @@ -303,8 +303,8 @@ class XendAPI: 84.4 # all get_by_uuid() methods. 84.5 84.6 for cls in classes.keys(): 84.7 - get_by_uuid = '%s_get_by_uuid' % cls.lower() 84.8 - get_uuid = '%s_get_uuid' % cls.lower() 84.9 + get_by_uuid = '%s_get_by_uuid' % cls 84.10 + get_uuid = '%s_get_uuid' % cls 84.11 setattr(XendAPI, get_by_uuid, 84.12 lambda s, sess, obj_ref: xen_api_success(obj_ref)) 84.13 setattr(XendAPI, get_uuid, 84.14 @@ -327,7 +327,7 @@ class XendAPI: 84.15 84.16 # wrap validators around readable class attributes 84.17 for attr_name in ro_attrs + rw_attrs + self.Base_attr_ro: 84.18 - getter_name = '%s_get_%s' % (cls.lower(), attr_name) 84.19 + getter_name = '%s_get_%s' % (cls, attr_name) 84.20 try: 84.21 getter = getattr(XendAPI, getter_name) 84.22 for validator in validators: 84.23 @@ -340,7 +340,7 @@ class XendAPI: 84.24 84.25 # wrap validators around writable class attrributes 84.26 for attr_name in rw_attrs + self.Base_attr_rw: 84.27 - setter_name = '%s_set_%s' % (cls.lower(), attr_name) 84.28 + setter_name = '%s_set_%s' % (cls, attr_name) 84.29 try: 84.30 setter = getattr(XendAPI, setter_name) 84.31 for validator in validators: 84.32 @@ -353,7 +353,8 @@ class XendAPI: 84.33 84.34 # wrap validators around methods 84.35 for method_name in methods + self.Base_methods: 84.36 - method_full_name = '%s_%s' % (cls.lower(), method_name) 84.37 + method_full_name = '%s_%s' % (cls, method_name) 84.38 + 84.39 try: 84.40 method = getattr(XendAPI, method_full_name) 84.41 for validator in validators: 84.42 @@ -366,7 +367,7 @@ class XendAPI: 84.43 84.44 # wrap validators around class functions 84.45 for func_name in funcs + self.Base_funcs: 84.46 - func_full_name = '%s_%s' % (cls.lower(), func_name) 84.47 + func_full_name = '%s_%s' % (cls, func_name) 84.48 try: 84.49 method = getattr(XendAPI, func_full_name) 84.50 method = session_required(method) 84.51 @@ -379,7 +380,7 @@ class XendAPI: 84.52 84.53 Base_attr_ro = ['uuid'] 84.54 Base_attr_rw = [] 84.55 - Base_methods = ['destroy', 'to_XML', 'get_record'] 84.56 + Base_methods = ['destroy', 'get_record'] 84.57 Base_funcs = ['create', 'get_by_uuid', 'get_all'] 84.58 84.59 # Xen API: Class Session 84.60 @@ -411,8 +412,6 @@ class XendAPI: 84.61 record = {'this_host': XendNode.instance().uuid, 84.62 'this_user': auth_manager().get_user(session)} 84.63 return xen_api_success(record) 84.64 - def session_to_XML(self, session): 84.65 - return xen_api_todo() 84.66 84.67 # attributes (ro) 84.68 def session_get_this_host(self, session): 84.69 @@ -536,8 +535,6 @@ class XendAPI: 84.70 'features': node.get_host_cpu_features(host_cpu_ref), 84.71 'utilisation': node.get_host_cpu_load(host_cpu_ref)} 84.72 return xen_api_success(record) 84.73 - def host_cpu_to_XML(self, session, host_cpu_ref): 84.74 - return xen_api_todo() 84.75 84.76 # class methods 84.77 def host_cpu_get_all(self, session): 84.78 @@ -656,304 +653,301 @@ class XendAPI: 84.79 'otherConfig'] 84.80 84.81 # attributes (ro) 84.82 - def vm_get_power_state(self, session, vm_ref): 84.83 + def VM_get_power_state(self, session, vm_ref): 84.84 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.85 return xen_api_success(dom.state) 84.86 84.87 - def vm_get_resident_on(self, session, vm_ref): 84.88 + def VM_get_resident_on(self, session, vm_ref): 84.89 return xen_api_success(XendNode.instance().uuid) 84.90 84.91 - def vm_get_memory_actual(self, session, vm_ref): 84.92 + def VM_get_memory_actual(self, session, vm_ref): 84.93 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.94 return xen_api_todo() # unsupported by xc 84.95 84.96 - def vm_get_memory_static_max(self, session, vm_ref): 84.97 + def VM_get_memory_static_max(self, session, vm_ref): 84.98 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.99 return xen_api_success(dom.get_memory_static_max()) 84.100 84.101 - def vm_get_memory_static_min(self, session, vm_ref): 84.102 + def VM_get_memory_static_min(self, session, vm_ref): 84.103 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.104 return xen_api_success(dom.get_memory_static_min()) 84.105 84.106 - def vm_get_VCPUs_number(self, session, vm_ref): 84.107 + def VM_get_VCPUs_number(self, session, vm_ref): 84.108 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.109 return xen_api_success(dom.getVCpuCount()) 84.110 84.111 - def vm_get_VCPUs_utilisation(self, session, vm_ref): 84.112 + def VM_get_VCPUs_utilisation(self, session, vm_ref): 84.113 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.114 return xen_api_success(dom.get_vcpus_util()) 84.115 84.116 - def vm_get_VCPUs_features_required(self, session, vm_ref): 84.117 + def VM_get_VCPUs_features_required(self, session, vm_ref): 84.118 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.119 return xen_api_todo() # unsupported by xc 84.120 84.121 - def vm_get_VCPUs_can_use(self, session, vm_ref): 84.122 + def VM_get_VCPUs_can_use(self, session, vm_ref): 84.123 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.124 return xen_api_todo() # unsupported by xc 84.125 84.126 - def vm_get_VIFs(self, session, vm_ref): 84.127 + def VM_get_VIFs(self, session, vm_ref): 84.128 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.129 return xen_api_success(dom.get_vifs()) 84.130 84.131 - def vm_get_VBDs(self, session, vm_ref): 84.132 + def VM_get_VBDs(self, session, vm_ref): 84.133 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.134 return xen_api_success(dom.get_vbds()) 84.135 84.136 - def vm_get_VTPMs(self, session, vm_ref): 84.137 + def VM_get_VTPMs(self, session, vm_ref): 84.138 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.139 return xen_api_success(dom.get_vtpms()) 84.140 84.141 - def vm_get_PCI_bus(self, session, vm_ref): 84.142 + def VM_get_PCI_bus(self, session, vm_ref): 84.143 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.144 return xen_api_todo() # unsupported by xc 84.145 84.146 - def vm_get_tools_version(self, session, vm_ref): 84.147 + def VM_get_tools_version(self, session, vm_ref): 84.148 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.149 return xen_api_todo() 84.150 84.151 # attributes (rw) 84.152 - def vm_get_name_label(self, session, vm_ref): 84.153 + def VM_get_name_label(self, session, vm_ref): 84.154 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.155 return xen_api_success(dom.getName()) 84.156 84.157 - def vm_get_name_description(self, session, vm_ref): 84.158 + def VM_get_name_description(self, session, vm_ref): 84.159 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.160 return xen_api_todo() 84.161 84.162 - def vm_get_user_version(self, session, vm_ref): 84.163 + def VM_get_user_version(self, session, vm_ref): 84.164 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.165 return xen_api_todo() 84.166 84.167 - def vm_get_is_a_template(self, session, vm_ref): 84.168 + def VM_get_is_a_template(self, session, vm_ref): 84.169 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.170 return xen_api_todo() 84.171 84.172 - def vm_get_memory_dynamic_max(self, session, vm_ref): 84.173 + def VM_get_memory_dynamic_max(self, session, vm_ref): 84.174 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.175 - return xen_api_todo() 84.176 + return xen_api_success(dom.get_memory_dynamic_max()) 84.177 84.178 - def vm_get_memory_dynamic_min(self, session, vm_ref): 84.179 + def VM_get_memory_dynamic_min(self, session, vm_ref): 84.180 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.181 - return xen_api_todo() 84.182 + return xen_api_success(dom.get_memory_dynamic_min()) 84.183 84.184 - def vm_get_VCPUs_policy(self, session, vm_ref): 84.185 + def VM_get_VCPUs_policy(self, session, vm_ref): 84.186 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.187 return xen_api_todo() # need to access scheduler 84.188 84.189 - def vm_get_VCPUs_params(self, session, vm_ref): 84.190 + def VM_get_VCPUs_params(self, session, vm_ref): 84.191 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.192 return xen_api_todo() # need access to scheduler 84.193 84.194 - def vm_get_VCPUs_features_force_on(self, session, vm_ref): 84.195 + def VM_get_VCPUs_features_force_on(self, session, vm_ref): 84.196 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.197 return xen_api_todo() 84.198 84.199 - def vm_get_VCPUs_features_force_off(self, session, vm_ref): 84.200 + def VM_get_VCPUs_features_force_off(self, session, vm_ref): 84.201 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.202 return xen_api_todo() 84.203 84.204 - def vm_get_actions_after_shutdown(self, session, vm_ref): 84.205 + def VM_get_actions_after_shutdown(self, session, vm_ref): 84.206 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.207 return xen_api_success(dom.get_on_shutdown()) 84.208 84.209 - def vm_get_actions_after_reboot(self, session, vm_ref): 84.210 + def VM_get_actions_after_reboot(self, session, vm_ref): 84.211 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.212 return xen_api_success(dom.get_on_reboot()) 84.213 84.214 - def vm_get_actions_after_suspend(self, session, vm_ref): 84.215 + def VM_get_actions_after_suspend(self, session, vm_ref): 84.216 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.217 return xen_api_success(dom.get_on_suspend()) 84.218 84.219 - def vm_get_actions_after_crash(self, session, vm_ref): 84.220 + def VM_get_actions_after_crash(self, session, vm_ref): 84.221 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.222 return xen_api_success(dom.get_on_crash()) 84.223 84.224 - def vm_get_bios_boot(self, session, vm_ref): 84.225 + def VM_get_bios_boot(self, session, vm_ref): 84.226 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.227 return xen_api_success(dom.get_bios_boot()) 84.228 84.229 - def vm_get_platform_std_VGA(self, session, vm_ref): 84.230 + def VM_get_platform_std_VGA(self, session, vm_ref): 84.231 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.232 return xen_api_todo() 84.233 84.234 - def vm_get_platform_serial(self, session, vm_ref): 84.235 + def VM_get_platform_serial(self, session, vm_ref): 84.236 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.237 return xen_api_todo() 84.238 84.239 - def vm_get_platform_localtime(self, session, vm_ref): 84.240 + def VM_get_platform_localtime(self, session, vm_ref): 84.241 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.242 return xen_api_todo() 84.243 84.244 - def vm_get_platform_clock_offset(self, session, vm_ref): 84.245 + def VM_get_platform_clock_offset(self, session, vm_ref): 84.246 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.247 return xen_api_todo() 84.248 84.249 - def vm_get_platform_enable_audio(self, session, vm_ref): 84.250 + def VM_get_platform_enable_audio(self, session, vm_ref): 84.251 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.252 return xen_api_todo() 84.253 84.254 - def vm_get_platform_keymap(self, session, vm_ref): 84.255 - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.256 - return xen_api_todo() 84.257 - 84.258 - def vm_get_builder(self, session, vm_ref): 84.259 + def VM_get_platform_keymap(self, session, vm_ref): 84.260 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.261 return xen_api_todo() 84.262 84.263 - def vm_get_boot_method(self, session, vm_ref): 84.264 + def VM_get_builder(self, session, vm_ref): 84.265 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.266 - return xen_api_success('') 84.267 + return xen_api_success(dom.get_builder()) 84.268 84.269 - def vm_get_kernel_kernel(self, session, vm_ref): 84.270 + def VM_get_boot_method(self, session, vm_ref): 84.271 + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.272 + return xen_api_success(dom.get_boot_method()) 84.273 + 84.274 + def VM_get_kernel_kernel(self, session, vm_ref): 84.275 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.276 return xen_api_success('') 84.277 84.278 - def vm_get_kernel_initrd(self, session, vm_ref): 84.279 + def VM_get_kernel_initrd(self, session, vm_ref): 84.280 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.281 return xen_api_success('') 84.282 84.283 - def vm_get_kernel_args(self, session, vm_ref): 84.284 + def VM_get_kernel_args(self, session, vm_ref): 84.285 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.286 return xen_api_success('') 84.287 84.288 - def vm_get_grub_cmdline(self, session, vm_ref): 84.289 + def VM_get_grub_cmdline(self, session, vm_ref): 84.290 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.291 return xen_api_success('') 84.292 84.293 - def vm_get_otherConfig(self, session, vm_ref): 84.294 + def VM_get_otherConfig(self, session, vm_ref): 84.295 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.296 return xen_api_todo() 84.297 84.298 - def vm_set_name_label(self, session, vm_ref): 84.299 + def VM_set_name_label(self, session, vm_ref): 84.300 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.301 return xen_api_success_void() 84.302 84.303 - def vm_set_name_description(self, session, vm_ref): 84.304 + def VM_set_name_description(self, session, vm_ref): 84.305 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.306 return xen_api_success_void() 84.307 84.308 - def vm_set_user_version(self, session, vm_ref): 84.309 + def VM_set_user_version(self, session, vm_ref): 84.310 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.311 return xen_api_success_void() 84.312 84.313 - def vm_set_is_a_template(self, session, vm_ref): 84.314 + def VM_set_is_a_template(self, session, vm_ref): 84.315 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.316 return xen_api_success_void() 84.317 84.318 - def vm_set_memory_dynamic_max(self, session, vm_ref): 84.319 + def VM_set_memory_dynamic_max(self, session, vm_ref): 84.320 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.321 return xen_api_success_void() 84.322 84.323 - def vm_set_memory_dynamic_min(self, session, vm_ref): 84.324 + def VM_set_memory_dynamic_min(self, session, vm_ref): 84.325 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.326 return xen_api_success_void() 84.327 84.328 - def vm_set_VCPUs_policy(self, session, vm_ref): 84.329 + def VM_set_VCPUs_policy(self, session, vm_ref): 84.330 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.331 return xen_api_success_void() 84.332 84.333 - def vm_set_VCPUs_params(self, session, vm_ref): 84.334 + def VM_set_VCPUs_params(self, session, vm_ref): 84.335 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.336 return xen_api_success_void() 84.337 84.338 - def vm_set_VCPUs_features_force_on(self, session, vm_ref): 84.339 + def VM_set_VCPUs_features_force_on(self, session, vm_ref): 84.340 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.341 return xen_api_success_void() 84.342 84.343 - def vm_set_VCPUs_features_force_off(self, session, vm_ref): 84.344 + def VM_set_VCPUs_features_force_off(self, session, vm_ref): 84.345 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.346 return xen_api_success_void() 84.347 84.348 - def vm_set_actions_after_shutdown(self, session, vm_ref): 84.349 + def VM_set_actions_after_shutdown(self, session, vm_ref): 84.350 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.351 return xen_api_success_void() 84.352 84.353 - def vm_set_actions_after_reboot(self, session, vm_ref): 84.354 + def VM_set_actions_after_reboot(self, session, vm_ref): 84.355 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.356 return xen_api_success_void() 84.357 84.358 - def vm_set_actions_after_suspend(self, session, vm_ref): 84.359 + def VM_set_actions_after_suspend(self, session, vm_ref): 84.360 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.361 return xen_api_success_void() 84.362 84.363 - def vm_set_actions_after_crash(self, session, vm_ref): 84.364 + def VM_set_actions_after_crash(self, session, vm_ref): 84.365 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.366 return xen_api_success_void() 84.367 84.368 - def vm_set_bios_boot(self, session, vm_ref): 84.369 + def VM_set_bios_boot(self, session, vm_ref): 84.370 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.371 return xen_api_success_void() 84.372 84.373 - def vm_set_platform_std_VGA(self, session, vm_ref): 84.374 + def VM_set_platform_std_VGA(self, session, vm_ref): 84.375 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.376 return xen_api_success_void() 84.377 84.378 - def vm_set_platform_serial(self, session, vm_ref): 84.379 + def VM_set_platform_serial(self, session, vm_ref): 84.380 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.381 return xen_api_success_void() 84.382 84.383 - def vm_set_platform_localtime(self, session, vm_ref): 84.384 + def VM_set_platform_localtime(self, session, vm_ref): 84.385 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.386 return xen_api_success_void() 84.387 84.388 - def vm_set_platform_clock_offset(self, session, vm_ref): 84.389 + def VM_set_platform_clock_offset(self, session, vm_ref): 84.390 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.391 return xen_api_success_void() 84.392 84.393 - def vm_set_platform_enable_audio(self, session, vm_ref): 84.394 + def VM_set_platform_enable_audio(self, session, vm_ref): 84.395 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.396 return xen_api_success_void() 84.397 84.398 - def vm_set_builder(self, session, vm_ref): 84.399 + def VM_set_builder(self, session, vm_ref): 84.400 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.401 return xen_api_success_void() 84.402 84.403 - def vm_set_boot_method(self, session, vm_ref): 84.404 + def VM_set_boot_method(self, session, vm_ref): 84.405 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.406 return xen_api_success_void() 84.407 84.408 - def vm_set_kernel_kernel(self, session, vm_ref): 84.409 + def VM_set_kernel_kernel(self, session, vm_ref): 84.410 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.411 return xen_api_success_void() 84.412 84.413 - def vm_set_kernel_initrd(self, session, vm_ref): 84.414 + def VM_set_kernel_initrd(self, session, vm_ref): 84.415 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.416 return xen_api_success_void() 84.417 84.418 - def vm_set_kernel_args(self, session, vm_ref): 84.419 + def VM_set_kernel_args(self, session, vm_ref): 84.420 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.421 return xen_api_success_void() 84.422 84.423 - def vm_set_grub_cmdline(self, session, vm_ref): 84.424 + def VM_set_grub_cmdline(self, session, vm_ref): 84.425 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.426 return xen_api_success_void() 84.427 84.428 - def vm_set_otherConfig(self, session, vm_ref): 84.429 + def VM_set_otherConfig(self, session, vm_ref): 84.430 dom = XendDomain.instance().get_vm_by_uuid(vm_ref) 84.431 return xen_api_success_void() 84.432 84.433 # class methods 84.434 - def vm_get_all(self, session): 84.435 - refs = [d.get_uuid() for d in XendDomain.instance().list()] 84.436 + def VM_get_all(self, session): 84.437 + refs = [d.get_uuid() for d in XendDomain.instance().list('all')] 84.438 return xen_api_success(refs) 84.439 84.440 - def vm_get_by_name_label(self, session, label): 84.441 + def VM_get_by_name_label(self, session, label): 84.442 xendom = XendDomain.instance() 84.443 dom = xendom.domain_lookup_nr(label) 84.444 if dom: 84.445 return xen_api_success([dom.get_uuid()]) 84.446 return xen_api_error(XEND_ERROR_VM_INVALID) 84.447 84.448 - def vm_create(self, session, vm_struct): 84.449 + def VM_create(self, session, vm_struct): 84.450 xendom = XendDomain.instance() 84.451 domuuid = xendom.create_domain(vm_struct) 84.452 return xen_api_success(domuuid) 84.453 84.454 # object methods 84.455 - def vm_to_XML(self, session, vm_ref): 84.456 - return xen_api_todo() 84.457 - 84.458 - def vm_get_record(self, session, vm_ref): 84.459 + def VM_get_record(self, session, vm_ref): 84.460 xendom = XendDomain.instance() 84.461 xeninfo = xendom.get_vm_by_uuid(vm_ref) 84.462 if not xeninfo: 84.463 @@ -969,17 +963,17 @@ class XendAPI: 84.464 'resident_on': XendNode.instance().uuid, 84.465 'memory_static_min': xeninfo.get_memory_static_min(), 84.466 'memory_static_max': xeninfo.get_memory_static_max(), 84.467 - 'memory_dynamic_min': xeninfo.get_memory_static_min(), 84.468 - 'memory_dynamic_max': xeninfo.get_memory_static_max(), 84.469 + 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(), 84.470 + 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(), 84.471 'memory_actual': xeninfo.get_memory_static_min(), 84.472 - 'vcpus_policy': xeninfo.get_vcpus_policy(), 84.473 - 'vcpus_params': xeninfo.get_vcpus_params(), 84.474 - 'vcpus_number': xeninfo.getVCpuCount(), 84.475 - 'vcpus_utilisation': xeninfo.get_vcpus_util(), 84.476 - 'vcpus_features_required': [], 84.477 - 'vcpus_features_can_use': [], 84.478 - 'vcpus_features_force_on': [], 84.479 - 'vcpus_features_force_off': [], 84.480 + 'VCPUs_policy': xeninfo.get_vcpus_policy(), 84.481 + 'VCPUs_params': xeninfo.get_vcpus_params(), 84.482 + 'VCPUs_number': xeninfo.getVCpuCount(), 84.483 + 'VCPUs_utilisation': xeninfo.get_vcpus_util(), 84.484 + 'VCPUs_features_required': [], 84.485 + 'VCPUs_features_can_use': [], 84.486 + 'VCPUs_features_force_on': [], 84.487 + 'VCPUs_features_force_off': [], 84.488 'actions_after_shutdown': xeninfo.get_on_shutdown(), 84.489 'actions_after_reboot': xeninfo.get_on_reboot(), 84.490 'actions_after_suspend': xeninfo.get_on_suspend(), 84.491 @@ -1006,41 +1000,39 @@ class XendAPI: 84.492 } 84.493 return xen_api_success(record) 84.494 84.495 - def vm_clean_reboot(self, session, vm_ref): 84.496 + def VM_clean_reboot(self, session, vm_ref): 84.497 xendom = XendDomain.instance() 84.498 xeninfo = xendom.get_vm_by_uuid(vm_ref) 84.499 xeninfo.shutdown("reboot") 84.500 return xen_api_success_void() 84.501 - def vm_clean_shutdown(self, session, vm_ref): 84.502 + def VM_clean_shutdown(self, session, vm_ref): 84.503 xendom = XendDomain.instance() 84.504 xeninfo = xendom.get_vm_by_uuid(vm_ref) 84.505 xeninfo.shutdown("poweroff") 84.506 return xen_api_success_void() 84.507 - def vm_clone(self, session, vm_ref): 84.508 + def VM_clone(self, session, vm_ref): 84.509 return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.510 - def vm_destroy(self, session, vm_ref): 84.511 + def VM_destroy(self, session, vm_ref): 84.512 return do_vm_func("domain_delete", vm_ref) 84.513 - def vm_hard_reboot(self, session, vm_ref): 84.514 + def VM_hard_reboot(self, session, vm_ref): 84.515 return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.516 - def vm_hard_shutdown(self, session, vm_ref): 84.517 + def VM_hard_shutdown(self, session, vm_ref): 84.518 return do_vm_func("domain_destroy", vm_ref) 84.519 - def vm_pause(self, session, vm_ref): 84.520 + def VM_pause(self, session, vm_ref): 84.521 return do_vm_func("domain_pause", vm_ref) 84.522 - def vm_resume(self, session, vm_ref, start_paused): 84.523 + def VM_resume(self, session, vm_ref, start_paused): 84.524 return do_vm_func("domain_resume", vm_ref, start_paused = start_paused) 84.525 - def vm_start(self, session, vm_ref, start_paused): 84.526 + def VM_start(self, session, vm_ref, start_paused): 84.527 return do_vm_func("domain_start", vm_ref, start_paused = start_paused) 84.528 - def vm_suspend(self, session, vm_ref): 84.529 + def VM_suspend(self, session, vm_ref): 84.530 return do_vm_func("domain_suspend", vm_ref) 84.531 - def vm_unpause(self, session, vm_ref): 84.532 + def VM_unpause(self, session, vm_ref): 84.533 return do_vm_func("domain_unpause", vm_ref) 84.534 84.535 - # Xen API: Class VDI 84.536 - # ---------------------------------------------------------------- 84.537 - # TODO: NOT IMPLEMENTED. 84.538 - 84.539 # Xen API: Class VBD 84.540 # ---------------------------------------------------------------- 84.541 + # Note: accepts a non-API standard 'image' attribute to emulate 84.542 + # regular xm created VBDs 84.543 84.544 VBD_attr_ro = ['image', 84.545 'IO_bandwidth_incoming_kbs', 84.546 @@ -1053,8 +1045,10 @@ class XendAPI: 84.547 84.548 VBD_attr_inst = VBD_attr_rw + ['image'] 84.549 84.550 + VBD_methods = ['media_change'] 84.551 + 84.552 # object methods 84.553 - def vbd_get_record(self, session, vbd_ref): 84.554 + def VBD_get_record(self, session, vbd_ref): 84.555 xendom = XendDomain.instance() 84.556 vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref) 84.557 if not vm: 84.558 @@ -1063,9 +1057,12 @@ class XendAPI: 84.559 if not cfg: 84.560 return xen_api_error(XEND_ERROR_VBD_INVALID) 84.561 return xen_api_success(cfg) 84.562 - 84.563 + 84.564 + def VBD_media_change(self, session, vbd_ref, vdi_ref): 84.565 + return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.566 + 84.567 # class methods 84.568 - def vbd_create(self, session, vbd_struct): 84.569 + def VBD_create(self, session, vbd_struct): 84.570 xendom = XendDomain.instance() 84.571 if not xendom.is_valid_vm(vbd_struct['VM']): 84.572 return xen_api_error(XEND_ERROR_DOMAIN_INVALID) 84.573 @@ -1092,22 +1089,22 @@ class XendAPI: 84.574 return xen_api_success(vbd_ref) 84.575 84.576 # attributes (rw) 84.577 - def vbd_get_VM(self, session, vbd_ref): 84.578 + def VBD_get_VM(self, session, vbd_ref): 84.579 xendom = XendDomain.instance() 84.580 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM')) 84.581 84.582 - def vbd_get_VDI(self, session, vbd_ref): 84.583 + def VBD_get_VDI(self, session, vbd_ref): 84.584 return xen_api_todo() 84.585 84.586 - def vbd_get_device(self, session, vbd_ref): 84.587 + def VBD_get_device(self, session, vbd_ref): 84.588 xendom = XendDomain.instance() 84.589 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 84.590 'device')) 84.591 - def vbd_get_mode(self, session, vbd_ref): 84.592 + def VBD_get_mode(self, session, vbd_ref): 84.593 xendom = XendDomain.instance() 84.594 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 84.595 'mode')) 84.596 - def vbd_get_driver(self, session, vbd_ref): 84.597 + def VBD_get_driver(self, session, vbd_ref): 84.598 xendom = XendDomain.instance() 84.599 return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 84.600 'driver')) 84.601 @@ -1130,7 +1127,7 @@ class XendAPI: 84.602 VIF_attr_inst = VIF_attr_rw 84.603 84.604 # object methods 84.605 - def vif_get_record(self, session, vif_ref): 84.606 + def VIF_get_record(self, session, vif_ref): 84.607 xendom = XendDomain.instance() 84.608 vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) 84.609 if not vm: 84.610 @@ -1147,7 +1144,7 @@ class XendAPI: 84.611 return xen_api_success(cfg) 84.612 84.613 # class methods 84.614 - def vif_create(self, session, vif_struct): 84.615 + def VIF_create(self, session, vif_struct): 84.616 xendom = XendDomain.instance() 84.617 if xendom.is_valid_vm(vif_struct['VM']): 84.618 dom = xendom.get_vm_by_uuid(vif_struct['VM']) 84.619 @@ -1180,99 +1177,96 @@ class XendAPI: 84.620 VDI_methods = ['snapshot'] 84.621 VDI_funcs = ['get_by_name_label'] 84.622 84.623 - def vdi_get_VBDs(self, session, vdi_ref): 84.624 + def VDI_get_VBDs(self, session, vdi_ref): 84.625 return xen_api_todo() 84.626 84.627 - def vdi_get_physical_utilisation(self, session, vdi_ref): 84.628 + def VDI_get_physical_utilisation(self, session, vdi_ref): 84.629 sr = XendNode.instance().get_sr() 84.630 image = sr.xen_api_get_by_uuid(vdi_ref) 84.631 return xen_api_success(image.get_physical_utilisation()) 84.632 84.633 - def vdi_get_sector_size(self, session, vdi_ref): 84.634 + def VDI_get_sector_size(self, session, vdi_ref): 84.635 sr = XendNode.instance().get_sr() 84.636 image = sr.xen_api_get_by_uuid(vdi_ref) 84.637 return xen_api_success(image.sector_size) 84.638 84.639 - def vdi_get_type(self, session, vdi_ref): 84.640 + def VDI_get_type(self, session, vdi_ref): 84.641 sr = XendNode.instance().get_sr() 84.642 image = sr.xen_api_get_by_uuid(vdi_ref) 84.643 return xen_api_success(image.type) 84.644 84.645 - def vdi_get_parent(self, session, vdi_ref): 84.646 + def VDI_get_parent(self, session, vdi_ref): 84.647 sr = XendNode.instance().get_sr() 84.648 image = sr.xen_api_get_by_uuid(vdi_ref) 84.649 return xen_api_success(image.parent) 84.650 84.651 - def vdi_get_children(self, session, vdi_ref): 84.652 + def VDI_get_children(self, session, vdi_ref): 84.653 sr = XendNode.instance().get_sr() 84.654 image = sr.xen_api_get_by_uuid(vdi_ref) 84.655 return xen_api_success(image.children) 84.656 84.657 - def vdi_get_name_label(self, session, vdi_ref): 84.658 + def VDI_get_name_label(self, session, vdi_ref): 84.659 sr = XendNode.instance().get_sr() 84.660 image = sr.xen_api_get_by_uuid(vdi_ref) 84.661 return xen_api_success(image.name_label) 84.662 84.663 - def vdi_get_name_description(self, session, vdi_ref): 84.664 + def VDI_get_name_description(self, session, vdi_ref): 84.665 sr = XendNode.instance().get_sr() 84.666 image = sr.xen_api_get_by_uuid(vdi_ref) 84.667 return xen_api_success(image.name_description) 84.668 84.669 - def vdi_get_SR(self, session, vdi_ref): 84.670 + def VDI_get_SR(self, session, vdi_ref): 84.671 sr = XendNode.instance().get_sr() 84.672 return xen_api_success(sr.uuid) 84.673 84.674 - def vdi_get_virtual_size(self, session, vdi_ref): 84.675 + def VDI_get_virtual_size(self, session, vdi_ref): 84.676 sr = XendNode.instance().get_sr() 84.677 image = sr.xen_api_get_by_uuid(vdi_ref) 84.678 return xen_api_success(image.virtual_size) 84.679 84.680 - def vdi_get_sharable(self, session, vdi_ref): 84.681 + def VDI_get_sharable(self, session, vdi_ref): 84.682 sr = XendNode.instance().get_sr() 84.683 image = sr.xen_api_get_by_uuid(vdi_ref) 84.684 return xen_api_success(image.sharable) 84.685 84.686 - def vdi_get_read_only(self, session, vdi_ref): 84.687 + def VDI_get_read_only(self, session, vdi_ref): 84.688 sr = XendNode.instance().get_sr() 84.689 image = sr.xen_api_get_by_uuid(vdi_ref) 84.690 return xen_api_success(image.sharable) 84.691 84.692 - def vdi_set_name_label(self, session, vdi_ref, value): 84.693 + def VDI_set_name_label(self, session, vdi_ref, value): 84.694 sr = XendNode.instance().get_sr() 84.695 image = sr.xen_api_get_by_uuid(vdi_ref) 84.696 image.name_label = value 84.697 return xen_api_success_void() 84.698 84.699 - def vdi_set_name_description(self, session, vdi_ref, value): 84.700 + def VDI_set_name_description(self, session, vdi_ref, value): 84.701 sr = XendNode.instance().get_sr() 84.702 image = sr.xen_api_get_by_uuid(vdi_ref) 84.703 image.name_description = value 84.704 return xen_api_success_void() 84.705 84.706 - def vdi_set_SR(self, session, vdi_ref, value): 84.707 + def VDI_set_SR(self, session, vdi_ref, value): 84.708 return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.709 84.710 - def vdi_set_virtual_size(self, session, vdi_ref, value): 84.711 + def VDI_set_virtual_size(self, session, vdi_ref, value): 84.712 return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.713 84.714 - def vdi_set_sharable(self, session, vdi_ref, value): 84.715 + def VDI_set_sharable(self, session, vdi_ref, value): 84.716 return xen_api_todo() 84.717 - def vdi_set_read_only(self, session, vdi_ref, value): 84.718 + def VDI_set_read_only(self, session, vdi_ref, value): 84.719 return xen_api_todo() 84.720 84.721 # Object Methods 84.722 - def vdi_snapshot(self, session, vdi_ref): 84.723 + def VDI_snapshot(self, session, vdi_ref): 84.724 return xen_api_todo() 84.725 84.726 - def vdi_destroy(self, session, vdi_ref): 84.727 + def VDI_destroy(self, session, vdi_ref): 84.728 sr = XendNode.instance().get_sr() 84.729 sr.destroy_image(vdi_ref) 84.730 return xen_api_success_void() 84.731 84.732 - def vdi_to_XML(self, session, vdi_ref): 84.733 - return xen_api_todo() 84.734 - 84.735 - def vdi_get_record(self, session, vdi_ref): 84.736 + def VDI_get_record(self, session, vdi_ref): 84.737 sr = XendNode.instance().get_sr() 84.738 image = sr.xen_api_get_by_uuid(vdi_ref) 84.739 if image: 84.740 @@ -1295,7 +1289,7 @@ class XendAPI: 84.741 return xen_api_error(XEND_ERROR_VDI_INVALID) 84.742 84.743 # Class Functions 84.744 - def vdi_create(self, session, vdi_struct): 84.745 + def VDI_create(self, session, vdi_struct): 84.746 sr = XendNode.instance().get_sr() 84.747 sr_ref = vdi_struct['SR'] 84.748 if sr.uuid != sr_ref: 84.749 @@ -1304,11 +1298,11 @@ class XendAPI: 84.750 vdi_uuid = sr.create_image(vdi_struct) 84.751 return xen_api_success(vdi_uuid) 84.752 84.753 - def vdi_get_all(self, session): 84.754 + def VDI_get_all(self, session): 84.755 sr = XendNode.instance().get_sr() 84.756 return xen_api_success(sr.list_images()) 84.757 84.758 - def vdi_get_by_name_label(self, session, name): 84.759 + def VDI_get_by_name_label(self, session, name): 84.760 sr = XendNode.instance().get_sr() 84.761 image_uuid = sr.xen_api_get_by_name_label(name) 84.762 if image_uuid: 84.763 @@ -1329,7 +1323,7 @@ class XendAPI: 84.764 VTPM_attr_inst = VTPM_attr_rw 84.765 84.766 # object methods 84.767 - def vtpm_get_record(self, session, vtpm_ref): 84.768 + def VTPM_get_record(self, session, vtpm_ref): 84.769 xendom = XendDomain.instance() 84.770 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) 84.771 if not vm: 84.772 @@ -1346,7 +1340,7 @@ class XendAPI: 84.773 return xen_api_success(cfg) 84.774 84.775 # Class Functions 84.776 - def vtpm_get_instance(self, session, vtpm_ref): 84.777 + def VTPM_get_instance(self, session, vtpm_ref): 84.778 xendom = XendDomain.instance() 84.779 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) 84.780 if not vm: 84.781 @@ -1360,7 +1354,7 @@ class XendAPI: 84.782 instance = -1 84.783 return xen_api_success(instance) 84.784 84.785 - def vtpm_get_driver(self, session, vtpm_ref): 84.786 + def VTPM_get_driver(self, session, vtpm_ref): 84.787 xendom = XendDomain.instance() 84.788 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) 84.789 if not vm: 84.790 @@ -1374,7 +1368,7 @@ class XendAPI: 84.791 driver = "Unknown" 84.792 return xen_api_success(driver) 84.793 84.794 - def vtpm_get_backend(self, session, vtpm_ref): 84.795 + def VTPM_get_backend(self, session, vtpm_ref): 84.796 xendom = XendDomain.instance() 84.797 vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) 84.798 if not vm: 84.799 @@ -1388,12 +1382,12 @@ class XendAPI: 84.800 backend = "Domain-0" 84.801 return xen_api_success(backend) 84.802 84.803 - def vtpm_get_VM(self, session, vtpm_ref): 84.804 + def VTPM_get_VM(self, session, vtpm_ref): 84.805 xendom = XendDomain.instance() 84.806 return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM')) 84.807 84.808 # class methods 84.809 - def vtpm_create(self, session, vtpm_struct): 84.810 + def VTPM_create(self, session, vtpm_struct): 84.811 xendom = XendDomain.instance() 84.812 if xendom.is_valid_vm(vtpm_struct['VM']): 84.813 dom = xendom.get_vm_by_uuid(vtpm_struct['VM']) 84.814 @@ -1429,32 +1423,30 @@ class XendAPI: 84.815 SR_funcs = ['get_by_name_label'] 84.816 84.817 # Class Functions 84.818 - def sr_get_all(self, session): 84.819 + def SR_get_all(self, session): 84.820 sr = XendNode.instance().get_sr() 84.821 return xen_api_success([sr.uuid]) 84.822 84.823 - def sr_get_by_name_label(self, session, label): 84.824 + def SR_get_by_name_label(self, session, label): 84.825 sr = XendNode.instance().get_sr() 84.826 if sr.name_label != label: 84.827 return xen_api_error(XEND_ERROR_SR_INVALID) 84.828 return xen_api_success([sr.uuid]) 84.829 84.830 - def sr_create(self, session): 84.831 + def SR_create(self, session): 84.832 return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.833 84.834 - def sr_get_by_uuid(self, session): 84.835 + def SR_get_by_uuid(self, session): 84.836 return xen_api_success(XendNode.instance().get_sr().uuid) 84.837 84.838 # Class Methods 84.839 - def sr_clone(self, session, sr_ref): 84.840 - return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.841 - def sr_destroy(self, session, sr_ref): 84.842 + def SR_clone(self, session, sr_ref): 84.843 return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.844 84.845 - def sr_to_XML(self, session, sr_ref): 84.846 - return xen_api_todo() 84.847 + def SR_destroy(self, session, sr_ref): 84.848 + return xen_api_error(XEND_ERROR_UNSUPPORTED) 84.849 84.850 - def sr_get_record(self, session, sr_ref): 84.851 + def SR_get_record(self, session, sr_ref): 84.852 sr = XendNode.instance().get_sr() 84.853 return xen_api_success({ 84.854 'uuid': sr.uuid, 84.855 @@ -1469,44 +1461,44 @@ class XendAPI: 84.856 }) 84.857 84.858 # Attribute acceess 84.859 - def sr_get_VDIs(self, session, sr_ref): 84.860 + def SR_get_VDIs(self, session, sr_ref): 84.861 sr = XendNode.instance().get_sr() 84.862 return xen_api_success(sr.list_images()) 84.863 84.864 - def sr_get_virtual_allocation(self, session, sr_ref): 84.865 + def SR_get_virtual_allocation(self, session, sr_ref): 84.866 sr = XendNode.instance().get_sr() 84.867 return sr.used_space_bytes() 84.868 84.869 - def sr_get_physical_utilisation(self, session, sr_ref): 84.870 + def SR_get_physical_utilisation(self, session, sr_ref): 84.871 sr = XendNode.instance().get_sr() 84.872 return sr.used_space_bytes() 84.873 84.874 - def sr_get_physical_size(self, session, sr_ref): 84.875 + def SR_get_physical_size(self, session, sr_ref): 84.876 sr = XendNode.instance().get_sr() 84.877 return sr.total_space_bytes() 84.878 84.879 - def sr_get_type(self, session, sr_ref): 84.880 + def SR_get_type(self, session, sr_ref): 84.881 sr = XendNode.instance().get_sr() 84.882 return xen_api_success(sr.type) 84.883 84.884 - def sr_get_location(self, session, sr_ref): 84.885 + def SR_get_location(self, session, sr_ref): 84.886 sr = XendNode.instance().get_sr() 84.887 return xen_api_success(sr.location) 84.888 84.889 - def sr_get_name_label(self, session, sr_ref): 84.890 + def SR_get_name_label(self, session, sr_ref): 84.891 sr = XendNode.instance().get_sr() 84.892 return xen_api_success(sr.name_label) 84.893 84.894 - def sr_get_name_description(self, session, sr_ref): 84.895 + def SR_get_name_description(self, session, sr_ref): 84.896 sr = XendNode.instance().get_sr() 84.897 return xen_api_success(sr.name_description) 84.898 84.899 - def sr_set_name_label(self, session, sr_ref, value): 84.900 + def SR_set_name_label(self, session, sr_ref, value): 84.901 sr = XendNode.instance().get_sr() 84.902 sr.name_label = value 84.903 return xen_api_success_void() 84.904 84.905 - def sr_set_name_description(self, session, sr_ref, value): 84.906 + def SR_set_name_description(self, session, sr_ref, value): 84.907 sr = XendNode.instance().get_sr() 84.908 sr.name_description = value 84.909 return xen_api_success_void() 84.910 @@ -1525,24 +1517,24 @@ if __name__ == "__main__": 84.911 methods = getattr(XendAPI, '%s_methods' % cls, []) 84.912 funcs = getattr(XendAPI, '%s_funcs' % cls, []) 84.913 84.914 - ref = '%s_ref' % cls.lower() 84.915 + ref = '%s_ref' % cls 84.916 84.917 for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro: 84.918 - getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower()) 84.919 + getter_name = '%s_get_%s' % (cls, attr_name) 84.920 output('def %s(self, session, %s):' % (getter_name, ref)) 84.921 output(' return xen_api_todo()') 84.922 84.923 for attr_name in rw_attrs + XendAPI.Base_attr_rw: 84.924 - setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower()) 84.925 + setter_name = '%s_set_%s' % (cls, attr_name) 84.926 output('def %s(self, session, %s, value):' % (setter_name, ref)) 84.927 output(' return xen_api_todo()') 84.928 84.929 for method_name in methods + XendAPI.Base_methods: 84.930 - method_full_name = '%s_%s' % (cls.lower(),method_name.lower()) 84.931 + method_full_name = '%s_%s' % (cls,method_name) 84.932 output('def %s(self, session, %s):' % (method_full_name, ref)) 84.933 output(' return xen_api_todo()') 84.934 84.935 for func_name in funcs + XendAPI.Base_funcs: 84.936 - func_full_name = '%s_%s' % (cls.lower(), func_name.lower()) 84.937 + func_full_name = '%s_%s' % (cls, func_name) 84.938 output('def %s(self, session):' % func_full_name) 84.939 output(' return xen_api_todo()')
85.1 --- a/tools/python/xen/xend/XendCheckpoint.py Sat Dec 02 15:19:50 2006 -0700 85.2 +++ b/tools/python/xen/xend/XendCheckpoint.py Mon Dec 04 08:24:41 2006 -0700 85.3 @@ -18,8 +18,8 @@ import xen.lowlevel.xc 85.4 from xen.xend import balloon, sxp 85.5 from xen.xend.XendError import XendError, VmError 85.6 from xen.xend.XendLogging import log 85.7 +from xen.xend.XendConfig import XendConfig 85.8 from xen.xend.XendConstants import * 85.9 -from xen.xend.XendConfig import XendConfig 85.10 85.11 SIGNATURE = "LinuxGuestRecord" 85.12 XC_SAVE = "xc_save" 85.13 @@ -137,7 +137,7 @@ def restore(xd, fd, dominfo = None, paus 85.14 vmconfig = p.get_val() 85.15 85.16 if dominfo: 85.17 - dominfo.update(XendConfig(sxp = vmconfig), refresh = False) 85.18 + dominfo.update(XendConfig(sxp_obj = vmconfig), refresh = False) 85.19 dominfo.resume() 85.20 else: 85.21 dominfo = xd.restore_(vmconfig)
86.1 --- a/tools/python/xen/xend/XendConfig.py Sat Dec 02 15:19:50 2006 -0700 86.2 +++ b/tools/python/xen/xend/XendConfig.py Mon Dec 04 08:24:41 2006 -0700 86.3 @@ -31,143 +31,197 @@ from xen.xend.XendConstants import DOM_S 86.4 XendConfig API 86.5 86.6 XendConfig will try to mirror as closely the Xen API VM Struct 86.7 - providing a backwards compatibility mode for SXP dumping, loading. 86.8 + with extra parameters for those options that are not supported. 86.9 86.10 """ 86.11 86.12 +def reverse_dict(adict): 86.13 + """Return the reverse mapping of a dictionary.""" 86.14 + return dict([(v, k) for k, v in adict.items()]) 86.15 86.16 -LEGACY_CFG_TO_XENAPI_CFG = { 86.17 +def bool0(v): 86.18 + return v != '0' and bool(v) 86.19 + 86.20 +# Mapping from XendConfig configuration keys to the old 86.21 +# legacy configuration keys that map directly. 86.22 + 86.23 +XENAPI_CFG_TO_LEGACY_CFG = { 86.24 'uuid': 'uuid', 86.25 - 'vcpus': 'vcpus_number', 86.26 - 'maxmem': 'memory_static_max', 86.27 - 'memory': 'memory_static_min', 86.28 - 'name': 'name_label', 86.29 - 'on_poweroff': 'actions_after_shutdown', 86.30 - 'on_reboot': 'actions_after_reboot', 86.31 - 'on_crash': 'actions_after_crash', 86.32 - 'bootloader': 'boot_method', 86.33 - 'kernel_kernel': 'kernel_kernel', 86.34 - 'kernel_initrd': 'kernel_initrd', 86.35 - 'kernel_args': 'kernel_args', 86.36 - } 86.37 + 'vcpus_number': 'vcpus', 86.38 + 'memory_static_min': 'memory', 86.39 + 'memory_static_max': 'maxmem', 86.40 + 'name_label': 'name', 86.41 + 'actions_after_shutdown': 'on_poweroff', 86.42 + 'actions_after_reboot': 'on_reboot', 86.43 + 'actions_after_crash': 'on_crash', 86.44 + 'platform_localtime': 'localtime', 86.45 +} 86.46 86.47 -XENAPI_CFG_CUSTOM_TRANSLATE = [ 86.48 - 'vifs', 86.49 - 'vbds', 86.50 - ] 86.51 +LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG) 86.52 86.53 +# Mapping from XendConfig configuration keys to the old 86.54 +# legacy configuration keys that are found in the 'image' 86.55 +# SXP object. 86.56 XENAPI_HVM_CFG = { 86.57 - 'platform_std_vga': 'std-vga', 86.58 + 'platform_std_vga': 'stdvga', 86.59 'platform_serial' : 'serial', 86.60 'platform_localtime': 'localtime', 86.61 'platform_enable_audio': 'soundhw', 86.62 'platform_keymap' : 'keymap', 86.63 } 86.64 86.65 -XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [ 86.66 - 'name_description', 86.67 - 'user_version', 86.68 - 'is_a_template', 86.69 - 'memory_dynamic_min', 86.70 - 'memory_dynamic_max', 86.71 - 'memory_actual', 86.72 - 'vcpus_policy', 86.73 - 'vcpus_params', 86.74 - 'vcpus_features_required', 86.75 - 'vcpus_features_can_use', 86.76 - 'vcpus_features_force_on', 86.77 - 'vcpus_features_force_off', 86.78 - 'actions_after_suspend', 86.79 - 'bios_boot', 86.80 - 'platform_std_vga', 86.81 - 'platform_serial', 86.82 - 'platform_localtime', 86.83 - 'platform_clock_offset', 86.84 - 'platform_enable_audio', 86.85 - 'platform_keymap', 86.86 - 'builder', 86.87 - 'grub_cmdline', 86.88 - 'pci_bus', 86.89 - 'otherconfig' 86.90 - ] 86.91 - 86.92 +# List of XendConfig configuration keys that have no equivalent 86.93 +# in the old world. 86.94 86.95 -# configuration params that need to be converted to ints 86.96 -# since the XMLRPC transport for Xen API does not use 86.97 -# 32 bit ints but string representation of 64 bit ints. 86.98 -XENAPI_INT_CFG = [ 86.99 - 'user_version', 86.100 - 'vcpus_number', 86.101 - 'memory_static_min', 86.102 - 'memory_static_max', 86.103 - 'memory_dynamic_min', 86.104 - 'memory_dynamic_max', 86.105 - 'tpm_instance', 86.106 - 'tpm_backend', 86.107 -] 86.108 +XENAPI_CFG_TYPES = { 86.109 + 'uuid': str, 86.110 + 'power_state': str, 86.111 + 'name_label': str, 86.112 + 'name_description': str, 86.113 + 'user_version': str, 86.114 + 'is_a_template': bool0, 86.115 + 'resident_on': str, 86.116 + 'memory_static_min': int, 86.117 + 'memory_static_max': int, 86.118 + 'memory_dynamic_min': int, 86.119 + 'memory_dynamic_max': int, 86.120 + 'memory_actual': int, 86.121 + 'vcpus_policy': str, 86.122 + 'vcpus_params': str, 86.123 + 'vcpus_number': int, 86.124 + 'vcpus_features_required': list, 86.125 + 'vcpus_features_can_use': list, 86.126 + 'vcpus_features_force_on': list, 86.127 + 'vcpus_features_force_off': list, 86.128 + 'actions_after_shutdown': str, 86.129 + 'actions_after_reboot': str, 86.130 + 'actions_after_suspend': str, 86.131 + 'actions_after_crash': str, 86.132 + 'tpm_instance': int, 86.133 + 'tpm_backend': int, 86.134 + 'bios_boot': str, 86.135 + 'platform_std_vga': bool0, 86.136 + 'platform_serial': str, 86.137 + 'platform_localtime': bool0, 86.138 + 'platform_clock_offset': bool0, 86.139 + 'platform_enable_audio': bool0, 86.140 + 'platform_keymap': str, 86.141 + 'boot_method': str, 86.142 + 'builder': str, 86.143 + 'kernel_kernel': str, 86.144 + 'kernel_initrd': str, 86.145 + 'kernel_args': str, 86.146 + 'grub_cmdline': str, 86.147 + 'pci_bus': str, 86.148 + 'tools_version': dict, 86.149 + 'otherconfig': dict, 86.150 +} 86.151 86.152 -## 86.153 -## Xend Configuration Parameters 86.154 -## 86.155 - 86.156 +# List of legacy configuration keys that have no equivalent in the 86.157 +# Xen API, but are still stored in XendConfig. 86.158 86.159 -# All parameters of VMs that may be configured on-the-fly, or at start-up. 86.160 -VM_CONFIG_ENTRIES = [ 86.161 - ('name', str), 86.162 - ('on_crash', str), 86.163 - ('on_poweroff', str), 86.164 - ('on_reboot', str), 86.165 - ('on_xend_start', str), 86.166 - ('on_xend_stop', str), 86.167 +LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [ 86.168 + # roundtripped (dynamic, unmodified) 86.169 + 'shadow_memory', 86.170 + 'security', 86.171 + 'vcpu_avail', 86.172 + 'cpu_weight', 86.173 + 'cpu_cap', 86.174 + 'bootloader', 86.175 + 'bootloader_args', 86.176 + 'features', 86.177 + # read/write 86.178 + 'on_xend_start', 86.179 + 'on_xend_stop', 86.180 + # read-only 86.181 + 'domid', 86.182 + 'start_time', 86.183 + 'cpu_time', 86.184 + 'online_vcpus', 86.185 + # write-once 86.186 + 'cpu', 86.187 + 'cpus', 86.188 ] 86.189 86.190 -# All entries written to the store. This is VM_CONFIG_ENTRIES, plus those 86.191 -# entries written to the store that cannot be reconfigured on-the-fly. 86.192 -VM_STORE_ENTRIES = [ 86.193 - ('uuid', str), 86.194 - ('vcpus', int), 86.195 - ('vcpu_avail', int), 86.196 - ('memory', int), 86.197 - ('maxmem', int), 86.198 - ('start_time', float), 86.199 +LEGACY_CFG_TYPES = { 86.200 + 'uuid': str, 86.201 + 'name': str, 86.202 + 'vcpus': int, 86.203 + 'vcpu_avail': int, 86.204 + 'memory': int, 86.205 + 'shadow_memory': int, 86.206 + 'maxmem': int, 86.207 + 'start_time': float, 86.208 + 'cpu_cap': int, 86.209 + 'cpu_weight': int, 86.210 + 'cpu_time': float, 86.211 + 'bootloader': str, 86.212 + 'bootloader_args': str, 86.213 + 'features': str, 86.214 + 'localtime': int, 86.215 + 'name': str, 86.216 + 'on_poweroff': str, 86.217 + 'on_reboot': str, 86.218 + 'on_crash': str, 86.219 + 'on_xend_stop': str, 86.220 + 'on_xend_start': str, 86.221 + 'online_vcpus': int, 86.222 +} 86.223 + 86.224 +# Values that should be stored in xenstore's /vm/<uuid> that is used 86.225 +# by Xend. Used in XendDomainInfo to restore running VM state from 86.226 +# xenstore. 86.227 +LEGACY_XENSTORE_VM_PARAMS = [ 86.228 + 'uuid', 86.229 + 'name', 86.230 + 'vcpus', 86.231 + 'vcpu_avail', 86.232 + 'memory', 86.233 + 'shadow_memory', 86.234 + 'maxmem', 86.235 + 'start_time', 86.236 + 'name', 86.237 + 'on_poweroff', 86.238 + 'on_crash', 86.239 + 'on_reboot', 86.240 + 'on_xend_start', 86.241 + 'on_xend_stop', 86.242 ] 86.243 86.244 -VM_STORED_ENTRIES = VM_CONFIG_ENTRIES + VM_STORE_ENTRIES 86.245 - 86.246 -# Configuration entries that we expect to round-trip -- be read from the 86.247 -# config file or xc, written to save-files (i.e. through sxpr), and reused as 86.248 -# config on restart or restore, all without munging. Some configuration 86.249 -# entries are munged for backwards compatibility reasons, or because they 86.250 -# don't come out of xc in the same form as they are specified in the config 86.251 -# file, so those are handled separately. 86.252 - 86.253 -ROUNDTRIPPING_CONFIG_ENTRIES = [ 86.254 - ('uuid', str), 86.255 - ('vcpus', int), 86.256 - ('vcpu_avail', int), 86.257 - ('cpu_cap', int), 86.258 - ('cpu_weight', int), 86.259 - ('memory', int), 86.260 - ('shadow_memory', int), 86.261 - ('maxmem', int), 86.262 - ('bootloader', str), 86.263 - ('bootloader_args', str), 86.264 - ('features', str), 86.265 - ('localtime', int), 86.266 -] 86.267 -ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_ENTRIES 86.268 - 86.269 -## Static Configuration 86.270 - 86.271 -STATIC_CONFIG_ENTRIES = [ 86.272 - ('cpu', int), 86.273 - ('cpus', str), 86.274 - ('image', list), 86.275 - ('security', list), # TODO: what if null? 86.276 +LEGACY_IMAGE_CFG = [ 86.277 + ('root', str), 86.278 + ('ip', str), 86.279 + ('nographic', int), 86.280 + ('vnc', int), 86.281 + ('sdl', int), 86.282 + ('vncdisplay', int), 86.283 + ('vncunused', int), 86.284 + ('vncpasswd', str), 86.285 ] 86.286 86.287 -DEPRECATED_ENTRIES = [ 86.288 - ('restart', str), 86.289 +LEGACY_IMAGE_HVM_CFG = [ 86.290 + ('device_model', str), 86.291 + ('display', str), 86.292 + ('xauthority', str), 86.293 + ('vncconsole', int), 86.294 + ('pae', int), 86.295 + ('apic', int), 86.296 +] 86.297 + 86.298 +LEGACY_IMAGE_HVM_DEVICES_CFG = [ 86.299 + ('acpi', int), 86.300 + ('boot', str), 86.301 + ('fda', str), 86.302 + ('fdb', str), 86.303 + ('isa', str), 86.304 + ('keymap', str), 86.305 + ('localtime', str), 86.306 + ('serial', str), 86.307 + ('stdvga', int), 86.308 + ('soundhw', str), 86.309 + ('usb', str), 86.310 + ('usbdevice', str), 86.311 + ('vcpus', int), 86.312 ] 86.313 86.314 ## 86.315 @@ -178,245 +232,172 @@ CONFIG_RESTART_MODES = ('restart', 'dest 86.316 CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown', 86.317 'crashed', 'dying') 86.318 86.319 -## 86.320 -## Defaults 86.321 -## 86.322 - 86.323 -def DEFAULT_VCPUS(info): 86.324 - if 'max_vcpu_id' in info: return int(info['max_vcpu_id']) + 1 86.325 - else: return 1 86.326 - 86.327 -DEFAULT_CONFIGURATION = ( 86.328 - ('uuid', lambda info: uuid.createString()), 86.329 - ('name', lambda info: 'Domain-' + info['uuid']), 86.330 - 86.331 - ('on_poweroff', lambda info: 'destroy'), 86.332 - ('on_reboot', lambda info: 'restart'), 86.333 - ('on_crash', lambda info: 'restart'), 86.334 - ('features', lambda info: ''), 86.335 - 86.336 - 86.337 - ('memory', lambda info: 0), 86.338 - ('shadow_memory',lambda info: 0), 86.339 - ('maxmem', lambda info: 0), 86.340 - ('bootloader', lambda info: None), 86.341 - ('bootloader_args', lambda info: None), 86.342 - ('backend', lambda info: []), 86.343 - ('device', lambda info: {}), 86.344 - ('image', lambda info: None), 86.345 - ('security', lambda info: []), 86.346 - ('on_xend_start', lambda info: 'ignore'), 86.347 - ('on_xend_stop', lambda info: 'ignore'), 86.348 - 86.349 - ('cpus', lambda info: []), 86.350 - ('cpu_cap', lambda info: 0), 86.351 - ('cpu_weight', lambda info: 256), 86.352 - ('vcpus', lambda info: DEFAULT_VCPUS(info)), 86.353 - ('online_vcpus', lambda info: info['vcpus']), 86.354 - ('max_vcpu_id', lambda info: info['vcpus']-1), 86.355 - ('vcpu_avail', lambda info: (1<<info['vcpus'])-1), 86.356 - 86.357 - # New for Xen API 86.358 - ('kernel_kernel', lambda info: ''), 86.359 - ('kernel_initrd', lambda info: ''), 86.360 - ('kernel_args', lambda info: ''), 86.361 - 86.362 -) 86.363 - 86.364 class XendConfigError(VmError): 86.365 def __str__(self): 86.366 return 'Invalid Configuration: %s' % str(self.value) 86.367 86.368 ## 86.369 -## XendConfig SXP Config Compat 86.370 -## 86.371 - 86.372 -class XendSXPConfig: 86.373 - def get_domid(self): 86.374 - pass 86.375 - def get_handle(self): 86.376 - return self['uuid'] 86.377 - 86.378 - 86.379 -## 86.380 ## XendConfig Class (an extended dictionary) 86.381 ## 86.382 86.383 class XendConfig(dict): 86.384 - """ Generic Configuration Parser accepting SXP, Python or XML. 86.385 - This is a dictionary-like object that is populated. 86.386 - 86.387 - @ivar legacy: dictionary holding legacy xen domain info 86.388 - @ivar xenapi: dictionary holding xen api config info 86.389 - """ 86.390 - 86.391 - def __init__(self, filename = None, fd = None, 86.392 - sxp = None, xml = None, pycfg = None, xenapi_vm = None, 86.393 - cfg = {}): 86.394 - """Constructor. Provide either the filename, fd or sxp. 86.395 + """ The new Xend VM Configuration. 86.396 86.397 - @keyword filename: filename of an SXP file 86.398 - @keyword fd: file descriptor of an SXP file 86.399 - @keyword sxp: a list of list of a parsed SXP 86.400 - @keyword xml: an XML tree object 86.401 - @keyword xenapi_vm: a struct passed from an XMLRPC call (Xen API) 86.402 - @keyword cfg: a dictionary of configuration (eg. from xc) 86.403 - """ 86.404 - format = 'unknown' 86.405 - 86.406 - self.xenapi = {} 86.407 - 86.408 - if filename and not fd: 86.409 - fd = open(filename, 'r') 86.410 - 86.411 - if fd: 86.412 - format = self._detect_format(fd) 86.413 + Stores the configuration in xenapi compatible format but retains 86.414 + import and export functions for SXP. 86.415 + """ 86.416 + def __init__(self, filename = None, sxp_obj = None, 86.417 + xapi = None, dominfo = None): 86.418 86.419 - if fd: 86.420 - if format == 'sxp': 86.421 - sxp = self._read_sxp(fd) 86.422 - elif format == 'python' and filename != None: 86.423 - pycfg = self._read_python(filename) 86.424 - elif format == 'python' and filename == None: 86.425 - raise XendConfigError("Python files must be passed as a " 86.426 - "filename rather than file descriptor.") 86.427 - elif format == 'xml': 86.428 - xml = self._read_xml(fd) 86.429 - else: 86.430 - raise XendConfigError("Unable to determine format of file") 86.431 - 86.432 - if sxp: 86.433 - cfg = self._populate_from_sxp(sxp) 86.434 - if xml: 86.435 - cfg = self._populate_from_xml(xml) 86.436 - if pycfg: 86.437 - cfg = self._populate_from_python_config(pycfg) 86.438 - if xenapi_vm: 86.439 - cfg = self._populate_from_xenapi_vm(xenapi_vm) 86.440 - 86.441 - if cfg: 86.442 - self.update(cfg) 86.443 - 86.444 - if xenapi_vm: 86.445 - self.xenapi.update(xenapi_vm) 86.446 + dict.__init__(self) 86.447 + self.update(self._defaults()) 86.448 86.449 - log.debug('XendConfig: %s' % str(self)) 86.450 + if filename: 86.451 + try: 86.452 + sxp_obj = sxp.parse(open(filename,'r')) 86.453 + sxp_obj = sxp_obj[0] 86.454 + except IOError, e: 86.455 + raise XendConfigError("Unable to read file: %s" % filename) 86.456 + 86.457 + if sxp_obj: 86.458 + self._sxp_to_xapi(sxp_obj) 86.459 + self._sxp_to_xapi_unsupported(sxp_obj) 86.460 + elif xapi: 86.461 + self.update_with_xenapi_config(xapi) 86.462 + self._add_xapi_unsupported() 86.463 + elif dominfo: 86.464 + # output from xc.domain_getinfo 86.465 + self._dominfo_to_xapi(dominfo) 86.466 + 86.467 + log.debug('XendConfig.init: %s' % self) 86.468 + 86.469 + # validators go here 86.470 self.validate() 86.471 86.472 - # 86.473 - # Xen API Attribute Access 86.474 - # 86.475 - 86.476 - def __getattr__(self, name): 86.477 - try: 86.478 - return dict.__getattr__(self, name) 86.479 - except AttributeError: 86.480 + """ In time, we should enable this type checking addition. It is great 86.481 + also for tracking bugs and unintended writes to XendDomainInfo.info 86.482 + def __setitem__(self, key, value): 86.483 + type_conv = XENAPI_CFG_TYPES.get(key) 86.484 + if callable(type_conv): 86.485 try: 86.486 - return self.__dict__['xenapi'][name] 86.487 - except KeyError: 86.488 - raise AttributeError("XendConfig Xen API has no attribute " 86.489 - "'%s'" % name) 86.490 - 86.491 - 86.492 - def __setattr__(self, name, value): 86.493 - try: 86.494 - return dict.__setattr__(self, name, value) 86.495 - except AttributeError: 86.496 - self.xenapi[name] = value 86.497 - #self.set_legacy_api_with_xen_api_value(name, value) 86.498 + dict.__setitem__(self, key, type_conv(value)) 86.499 + except (ValueError, TypeError): 86.500 + raise XendConfigError("Wrong type for configuration value " + 86.501 + "%s. Expected %s" % 86.502 + (key, type_conv.__name__)) 86.503 + else: 86.504 + dict.__setitem__(self, key, value) 86.505 + """ 86.506 86.507 - def __delattr__(self, name): 86.508 - try: 86.509 - dict.__delattr__(self, name) 86.510 - except AttributeError: 86.511 - del self.xenapi[name] 86.512 - #self.del_legacy_api_with_xen_api_key(name) 86.513 - 86.514 - 86.515 - """ 86.516 - # 86.517 - # Legacy API Attribute Access 86.518 - # 86.519 - 86.520 - def __getitem__(self, key): 86.521 - try: 86.522 - return self.legacy[key] 86.523 - except KeyError: 86.524 - raise AttributeError, "XendConfig Legacy has no attribute '%s'"\ 86.525 - % key 86.526 - 86.527 - def __setitem__(self, key, value): 86.528 - self.legacy[key] = value 86.529 - self.set_xen_api_with_legacy_api_value(key, value) 86.530 - 86.531 - def __delitem__(self, key): 86.532 - del self.legacy[key] 86.533 - self.del_xen_api_with_legacy_api_key(key) 86.534 - """ 86.535 - 86.536 + def _defaults(self): 86.537 + defaults = { 86.538 + 'uuid': uuid.createString(), 86.539 + 'name_label': 'Domain-Unnamed', 86.540 + 'actions_after_shutdown': 'destroy', 86.541 + 'actions_after_reboot': 'restart', 86.542 + 'actions_after_crash': 'restart', 86.543 + 'actions_after_suspend': '', 86.544 + 'features': '', 86.545 + 'builder': 'linux', 86.546 + 'memory_static_min': 0, 86.547 + 'memory_dynamic_min': 0, 86.548 + 'shadow_memory': 0, 86.549 + 'memory_static_max': 0, 86.550 + 'memory_dynamic_max': 0, 86.551 + 'memory_actual': 0, 86.552 + 'boot_method': None, 86.553 + 'bootloader': None, 86.554 + 'bootloader_args': None, 86.555 + 'devices': {}, 86.556 + 'image': {}, 86.557 + 'security': None, 86.558 + 'on_xend_start': 'ignore', 86.559 + 'on_xend_stop': 'ignore', 86.560 + 'cpus': [], 86.561 + 'cpu_weight': 256, 86.562 + 'cpu_cap': 0, 86.563 + 'vcpus_number': 1, 86.564 + 'online_vcpus': 1, 86.565 + 'max_vcpu_id': 0, 86.566 + 'vcpu_avail': 1, 86.567 + 'vif_refs': [], 86.568 + 'vbd_refs': [], 86.569 + 'vtpm_refs': [], 86.570 + } 86.571 + 86.572 + defaults['name_label'] = 'Domain-' + defaults['uuid'] 86.573 + return defaults 86.574 86.575 - def _detect_format(self, fd): 86.576 - """Detect the format of the configuration passed. 86.577 + def _memory_sanity_check(self): 86.578 + if self['memory_static_min'] == 0: 86.579 + self['memory_static_min'] = self['memory_dynamic_min'] 86.580 + 86.581 + # If the static max is not set, let's set it to dynamic max. 86.582 + # If the static max is smaller than static min, then fix it! 86.583 + self['memory_static_max'] = max(self['memory_static_max'], 86.584 + self['memory_dynamic_max'], 86.585 + self['memory_static_min']) 86.586 86.587 - @param fd: file descriptor of contents to detect 86.588 - @rtype: string, 'sxp', 'xml', 'python' or 'unknown' 86.589 - """ 86.590 - format = 'unknown' 86.591 - 86.592 - fd.seek(0) 86.593 - for line in fd: 86.594 - stripped = line.strip() 86.595 - if stripped: 86.596 - if re.search(r'^\(', stripped): 86.597 - format = 'sxp' 86.598 - elif re.search(r'^\<?xml', stripped): 86.599 - format = 'xml' 86.600 - else: 86.601 - format = 'python' 86.602 - break 86.603 + for mem_type in ('memory_static_min', 'memory_static_max'): 86.604 + if self[mem_type] <= 0: 86.605 + raise XendConfigError('Memory value too low for %s: %d' % 86.606 + (mem_type, self[mem_type])) 86.607 86.608 - fd.seek(0) 86.609 - return format 86.610 + def _actions_sanity_check(self): 86.611 + for event in ['shutdown', 'reboot', 'crash']: 86.612 + if self['actions_after_' + event] not in CONFIG_RESTART_MODES: 86.613 + raise XendConfigError('Invalid event handling mode: ' + 86.614 + event) 86.615 86.616 - def _read_sxp(self, fd): 86.617 - """ Read and parse SXP (from SXP to list of lists) 86.618 + def _builder_sanity_check(self): 86.619 + if self['builder'] not in ('hvm', 'linux'): 86.620 + raise XendConfigError('Invalid builder configuration') 86.621 86.622 - @rtype: list of lists. 86.623 - """ 86.624 - try: 86.625 - parsed = sxp.parse(fd)[0] 86.626 - return parsed 86.627 - except: 86.628 - raise 86.629 - return None 86.630 - 86.631 - def _read_xml(self, fd): 86.632 - """TODO: Read and parse XML (from XML to dict) 86.633 + def validate(self): 86.634 + self._memory_sanity_check() 86.635 + self._actions_sanity_check() 86.636 + self._builder_sanity_check() 86.637 86.638 - @rtype: dict 86.639 - """ 86.640 - raise NotImplementedError 86.641 - 86.642 - def _read_python(self, filename): 86.643 - """Read and parse python module that represents the config. 86.644 + def _dominfo_to_xapi(self, dominfo): 86.645 + self['domid'] = dominfo['domid'] 86.646 + self['online_vcpus'] = dominfo['online_vcpus'] 86.647 + self['max_vcpu_id'] = dominfo['max_vcpu_id'] 86.648 + self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024 86.649 + self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024 86.650 + self['cpu_time'] = dominfo['cpu_time']/1e9 86.651 + # TODO: i don't know what the security stuff expects here 86.652 + if dominfo.get('ssidref'): 86.653 + self['security'] = [['ssidref', dominfo['ssidref']]] 86.654 + self['shutdown_reason'] = dominfo['shutdown_reason'] 86.655 86.656 - @rtype: dict 86.657 - """ 86.658 - cfg_globals = {} 86.659 - execfile(filename, cfg_globals, {}) 86.660 - return cfg_globals 86.661 + # parse state into Xen API states 86.662 + self['running'] = dominfo['running'] 86.663 + self['crashed'] = dominfo['crashed'] 86.664 + self['dying'] = dominfo['dying'] 86.665 + self['shutdown'] = dominfo['shutdown'] 86.666 + self['paused'] = dominfo['paused'] 86.667 + self['blocked'] = dominfo['blocked'] 86.668 86.669 - def _populate_from_sxp(self, parsed): 86.670 + if 'name' in dominfo: 86.671 + self['name_label'] = dominfo['name'] 86.672 + 86.673 + if 'handle' in dominfo: 86.674 + self['uuid'] = uuid.toString(dominfo['handle']) 86.675 + 86.676 + def _parse_sxp(self, sxp_cfg): 86.677 """ Populate this XendConfig using the parsed SXP. 86.678 86.679 + @param sxp_cfg: Parsed SXP Configuration 86.680 + @type sxp_cfg: list of lists 86.681 @rtype: dictionary 86.682 + @return: A dictionary containing the parsed options of the SXP. 86.683 """ 86.684 cfg = {} 86.685 86.686 # First step is to convert deprecated options to 86.687 # current equivalents. 86.688 86.689 - restart = sxp.child_value(parsed, 'restart') 86.690 + restart = sxp.child_value(sxp_cfg, 'restart') 86.691 if restart: 86.692 if restart == 'onreboot': 86.693 cfg['on_poweroff'] = 'destroy' 86.694 @@ -433,23 +414,19 @@ class XendConfig(dict): 86.695 'restart = \'%s\'', restart) 86.696 86.697 # Only extract options we know about. 86.698 - all_params = VM_CONFIG_ENTRIES + ROUNDTRIPPING_CONFIG_ENTRIES + \ 86.699 - STATIC_CONFIG_ENTRIES 86.700 - 86.701 - for key, typeconv in all_params: 86.702 - val = sxp.child_value(parsed, key) 86.703 - if val: 86.704 + extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG 86.705 + extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values() 86.706 + 86.707 + for key in extract_keys: 86.708 + val = sxp.child_value(sxp_cfg, key) 86.709 + if val != None: 86.710 try: 86.711 - cfg[key] = typeconv(val) 86.712 - except ValueError: 86.713 - pass 86.714 - 86.715 - # Manually extract other complex configuration 86.716 - # options. 86.717 - 86.718 - cfg['backend'] = [] 86.719 - for c in sxp.children(parsed, 'backend'): 86.720 - cfg['backend'].append(sxp.name(sxp.child0(c))) 86.721 + cfg[key] = LEGACY_CFG_TYPES[key](val) 86.722 + except KeyError: 86.723 + cfg[key] = val 86.724 + except (TypeError, ValueError), e: 86.725 + log.warn("Unable to parse key %s: %s: %s" % 86.726 + (key, str(val), e)) 86.727 86.728 # Parsing the device SXP's. In most cases, the SXP looks 86.729 # like this: 86.730 @@ -472,65 +449,52 @@ class XendConfig(dict): 86.731 # Hence we deal with pci device configurations outside of 86.732 # the regular device parsing. 86.733 86.734 - cfg['device'] = {} 86.735 - for dev in sxp.children(parsed, 'device'): 86.736 + cfg['devices'] = {} 86.737 + for dev in sxp.children(sxp_cfg, 'device'): 86.738 config = sxp.child0(dev) 86.739 dev_type = sxp.name(config) 86.740 dev_info = {} 86.741 86.742 if dev_type == 'pci': 86.743 - continue 86.744 - 86.745 - for opt, val in config[1:]: 86.746 - dev_info[opt] = val 86.747 - log.debug("XendConfig: reading device: %s" % dev_info) 86.748 - # create uuid if it doesn't 86.749 - dev_uuid = dev_info.get('uuid', uuid.createString()) 86.750 - dev_info['uuid'] = dev_uuid 86.751 - cfg['device'][dev_uuid] = (dev_type, dev_info) 86.752 - 86.753 - # deal with PCI device configurations if they exist 86.754 - for dev in sxp.children(parsed, 'device'): 86.755 - config = sxp.child0(dev) 86.756 - dev_type = sxp.name(config) 86.757 - 86.758 - if dev_type != 'pci': 86.759 - continue 86.760 - 86.761 - dev_attr = sxp.child_value(config, 'dev') 86.762 - if isinstance(dev_attr, (types.ListType, types.TupleType)): 86.763 + pci_devs_uuid = sxp.child_value(config, 'uuid', 86.764 + uuid.createString()) 86.765 + pci_devs = [] 86.766 for pci_dev in sxp.children(config, 'dev'): 86.767 - dev_info = {} 86.768 + pci_dev_info = {} 86.769 for opt, val in pci_dev[1:]: 86.770 - dev_info[opt] = val 86.771 - log.debug("XendConfig: reading device: %s" % dev_info) 86.772 - dev_uuid = dev_info.get('uuid', uuid.createString()) 86.773 - dev_info['uuid'] = dev_uuid 86.774 - cfg['device'][dev_uuid] = (dev_type, dev_info) 86.775 - 86.776 - else: # Xen 2.0 PCI device configuration 86.777 + pci_dev_info[opt] = val 86.778 + pci_devs.append(pci_dev_info) 86.779 + 86.780 + cfg['devices'][pci_devs_uuid] = (dev_type, 86.781 + {'devs': pci_devs, 86.782 + 'uuid': pci_devs_uuid}) 86.783 + 86.784 + log.debug("XendConfig: reading device: %s" % pci_devs) 86.785 + else: 86.786 for opt, val in config[1:]: 86.787 dev_info[opt] = val 86.788 log.debug("XendConfig: reading device: %s" % dev_info) 86.789 # create uuid if it doesn't 86.790 dev_uuid = dev_info.get('uuid', uuid.createString()) 86.791 dev_info['uuid'] = dev_uuid 86.792 - cfg['device'][dev_uuid] = (dev_type, dev_info) 86.793 + cfg['devices'][dev_uuid] = (dev_type, dev_info) 86.794 + 86.795 86.796 # Extract missing data from configuration entries 86.797 - if 'image' in cfg: 86.798 - image_vcpus = sxp.child_value(cfg['image'], 'vcpus') 86.799 - if image_vcpus is not None: 86.800 + image_sxp = sxp.child_value(sxp_cfg, 'image', []) 86.801 + if image_sxp: 86.802 + image_vcpus = sxp.child_value(image_sxp, 'vcpus') 86.803 + if image_vcpus != None: 86.804 try: 86.805 - if 'vcpus' not in cfg: 86.806 - cfg['vcpus'] = int(image_vcpus) 86.807 - elif cfg['vcpus'] != int(image_vcpus): 86.808 - cfg['vcpus'] = int(image_vcpus) 86.809 + if 'vcpus_number' not in cfg: 86.810 + cfg['vcpus_number'] = int(image_vcpus) 86.811 + elif cfg['vcpus_number'] != int(image_vcpus): 86.812 + cfg['vcpus_number'] = int(image_vcpus) 86.813 log.warn('Overriding vcpus from %d to %d using image' 86.814 - 'vcpus value.', cfg['vcpus']) 86.815 + 'vcpus value.', cfg['vcpus_number']) 86.816 except ValueError, e: 86.817 raise XendConfigError('integer expeceted: %s: %s' % 86.818 - str(cfg['image']), e) 86.819 + image_sxp, e) 86.820 86.821 # Deprecated cpu configuration 86.822 if 'cpu' in cfg: 86.823 @@ -564,101 +528,188 @@ class XendConfig(dict): 86.824 except ValueError, e: 86.825 raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) 86.826 86.827 - # Parse image SXP outside of image.py 86.828 - # - used to be only done in image.py 86.829 - if 'image' in cfg: 86.830 - cfg['kernel_kernel'] = sxp.child_value(cfg['image'], 'kernel','') 86.831 - cfg['kernel_initrd'] = sxp.child_value(cfg['image'], 'ramdisk','') 86.832 - kernel_args = sxp.child_value(cfg['image'], 'args', '') 86.833 - 86.834 - # attempt to extract extra arguments from SXP config 86.835 - arg_ip = sxp.child_value(cfg['image'], 'ip') 86.836 - if arg_ip: kernel_args += ' ip=%s' % arg_ip 86.837 - arg_root = sxp.child_value(cfg['image'], 'root') 86.838 - if arg_root: kernel_args += ' root=%s' % arg_root 86.839 - 86.840 - cfg['kernel_args'] = kernel_args 86.841 + if 'security' in cfg and isinstance(cfg['security'], str): 86.842 + cfg['security'] = sxp.from_string(cfg['security']) 86.843 86.844 # TODO: get states 86.845 - old_state = sxp.child_value(parsed, 'state') 86.846 + old_state = sxp.child_value(sxp_cfg, 'state') 86.847 if old_state: 86.848 for i in range(len(CONFIG_OLD_DOM_STATES)): 86.849 cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-') 86.850 86.851 - # Xen API extra cfgs 86.852 - # ------------------ 86.853 - cfg['vif_refs'] = [] 86.854 - cfg['vbd_refs'] = [] 86.855 - cfg['vtpm_refs'] = [] 86.856 - for dev_uuid, (dev_type, dev_info) in cfg['device'].items(): 86.857 - if dev_type == 'vif': 86.858 - cfg['vif_refs'].append(dev_uuid) 86.859 - elif dev_type in ('vbd','tap'): 86.860 - cfg['vbd_refs'].append(dev_uuid) 86.861 - elif dev_type == 'vtpm': 86.862 - cfg['vtpm_refs'].append(dev_uuid) 86.863 - 86.864 return cfg 86.865 - 86.866 + 86.867 86.868 - def _populate_from_xenapi_vm(self, xenapi_vm): 86.869 - cfg = {} 86.870 + def _sxp_to_xapi(self, sxp_cfg): 86.871 + """Read in an SXP Configuration object and 86.872 + populate at much of the Xen API with valid values. 86.873 + """ 86.874 + cfg = self._parse_sxp(sxp_cfg) 86.875 86.876 - for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items(): 86.877 + # Convert parameters that can be directly mapped from 86.878 + # the Legacy Config to Xen API Config 86.879 + 86.880 + for apikey, cfgkey in XENAPI_CFG_TO_LEGACY_CFG.items(): 86.881 try: 86.882 - if apikey in XENAPI_INT_CFG: 86.883 - cfg[cfgkey] = int(xenapi_vm[apikey]) 86.884 + type_conv = XENAPI_CFG_TYPES.get(apikey) 86.885 + if callable(type_conv): 86.886 + self[apikey] = type_conv(cfg[cfgkey]) 86.887 else: 86.888 - cfg[cfgkey] = xenapi_vm[apikey] 86.889 + log.warn("Unconverted key: " + apikey) 86.890 + self[apikey] = cfg[cfgkey] 86.891 except KeyError: 86.892 pass 86.893 86.894 - # Reconstruct image SXP 86.895 - # TODO: get rid of SXP altogether from here 86.896 - sxp_image = ['linux'] 86.897 - if xenapi_vm['kernel_kernel']: 86.898 - sxp_image.append(['kernel', xenapi_vm['kernel_kernel']]) 86.899 - if xenapi_vm['kernel_initrd']: 86.900 - sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']]) 86.901 - if xenapi_vm['kernel_args']: 86.902 - sxp_image.append(['args', xenapi_vm['kernel_args']]) 86.903 + # Convert Legacy "image" config to Xen API kernel_* 86.904 + # configuration 86.905 + image_sxp = sxp.child_value(sxp_cfg, 'image', []) 86.906 + if image_sxp: 86.907 + self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','') 86.908 + self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','') 86.909 + kernel_args = sxp.child_value(image_sxp, 'args', '') 86.910 + 86.911 + # attempt to extract extra arguments from SXP config 86.912 + arg_ip = sxp.child_value(image_sxp, 'ip') 86.913 + if arg_ip and not re.search(r'ip=[^ ]+', kernel_args): 86.914 + kernel_args += ' ip=%s' % arg_ip 86.915 + arg_root = sxp.child_value(image_sxp, 'root') 86.916 + if arg_root and not re.search(r'root=[^ ]+', kernel_args): 86.917 + kernel_args += ' root=%s' % arg_root 86.918 + 86.919 + self['kernel_args'] = kernel_args 86.920 + 86.921 + # Convert Legacy HVM parameters to Xen API configuration 86.922 + self['platform_std_vga'] = bool0(cfg.get('stdvga', 0)) 86.923 + self['platform_serial'] = str(cfg.get('serial', '')) 86.924 + self['platform_localtime'] = bool0(cfg.get('localtime', 0)) 86.925 + self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0)) 86.926 + 86.927 + # Convert path to bootloader to boot_method 86.928 + if not cfg.get('bootloader'): 86.929 + if self.get('kernel_kernel','').endswith('hvmloader'): 86.930 + self['boot_method'] = 'bios' 86.931 + else: 86.932 + self['boot_method'] = 'kernel_external' 86.933 + else: 86.934 + self['boot_method'] = 'grub' 86.935 86.936 - cfg['image'] = prettyprintstring(sxp_image) 86.937 + # make sure a sane maximum is set 86.938 + if self['memory_static_max'] <= 0: 86.939 + self['memory_static_max'] = self['memory_static_min'] 86.940 + 86.941 + self['memory_dynamic_max'] = self['memory_static_max'] 86.942 + self['memory_dynamic_min'] = self['memory_static_min'] 86.943 86.944 - # make sure device structures are there. 86.945 - if 'device' not in cfg: 86.946 - cfg['device'] = {} 86.947 - if 'vif_refs' not in cfg: 86.948 - cfg['vif_refs'] = [] 86.949 - if 'vbd_refs' not in cfg: 86.950 - cfg['vbd_refs'] = [] 86.951 - if 'vtpm_refs' not in cfg: 86.952 - cfg['vtpm_refs'] = [] 86.953 + # set device references in the configuration 86.954 + self['devices'] = cfg.get('devices', {}) 86.955 + 86.956 + self['vif_refs'] = [] 86.957 + self['vbd_refs'] = [] 86.958 + self['vtpm_refs'] = [] 86.959 + for dev_uuid, (dev_type, dev_info) in self['devices'].items(): 86.960 + if dev_type == 'vif': 86.961 + self['vif_refs'].append(dev_uuid) 86.962 + elif dev_type in ('vbd','tap'): 86.963 + self['vbd_refs'].append(dev_uuid) 86.964 + elif dev_type in ('vtpm',): 86.965 + self['vtpm_refs'].append(dev_uuid) 86.966 + 86.967 + 86.968 + def _sxp_to_xapi_unsupported(self, sxp_cfg): 86.969 + """Read in an SXP configuration object and populate 86.970 + values are that not related directly supported in 86.971 + the Xen API. 86.972 + """ 86.973 + 86.974 + # Parse and convert parameters used to configure 86.975 + # the image (as well as HVM images) 86.976 + image_sxp = sxp.child_value(sxp_cfg, 'image', []) 86.977 + if image_sxp: 86.978 + image = {} 86.979 + image['type'] = sxp.name(image_sxp) 86.980 + for arg, conv in LEGACY_IMAGE_CFG: 86.981 + val = sxp.child_value(image_sxp, arg, None) 86.982 + if val != None: 86.983 + image[arg] = conv(val) 86.984 86.985 - return cfg 86.986 - 86.987 + image_hvm = {} 86.988 + for arg, conv in LEGACY_IMAGE_HVM_CFG: 86.989 + val = sxp.child_value(image_sxp, arg, None) 86.990 + if val != None: 86.991 + image_hvm[arg] = conv(val) 86.992 + 86.993 + image_hvm_devices = {} 86.994 + for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG: 86.995 + val = sxp.child_value(image_sxp, arg, None) 86.996 + if val != None: 86.997 + image_hvm_devices[arg] = conv(val) 86.998 86.999 - def _sync_xen_api_from_legacy_api(self): 86.1000 - """ Sync all the attributes that is supported by the Xen API 86.1001 - from the legacy API configuration. 86.1002 - """ 86.1003 - for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items(): 86.1004 - if cfgkey in self: 86.1005 - self.xenapi[apikey] = self[cfgkey] 86.1006 + if image_hvm or image_hvm_devices: 86.1007 + image['hvm'] = image_hvm 86.1008 + image['hvm']['devices'] = image_hvm_devices 86.1009 + 86.1010 + self['image'] = image 86.1011 + 86.1012 + for apikey, imgkey in XENAPI_HVM_CFG.items(): 86.1013 + val = sxp.child_value(image_sxp, imgkey, None) 86.1014 + if val != None: 86.1015 + self[apikey] = val 86.1016 + 86.1017 + # extract backend value 86.1018 + 86.1019 + backend = [] 86.1020 + for c in sxp.children(sxp_cfg, 'backend'): 86.1021 + backend.append(sxp.name(sxp.child0(c))) 86.1022 + if backend: 86.1023 + self['backend'] = backend 86.1024 86.1025 - def _sync_legacy_api_from_xen_api(self): 86.1026 - for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items(): 86.1027 - if apikey in self.xenapi: 86.1028 - self[cfgkey] = self.xenapi[apikey] 86.1029 - 86.1030 + if self['image'].has_key('hvm'): 86.1031 + self['builder'] = 'hvm' 86.1032 + 86.1033 + # Parse and convert other Non Xen API parameters. 86.1034 + def _set_cfg_if_exists(sxp_arg): 86.1035 + val = sxp.child_value(sxp_cfg, sxp_arg) 86.1036 + if val != None: 86.1037 + if LEGACY_CFG_TYPES.get(sxp_arg): 86.1038 + self[sxp_arg] = LEGACY_CFG_TYPES[sxp_arg](val) 86.1039 + else: 86.1040 + self[sxp_arg] = val 86.1041 86.1042 - def _populate_from_xml(self, parsed_xml): 86.1043 - raise NotImplementedError 86.1044 + _set_cfg_if_exists('shadow_memory') 86.1045 + _set_cfg_if_exists('security') 86.1046 + _set_cfg_if_exists('features') 86.1047 + _set_cfg_if_exists('on_xend_stop') 86.1048 + _set_cfg_if_exists('on_xend_start') 86.1049 + _set_cfg_if_exists('vcpu_avail') 86.1050 + _set_cfg_if_exists('max_vcpu_id') # TODO, deprecated? 86.1051 + 86.1052 + # Parse and store runtime configuration 86.1053 + _set_cfg_if_exists('start_time') 86.1054 + _set_cfg_if_exists('online_vcpus') 86.1055 + _set_cfg_if_exists('cpu_time') 86.1056 + _set_cfg_if_exists('shutdown_reason') 86.1057 + _set_cfg_if_exists('up_time') 86.1058 + _set_cfg_if_exists('status') # TODO, deprecated 86.1059 86.1060 - def _populate_from_python_config(self, parsed_py): 86.1061 - raise NotImplementedError 86.1062 + def _add_xapi_unsupported(self): 86.1063 + """Updates the configuration object with entries that are not 86.1064 + officially supported by the Xen API but is required for 86.1065 + the rest of Xend to function. 86.1066 + """ 86.1067 + 86.1068 + # populate image 86.1069 + self['image']['type'] = self['builder'] 86.1070 + if self['builder'] == 'hvm': 86.1071 + self['image']['hvm'] = {} 86.1072 + for xapi, cfgapi in XENAPI_HVM_CFG.items(): 86.1073 + self['image']['hvm'][cfgapi] = self[xapi] 86.1074 + 86.1075 86.1076 def _get_old_state_string(self): 86.1077 + """Returns the old xm state string. 86.1078 + @rtype: string 86.1079 + @return: old state string 86.1080 + """ 86.1081 state_string = '' 86.1082 for state_name in CONFIG_OLD_DOM_STATES: 86.1083 on_off = self.get(state_name, 0) 86.1084 @@ -669,9 +720,41 @@ class XendConfig(dict): 86.1085 86.1086 return state_string 86.1087 86.1088 - def get_sxp(self, domain = None, ignore_devices = False, ignore = []): 86.1089 + 86.1090 + def update_config(self, dominfo): 86.1091 + """Update configuration with the output from xc.domain_getinfo(). 86.1092 + 86.1093 + @param dominfo: Domain information via xc.domain_getinfo() 86.1094 + @type dominfo: dict 86.1095 + """ 86.1096 + self._dominfo_to_xapi(dominfo) 86.1097 + self.validate() 86.1098 + 86.1099 + def update_with_xenapi_config(self, xapi): 86.1100 + """Update configuration with a Xen API VM struct 86.1101 + 86.1102 + @param xapi: Xen API VM Struct 86.1103 + @type xapi: dict 86.1104 + """ 86.1105 + for key, val in xapi.items(): 86.1106 + key = key.lower() 86.1107 + type_conv = XENAPI_CFG_TYPES.get(key) 86.1108 + if callable(type_conv): 86.1109 + self[key] = type_conv(val) 86.1110 + else: 86.1111 + self[key] = val 86.1112 + 86.1113 + self.validate() 86.1114 + 86.1115 + def to_xml(self): 86.1116 + """Return an XML string representing the configuration.""" 86.1117 + pass 86.1118 + 86.1119 + def to_sxp(self, domain = None, ignore_devices = False, ignore = []): 86.1120 """ Get SXP representation of this config object. 86.1121 86.1122 + Incompat: removed store_mfn, console_mfn 86.1123 + 86.1124 @keyword domain: (optional) XendDomainInfo to get extra information 86.1125 from such as domid and running devices. 86.1126 @type domain: XendDomainInfo 86.1127 @@ -688,45 +771,37 @@ class XendConfig(dict): 86.1128 if domain.getDomid() is not None: 86.1129 sxpr.append(['domid', domain.getDomid()]) 86.1130 86.1131 - for cfg, typefunc in ROUNDTRIPPING_CONFIG_ENTRIES: 86.1132 - if cfg in self: 86.1133 - if self[cfg] is not None: 86.1134 - sxpr.append([cfg, self[cfg]]) 86.1135 + for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items(): 86.1136 + if self.has_key(xenapi) and self[xenapi] not in (None, []): 86.1137 + if type(self[xenapi]) == bool: 86.1138 + # convert booleans to ints before making an sxp item 86.1139 + sxpr.append([legacy, int(self[xenapi])]) 86.1140 + else: 86.1141 + sxpr.append([legacy, self[xenapi]]) 86.1142 86.1143 - if 'image' in self and self['image'] is not None: 86.1144 - sxpr.append(['image', self['image']]) 86.1145 - if 'security' in self and self['security']: 86.1146 - sxpr.append(['security', self['security']]) 86.1147 - if 'shutdown_reason' in self: 86.1148 - sxpr.append(['shutdown_reason', self['shutdown_reason']]) 86.1149 - if 'cpu_time' in self: 86.1150 - sxpr.append(['cpu_time', self['cpu_time']/1e9]) 86.1151 + for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG: 86.1152 + if legacy in ('domid', 'uuid'): # skip these 86.1153 + continue 86.1154 + if self.has_key(legacy) and self[legacy] not in (None, []): 86.1155 + sxpr.append([legacy, self[legacy]]) 86.1156 86.1157 - sxpr.append(['online_vcpus', self['online_vcpus']]) 86.1158 + if 'image' in self and self['image']: 86.1159 + sxpr.append(['image', self.image_sxpr()]) 86.1160 86.1161 - if 'start_time' in self: 86.1162 - uptime = time.time() - self['start_time'] 86.1163 - sxpr.append(['up_time', str(uptime)]) 86.1164 - sxpr.append(['start_time', str(self['start_time'])]) 86.1165 - 86.1166 - if domain: 86.1167 - sxpr.append(['status', str(domain.state)]) 86.1168 - else: 86.1169 - sxpr.append(['status', str(DOM_STATE_HALTED)]) 86.1170 + sxpr.append(['status', domain.state]) 86.1171 + sxpr.append(['memory_dynamic_min', self.get('memory_dynamic_min')]) 86.1172 + sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max')]) 86.1173 86.1174 if domain.getDomid() is not None: 86.1175 sxpr.append(['state', self._get_old_state_string()]) 86.1176 86.1177 - sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max', 86.1178 - self['memory'])]) 86.1179 - 86.1180 - # For save/restore migration 86.1181 if domain: 86.1182 if domain.store_mfn: 86.1183 sxpr.append(['store_mfn', domain.store_mfn]) 86.1184 if domain.console_mfn: 86.1185 sxpr.append(['console_mfn', domain.console_mfn]) 86.1186 86.1187 + 86.1188 # Marshall devices (running or from configuration) 86.1189 if not ignore_devices: 86.1190 for cls in XendDevices.valid_devices(): 86.1191 @@ -743,7 +818,7 @@ class XendConfig(dict): 86.1192 except: 86.1193 log.exception("dumping sxp from device controllers") 86.1194 pass 86.1195 - 86.1196 + 86.1197 # if we didn't find that device, check the existing config 86.1198 # for a device in the same class 86.1199 if not found: 86.1200 @@ -751,58 +826,28 @@ class XendConfig(dict): 86.1201 if dev_type == cls: 86.1202 sxpr.append(['device', dev_info]) 86.1203 86.1204 - return sxpr 86.1205 - 86.1206 - def validate(self): 86.1207 - """ Validate the configuration and fill in missing configuration 86.1208 - with defaults. 86.1209 - """ 86.1210 - 86.1211 - # Fill in default values 86.1212 - for key, default_func in DEFAULT_CONFIGURATION: 86.1213 - if key not in self or self[key] == None: 86.1214 - self[key] = default_func(self) 86.1215 + return sxpr 86.1216 + 86.1217 + def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None): 86.1218 + """Add a device configuration in SXP format or XenAPI struct format. 86.1219 86.1220 - # Basic sanity checks 86.1221 - if 'image' in self and isinstance(self['image'], str): 86.1222 - self['image'] = sxp.from_string(self['image']) 86.1223 - if 'security' in self and isinstance(self['security'], str): 86.1224 - self['security'] = sxp.from_string(self['security']) 86.1225 - if self['memory'] == 0 and 'mem_kb' in self: 86.1226 - self['memory'] = (self['mem_kb'] + 1023)/1024 86.1227 - if self['memory'] <= 0: 86.1228 - raise XendConfigError('Invalid memory size: %s' % 86.1229 - str(self['memory'])) 86.1230 + For SXP, it could be either: 86.1231 86.1232 - self['maxmem'] = max(self['memory'], self['maxmem']) 86.1233 + [device, [vbd, [uname ...]] 86.1234 + 86.1235 + or: 86.1236 86.1237 - # convert mem_kb from domain_getinfo to something more descriptive 86.1238 - if 'mem_kb' in self: 86.1239 - self['memory_dynamic_max'] = (self['mem_kb'] + 1023)/1024 86.1240 - 86.1241 - # Verify devices 86.1242 - for d_uuid, (d_type, d_info) in self['device'].items(): 86.1243 - if d_type not in XendDevices.valid_devices() and \ 86.1244 - d_type not in XendDevices.pseudo_devices(): 86.1245 - raise XendConfigError('Invalid device (%s)' % d_type) 86.1246 + [vbd, [uname ..]] 86.1247 86.1248 - # Verify restart modes 86.1249 - for event in ('on_poweroff', 'on_reboot', 'on_crash'): 86.1250 - if self[event] not in CONFIG_RESTART_MODES: 86.1251 - raise XendConfigError('Invalid restart event: %s = %s' % \ 86.1252 - (event, str(self[event]))) 86.1253 - 86.1254 - # Verify that {vif,vbd}_refs are here too 86.1255 - if 'vif_refs' not in self: 86.1256 - self['vif_refs'] = [] 86.1257 - if 'vbd_refs' not in self: 86.1258 - self['vbd_refs'] = [] 86.1259 - if 'vtpm_refs' not in self: 86.1260 - self['vtpm_refs'] = [] 86.1261 - 86.1262 - def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None): 86.1263 + @type cfg_sxp: list of lists (parsed sxp object) 86.1264 + @param cfg_sxp: SXP configuration object 86.1265 + @type cfg_xenapi: dict 86.1266 + @param cfg_xenapi: A device configuration from Xen API (eg. vbd,vif) 86.1267 + @rtype: string 86.1268 + @return: Assigned UUID of the device. 86.1269 + """ 86.1270 if dev_type not in XendDevices.valid_devices() and \ 86.1271 - dev_type not in XendDevices.pseudo_devices(): 86.1272 + dev_type not in XendDevices.pseudo_devices(): 86.1273 raise XendConfigError("XendConfig: %s not a valid device type" % 86.1274 dev_type) 86.1275 86.1276 @@ -816,22 +861,48 @@ class XendConfig(dict): 86.1277 log.debug("XendConfig.device_add: %s" % str(cfg_xenapi)) 86.1278 86.1279 if cfg_sxp: 86.1280 + if sxp.child0(cfg_sxp) == 'device': 86.1281 + config = sxp.child0(cfg_sxp) 86.1282 + else: 86.1283 + config = cfg_sxp 86.1284 + 86.1285 + dev_type = sxp.name(config) 86.1286 dev_info = {} 86.1287 86.1288 try: 86.1289 - for opt, val in cfg_sxp[1:]: 86.1290 + for opt, val in config[1:]: 86.1291 dev_info[opt] = val 86.1292 except ValueError: 86.1293 pass # SXP has no options for this device 86.1294 86.1295 + 86.1296 + def _get_config_ipaddr(config): 86.1297 + val = [] 86.1298 + for ipaddr in sxp.children(config, elt='ip'): 86.1299 + val.append(sxp.child0(ipaddr)) 86.1300 + return val 86.1301 + 86.1302 + if dev_type == 'vif' and 'ip' in dev_info: 86.1303 + dev_info['ip'] = _get_config_ipaddr(config) 86.1304 + 86.1305 + if dev_type == 'vbd': 86.1306 + if dev_info.get('dev', '').startswith('ioemu:'): 86.1307 + dev_info['driver'] = 'ioemu' 86.1308 + else: 86.1309 + dev_info['driver'] = 'paravirtualised' 86.1310 + 86.1311 + 86.1312 # create uuid if it doesn't exist 86.1313 dev_uuid = dev_info.get('uuid', uuid.createString()) 86.1314 dev_info['uuid'] = dev_uuid 86.1315 - self['device'][dev_uuid] = (dev_type, dev_info) 86.1316 - if dev_type in ('vif', 'vbd'): 86.1317 + 86.1318 + # store dev references by uuid for certain device types 86.1319 + self['devices'][dev_uuid] = (dev_type, dev_info) 86.1320 + if dev_type in ('vif', 'vbd', 'vtpm'): 86.1321 self['%s_refs' % dev_type].append(dev_uuid) 86.1322 elif dev_type in ('tap',): 86.1323 self['vbd_refs'].append(dev_uuid) 86.1324 + 86.1325 return dev_uuid 86.1326 86.1327 if cfg_xenapi: 86.1328 @@ -849,13 +920,21 @@ class XendConfig(dict): 86.1329 86.1330 dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) 86.1331 dev_info['uuid'] = dev_uuid 86.1332 - self['device'][dev_uuid] = (dev_type, dev_info) 86.1333 + self['devices'][dev_uuid] = (dev_type, dev_info) 86.1334 self['vif_refs'].append(dev_uuid) 86.1335 return dev_uuid 86.1336 86.1337 - elif dev_type == 'vbd': 86.1338 - dev_info['uname'] = cfg_xenapi.get('image', None) 86.1339 - dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') 86.1340 + elif dev_type in ('vbd', 'tap'): 86.1341 + if dev_type == 'vbd': 86.1342 + dev_info['uname'] = cfg_xenapi.get('image', '') 86.1343 + dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') 86.1344 + elif dev_type == 'tap': 86.1345 + dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image') 86.1346 + dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') 86.1347 + 86.1348 + dev_info['driver'] = cfg_xenapi.get('driver') 86.1349 + dev_info['VDI'] = cfg_xenapi.get('VDI', '') 86.1350 + 86.1351 if cfg_xenapi.get('mode') == 'RW': 86.1352 dev_info['mode'] = 'w' 86.1353 else: 86.1354 @@ -863,35 +942,43 @@ class XendConfig(dict): 86.1355 86.1356 dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) 86.1357 dev_info['uuid'] = dev_uuid 86.1358 - self['device'][dev_uuid] = (dev_type, dev_info) 86.1359 + self['devices'][dev_uuid] = (dev_type, dev_info) 86.1360 self['vbd_refs'].append(dev_uuid) 86.1361 return dev_uuid 86.1362 86.1363 - elif dev_type == 'vtpm': 86.1364 + elif dev_type in ('vtpm'): 86.1365 if cfg_xenapi.get('type'): 86.1366 dev_info['type'] = cfg_xenapi.get('type') 86.1367 + 86.1368 dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) 86.1369 dev_info['uuid'] = dev_uuid 86.1370 - self['device'][dev_uuid] = (dev_type, dev_info) 86.1371 + self['devices'][dev_uuid] = (dev_type, dev_info) 86.1372 self['vtpm_refs'].append(dev_uuid) 86.1373 return dev_uuid 86.1374 86.1375 - elif dev_type == 'tap': 86.1376 - dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image') 86.1377 - dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') 86.1378 - 86.1379 - if cfg_xenapi.get('mode') == 'RW': 86.1380 - dev_info['mode'] = 'w' 86.1381 - else: 86.1382 - dev_info['mode'] = 'r' 86.1383 + return '' 86.1384 + 86.1385 + def device_update(self, dev_uuid, cfg_sxp): 86.1386 + """Update an existing device with the new configuration. 86.1387 86.1388 - dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) 86.1389 - dev_info['uuid'] = dev_uuid 86.1390 - self['device'][dev_uuid] = (dev_type, dev_info) 86.1391 - self['vbd_refs'].append(dev_uuid) 86.1392 - return dev_uuid 86.1393 - 86.1394 - return '' 86.1395 + @rtype: boolean 86.1396 + @return: Returns True if succesfully found and updated a device conf 86.1397 + """ 86.1398 + if dev_uuid in self['devices']: 86.1399 + config = sxp.child0(cfg_sxp) 86.1400 + dev_type = sxp.name(config) 86.1401 + dev_info = {} 86.1402 + 86.1403 + try: 86.1404 + for opt, val in config[1:]: 86.1405 + self['devices'][opt] = val 86.1406 + except ValueError: 86.1407 + pass # SXP has no options for this device 86.1408 + 86.1409 + return True 86.1410 + 86.1411 + return False 86.1412 + 86.1413 86.1414 def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None): 86.1415 """Get Device SXPR by either giving the device UUID or (type, config). 86.1416 @@ -900,8 +987,8 @@ class XendConfig(dict): 86.1417 @return: device config sxpr 86.1418 """ 86.1419 sxpr = [] 86.1420 - if dev_uuid != None and dev_uuid in self['device']: 86.1421 - dev_type, dev_info = self['device'][dev_uuid] 86.1422 + if dev_uuid != None and dev_uuid in self['devices']: 86.1423 + dev_type, dev_info = self['devices'][dev_uuid] 86.1424 86.1425 if dev_type == None or dev_info == None: 86.1426 raise XendConfigError("Required either UUID or device type and " 86.1427 @@ -917,27 +1004,106 @@ class XendConfig(dict): 86.1428 """Returns the SXPR for all devices in the current configuration.""" 86.1429 sxprs = [] 86.1430 pci_devs = [] 86.1431 - for dev_type, dev_info in self['device'].values(): 86.1432 + 86.1433 + if 'devices' not in self: 86.1434 + return sxprs 86.1435 + 86.1436 + for dev_type, dev_info in self['devices'].values(): 86.1437 if dev_type == 'pci': # special case for pci devices 86.1438 - pci_devs.append(dev_info) 86.1439 + sxpr = [['uuid', dev_info['uuid']]] 86.1440 + for pci_dev_info in dev_info['devs']: 86.1441 + pci_dev_sxpr = ['dev'] 86.1442 + for opt, val in pci_dev_info.items(): 86.1443 + pci_dev_sxpr.append([opt, val]) 86.1444 + sxpr.append(pci_dev_sxpr) 86.1445 + sxprs.append((dev_type, sxpr)) 86.1446 else: 86.1447 sxpr = self.device_sxpr(dev_type = dev_type, 86.1448 dev_info = dev_info) 86.1449 sxprs.append((dev_type, sxpr)) 86.1450 86.1451 - # if we have any pci_devs, we parse them differently into 86.1452 - # one single pci SXP entry. 86.1453 - if pci_devs: 86.1454 - sxpr = ['pci',] 86.1455 - for dev_info in pci_devs: 86.1456 - dev_sxpr = self.device_sxpr(dev_type = 'dev', 86.1457 - dev_info = dev_info) 86.1458 - sxpr.append(dev_sxpr) 86.1459 - sxprs.append(('pci', sxpr)) 86.1460 - 86.1461 return sxprs 86.1462 86.1463 - 86.1464 + def image_sxpr(self): 86.1465 + """Returns a backwards compatible image SXP expression that is 86.1466 + used in xenstore's /vm/<uuid>/image value and xm list.""" 86.1467 + image = [self['image'].get('type', 'linux')] 86.1468 + if self.has_key('kernel_kernel'): 86.1469 + image.append(['kernel', self['kernel_kernel']]) 86.1470 + if self.has_key('kernel_initrd') and self['kernel_initrd']: 86.1471 + image.append(['ramdisk', self['kernel_initrd']]) 86.1472 + if self.has_key('kernel_args') and self['kernel_args']: 86.1473 + image.append(['args', self['kernel_args']]) 86.1474 + 86.1475 + for arg, conv in LEGACY_IMAGE_CFG: 86.1476 + if self['image'].has_key(arg): 86.1477 + image.append([arg, self['image'][arg]]) 86.1478 + 86.1479 + if 'hvm' in self['image']: 86.1480 + for arg, conv in LEGACY_IMAGE_HVM_CFG: 86.1481 + if self['image']['hvm'].get(arg): 86.1482 + image.append([arg, self['image']['hvm'][arg]]) 86.1483 + 86.1484 + if 'hvm' in self['image'] and 'devices' in self['image']['hvm']: 86.1485 + for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG: 86.1486 + if self['image']['hvm']['devices'].get(arg): 86.1487 + image.append([arg, 86.1488 + self['image']['hvm']['devices'][arg]]) 86.1489 + 86.1490 + return image 86.1491 + 86.1492 + def update_with_image_sxp(self, image_sxp): 86.1493 + # Convert Legacy "image" config to Xen API kernel_* 86.1494 + # configuration 86.1495 + self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','') 86.1496 + self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','') 86.1497 + kernel_args = sxp.child_value(image_sxp, 'args', '') 86.1498 + 86.1499 + # attempt to extract extra arguments from SXP config 86.1500 + arg_ip = sxp.child_value(image_sxp, 'ip') 86.1501 + if arg_ip and not re.search(r'ip=[^ ]+', kernel_args): 86.1502 + kernel_args += ' ip=%s' % arg_ip 86.1503 + arg_root = sxp.child_value(image_sxp, 'root') 86.1504 + if arg_root and not re.search(r'root=', kernel_args): 86.1505 + kernel_args += ' root=%s' % arg_root 86.1506 + self['kernel_args'] = kernel_args 86.1507 + 86.1508 + # Store image SXP in python dictionary format 86.1509 + image = {} 86.1510 + image['type'] = sxp.name(image_sxp) 86.1511 + for arg, conv in LEGACY_IMAGE_CFG: 86.1512 + val = sxp.child_value(image_sxp, arg, None) 86.1513 + if val != None: 86.1514 + image[arg] = conv(val) 86.1515 + 86.1516 + image_hvm = {} 86.1517 + for arg, conv in LEGACY_IMAGE_HVM_CFG: 86.1518 + val = sxp.child_value(image_sxp, arg, None) 86.1519 + if val != None: 86.1520 + image_hvm[arg] = conv(val) 86.1521 + 86.1522 + image_hvm_devices = {} 86.1523 + for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG: 86.1524 + val = sxp.child_value(image_sxp, arg, None) 86.1525 + if val != None: 86.1526 + image_hvm_devices[arg] = conv(val) 86.1527 + 86.1528 + if image_hvm or image_hvm_devices: 86.1529 + image['hvm'] = image_hvm 86.1530 + image['hvm']['devices'] = image_hvm_devices 86.1531 + 86.1532 + self['image'] = image 86.1533 + 86.1534 + for apikey, imgkey in XENAPI_HVM_CFG.items(): 86.1535 + val = sxp.child_value(image_sxp, imgkey, None) 86.1536 + if val != None: 86.1537 + type_conv = XENAPI_CFG_TYPES[apikey] 86.1538 + if callable(conv): 86.1539 + self[apikey] = type_conv(val) 86.1540 + else: 86.1541 + self[apikey] = val 86.1542 + 86.1543 + 86.1544 # 86.1545 # debugging 86.1546 #
87.1 --- a/tools/python/xen/xend/XendConstants.py Sat Dec 02 15:19:50 2006 -0700 87.2 +++ b/tools/python/xen/xend/XendConstants.py Mon Dec 04 08:24:41 2006 -0700 87.3 @@ -34,6 +34,8 @@ DOMAIN_SHUTDOWN_REASONS = { 87.4 DOMAIN_CRASH : "crash", 87.5 DOMAIN_HALT : "halt" 87.6 } 87.7 +REVERSE_DOMAIN_SHUTDOWN_REASONS = \ 87.8 + dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()]) 87.9 87.10 restart_modes = [ 87.11 "restart",
88.1 --- a/tools/python/xen/xend/XendDevices.py Sat Dec 02 15:19:50 2006 -0700 88.2 +++ b/tools/python/xen/xend/XendDevices.py Mon Dec 04 08:24:41 2006 -0700 88.3 @@ -19,7 +19,7 @@ 88.4 # A collection of DevControllers 88.5 # 88.6 88.7 -from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif 88.8 +from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif 88.9 from xen.xend.server.BlktapController import BlktapController 88.10 88.11 class XendDevices: 88.12 @@ -41,6 +41,8 @@ class XendDevices: 88.13 'irq': irqif.IRQController, 88.14 'usb': usbif.UsbifController, 88.15 'tap': BlktapController, 88.16 + 'vfb': vfbif.VfbifController, 88.17 + 'vkbd': vfbif.VkbdifController, 88.18 } 88.19 88.20 #@classmethod
89.1 --- a/tools/python/xen/xend/XendDomain.py Sat Dec 02 15:19:50 2006 -0700 89.2 +++ b/tools/python/xen/xend/XendDomain.py Mon Dec 04 08:24:41 2006 -0700 89.3 @@ -23,6 +23,7 @@ 89.4 """ 89.5 89.6 import os 89.7 +import stat 89.8 import shutil 89.9 import socket 89.10 import threading 89.11 @@ -44,7 +45,7 @@ from xen.xend.XendDevices import XendDev 89.12 89.13 from xen.xend.xenstore.xstransact import xstransact 89.14 from xen.xend.xenstore.xswatch import xswatch 89.15 -from xen.util import security 89.16 +from xen.util import mkdir, security 89.17 from xen.xend import uuid 89.18 89.19 xc = xen.lowlevel.xc.xc() 89.20 @@ -99,11 +100,7 @@ class XendDomain: 89.21 """Singleton initialisation function.""" 89.22 89.23 dom_path = self._managed_path() 89.24 - try: 89.25 - os.stat(dom_path) 89.26 - except OSError: 89.27 - log.info("Making %s", dom_path) 89.28 - os.makedirs(dom_path, 0755) 89.29 + mkdir.parents(dom_path, stat.S_IRWXU) 89.30 89.31 xstransact.Mkdir(XS_VMROOT) 89.32 xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID}) 89.33 @@ -184,7 +181,7 @@ class XendDomain: 89.34 if not dom_uuid: 89.35 continue 89.36 89.37 - dom_name = dom.get('name', 'Domain-%s' % dom_uuid) 89.38 + dom_name = dom.get('name_label', 'Domain-%s' % dom_uuid) 89.39 try: 89.40 running_dom = self.domain_lookup_nr(dom_name) 89.41 if not running_dom: 89.42 @@ -271,25 +268,17 @@ class XendDomain: 89.43 domains_dir = self._managed_path() 89.44 dom_uuid = dominfo.get_uuid() 89.45 domain_config_dir = self._managed_path(dom_uuid) 89.46 - 89.47 - # make sure the domain dir exists 89.48 - if not os.path.exists(domains_dir): 89.49 - os.makedirs(domains_dir, 0755) 89.50 - elif not os.path.isdir(domains_dir): 89.51 - log.error("xend_domain_dir is not a directory.") 89.52 - raise XendError("Unable to save managed configuration " 89.53 - "because %s is not a directory." % 89.54 - domains_dir) 89.55 - 89.56 - if not os.path.exists(domain_config_dir): 89.57 + 89.58 + def make_or_raise(path): 89.59 try: 89.60 - os.makedirs(domain_config_dir, 0755) 89.61 - except IOError: 89.62 - log.exception("Failed to create directory: %s" % 89.63 - domain_config_dir) 89.64 - raise XendError("Failed to create directory: %s" % 89.65 - domain_config_dir) 89.66 - 89.67 + mkdir.parents(path, stat.S_IRWXU) 89.68 + except: 89.69 + log.exception("%s could not be created." % path) 89.70 + raise XendError("%s could not be created." % path) 89.71 + 89.72 + make_or_raise(domains_dir) 89.73 + make_or_raise(domain_config_dir) 89.74 + 89.75 try: 89.76 sxp_cache_file = open(self._managed_config_path(dom_uuid),'w') 89.77 prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78) 89.78 @@ -423,7 +412,6 @@ class XendDomain: 89.79 self._remove_domain(dom, domid) 89.80 89.81 89.82 - 89.83 def _add_domain(self, info): 89.84 """Add a domain to the list of running domains 89.85 89.86 @@ -433,6 +421,11 @@ class XendDomain: 89.87 """ 89.88 log.debug("Adding Domain: %s" % info.getDomid()) 89.89 self.domains[info.getDomid()] = info 89.90 + 89.91 + # update the managed domains with a new XendDomainInfo object 89.92 + # if we are keeping track of it. 89.93 + if info.get_uuid() in self.managed_domains: 89.94 + self._managed_domain_register(info) 89.95 89.96 def _remove_domain(self, info, domid = None): 89.97 """Remove the domain from the list of running domains 89.98 @@ -669,7 +662,7 @@ class XendDomain: 89.99 self.domains_lock.acquire() 89.100 try: 89.101 try: 89.102 - xeninfo = XendConfig(xenapi_vm = xenapi_vm) 89.103 + xeninfo = XendConfig(xapi = xenapi_vm) 89.104 dominfo = XendDomainInfo.createDormant(xeninfo) 89.105 log.debug("Creating new managed domain: %s: %s" % 89.106 (dominfo.getName(), dominfo.get_uuid())) 89.107 @@ -873,8 +866,8 @@ class XendDomain: 89.108 self.domains_lock.acquire() 89.109 try: 89.110 try: 89.111 - xeninfo = XendConfig(sxp = config) 89.112 - dominfo = XendDomainInfo.createDormant(xeninfo) 89.113 + domconfig = XendConfig(sxp_obj = config) 89.114 + dominfo = XendDomainInfo.createDormant(domconfig) 89.115 log.debug("Creating new managed domain: %s" % 89.116 dominfo.getName()) 89.117 self._managed_domain_register(dominfo) 89.118 @@ -936,6 +929,9 @@ class XendDomain: 89.119 if dominfo.state != DOM_STATE_HALTED: 89.120 raise XendError("Domain is still running") 89.121 89.122 + log.info("Domain %s (%s) deleted." % 89.123 + (dominfo.getName(), dominfo.info.get('uuid'))) 89.124 + 89.125 self._managed_domain_unregister(dominfo) 89.126 self._remove_domain(dominfo) 89.127 XendDevices.destroy_device_state(dominfo)
90.1 --- a/tools/python/xen/xend/XendDomainInfo.py Sat Dec 02 15:19:50 2006 -0700 90.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Dec 04 08:24:41 2006 -0700 90.3 @@ -38,10 +38,9 @@ from xen.util.blkif import blkdev_uname_ 90.4 from xen.util import security 90.5 90.6 from xen.xend import balloon, sxp, uuid, image, arch 90.7 -from xen.xend import XendRoot, XendNode 90.8 +from xen.xend import XendRoot, XendNode, XendConfig 90.9 90.10 from xen.xend.XendBootloader import bootloader 90.11 -from xen.xend.XendConfig import XendConfig 90.12 from xen.xend.XendError import XendError, VmError 90.13 from xen.xend.XendDevices import XendDevices 90.14 from xen.xend.xenstore.xstransact import xstransact, complete 90.15 @@ -58,6 +57,11 @@ xroot = XendRoot.instance() 90.16 log = logging.getLogger("xend.XendDomainInfo") 90.17 #log.setLevel(logging.TRACE) 90.18 90.19 + 90.20 +def bool0(v): 90.21 + return v != "0" and bool(v) 90.22 + 90.23 + 90.24 ## 90.25 # All parameters of VMs that may be configured on-the-fly, or at start-up. 90.26 # 90.27 @@ -88,7 +92,7 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [ 90.28 ('bootloader', str), 90.29 ('bootloader_args', str), 90.30 ('features', str), 90.31 - ('localtime', int), 90.32 + ('localtime', bool0), 90.33 ] 90.34 90.35 ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS 90.36 @@ -145,7 +149,7 @@ def create(config): 90.37 """ 90.38 90.39 log.debug("XendDomainInfo.create(%s)", config) 90.40 - vm = XendDomainInfo(XendConfig(sxp = config)) 90.41 + vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config)) 90.42 try: 90.43 vm.start() 90.44 except: 90.45 @@ -175,10 +179,9 @@ def recreate(info, priv): 90.46 90.47 assert not info['dying'] 90.48 90.49 - xeninfo = XendConfig(cfg = info) 90.50 + xeninfo = XendConfig.XendConfig(dominfo = info) 90.51 domid = xeninfo['domid'] 90.52 - uuid1 = xeninfo['handle'] 90.53 - xeninfo['uuid'] = uuid.toString(uuid1) 90.54 + uuid1 = uuid.fromString(xeninfo['uuid']) 90.55 needs_reinitialising = False 90.56 90.57 dompath = GetDomainPath(domid) 90.58 @@ -228,6 +231,15 @@ def recreate(info, priv): 90.59 vm._storeVmDetails() 90.60 vm._storeDomDetails() 90.61 90.62 + if vm.info['image']: # Only dom0 should be without an image entry when 90.63 + # recreating, but we cope with missing ones 90.64 + # elsewhere just in case. 90.65 + vm.image = image.create(vm, 90.66 + vm.info, 90.67 + vm.info['image'], 90.68 + vm.info['devices']) 90.69 + vm.image.recreate() 90.70 + 90.71 vm._registerWatches() 90.72 vm.refreshShutdown(xeninfo) 90.73 return vm 90.74 @@ -236,7 +248,7 @@ def recreate(info, priv): 90.75 def restore(config): 90.76 """Create a domain and a VM object to do a restore. 90.77 90.78 - @param config: Domain configuration object 90.79 + @param config: Domain SXP configuration 90.80 @type config: list of lists. (see C{create}) 90.81 90.82 @rtype: XendDomainInfo 90.83 @@ -246,7 +258,8 @@ def restore(config): 90.84 """ 90.85 90.86 log.debug("XendDomainInfo.restore(%s)", config) 90.87 - vm = XendDomainInfo(XendConfig(sxp = config), resume = True) 90.88 + vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config), 90.89 + resume = True) 90.90 try: 90.91 vm.resume() 90.92 return vm 90.93 @@ -254,24 +267,24 @@ def restore(config): 90.94 vm.destroy() 90.95 raise 90.96 90.97 -def createDormant(xeninfo): 90.98 +def createDormant(domconfig): 90.99 """Create a dormant/inactive XenDomainInfo without creating VM. 90.100 This is for creating instances of persistent domains that are not 90.101 yet start. 90.102 90.103 - @param xeninfo: Parsed configuration 90.104 - @type xeninfo: dictionary 90.105 + @param domconfig: Parsed configuration 90.106 + @type domconfig: XendConfig object 90.107 90.108 @rtype: XendDomainInfo 90.109 @return: A up and running XendDomainInfo instance 90.110 @raise XendError: Errors with configuration. 90.111 """ 90.112 90.113 - log.debug("XendDomainInfo.createDormant(%s)", xeninfo) 90.114 + log.debug("XendDomainInfo.createDormant(%s)", domconfig) 90.115 90.116 # domid does not make sense for non-running domains. 90.117 - xeninfo.pop('domid', None) 90.118 - vm = XendDomainInfo(XendConfig(cfg = xeninfo)) 90.119 + domconfig.pop('domid', None) 90.120 + vm = XendDomainInfo(domconfig) 90.121 return vm 90.122 90.123 def domain_by_name(name): 90.124 @@ -383,14 +396,6 @@ class XendDomainInfo: 90.125 #if not self._infoIsSet('uuid'): 90.126 # self.info['uuid'] = uuid.toString(uuid.create()) 90.127 90.128 - #REMOVE: domid logic can be shortened 90.129 - #if domid is not None: 90.130 - # self.domid = domid 90.131 - #elif info.has_key('dom'): 90.132 - # self.domid = int(info['dom']) 90.133 - #else: 90.134 - # self.domid = None 90.135 - 90.136 self.vmpath = XS_VMROOT + self.info['uuid'] 90.137 self.dompath = dompath 90.138 90.139 @@ -403,6 +408,7 @@ class XendDomainInfo: 90.140 self.vmWatch = None 90.141 self.shutdownWatch = None 90.142 self.shutdownStartTime = None 90.143 + self._resume = resume 90.144 90.145 self.state = DOM_STATE_HALTED 90.146 self.state_updated = threading.Condition() 90.147 @@ -416,8 +422,7 @@ class XendDomainInfo: 90.148 if augment: 90.149 self._augmentInfo(priv) 90.150 90.151 - self._checkName(self.info['name']) 90.152 - self.setResume(resume) 90.153 + self._checkName(self.info['name_label']) 90.154 90.155 90.156 # 90.157 @@ -477,10 +482,11 @@ class XendDomainInfo: 90.158 if self.domid == 0: 90.159 raise XendError('Domain 0 cannot be shutdown') 90.160 90.161 - if not reason in DOMAIN_SHUTDOWN_REASONS.values(): 90.162 + if reason not in DOMAIN_SHUTDOWN_REASONS.values(): 90.163 raise XendError('Invalid reason: %s' % reason) 90.164 - self._storeDom("control/shutdown", reason) 90.165 - 90.166 + self._removeVm('xend/previous_restart_time') 90.167 + self.storeDom("control/shutdown", reason) 90.168 + 90.169 def pause(self): 90.170 """Pause domain 90.171 90.172 @@ -506,18 +512,20 @@ class XendDomainInfo: 90.173 def send_sysrq(self, key): 90.174 """ Send a Sysrq equivalent key via xenstored.""" 90.175 asserts.isCharConvertible(key) 90.176 - self._storeDom("control/sysrq", '%c' % key) 90.177 + self.storeDom("control/sysrq", '%c' % key) 90.178 90.179 def device_create(self, dev_config): 90.180 """Create a new device. 90.181 90.182 @param dev_config: device configuration 90.183 - @type dev_config: dictionary (parsed config) 90.184 + @type dev_config: SXP object (parsed config) 90.185 """ 90.186 log.debug("XendDomainInfo.device_create: %s" % dev_config) 90.187 dev_type = sxp.name(dev_config) 90.188 - devid = self._createDevice(dev_type, dev_config) 90.189 - self.info.device_add(dev_type, cfg_sxp = dev_config) 90.190 + dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config) 90.191 + dev_config_dict = self.info['devices'][dev_uuid][1] 90.192 + log.debug("XendDomainInfo.device_create: %s" % dev_config_dict) 90.193 + devid = self._createDevice(dev_type, dev_config_dict) 90.194 self._waitForDevice(dev_type, devid) 90.195 return self.getDeviceController(dev_type).sxpr(devid) 90.196 90.197 @@ -525,12 +533,26 @@ class XendDomainInfo: 90.198 """Configure an existing device. 90.199 90.200 @param dev_config: device configuration 90.201 - @type dev_config: dictionary (parsed config) 90.202 + @type dev_config: SXP object (parsed config) 90.203 @param devid: device id 90.204 @type devid: int 90.205 + @return: Returns True if successfully updated device 90.206 + @rtype: boolean 90.207 """ 90.208 deviceClass = sxp.name(dev_config) 90.209 - self._reconfigureDevice(deviceClass, devid, dev_config) 90.210 + 90.211 + # look up uuid of the device 90.212 + dev_control = self.getDeviceController(deviceClass) 90.213 + dev_sxpr = dev_control.sxpr(devid) 90.214 + dev_uuid = sxp.child_value(sxpr, 'uuid') 90.215 + if not dev_uuid: 90.216 + return False 90.217 + 90.218 + self.info.device_update(dev_uuid, dev_config) 90.219 + dev_config_dict = self.info['devices'].get(dev_uuid) 90.220 + if dev_config_dict: 90.221 + dev_control.reconfigureDevice(devid, dev_config_dict[1]) 90.222 + return True 90.223 90.224 def waitForDevices(self): 90.225 """Wait for this domain's configured devices to connect. 90.226 @@ -558,8 +580,18 @@ class XendDomainInfo: 90.227 return self.getDeviceController(deviceClass).destroyDevice(devid) 90.228 90.229 90.230 + 90.231 def getDeviceSxprs(self, deviceClass): 90.232 - return self.getDeviceController(deviceClass).sxprs() 90.233 + if self.state == DOM_STATE_RUNNING: 90.234 + return self.getDeviceController(deviceClass).sxprs() 90.235 + else: 90.236 + sxprs = [] 90.237 + dev_num = 0 90.238 + for dev_type, dev_info in self.info.all_devices_sxpr(): 90.239 + if dev_type == deviceClass: 90.240 + sxprs.append([dev_num, dev_info]) 90.241 + dev_num += 1 90.242 + return sxprs 90.243 90.244 90.245 def setMemoryTarget(self, target): 90.246 @@ -567,22 +599,22 @@ class XendDomainInfo: 90.247 @param target: In MiB. 90.248 """ 90.249 log.debug("Setting memory target of domain %s (%d) to %d MiB.", 90.250 - self.info['name'], self.domid, target) 90.251 + self.info['name_label'], self.domid, target) 90.252 90.253 if target <= 0: 90.254 raise XendError('Invalid memory size') 90.255 90.256 - self.info['memory'] = target 90.257 + self.info['memory_static_min'] = target 90.258 self.storeVm("memory", target) 90.259 - self._storeDom("memory/target", target << 10) 90.260 + self.storeDom("memory/target", target << 10) 90.261 90.262 def getVCPUInfo(self): 90.263 try: 90.264 # We include the domain name and ID, to help xm. 90.265 sxpr = ['domain', 90.266 ['domid', self.domid], 90.267 - ['name', self.info['name']], 90.268 - ['vcpu_count', self.info['online_vcpus']]] 90.269 + ['name', self.info['name_label']], 90.270 + ['vcpu_count', self.info['vcpus_number']]] 90.271 90.272 for i in range(0, self.info['max_vcpu_id']+1): 90.273 info = xc.vcpu_getinfo(self.domid, i) 90.274 @@ -610,30 +642,40 @@ class XendDomainInfo: 90.275 values taken from the store. This recovers those values known 90.276 to xend but not to the hypervisor. 90.277 """ 90.278 - def useIfNeeded(name, val): 90.279 - if not self._infoIsSet(name) and val is not None: 90.280 - self.info[name] = val 90.281 - 90.282 + augment_entries = XendConfig.LEGACY_XENSTORE_VM_PARAMS[:] 90.283 if priv: 90.284 - entries = VM_STORE_ENTRIES[:] 90.285 - entries.remove(('memory', int)) 90.286 - entries.remove(('maxmem', int)) 90.287 - else: 90.288 - entries = VM_STORE_ENTRIES 90.289 - entries.append(('image', str)) 90.290 - entries.append(('security', str)) 90.291 + augment_entries.remove('memory') 90.292 + augment_entries.remove('maxmem') 90.293 90.294 - map(lambda x, y: useIfNeeded(x[0], y), entries, 90.295 - self._readVMDetails(entries)) 90.296 + vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k]) 90.297 + for k in augment_entries]) 90.298 + 90.299 + # make returned lists into a dictionary 90.300 + vm_config = dict(zip(augment_entries, vm_config)) 90.301 + 90.302 + for arg in augment_entries: 90.303 + xapicfg = arg 90.304 + val = vm_config[arg] 90.305 + if val != None: 90.306 + if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG: 90.307 + xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg] 90.308 + self.info[xapiarg] = val 90.309 + else: 90.310 + self.info[arg] = val 90.311 90.312 + # read image value 90.313 + image_sxp = self._readVm('image') 90.314 + if image_sxp: 90.315 + self.info.update_with_image_sxp(sxp.from_string(image_sxp)) 90.316 + 90.317 + # read devices 90.318 devices = [] 90.319 - 90.320 for devclass in XendDevices.valid_devices(): 90.321 devconfig = self.getDeviceController(devclass).configurations() 90.322 if devconfig: 90.323 - devices.extend(map(lambda conf: (devclass, conf), devconfig)) 90.324 + devices.extend(devconfig) 90.325 90.326 - if not self.info['device'] and devices is not None: 90.327 + if not self.info['devices'] and devices is not None: 90.328 for device in devices: 90.329 self.info.device_add(device[0], cfg_sxp = device) 90.330 90.331 @@ -660,16 +702,19 @@ class XendDomainInfo: 90.332 # Function to update xenstore /dom/* 90.333 # 90.334 90.335 - def _readDom(self, *args): 90.336 + def readDom(self, *args): 90.337 return xstransact.Read(self.dompath, *args) 90.338 90.339 + def gatherDom(self, *args): 90.340 + return xstransact.Gather(self.dompath, *args) 90.341 + 90.342 def _writeDom(self, *args): 90.343 return xstransact.Write(self.dompath, *args) 90.344 90.345 def _removeDom(self, *args): 90.346 return xstransact.Remove(self.dompath, *args) 90.347 90.348 - def _storeDom(self, *args): 90.349 + def storeDom(self, *args): 90.350 return xstransact.Store(self.dompath, *args) 90.351 90.352 def _recreateDom(self): 90.353 @@ -678,16 +723,16 @@ class XendDomainInfo: 90.354 def _recreateDomFunc(self, t): 90.355 t.remove() 90.356 t.mkdir() 90.357 - t.set_permissions({ 'dom' : self.domid }) 90.358 + t.set_permissions({'dom' : self.domid}) 90.359 t.write('vm', self.vmpath) 90.360 90.361 def _storeDomDetails(self): 90.362 to_store = { 90.363 'domid': str(self.domid), 90.364 'vm': self.vmpath, 90.365 - 'name': self.info['name'], 90.366 + 'name': self.info['name_label'], 90.367 'console/limit': str(xroot.get_console_limit() * 1024), 90.368 - 'memory/target': str(self.info['memory'] * 1024) 90.369 + 'memory/target': str(self.info['memory_static_min'] * 1024) 90.370 } 90.371 90.372 def f(n, v): 90.373 @@ -713,7 +758,7 @@ class XendDomainInfo: 90.374 return 'offline' 90.375 90.376 result = {} 90.377 - for v in range(0, self.info['vcpus']): 90.378 + for v in range(0, self.info['vcpus_number']): 90.379 result["cpu/%d/availability" % v] = availability(v) 90.380 return result 90.381 90.382 @@ -735,19 +780,29 @@ class XendDomainInfo: 90.383 log.trace("XendDomainInfo.storeChanged"); 90.384 90.385 changed = False 90.386 + 90.387 + # Check whether values in the configuration have 90.388 + # changed in Xenstore. 90.389 90.390 - def f(x, y): 90.391 - if y is not None and self.info[x[0]] != y: 90.392 - self.info[x[0]] = y 90.393 - changed = True 90.394 + cfg_vm = ['name', 'on_poweroff', 'on_reboot', 'on_crash'] 90.395 + 90.396 + vm_details = self._readVMDetails([(k,XendConfig.LEGACY_CFG_TYPES[k]) 90.397 + for k in cfg_vm]) 90.398 90.399 - map(f, VM_CONFIG_PARAMS, self._readVMDetails(VM_CONFIG_PARAMS)) 90.400 + # convert two lists into a python dictionary 90.401 + vm_details = dict(zip(cfg_vm, vm_details)) 90.402 + 90.403 + for arg, val in vm_details.items(): 90.404 + if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG: 90.405 + xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg] 90.406 + if val != None and val != self.info[xapiarg]: 90.407 + self.info[xapiarg] = val 90.408 + changed= True 90.409 90.410 - im = self._readVm('image') 90.411 - current_im = self.info['image'] 90.412 - if (im is not None and 90.413 - (current_im is None or sxp.to_string(current_im) != im)): 90.414 - self.info['image'] = sxp.from_string(im) 90.415 + # Check whether image definition has been updated 90.416 + image_sxp = self._readVm('image') 90.417 + if image_sxp and image_sxp != self.info.image_sxpr(): 90.418 + self.info.update_with_image_sxp(sxp.from_string(image_sxp)) 90.419 changed = True 90.420 90.421 if changed: 90.422 @@ -760,17 +815,17 @@ class XendDomainInfo: 90.423 def _handleShutdownWatch(self, _): 90.424 log.debug('XendDomainInfo.handleShutdownWatch') 90.425 90.426 - reason = self._readDom('control/shutdown') 90.427 + reason = self.readDom('control/shutdown') 90.428 90.429 if reason and reason != 'suspend': 90.430 - sst = self._readDom('xend/shutdown_start_time') 90.431 + sst = self.readDom('xend/shutdown_start_time') 90.432 now = time.time() 90.433 if sst: 90.434 self.shutdownStartTime = float(sst) 90.435 timeout = float(sst) + SHUTDOWN_TIMEOUT - now 90.436 else: 90.437 self.shutdownStartTime = now 90.438 - self._storeDom('xend/shutdown_start_time', now) 90.439 + self.storeDom('xend/shutdown_start_time', now) 90.440 timeout = SHUTDOWN_TIMEOUT 90.441 90.442 log.trace( 90.443 @@ -791,17 +846,17 @@ class XendDomainInfo: 90.444 90.445 def setName(self, name): 90.446 self._checkName(name) 90.447 - self.info['name'] = name 90.448 + self.info['name_label'] = name 90.449 self.storeVm("name", name) 90.450 90.451 def getName(self): 90.452 - return self.info['name'] 90.453 + return self.info['name_label'] 90.454 90.455 def getDomainPath(self): 90.456 return self.dompath 90.457 90.458 def getShutdownReason(self): 90.459 - return self._readDom('control/shutdown') 90.460 + return self.readDom('control/shutdown') 90.461 90.462 def getStorePort(self): 90.463 """For use only by image.py and XendCheckpoint.py.""" 90.464 @@ -816,11 +871,13 @@ class XendDomainInfo: 90.465 return self.info['features'] 90.466 90.467 def getVCpuCount(self): 90.468 - return self.info['vcpus'] 90.469 + return self.info['vcpus_number'] 90.470 90.471 def setVCpuCount(self, vcpus): 90.472 self.info['vcpu_avail'] = (1 << vcpus) - 1 90.473 + self.info['vcpus_number'] = vcpus 90.474 self.storeVm('vcpu_avail', self.info['vcpu_avail']) 90.475 + self.storeVm('vcpus', self.info['vcpus_number']) 90.476 self._writeDom(self._vcpuDomDetails()) 90.477 90.478 def getLabel(self): 90.479 @@ -828,19 +885,19 @@ class XendDomainInfo: 90.480 90.481 def getMemoryTarget(self): 90.482 """Get this domain's target memory size, in KB.""" 90.483 - return self.info['memory'] * 1024 90.484 + return self.info['memory_static_min'] * 1024 90.485 90.486 def getResume(self): 90.487 - return "%s" % self.info['resume'] 90.488 + return str(self._resume) 90.489 90.490 def getCap(self): 90.491 - return self.info['cpu_cap'] 90.492 + return self.info.get('cpu_cap', 0) 90.493 90.494 def getWeight(self): 90.495 return self.info['cpu_weight'] 90.496 90.497 def setResume(self, state): 90.498 - self.info['resume'] = state 90.499 + self._resume = state 90.500 90.501 def getRestartCount(self): 90.502 return self._readVm('xend/restart_count') 90.503 @@ -885,13 +942,13 @@ class XendDomainInfo: 90.504 return 90.505 90.506 elif xeninfo['crashed']: 90.507 - if self._readDom('xend/shutdown_completed'): 90.508 + if self.readDom('xend/shutdown_completed'): 90.509 # We've seen this shutdown already, but we are preserving 90.510 # the domain for debugging. Leave it alone. 90.511 return 90.512 90.513 log.warn('Domain has crashed: name=%s id=%d.', 90.514 - self.info['name'], self.domid) 90.515 + self.info['name_label'], self.domid) 90.516 90.517 if xroot.get_enable_dump(): 90.518 self.dumpCore() 90.519 @@ -901,7 +958,7 @@ class XendDomainInfo: 90.520 90.521 elif xeninfo['shutdown']: 90.522 self._stateSet(DOM_STATE_SHUTDOWN) 90.523 - if self._readDom('xend/shutdown_completed'): 90.524 + if self.readDom('xend/shutdown_completed'): 90.525 # We've seen this shutdown already, but we are preserving 90.526 # the domain for debugging. Leave it alone. 90.527 return 90.528 @@ -910,7 +967,7 @@ class XendDomainInfo: 90.529 reason = shutdown_reason(xeninfo['shutdown_reason']) 90.530 90.531 log.info('Domain has shutdown: name=%s id=%d reason=%s.', 90.532 - self.info['name'], self.domid, reason) 90.533 + self.info['name_label'], self.domid, reason) 90.534 90.535 self._clearRestart() 90.536 90.537 @@ -945,7 +1002,7 @@ class XendDomainInfo: 90.538 if timeout < 0: 90.539 log.info( 90.540 "Domain shutdown timeout expired: name=%s id=%s", 90.541 - self.info['name'], self.domid) 90.542 + self.info['name_label'], self.domid) 90.543 self.destroy() 90.544 finally: 90.545 self.refresh_shutdown_lock.release() 90.546 @@ -965,11 +1022,23 @@ class XendDomainInfo: 90.547 def _maybeRestart(self, reason): 90.548 # Dispatch to the correct method based upon the configured on_{reason} 90.549 # behaviour. 90.550 - {"destroy" : self.destroy, 90.551 - "restart" : self._restart, 90.552 - "preserve" : self._preserve, 90.553 - "rename-restart" : self._renameRestart}[self.info['on_' + reason]]() 90.554 + actions = {"destroy" : self.destroy, 90.555 + "restart" : self._restart, 90.556 + "preserve" : self._preserve, 90.557 + "rename-restart" : self._renameRestart} 90.558 90.559 + action_conf = { 90.560 + 'poweroff': 'actions_after_shutdown', 90.561 + 'reboot': 'actions_after_reboot', 90.562 + 'crash': 'actions_after_crash', 90.563 + } 90.564 + 90.565 + action_target = self.info.get(action_conf.get(reason)) 90.566 + func = actions.get(action_target, None) 90.567 + if func and callable(func): 90.568 + func() 90.569 + else: 90.570 + self.destroy() # default to destroy 90.571 90.572 def _renameRestart(self): 90.573 self._restart(True) 90.574 @@ -1008,7 +1077,7 @@ class XendDomainInfo: 90.575 log.error( 90.576 'VM %s restarting too fast (%f seconds since the last ' 90.577 'restart). Refusing to restart to avoid loops.', 90.578 - self.info['name'], timeout) 90.579 + self.info['name_label'], timeout) 90.580 self.destroy() 90.581 return 90.582 90.583 @@ -1055,11 +1124,11 @@ class XendDomainInfo: 90.584 new_uuid = uuid.createString() 90.585 new_name = 'Domain-%s' % new_uuid 90.586 log.info("Renaming dead domain %s (%d, %s) to %s (%s).", 90.587 - self.info['name'], self.domid, self.info['uuid'], 90.588 + self.info['name_label'], self.domid, self.info['uuid'], 90.589 new_name, new_uuid) 90.590 self._unwatchVm() 90.591 self._releaseDevices() 90.592 - self.info['name'] = new_name 90.593 + self.info['name_label'] = new_name 90.594 self.info['uuid'] = new_uuid 90.595 self.vmpath = XS_VMROOT + new_uuid 90.596 self._storeVmDetails() 90.597 @@ -1067,10 +1136,10 @@ class XendDomainInfo: 90.598 90.599 90.600 def _preserve(self): 90.601 - log.info("Preserving dead domain %s (%d).", self.info['name'], 90.602 + log.info("Preserving dead domain %s (%d).", self.info['name_label'], 90.603 self.domid) 90.604 self._unwatchVm() 90.605 - self._storeDom('xend/shutdown_completed', 'True') 90.606 + self.storeDom('xend/shutdown_completed', 'True') 90.607 self._stateSet(DOM_STATE_HALTED) 90.608 90.609 # 90.610 @@ -1084,7 +1153,7 @@ class XendDomainInfo: 90.611 if not corefile: 90.612 this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime()) 90.613 corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time, 90.614 - self.info['name'], self.domid) 90.615 + self.info['name_label'], self.domid) 90.616 90.617 if os.path.isdir(corefile): 90.618 raise XendError("Cannot dump core in a directory: %s" % 90.619 @@ -1095,7 +1164,7 @@ class XendDomainInfo: 90.620 corefile_incomp = corefile+'-incomplete' 90.621 os.rename(corefile, corefile_incomp) 90.622 log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s", 90.623 - self.domid, self.info['name']) 90.624 + self.domid, self.info['name_label']) 90.625 raise XendError("Failed to dump core: %s" % str(ex)) 90.626 90.627 # 90.628 @@ -1117,8 +1186,8 @@ class XendDomainInfo: 90.629 90.630 @raise: VmError for invalid devices 90.631 """ 90.632 - for (devclass, config) in self.info.all_devices_sxpr(): 90.633 - if devclass in XendDevices.valid_devices(): 90.634 + for (devclass, config) in self.info.get('devices', {}).values(): 90.635 + if devclass in XendDevices.valid_devices(): 90.636 log.info("createDevice: %s : %s" % (devclass, config)) 90.637 self._createDevice(devclass, config) 90.638 90.639 @@ -1139,7 +1208,7 @@ class XendDomainInfo: 90.640 # there's nothing more we can do. 90.641 log.exception( 90.642 "Device release failed: %s; %s; %s", 90.643 - self.info['name'], devclass, dev) 90.644 + self.info['name_label'], devclass, dev) 90.645 if t.commit(): 90.646 break 90.647 90.648 @@ -1211,11 +1280,12 @@ class XendDomainInfo: 90.649 90.650 log.debug('XendDomainInfo.constructDomain') 90.651 90.652 - hvm = (self._infoIsSet('image') and 90.653 - sxp.name(self.info['image']) == "hvm") 90.654 + image_cfg = self.info.get('image', {}) 90.655 + hvm = image_cfg.has_key('hvm') 90.656 + 90.657 if hvm: 90.658 info = xc.xeninfo() 90.659 - if not 'hvm' in info['xen_caps']: 90.660 + if 'hvm' not in info['xen_caps']: 90.661 raise VmError("HVM guest support is unavailable: is VT/AMD-V " 90.662 "supported by your CPU and enabled in your " 90.663 "BIOS?") 90.664 @@ -1228,14 +1298,14 @@ class XendDomainInfo: 90.665 90.666 if self.domid < 0: 90.667 raise VmError('Creating domain failed: name=%s' % 90.668 - self.info['name']) 90.669 + self.info['name_label']) 90.670 90.671 self.dompath = GetDomainPath(self.domid) 90.672 90.673 self._recreateDom() 90.674 90.675 # Set maximum number of vcpus in domain 90.676 - xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])) 90.677 + xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number'])) 90.678 90.679 90.680 def _introduceDomain(self): 90.681 @@ -1256,7 +1326,7 @@ class XendDomainInfo: 90.682 90.683 # if we have a boot loader but no image, then we need to set things 90.684 # up by running the boot loader non-interactively 90.685 - if self._infoIsSet('bootloader') and not self._infoIsSet('image'): 90.686 + if self.info.get('bootloader') and self.info.get('image'): 90.687 self._configureBootloader() 90.688 90.689 if not self._infoIsSet('image'): 90.690 @@ -1264,11 +1334,12 @@ class XendDomainInfo: 90.691 90.692 try: 90.693 self.image = image.create(self, 90.694 + self.info, 90.695 self.info['image'], 90.696 - self.info.all_devices_sxpr()) 90.697 + self.info['devices']) 90.698 90.699 - localtime = self.info.get('localtime', 0) 90.700 - if localtime is not None and localtime == 1: 90.701 + localtime = self.info.get('localtime', False) 90.702 + if localtime: 90.703 xc.domain_set_time_offset(self.domid) 90.704 90.705 xc.domain_setcpuweight(self.domid, self.info['cpu_weight']) 90.706 @@ -1284,12 +1355,12 @@ class XendDomainInfo: 90.707 # the various headrooms necessary, given the raw configured 90.708 # values. maxmem, memory, and shadow are all in KiB. 90.709 maxmem = self.image.getRequiredAvailableMemory( 90.710 - self.info['maxmem'] * 1024) 90.711 + self.info['memory_static_min'] * 1024) 90.712 memory = self.image.getRequiredAvailableMemory( 90.713 - self.info['memory'] * 1024) 90.714 + self.info['memory_static_max'] * 1024) 90.715 shadow = self.image.getRequiredShadowMemory( 90.716 self.info['shadow_memory'] * 1024, 90.717 - self.info['maxmem'] * 1024) 90.718 + self.info['memory_static_max'] * 1024) 90.719 90.720 # Round shadow up to a multiple of a MiB, as shadow_mem_control 90.721 # takes MiB and we must not round down and end up under-providing. 90.722 @@ -1317,7 +1388,7 @@ class XendDomainInfo: 90.723 90.724 self._createDevices() 90.725 90.726 - if self.info['bootloader'] not in [None, 'kernel_external']: 90.727 + if self.info['bootloader']: 90.728 self.image.cleanupBootloading() 90.729 90.730 self.info['start_time'] = time.time() 90.731 @@ -1325,7 +1396,7 @@ class XendDomainInfo: 90.732 self._stateSet(DOM_STATE_RUNNING) 90.733 except RuntimeError, exn: 90.734 log.exception("XendDomainInfo.initDomain: exception occurred") 90.735 - if self.info['bootloader'] not in [None, 'kernel_external'] \ 90.736 + if self.info['bootloader'] not in (None, 'kernel_external') \ 90.737 and self.image is not None: 90.738 self.image.cleanupBootloading() 90.739 raise VmError(str(exn)) 90.740 @@ -1338,7 +1409,6 @@ class XendDomainInfo: 90.741 self.refresh_shutdown_lock.acquire() 90.742 try: 90.743 self.unwatchShutdown() 90.744 - 90.745 self._releaseDevices() 90.746 90.747 if self.image: 90.748 @@ -1459,14 +1529,14 @@ class XendDomainInfo: 90.749 90.750 def _configureBootloader(self): 90.751 """Run the bootloader if we're configured to do so.""" 90.752 - if not self.info['bootloader']: 90.753 + if not self.info.get('bootloader'): 90.754 return 90.755 blcfg = None 90.756 # FIXME: this assumes that we want to use the first disk device 90.757 - for (n, c) in self.info.all_devices_sxpr(): 90.758 - if not n or not c or not(n in ["vbd", "tap"]): 90.759 + for devuuid, (devtype, devinfo) in self.info.all_devices_sxpr(): 90.760 + if not devtype or not devinfo or devtype not in ('vbd', 'tap'): 90.761 continue 90.762 - disk = sxp.child_value(c, "uname") 90.763 + disk = devinfo.get('uname') 90.764 if disk is None: 90.765 continue 90.766 fn = blkdev_uname_to_file(disk) 90.767 @@ -1478,7 +1548,8 @@ class XendDomainInfo: 90.768 msg = "Had a bootloader specified, but can't find disk" 90.769 log.error(msg) 90.770 raise VmError(msg) 90.771 - self.info['image'] = blcfg 90.772 + 90.773 + self.info.update_with_image_sxp(blcfg) 90.774 90.775 # 90.776 # VM Functions 90.777 @@ -1516,7 +1587,8 @@ class XendDomainInfo: 90.778 if arch.type == "x86": 90.779 # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than 90.780 # the minimum that Xen would allocate if no value were given. 90.781 - overhead_kb = self.info['vcpus'] * 1024 + self.info['maxmem'] * 4 90.782 + overhead_kb = self.info['vcpus_number'] * 1024 + \ 90.783 + self.info['memory_static_max'] * 4 90.784 overhead_kb = ((overhead_kb + 1023) / 1024) * 1024 90.785 # The domain might already have some shadow memory 90.786 overhead_kb -= xc.shadow_mem_control(self.domid) * 1024 90.787 @@ -1558,12 +1630,15 @@ class XendDomainInfo: 90.788 def _storeVmDetails(self): 90.789 to_store = {} 90.790 90.791 - for k in VM_STORE_ENTRIES: 90.792 - if self._infoIsSet(k[0]): 90.793 - to_store[k[0]] = str(self.info[k[0]]) 90.794 + for key in XendConfig.LEGACY_XENSTORE_VM_PARAMS: 90.795 + info_key = XendConfig.LEGACY_CFG_TO_XENAPI_CFG.get(key, key) 90.796 + if self._infoIsSet(info_key): 90.797 + to_store[key] = str(self.info[info_key]) 90.798 90.799 - if self._infoIsSet('image'): 90.800 - to_store['image'] = sxp.to_string(self.info['image']) 90.801 + if self.info.get('image'): 90.802 + image_sxpr = self.info.image_sxpr() 90.803 + if image_sxpr: 90.804 + to_store['image'] = sxp.to_string(image_sxpr) 90.805 90.806 if self._infoIsSet('security'): 90.807 secinfo = self.info['security'] 90.808 @@ -1633,8 +1708,9 @@ class XendDomainInfo: 90.809 raise VmError('Invalid VM Name') 90.810 90.811 dom = XendDomain.instance().domain_lookup_nr(name) 90.812 - if dom and dom != self and not dom.info['dying']: 90.813 - raise VmError("VM name '%s' already exists" % name) 90.814 + if dom and dom.info['uuid'] != self.info['uuid']: 90.815 + raise VmError("VM name '%s' already exists as domain %s" % 90.816 + (name, str(dom.domid))) 90.817 90.818 90.819 def update(self, info = None, refresh = True): 90.820 @@ -1656,6 +1732,7 @@ class XendDomainInfo: 90.821 #create new security element 90.822 self.info.update({'security': 90.823 [['ssidref', str(info['ssidref'])]]}) 90.824 + 90.825 #ssidref field not used any longer 90.826 if 'ssidref' in info: 90.827 info.pop('ssidref') 90.828 @@ -1663,8 +1740,7 @@ class XendDomainInfo: 90.829 # make sure state is reset for info 90.830 # TODO: we should eventually get rid of old_dom_states 90.831 90.832 - self.info.update(info) 90.833 - self.info.validate() 90.834 + self.info.update_config(info) 90.835 90.836 if refresh: 90.837 self.refreshShutdown(info) 90.838 @@ -1673,11 +1749,11 @@ class XendDomainInfo: 90.839 str(self.domid), self.info) 90.840 90.841 def sxpr(self, ignore_store = False): 90.842 - result = self.info.get_sxp(domain = self, 90.843 + result = self.info.to_sxp(domain = self, 90.844 ignore_devices = ignore_store) 90.845 90.846 if not ignore_store and self.dompath: 90.847 - vnc_port = self._readDom('console/vnc-port') 90.848 + vnc_port = self.readDom('console/vnc-port') 90.849 if vnc_port is not None: 90.850 result.append(['device', 90.851 ['console', ['vnc-port', str(vnc_port)]]]) 90.852 @@ -1695,9 +1771,15 @@ class XendDomainInfo: 90.853 return dom_uuid 90.854 90.855 def get_memory_static_max(self): 90.856 - return self.info['maxmem'] 90.857 + return self.info.get('memory_static_max') 90.858 def get_memory_static_min(self): 90.859 - return self.info['memory'] 90.860 + return self.info.get('memory_static_min') 90.861 + def get_memory_dynamic_max(self): 90.862 + return self.info.get('memory_dynamic_min') 90.863 + def get_memory_dynamic_min(self): 90.864 + return self.info.get('memory_dynamic_max') 90.865 + 90.866 + 90.867 def get_vcpus_policy(self): 90.868 sched_id = xc.sched_id_get() 90.869 if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF: 90.870 @@ -1713,31 +1795,29 @@ class XendDomainInfo: 90.871 def get_bios_boot(self): 90.872 return '' # TODO 90.873 def get_platform_std_vga(self): 90.874 - return False 90.875 + return self.info.get('platform_std_vga', False) 90.876 def get_platform_keymap(self): 90.877 return '' 90.878 def get_platform_serial(self): 90.879 - return '' # TODO 90.880 + return self.info.get('platform_serial', '') 90.881 def get_platform_localtime(self): 90.882 - return False # TODO 90.883 + return self.info.get('platform_localtime', False) 90.884 def get_platform_clock_offset(self): 90.885 - return False # TODO 90.886 + return self.info.get('platform_clock_offset', False) 90.887 def get_platform_enable_audio(self): 90.888 - return False # TODO 90.889 + return self.info.get('platform_enable_audio', False) 90.890 + def get_platform_keymap(self): 90.891 + return self.info.get('platform_keymap', '') 90.892 def get_builder(self): 90.893 - return 'Linux' # TODO 90.894 + return self.info.get('builder', 0) 90.895 def get_boot_method(self): 90.896 - bootloader = self.info['bootloader'] 90.897 - if not bootloader or bootloader not in XEN_API_BOOT_TYPE: 90.898 - return 'kernel_external' 90.899 - return bootloader 90.900 - 90.901 + return self.info.get('boot_method', '') 90.902 def get_kernel_image(self): 90.903 - return self.info['kernel_kernel'] 90.904 + return self.info.get('kernel_kernel', '') 90.905 def get_kernel_initrd(self): 90.906 - return self.info['kernel_initrd'] 90.907 + return self.info.get('kernel_initrd', '') 90.908 def get_kernel_args(self): 90.909 - return self.info['kernel_args'] 90.910 + return self.info.get('kernel_args', '') 90.911 def get_grub_cmdline(self): 90.912 return '' # TODO 90.913 def get_pci_bus(self): 90.914 @@ -1748,25 +1828,26 @@ class XendDomainInfo: 90.915 return {} # TODO 90.916 90.917 def get_on_shutdown(self): 90.918 - after_shutdown = self.info.get('on_poweroff') 90.919 + after_shutdown = self.info.get('action_after_shutdown') 90.920 if not after_shutdown or after_shutdown not in XEN_API_ON_NORMAL_EXIT: 90.921 return XEN_API_ON_NORMAL_EXIT[-1] 90.922 return after_shutdown 90.923 90.924 def get_on_reboot(self): 90.925 - after_reboot = self.info.get('on_reboot') 90.926 + after_reboot = self.info.get('action_after_reboot') 90.927 if not after_reboot or after_reboot not in XEN_API_ON_NORMAL_EXIT: 90.928 return XEN_API_ON_NORMAL_EXIT[-1] 90.929 return after_reboot 90.930 90.931 def get_on_suspend(self): 90.932 - after_suspend = self.info.get('on_suspend') # TODO: not supported 90.933 + # TODO: not supported 90.934 + after_suspend = self.info.get('action_after_suspend') 90.935 if not after_suspend or after_suspend not in XEN_API_ON_NORMAL_EXIT: 90.936 return XEN_API_ON_NORMAL_EXIT[-1] 90.937 return after_suspend 90.938 90.939 def get_on_crash(self): 90.940 - after_crash = self.info.get('on_crash') 90.941 + after_crash = self.info.get('action_after_crash') 90.942 if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR: 90.943 return XEN_API_ON_CRASH_BEHAVIOUR[0] 90.944 return after_crash 90.945 @@ -1780,7 +1861,7 @@ class XendDomainInfo: 90.946 90.947 @rtype: dictionary 90.948 """ 90.949 - dev_type_config = self.info['device'].get(dev_uuid) 90.950 + dev_type_config = self.info['devices'].get(dev_uuid) 90.951 90.952 # shortcut if the domain isn't started because 90.953 # the devcontrollers will have no better information 90.954 @@ -1840,7 +1921,7 @@ class XendDomainInfo: 90.955 config['IO_bandwidth_incoming_kbs'] = 0.0 90.956 config['IO_bandwidth_outgoing_kbs'] = 0.0 90.957 90.958 - if dev_class =='vbd': 90.959 + if dev_class == 'vbd': 90.960 config['VDI'] = '' # TODO 90.961 config['device'] = config.get('dev', '') 90.962 config['driver'] = 'paravirtualised' # TODO 90.963 @@ -1984,8 +2065,8 @@ class XendDomainInfo: 90.964 90.965 def __str__(self): 90.966 return '<domain id=%s name=%s memory=%s state=%s>' % \ 90.967 - (str(self.domid), self.info['name'], 90.968 - str(self.info['memory']), DOM_STATES[self.state]) 90.969 + (str(self.domid), self.info['name_label'], 90.970 + str(self.info['memory_static_min']), DOM_STATES[self.state]) 90.971 90.972 __repr__ = __str__ 90.973
91.1 --- a/tools/python/xen/xend/XendLogging.py Sat Dec 02 15:19:50 2006 -0700 91.2 +++ b/tools/python/xen/xend/XendLogging.py Mon Dec 04 08:24:41 2006 -0700 91.3 @@ -16,13 +16,15 @@ 91.4 # Copyright (C) 2005, 2006 XenSource Ltd. 91.5 #============================================================================ 91.6 91.7 - 91.8 +import os 91.9 +import stat 91.10 import tempfile 91.11 import types 91.12 import logging 91.13 import logging.handlers 91.14 import fcntl 91.15 91.16 +from xen.util import mkdir 91.17 from xen.xend.server import params 91.18 91.19 91.20 @@ -80,6 +82,7 @@ def init(filename, level): 91.21 global logfilename 91.22 91.23 def openFileHandler(fname): 91.24 + mkdir.parents(os.path.dirname(fname), stat.S_IRWXU) 91.25 return XendRotatingFileHandler(fname, mode = 'a', 91.26 maxBytes = MAX_BYTES, 91.27 backupCount = BACKUP_COUNT)
92.1 --- a/tools/python/xen/xend/XendStorageRepository.py Sat Dec 02 15:19:50 2006 -0700 92.2 +++ b/tools/python/xen/xend/XendStorageRepository.py Mon Dec 04 08:24:41 2006 -0700 92.3 @@ -19,10 +19,12 @@ 92.4 # The default QCOW Xen API Storage Repository 92.5 # 92.6 92.7 +import commands 92.8 import os 92.9 -import commands 92.10 +import stat 92.11 import threading 92.12 92.13 +from xen.util import mkdir 92.14 from xen.xend import uuid 92.15 from xen.xend.XendError import XendError 92.16 from xen.xend.XendVDI import * 92.17 @@ -98,10 +100,7 @@ class XendStorageRepository: 92.18 """ 92.19 self.lock.acquire() 92.20 try: 92.21 - # create directory if /var/lib/xend/storage does not exist 92.22 - if not os.path.exists(XEND_STORAGE_DIR): 92.23 - os.makedirs(XEND_STORAGE_DIR) 92.24 - os.chmod(XEND_STORAGE_DIR, 0700) 92.25 + mkdir.parents(XEND_STORAGE_DIR, stat.S_IRWXU) 92.26 92.27 # scan the directory and populate self.images 92.28 total_used = 0
93.1 --- a/tools/python/xen/xend/image.py Sat Dec 02 15:19:50 2006 -0700 93.2 +++ b/tools/python/xen/xend/image.py Mon Dec 04 08:24:41 2006 -0700 93.3 @@ -23,7 +23,7 @@ import math 93.4 import signal 93.5 93.6 import xen.lowlevel.xc 93.7 -from xen.xend import sxp 93.8 +from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS 93.9 from xen.xend.XendError import VmError, XendError 93.10 from xen.xend.XendLogging import log 93.11 from xen.xend.server.netif import randomMAC 93.12 @@ -31,19 +31,18 @@ from xen.xend.xenstore.xswatch import xs 93.13 from xen.xend import arch 93.14 from xen.xend import FlatDeviceTree 93.15 93.16 - 93.17 xc = xen.lowlevel.xc.xc() 93.18 93.19 - 93.20 MAX_GUEST_CMDLINE = 1024 93.21 93.22 93.23 -def create(vm, imageConfig, deviceConfig): 93.24 +def create(vm, vmConfig, imageConfig, deviceConfig): 93.25 """Create an image handler for a vm. 93.26 93.27 @return ImageHandler instance 93.28 """ 93.29 - return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig) 93.30 + return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig, 93.31 + deviceConfig) 93.32 93.33 93.34 class ImageHandler: 93.35 @@ -66,34 +65,20 @@ class ImageHandler: 93.36 ostype = None 93.37 93.38 93.39 - def __init__(self, vm, imageConfig, deviceConfig): 93.40 + def __init__(self, vm, vmConfig, imageConfig, deviceConfig): 93.41 self.vm = vm 93.42 93.43 self.kernel = None 93.44 self.ramdisk = None 93.45 self.cmdline = None 93.46 93.47 - self.configure(imageConfig, deviceConfig) 93.48 - 93.49 - def configure(self, imageConfig, _): 93.50 - """Config actions common to all unix-like domains.""" 93.51 - 93.52 - def get_cfg(name, default = None): 93.53 - return sxp.child_value(imageConfig, name, default) 93.54 + self.configure(vmConfig, imageConfig, deviceConfig) 93.55 93.56 - self.kernel = get_cfg("kernel") 93.57 - self.cmdline = "" 93.58 - ip = get_cfg("ip") 93.59 - if ip: 93.60 - self.cmdline += " ip=" + ip 93.61 - root = get_cfg("root") 93.62 - if root: 93.63 - self.cmdline += " root=" + root 93.64 - args = get_cfg("args") 93.65 - if args: 93.66 - self.cmdline += " " + args 93.67 - self.ramdisk = get_cfg("ramdisk", '') 93.68 - 93.69 + def configure(self, vmConfig, imageConfig, _): 93.70 + """Config actions common to all unix-like domains.""" 93.71 + self.kernel = vmConfig['kernel_kernel'] 93.72 + self.cmdline = vmConfig['kernel_args'] 93.73 + self.ramdisk = vmConfig['kernel_initrd'] 93.74 self.vm.storeVm(("image/ostype", self.ostype), 93.75 ("image/kernel", self.kernel), 93.76 ("image/cmdline", self.cmdline), 93.77 @@ -181,6 +166,10 @@ class ImageHandler: 93.78 pass 93.79 93.80 93.81 + def recreate(self): 93.82 + pass 93.83 + 93.84 + 93.85 class LinuxImageHandler(ImageHandler): 93.86 93.87 ostype = "linux" 93.88 @@ -214,8 +203,8 @@ class PPC_LinuxImageHandler(LinuxImageHa 93.89 93.90 ostype = "linux" 93.91 93.92 - def configure(self, imageConfig, deviceConfig): 93.93 - LinuxImageHandler.configure(self, imageConfig, deviceConfig) 93.94 + def configure(self, vmConfig, imageConfig, deviceConfig): 93.95 + LinuxImageHandler.configure(self, vmConfig, imageConfig, deviceConfig) 93.96 self.imageConfig = imageConfig 93.97 93.98 def buildDomain(self): 93.99 @@ -248,37 +237,42 @@ class PPC_LinuxImageHandler(LinuxImageHa 93.100 93.101 class HVMImageHandler(ImageHandler): 93.102 93.103 - def __init__(self, vm, imageConfig, deviceConfig): 93.104 - ImageHandler.__init__(self, vm, imageConfig, deviceConfig) 93.105 + ostype = "hvm" 93.106 + 93.107 + def __init__(self, vm, vmConfig, imageConfig, deviceConfig): 93.108 + ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig) 93.109 self.shutdownWatch = None 93.110 + self.rebootFeatureWatch = None 93.111 93.112 - def configure(self, imageConfig, deviceConfig): 93.113 - ImageHandler.configure(self, imageConfig, deviceConfig) 93.114 + def configure(self, vmConfig, imageConfig, deviceConfig): 93.115 + ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig) 93.116 93.117 info = xc.xeninfo() 93.118 - if not 'hvm' in info['xen_caps']: 93.119 + if 'hvm' not in info['xen_caps']: 93.120 raise VmError("HVM guest support is unavailable: is VT/AMD-V " 93.121 "supported by your CPU and enabled in your BIOS?") 93.122 93.123 self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig) 93.124 - self.device_model = sxp.child_value(imageConfig, 'device_model') 93.125 + self.device_model = imageConfig['hvm'].get('device_model') 93.126 if not self.device_model: 93.127 raise VmError("hvm: missing device model") 93.128 - self.display = sxp.child_value(imageConfig, 'display') 93.129 - self.xauthority = sxp.child_value(imageConfig, 'xauthority') 93.130 - self.vncconsole = sxp.child_value(imageConfig, 'vncconsole') 93.131 + 93.132 + self.display = imageConfig['hvm'].get('display') 93.133 + self.xauthority = imageConfig['hvm'].get('xauthority') 93.134 + self.vncconsole = imageConfig['hvm'].get('vncconsole') 93.135 93.136 self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)), 93.137 ("image/device-model", self.device_model), 93.138 ("image/display", self.display)) 93.139 93.140 - self.pid = 0 93.141 + self.pid = None 93.142 93.143 self.dmargs += self.configVNC(imageConfig) 93.144 93.145 - self.pae = int(sxp.child_value(imageConfig, 'pae', 1)) 93.146 - self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1)) 93.147 - self.apic = int(sxp.child_value(imageConfig, 'apic', 1)) 93.148 + self.pae = imageConfig['hvm'].get('pae', 0) 93.149 + self.apic = imageConfig['hvm'].get('apic', 0) 93.150 + self.acpi = imageConfig['hvm']['devices'].get('acpi', 0) 93.151 + 93.152 93.153 def buildDomain(self): 93.154 store_evtchn = self.vm.getStorePort() 93.155 @@ -295,6 +289,7 @@ class HVMImageHandler(ImageHandler): 93.156 log.debug("apic = %d", self.apic) 93.157 93.158 self.register_shutdown_watch() 93.159 + self.register_reboot_feature_watch() 93.160 93.161 return xc.hvm_build(domid = self.vm.getDomid(), 93.162 image = self.kernel, 93.163 @@ -312,8 +307,10 @@ class HVMImageHandler(ImageHandler): 93.164 'localtime', 'serial', 'stdvga', 'isa', 'vcpus', 93.165 'acpi', 'usb', 'usbdevice', 'keymap' ] 93.166 ret = [] 93.167 + hvmDeviceConfig = imageConfig['hvm']['devices'] 93.168 + 93.169 for a in dmargs: 93.170 - v = sxp.child_value(imageConfig, a) 93.171 + v = hvmDeviceConfig.get(a) 93.172 93.173 # python doesn't allow '-' in variable names 93.174 if a == 'stdvga': a = 'std-vga' 93.175 @@ -328,7 +325,7 @@ class HVMImageHandler(ImageHandler): 93.176 ret.append("-%s" % a) 93.177 ret.append("%s" % v) 93.178 93.179 - if a in ['fda', 'fdb' ]: 93.180 + if a in ['fda', 'fdb']: 93.181 if v: 93.182 if not os.path.isabs(v): 93.183 raise VmError("Floppy file %s does not exist." % v) 93.184 @@ -336,26 +333,27 @@ class HVMImageHandler(ImageHandler): 93.185 93.186 # Handle disk/network related options 93.187 mac = None 93.188 - ret = ret + ["-domain-name", "%s" % self.vm.info['name']] 93.189 + ret = ret + ["-domain-name", str(self.vm.info['name_label'])] 93.190 nics = 0 93.191 - for (name, info) in deviceConfig: 93.192 - if name == 'vbd': 93.193 - uname = sxp.child_value(info, 'uname') 93.194 + 93.195 + for devuuid, (devtype, devinfo) in deviceConfig.items(): 93.196 + if devtype == 'vbd': 93.197 + uname = devinfo['uname'] 93.198 if uname is not None and 'file:' in uname: 93.199 (_, vbdparam) = string.split(uname, ':', 1) 93.200 if not os.path.isfile(vbdparam): 93.201 raise VmError('Disk image does not exist: %s' % 93.202 vbdparam) 93.203 - if name == 'vif': 93.204 - type = sxp.child_value(info, 'type') 93.205 - if type != 'ioemu': 93.206 + if devtype == 'vif': 93.207 + dtype = devinfo.get('type', 'ioemu') 93.208 + if dtype != 'ioemu': 93.209 continue 93.210 nics += 1 93.211 - mac = sxp.child_value(info, 'mac') 93.212 + mac = devinfo.get('mac') 93.213 if mac == None: 93.214 mac = randomMAC() 93.215 - bridge = sxp.child_value(info, 'bridge', 'xenbr0') 93.216 - model = sxp.child_value(info, 'model', 'rtl8139') 93.217 + bridge = devinfo.get('bridge', 'xenbr0') 93.218 + model = devinfo.get('model', 'rtl8139') 93.219 ret.append("-net") 93.220 ret.append("nic,vlan=%d,macaddr=%s,model=%s" % 93.221 (nics, mac, model)) 93.222 @@ -363,31 +361,32 @@ class HVMImageHandler(ImageHandler): 93.223 ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge)) 93.224 return ret 93.225 93.226 - def configVNC(self, config): 93.227 + def configVNC(self, imageConfig): 93.228 # Handle graphics library related options 93.229 - vnc = sxp.child_value(config, 'vnc') 93.230 - sdl = sxp.child_value(config, 'sdl') 93.231 + vnc = imageConfig.get('vnc') 93.232 + sdl = imageConfig.get('sdl') 93.233 ret = [] 93.234 - nographic = sxp.child_value(config, 'nographic') 93.235 + nographic = imageConfig.get('nographic') 93.236 93.237 # get password from VM config (if password omitted, None) 93.238 - vncpasswd_vmconfig = sxp.child_value(config, 'vncpasswd') 93.239 + vncpasswd_vmconfig = imageConfig.get('vncpasswd') 93.240 93.241 if nographic: 93.242 ret.append('-nographic') 93.243 return ret 93.244 93.245 if vnc: 93.246 - vncdisplay = int(sxp.child_value(config, 'vncdisplay', 93.247 - self.vm.getDomid())) 93.248 + vncdisplay = imageConfig.get('vncdisplay', 93.249 + int(self.vm.getDomid())) 93.250 + vncunused = imageConfig.get('vncunused') 93.251 93.252 - vncunused = sxp.child_value(config, 'vncunused') 93.253 if vncunused: 93.254 ret += ['-vncunused'] 93.255 else: 93.256 ret += ['-vnc', '%d' % vncdisplay] 93.257 93.258 - vnclisten = sxp.child_value(config, 'vnclisten') 93.259 + vnclisten = imageConfig.get('vnclisten') 93.260 + 93.261 if not(vnclisten): 93.262 vnclisten = (xen.xend.XendRoot.instance(). 93.263 get_vnclisten_address()) 93.264 @@ -423,21 +422,37 @@ class HVMImageHandler(ImageHandler): 93.265 if self.vncconsole: 93.266 args = args + ([ "-vncviewer" ]) 93.267 log.info("spawning device models: %s %s", self.device_model, args) 93.268 + # keep track of pid and spawned options to kill it later 93.269 self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env) 93.270 + self.vm.storeDom("image/device-model-pid", self.pid) 93.271 log.info("device model pid: %d", self.pid) 93.272 93.273 + def recreate(self): 93.274 + self.register_shutdown_watch() 93.275 + self.register_reboot_feature_watch() 93.276 + self.pid = self.vm.gatherDom(('image/device-model-pid', int)) 93.277 + 93.278 def destroy(self): 93.279 - self.unregister_shutdown_watch(); 93.280 - if not self.pid: 93.281 - return 93.282 - os.kill(self.pid, signal.SIGKILL) 93.283 - os.waitpid(self.pid, 0) 93.284 - self.pid = 0 93.285 + self.unregister_shutdown_watch() 93.286 + self.unregister_reboot_feature_watch(); 93.287 + if self.pid: 93.288 + try: 93.289 + os.kill(self.pid, signal.SIGKILL) 93.290 + except OSError, exn: 93.291 + log.exception(exn) 93.292 + try: 93.293 + os.waitpid(self.pid, 0) 93.294 + except OSError, exn: 93.295 + # This is expected if Xend has been restarted within the 93.296 + # life of this domain. In this case, we can kill the process, 93.297 + # but we can't wait for it because it's not our child. 93.298 + pass 93.299 + self.pid = None 93.300 93.301 def register_shutdown_watch(self): 93.302 """ add xen store watch on control/shutdown """ 93.303 - self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \ 93.304 - self.hvm_shutdown) 93.305 + self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", 93.306 + self.hvm_shutdown) 93.307 log.debug("hvm shutdown watch registered") 93.308 93.309 def unregister_shutdown_watch(self): 93.310 @@ -456,28 +471,55 @@ class HVMImageHandler(ImageHandler): 93.311 """ watch call back on node control/shutdown, 93.312 if node changed, this function will be called 93.313 """ 93.314 - from xen.xend.XendConstants import DOMAIN_SHUTDOWN_REASONS 93.315 xd = xen.xend.XendDomain.instance() 93.316 try: 93.317 vm = xd.domain_lookup( self.vm.getDomid() ) 93.318 except XendError: 93.319 # domain isn't registered, no need to clean it up. 93.320 - return 93.321 + return False 93.322 93.323 reason = vm.getShutdownReason() 93.324 log.debug("hvm_shutdown fired, shutdown reason=%s", reason) 93.325 - for x in DOMAIN_SHUTDOWN_REASONS.keys(): 93.326 - if DOMAIN_SHUTDOWN_REASONS[x] == reason: 93.327 - vm.info['shutdown'] = 1 93.328 - vm.info['shutdown_reason'] = x 93.329 - vm.refreshShutdown(vm.info) 93.330 + if reason in REVERSE_DOMAIN_SHUTDOWN_REASONS: 93.331 + vm.info['shutdown'] = 1 93.332 + vm.info['shutdown_reason'] = \ 93.333 + REVERSE_DOMAIN_SHUTDOWN_REASONS[reason] 93.334 + vm.refreshShutdown(vm.info) 93.335 + 93.336 + return True # Keep watching 93.337 + 93.338 + def register_reboot_feature_watch(self): 93.339 + """ add xen store watch on control/feature-reboot """ 93.340 + self.rebootFeatureWatch = xswatch(self.vm.dompath + "/control/feature-reboot", \ 93.341 + self.hvm_reboot_feature) 93.342 + log.debug("hvm reboot feature watch registered") 93.343 + 93.344 + def unregister_reboot_feature_watch(self): 93.345 + """Remove the watch on the control/feature-reboot, if any. Nothrow 93.346 + guarantee.""" 93.347 93.348 - return 1 # Keep watching 93.349 + try: 93.350 + if self.rebootFeatureWatch: 93.351 + self.rebootFeatureWatch.unwatch() 93.352 + except: 93.353 + log.exception("Unwatching hvm reboot feature watch failed.") 93.354 + self.rebootFeatureWatch = None 93.355 + log.debug("hvm reboot feature watch unregistered") 93.356 + 93.357 + def hvm_reboot_feature(self, _): 93.358 + """ watch call back on node control/feature-reboot, 93.359 + if node changed, this function will be called 93.360 + """ 93.361 + status = self.vm.readDom('control/feature-reboot') 93.362 + log.debug("hvm_reboot_feature fired, module status=%s", status) 93.363 + if status == '1': 93.364 + self.unregister_shutdown_watch() 93.365 + 93.366 + return True # Keep watching 93.367 + 93.368 93.369 class IA64_HVM_ImageHandler(HVMImageHandler): 93.370 93.371 - ostype = "hvm" 93.372 - 93.373 def getRequiredAvailableMemory(self, mem_kb): 93.374 page_kb = 16 93.375 # ROM size for guest firmware, ioreq page and xenstore page 93.376 @@ -490,8 +532,6 @@ class IA64_HVM_ImageHandler(HVMImageHand 93.377 93.378 class X86_HVM_ImageHandler(HVMImageHandler): 93.379 93.380 - ostype = "hvm" 93.381 - 93.382 def getRequiredAvailableMemory(self, mem_kb): 93.383 # Add 8 MiB overhead for QEMU's video RAM. 93.384 return mem_kb + 8192 93.385 @@ -529,10 +569,10 @@ def findImageHandlerClass(image): 93.386 @param image config 93.387 @return ImageHandler subclass or None 93.388 """ 93.389 - type = sxp.name(image) 93.390 - if type is None: 93.391 + image_type = image['type'] 93.392 + if image_type is None: 93.393 raise VmError('missing image type') 93.394 try: 93.395 - return _handlers[arch.type][type] 93.396 + return _handlers[arch.type][image_type] 93.397 except KeyError: 93.398 - raise VmError('unknown image type: ' + type) 93.399 + raise VmError('unknown image type: ' + image_type)
94.1 --- a/tools/python/xen/xend/server/DevController.py Sat Dec 02 15:19:50 2006 -0700 94.2 +++ b/tools/python/xen/xend/server/DevController.py Mon Dec 04 08:24:41 2006 -0700 94.3 @@ -17,6 +17,7 @@ 94.4 #============================================================================ 94.5 94.6 from threading import Event 94.7 +import types 94.8 94.9 from xen.xend import sxp 94.10 from xen.xend.XendError import VmError 94.11 @@ -86,7 +87,7 @@ class DevController: 94.12 94.13 import xen.xend.XendDomain 94.14 xd = xen.xend.XendDomain.instance() 94.15 - backdom_name = sxp.child_value(config, 'backend') 94.16 + backdom_name = config.get('backend') 94.17 if backdom_name is None: 94.18 backdom = xen.xend.XendDomain.DOM0_ID 94.19 else: 94.20 @@ -223,7 +224,7 @@ class DevController: 94.21 configDict = self.getDeviceConfiguration(devid) 94.22 sxpr = [self.deviceClass] 94.23 for key, val in configDict.items(): 94.24 - if type(val) == type(list()): 94.25 + if isinstance(val, (types.ListType, types.TupleType)): 94.26 for v in val: 94.27 sxpr.append([key, v]) 94.28 else: 94.29 @@ -405,7 +406,7 @@ class DevController: 94.30 import xen.xend.XendDomain 94.31 xd = xen.xend.XendDomain.instance() 94.32 94.33 - backdom_name = sxp.child_value(config, 'backend') 94.34 + backdom_name = config.get('backend') 94.35 if backdom_name: 94.36 backdom = xd.domain_lookup_nr(backdom_name) 94.37 else:
95.1 --- a/tools/python/xen/xend/server/SrvDaemon.py Sat Dec 02 15:19:50 2006 -0700 95.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py Mon Dec 04 08:24:41 2006 -0700 95.3 @@ -21,6 +21,7 @@ import xen.lowlevel.xc 95.4 95.5 from xen.xend.XendLogging import log 95.6 from xen.xend import osdep 95.7 +from xen.util import mkdir 95.8 95.9 import relocate 95.10 import SrvServer 95.11 @@ -108,8 +109,7 @@ class Daemon: 95.12 # so _before_ we close stderr. 95.13 try: 95.14 parent = os.path.dirname(XEND_DEBUG_LOG) 95.15 - if not os.path.exists(parent): 95.16 - os.makedirs(parent, stat.S_IRWXU) 95.17 + mkdir.parents(parent, stat.S_IRWXU) 95.18 fd = os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND) 95.19 except Exception, exn: 95.20 print >>sys.stderr, exn
96.1 --- a/tools/python/xen/xend/server/SrvServer.py Sat Dec 02 15:19:50 2006 -0700 96.2 +++ b/tools/python/xen/xend/server/SrvServer.py Mon Dec 04 08:24:41 2006 -0700 96.3 @@ -154,7 +154,7 @@ def create(): 96.4 if api_cfg: 96.5 try: 96.6 addrs = [(str(x[0]).split(':'), 96.7 - len(x) > 1 and x[1] or XendAPI.AUTH_NONE, 96.8 + len(x) > 1 and x[1] or XendAPI.AUTH_PAM, 96.9 len(x) > 2 and x[2] and map(re.compile, x[2].split(" ")) 96.10 or None) 96.11 for x in api_cfg]
97.1 --- a/tools/python/xen/xend/server/blkif.py Sat Dec 02 15:19:50 2006 -0700 97.2 +++ b/tools/python/xen/xend/server/blkif.py Mon Dec 04 08:24:41 2006 -0700 97.3 @@ -21,7 +21,6 @@ import string 97.4 97.5 from xen.util import blkif 97.6 from xen.util import security 97.7 -from xen.xend import sxp 97.8 from xen.xend.XendError import VmError 97.9 from xen.xend.server.DevController import DevController 97.10 97.11 @@ -37,9 +36,9 @@ class BlkifController(DevController): 97.12 97.13 def getDeviceDetails(self, config): 97.14 """@see DevController.getDeviceDetails""" 97.15 - uname = sxp.child_value(config, 'uname', '') 97.16 - dev = sxp.child_value(config, 'dev', '') 97.17 - 97.18 + uname = config.get('uname', '') 97.19 + dev = config.get('dev', '') 97.20 + 97.21 if 'ioemu:' in dev: 97.22 (_, dev) = string.split(dev, ':', 1) 97.23 try: 97.24 @@ -59,17 +58,17 @@ class BlkifController(DevController): 97.25 except ValueError: 97.26 (typ, params) = ("", "") 97.27 97.28 - mode = sxp.child_value(config, 'mode', 'r') 97.29 + mode = config.get('mode', 'r') 97.30 if mode not in ('r', 'w', 'w!'): 97.31 raise VmError('Invalid mode') 97.32 97.33 - back = { 'dev' : dev, 97.34 - 'type' : typ, 97.35 - 'params' : params, 97.36 - 'mode' : mode 97.37 - } 97.38 + back = {'dev' : dev, 97.39 + 'type' : typ, 97.40 + 'params' : params, 97.41 + 'mode' : mode, 97.42 + } 97.43 97.44 - uuid = sxp.child_value(config, 'uuid') 97.45 + uuid = config.get('uuid') 97.46 if uuid: 97.47 back['uuid'] = uuid 97.48
98.1 --- a/tools/python/xen/xend/server/iopif.py Sat Dec 02 15:19:50 2006 -0700 98.2 +++ b/tools/python/xen/xend/server/iopif.py Mon Dec 04 08:24:41 2006 -0700 98.3 @@ -22,7 +22,6 @@ import types 98.4 98.5 import xen.lowlevel.xc 98.6 98.7 -from xen.xend import sxp 98.8 from xen.xend.XendError import VmError 98.9 98.10 from xen.xend.server.DevController import DevController 98.11 @@ -49,13 +48,12 @@ class IOPortsController(DevController): 98.12 def __init__(self, vm): 98.13 DevController.__init__(self, vm) 98.14 98.15 - 98.16 def getDeviceDetails(self, config): 98.17 """@see DevController.getDeviceDetails""" 98.18 98.19 def get_param(field): 98.20 try: 98.21 - val = sxp.child_value(config, field) 98.22 + val = config.get(field) 98.23 98.24 if not val: 98.25 raise VmError('ioports: Missing %s config setting' % field)
99.1 --- a/tools/python/xen/xend/server/irqif.py Sat Dec 02 15:19:50 2006 -0700 99.2 +++ b/tools/python/xen/xend/server/irqif.py Mon Dec 04 08:24:41 2006 -0700 99.3 @@ -45,7 +45,7 @@ class IRQController(DevController): 99.4 99.5 def get_param(field): 99.6 try: 99.7 - val = sxp.child_value(config, field) 99.8 + val = config.get(field) 99.9 99.10 if not val: 99.11 raise VmError('irq: Missing %s config setting' % field)
100.1 --- a/tools/python/xen/xend/server/netif.py Sat Dec 02 15:19:50 2006 -0700 100.2 +++ b/tools/python/xen/xend/server/netif.py Mon Dec 04 08:24:41 2006 -0700 100.3 @@ -24,7 +24,6 @@ import os 100.4 import random 100.5 import re 100.6 100.7 -from xen.xend import sxp 100.8 from xen.xend import XendRoot 100.9 from xen.xend.server.DevController import DevController 100.10 100.11 @@ -139,22 +138,15 @@ class NetifController(DevController): 100.12 def getDeviceDetails(self, config): 100.13 """@see DevController.getDeviceDetails""" 100.14 100.15 - def _get_config_ipaddr(config): 100.16 - val = [] 100.17 - for ipaddr in sxp.children(config, elt='ip'): 100.18 - val.append(sxp.child0(ipaddr)) 100.19 - return val 100.20 - 100.21 script = os.path.join(xroot.network_script_dir, 100.22 - sxp.child_value(config, 'script', 100.23 - xroot.get_vif_script())) 100.24 - typ = sxp.child_value(config, 'type') 100.25 - bridge = sxp.child_value(config, 'bridge') 100.26 - mac = sxp.child_value(config, 'mac') 100.27 - vifname = sxp.child_value(config, 'vifname') 100.28 - rate = sxp.child_value(config, 'rate') 100.29 - uuid = sxp.child_value(config, 'uuid') 100.30 - ipaddr = _get_config_ipaddr(config) 100.31 + config.get('script', xroot.get_vif_script())) 100.32 + typ = config.get('type') 100.33 + bridge = config.get('bridge') 100.34 + mac = config.get('mac') 100.35 + vifname = config.get('vifname') 100.36 + rate = config.get('rate') 100.37 + uuid = config.get('uuid') 100.38 + ipaddr = config.get('ip') 100.39 100.40 devid = self.allocateDeviceID() 100.41
101.1 --- a/tools/python/xen/xend/server/pciif.py Sat Dec 02 15:19:50 2006 -0700 101.2 +++ b/tools/python/xen/xend/server/pciif.py Mon Dec 04 08:24:41 2006 -0700 101.3 @@ -53,60 +53,29 @@ class PciController(DevController): 101.4 101.5 def getDeviceDetails(self, config): 101.6 """@see DevController.getDeviceDetails""" 101.7 - #log.debug('pci config='+sxp.to_string(config)) 101.8 - 101.9 - def get_param(config, field, default=None): 101.10 + def parse_hex(val): 101.11 try: 101.12 - val = sxp.child_value(config, field) 101.13 - 101.14 - if not val: 101.15 - if default==None: 101.16 - raise VmError('pci: Missing %s config setting' % field) 101.17 - else: 101.18 - return default 101.19 - 101.20 if isinstance(val, types.StringTypes): 101.21 return int(val, 16) 101.22 else: 101.23 return val 101.24 - except: 101.25 - if default==None: 101.26 - raise VmError('pci: Invalid config setting %s: %s' % 101.27 - (field, val)) 101.28 - else: 101.29 - return default 101.30 - 101.31 + except ValueError: 101.32 + return None 101.33 + 101.34 back = {} 101.35 - 101.36 - val = sxp.child_value(config, 'dev') 101.37 - if isinstance(val, (types.ListType, types.TupleType)): 101.38 - pcidevid = 0 101.39 - for dev_config in sxp.children(config, 'dev'): 101.40 - domain = get_param(dev_config, 'domain', 0) 101.41 - bus = get_param(dev_config,'bus') 101.42 - slot = get_param(dev_config,'slot') 101.43 - func = get_param(dev_config,'func') 101.44 + pcidevid = 0 101.45 + for pci_config in config.get('devs', []): 101.46 + domain = parse_hex(pci_config.get('domain', 0)) 101.47 + bus = parse_hex(pci_config.get('bus', 0)) 101.48 + slot = parse_hex(pci_config.get('slot', 0)) 101.49 + func = parse_hex(pci_config.get('func', 0)) 101.50 + self.setupDevice(domain, bus, slot, func) 101.51 + back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \ 101.52 + (domain, bus, slot, func) 101.53 + pcidevid += 1 101.54 101.55 - self.setupDevice(domain, bus, slot, func) 101.56 - 101.57 - back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \ 101.58 - (domain, bus, slot, func) 101.59 - pcidevid+=1 101.60 - 101.61 - back['num_devs']=str(pcidevid) 101.62 - 101.63 - else: 101.64 - # Xen 2.0 configuration compatibility 101.65 - domain = get_param(config, 'domain', 0) 101.66 - bus = get_param(config, 'bus') 101.67 - slot = get_param(config, 'dev') 101.68 - func = get_param(config, 'func') 101.69 - 101.70 - self.setupDevice(domain, bus, slot, func) 101.71 - 101.72 - back['dev-0']="%04x:%02x:%02x.%02x"%(domain, bus, slot, func) 101.73 - back['num_devs']=str(1) 101.74 - 101.75 + back['num_devs']=str(pcidevid) 101.76 + back['uuid'] = config.get('uuid','') 101.77 return (0, back, {}) 101.78 101.79 def getDeviceConfiguration(self, devid): 101.80 @@ -129,7 +98,8 @@ class PciController(DevController): 101.81 'slot': '0x%(slot)s' % pci_dev_info, 101.82 'func': '0x%(func)s' % pci_dev_info}) 101.83 101.84 - result['dev'] = pci_devs 101.85 + result['devs'] = pci_devs 101.86 + result['uuid'] = self.readBackend(devid, 'uuid') 101.87 return result 101.88 101.89 def configuration(self, devid): 101.90 @@ -142,7 +112,8 @@ class PciController(DevController): 101.91 sxpr = [self.deviceClass] 101.92 101.93 # remove devs 101.94 - devs = configDict.pop('dev', []) 101.95 + devs = configDict.pop('devs', []) 101.96 + 101.97 for dev in devs: 101.98 dev_sxpr = ['dev'] 101.99 for dev_item in dev.items():
102.1 --- a/tools/python/xen/xend/server/pciquirk.py Sat Dec 02 15:19:50 2006 -0700 102.2 +++ b/tools/python/xen/xend/server/pciquirk.py Mon Dec 04 08:24:41 2006 -0700 102.3 @@ -15,25 +15,24 @@ class PCIQuirk: 102.4 self.device = device 102.5 self.subvendor = subvendor 102.6 self.subdevice = subdevice 102.7 - self.domain = domain 102.8 - self.bus = bus 102.9 - self.slot = slot 102.10 - self.func = func 102.11 + self.domain = domain 102.12 + self.bus = bus 102.13 + self.slot = slot 102.14 + self.func = func 102.15 102.16 self.devid = "%04x:%04x:%04x:%04x" % (vendor, device, subvendor, subdevice) 102.17 - self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) 102.18 + self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) 102.19 + self.quirks = self.__getQuirksByID() 102.20 102.21 - self.quirks = self.__getQuirksByID( ) 102.22 - 102.23 - self.__sendQuirks( ) 102.24 - self.__sendPermDevs( ) 102.25 + self.__sendQuirks() 102.26 + self.__sendPermDevs() 102.27 102.28 def __matchPCIdev( self, list ): 102.29 ret = False 102.30 if list == None: 102.31 return False 102.32 for id in list: 102.33 - if id.startswith( self.devid[:9] ): # id's vendor and device ID match 102.34 + if id.startswith(self.devid[:9]): # id's vendor and device ID match 102.35 skey = id.split(':') 102.36 size = len(skey) 102.37 if (size == 2): # subvendor/subdevice not suplied 102.38 @@ -41,13 +40,13 @@ class PCIQuirk: 102.39 break 102.40 elif (size == 4): # check subvendor/subdevice 102.41 # check subvendor 102.42 - subven = '%04x' % self.subvendor 102.43 + subven = '%04x' % self.subvendor 102.44 if ((skey[2] != 'FFFF') and 102.45 (skey[2] != 'ffff') and 102.46 (skey[2] != subven)): 102.47 continue 102.48 # check subdevice 102.49 - subdev = '%04x' % self.subdevice 102.50 + subdev = '%04x' % self.subdevice 102.51 if ((skey[3] != 'FFFF') and 102.52 (skey[3] != 'ffff') and 102.53 (skey[3] != subdev)): 102.54 @@ -101,8 +100,8 @@ class PCIQuirk: 102.55 self.slot, self.func, quirk) ) 102.56 f.close() 102.57 except Exception, e: 102.58 - raise VmError("pci: failed to open/write/close quirks sysfs " + \ 102.59 - "node - " + str(e)) 102.60 + raise VmError("pci: failed to open/write/close quirks " + 102.61 + "sysfs node - " + str(e)) 102.62 102.63 def __devIsUnconstrained( self ): 102.64 if os.path.exists(PERMISSIVE_CONFIG_FILE): 102.65 @@ -126,20 +125,22 @@ class PCIQuirk: 102.66 102.67 devices = child_at(child(pci_perm_dev_config, 'unconstrained_dev_ids'),0) 102.68 if self.__matchPCIdev( devices ): 102.69 - log.debug("Permissive mode enabled for PCI device [%s]" % self.devid) 102.70 + log.debug("Permissive mode enabled for PCI device [%s]" % 102.71 + self.devid) 102.72 return True 102.73 - log.debug("Permissive mode NOT enabled for PCI device [%s]" % self.devid) 102.74 + log.debug("Permissive mode NOT enabled for PCI device [%s]" % 102.75 + self.devid) 102.76 return False 102.77 102.78 def __sendPermDevs(self): 102.79 if self.__devIsUnconstrained( ): 102.80 - log.debug("Unconstrained device: %04x:%02x:%02x.%1x" % (self.domain, 102.81 - self.bus, self.slot, self.func)) 102.82 + log.debug("Unconstrained device: %04x:%02x:%02x.%1x" % 102.83 + (self.domain, self.bus, self.slot, self.func)) 102.84 try: 102.85 f = file(PERMISSIVE_SYSFS_NODE ,"w") 102.86 f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus, 102.87 - self.slot, self.func) ) 102.88 + self.slot, self.func)) 102.89 f.close() 102.90 except Exception, e: 102.91 - raise VmError("pci: failed to open/write/close permissive " + \ 102.92 - "sysfs node: " + str(e)) 102.93 + raise VmError("pci: