mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
merge with xen-unstable.hg
This commit is contained in:
commit
a6e547a237
74 files changed
+1559
-455
No files matched your search
@@ -1268,6 +1268,7 @@ CONFIG_IEEE1394_RAWIO=m
|
||||
CONFIG_I2O=m
|
||||
CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
|
||||
CONFIG_I2O_EXT_ADAPTEC=y
|
||||
CONFIG_I2O_EXT_ADAPTEC_DMA64=y
|
||||
CONFIG_I2O_CONFIG=m
|
||||
CONFIG_I2O_CONFIG_OLD_IOCTL=y
|
||||
CONFIG_I2O_BUS=m
|
||||
|
||||
@@ -142,7 +142,6 @@ The following enumeration types are used:
|
||||
\hspace{0.5cm}{\tt Paused} & Paused \\
|
||||
\hspace{0.5cm}{\tt Running} & Running \\
|
||||
\hspace{0.5cm}{\tt Suspended} & Suspended \\
|
||||
\hspace{0.5cm}{\tt ShuttingDown} & Shutting Down \\
|
||||
\hspace{0.5cm}{\tt Unknown} & Some other unknown state \\
|
||||
\hline
|
||||
\end{longtable}
|
||||
@@ -1026,9 +1025,9 @@ references to objects with match names
|
||||
virtual machine (or 'guest').
|
||||
|
||||
VM booting is controlled by setting one of the two mutually exclusive
|
||||
groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual
|
||||
domain building and booting will be used; otherwise the VM will be loaded
|
||||
as an HVM domain, and booted using an emulated BIOS.
|
||||
groups: "PV", and "HVM". If HVM.boot\_policy is the empty string, then
|
||||
paravirtual domain building and booting will be used; otherwise the VM will
|
||||
be loaded as an HVM domain, and booted using an emulated BIOS.
|
||||
|
||||
When paravirtual booting is in use, the PV/bootloader field indicates the
|
||||
bootloader to use. It may be "pygrub", in which case the platform's
|
||||
@@ -1053,7 +1052,10 @@ ramdisk values will be treated as paths within the control domain. If both
|
||||
PV/bootloader and PV/kernel are empty, then the behaviour is as if
|
||||
PV/bootloader was specified as "pygrub".
|
||||
|
||||
When using HVM booting, HVM/boot specifies the order of the boot devices.}} \\
|
||||
When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the
|
||||
boot handling. Only one policy is currently defined: "BIOS order". In
|
||||
this case, HVM/boot\_params should contain one key-value pair "order" = "N"
|
||||
where N is the string that will be passed to QEMU.}} \\
|
||||
\hline
|
||||
Quals & Field & Type & Description \\
|
||||
\hline
|
||||
@@ -1089,7 +1091,8 @@ $\mathit{RW}$ & {\tt PV/kernel} & string & path to the kernel \\
|
||||
$\mathit{RW}$ & {\tt PV/ramdisk} & string & path to the initrd \\
|
||||
$\mathit{RW}$ & {\tt PV/args} & string & kernel command-line arguments \\
|
||||
$\mathit{RW}$ & {\tt PV/bootloader\_args} & string & miscellaneous arguments for the bootloader \\
|
||||
$\mathit{RW}$ & {\tt HVM/boot} & string & device boot order \\
|
||||
$\mathit{RW}$ & {\tt HVM/boot\_policy} & string & HVM boot policy \\
|
||||
$\mathit{RW}$ & {\tt HVM/boot\_params} & (string $\rightarrow$ string) Map & HVM boot params \\
|
||||
$\mathit{RW}$ & {\tt platform/std\_VGA} & bool & emulate standard VGA instead of cirrus logic \\
|
||||
$\mathit{RW}$ & {\tt platform/serial} & string & redirect serial port to pty \\
|
||||
$\mathit{RW}$ & {\tt platform/localtime} & bool & set RTC to local time \\
|
||||
@@ -3297,13 +3300,13 @@ void
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~get\_HVM\_boot}
|
||||
\subsubsection{RPC name:~get\_HVM\_boot\_policy}
|
||||
|
||||
{\bf Overview:}
|
||||
Get the HVM/boot field of the given VM.
|
||||
Get the HVM/boot\_policy field of the given VM.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} string get_HVM_boot (session_id s, VM ref self)\end{verbatim}
|
||||
\begin{verbatim} string get_HVM_boot_policy (session_id s, VM ref self)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
@@ -3329,13 +3332,13 @@ value of the field
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~set\_HVM\_boot}
|
||||
\subsubsection{RPC name:~set\_HVM\_boot\_policy}
|
||||
|
||||
{\bf Overview:}
|
||||
Set the HVM/boot field of the given VM.
|
||||
Set the HVM/boot\_policy field of the given VM.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void set_HVM_boot (session_id s, VM ref self, string value)\end{verbatim}
|
||||
\begin{verbatim} void set_HVM_boot_policy (session_id s, VM ref self, string value)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
@@ -3360,6 +3363,143 @@ void
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~get\_HVM\_boot\_params}
|
||||
|
||||
{\bf Overview:}
|
||||
Get the HVM/boot\_params field of the given VM.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} ((string -> string) Map) get_HVM_boot_params (session_id s, VM ref self)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt VM ref } & self & reference to the object \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
(string $\rightarrow$ string) Map
|
||||
}
|
||||
|
||||
|
||||
value of the field
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~set\_HVM\_boot\_params}
|
||||
|
||||
{\bf Overview:}
|
||||
Set the HVM/boot\_params field of the given VM.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void set_HVM_boot_params (session_id s, VM ref self, (string -> string) Map value)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt VM ref } & self & reference to the object \\ \hline
|
||||
|
||||
{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
void
|
||||
}
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~add\_to\_HVM\_boot\_params}
|
||||
|
||||
{\bf Overview:}
|
||||
Add the given key-value pair to the HVM/boot\_params field of the given VM.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void add_to_HVM_boot_params (session_id s, VM ref self, string key, string value)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt VM ref } & self & reference to the object \\ \hline
|
||||
|
||||
{\tt string } & key & Key to add \\ \hline
|
||||
|
||||
{\tt string } & value & Value to add \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
void
|
||||
}
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~remove\_from\_HVM\_boot\_params}
|
||||
|
||||
{\bf Overview:}
|
||||
Remove the given key and its corresponding value from the HVM/boot\_params
|
||||
field of the given VM. If the key is not in that Map, then do nothing.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} void remove_from_HVM_boot_params (session_id s, VM ref self, string key)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt VM ref } & self & reference to the object \\ \hline
|
||||
|
||||
{\tt string } & key & Key to remove \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
void
|
||||
}
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
@@ -4521,13 +4661,45 @@ void
|
||||
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~dmesg}
|
||||
|
||||
{\bf Overview:}
|
||||
Get the host xen dmesg.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} string dmesg (session_id s, host ref host)\end{verbatim}
|
||||
|
||||
|
||||
\noindent{\bf Arguments:}
|
||||
|
||||
|
||||
\vspace{0.3cm}
|
||||
\begin{tabular}{|c|c|p{7cm}|}
|
||||
\hline
|
||||
{\bf type} & {\bf name} & {\bf description} \\ \hline
|
||||
{\tt host ref } & host & The Host to query \\ \hline
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\vspace{0.3cm}
|
||||
|
||||
\noindent {\bf Return Type:}
|
||||
{\tt
|
||||
string
|
||||
}
|
||||
|
||||
|
||||
dmesg string
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\vspace{0.3cm}
|
||||
\subsubsection{RPC name:~get\_all}
|
||||
|
||||
{\bf Overview:}
|
||||
Return a list of all the hosts known to the system
|
||||
Return a list of all the hosts known to the system.
|
||||
|
||||
\noindent {\bf Signature:}
|
||||
\begin{verbatim} ((host ref) Set) get_all (session_id s)\end{verbatim}
|
||||
@@ -11758,6 +11930,17 @@ The handle parameter echoes the bad value given.
|
||||
\begin{verbatim}TASK_HANDLE_INVALID(handle)\end{verbatim}
|
||||
\begin{center}\rule{10em}{0.1pt}\end{center}
|
||||
|
||||
\subsubsection{VALUE\_NOT\_SUPPORTED}
|
||||
|
||||
You attempted to set a value that is not supported by this implementation.
|
||||
The fully-qualified field name and the value that you tried to set are
|
||||
returned. Also returned is a developer-only diagnostic reason.
|
||||
|
||||
\vspace{0.3cm}
|
||||
{\bf Signature:}
|
||||
\begin{verbatim}VALUE_NOT_SUPPORTED(field, value, reason)\end{verbatim}
|
||||
\begin{center}\rule{10em}{0.1pt}\end{center}
|
||||
|
||||
\subsubsection{VBD\_HANDLE\_INVALID}
|
||||
|
||||
You gave an invalid VBD handle. The VBD may have recently been deleted.
|
||||
|
||||
@@ -69,7 +69,7 @@ CS = 0x2C
|
||||
popl %ds; \
|
||||
popl %es; \
|
||||
addl $4,%esp; \
|
||||
iret; \
|
||||
iret;
|
||||
|
||||
ENTRY(divide_error)
|
||||
pushl $0 # no error code
|
||||
@@ -101,10 +101,9 @@ do_exception:
|
||||
jmp ret_from_exception
|
||||
|
||||
ret_from_exception:
|
||||
movb CS(%esp),%cl
|
||||
test $2,%cl # slow return to ring 2 or 3
|
||||
jne safesti
|
||||
RESTORE_ALL
|
||||
movb CS(%esp),%cl
|
||||
addl $8,%esp
|
||||
RESTORE_ALL
|
||||
|
||||
# A note on the "critical region" in our callback handler.
|
||||
# We want to avoid stacking callback handlers due to events occurring
|
||||
|
||||
@@ -178,6 +178,7 @@ static void release_xenbus_id(int id)
|
||||
BUG_ON(!req_info[id].in_use);
|
||||
spin_lock(&req_lock);
|
||||
nr_live_reqs--;
|
||||
req_info[id].in_use = 0;
|
||||
if (nr_live_reqs == NR_REQS - 1)
|
||||
wake_up(&req_wq);
|
||||
spin_unlock(&req_lock);
|
||||
@@ -212,6 +213,7 @@ static int allocate_xenbus_id(void)
|
||||
probe = o_probe + 1;
|
||||
spin_unlock(&req_lock);
|
||||
init_waitqueue_head(&req_info[o_probe].waitq);
|
||||
|
||||
return o_probe;
|
||||
}
|
||||
|
||||
|
||||
@@ -1935,8 +1935,6 @@ static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
|
||||
np = netdev_priv(netdev);
|
||||
np->xbdev = dev;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
spin_lock_init(&np->tx_lock);
|
||||
spin_lock_init(&np->rx_lock);
|
||||
|
||||
@@ -1991,6 +1989,9 @@ static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
|
||||
SET_NETDEV_DEV(netdev, &dev->dev);
|
||||
|
||||
np->netdev = netdev;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
|
||||
return netdev;
|
||||
|
||||
exit_free_tx:
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
#define DPRINTK(fmt, args...) \
|
||||
pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
|
||||
|
||||
char *xenbus_strstate(enum xenbus_state state)
|
||||
const char *xenbus_strstate(enum xenbus_state state)
|
||||
{
|
||||
static char *name[] = {
|
||||
static const char *const name[] = {
|
||||
[ XenbusStateUnknown ] = "Unknown",
|
||||
[ XenbusStateInitialising ] = "Initialising",
|
||||
[ XenbusStateInitWait ] = "InitWait",
|
||||
@@ -55,6 +55,7 @@ char *xenbus_strstate(enum xenbus_state state)
|
||||
};
|
||||
return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xenbus_strstate);
|
||||
|
||||
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
|
||||
struct xenbus_watch *watch,
|
||||
|
||||
@@ -295,7 +295,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
|
||||
|
||||
int __init xenbus_dev_init(void);
|
||||
|
||||
char *xenbus_strstate(enum xenbus_state state);
|
||||
const char *xenbus_strstate(enum xenbus_state state);
|
||||
int xenbus_dev_is_online(struct xenbus_device *dev);
|
||||
int xenbus_frontend_closed(struct xenbus_device *dev);
|
||||
|
||||
|
||||
@@ -363,9 +363,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/oprofile/oprof.c ./drivers/oprofile/opro
|
||||
+ if (!oprofile_ops.set_active)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ down(&start_sem);
|
||||
+ mutex_lock(&start_mutex);
|
||||
+ err = oprofile_ops.set_active(active_domains, adomains);
|
||||
+ up(&start_sem);
|
||||
+ mutex_unlock(&start_mutex);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
@@ -376,9 +376,9 @@ diff -pruN ../orig-linux-2.6.18/drivers/oprofile/oprof.c ./drivers/oprofile/opro
|
||||
+ if (!oprofile_ops.set_passive)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ down(&start_sem);
|
||||
+ mutex_lock(&start_mutex);
|
||||
+ err = oprofile_ops.set_passive(passive_domains, pdomains);
|
||||
+ up(&start_sem);
|
||||
+ mutex_unlock(&start_mutex);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
|
||||
+1
-1
@@ -56,6 +56,6 @@ mk-symlinks-xen:
|
||||
( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/Makefile . )
|
||||
( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/reference.size . )
|
||||
( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/*.py . )
|
||||
make -C xen/foreign
|
||||
$(MAKE) -C xen/foreign
|
||||
|
||||
mk-symlinks: mk-symlinks-xen mk-symlinks-$(XEN_OS)
|
||||
+18
-21
@@ -144,7 +144,7 @@ static int x86_shadow(int xc, domid_t domid)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int arch_setup_early(struct xc_dom_image *dom)
|
||||
static int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@@ -157,13 +157,13 @@ static int arch_setup_early(struct xc_dom_image *dom)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int arch_setup_middle(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootearly(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_setup_late(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootlate(struct xc_dom_image *dom)
|
||||
{
|
||||
static const struct {
|
||||
char *guest;
|
||||
@@ -263,13 +263,13 @@ static int arch_setup_late(struct xc_dom_image *dom)
|
||||
|
||||
#elif defined(__ia64__)
|
||||
|
||||
static int arch_setup_early(struct xc_dom_image *dom)
|
||||
static int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_setup_middle(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootearly(struct xc_dom_image *dom)
|
||||
{
|
||||
DECLARE_DOMCTL;
|
||||
int rc;
|
||||
@@ -281,10 +281,6 @@ static int arch_setup_middle(struct xc_dom_image *dom)
|
||||
domctl.domain = dom->guest_domid;
|
||||
domctl.u.arch_setup.flags = 0;
|
||||
|
||||
/* dom->start_info_pfn should be initialized by alloc_magic_pages().
|
||||
* However it is called later. So we initialize here.
|
||||
*/
|
||||
dom->start_info_pfn = dom->total_pages - 3;
|
||||
domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
|
||||
+ sizeof(start_info_t);
|
||||
/* 3 = start info page, xenstore page and console page */
|
||||
@@ -293,7 +289,7 @@ static int arch_setup_middle(struct xc_dom_image *dom)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int arch_setup_late(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootlate(struct xc_dom_image *dom)
|
||||
{
|
||||
unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
shared_info_t *shared_info;
|
||||
@@ -317,19 +313,19 @@ static int arch_setup_late(struct xc_dom_image *dom)
|
||||
|
||||
#elif defined(__powerpc64__)
|
||||
|
||||
static int arch_setup_early(struct xc_dom_image *dom)
|
||||
static int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_setup_middle(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootearly(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_setup_late(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootlate(struct xc_dom_image *dom)
|
||||
{
|
||||
start_info_t *si =
|
||||
xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
|
||||
@@ -355,19 +351,19 @@ static int arch_setup_late(struct xc_dom_image *dom)
|
||||
|
||||
#else
|
||||
|
||||
static int arch_setup_early(struct xc_dom_image *dom)
|
||||
static int arch_setup_meminit(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_setup_middle(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootearly(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_setup_late(struct xc_dom_image *dom)
|
||||
static int arch_setup_bootlate(struct xc_dom_image *dom)
|
||||
{
|
||||
xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
|
||||
return 0;
|
||||
@@ -423,7 +419,7 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom)
|
||||
|
||||
xc_dom_printf("%s: called\n", __FUNCTION__);
|
||||
|
||||
if (0 != (rc = arch_setup_early(dom)))
|
||||
if (0 != (rc = arch_setup_meminit(dom)))
|
||||
return rc;
|
||||
|
||||
/* allocate guest memory */
|
||||
@@ -438,9 +434,6 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (0 != (rc = arch_setup_middle(dom)))
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -497,6 +490,10 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
|
||||
|
||||
xc_dom_printf("%s: called\n", __FUNCTION__);
|
||||
|
||||
/* misc ia64 stuff*/
|
||||
if (0 != (rc = arch_setup_bootearly(dom)))
|
||||
return rc;
|
||||
|
||||
/* collect some info */
|
||||
domctl.cmd = XEN_DOMCTL_getdomaininfo;
|
||||
domctl.domain = dom->guest_domid;
|
||||
@@ -542,7 +539,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
|
||||
xc_dom_log_memory_footprint(dom);
|
||||
|
||||
/* misc x86 stuff */
|
||||
if (0 != (rc = arch_setup_late(dom)))
|
||||
if (0 != (rc = arch_setup_bootlate(dom)))
|
||||
return rc;
|
||||
|
||||
/* let the vm run */
|
||||
|
||||
@@ -717,6 +717,9 @@ int xc_dom_build_image(struct xc_dom_image *dom)
|
||||
}
|
||||
page_size = XC_DOM_PAGE_SIZE(dom);
|
||||
|
||||
/* 4MB align virtual base address */
|
||||
dom->parms.virt_base &= ~(((uint64_t)1<<22)-1);
|
||||
|
||||
/* load kernel */
|
||||
if (0 != xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel",
|
||||
dom->kernel_seg.vstart,
|
||||
|
||||
@@ -26,11 +26,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
|
||||
/* allocate special pages */
|
||||
dom->console_pfn = dom->total_pages -1;
|
||||
dom->xenstore_pfn = dom->total_pages -2;
|
||||
|
||||
/*
|
||||
* this is initialized by arch_setup_middle().
|
||||
* dom->start_info_pfn = dom->total_pages -3;
|
||||
*/
|
||||
dom->start_info_pfn = dom->total_pages -3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,11 +66,12 @@ static int count_pgtables(struct xc_dom_image *dom, int pae,
|
||||
|
||||
extra_pages = dom->alloc_bootstack ? 1 : 0;
|
||||
extra_pages += dom->extra_pages;
|
||||
extra_pages += 128; /* 512kB padding */
|
||||
pages = extra_pages;
|
||||
for (;;)
|
||||
{
|
||||
try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86,
|
||||
bits_to_mask(l1_bits));
|
||||
bits_to_mask(22)); /* 4MB alignment */
|
||||
dom->pg_l4 =
|
||||
nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits);
|
||||
dom->pg_l3 =
|
||||
@@ -313,6 +314,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
|
||||
if (xc_dom_feature_translated(dom))
|
||||
dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info");
|
||||
dom->alloc_bootstack = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+20
-16
@@ -241,45 +241,49 @@ int xc_domain_getinfolist(int xc_handle,
|
||||
/* get info from hvm guest for save */
|
||||
int xc_domain_hvm_getcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
hvm_domain_context_t *hvm_ctxt)
|
||||
uint8_t *ctxt_buf,
|
||||
uint32_t size)
|
||||
{
|
||||
int rc;
|
||||
int ret;
|
||||
DECLARE_DOMCTL;
|
||||
|
||||
domctl.cmd = XEN_DOMCTL_gethvmcontext;
|
||||
domctl.domain = (domid_t)domid;
|
||||
set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
|
||||
domctl.u.hvmcontext.size = size;
|
||||
set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
|
||||
|
||||
if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
|
||||
return rc;
|
||||
if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
|
||||
return ret;
|
||||
|
||||
rc = do_domctl(xc_handle, &domctl);
|
||||
ret = do_domctl(xc_handle, &domctl);
|
||||
|
||||
safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
|
||||
unlock_pages(ctxt_buf, size);
|
||||
|
||||
return rc;
|
||||
return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
|
||||
}
|
||||
|
||||
/* set info to hvm guest for restore */
|
||||
int xc_domain_hvm_setcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
hvm_domain_context_t *hvm_ctxt)
|
||||
uint8_t *ctxt_buf,
|
||||
uint32_t size)
|
||||
{
|
||||
int rc;
|
||||
int ret;
|
||||
DECLARE_DOMCTL;
|
||||
|
||||
domctl.cmd = XEN_DOMCTL_sethvmcontext;
|
||||
domctl.domain = domid;
|
||||
set_xen_guest_handle(domctl.u.hvmcontext.ctxt, hvm_ctxt);
|
||||
domctl.u.hvmcontext.size = size;
|
||||
set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
|
||||
|
||||
if ( (rc = mlock(hvm_ctxt, sizeof(*hvm_ctxt))) != 0 )
|
||||
return rc;
|
||||
if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
|
||||
return ret;
|
||||
|
||||
rc = do_domctl(xc_handle, &domctl);
|
||||
ret = do_domctl(xc_handle, &domctl);
|
||||
|
||||
safe_munlock(hvm_ctxt, sizeof(*hvm_ctxt));
|
||||
unlock_pages(ctxt_buf, size);
|
||||
|
||||
return rc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xc_vcpu_getcontext(int xc_handle,
|
||||
|
||||
@@ -87,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io_fd,
|
||||
xc_dominfo_t info;
|
||||
unsigned int rc = 1, n, i;
|
||||
uint32_t rec_len, nr_vcpus;
|
||||
hvm_domain_context_t hvm_ctxt;
|
||||
uint8_t *hvm_buf = NULL;
|
||||
unsigned long long v_end, memsize;
|
||||
unsigned long shared_page_nr;
|
||||
|
||||
@@ -128,8 +128,7 @@ int xc_hvm_restore(int xc_handle, int io_fd,
|
||||
}
|
||||
|
||||
|
||||
p2m = malloc(max_pfn * sizeof(xen_pfn_t));
|
||||
|
||||
p2m = malloc(max_pfn * sizeof(xen_pfn_t));
|
||||
if (p2m == NULL) {
|
||||
ERROR("memory alloc failed");
|
||||
errno = ENOMEM;
|
||||
@@ -297,18 +296,21 @@ int xc_hvm_restore(int xc_handle, int io_fd,
|
||||
ERROR("error read hvm context size!\n");
|
||||
goto out;
|
||||
}
|
||||
if (rec_len != sizeof(hvm_ctxt)) {
|
||||
ERROR("hvm context size dismatch!\n");
|
||||
|
||||
hvm_buf = malloc(rec_len);
|
||||
if (hvm_buf == NULL) {
|
||||
ERROR("memory alloc for hvm context buffer failed");
|
||||
errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!read_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt))) {
|
||||
ERROR("error read hvm context!\n");
|
||||
if (!read_exact(io_fd, hvm_buf, rec_len)) {
|
||||
ERROR("error read hvm buffer!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, &hvm_ctxt))) {
|
||||
ERROR("error set hvm context!\n");
|
||||
if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) {
|
||||
ERROR("error set hvm buffer!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -361,6 +363,7 @@ int xc_hvm_restore(int xc_handle, int io_fd,
|
||||
if ( (rc != 0) && (dom != 0) )
|
||||
xc_domain_destroy(xc_handle, dom);
|
||||
free(p2m);
|
||||
free(hvm_buf);
|
||||
|
||||
DPRINTF("Restore exit with rc=%d\n", rc);
|
||||
|
||||
|
||||
+20
-20
@@ -32,6 +32,12 @@
|
||||
#include "xg_private.h"
|
||||
#include "xg_save_restore.h"
|
||||
|
||||
/*
|
||||
* Size of a buffer big enough to take the HVM state of a domain.
|
||||
* Ought to calculate this a bit more carefully, or maybe ask Xen.
|
||||
*/
|
||||
#define HVM_CTXT_SIZE 8192
|
||||
|
||||
/*
|
||||
** Default values for important tuning parameters. Can override by passing
|
||||
** non-zero replacement values to xc_hvm_save().
|
||||
@@ -279,8 +285,8 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
unsigned long *pfn_type = NULL;
|
||||
unsigned long *pfn_batch = NULL;
|
||||
|
||||
/* A copy of hvm domain context */
|
||||
hvm_domain_context_t hvm_ctxt;
|
||||
/* A copy of hvm domain context buffer*/
|
||||
uint8_t *hvm_buf = NULL;
|
||||
|
||||
/* Live mapping of shared info structure */
|
||||
shared_info_t *live_shinfo = NULL;
|
||||
@@ -423,8 +429,12 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
to_send = malloc(BITMAP_SIZE);
|
||||
to_skip = malloc(BITMAP_SIZE);
|
||||
|
||||
if (!to_send ||!to_skip) {
|
||||
ERROR("Couldn't allocate to_send array");
|
||||
page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn);
|
||||
|
||||
hvm_buf = malloc(HVM_CTXT_SIZE);
|
||||
|
||||
if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) {
|
||||
ERROR("Couldn't allocate memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -444,11 +454,6 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
|
||||
|
||||
/* get all the HVM domain pfns */
|
||||
if ( (page_array = (unsigned long *) malloc (sizeof(unsigned long) * max_pfn)) == NULL) {
|
||||
ERROR("HVM:malloc fail!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for ( i = 0; i < max_pfn; i++)
|
||||
page_array[i] = i;
|
||||
|
||||
@@ -655,24 +660,18 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* save hvm hypervisor state including pic/pit/shpage */
|
||||
if (mlock(&hvm_ctxt, sizeof(hvm_ctxt))) {
|
||||
ERROR("Unable to mlock ctxt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (xc_domain_hvm_getcontext(xc_handle, dom, &hvm_ctxt)){
|
||||
ERROR("HVM:Could not get hvm context");
|
||||
if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf,
|
||||
HVM_CTXT_SIZE)) == -1) {
|
||||
ERROR("HVM:Could not get hvm buffer");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rec_size = sizeof(hvm_ctxt);
|
||||
if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) {
|
||||
ERROR("error write hvm ctxt size");
|
||||
ERROR("error write hvm buffer size");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( !write_exact(io_fd, &hvm_ctxt, sizeof(hvm_ctxt)) ) {
|
||||
if ( !write_exact(io_fd, hvm_buf, rec_size) ) {
|
||||
ERROR("write HVM info failed!\n");
|
||||
}
|
||||
|
||||
@@ -722,6 +721,7 @@ int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
}
|
||||
}
|
||||
|
||||
free(hvm_buf);
|
||||
free(page_array);
|
||||
|
||||
free(pfn_type);
|
||||
|
||||
@@ -536,8 +536,6 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn,
|
||||
if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) {
|
||||
/* This will happen if the type info is stale which
|
||||
is quite feasible under live migration */
|
||||
DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
|
||||
type, i, (unsigned long long)pte, mfn);
|
||||
pfn = 0; /* zap it - we'll retransmit this page later */
|
||||
race = 1; /* inform the caller of race; fatal if !live */
|
||||
} else
|
||||
|
||||
@@ -328,13 +328,15 @@ int xc_domain_getinfolist(int xc_handle,
|
||||
* This function returns information about the context of a hvm domain
|
||||
* @parm xc_handle a handle to an open hypervisor interface
|
||||
* @parm domid the domain to get information from
|
||||
* @parm hvm_ctxt a pointer to a structure to store the execution context of the
|
||||
* hvm domain
|
||||
* @parm ctxt_buf a pointer to a structure to store the execution context of
|
||||
* the hvm domain
|
||||
* @parm size the size of ctxt_buf in bytes
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int xc_domain_hvm_getcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
hvm_domain_context_t *hvm_ctxt);
|
||||
uint8_t *ctxt_buf,
|
||||
uint32_t size);
|
||||
|
||||
/**
|
||||
* This function will set the context for hvm domain
|
||||
@@ -342,11 +344,13 @@ int xc_domain_hvm_getcontext(int xc_handle,
|
||||
* @parm xc_handle a handle to an open hypervisor interface
|
||||
* @parm domid the domain to set the hvm domain context for
|
||||
* @parm hvm_ctxt pointer to the the hvm context with the values to set
|
||||
* @parm size the size of hvm_ctxt in bytes
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int xc_domain_hvm_setcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
hvm_domain_context_t *hvm_ctxt);
|
||||
uint8_t *hvm_ctxt,
|
||||
uint32_t size);
|
||||
|
||||
/**
|
||||
* This function returns information about the execution context of a
|
||||
|
||||
@@ -51,6 +51,9 @@ libxenapi.a: $(LIBXENAPI_OBJS)
|
||||
test/test_bindings: test/test_bindings.o libxenapi.so
|
||||
$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
|
||||
|
||||
test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
|
||||
$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
|
||||
|
||||
|
||||
.PHONY: install
|
||||
install: all
|
||||
|
||||
@@ -393,6 +393,13 @@ extern bool
|
||||
xen_host_reboot(xen_session *session, xen_host host);
|
||||
|
||||
|
||||
/**
|
||||
* Get the host xen dmesg.
|
||||
*/
|
||||
extern bool
|
||||
xen_host_dmesg(xen_session *session, char **result, xen_host host);
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of all the hosts known to the system.
|
||||
*/
|
||||
|
||||
@@ -74,6 +74,7 @@ typedef struct xen_vdi_record
|
||||
int64_t virtual_size;
|
||||
int64_t physical_utilisation;
|
||||
int64_t sector_size;
|
||||
char *location;
|
||||
enum xen_vdi_type type;
|
||||
bool sharable;
|
||||
bool read_only;
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
* A virtual machine (or 'guest').
|
||||
*
|
||||
* VM booting is controlled by setting one of the two mutually exclusive
|
||||
* groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual
|
||||
* domain building and booting will be used; otherwise the VM will be loaded
|
||||
* as an HVM domain, and booted using an emulated BIOS.
|
||||
* groups: "PV", and "HVM". If HVM.boot_policy is the empty string, then
|
||||
* paravirtual domain building and booting will be used; otherwise the VM will
|
||||
* be loaded as an HVM domain, and booted using an emulated BIOS.
|
||||
*
|
||||
* When paravirtual booting is in use, the PV/bootloader field indicates the
|
||||
* bootloader to use. It may be "pygrub", in which case the platform's
|
||||
@@ -69,7 +69,10 @@
|
||||
* PV/bootloader and PV/kernel are empty, then the behaviour is as if
|
||||
* PV/bootloader was specified as "pygrub".
|
||||
*
|
||||
* When using HVM booting, HVM/boot specifies the order of the boot devices.
|
||||
* When using HVM booting, HVM/boot_policy and HVM/boot_params specify the
|
||||
* boot handling. Only one policy is currently defined: "BIOS order". In
|
||||
* this case, HVM/boot_params should contain one key-value pair "order" = "N"
|
||||
* where N is the string that will be passed to QEMU..
|
||||
*/
|
||||
|
||||
|
||||
@@ -136,7 +139,8 @@ typedef struct xen_vm_record
|
||||
char *pv_ramdisk;
|
||||
char *pv_args;
|
||||
char *pv_bootloader_args;
|
||||
char *hvm_boot;
|
||||
char *hvm_boot_policy;
|
||||
xen_string_string_map *hvm_boot_params;
|
||||
bool platform_std_vga;
|
||||
char *platform_serial;
|
||||
bool platform_localtime;
|
||||
@@ -490,10 +494,17 @@ xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
|
||||
|
||||
|
||||
/**
|
||||
* Get the HVM/boot field of the given VM.
|
||||
* Get the HVM/boot_policy field of the given VM.
|
||||
*/
|
||||
extern bool
|
||||
xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm);
|
||||
xen_vm_get_hvm_boot_policy(xen_session *session, char **result, xen_vm vm);
|
||||
|
||||
|
||||
/**
|
||||
* Get the HVM/boot_params field of the given VM.
|
||||
*/
|
||||
extern bool
|
||||
xen_vm_get_hvm_boot_params(xen_session *session, xen_string_string_map **result, xen_vm vm);
|
||||
|
||||
|
||||
/**
|
||||
@@ -731,10 +742,34 @@ xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_
|
||||
|
||||
|
||||
/**
|
||||
* Set the HVM/boot field of the given VM.
|
||||
* Set the HVM/boot_policy field of the given VM.
|
||||
*/
|
||||
extern bool
|
||||
xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
|
||||
xen_vm_set_hvm_boot_policy(xen_session *session, xen_vm vm, char *boot_policy);
|
||||
|
||||
|
||||
/**
|
||||
* Set the HVM/boot_params field of the given VM.
|
||||
*/
|
||||
extern bool
|
||||
xen_vm_set_hvm_boot_params(xen_session *session, xen_vm vm, xen_string_string_map *boot_params);
|
||||
|
||||
|
||||
/**
|
||||
* Add the given key-value pair to the HVM/boot_params field of the
|
||||
* given VM.
|
||||
*/
|
||||
extern bool
|
||||
xen_vm_add_to_hvm_boot_params(xen_session *session, xen_vm vm, char *key, char *value);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given key and its corresponding value from the
|
||||
* HVM/boot_params field of the given VM. If the key is not in that Map, then
|
||||
* do nothing.
|
||||
*/
|
||||
extern bool
|
||||
xen_vm_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,11 +45,6 @@ enum xen_vm_power_state
|
||||
*/
|
||||
XEN_VM_POWER_STATE_SUSPENDED,
|
||||
|
||||
/**
|
||||
* Shutting Down
|
||||
*/
|
||||
XEN_VM_POWER_STATE_SHUTTINGDOWN,
|
||||
|
||||
/**
|
||||
* Some other unknown state
|
||||
*/
|
||||
|
||||
+106
-38
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 XenSource, Inc.
|
||||
* Copyright (c) 2006-2007 XenSource, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -86,6 +86,8 @@ static xmlNode *
|
||||
add_param_struct(xmlNode *);
|
||||
static xmlNode *
|
||||
add_struct_array(xmlNode *, const char *);
|
||||
static xmlNode *
|
||||
add_nested_struct(xmlNode *, const char *);
|
||||
static void
|
||||
add_struct_member(xmlNode *, const char *, const char *, const char *);
|
||||
static void
|
||||
@@ -107,6 +109,9 @@ parse_structmap_value(xen_session *, xmlNode *, const abstract_type *,
|
||||
|
||||
static size_t size_of_member(const abstract_type *);
|
||||
|
||||
static const char *
|
||||
get_val_as_string(const struct abstract_type *, void *, char *);
|
||||
|
||||
|
||||
void
|
||||
xen_init(void)
|
||||
@@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_type *type, void *value,
|
||||
switch (type->typename)
|
||||
{
|
||||
case REF:
|
||||
{
|
||||
arbitrary_record_opt *val = *(arbitrary_record_opt **)value;
|
||||
if (val != NULL)
|
||||
{
|
||||
if (val->is_record)
|
||||
{
|
||||
adder(node, key, "string", val->u.record->handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
adder(node, key, "string", val->u.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
{
|
||||
char *val = *(char **)value;
|
||||
if (val != NULL)
|
||||
{
|
||||
adder(node, key, "string", val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case INT:
|
||||
case ENUM:
|
||||
{
|
||||
int64_t val = *(int64_t *)value;
|
||||
snprintf(buf, sizeof(buf), "%"PRId64, val);
|
||||
adder(node, key, "string", buf);
|
||||
const char *val_as_string = get_val_as_string(type, value, buf);
|
||||
adder(node, key, "string", val_as_string);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1223,13 +1203,6 @@ add_struct_value(const struct abstract_type *type, void *value,
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM:
|
||||
{
|
||||
int val = *(int *)value;
|
||||
adder(node, key, "string", type->enum_marshaller(val));
|
||||
}
|
||||
break;
|
||||
|
||||
case SET:
|
||||
{
|
||||
const struct abstract_type *member_type = type->child;
|
||||
@@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_type *type, void *value,
|
||||
break;
|
||||
|
||||
case STRUCT:
|
||||
case MAP:
|
||||
{
|
||||
assert(false);
|
||||
/* XXX Nested structures aren't supported yet, but
|
||||
fortunately we don't need them, because we don't have
|
||||
any "deep create" calls. This will need to be
|
||||
fixed. We don't need maps either. */
|
||||
fixed. */
|
||||
}
|
||||
break;
|
||||
|
||||
case MAP:
|
||||
{
|
||||
size_t member_size = type->struct_size;
|
||||
const struct abstract_type *l_type = type->members[0].type;
|
||||
const struct abstract_type *r_type = type->members[1].type;
|
||||
int l_offset = type->members[0].offset;
|
||||
int r_offset = type->members[1].offset;
|
||||
|
||||
arbitrary_map *map_val = *(arbitrary_map **)value;
|
||||
|
||||
if (map_val != NULL)
|
||||
{
|
||||
xmlNode *struct_node = add_nested_struct(node, key);
|
||||
|
||||
for (size_t i = 0; i < map_val->size; i++)
|
||||
{
|
||||
void *contents = (void *)map_val->contents;
|
||||
void *l_value = contents + (i * member_size) + l_offset;
|
||||
void *r_value = contents + (i * member_size) + r_offset;
|
||||
|
||||
const char *l_value_as_string =
|
||||
get_val_as_string(l_type, l_value, buf);
|
||||
|
||||
add_struct_value(r_type, r_value, add_struct_member,
|
||||
l_value_as_string, struct_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
get_val_as_string(const struct abstract_type *type, void *value, char *buf)
|
||||
{
|
||||
switch (type->typename)
|
||||
{
|
||||
case REF:
|
||||
{
|
||||
arbitrary_record_opt *val = *(arbitrary_record_opt **)value;
|
||||
if (val != NULL)
|
||||
{
|
||||
if (val->is_record)
|
||||
{
|
||||
return val->u.record->handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val->u.handle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
{
|
||||
return *(char **)value;
|
||||
}
|
||||
break;
|
||||
|
||||
case INT:
|
||||
{
|
||||
int64_t val = *(int64_t *)value;
|
||||
snprintf(buf, sizeof(buf), "%"PRId64, val);
|
||||
return buf;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM:
|
||||
{
|
||||
int val = *(int *)value;
|
||||
return type->enum_marshaller(val);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1331,7 +1387,19 @@ add_struct_array(xmlNode *struct_node, const char *name)
|
||||
xmlNode *array_node = add_container(value_node, "array");
|
||||
|
||||
return add_container(array_node, "data");
|
||||
}
|
||||
|
||||
|
||||
static xmlNode *
|
||||
add_nested_struct(xmlNode *struct_node, const char *name)
|
||||
{
|
||||
xmlNode *member_node = add_container(struct_node, "member");
|
||||
|
||||
xmlNewChild(member_node, NULL, BAD_CAST "name", BAD_CAST name);
|
||||
|
||||
xmlNode *value_node = add_container(member_node, "value");
|
||||
|
||||
return add_container(value_node, "struct");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -631,6 +631,23 @@ xen_host_reboot(xen_session *session, xen_host host)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_host_dmesg(xen_session *session, char **result, xen_host host)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = host }
|
||||
};
|
||||
|
||||
abstract_type result_type = abstract_type_string;
|
||||
|
||||
*result = NULL;
|
||||
XEN_CALL_("host.dmesg");
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_host_get_all(xen_session *session, struct xen_host_set **result)
|
||||
{
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
xen_int_float_map *
|
||||
xen_int_float_map_alloc(size_t size)
|
||||
{
|
||||
return calloc(1, sizeof(xen_int_float_map) +
|
||||
size * sizeof(struct xen_int_float_map_contents));
|
||||
xen_int_float_map *result = calloc(1, sizeof(xen_int_float_map) +
|
||||
size * sizeof(struct xen_int_float_map_contents));
|
||||
result->size = size;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
xen_string_string_map *
|
||||
xen_string_string_map_alloc(size_t size)
|
||||
{
|
||||
return calloc(1, sizeof(xen_string_string_map) +
|
||||
size * sizeof(struct xen_string_string_map_contents));
|
||||
xen_string_string_map *result = calloc(1, sizeof(xen_string_string_map) +
|
||||
size * sizeof(struct xen_string_string_map_contents));
|
||||
result->size = size;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ static const struct_member xen_vdi_record_struct_members[] =
|
||||
{ .key = "sector_size",
|
||||
.type = &abstract_type_int,
|
||||
.offset = offsetof(xen_vdi_record, sector_size) },
|
||||
{ .key = "location",
|
||||
.type = &abstract_type_string,
|
||||
.offset = offsetof(xen_vdi_record, location) },
|
||||
{ .key = "type",
|
||||
.type = &xen_vdi_type_abstract_type_,
|
||||
.offset = offsetof(xen_vdi_record, type) },
|
||||
|
||||
@@ -145,9 +145,12 @@ static const struct_member xen_vm_record_struct_members[] =
|
||||
{ .key = "PV_bootloader_args",
|
||||
.type = &abstract_type_string,
|
||||
.offset = offsetof(xen_vm_record, pv_bootloader_args) },
|
||||
{ .key = "HVM_boot",
|
||||
{ .key = "HVM_boot_policy",
|
||||
.type = &abstract_type_string,
|
||||
.offset = offsetof(xen_vm_record, hvm_boot) },
|
||||
.offset = offsetof(xen_vm_record, hvm_boot_policy) },
|
||||
{ .key = "HVM_boot_params",
|
||||
.type = &abstract_type_string_string_map,
|
||||
.offset = offsetof(xen_vm_record, hvm_boot_params) },
|
||||
{ .key = "platform_std_VGA",
|
||||
.type = &abstract_type_bool,
|
||||
.offset = offsetof(xen_vm_record, platform_std_vga) },
|
||||
@@ -216,7 +219,8 @@ xen_vm_record_free(xen_vm_record *record)
|
||||
free(record->pv_ramdisk);
|
||||
free(record->pv_args);
|
||||
free(record->pv_bootloader_args);
|
||||
free(record->hvm_boot);
|
||||
free(record->hvm_boot_policy);
|
||||
xen_string_string_map_free(record->hvm_boot_params);
|
||||
free(record->platform_serial);
|
||||
free(record->pci_bus);
|
||||
xen_string_string_map_free(record->tools_version);
|
||||
@@ -824,7 +828,7 @@ xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
|
||||
|
||||
|
||||
bool
|
||||
xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
|
||||
xen_vm_get_hvm_boot_policy(xen_session *session, char **result, xen_vm vm)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
@@ -835,7 +839,24 @@ xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
|
||||
abstract_type result_type = abstract_type_string;
|
||||
|
||||
*result = NULL;
|
||||
XEN_CALL_("VM.get_HVM_boot");
|
||||
XEN_CALL_("VM.get_HVM_boot_policy");
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_vm_get_hvm_boot_params(xen_session *session, xen_string_string_map **result, xen_vm vm)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = vm }
|
||||
};
|
||||
|
||||
abstract_type result_type = abstract_type_string_string_map;
|
||||
|
||||
*result = NULL;
|
||||
XEN_CALL_("VM.get_HVM_boot_params");
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
@@ -1376,17 +1397,67 @@ xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_
|
||||
|
||||
|
||||
bool
|
||||
xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
|
||||
xen_vm_set_hvm_boot_policy(xen_session *session, xen_vm vm, char *boot_policy)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = vm },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = boot }
|
||||
.u.string_val = boot_policy }
|
||||
};
|
||||
|
||||
xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL);
|
||||
xen_call_(session, "VM.set_HVM_boot_policy", param_values, 2, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_vm_set_hvm_boot_params(xen_session *session, xen_vm vm, xen_string_string_map *boot_params)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = vm },
|
||||
{ .type = &abstract_type_string_string_map,
|
||||
.u.set_val = (arbitrary_set *)boot_params }
|
||||
};
|
||||
|
||||
xen_call_(session, "VM.set_HVM_boot_params", param_values, 2, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_vm_add_to_hvm_boot_params(xen_session *session, xen_vm vm, char *key, char *value)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = vm },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = key },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = value }
|
||||
};
|
||||
|
||||
xen_call_(session, "VM.add_to_HVM_boot_params", param_values, 3, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xen_vm_remove_from_hvm_boot_params(xen_session *session, xen_vm vm, char *key)
|
||||
{
|
||||
abstract_value param_values[] =
|
||||
{
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = vm },
|
||||
{ .type = &abstract_type_string,
|
||||
.u.string_val = key }
|
||||
};
|
||||
|
||||
xen_call_(session, "VM.remove_from_HVM_boot_params", param_values, 2, NULL, NULL);
|
||||
return session->ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ static const char *lookup_table[] =
|
||||
"Paused",
|
||||
"Running",
|
||||
"Suspended",
|
||||
"ShuttingDown",
|
||||
"Unknown"
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 XenSource, Inc.
|
||||
* Copyright (c) 2006-2007 XenSource, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "xen_sr.h"
|
||||
#include "xen_vbd.h"
|
||||
#include "xen_vdi.h"
|
||||
#include "xen_console.h"
|
||||
#include "xen_vm.h"
|
||||
|
||||
|
||||
@@ -58,7 +59,7 @@ typedef struct
|
||||
} xen_comms;
|
||||
|
||||
|
||||
static xen_vm create_new_vm(xen_session *session);
|
||||
static xen_vm create_new_vm(xen_session *session, bool hvm);
|
||||
static void print_vm_power_state(xen_session *session, xen_vm vm);
|
||||
|
||||
|
||||
@@ -205,6 +206,20 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *dmesg;
|
||||
if (!xen_host_dmesg(session, &dmesg, host))
|
||||
{
|
||||
print_error(session);
|
||||
xen_string_string_map_free(versions);
|
||||
xen_host_free(host);
|
||||
xen_vm_record_free(vm_record);
|
||||
xen_uuid_bytes_free(vm_uuid_bytes);
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_vm_free(vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s.\n", vm_uuid);
|
||||
|
||||
fprintf(stderr, "In bytes, the VM UUID is ");
|
||||
@@ -222,6 +237,8 @@ int main(int argc, char **argv)
|
||||
versions->contents[i].val);
|
||||
}
|
||||
|
||||
printf("Host dmesg follows:\n%s\n\n", dmesg);
|
||||
|
||||
printf("%s.\n", vm_record->uuid);
|
||||
|
||||
printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
|
||||
@@ -243,9 +260,10 @@ int main(int argc, char **argv)
|
||||
|
||||
xen_host_free(host);
|
||||
xen_string_string_map_free(versions);
|
||||
free(dmesg);
|
||||
|
||||
|
||||
xen_vm new_vm = create_new_vm(session);
|
||||
xen_vm new_vm = create_new_vm(session, true);
|
||||
if (!session->ok)
|
||||
{
|
||||
/* Error has been logged, just clean up. */
|
||||
@@ -275,13 +293,28 @@ int main(int argc, char **argv)
|
||||
* allocation patterns can be used, as long as the allocation and free are
|
||||
* paired correctly.
|
||||
*/
|
||||
static xen_vm create_new_vm(xen_session *session)
|
||||
static xen_vm create_new_vm(xen_session *session, bool hvm)
|
||||
{
|
||||
xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
|
||||
vcpus_params->contents[0].key = strdup("weight");
|
||||
vcpus_params->contents[0].val = strdup("300");
|
||||
|
||||
xen_string_string_map *hvm_boot_params;
|
||||
if (hvm)
|
||||
{
|
||||
hvm_boot_params = xen_string_string_map_alloc(1);
|
||||
hvm_boot_params->contents[0].key = strdup("order");
|
||||
hvm_boot_params->contents[0].val = strdup("cd");
|
||||
}
|
||||
else
|
||||
{
|
||||
hvm_boot_params = NULL;
|
||||
}
|
||||
|
||||
xen_vm_record vm_record =
|
||||
{
|
||||
.name_label = "NewVM",
|
||||
.name_description = "New VM Description",
|
||||
.name_label = hvm ? "NewHVM" : "NewPV",
|
||||
.name_description = hvm ? "New HVM VM" : "New PV VM",
|
||||
.user_version = 1,
|
||||
.is_a_template = false,
|
||||
.memory_static_max = 256,
|
||||
@@ -294,18 +327,18 @@ static xen_vm create_new_vm(xen_session *session)
|
||||
.actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
|
||||
.actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
|
||||
.actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
|
||||
.hvm_boot = "",
|
||||
.pv_bootloader = "pygrub",
|
||||
.pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
|
||||
.pv_ramdisk = "",
|
||||
.pv_args = "",
|
||||
.pv_bootloader_args = ""
|
||||
.hvm_boot_policy = hvm ? "BIOS order" : NULL,
|
||||
.hvm_boot_params = hvm ? hvm_boot_params : NULL,
|
||||
.pv_bootloader = hvm ? NULL : "pygrub",
|
||||
.pv_kernel = hvm ? NULL : "/boot/vmlinuz-2.6.16.33-xen",
|
||||
};
|
||||
|
||||
|
||||
xen_vm vm;
|
||||
xen_vm_create(session, &vm, &vm_record);
|
||||
|
||||
xen_string_string_map_free(vcpus_params);
|
||||
xen_string_string_map_free(hvm_boot_params);
|
||||
|
||||
if (!session->ok)
|
||||
{
|
||||
fprintf(stderr, "VM creation failed.\n");
|
||||
@@ -368,7 +401,8 @@ static xen_vm create_new_vm(xen_session *session)
|
||||
.vm = &vm_record_opt,
|
||||
.vdi = &vdi0_record_opt,
|
||||
.device = "xvda1",
|
||||
.mode = XEN_VBD_MODE_RW
|
||||
.mode = XEN_VBD_MODE_RW,
|
||||
.bootable = 1,
|
||||
};
|
||||
|
||||
xen_vbd vbd0;
|
||||
@@ -383,13 +417,38 @@ static xen_vm create_new_vm(xen_session *session)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xen_console vnc_console = NULL;
|
||||
if (hvm) {
|
||||
xen_console_record vnc_console_record =
|
||||
{
|
||||
.protocol = XEN_CONSOLE_PROTOCOL_RFB,
|
||||
.vm = &vm_record_opt,
|
||||
};
|
||||
|
||||
if (!xen_console_create(session, &vnc_console, &vnc_console_record))
|
||||
{
|
||||
fprintf(stderr, "VNC console creation failed.\n");
|
||||
print_error(session);
|
||||
|
||||
xen_vbd_free(vbd0);
|
||||
xen_vdi_free(vdi0);
|
||||
xen_sr_set_free(srs);
|
||||
xen_vm_free(vm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *vm_uuid;
|
||||
char *vdi0_uuid;
|
||||
char *vbd0_uuid;
|
||||
char *vnc_uuid = NULL;
|
||||
|
||||
xen_vm_get_uuid(session, &vm_uuid, vm);
|
||||
xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
|
||||
xen_vbd_get_uuid(session, &vbd0_uuid, vbd0);
|
||||
if (hvm) {
|
||||
xen_console_get_uuid(session, &vnc_uuid, vnc_console);
|
||||
}
|
||||
|
||||
if (!session->ok)
|
||||
{
|
||||
@@ -399,22 +458,35 @@ static xen_vm create_new_vm(xen_session *session)
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_uuid_free(vdi0_uuid);
|
||||
xen_uuid_free(vbd0_uuid);
|
||||
xen_uuid_free(vnc_uuid);
|
||||
xen_vbd_free(vbd0);
|
||||
xen_vdi_free(vdi0);
|
||||
xen_console_free(vnc_console);
|
||||
xen_sr_set_free(srs);
|
||||
xen_vm_free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n",
|
||||
vm_uuid, vdi0_uuid, vbd0_uuid);
|
||||
if (hvm) {
|
||||
fprintf(stderr,
|
||||
"Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
|
||||
"UUID %s, and VNC console UUID %s.\n",
|
||||
vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
|
||||
"UUID %s.\n",
|
||||
vm_uuid, vdi0_uuid, vbd0_uuid);
|
||||
}
|
||||
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_uuid_free(vdi0_uuid);
|
||||
xen_uuid_free(vbd0_uuid);
|
||||
xen_uuid_free(vnc_uuid);
|
||||
xen_vbd_free(vbd0);
|
||||
xen_vdi_free(vdi0);
|
||||
xen_console_free(vnc_console);
|
||||
xen_sr_set_free(srs);
|
||||
|
||||
return vm;
|
||||
|
||||
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* Copyright (c) 2006 XenSource, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "xen_host.h"
|
||||
#include "xen_sr.h"
|
||||
#include "xen_vbd.h"
|
||||
#include "xen_vdi.h"
|
||||
#include "xen_vm.h"
|
||||
|
||||
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
" test_bindings <url> <username> <password>\n"
|
||||
"\n"
|
||||
"where\n"
|
||||
" <url> is a fragment of the server's URL, e.g. localhost:8005/RPC2;\n"
|
||||
" <username> is the username to use at the server; and\n"
|
||||
" <password> is the password.\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static char *url;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
xen_result_func func;
|
||||
void *handle;
|
||||
} xen_comms;
|
||||
|
||||
|
||||
static xen_vm create_new_vm(xen_session *session);
|
||||
static void print_vm_power_state(xen_session *session, xen_vm vm);
|
||||
|
||||
|
||||
static size_t
|
||||
write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
|
||||
{
|
||||
size_t n = size * nmemb;
|
||||
return comms->func(ptr, n, comms->handle) ? n : 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
call_func(const void *data, size_t len, void *user_handle,
|
||||
void *result_handle, xen_result_func result_func)
|
||||
{
|
||||
(void)user_handle;
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
xen_comms comms = {
|
||||
.func = result_func,
|
||||
.handle = result_handle
|
||||
};
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_MUTE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
|
||||
|
||||
CURLcode result = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void print_error(xen_session *session)
|
||||
{
|
||||
fprintf(stderr, "Error: %d", session->error_description_count);
|
||||
for (int i = 0; i < session->error_description_count; i++)
|
||||
{
|
||||
fprintf(stderr, "%s ", session->error_description[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 4)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
url = argv[1];
|
||||
char *username = argv[2];
|
||||
char *password = argv[3];
|
||||
|
||||
xmlInitParser();
|
||||
xen_init();
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
#define CLEANUP \
|
||||
do { \
|
||||
xen_session_logout(session); \
|
||||
curl_global_cleanup(); \
|
||||
xen_fini(); \
|
||||
xmlCleanupParser(); \
|
||||
} while(0) \
|
||||
|
||||
|
||||
xen_session *session =
|
||||
xen_session_login_with_password(call_func, NULL, username, password);
|
||||
|
||||
xen_vm vm;
|
||||
if (!xen_vm_get_by_uuid(session, &vm,
|
||||
"00000000-0000-0000-0000-000000000000"))
|
||||
{
|
||||
print_error(session);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *vm_uuid;
|
||||
if (!xen_vm_get_uuid(session, &vm_uuid, vm))
|
||||
{
|
||||
print_error(session);
|
||||
xen_vm_free(vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *vm_uuid_bytes;
|
||||
if (!xen_uuid_string_to_bytes(vm_uuid, &vm_uuid_bytes))
|
||||
{
|
||||
fprintf(stderr, "xen_uuid_string_to_bytes failed.\n");
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_vm_free(vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
xen_vm_record *vm_record;
|
||||
if (!xen_vm_get_record(session, &vm_record, vm))
|
||||
{
|
||||
print_error(session);
|
||||
xen_uuid_bytes_free(vm_uuid_bytes);
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_vm_free(vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
xen_host host;
|
||||
if (!xen_session_get_this_host(session, &host))
|
||||
{
|
||||
print_error(session);
|
||||
xen_vm_record_free(vm_record);
|
||||
xen_uuid_bytes_free(vm_uuid_bytes);
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_vm_free(vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
xen_string_string_map *versions;
|
||||
if (!xen_host_get_software_version(session, &versions, host))
|
||||
{
|
||||
print_error(session);
|
||||
xen_host_free(host);
|
||||
xen_vm_record_free(vm_record);
|
||||
xen_uuid_bytes_free(vm_uuid_bytes);
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_vm_free(vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s.\n", vm_uuid);
|
||||
|
||||
fprintf(stderr, "In bytes, the VM UUID is ");
|
||||
for (int i = 0; i < 15; i++)
|
||||
{
|
||||
fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
|
||||
}
|
||||
fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
|
||||
|
||||
printf("%zd.\n", versions->size);
|
||||
|
||||
for (size_t i = 0; i < versions->size; i++)
|
||||
{
|
||||
printf("%s -> %s.\n", versions->contents[i].key,
|
||||
versions->contents[i].val);
|
||||
}
|
||||
|
||||
printf("%s.\n", vm_record->uuid);
|
||||
|
||||
printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
|
||||
|
||||
printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
|
||||
|
||||
for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++)
|
||||
{
|
||||
printf("%"PRId64" -> %lf.\n",
|
||||
vm_record->vcpus_utilisation->contents[i].key,
|
||||
vm_record->vcpus_utilisation->contents[i].val);
|
||||
}
|
||||
|
||||
xen_uuid_bytes_free(vm_uuid_bytes);
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_vm_free(vm);
|
||||
|
||||
xen_vm_record_free(vm_record);
|
||||
|
||||
xen_host_free(host);
|
||||
xen_string_string_map_free(versions);
|
||||
|
||||
|
||||
xen_vm new_vm = create_new_vm(session);
|
||||
if (!session->ok)
|
||||
{
|
||||
/* Error has been logged, just clean up. */
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_vm_power_state(session, new_vm);
|
||||
if (!session->ok)
|
||||
{
|
||||
/* Error has been logged, just clean up. */
|
||||
xen_vm_free(new_vm);
|
||||
CLEANUP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
xen_vm_free(new_vm);
|
||||
CLEANUP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creation of a new VM, using the Named Parameters idiom. Allocate the
|
||||
* xen_vm_record here, but the sets through the library. Either
|
||||
* allocation patterns can be used, as long as the allocation and free are
|
||||
* paired correctly.
|
||||
*/
|
||||
static xen_vm create_new_vm(xen_session *session)
|
||||
{
|
||||
xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
|
||||
xen_vm_record vm_record =
|
||||
{
|
||||
.name_label = "NewHVM",
|
||||
.name_description = "New HVM Description",
|
||||
.user_version = 1,
|
||||
.is_a_template = false,
|
||||
.memory_static_max = 256,
|
||||
.memory_dynamic_max = 256,
|
||||
.memory_dynamic_min = 128,
|
||||
.memory_static_min = 128,
|
||||
.vcpus_policy = "credit",
|
||||
.vcpus_params = vcpus_params,
|
||||
.vcpus_number = 2,
|
||||
.actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
|
||||
.actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
|
||||
.actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
|
||||
.hvm_boot = "cda",
|
||||
};
|
||||
|
||||
|
||||
xen_vm vm;
|
||||
xen_vm_create(session, &vm, &vm_record);
|
||||
|
||||
if (!session->ok)
|
||||
{
|
||||
fprintf(stderr, "VM creation failed.\n");
|
||||
print_error(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new disk for the new VM.
|
||||
*/
|
||||
xen_sr_set *srs;
|
||||
if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
|
||||
srs->size < 1)
|
||||
{
|
||||
fprintf(stderr, "SR lookup failed.\n");
|
||||
print_error(session);
|
||||
xen_vm_free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xen_sr_record_opt sr_record =
|
||||
{
|
||||
.u.handle = srs->contents[0]
|
||||
};
|
||||
xen_vdi_record vdi0_record =
|
||||
{
|
||||
.name_label = "MyRootFS",
|
||||
.name_description = "MyRootFS description",
|
||||
.sr = &sr_record,
|
||||
.virtual_size = (1 << 21), // 1GiB / 512 bytes/sector
|
||||
.sector_size = 512,
|
||||
.location = "file:/root/gentoo.amd64.hvm.img",
|
||||
.type = XEN_VDI_TYPE_SYSTEM,
|
||||
.sharable = false,
|
||||
.read_only = false
|
||||
};
|
||||
|
||||
xen_vdi vdi0;
|
||||
if (!xen_vdi_create(session, &vdi0, &vdi0_record))
|
||||
{
|
||||
fprintf(stderr, "VDI creation failed.\n");
|
||||
print_error(session);
|
||||
|
||||
xen_sr_set_free(srs);
|
||||
xen_vm_free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
xen_vm_record_opt vm_record_opt =
|
||||
{
|
||||
.u.handle = vm
|
||||
};
|
||||
xen_vdi_record_opt vdi0_record_opt =
|
||||
{
|
||||
.u.handle = vdi0
|
||||
};
|
||||
xen_vbd_record vbd0_record =
|
||||
{
|
||||
.vm = &vm_record_opt,
|
||||
.vdi = &vdi0_record_opt,
|
||||
.device = "xvda1",
|
||||
.mode = XEN_VBD_MODE_RW
|
||||
};
|
||||
|
||||
xen_vbd vbd0;
|
||||
if (!xen_vbd_create(session, &vbd0, &vbd0_record))
|
||||
{
|
||||
fprintf(stderr, "VBD creation failed.\n");
|
||||
print_error(session);
|
||||
|
||||
xen_vdi_free(vdi0);
|
||||
xen_sr_set_free(srs);
|
||||
xen_vm_free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *vm_uuid;
|
||||
char *vdi0_uuid;
|
||||
char *vbd0_uuid;
|
||||
|
||||
xen_vm_get_uuid(session, &vm_uuid, vm);
|
||||
xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
|
||||
xen_vbd_get_uuid(session, &vbd0_uuid, vbd0);
|
||||
|
||||
if (!session->ok)
|
||||
{
|
||||
fprintf(stderr, "get_uuid call failed.\n");
|
||||
print_error(session);
|
||||
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_uuid_free(vdi0_uuid);
|
||||
xen_uuid_free(vbd0_uuid);
|
||||
xen_vbd_free(vbd0);
|
||||
xen_vdi_free(vdi0);
|
||||
xen_sr_set_free(srs);
|
||||
xen_vm_free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n",
|
||||
vm_uuid, vdi0_uuid, vbd0_uuid);
|
||||
|
||||
xen_uuid_free(vm_uuid);
|
||||
xen_uuid_free(vdi0_uuid);
|
||||
xen_uuid_free(vbd0_uuid);
|
||||
xen_vbd_free(vbd0);
|
||||
xen_vdi_free(vdi0);
|
||||
xen_sr_set_free(srs);
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print the power state for the given VM.
|
||||
*/
|
||||
static void print_vm_power_state(xen_session *session, xen_vm vm)
|
||||
{
|
||||
char *vm_uuid;
|
||||
enum xen_vm_power_state power_state;
|
||||
|
||||
if (!xen_vm_get_uuid(session, &vm_uuid, vm))
|
||||
{
|
||||
print_error(session);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xen_vm_get_power_state(session, &power_state, vm))
|
||||
{
|
||||
xen_uuid_free(vm_uuid);
|
||||
print_error(session);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("VM %s power state is %s.\n", vm_uuid,
|
||||
xen_vm_power_state_to_string(power_state));
|
||||
|
||||
xen_uuid_free(vm_uuid);
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ HDRS = $(wildcard *.h)
|
||||
TARGETS = xenperf xc_shadow
|
||||
|
||||
INSTALL_BIN = $(TARGETS) xencons
|
||||
INSTALL_SBIN = netfix xm xen-bugtool xend xenperf
|
||||
INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- mode: python; -*-
|
||||
#============================================================================
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2007 XenSource Inc.
|
||||
#============================================================================
|
||||
|
||||
|
||||
# Use the auxbin module in Xend to determine the correct Python path. We
|
||||
# take the first installed instance of auxbin that we find, and then run it
|
||||
# to determine the correct path, appending that to sys.path.
|
||||
|
||||
AUXBIN = 'xen/util/auxbin.py'
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
for p in ['python%s' % sys.version[:3], 'python']:
|
||||
for l in ['/usr/lib64', '/usr/lib']:
|
||||
d = os.path.join(l, p)
|
||||
if os.path.exists(os.path.join(d, AUXBIN)):
|
||||
sys.path.append(d)
|
||||
import xen.util.auxbin
|
||||
print os.path.join(xen.util.auxbin.libpath(), p)
|
||||
sys.exit(0)
|
||||
|
||||
print >>sys.stderr, "Cannot find Xen Python modules."
|
||||
sys.exit(1)
|
||||
+6
-16
@@ -31,23 +31,13 @@ import signal
|
||||
import time
|
||||
import commands
|
||||
|
||||
result = commands.getstatusoutput(os.path.join(os.path.dirname(sys.argv[0]),
|
||||
'xen-python-path'))
|
||||
if result[0] != 0:
|
||||
print >>sys.stderr, result[1]
|
||||
sys.exit(1)
|
||||
|
||||
# Use the auxbin module in Xend to determine the correct Python path. We
|
||||
# take the first installed instance of auxbin that we find, and then run it
|
||||
# to determine the correct path, appending that to sys.path.
|
||||
|
||||
AUXBIN = 'xen/util/auxbin.py'
|
||||
|
||||
for p in ['python%s' % sys.version[:3], 'python']:
|
||||
for l in ['/usr/lib64', '/usr/lib']:
|
||||
d = os.path.join(l, p)
|
||||
if os.path.exists(os.path.join(d, AUXBIN)):
|
||||
sys.path.append(d)
|
||||
import xen.util.auxbin
|
||||
libpath = os.path.join(xen.util.auxbin.libpath(), p)
|
||||
sys.path = sys.path[:-1]
|
||||
sys.path.append(libpath)
|
||||
break
|
||||
sys.path.append(result[1])
|
||||
|
||||
from xen.xend.server import SrvDaemon
|
||||
|
||||
|
||||
@@ -197,7 +197,10 @@ class Grub:
|
||||
self.screen = curses.initscr()
|
||||
self.screen.timeout(1000)
|
||||
if hasattr(curses, 'use_default_colors'):
|
||||
curses.use_default_colors()
|
||||
try:
|
||||
curses.use_default_colors()
|
||||
except:
|
||||
pass # Not important if we can't use colour
|
||||
enable_cursor(False)
|
||||
self.entry_win = curses.newwin(10, 74, 2, 1)
|
||||
self.text_win = curses.newwin(10, 70, 12, 5)
|
||||
|
||||
@@ -13,16 +13,11 @@ vm_cfg = {
|
||||
|
||||
|
||||
'VCPUs_policy': 'credit',
|
||||
'VCPUs_params': '',
|
||||
'VCPUs_params': {},
|
||||
'VCPUs_number': 2,
|
||||
'VCPUs_features_required': '',
|
||||
'VCPUs_features_can_use': '',
|
||||
'VCPUs_features_force_on': '',
|
||||
'VCPUs_features_force_off': '',
|
||||
|
||||
'actions_after_shutdown': 'destroy',
|
||||
'actions_after_reboot': 'restart',
|
||||
'actions_after_suspend': 'destroy',
|
||||
'actions_after_crash': 'destroy',
|
||||
|
||||
'PV_bootloader': '',
|
||||
@@ -44,7 +39,7 @@ vm_cfg = {
|
||||
local_vdi_cfg = {
|
||||
'name_label': 'gentoo.hvm',
|
||||
'name_description': '',
|
||||
'uri': 'file:/root/gentoo.amd64.hvm.img',
|
||||
'location': 'file:/root/gentoo.amd64.hvm.img',
|
||||
'virtual_size': 0,
|
||||
'sector_size': 0,
|
||||
'type': 'system',
|
||||
|
||||
@@ -15,14 +15,9 @@ vm_cfg = {
|
||||
'VCPUs_policy': 'credit',
|
||||
'VCPUs_params': '',
|
||||
'VCPUs_number': 2,
|
||||
'VCPUs_features_required': '',
|
||||
'VCPUs_features_can_use': '',
|
||||
'VCPUs_features_force_on': '',
|
||||
'VCPUs_features_force_off': '',
|
||||
|
||||
'actions_after_shutdown': 'destroy',
|
||||
'actions_after_reboot': 'restart',
|
||||
'actions_after_suspend': 'destroy',
|
||||
'actions_after_crash': 'destroy',
|
||||
|
||||
'PV_bootloader': '',
|
||||
@@ -65,7 +60,7 @@ vbd_cfg = {
|
||||
local_vdi_cfg = {
|
||||
'name_label': 'gentoo.amd64.img',
|
||||
'name_description': '',
|
||||
'uri': 'file:/root/gentoo.amd64.img',
|
||||
'location': 'file:/root/gentoo.amd64.img',
|
||||
'virtual_size': 0,
|
||||
'sector_size': 0,
|
||||
'type': 'system',
|
||||
@@ -183,13 +178,13 @@ def test_vm_create():
|
||||
execute(server, 'VM.resume', (session, vm_uuid, False))
|
||||
print 'Resumed VM.'
|
||||
|
||||
finally:
|
||||
# Wait for user to say we're good to shut it down
|
||||
while True:
|
||||
destroy = raw_input('destroy VM? ')
|
||||
if destroy[0] in ('y', 'Y'):
|
||||
break
|
||||
|
||||
finally:
|
||||
|
||||
# Clean up
|
||||
if vif_uuid:
|
||||
execute(server, 'VIF.destroy', (session, vif_uuid))
|
||||
|
||||
@@ -22,7 +22,7 @@ import sys
|
||||
import traceback
|
||||
import threading
|
||||
|
||||
from xen.xend import XendDomain, XendDomainInfo, XendNode
|
||||
from xen.xend import XendDomain, XendDomainInfo, XendNode, XendDmesg
|
||||
from xen.xend import XendLogging, XendTaskManager
|
||||
|
||||
from xen.xend.XendAuthSessions import instance as auth_manager
|
||||
@@ -615,7 +615,8 @@ class XendAPI(object):
|
||||
('reboot', None),
|
||||
('shutdown', None),
|
||||
('add_to_other_config', None),
|
||||
('remove_from_other_config', None)]
|
||||
('remove_from_other_config', None),
|
||||
('dmesg', 'String')]
|
||||
|
||||
host_funcs = [('get_by_name_label', 'Set(host)')]
|
||||
|
||||
@@ -674,6 +675,9 @@ class XendAPI(object):
|
||||
return xen_api_error(XEND_ERROR_HOST_RUNNING)
|
||||
return xen_api_error(XEND_ERROR_UNSUPPORTED)
|
||||
|
||||
def host_dmesg(self, session, host_ref):
|
||||
return xen_api_success(XendDmesg.instance().info())
|
||||
|
||||
def host_get_record(self, session, host_ref):
|
||||
node = XendNode.instance()
|
||||
dom = XendDomain.instance()
|
||||
@@ -737,7 +741,7 @@ class XendAPI(object):
|
||||
'memory_free',
|
||||
'host']
|
||||
host_metrics_attr_rw = []
|
||||
host_methods = []
|
||||
host_metrics_methods = []
|
||||
|
||||
def _host_metrics_get(self, ref, f):
|
||||
return xen_api_success(getattr(node, f)())
|
||||
@@ -974,7 +978,8 @@ class XendAPI(object):
|
||||
'PV_ramdisk',
|
||||
'PV_args',
|
||||
'PV_bootloader_args',
|
||||
'HVM_boot',
|
||||
'HVM_boot_policy',
|
||||
'HVM_boot_params',
|
||||
'platform_std_VGA',
|
||||
'platform_serial',
|
||||
'platform_localtime',
|
||||
@@ -1020,7 +1025,8 @@ class XendAPI(object):
|
||||
'PV_ramdisk',
|
||||
'PV_args',
|
||||
'PV_bootloader_args',
|
||||
'HVM_boot',
|
||||
'HVM_boot_policy',
|
||||
'HVM_boot_params',
|
||||
'platform_std_VGA',
|
||||
'platform_serial',
|
||||
'platform_localtime',
|
||||
@@ -1121,11 +1127,11 @@ class XendAPI(object):
|
||||
|
||||
def VM_get_VCPUs_policy(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return dom.get_vcpus_policy()
|
||||
return xen_api_success(dom.get_vcpus_policy())
|
||||
|
||||
def VM_get_VCPUs_params(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_todo() # need access to scheduler
|
||||
return xen_api_success(dom.get_vcpus_params())
|
||||
|
||||
def VM_get_actions_after_shutdown(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
@@ -1158,8 +1164,11 @@ class XendAPI(object):
|
||||
def VM_get_PV_bootloader_args(self, session, vm_ref):
|
||||
return self.VM_get('PV_bootloader_args', session, vm_ref)
|
||||
|
||||
def VM_get_HVM_boot(self, session, vm_ref):
|
||||
return self.VM_get('HVM_boot', session, vm_ref)
|
||||
def VM_get_HVM_boot_policy(self, session, vm_ref):
|
||||
return self.VM_get('HVM_boot_policy', session, vm_ref)
|
||||
|
||||
def VM_get_HVM_boot_params(self, session, vm_ref):
|
||||
return self.VM_get('HVM_boot_params', session, vm_ref)
|
||||
|
||||
def VM_get_platform_std_VGA(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
@@ -1186,7 +1195,7 @@ class XendAPI(object):
|
||||
return xen_api_success(dom.get_platform_keymap())
|
||||
|
||||
def VM_get_other_config(self, session, vm_ref):
|
||||
return self.VM_get('otherconfig', session, vm_ref)
|
||||
return self.VM_get('other_config', session, vm_ref)
|
||||
|
||||
def VM_get_is_control_domain(self, session, vm_ref):
|
||||
xd = XendDomain.instance()
|
||||
@@ -1246,8 +1255,30 @@ class XendAPI(object):
|
||||
return xen_api_error(['VM_ON_CRASH_BEHAVIOUR_INVALID', vm_ref])
|
||||
return self.VM_set('actions_after_crash', session, vm_ref, action)
|
||||
|
||||
def VM_set_HVM_boot(self, session, vm_ref, value):
|
||||
return self.VM_set('HVM_boot', session, vm_ref, value)
|
||||
def VM_set_HVM_boot_policy(self, session, vm_ref, value):
|
||||
if value != "" and value != "BIOS order":
|
||||
return xen_api_error(
|
||||
['VALUE_NOT_SUPPORTED', 'VM.HVM_boot_policy', value,
|
||||
'Xend supports only the "BIOS order" boot policy.'])
|
||||
else:
|
||||
return self.VM_set('HVM_boot_policy', session, vm_ref, value)
|
||||
|
||||
def VM_set_HVM_boot_params(self, session, vm_ref, value):
|
||||
return self.VM_set('HVM_boot_params', session, vm_ref, value)
|
||||
|
||||
def VM_add_to_HVM_boot_params(self, session, vm_ref, key, value):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
if 'HVM_boot_params' not in dom.info:
|
||||
dom.info['HVM_boot_params'] = {}
|
||||
dom.info['HVM_boot_params'][key] = value
|
||||
return xen_api_success_void()
|
||||
|
||||
def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
if 'HVM_boot_params' in dom.info \
|
||||
and key in dom.info['HVM_boot_params']:
|
||||
del dom.info['HVM_boot_params'][key]
|
||||
return xen_api_success_void()
|
||||
|
||||
def VM_set_PV_bootloader(self, session, vm_ref, value):
|
||||
return self.VM_set('PV_bootloader', session, vm_ref, value)
|
||||
@@ -1354,7 +1385,8 @@ class XendAPI(object):
|
||||
'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
|
||||
'PV_args': xeninfo.info.get('PV_args'),
|
||||
'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
|
||||
'HVM_boot': xeninfo.info.get('HVM_boot'),
|
||||
'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
|
||||
'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
|
||||
'platform_std_VGA': xeninfo.get_platform_std_vga(),
|
||||
'platform_serial': xeninfo.get_platform_serial(),
|
||||
'platform_localtime': xeninfo.get_platform_localtime(),
|
||||
@@ -1363,7 +1395,7 @@ class XendAPI(object):
|
||||
'platform_keymap': xeninfo.get_platform_keymap(),
|
||||
'PCI_bus': xeninfo.get_pci_bus(),
|
||||
'tools_version': xeninfo.get_tools_version(),
|
||||
'other_config': xeninfo.info.get('otherconfig'),
|
||||
'other_config': xeninfo.info.get('other_config', {}),
|
||||
'is_control_domain': xeninfo == xendom.privilegedDomain(),
|
||||
}
|
||||
return xen_api_success(record)
|
||||
@@ -1469,7 +1501,7 @@ class XendAPI(object):
|
||||
vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
|
||||
if not vdi:
|
||||
return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
|
||||
vdi_image = vdi.get_image_uri()
|
||||
vdi_image = vdi.get_location()
|
||||
vbd_ref = XendTask.log_progress(0, 100,
|
||||
dom.create_vbd,
|
||||
vbd_struct, vdi_image)
|
||||
@@ -1622,7 +1654,7 @@ class XendAPI(object):
|
||||
xendom = XendDomain.instance()
|
||||
return xen_api_success(xendom.get_dev_property_by_uuid('vif', vif_ref,
|
||||
'io_write_kbs'))
|
||||
|
||||
|
||||
def VIF_get_all(self, session):
|
||||
xendom = XendDomain.instance()
|
||||
vifs = [d.get_vifs() for d in XendDomain.instance().list('all')]
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2006 XenSource Ltd.
|
||||
# Copyright (C) 2006-2007 XenSource Ltd.
|
||||
#============================================================================
|
||||
|
||||
#
|
||||
@@ -24,7 +24,7 @@ XEN_API_VM_POWER_STATE = [
|
||||
'Paused',
|
||||
'Running',
|
||||
'Suspended',
|
||||
'ShuttingDown',
|
||||
'Halted',
|
||||
'Unknown'
|
||||
]
|
||||
|
||||
@@ -49,16 +49,8 @@ XEN_API_ON_CRASH_BEHAVIOUR = [
|
||||
'rename_restart'
|
||||
]
|
||||
|
||||
XEN_API_BOOT_TYPE = [
|
||||
'bios',
|
||||
'grub',
|
||||
'kernel_external',
|
||||
'kernel_internal'
|
||||
]
|
||||
|
||||
XEN_API_VBD_MODE = ['RO', 'RW']
|
||||
XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral']
|
||||
XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised']
|
||||
XEN_API_VBD_TYPE = ['CD', 'Disk']
|
||||
XEN_API_TASK_STATUS_TYPE = ['pending', 'success', 'failure']
|
||||
XEN_API_CONSOLE_PROTOCOL = ['vt100', 'rfb', 'rdp']
|
||||
@@ -97,7 +97,9 @@ def bootloader(blexec, disk, dom, quiet = False, blargs = '', kernel = '',
|
||||
|
||||
try:
|
||||
log.debug("Launching bootloader as %s." % str(args))
|
||||
os.execvp(args[0], args)
|
||||
env = os.environ.copy()
|
||||
env['TERM'] = 'vt100'
|
||||
os.execvpe(args[0], args, env)
|
||||
except OSError, e:
|
||||
print e
|
||||
pass
|
||||
|
||||
@@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyprintstring
|
||||
from xen.xend.XendConstants import DOM_STATE_HALTED
|
||||
|
||||
log = logging.getLogger("xend.XendConfig")
|
||||
log.setLevel(logging.WARN)
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
"""
|
||||
@@ -125,8 +125,7 @@ XENAPI_HVM_CFG = {
|
||||
'platform_std_vga': 'stdvga',
|
||||
'platform_serial' : 'serial',
|
||||
'platform_localtime': 'localtime',
|
||||
'platform_keymap' : 'keymap',
|
||||
'HVM_boot': 'boot',
|
||||
'platform_keymap' : 'keymap'
|
||||
}
|
||||
|
||||
# List of XendConfig configuration keys that have no direct equivalent
|
||||
@@ -147,24 +146,19 @@ XENAPI_CFG_TYPES = {
|
||||
'memory_actual': int,
|
||||
'cpus': list,
|
||||
'vcpus_policy': str,
|
||||
'vcpus_params': str,
|
||||
'vcpus_params': dict,
|
||||
'vcpus_number': int,
|
||||
'vcpus_features_required': list,
|
||||
'vcpus_features_can_use': list,
|
||||
'vcpus_features_force_on': list,
|
||||
'vcpus_features_force_off': list,
|
||||
'actions_after_shutdown': str,
|
||||
'actions_after_reboot': str,
|
||||
'actions_after_suspend': str,
|
||||
'actions_after_crash': str,
|
||||
'tpm_instance': int,
|
||||
'tpm_backend': int,
|
||||
'PV_bootloader': str,
|
||||
'PV_kernel': str,
|
||||
'PV_ramdisk': str,
|
||||
'PV_args': str,
|
||||
'PV_bootloader_args': str,
|
||||
'HVM_boot': str,
|
||||
'HVM_boot_policy': str,
|
||||
'HVM_boot_params': dict,
|
||||
'platform_std_vga': bool0,
|
||||
'platform_serial': str,
|
||||
'platform_localtime': bool0,
|
||||
@@ -349,7 +343,6 @@ class XendConfig(dict):
|
||||
|
||||
def _defaults(self):
|
||||
defaults = {
|
||||
'uuid': uuid.createString(),
|
||||
'name_label': 'Domain-Unnamed',
|
||||
'actions_after_shutdown': 'destroy',
|
||||
'actions_after_reboot': 'restart',
|
||||
@@ -361,7 +354,8 @@ class XendConfig(dict):
|
||||
'PV_ramdisk': '',
|
||||
'PV_args': '',
|
||||
'PV_bootloader_args': '',
|
||||
'HVM_boot': '',
|
||||
'HVM_boot_policy': '',
|
||||
'HVM_boot_params': {},
|
||||
'memory_static_min': 0,
|
||||
'memory_dynamic_min': 0,
|
||||
'shadow_memory': 0,
|
||||
@@ -377,6 +371,7 @@ class XendConfig(dict):
|
||||
'cpu_weight': 256,
|
||||
'cpu_cap': 0,
|
||||
'vcpus_number': 1,
|
||||
'vcpus_params': {},
|
||||
'console_refs': [],
|
||||
'vif_refs': [],
|
||||
'vbd_refs': [],
|
||||
@@ -384,7 +379,6 @@ class XendConfig(dict):
|
||||
'other_config': {},
|
||||
}
|
||||
|
||||
defaults['name_label'] = 'Domain-' + defaults['uuid']
|
||||
return defaults
|
||||
|
||||
def _memory_sanity_check(self):
|
||||
@@ -414,13 +408,21 @@ class XendConfig(dict):
|
||||
|
||||
def _uuid_sanity_check(self):
|
||||
"""Make sure UUID is in proper string format with hyphens."""
|
||||
self['uuid'] = uuid.toString(uuid.fromString(self['uuid']))
|
||||
if 'uuid' not in self or not self['uuid']:
|
||||
self['uuid'] = uuid.createString()
|
||||
else:
|
||||
self['uuid'] = uuid.toString(uuid.fromString(self['uuid']))
|
||||
|
||||
def _name_sanity_check(self):
|
||||
if 'name_label' not in self:
|
||||
self['name_label'] = 'Domain-' + self['uuid']
|
||||
|
||||
def validate(self):
|
||||
self._uuid_sanity_check()
|
||||
self._name_sanity_check()
|
||||
self._memory_sanity_check()
|
||||
self._actions_sanity_check()
|
||||
self._vcpus_sanity_check()
|
||||
self._uuid_sanity_check()
|
||||
|
||||
def _dominfo_to_xapi(self, dominfo):
|
||||
self['domid'] = dominfo['domid']
|
||||
@@ -496,6 +498,12 @@ class XendConfig(dict):
|
||||
log.warn("Unable to parse key %s: %s: %s" %
|
||||
(key, str(val), e))
|
||||
|
||||
# Compatibility hack -- can go soon.
|
||||
boot_order = sxp.child_value(sxp_cfg, 'HVM_boot')
|
||||
if boot_order:
|
||||
cfg['HVM_boot_policy'] = 'BIOS order'
|
||||
cfg['HVM_boot_params'] = { 'order' : boot_order }
|
||||
|
||||
# Parsing the device SXP's. In most cases, the SXP looks
|
||||
# like this:
|
||||
#
|
||||
@@ -671,6 +679,9 @@ class XendConfig(dict):
|
||||
if self['devices'][console_uuid][1].get('protocol') == 'rfb':
|
||||
has_rfb = True
|
||||
break
|
||||
if self['devices'][console_uuid][0] == 'vfb':
|
||||
has_rfb = True
|
||||
break
|
||||
|
||||
if not has_rfb:
|
||||
dev_config = ['vfb']
|
||||
@@ -724,6 +735,7 @@ class XendConfig(dict):
|
||||
val = sxp.child_value(image_sxp, imgkey, None)
|
||||
if val != None:
|
||||
self[apikey] = val
|
||||
self._hvm_boot_params_from_sxp(image_sxp)
|
||||
|
||||
# extract backend value
|
||||
|
||||
@@ -768,7 +780,7 @@ class XendConfig(dict):
|
||||
if 'image' in xapi_dict:
|
||||
self['image'].update(xapi_dict['image'])
|
||||
else:
|
||||
hvm = self['HVM_boot'] != ''
|
||||
hvm = self['HVM_boot_policy'] != ''
|
||||
self['image']['type'] = hvm and 'hvm' or 'linux'
|
||||
if hvm:
|
||||
self['image']['hvm'] = {'devices': {}}
|
||||
@@ -829,8 +841,6 @@ class XendConfig(dict):
|
||||
else:
|
||||
self[key] = val
|
||||
|
||||
self.validate()
|
||||
|
||||
def to_sxp(self, domain = None, ignore_devices = False, ignore = [],
|
||||
legacy_only = True):
|
||||
""" Get SXP representation of this config object.
|
||||
@@ -854,9 +864,13 @@ class XendConfig(dict):
|
||||
sxpr.append(['domid', domain.getDomid()])
|
||||
|
||||
if not legacy_only:
|
||||
for name in XENAPI_CFG_TYPES.keys():
|
||||
for name, typ in XENAPI_CFG_TYPES.items():
|
||||
if name in self and self[name] not in (None, []):
|
||||
sxpr.append([name, str(self[name])])
|
||||
if typ == dict:
|
||||
s = self[name].items()
|
||||
else:
|
||||
s = str(self[name])
|
||||
sxpr.append([name, s])
|
||||
|
||||
for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
|
||||
if self.has_key(xenapi) and self[xenapi] not in (None, []):
|
||||
@@ -905,7 +919,7 @@ class XendConfig(dict):
|
||||
# store as part of the device config.
|
||||
dev_uuid = sxp.child_value(config, 'uuid')
|
||||
dev_type, dev_cfg = self['devices'][dev_uuid]
|
||||
is_bootable = dev_cfg.get('bootable', False)
|
||||
is_bootable = dev_cfg.get('bootable', 0)
|
||||
config.append(['bootable', int(is_bootable)])
|
||||
|
||||
sxpr.append(['device', config])
|
||||
@@ -978,14 +992,16 @@ class XendConfig(dict):
|
||||
pass
|
||||
|
||||
if dev_type == 'vbd':
|
||||
dev_info['bootable'] = False
|
||||
dev_info['bootable'] = 0
|
||||
if dev_info.get('dev', '').startswith('ioemu:'):
|
||||
dev_info['driver'] = 'ioemu'
|
||||
else:
|
||||
dev_info['driver'] = 'paravirtualised'
|
||||
|
||||
# create uuid if it doesn't exist
|
||||
dev_uuid = dev_info.get('uuid', uuid.createString())
|
||||
dev_uuid = dev_info.get('uuid', None)
|
||||
if not dev_uuid:
|
||||
dev_uuid = uuid.createString()
|
||||
dev_info['uuid'] = dev_uuid
|
||||
|
||||
# store dev references by uuid for certain device types
|
||||
@@ -998,7 +1014,7 @@ class XendConfig(dict):
|
||||
if dev_type == 'vbd' and not target[param]:
|
||||
# Compat hack -- this is the first disk, so mark it
|
||||
# bootable.
|
||||
dev_info['bootable'] = True
|
||||
dev_info['bootable'] = 1
|
||||
target[param].append(dev_uuid)
|
||||
elif dev_type == 'tap':
|
||||
if 'vbd_refs' not in target:
|
||||
@@ -1007,7 +1023,7 @@ class XendConfig(dict):
|
||||
if not target['vbd_refs']:
|
||||
# Compat hack -- this is the first disk, so mark it
|
||||
# bootable.
|
||||
dev_info['bootable'] = True
|
||||
dev_info['bootable'] = 1
|
||||
target['vbd_refs'].append(dev_uuid)
|
||||
|
||||
elif dev_type == 'vfb':
|
||||
@@ -1055,7 +1071,9 @@ class XendConfig(dict):
|
||||
if cfg_xenapi.get('name'):
|
||||
dev_info['name'] = cfg_xenapi.get('name')
|
||||
|
||||
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
|
||||
dev_uuid = cfg_xenapi.get('uuid', None)
|
||||
if not dev_uuid:
|
||||
dev_uuid = uuid.createString()
|
||||
dev_info['uuid'] = dev_uuid
|
||||
target['devices'][dev_uuid] = (dev_type, dev_info)
|
||||
target['vif_refs'].append(dev_uuid)
|
||||
@@ -1070,8 +1088,8 @@ class XendConfig(dict):
|
||||
dev_info['uname'] = cfg_xenapi.get('image', '')
|
||||
dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'),
|
||||
old_vbd_type)
|
||||
dev_info['bootable'] = cfg_xenapi.get('bootable', False)
|
||||
dev_info['driver'] = cfg_xenapi.get('driver')
|
||||
dev_info['bootable'] = int(cfg_xenapi.get('bootable', 0))
|
||||
dev_info['driver'] = cfg_xenapi.get('driver', '')
|
||||
dev_info['VDI'] = cfg_xenapi.get('VDI', '')
|
||||
|
||||
if cfg_xenapi.get('mode') == 'RW':
|
||||
@@ -1079,7 +1097,9 @@ class XendConfig(dict):
|
||||
else:
|
||||
dev_info['mode'] = 'r'
|
||||
|
||||
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
|
||||
dev_uuid = cfg_xenapi.get('uuid', None)
|
||||
if not dev_uuid:
|
||||
dev_uuid = uuid.createString()
|
||||
dev_info['uuid'] = dev_uuid
|
||||
target['devices'][dev_uuid] = (dev_type, dev_info)
|
||||
target['vbd_refs'].append(dev_uuid)
|
||||
@@ -1088,13 +1108,17 @@ class XendConfig(dict):
|
||||
if cfg_xenapi.get('type'):
|
||||
dev_info['type'] = cfg_xenapi.get('type')
|
||||
|
||||
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
|
||||
dev_uuid = cfg_xenapi.get('uuid', None)
|
||||
if not dev_uuid:
|
||||
dev_uuid = uuid.createString()
|
||||
dev_info['uuid'] = dev_uuid
|
||||
target['devices'][dev_uuid] = (dev_type, dev_info)
|
||||
target['vtpm_refs'].append(dev_uuid)
|
||||
|
||||
elif dev_type == 'console':
|
||||
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
|
||||
dev_uuid = cfg_xenapi.get('uuid', None)
|
||||
if not dev_uuid:
|
||||
dev_uuid = uuid.createString()
|
||||
dev_info['uuid'] = dev_uuid
|
||||
dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb')
|
||||
dev_info['other_config'] = cfg_xenapi.get('other_config', {})
|
||||
@@ -1223,7 +1247,12 @@ class XendConfig(dict):
|
||||
"configuration dictionary.")
|
||||
|
||||
sxpr.append(dev_type)
|
||||
config = [(opt, val) for opt, val in dev_info.items()]
|
||||
if dev_type in ('console', 'vfb'):
|
||||
config = [(opt, val) for opt, val in dev_info.items()
|
||||
if opt != 'other_config']
|
||||
else:
|
||||
config = [(opt, val) for opt, val in dev_info.items()]
|
||||
|
||||
sxpr += config
|
||||
|
||||
return sxpr
|
||||
@@ -1356,12 +1385,19 @@ class XendConfig(dict):
|
||||
val = sxp.child_value(image_sxp, imgkey, None)
|
||||
if val != None:
|
||||
type_conv = XENAPI_CFG_TYPES[apikey]
|
||||
if callable(conv):
|
||||
if callable(type_conv):
|
||||
self[apikey] = type_conv(val)
|
||||
else:
|
||||
self[apikey] = val
|
||||
self._hvm_boot_params_from_sxp(image_sxp)
|
||||
|
||||
|
||||
def _hvm_boot_params_from_sxp(self, image_sxp):
|
||||
boot = sxp.child_value(image_sxp, 'boot', None)
|
||||
if boot is not None:
|
||||
self['HVM_boot_policy'] = 'BIOS order'
|
||||
self['HVM_boot_params'] = { 'order' : boot }
|
||||
|
||||
|
||||
#
|
||||
# debugging
|
||||
|
||||
@@ -1648,14 +1648,15 @@ class XendDomainInfo:
|
||||
kernel = self.info['PV_kernel']
|
||||
ramdisk = self.info['PV_ramdisk']
|
||||
args = self.info['PV_args']
|
||||
boot = self.info['HVM_boot']
|
||||
boot = self.info['HVM_boot_policy']
|
||||
|
||||
if boot:
|
||||
# HVM booting.
|
||||
self.info['image']['type'] = 'hvm'
|
||||
if not 'devices' in self.info['image']:
|
||||
self.info['image']['devices'] = {}
|
||||
self.info['image']['devices']['boot'] = boot
|
||||
self.info['image']['devices']['boot'] = \
|
||||
self.info['HVM_boot_params'].get('order', 'dc')
|
||||
elif not blexec and kernel:
|
||||
# Boot from dom0. Nothing left to do -- the kernel and ramdisk
|
||||
# will be picked up by image.py.
|
||||
@@ -1976,7 +1977,11 @@ class XendDomainInfo:
|
||||
else:
|
||||
return 'unknown'
|
||||
def get_vcpus_params(self):
|
||||
return '' # TODO
|
||||
if self.getDomid() is None:
|
||||
return self.info['vcpus_params']
|
||||
|
||||
retval = xc.sched_credit_domain_get(self.getDomid())
|
||||
return retval
|
||||
def get_power_state(self):
|
||||
return XEN_API_VM_POWER_STATE[self.state]
|
||||
def get_platform_std_vga(self):
|
||||
|
||||
@@ -73,6 +73,7 @@ class XendVDI(AutoSaveObject):
|
||||
self.sharable = False
|
||||
self.read_only = False
|
||||
self.type = "system"
|
||||
self.location = ''
|
||||
|
||||
def load_config_dict(self, cfg):
|
||||
"""Loads configuration into the object from a dict.
|
||||
@@ -147,9 +148,10 @@ class XendVDI(AutoSaveObject):
|
||||
'sharable': False,
|
||||
'readonly': False,
|
||||
'SR': self.sr_uuid,
|
||||
'location': self.get_location(),
|
||||
'VBDs': []}
|
||||
|
||||
def get_image_uri(self):
|
||||
def get_location(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@@ -163,9 +165,10 @@ class XendQCoWVDI(XendVDI):
|
||||
self.virtual_size = vsize
|
||||
self.sector_size = 512
|
||||
self.auto_save = True
|
||||
self.location = 'tap:qcow:%s' % self.qcow_path
|
||||
|
||||
def get_image_uri(self):
|
||||
return 'tap:qcow:%s' % self.qcow_path
|
||||
def get_location(self):
|
||||
return self.location
|
||||
|
||||
class XendLocalVDI(XendVDI):
|
||||
def __init__(self, vdi_struct):
|
||||
@@ -183,7 +186,7 @@ class XendLocalVDI(XendVDI):
|
||||
self.type = vdi_struct.get('type', '')
|
||||
self.sharable = vdi_struct.get('sharable', False)
|
||||
self.read_only = vdi_struct.get('read_only', False)
|
||||
self.image_uri = vdi_struct.get('uri', 'file:/dev/null')
|
||||
self.location = vdi_struct.get('location', 'file:/dev/null')
|
||||
|
||||
def get_image_uri(self):
|
||||
return self.image_uri
|
||||
def get_location(self):
|
||||
return self.location
|
||||
@@ -449,48 +449,50 @@ class HVMImageHandler(ImageHandler):
|
||||
return ret
|
||||
|
||||
vnc_config = {}
|
||||
has_vfb = False
|
||||
has_vnc = int(vmConfig['image'].get('vnc')) != 0
|
||||
has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0
|
||||
has_sdl = int(vmConfig['image'].get('sdl', 0)) != 0
|
||||
for dev_uuid in vmConfig['console_refs']:
|
||||
dev_type, dev_info = vmConfig['devices'][devuuid]
|
||||
if dev_type == 'rfb':
|
||||
dev_type, dev_info = vmConfig['devices'][dev_uuid]
|
||||
if dev_type == 'vfb':
|
||||
vnc_config = dev_info.get('other_config', {})
|
||||
has_vfb = True
|
||||
has_vnc = True
|
||||
break
|
||||
|
||||
if not vnc_config:
|
||||
for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'):
|
||||
if key in vmConfig['image']:
|
||||
vnc_config[key] = vmConfig['image'][key]
|
||||
if has_vnc:
|
||||
if not vnc_config:
|
||||
for key in ('vncunused', 'vnclisten', 'vncdisplay',
|
||||
'vncpasswd'):
|
||||
if key in vmConfig['image']:
|
||||
vnc_config[key] = vmConfig['image'][key]
|
||||
|
||||
if not has_vfb and not has_vnc:
|
||||
ret.append('-nographic')
|
||||
return ret
|
||||
if not vnc_config.get('vncunused', 0) and \
|
||||
vnc_config.get('vncdisplay', 0):
|
||||
ret.append('-vnc')
|
||||
ret.append(str(vncdisplay))
|
||||
else:
|
||||
ret.append('-vncunused')
|
||||
|
||||
|
||||
if not vnc_config.get('vncunused', 0) and \
|
||||
vnc_config.get('vncdisplay', 0):
|
||||
ret.append('-vnc')
|
||||
ret.append(str(vncdisplay))
|
||||
vnclisten = vnc_config.get('vnclisten',
|
||||
xenopts().get_vnclisten_address())
|
||||
ret.append('-vnclisten')
|
||||
ret.append(str(vnclisten))
|
||||
|
||||
# Store vncpassword in xenstore
|
||||
vncpasswd = vnc_config.get('vncpasswd')
|
||||
if not vncpasswd:
|
||||
vncpasswd = xenopts().get_vncpasswd_default()
|
||||
|
||||
if vncpasswd is None:
|
||||
raise VmError('vncpasswd is not setup in vmconfig or '
|
||||
'xend-config.sxp')
|
||||
|
||||
if vncpasswd != '':
|
||||
self.vm.storeVm('vncpasswd', vncpasswd)
|
||||
elif has_sdl:
|
||||
# SDL is default in QEMU.
|
||||
pass
|
||||
else:
|
||||
ret.append('-vncunused')
|
||||
|
||||
vnclisten = vnc_config.get('vnclisten',
|
||||
xenopts().get_vnclisten_address())
|
||||
ret.append('-vnclisten')
|
||||
ret.append(str(vnclisten))
|
||||
|
||||
# Store vncpassword in xenstore
|
||||
vncpasswd = vnc_config.get('vncpasswd')
|
||||
if not vncpasswd:
|
||||
vncpasswd = xenopts().get_vncpasswd_default()
|
||||
|
||||
if vncpasswd is None:
|
||||
raise VmError('vncpasswd is not setup in vmconfig or '
|
||||
'xend-config.sxp')
|
||||
|
||||
if vncpasswd != '':
|
||||
self.vm.storeVm('vncpasswd', vncpasswd)
|
||||
ret.append('-nographic')
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class VfbifController(DevController):
|
||||
|
||||
def createDevice(self, config):
|
||||
DevController.createDevice(self, config)
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
# is HVM, so qemu-dm will handle the vfb.
|
||||
return
|
||||
|
||||
@@ -90,7 +90,7 @@ class VfbifController(DevController):
|
||||
|
||||
|
||||
def waitForDevice(self, devid):
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
log.debug('skip waiting for HVM vfb')
|
||||
# is a qemu-dm managed device, don't wait for hotplug for these.
|
||||
return
|
||||
@@ -110,7 +110,7 @@ class VfbifController(DevController):
|
||||
raise VmError('Refusing to reconfigure device vfb:%d' % devid)
|
||||
|
||||
def destroyDevice(self, devid, force):
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
# remove the backend xenstore entries for HVM guests no matter
|
||||
# what
|
||||
DevController.destroyDevice(self, devid, True)
|
||||
@@ -119,7 +119,7 @@ class VfbifController(DevController):
|
||||
|
||||
|
||||
def migrate(self, deviceConfig, network, dst, step, domName):
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
return 0
|
||||
return DevController.migrate(self, deviceConfig, network, dst, step,
|
||||
domName)
|
||||
@@ -136,14 +136,14 @@ class VkbdifController(DevController):
|
||||
return (devid, back, front)
|
||||
|
||||
def waitForDevice(self, config):
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
# is a qemu-dm managed device, don't wait for hotplug for these.
|
||||
return
|
||||
|
||||
DevController.waitForDevice(self, config)
|
||||
|
||||
def destroyDevice(self, devid, force):
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
# remove the backend xenstore entries for HVM guests no matter
|
||||
# what
|
||||
DevController.destroyDevice(self, devid, True)
|
||||
@@ -151,7 +151,7 @@ class VkbdifController(DevController):
|
||||
DevController.destroyDevice(self, devid, force)
|
||||
|
||||
def migrate(self, deviceConfig, network, dst, step, domName):
|
||||
if self.vm.info.get('HVM_boot'):
|
||||
if self.vm.info.get('HVM_boot_policy'):
|
||||
return 0
|
||||
return DevController.migrate(self, deviceConfig, network, dst, step,
|
||||
domName)
|
||||
@@ -19,7 +19,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Xen-xm 3.0\n"
|
||||
"PO-Revision-Date: 2007-01-30 17:15+0000\n"
|
||||
"PO-Revision-Date: 2007-01-31 12:34+0000\n"
|
||||
"Last-Translator: Ewan Mellor <ewan@xensource.com>\n"
|
||||
"Language-Team: xen-devel <xen-devel@lists.xensource.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -41,6 +41,9 @@ msgstr "The method %(1)s takes %(2)s argument(s) (%(3)s given)."
|
||||
msgid "SESSION_AUTHENTICATION_FAILED"
|
||||
msgstr "Permission denied."
|
||||
|
||||
msgid "VALUE_NOT_SUPPORTED"
|
||||
msgstr "Value \"%(2)s\" for %(1)s is not supported by this server. The server said \"%(3)s\"."
|
||||
|
||||
msgid "HOST_CPU_HANDLE_INVALID"
|
||||
msgstr "The host_cpu handle %(1)s is invalid."
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ int main(int argc, char **argv)
|
||||
usize = xc_dom_check_gzip(image, st.st_size);
|
||||
if (usize)
|
||||
{
|
||||
tmp = malloc(size);
|
||||
xc_dom_do_gunzip(image, st.st_size, tmp, size);
|
||||
tmp = malloc(usize);
|
||||
xc_dom_do_gunzip(image, st.st_size, tmp, usize);
|
||||
image = tmp;
|
||||
size = usize;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,12 @@ AC_PROG_CC
|
||||
#AC_PROG_INSTALL
|
||||
AC_CHECK_PROG([LILO], lilo, lilo, "no", [$PATH])
|
||||
|
||||
XEN_PYTHON_PATH=$(/usr/sbin/xen-python-path)
|
||||
|
||||
# Right now, we can assume that the lib/ directory
|
||||
# is two levels above the tests
|
||||
TESTLIB=../../lib
|
||||
TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB"
|
||||
TENV="PYTHONPATH=$PYTHONPATH:$TESTLIB:$XEN_PYTHON_PATH"
|
||||
|
||||
AC_ARG_ENABLE(hvm-support,
|
||||
[[ --enable-hvm-support enable hardware virtual machine assist]],
|
||||
|
||||
@@ -33,6 +33,9 @@ from DomainTracking import *
|
||||
from acm import *
|
||||
|
||||
|
||||
DOM0_UUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def getDefaultKernel():
|
||||
return arch.getDefaultKernel()
|
||||
|
||||
|
||||
@@ -3,26 +3,6 @@
|
||||
# Author: Dan Smith <danms@us.ibm.com>
|
||||
#
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
# Use the auxbin module in Xend to determine the correct Python path. We
|
||||
# take the first installed instance of auxbin that we find, and then run it
|
||||
# to determine the correct path, appending that to sys.path.
|
||||
|
||||
AUXBIN = 'xen/util/auxbin.py'
|
||||
|
||||
for p in ['python%s' % sys.version[:3], 'python']:
|
||||
for l in ['/usr/lib64', '/usr/lib']:
|
||||
d = os.path.join(l, p)
|
||||
if os.path.exists(os.path.join(d, AUXBIN)):
|
||||
sys.path.append(d)
|
||||
import xen.util.auxbin
|
||||
libpath = xen.util.auxbin.libpath()
|
||||
sys.path = sys.path[:-1]
|
||||
sys.path.append(libpath)
|
||||
break
|
||||
|
||||
from Console import *
|
||||
from Test import *
|
||||
from Xm import *
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
from XmTestLib import xapi
|
||||
from XmTestLib.XenAPIDomain import XmTestAPIDomain
|
||||
from XmTestLib import *
|
||||
from xen.xend import XendDomain
|
||||
from vtpm_utils import *
|
||||
import commands
|
||||
import os
|
||||
@@ -28,7 +27,7 @@ except Exception, e:
|
||||
vm_uuid = domain.get_uuid()
|
||||
|
||||
vtpmcfg = {}
|
||||
vtpmcfg['backend'] = XendDomain.DOM0_UUID
|
||||
vtpmcfg['backend'] = DOM0_UUID
|
||||
vtpmcfg['VM'] = vm_uuid
|
||||
|
||||
session = xapi.connect()
|
||||
|
||||
@@ -159,7 +159,7 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
|
||||
return;
|
||||
dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
|
||||
if(dmi_ident[slot])
|
||||
safe_strcpy(dmi_ident[slot], p);
|
||||
strlcpy(dmi_ident[slot], p, strlen(p)+1);
|
||||
else
|
||||
printk(KERN_ERR "dmi_save_ident: out of memory.\n");
|
||||
}
|
||||
|
||||
+32
-30
@@ -288,71 +288,73 @@ long arch_do_domctl(
|
||||
|
||||
case XEN_DOMCTL_sethvmcontext:
|
||||
{
|
||||
struct hvm_domain_context *c;
|
||||
struct hvm_domain_context c;
|
||||
struct domain *d;
|
||||
|
||||
c.cur = 0;
|
||||
c.size = domctl->u.hvmcontext.size;
|
||||
c.data = NULL;
|
||||
|
||||
ret = -ESRCH;
|
||||
if ( (d = get_domain_by_id(domctl->domain)) == NULL )
|
||||
break;
|
||||
|
||||
ret = -ENOMEM;
|
||||
if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
|
||||
goto sethvmcontext_out;
|
||||
|
||||
ret = -EFAULT;
|
||||
if ( copy_from_guest(c, domctl->u.hvmcontext.ctxt, 1) != 0 )
|
||||
goto sethvmcontext_out;
|
||||
c->size = sizeof (c->data);
|
||||
c->cur = 0;
|
||||
|
||||
ret = -EINVAL;
|
||||
if ( !is_hvm_domain(d) )
|
||||
goto sethvmcontext_out;
|
||||
|
||||
ret = hvm_load(d, c);
|
||||
ret = -ENOMEM;
|
||||
if ( (c.data = xmalloc_bytes(c.size)) == NULL )
|
||||
goto sethvmcontext_out;
|
||||
|
||||
xfree(c);
|
||||
ret = -EFAULT;
|
||||
if ( copy_from_guest(c.data, domctl->u.hvmcontext.buffer, c.size) != 0)
|
||||
goto sethvmcontext_out;
|
||||
|
||||
ret = hvm_load(d, &c);
|
||||
|
||||
sethvmcontext_out:
|
||||
put_domain(d);
|
||||
if ( c.data != NULL )
|
||||
xfree(c.data);
|
||||
|
||||
put_domain(d);
|
||||
}
|
||||
break;
|
||||
|
||||
case XEN_DOMCTL_gethvmcontext:
|
||||
{
|
||||
struct hvm_domain_context *c;
|
||||
struct hvm_domain_context c;
|
||||
struct domain *d;
|
||||
|
||||
c.cur = 0;
|
||||
c.size = domctl->u.hvmcontext.size;
|
||||
c.data = NULL;
|
||||
|
||||
ret = -ESRCH;
|
||||
if ( (d = get_domain_by_id(domctl->domain)) == NULL )
|
||||
break;
|
||||
|
||||
ret = -ENOMEM;
|
||||
if ( (c = xmalloc(struct hvm_domain_context)) == NULL )
|
||||
goto gethvmcontext_out;
|
||||
memset(c, 0, sizeof(*c));
|
||||
c->size = sizeof (c->data);
|
||||
|
||||
ret = -ENODATA;
|
||||
ret = -EINVAL;
|
||||
if ( !is_hvm_domain(d) )
|
||||
goto gethvmcontext_out;
|
||||
|
||||
ret = 0;
|
||||
if (hvm_save(d, c) != 0)
|
||||
ret = -EFAULT;
|
||||
|
||||
if ( copy_to_guest(domctl->u.hvmcontext.ctxt, c, 1) )
|
||||
ret = -EFAULT;
|
||||
ret = -ENOMEM;
|
||||
if ( (c.data = xmalloc_bytes(c.size)) == NULL )
|
||||
goto gethvmcontext_out;
|
||||
|
||||
xfree(c);
|
||||
ret = hvm_save(d, &c);
|
||||
|
||||
if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 )
|
||||
ret = -EFAULT;
|
||||
|
||||
if ( copy_to_guest(u_domctl, domctl, 1) )
|
||||
ret = -EFAULT;
|
||||
|
||||
gethvmcontext_out:
|
||||
put_domain(d);
|
||||
if ( c.data != NULL )
|
||||
xfree(c.data);
|
||||
|
||||
put_domain(d);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+36
-6
@@ -279,7 +279,7 @@ static void hpet_write(
|
||||
(h->hpet.timers[tn].config & HPET_TN_SETVAL) )
|
||||
h->hpet.timers[tn].cmp = new_val;
|
||||
else
|
||||
h->period[tn] = new_val;
|
||||
h->hpet.period[tn] = new_val;
|
||||
h->hpet.timers[tn].config &= ~HPET_TN_SETVAL;
|
||||
if ( hpet_enabled(h) && timer_enabled(h, tn) )
|
||||
hpet_set_timer(h, tn);
|
||||
@@ -289,7 +289,7 @@ static void hpet_write(
|
||||
case HPET_T1_ROUTE:
|
||||
case HPET_T2_ROUTE:
|
||||
tn = (addr - HPET_T0_ROUTE) >> 5;
|
||||
h->hpet.timers[tn].hpet_fsb[0] = new_val;
|
||||
h->hpet.timers[tn].fsb = new_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -351,21 +351,22 @@ static void hpet_timer_fn(void *opaque)
|
||||
|
||||
hpet_route_interrupt(h, tn);
|
||||
|
||||
if ( timer_is_periodic(h, tn) && (h->period[tn] != 0) )
|
||||
if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) )
|
||||
{
|
||||
uint64_t mc = hpet_read_maincounter(h);
|
||||
if ( timer_is_32bit(h, tn) )
|
||||
{
|
||||
while ( hpet_time_after(mc, h->hpet.timers[tn].cmp) )
|
||||
h->hpet.timers[tn].cmp = (uint32_t)(
|
||||
h->hpet.timers[tn].cmp + h->period[tn]);
|
||||
h->hpet.timers[tn].cmp + h->hpet.period[tn]);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( hpet_time_after64(mc, h->hpet.timers[tn].cmp) )
|
||||
h->hpet.timers[tn].cmp += h->period[tn];
|
||||
h->hpet.timers[tn].cmp += h->hpet.period[tn];
|
||||
}
|
||||
set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn]));
|
||||
set_timer(&h->timers[tn],
|
||||
NOW() + hpet_tick_to_ns(h, h->hpet.period[tn]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,6 +379,35 @@ void hpet_migrate_timers(struct vcpu *v)
|
||||
migrate_timer(&h->timers[i], v->processor);
|
||||
}
|
||||
|
||||
static int hpet_save(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
|
||||
|
||||
/* Save the HPET registers */
|
||||
return hvm_save_entry(HPET, 0, h, &hp->hpet);
|
||||
}
|
||||
|
||||
static int hpet_load(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
|
||||
int i;
|
||||
|
||||
/* Reload the HPET registers */
|
||||
if ( hvm_load_entry(HPET, h, &hp->hpet) )
|
||||
return -EINVAL;
|
||||
|
||||
/* Recalculate the offset between the main counter and guest time */
|
||||
hp->mc_offset = hp->hpet.mc64 - hvm_get_guest_time(hp->vcpu);
|
||||
|
||||
/* Restart the timers */
|
||||
for ( i = 0; i < HPET_TIMER_NUM; i++ )
|
||||
hpet_set_timer(hp, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load);
|
||||
|
||||
void hpet_init(struct vcpu *v)
|
||||
{
|
||||
HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
|
||||
|
||||
@@ -205,7 +205,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
|
||||
if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
|
||||
{
|
||||
gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
|
||||
return -1;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Save all available kinds of state */
|
||||
@@ -219,7 +219,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
gdprintk(XENLOG_ERR,
|
||||
"HVM save: failed to save type %"PRIu16"\n", i);
|
||||
return -1;
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,7 +229,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
/* Run out of data */
|
||||
gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
|
||||
return -1;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Save macros should not have let us overrun */
|
||||
|
||||
@@ -660,6 +660,13 @@ void svm_update_guest_cr3(struct vcpu *v)
|
||||
v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
|
||||
}
|
||||
|
||||
static void svm_update_vtpr(struct vcpu *v, unsigned long value)
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
vmcb->vintr.fields.tpr = value & 0x0f;
|
||||
}
|
||||
|
||||
unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
|
||||
{
|
||||
switch ( num )
|
||||
@@ -1048,6 +1055,8 @@ int start_svm(void)
|
||||
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
|
||||
hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
|
||||
|
||||
hvm_funcs.update_vtpr = svm_update_vtpr;
|
||||
|
||||
hvm_funcs.stts = svm_stts;
|
||||
hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
|
||||
|
||||
@@ -1939,6 +1948,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
|
||||
|
||||
case 8:
|
||||
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
|
||||
vmcb->vintr.fields.tpr = value & 0x0F;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -593,6 +593,7 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
|
||||
{
|
||||
case APIC_TASKPRI:
|
||||
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
|
||||
hvm_update_vtpr(v, (val >> 4) & 0x0f);
|
||||
break;
|
||||
|
||||
case APIC_EOI:
|
||||
|
||||
@@ -986,6 +986,11 @@ static void vmx_inject_exception(
|
||||
v->arch.hvm_vmx.cpu_cr2 = cr2;
|
||||
}
|
||||
|
||||
static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
|
||||
{
|
||||
/* VMX doesn't have a V_TPR field */
|
||||
}
|
||||
|
||||
/* Setup HVM interfaces */
|
||||
static void vmx_setup_hvm_funcs(void)
|
||||
{
|
||||
@@ -1011,6 +1016,8 @@ static void vmx_setup_hvm_funcs(void)
|
||||
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
|
||||
hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
|
||||
|
||||
hvm_funcs.update_vtpr = vmx_update_vtpr;
|
||||
|
||||
hvm_funcs.stts = vmx_stts;
|
||||
hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
|
||||
|
||||
|
||||
@@ -597,6 +597,11 @@ static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
|
||||
if ( !IS_PRIV(current->domain) )
|
||||
clear_bit(X86_FEATURE_MTRR, &d);
|
||||
}
|
||||
else if ( regs->eax == 0x80000001 )
|
||||
{
|
||||
/* Modify Feature Information. */
|
||||
clear_bit(X86_FEATURE_RDTSCP % 32, &d);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d);
|
||||
|
||||
@@ -281,9 +281,6 @@ CFIX14:
|
||||
.quad CFLT14,CFIX14
|
||||
.previous
|
||||
|
||||
compat_domctl:
|
||||
compat_sysctl:
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
ENTRY(compat_hypercall_table)
|
||||
@@ -365,8 +362,8 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 2 /* compat_event_channel_op */
|
||||
.byte 2 /* compat_physdev_op */
|
||||
.byte 2 /* do_hvm_op */
|
||||
.byte 1 /* compat_sysctl */ /* 35 */
|
||||
.byte 1 /* compat_domctl */
|
||||
.byte 1 /* do_sysctl */ /* 35 */
|
||||
.byte 1 /* do_domctl */
|
||||
.byte 2 /* compat_kexec_op */
|
||||
.rept NR_hypercalls-(.-compat_hypercall_args_table)
|
||||
.byte 0 /* compat_ni_hypercall */
|
||||
|
||||
+16
-7
@@ -131,12 +131,20 @@ __initcall(register_crashdump_trigger);
|
||||
|
||||
static void setup_note(Elf_Note *n, const char *name, int type, int descsz)
|
||||
{
|
||||
safe_strcpy(ELFNOTE_NAME(n), name);
|
||||
n->namesz = strlen(name);
|
||||
int l = strlen(name) + 1;
|
||||
strlcpy(ELFNOTE_NAME(n), name, l);
|
||||
n->namesz = l;
|
||||
n->descsz = descsz;
|
||||
n->type = type;
|
||||
}
|
||||
|
||||
static int sizeof_note(const char *name, int descsz)
|
||||
{
|
||||
return (sizeof(Elf_Note) +
|
||||
ELFNOTE_ALIGN(strlen(name)+1) +
|
||||
ELFNOTE_ALIGN(descsz));
|
||||
}
|
||||
|
||||
#define kexec_get(x) kexec_get_##x
|
||||
|
||||
#endif
|
||||
@@ -155,23 +163,24 @@ static int kexec_get(reserve)(xen_kexec_range_t *range)
|
||||
static int kexec_get(xen)(xen_kexec_range_t *range)
|
||||
{
|
||||
range->start = virt_to_maddr(_start);
|
||||
range->size = (unsigned long)_end - (unsigned long)_start;
|
||||
range->size = (unsigned long)xenheap_phys_end - (unsigned long)range->start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kexec_get(cpu)(xen_kexec_range_t *range)
|
||||
{
|
||||
int nr = range->nr;
|
||||
int nr_bytes = sizeof(Elf_Note) * 2
|
||||
+ ELFNOTE_ALIGN(sizeof(ELF_Prstatus))
|
||||
+ ELFNOTE_ALIGN(sizeof(crash_xen_core_t));
|
||||
int nr_bytes = 0;
|
||||
|
||||
if ( nr < 0 || nr >= num_present_cpus() )
|
||||
return -EINVAL;
|
||||
|
||||
nr_bytes += sizeof_note("CORE", sizeof(ELF_Prstatus));
|
||||
nr_bytes += sizeof_note("Xen", sizeof(crash_xen_core_t));
|
||||
|
||||
/* The Xen info note is included in CPU0's range. */
|
||||
if ( nr == 0 )
|
||||
nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t));
|
||||
nr_bytes += sizeof_note("Xen", sizeof(crash_xen_info_t));
|
||||
|
||||
if ( per_cpu(crash_notes, nr) == NULL )
|
||||
{
|
||||
|
||||
+13
-4
@@ -136,8 +136,8 @@ static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS];
|
||||
static xen_sysctl_perfc_val_t *perfc_vals;
|
||||
static int perfc_nbr_vals;
|
||||
static int perfc_init = 0;
|
||||
static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
|
||||
XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
|
||||
static int perfc_copy_info(XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc,
|
||||
XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int v = 0;
|
||||
@@ -217,20 +217,29 @@ static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
|
||||
int perfc_control(xen_sysctl_perfc_op_t *pc)
|
||||
{
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc;
|
||||
XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* 64 bit guest handles cannot be passed as parameters to
|
||||
* functions so cast to a regular guest handle.
|
||||
*/
|
||||
desc = guest_handle_cast(pc->desc, xen_sysctl_perfc_desc_t);
|
||||
val = guest_handle_cast(pc->val, xen_sysctl_perfc_val_t);
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
switch ( pc->cmd )
|
||||
{
|
||||
case XEN_SYSCTL_PERFCOP_reset:
|
||||
perfc_copy_info(pc->desc, pc->val);
|
||||
perfc_copy_info(desc, val);
|
||||
perfc_reset(0);
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
case XEN_SYSCTL_PERFCOP_query:
|
||||
perfc_copy_info(pc->desc, pc->val);
|
||||
perfc_copy_info(desc, val);
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#define X86_FEATURE_MP (1*32+19) /* MP Capable. */
|
||||
#define X86_FEATURE_NX (1*32+20) /* Execute Disable */
|
||||
#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
|
||||
#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */
|
||||
#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
|
||||
#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
|
||||
#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
|
||||
|
||||
@@ -49,8 +49,6 @@ struct hvm_domain {
|
||||
spinlock_t pbuf_lock;
|
||||
|
||||
uint64_t params[HVM_NR_PARAMS];
|
||||
|
||||
struct hvm_domain_context *hvm_ctxt;
|
||||
};
|
||||
|
||||
#endif /* __ASM_X86_HVM_DOMAIN_H__ */
|
||||
|
||||
@@ -114,6 +114,11 @@ struct hvm_function_table {
|
||||
*/
|
||||
void (*update_guest_cr3)(struct vcpu *v);
|
||||
|
||||
/*
|
||||
* Reflect the virtual APIC's value in the guest's V_TPR register
|
||||
*/
|
||||
void (*update_vtpr)(struct vcpu *v, unsigned long value);
|
||||
|
||||
/*
|
||||
* Update specifics of the guest state:
|
||||
* 1) TS bit in guest cr0
|
||||
@@ -203,6 +208,12 @@ hvm_update_host_cr3(struct vcpu *v)
|
||||
hvm_funcs.update_host_cr3(v);
|
||||
}
|
||||
|
||||
static inline void
|
||||
hvm_update_vtpr(struct vcpu *v, unsigned long value)
|
||||
{
|
||||
hvm_funcs.update_vtpr(v, value);
|
||||
}
|
||||
|
||||
void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
|
||||
|
||||
void hvm_hypercall_page_initialise(struct domain *d,
|
||||
|
||||
@@ -123,6 +123,13 @@ extern unsigned int opt_hvm_debug_level;
|
||||
* Save/restore support
|
||||
*/
|
||||
|
||||
/* Marshalling and unmarshalling uses a buffer with size and cursor. */
|
||||
typedef struct hvm_domain_context {
|
||||
uint32_t cur;
|
||||
uint32_t size;
|
||||
uint8_t *data;
|
||||
} hvm_domain_context_t;
|
||||
|
||||
/* Marshalling an entry: check space and fill in the header */
|
||||
static inline int _hvm_init_entry(struct hvm_domain_context *h,
|
||||
uint16_t tc, uint16_t inst, uint32_t len)
|
||||
|
||||
@@ -31,22 +31,6 @@
|
||||
#include <asm/hvm/vpic.h>
|
||||
#include <public/hvm/save.h>
|
||||
|
||||
#define HPET_TIMER_NUM 3 /* 3 timers supported now */
|
||||
struct HPET {
|
||||
uint64_t capability; /* capabilities */
|
||||
uint64_t res0; /* reserved */
|
||||
uint64_t config; /* configuration */
|
||||
uint64_t res1; /* reserved */
|
||||
uint64_t isr; /* interrupt status reg */
|
||||
uint64_t res2[25]; /* reserved */
|
||||
uint64_t mc64; /* main counter */
|
||||
uint64_t res3; /* reserved */
|
||||
struct { /* timers */
|
||||
uint64_t config; /* configuration/cap */
|
||||
uint64_t cmp; /* comparator */
|
||||
uint64_t hpet_fsb[2]; /* FSB route, not supported now */
|
||||
} timers[HPET_TIMER_NUM];
|
||||
};
|
||||
|
||||
struct HPETState;
|
||||
struct HPET_timer_fn_info {
|
||||
@@ -55,11 +39,10 @@ struct HPET_timer_fn_info {
|
||||
};
|
||||
|
||||
typedef struct HPETState {
|
||||
struct HPET hpet;
|
||||
struct vcpu *vcpu;
|
||||
uint64_t tsc_freq;
|
||||
uint64_t mc_offset;
|
||||
uint64_t period[HPET_TIMER_NUM];
|
||||
struct hvm_hw_hpet hpet;
|
||||
struct vcpu *vcpu;
|
||||
uint64_t tsc_freq;
|
||||
uint64_t mc_offset;
|
||||
struct timer timers[HPET_TIMER_NUM];
|
||||
struct HPET_timer_fn_info timer_fn_info[HPET_TIMER_NUM];
|
||||
} HPETState;
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
(hnd).p = val; \
|
||||
} while ( 0 )
|
||||
#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
|
||||
#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
|
||||
#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name __attribute__((aligned(8)))
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@@ -386,18 +386,11 @@ struct xen_domctl_settimeoffset {
|
||||
typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
|
||||
|
||||
#define HVM_CTXT_SIZE 8192
|
||||
typedef struct hvm_domain_context {
|
||||
uint32_t cur;
|
||||
uint32_t size;
|
||||
uint8_t data[HVM_CTXT_SIZE];
|
||||
} hvm_domain_context_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(hvm_domain_context_t);
|
||||
|
||||
#define XEN_DOMCTL_gethvmcontext 33
|
||||
#define XEN_DOMCTL_sethvmcontext 34
|
||||
typedef struct xen_domctl_hvmcontext {
|
||||
XEN_GUEST_HANDLE_64(hvm_domain_context_t) ctxt; /* IN/OUT */
|
||||
uint32_t size; /* IN/OUT: size of buffer / bytes filled */
|
||||
XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT */
|
||||
} xen_domctl_hvmcontext_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t);
|
||||
|
||||
|
||||
@@ -13,9 +13,16 @@ clean:
|
||||
rm -f checker checker.c $(XEN_TARGET_ARCH).size
|
||||
rm -f *.pyc *.o *~
|
||||
|
||||
ifeq ($(CROSS_COMPILE),)
|
||||
check-headers: checker
|
||||
./checker > $(XEN_TARGET_ARCH).size
|
||||
diff -u reference.size $(XEN_TARGET_ARCH).size
|
||||
checker: checker.c $(headers)
|
||||
$(HOSTCC) $(CFLAGS) -o $@ $<
|
||||
else
|
||||
check-headers:
|
||||
@echo "cross build: skipping check"
|
||||
endif
|
||||
|
||||
x86_32.h: ../arch-x86/xen-x86_32.h ../arch-x86/xen.h ../xen.h $(scripts)
|
||||
python mkheader.py $* $@ $(filter %.h,$^)
|
||||
@@ -26,8 +33,5 @@ x86_64.h: ../arch-x86/xen-x86_64.h ../arch-x86/xen.h ../xen.h $(scripts)
|
||||
ia64.h: ../arch-ia64.h ../xen.h $(scripts)
|
||||
python mkheader.py $* $@ $(filter %.h,$^)
|
||||
|
||||
checker: checker.c $(headers)
|
||||
$(HOSTCC) $(CFLAGS) -o $@ $<
|
||||
|
||||
checker.c: $(scripts)
|
||||
python mkchecker.py $(XEN_TARGET_ARCH) $@ $(architectures)
|
||||
@@ -381,10 +381,40 @@ struct hvm_hw_rtc {
|
||||
DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm_hw_rtc);
|
||||
|
||||
|
||||
/*
|
||||
* HPET
|
||||
*/
|
||||
|
||||
#define HPET_TIMER_NUM 3 /* 3 timers supported now */
|
||||
struct hvm_hw_hpet {
|
||||
/* Memory-mapped, software visible registers */
|
||||
uint64_t capability; /* capabilities */
|
||||
uint64_t res0; /* reserved */
|
||||
uint64_t config; /* configuration */
|
||||
uint64_t res1; /* reserved */
|
||||
uint64_t isr; /* interrupt status reg */
|
||||
uint64_t res2[25]; /* reserved */
|
||||
uint64_t mc64; /* main counter */
|
||||
uint64_t res3; /* reserved */
|
||||
struct { /* timers */
|
||||
uint64_t config; /* configuration/cap */
|
||||
uint64_t cmp; /* comparator */
|
||||
uint64_t fsb; /* FSB route, not supported now */
|
||||
uint64_t res4; /* reserved */
|
||||
} timers[HPET_TIMER_NUM];
|
||||
uint64_t res5[4*(24-HPET_TIMER_NUM)]; /* reserved, up to 0x3ff */
|
||||
|
||||
/* Hidden register state */
|
||||
uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
|
||||
};
|
||||
|
||||
DECLARE_HVM_SAVE_TYPE(HPET, 10, struct hvm_hw_hpet);
|
||||
|
||||
|
||||
/*
|
||||
* Largest type-code in use
|
||||
*/
|
||||
#define HVM_SAVE_CODE_MAX 9
|
||||
#define HVM_SAVE_CODE_MAX 10
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -82,8 +82,16 @@ extern void * memchr(const void *,int,__kernel_size_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define is_char_array(x) __builtin_types_compatible_p(typeof(x), char[])
|
||||
|
||||
/* safe_xxx always NUL-terminates and returns !=0 if result is truncated. */
|
||||
#define safe_strcpy(d, s) (strlcpy(d, s, sizeof(d)) >= sizeof(d))
|
||||
#define safe_strcat(d, s) (strlcat(d, s, sizeof(d)) >= sizeof(d))
|
||||
#define safe_strcpy(d, s) ({ \
|
||||
BUILD_BUG_ON(!is_char_array(d)); \
|
||||
(strlcpy(d, s, sizeof(d)) >= sizeof(d)); \
|
||||
})
|
||||
#define safe_strcat(d, s) ({ \
|
||||
BUILD_BUG_ON(!is_char_array(d)); \
|
||||
(strlcat(d, s, sizeof(d)) >= sizeof(d)); \
|
||||
})
|
||||
|
||||
#endif /* _LINUX_STRING_H_ */
|
||||
@@ -227,7 +227,7 @@ handle_array() {
|
||||
|
||||
build_body() {
|
||||
echo
|
||||
echo -n "#define XLAT_$1(_d_, _s_)"
|
||||
echo -n "#define XLAT_$1(_d_, _s_) do {"
|
||||
local level=1 fields= id= array= arrlvl=1 array_type= type= token
|
||||
for token in $2
|
||||
do
|
||||
@@ -303,6 +303,8 @@ build_body() {
|
||||
esac
|
||||
test -z "$fields" || fields="$fields $token"
|
||||
done
|
||||
echo " \\"
|
||||
echo "} while (0)"
|
||||
echo ""
|
||||
}
|
||||
|
||||
|
||||