[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Implement new booting parameters for Xen-API, and backwards compatibility for



# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Node ID 0ee4e33b4401be41ba3a30811eeefe05ae2aca3b
# Parent  da0849b741707e07723f97f7b3fc4b16a88636da
Implement new booting parameters for Xen-API, and backwards compatibility for
the old bootloader settings.

We now have two mutually exclusive config groups HVM and PV, with HVM/boot
and PV/{bootloader,kernel,ramdisk,args,bootloader_args}.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
---
 tools/libxen/include/xen_vm.h           |  223 ++++++++--------
 tools/libxen/src/xen_vm.c               |  421 ++++++++++++++------------------
 tools/python/xen/xend/XendAPI.py        |  149 +++++------
 tools/python/xen/xend/XendBootloader.py |   17 -
 tools/python/xen/xend/XendConfig.py     |   81 +-----
 tools/python/xen/xend/XendDomainInfo.py |  164 +++++++-----
 tools/python/xen/xend/image.py          |   13 
 7 files changed, 518 insertions(+), 550 deletions(-)

diff -r da0849b74170 -r 0ee4e33b4401 tools/libxen/include/xen_vm.h
--- a/tools/libxen/include/xen_vm.h     Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/libxen/include/xen_vm.h     Thu Dec 14 18:24:14 2006 +0000
@@ -19,7 +19,6 @@
 #ifndef XEN_VM_H
 #define XEN_VM_H
 
-#include "xen_boot_type.h"
 #include "xen_common.h"
 #include "xen_console_decl.h"
 #include "xen_cpu_feature.h"
@@ -36,9 +35,36 @@
 
 
 /*
- * The VM class. 
- *  
+ * The VM class.
+ * 
  * 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.
+ * 
+ * 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
+ * default installation of pygrub will be used, or a full path within the
+ * control domain to some other bootloader.  The other fields, PV/kernel,
+ * PV/ramdisk, PV/args and PV/bootloader_args will be passed to the bootloader
+ * unmodified, and interpretation of those fields is then specific to the
+ * bootloader itself, including the possibility that the bootloader will
+ * ignore some or all of those given values.
+ * 
+ * If the bootloader is pygrub, then the menu.lst is parsed if present in the
+ * guest's filesystem, otherwise the specified kernel and ramdisk are used, or
+ * an autodetected kernel is used if nothing is specified and autodetection is
+ * possible.  PV/args is appended to the kernel command line, no matter which
+ * mechanism is used for finding the kernel.
+ * 
+ * If PV/bootloader is empty but PV/kernel is specified, then the kernel and
+ * 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.
  */
 
 
@@ -102,18 +128,17 @@ typedef struct xen_vm_record
     struct xen_vif_record_opt_set *vifs;
     struct xen_vbd_record_opt_set *vbds;
     struct xen_vtpm_record_opt_set *vtpms;
-    char *bios_boot;
+    char *pv_bootloader;
+    char *pv_kernel;
+    char *pv_ramdisk;
+    char *pv_args;
+    char *pv_bootloader_args;
+    char *hvm_boot;
     bool platform_std_vga;
     char *platform_serial;
     bool platform_localtime;
     bool platform_clock_offset;
     bool platform_enable_audio;
-    char *builder;
-    enum xen_boot_type boot_method;
-    char *kernel_kernel;
-    char *kernel_initrd;
-    char *kernel_args;
-    char *grub_cmdline;
     char *pci_bus;
     xen_string_string_map *tools_version;
     xen_string_string_map *otherconfig;
@@ -439,10 +464,45 @@ xen_vm_get_vtpms(xen_session *session, s
 
 
 /**
- * Get the bios/boot field of the given VM.
- */
-extern bool
-xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm);
+ * Get the PV/bootloader field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/kernel field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/ramdisk field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/args field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/bootloader_args field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the HVM/boot field of the given VM.
+ */
+extern bool
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm);
 
 
 /**
@@ -478,48 +538,6 @@ xen_vm_get_platform_clock_offset(xen_ses
  */
 extern bool
 xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm 
vm);
-
-
-/**
- * Get the builder field of the given VM.
- */
-extern bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the boot_method field of the given VM.
- */
-extern bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, 
xen_vm vm);
-
-
-/**
- * Get the kernel/kernel field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the kernel/initrd field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the kernel/args field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the grub/cmdline field of the given VM.
- */
-extern bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm);
 
 
 /**
@@ -688,10 +706,45 @@ xen_vm_set_actions_after_crash(xen_sessi
 
 
 /**
- * Set the bios/boot field of the given VM.
- */
-extern bool
-xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot);
+ * Set the PV/bootloader field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader);
+
+
+/**
+ * Set the PV/kernel field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel);
+
+
+/**
+ * Set the PV/ramdisk field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk);
+
+
+/**
+ * Set the PV/args field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args);
+
+
+/**
+ * Set the PV/bootloader_args field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char 
*bootloader_args);
+
+
+/**
+ * Set the HVM/boot field of the given VM.
+ */
+extern bool
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
 
 
 /**
@@ -727,48 +780,6 @@ xen_vm_set_platform_clock_offset(xen_ses
  */
 extern bool
 xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool 
enable_audio);
-
-
-/**
- * Set the builder field of the given VM.
- */
-extern bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder);
-
-
-/**
- * Set the boot_method field of the given VM.
- */
-extern bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type 
boot_method);
-
-
-/**
- * Set the kernel/kernel field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel);
-
-
-/**
- * Set the kernel/initrd field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd);
-
-
-/**
- * Set the kernel/args field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args);
-
-
-/**
- * Set the grub/cmdline field of the given VM.
- */
-extern bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline);
 
 
 /**
@@ -814,8 +825,8 @@ xen_vm_unpause(xen_session *session, xen
 
 /**
  * Attempt to cleanly shutdown the specified VM. (Note: this may not be
- * supported---e.g. if a guest agent is not installed). 
- *  
+ * supported---e.g. if a guest agent is not installed).
+ * 
  * Once shutdown has been completed perform poweroff action specified in guest
  * configuration.
  */
@@ -825,8 +836,8 @@ xen_vm_clean_shutdown(xen_session *sessi
 
 /**
  * Attempt to cleanly shutdown the specified VM (Note: this may not be
- * supported---e.g. if a guest agent is not installed). 
- *  
+ * supported---e.g. if a guest agent is not installed).
+ * 
  * Once shutdown has been completed perform reboot action specified in guest
  * configuration.
  */
diff -r da0849b74170 -r 0ee4e33b4401 tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/libxen/src/xen_vm.c Thu Dec 14 18:24:14 2006 +0000
@@ -20,7 +20,6 @@
 #include <stddef.h>
 #include <stdlib.h>
 
-#include "xen_boot_type_internal.h"
 #include "xen_common.h"
 #include "xen_console.h"
 #include "xen_cpu_feature.h"
@@ -136,9 +135,24 @@ static const struct_member xen_vm_record
         { .key = "VTPMs",
           .type = &abstract_type_ref_set,
           .offset = offsetof(xen_vm_record, vtpms) },
-        { .key = "bios_boot",
+        { .key = "PV_bootloader",
           .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, bios_boot) },
+          .offset = offsetof(xen_vm_record, pv_bootloader) },
+        { .key = "PV_kernel",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_kernel) },
+        { .key = "PV_ramdisk",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_ramdisk) },
+        { .key = "PV_args",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_args) },
+        { .key = "PV_bootloader_args",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, pv_bootloader_args) },
+        { .key = "HVM_boot",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vm_record, hvm_boot) },
         { .key = "platform_std_VGA",
           .type = &abstract_type_bool,
           .offset = offsetof(xen_vm_record, platform_std_vga) },
@@ -154,24 +168,6 @@ static const struct_member xen_vm_record
         { .key = "platform_enable_audio",
           .type = &abstract_type_bool,
           .offset = offsetof(xen_vm_record, platform_enable_audio) },
-        { .key = "builder",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, builder) },
-        { .key = "boot_method",
-          .type = &xen_boot_type_abstract_type_,
-          .offset = offsetof(xen_vm_record, boot_method) },
-        { .key = "kernel_kernel",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, kernel_kernel) },
-        { .key = "kernel_initrd",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, kernel_initrd) },
-        { .key = "kernel_args",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, kernel_args) },
-        { .key = "grub_cmdline",
-          .type = &abstract_type_string,
-          .offset = offsetof(xen_vm_record, grub_cmdline) },
         { .key = "PCI_bus",
           .type = &abstract_type_string,
           .offset = offsetof(xen_vm_record, pci_bus) },
@@ -216,13 +212,13 @@ xen_vm_record_free(xen_vm_record *record
     xen_vif_record_opt_set_free(record->vifs);
     xen_vbd_record_opt_set_free(record->vbds);
     xen_vtpm_record_opt_set_free(record->vtpms);
-    free(record->bios_boot);
+    free(record->pv_bootloader);
+    free(record->pv_kernel);
+    free(record->pv_ramdisk);
+    free(record->pv_args);
+    free(record->pv_bootloader_args);
+    free(record->hvm_boot);
     free(record->platform_serial);
-    free(record->builder);
-    free(record->kernel_kernel);
-    free(record->kernel_initrd);
-    free(record->kernel_args);
-    free(record->grub_cmdline);
     free(record->pci_bus);
     xen_string_string_map_free(record->tools_version);
     xen_string_string_map_free(record->otherconfig);
@@ -786,7 +782,7 @@ xen_vm_get_vtpms(xen_session *session, s
 
 
 bool
-xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm)
 {
     abstract_value param_values[] =
         {
@@ -797,7 +793,92 @@ xen_vm_get_bios_boot(xen_session *sessio
     abstract_type result_type = abstract_type_string;
 
     *result = NULL;
-    XEN_CALL_("VM.get_bios_boot");
+    XEN_CALL_("VM.get_PV_bootloader");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_kernel");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_ramdisk");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_args");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_PV_bootloader_args");
+    return session->ok;
+}
+
+
+bool
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm }
+        };
+
+    abstract_type result_type = abstract_type_string;
+
+    *result = NULL;
+    XEN_CALL_("VM.get_HVM_boot");
     return session->ok;
 }
 
@@ -879,108 +960,6 @@ xen_vm_get_platform_enable_audio(xen_ses
     abstract_type result_type = abstract_type_bool;
 
     XEN_CALL_("VM.get_platform_enable_audio");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_builder");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, 
xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = xen_boot_type_abstract_type_;
-    char *result_str = NULL;
-    XEN_CALL_("VM.get_boot_method");
-    *result = xen_boot_type_from_string(session, result_str);
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_kernel_kernel");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_kernel_initrd");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_kernel_args");
-    return session->ok;
-}
-
-
-bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm }
-        };
-
-    abstract_type result_type = abstract_type_string;
-
-    *result = NULL;
-    XEN_CALL_("VM.get_grub_cmdline");
     return session->ok;
 }
 
@@ -1357,7 +1336,87 @@ xen_vm_set_actions_after_crash(xen_sessi
 
 
 bool
-xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot)
+xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = bootloader }
+        };
+
+    xen_call_(session, "VM.set_PV_bootloader", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = kernel }
+        };
+
+    xen_call_(session, "VM.set_PV_kernel", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = ramdisk }
+        };
+
+    xen_call_(session, "VM.set_PV_ramdisk", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = args }
+        };
+
+    xen_call_(session, "VM.set_PV_args", param_values, 2, NULL, NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char 
*bootloader_args)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = vm },
+            { .type = &abstract_type_string,
+              .u.string_val = bootloader_args }
+        };
+
+    xen_call_(session, "VM.set_PV_bootloader_args", param_values, 2, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
 {
     abstract_value param_values[] =
         {
@@ -1367,7 +1426,7 @@ xen_vm_set_bios_boot(xen_session *sessio
               .u.string_val = boot }
         };
 
-    xen_call_(session, "VM.set_bios_boot", param_values, 2, NULL, NULL);
+    xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL);
     return session->ok;
 }
 
@@ -1453,102 +1512,6 @@ xen_vm_set_platform_enable_audio(xen_ses
 
 
 bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = builder }
-        };
-
-    xen_call_(session, "VM.set_builder", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type 
boot_method)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &xen_boot_type_abstract_type_,
-              .u.string_val = xen_boot_type_to_string(boot_method) }
-        };
-
-    xen_call_(session, "VM.set_boot_method", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = kernel }
-        };
-
-    xen_call_(session, "VM.set_kernel_kernel", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = initrd }
-        };
-
-    xen_call_(session, "VM.set_kernel_initrd", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = args }
-        };
-
-    xen_call_(session, "VM.set_kernel_args", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline)
-{
-    abstract_value param_values[] =
-        {
-            { .type = &abstract_type_string,
-              .u.string_val = vm },
-            { .type = &abstract_type_string,
-              .u.string_val = cmdline }
-        };
-
-    xen_call_(session, "VM.set_grub_cmdline", param_values, 2, NULL, NULL);
-    return session->ok;
-}
-
-
-bool
 xen_vm_set_otherconfig(xen_session *session, xen_vm vm, xen_string_string_map 
*otherconfig)
 {
     abstract_value param_values[] =
diff -r da0849b74170 -r 0ee4e33b4401 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Thu Dec 14 18:24:14 2006 +0000
@@ -118,11 +118,16 @@ def valid_vm(func):
     @param func: function with params: (self, session, vm_ref)
     @rtype: callable object
     """    
-    def check_vm_ref(self, session, vm_ref, *args, **kwargs):
+    def check_vm_ref(self, session, *args, **kwargs):
+        if len(args) == 0:
+            return {'Status': 'Failure',
+                    'ErrorDescription': XEND_ERROR_VM_INVALID}
+
+        vm_ref = args[0]
         xendom = XendDomain.instance()
         if type(vm_ref) == type(str()) and \
                xendom.is_valid_vm(vm_ref):
-            return func(self, session, vm_ref, *args, **kwargs)
+            return func(self, session, *args, **kwargs)
         else:
             return {'Status': 'Failure',
                     'ErrorDescription': XEND_ERROR_VM_INVALID}
@@ -590,19 +595,18 @@ class XendAPI:
                   'actions_after_reboot',
                   'actions_after_suspend',
                   'actions_after_crash',
-                  'bios_boot',
+                  'PV_bootloader',
+                  'PV_kernel',
+                  'PV_ramdisk',
+                  'PV_args',
+                  'PV_bootloader_args',
+                  'HVM_boot',
                   'platform_std_VGA',
                   'platform_serial',
                   'platform_localtime',
                   'platform_clock_offset',
                   'platform_enable_audio',
                   'platform_keymap',
-                  'builder',
-                  'boot_method',
-                  'kernel_kernel',
-                  'kernel_initrd',
-                  'kernel_args',
-                  'grub_cmdline',
                   'otherConfig']
 
     VM_methods = ['clone',
@@ -638,22 +642,30 @@ class XendAPI:
         'actions_after_reboot',
         'actions_after_suspend',
         'actions_after_crash',
-        'bios_boot',
+        'PV_bootloader',
+        'PV_kernel',
+        'PV_ramdisk',
+        'PV_args',
+        'PV_bootloader_args',
+        'HVM_boot',
         'platform_std_VGA',
         'platform_serial',
         'platform_localtime',
         'platform_clock_offset',
         'platform_enable_audio',
         'platform_keymap',
-        'builder',
-        'boot_method',
-        'kernel_kernel',
-        'kernel_initrd',
-        'kernel_args',
         'grub_cmdline',
         'PCI_bus',
         'otherConfig']
         
+    def VM_get(self, name, session, vm_ref):
+        return xen_api_success(
+            XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
+
+    def VM_set(self, name, session, vm_ref, value):
+        XendDomain.instance().get_vm_by_uuid(vm_ref).info[name] = value
+        return xen_api_success_void()
+
     # attributes (ro)
     def VM_get_power_state(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -767,9 +779,23 @@ class XendAPI:
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_on_crash())
     
-    def VM_get_bios_boot(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.get_bios_boot())
+    def VM_get_PV_bootloader(self, session, vm_ref):
+        return self.VM_get('PV_bootloader', session, vm_ref)
+    
+    def VM_get_PV_kernel(self, session, vm_ref):
+        return self.VM_get('PV_kernel', session, vm_ref)
+    
+    def VM_get_PV_ramdisk(self, session, vm_ref):
+        return self.VM_get('PV_ramdisk', session, vm_ref)
+    
+    def VM_get_PV_args(self, session, vm_ref):
+        return self.VM_get('PV_args', session, vm_ref)
+
+    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_platform_std_VGA(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -795,34 +821,10 @@ class XendAPI:
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo()
     
-    def VM_get_builder(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.get_builder())
-    
-    def VM_get_boot_method(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success(dom.get_boot_method())
-    
-    def VM_get_kernel_kernel(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def VM_get_kernel_initrd(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def VM_get_kernel_args(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
-    def VM_get_grub_cmdline(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success('')
-    
     def VM_get_otherConfig(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_todo()
-    
+
     def VM_set_name_label(self, session, vm_ref, label):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         dom.setName(label)
@@ -879,11 +881,25 @@ class XendAPI:
     def VM_set_actions_after_crash(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
-    
-    def VM_set_bios_boot(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
+
+    def VM_set_HVM_boot(self, session, vm_ref, value):
+        return self.VM_set('HVM_boot', session, vm_ref, value)
+
+    def VM_set_PV_bootloader(self, session, vm_ref, value):
+        return self.VM_set('PV_bootloader', session, vm_ref, value)
+
+    def VM_set_PV_kernel(self, session, vm_ref, value):
+        return self.VM_set('PV_kernel', session, vm_ref, value)
+
+    def VM_set_PV_ramdisk(self, session, vm_ref, value):
+        return self.VM_set('PV_ramdisk', session, vm_ref, value)
+
+    def VM_set_PV_args(self, session, vm_ref, value):
+        return self.VM_set('PV_args', session, vm_ref, value)
+
+    def VM_set_PV_bootloader_args(self, session, vm_ref, value):
+        return self.VM_set('PV_bootloader_args', session, vm_ref, value)
+
     def VM_set_platform_std_VGA(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
@@ -901,30 +917,6 @@ class XendAPI:
         return xen_api_success_void()
     
     def VM_set_platform_enable_audio(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_builder(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_boot_method(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_kernel_kernel(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_kernel_initrd(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_kernel_args(self, session, vm_ref):
-        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_success_void()
-    
-    def VM_set_grub_cmdline(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success_void()
     
@@ -986,19 +978,18 @@ class XendAPI:
             'VIFs': xeninfo.get_vifs(),
             'VBDs': xeninfo.get_vbds(),
             'VTPMs': xeninfo.get_vtpms(),
-            'bios_boot': xeninfo.get_bios_boot(),
+            'PV_bootloader': xeninfo.info.get('PV_bootloader'),
+            'PV_kernel': xeninfo.info.get('PV_kernel'),
+            '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'),
             'platform_std_VGA': xeninfo.get_platform_std_vga(),
             'platform_serial': xeninfo.get_platform_serial(),
             'platform_localtime': xeninfo.get_platform_localtime(),
             'platform_clock_offset': xeninfo.get_platform_clock_offset(),
             'platform_enable_audio': xeninfo.get_platform_enable_audio(),
             'platform_keymap': xeninfo.get_platform_keymap(),
-            'builder': xeninfo.get_builder(),
-            'boot_method': xeninfo.get_boot_method(),
-            'kernel_kernel': xeninfo.get_kernel_image(),
-            'kernel_initrd': xeninfo.get_kernel_initrd(),
-            'kernel_args': xeninfo.get_kernel_args(),
-            'grub_cmdline': xeninfo.get_grub_cmdline(),
             'PCI_bus': xeninfo.get_pci_bus(),
             'tools_version': xeninfo.get_tools_version(),
             'otherConfig': xeninfo.get_other_config()
diff -r da0849b74170 -r 0ee4e33b4401 tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py   Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/python/xen/xend/XendBootloader.py   Thu Dec 14 18:24:14 2006 +0000
@@ -21,7 +21,8 @@ from XendLogging import log
 from XendLogging import log
 from XendError import VmError
 
-def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
+def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '',
+               ramdisk = '', kernel_args = ''):
     """Run the boot loader executable on the given disk and return a
     config image.
     @param blexec  Binary to use as the boot loader
@@ -55,18 +56,19 @@ def bootloader(blexec, disk, quiet = 0, 
         if quiet:
             args.append("-q")
         args.append("--output=%s" % fifo)
-        if blargs is not None:
+        if blargs:
             args.extend(shlex.split(blargs))
         args.append(disk)
 
         try:
+            log.debug("Launching bootloader as %s." % str(args))
             os.execvp(args[0], args)
         except OSError, e:
             print e
             pass
         os._exit(1)
 
-    while 1:
+    while True:
         try:
             r = os.open(fifo, os.O_RDONLY)
         except OSError, e:
@@ -74,7 +76,7 @@ def bootloader(blexec, disk, quiet = 0, 
                 continue
         break
     ret = ""
-    while 1:
+    while True:
         select.select([r], [], [])
         s = os.read(r, 1024)
         ret = ret + s
@@ -94,9 +96,4 @@ def bootloader(blexec, disk, quiet = 0, 
     pin.input(ret)
     pin.input_eof()
     blcfg = pin.val
-
-    if imgcfg is None:
-        return blcfg
-    else:
-        c = sxp.merge(blcfg, imgcfg)
-        return c
+    return blcfg
diff -r da0849b74170 -r 0ee4e33b4401 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Thu Dec 14 18:24:14 2006 +0000
@@ -103,7 +103,7 @@ XENAPI_HVM_CFG = {
     'platform_keymap' : 'keymap',
 }    
 
-# List of XendConfig configuration keys that have no equivalent
+# List of XendConfig configuration keys that have no direct equivalent
 # in the old world.
 
 XENAPI_CFG_TYPES = {
@@ -132,19 +132,18 @@ XENAPI_CFG_TYPES = {
     'actions_after_crash': str,
     'tpm_instance': int,
     'tpm_backend': int,    
-    'bios_boot': str,
+    'PV_bootloader': str,
+    'PV_kernel': str,
+    'PV_initrd': str,
+    'PV_args': str,
+    'PV_bootloader_args': str,
+    'HVM_boot': str,
     'platform_std_vga': bool0,
     'platform_serial': str,
     'platform_localtime': bool0,
     'platform_clock_offset': bool0,
     'platform_enable_audio': bool0,
     'platform_keymap': str,
-    'boot_method': str,
-    'builder': str,
-    'kernel_kernel': str,
-    'kernel_initrd': str,
-    'kernel_args': str,
-    'grub_cmdline': str,
     'pci_bus': str,
     'tools_version': dict,
     'otherconfig': dict,
@@ -160,8 +159,6 @@ LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
     'vcpu_avail',
     'cpu_weight',
     'cpu_cap',
-    'bootloader',
-    'bootloader_args',
     'features',
     # read/write
     'on_xend_start',
@@ -188,8 +185,6 @@ LEGACY_CFG_TYPES = {
     'cpu_cap':         int,
     'cpu_weight':      int,
     'cpu_time':      float,
-    'bootloader':      str,
-    'bootloader_args': str,
     'features':        str,
     'localtime':       int,
     'name':        str,
@@ -331,16 +326,18 @@ class XendConfig(dict):
             'actions_after_crash': 'restart',
             'actions_after_suspend': '',
             'features': '',
-            'builder': 'linux',
+            'PV_bootloader': '',
+            'PV_kernel': '',
+            'PV_ramdisk': '',
+            'PV_args': '',
+            'PV_bootloader_args': '',
+            'HVM_boot': '',
             'memory_static_min': 0,
             'memory_dynamic_min': 0,
             'shadow_memory': 0,
             'memory_static_max': 0,
             'memory_dynamic_max': 0,
             'memory_actual': 0,
-            'boot_method': None,
-            'bootloader': None,
-            'bootloader_args': None,
             'devices': {},
             'image': {},
             'security': None,
@@ -383,10 +380,6 @@ class XendConfig(dict):
                 raise XendConfigError('Invalid event handling mode: ' +
                                       event)
 
-    def _builder_sanity_check(self):
-        if self['builder'] not in ('hvm', 'linux'):
-            raise XendConfigError('Invalid builder configuration')
-
     def _vcpus_sanity_check(self):
         if self.get('vcpus_number') != None:
             self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
@@ -398,7 +391,6 @@ class XendConfig(dict):
     def validate(self):
         self._memory_sanity_check()
         self._actions_sanity_check()
-        self._builder_sanity_check()
         self._vcpus_sanity_check()
         self._uuid_sanity_check()
 
@@ -598,38 +590,18 @@ class XendConfig(dict):
             except KeyError:
                 pass
 
-        # Convert Legacy "image" config to Xen API kernel_*
-        # configuration
+        self['PV_bootloader']      = cfg.get('bootloader',      '')
+        self['PV_bootloader_args'] = cfg.get('bootloader_args', '')
+        
         image_sxp = sxp.child_value(sxp_cfg, 'image', [])
         if image_sxp:
-            self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
-            self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
-            kernel_args = sxp.child_value(image_sxp, 'args', '')
-
-            # attempt to extract extra arguments from SXP config
-            arg_ip = sxp.child_value(image_sxp, 'ip')
-            if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
-                kernel_args += ' ip=%s' % arg_ip
-            arg_root = sxp.child_value(image_sxp, 'root')
-            if arg_root and not re.search(r'root=[^ ]+', kernel_args):
-                kernel_args += ' root=%s' % arg_root
-            
-            self['kernel_args'] = kernel_args
+            self.update_with_image_sxp(image_sxp)
 
         # Convert Legacy HVM parameters to Xen API configuration
         self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
         self['platform_serial'] = str(cfg.get('serial', ''))
         self['platform_localtime'] = bool0(cfg.get('localtime', 0))
         self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
-
-        # Convert path to bootloader to boot_method
-        if not cfg.get('bootloader'):
-            if self.get('kernel_kernel','').endswith('hvmloader'):
-                self['boot_method'] = 'bios'
-            else:
-                self['boot_method'] = 'kernel_external'
-        else:
-            self['boot_method'] = 'grub'
 
         # make sure a sane maximum is set
         if self['memory_static_max'] <= 0:
@@ -705,9 +677,6 @@ class XendConfig(dict):
         if backend:
             self['backend'] = backend
 
-        if self['image'].has_key('hvm'):
-            self['builder'] = 'hvm'
-            
         # Parse and convert other Non Xen API parameters.
         def _set_cfg_if_exists(sxp_arg):
             val = sxp.child_value(sxp_cfg, sxp_arg)
@@ -717,7 +686,6 @@ class XendConfig(dict):
                 else:
                     self[sxp_arg] = val
 
-        _set_cfg_if_exists('bootloader')
         _set_cfg_if_exists('shadow_memory')
         _set_cfg_if_exists('security')
         _set_cfg_if_exists('features')
@@ -741,8 +709,9 @@ class XendConfig(dict):
         """
 
         # populate image
-        self['image']['type'] = self['builder']
-        if self['builder'] == 'hvm':
+        hvm = self['HVM_boot'] != ''
+        self['image']['type'] = hvm and 'hvm' or 'linux'
+        if hvm:
             self['image']['hvm'] = {}
             for xapi, cfgapi in XENAPI_HVM_CFG.items():
                 self['image']['hvm'][cfgapi] = self[xapi]
@@ -780,8 +749,10 @@ class XendConfig(dict):
         @type xapi: dict
         """
         for key, val in xapi.items():
-            key = key.lower()
             type_conv = XENAPI_CFG_TYPES.get(key)
+            if type_conv is None:
+                key = key.lower()
+                type_conv = XENAPI_CFG_TYPES.get(key)
             if callable(type_conv):
                 self[key] = type_conv(val)
             else:
@@ -1100,8 +1071,8 @@ class XendConfig(dict):
     def update_with_image_sxp(self, image_sxp):
         # Convert Legacy "image" config to Xen API kernel_*
         # configuration
-        self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
-        self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+        self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+        self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
         kernel_args = sxp.child_value(image_sxp, 'args', '')
         
         # attempt to extract extra arguments from SXP config
@@ -1111,7 +1082,7 @@ class XendConfig(dict):
         arg_root = sxp.child_value(image_sxp, 'root')
         if arg_root and not re.search(r'root=', kernel_args):
             kernel_args += ' root=%s' % arg_root
-        self['kernel_args'] = kernel_args
+        self['PV_args'] = kernel_args
 
         # Store image SXP in python dictionary format
         image = {}
diff -r da0849b74170 -r 0ee4e33b4401 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Dec 14 18:24:14 2006 +0000
@@ -51,6 +51,7 @@ from xen.xend.XendAPIConstants import *
 from xen.xend.XendAPIConstants import *
 
 MIGRATE_TIMEOUT = 30.0
+BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
 
 xc = xen.lowlevel.xc.xc()
 xroot = XendRoot.instance()
@@ -438,6 +439,7 @@ class XendDomainInfo:
             xc.domain_pause(self.domid)
             self._stateSet(DOM_STATE_PAUSED)
         except Exception, ex:
+            log.exception(ex)
             raise XendError("Domain unable to be paused: %s" % str(ex))
 
     def unpause(self):
@@ -449,6 +451,7 @@ class XendDomainInfo:
             xc.domain_unpause(self.domid)
             self._stateSet(DOM_STATE_RUNNING)
         except Exception, ex:
+            log.exception(ex)
             raise XendError("Domain unable to be unpaused: %s" % str(ex))
 
     def send_sysrq(self, key):
@@ -467,7 +470,8 @@ class XendDomainInfo:
         dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
         dev_config_dict = self.info['devices'][dev_uuid][1]
         log.debug("XendDomainInfo.device_create: %s" % 
scrub_password(dev_config_dict))
-        devid = self._createDevice(dev_type, dev_config_dict)
+        dev_config_dict['devid'] = devid = \
+             self._createDevice(dev_type, dev_config_dict)
         self._waitForDevice(dev_type, devid)
         return self.getDeviceController(dev_type).sxpr(devid)
 
@@ -504,7 +508,7 @@ class XendDomainInfo:
         for devclass in XendDevices.valid_devices():
             self.getDeviceController(devclass).waitForDevices()
 
-    def destroyDevice(self, deviceClass, devid, force=None):
+    def destroyDevice(self, deviceClass, devid, force = False):
         try:
             devid = int(devid)
         except ValueError:
@@ -972,7 +976,8 @@ class XendDomainInfo:
             self.refresh_shutdown_lock.release()
 
         if restart_reason:
-            self._maybeRestart(restart_reason)
+            threading.Thread(target = self._maybeRestart,
+                             args = (restart_reason,)).start()
 
 
     #
@@ -1015,7 +1020,6 @@ class XendDomainInfo:
         """
         from xen.xend import XendDomain
         
-        self._configureBootloader()
         config = self.sxpr()
 
         if self._infoIsSet('cpus') and len(self.info['cpus']) != 0:
@@ -1141,6 +1145,10 @@ class XendDomainInfo:
     def _waitForDevice(self, deviceClass, devid):
         return self.getDeviceController(deviceClass).waitForDevice(devid)
 
+    def _waitForDeviceUUID(self, dev_uuid):
+        deviceClass, config = self.info['devices'].get(dev_uuid)
+        self._waitForDevice(deviceClass, config['devid'])
+
     def _reconfigureDevice(self, deviceClass, devid, devconfig):
         return self.getDeviceController(deviceClass).reconfigureDevice(
             devid, devconfig)
@@ -1244,6 +1252,8 @@ class XendDomainInfo:
 
         log.debug('XendDomainInfo.constructDomain')
 
+        self.shutdownStartTime = None
+
         image_cfg = self.info.get('image', {})
         hvm = image_cfg.has_key('hvm')
 
@@ -1288,10 +1298,7 @@ class XendDomainInfo:
                   self.domid,
                   self.info['cpu_weight'])
 
-        # if we have a boot loader but no image, then we need to set things
-        # up by running the boot loader non-interactively
-        if self.info.get('bootloader'):
-            self._configureBootloader()
+        self._configureBootloader()
 
         if not self._infoIsSet('image'):
             raise VmError('Missing image in configuration')
@@ -1352,17 +1359,14 @@ class XendDomainInfo:
 
             self._createDevices()
 
-            if self.info['bootloader']:
-                self.image.cleanupBootloading()
+            self.image.cleanupBootloading()
 
             self.info['start_time'] = time.time()
 
             self._stateSet(DOM_STATE_RUNNING)
         except RuntimeError, exn:
             log.exception("XendDomainInfo.initDomain: exception occurred")
-            if self.info['bootloader'] not in (None, 'kernel_external') \
-                   and self.image is not None:
-                self.image.cleanupBootloading()
+            self.image.cleanupBootloading()
             raise VmError(str(exn))
 
 
@@ -1493,33 +1497,78 @@ class XendDomainInfo:
 
     def _configureBootloader(self):
         """Run the bootloader if we're configured to do so."""
-        if not self.info.get('bootloader'):
-            return
-        blcfg = None
-
-        # FIXME: this assumes that we want to use the first disk device
-        for (devtype, devinfo) in self.info.all_devices_sxpr():
-            if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
-                continue
-            disk = None
-            for param in devinfo:
-                if param[0] == 'uname':
-                    disk = param[1]
-                    break
-
-            if disk is None:
-                continue
-            fn = blkdev_uname_to_file(disk)
-            blcfg = bootloader(self.info['bootloader'], fn, 1,
-                               self.info['bootloader_args'],
-                               self.info['image'])
-            break
-        if blcfg is None:
-            msg = "Had a bootloader specified, but can't find disk"
-            log.error(msg)
-            raise VmError(msg)
-        
-        self.info.update_with_image_sxp(blcfg)
+
+        blexec          = self.info['PV_bootloader']
+        bootloader_args = self.info['PV_bootloader_args']
+        kernel          = self.info['PV_kernel']
+        ramdisk         = self.info['PV_ramdisk']
+        args            = self.info['PV_args']
+        boot            = self.info['HVM_boot']
+
+        if boot:
+            # HVM booting.
+            self.info['image']['type'] = 'hvm'
+            self.info['image']['devices']['boot'] = boot
+        elif not blexec and kernel:
+            # Boot from dom0.  Nothing left to do -- the kernel and ramdisk
+            # will be picked up by image.py.
+            pass
+        else:
+            # Boot using bootloader
+            if not blexec or blexec == 'pygrub':
+                blexec = '/usr/bin/pygrub'
+
+            blcfg = None
+            for (devtype, devinfo) in self.info.all_devices_sxpr():
+                if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
+                    continue
+                disk = None
+                for param in devinfo:
+                    if param[0] == 'uname':
+                        disk = param[1]
+                        break
+
+                if disk is None:
+                    continue
+                fn = blkdev_uname_to_file(disk)
+                mounted = devtype == 'tap' and not os.stat(fn).st_rdev
+                if mounted:
+                    # This is a file, not a device.  pygrub can cope with a
+                    # file if it's raw, but if it's QCOW or other such formats
+                    # used through blktap, then we need to mount it first.
+
+                    log.info("Mounting %s on %s." %
+                             (fn, BOOTLOADER_LOOPBACK_DEVICE))
+
+                    vbd = {
+                        'mode': 'RO',
+                        'device': BOOTLOADER_LOOPBACK_DEVICE,
+                        }
+
+                    from xen.xend import XendDomain
+                    dom0 = XendDomain.instance().privilegedDomain()
+                    dom0._waitForDeviceUUID(dom0.create_vbd_with_vdi(vbd, fn))
+                    fn = BOOTLOADER_LOOPBACK_DEVICE
+
+                try:
+                    blcfg = bootloader(blexec, fn, True,
+                                       bootloader_args, kernel, ramdisk, args)
+                finally:
+                    if mounted:
+                        log.info("Unmounting %s from %s." %
+                                 (fn, BOOTLOADER_LOOPBACK_DEVICE))
+
+                        dom0.destroyDevice('tap', '/dev/xvdp')
+
+                break
+
+            if blcfg is None:
+                msg = "Had a bootloader specified, but can't find disk"
+                log.error(msg)
+                raise VmError(msg)
+        
+            self.info.update_with_image_sxp(blcfg)
+
 
     # 
     # VM Functions
@@ -1764,8 +1813,6 @@ class XendDomainInfo:
         return '' # TODO
     def get_power_state(self):
         return XEN_API_VM_POWER_STATE[self.state]
-    def get_bios_boot(self):
-        return '' # TODO
     def get_platform_std_vga(self):
         return self.info.get('platform_std_vga', False)    
     def get_platform_keymap(self):
@@ -1780,18 +1827,6 @@ class XendDomainInfo:
         return self.info.get('platform_enable_audio', False)
     def get_platform_keymap(self):
         return self.info.get('platform_keymap', '')
-    def get_builder(self):
-        return self.info.get('builder', 0)
-    def get_boot_method(self):
-        return self.info.get('boot_method', XEN_API_BOOT_TYPE[2])
-    def get_kernel_image(self):
-        return self.info.get('kernel_kernel', '')
-    def get_kernel_initrd(self):
-        return self.info.get('kernel_initrd', '')
-    def get_kernel_args(self):
-        return self.info.get('kernel_args', '')
-    def get_grub_cmdline(self):
-        return '' # TODO
     def get_pci_bus(self):
         return '' # TODO
     def get_tools_version(self):
@@ -1950,10 +1985,9 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
         
-        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
-            sxpr = self.info.device_sxpr(dev_uuid)
-            devid = self.getDeviceController('vbd').createDevice(sxpr)
-            raise XendError("Device creation failed")
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('vbd').createDevice(config)
 
         return dev_uuid
 
@@ -1971,10 +2005,9 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
 
-        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
-            sxpr = self.info.device_sxpr(dev_uuid)
-            devid = self.getDeviceController('tap').createDevice(sxpr)
-            raise XendError("Device creation failed")
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('tap').createDevice(config)
 
         return dev_uuid
 
@@ -1989,10 +2022,9 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
         
-        if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
-            sxpr = self.info.device_sxpr(dev_uuid)
-            devid = self.getDeviceController('vif').createDevice(sxpr)
-            raise XendError("Device creation failed")
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('vif').createDevice(config)
 
         return dev_uuid
 
diff -r da0849b74170 -r 0ee4e33b4401 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Thu Dec 14 17:43:41 2006 +0000
+++ b/tools/python/xen/xend/image.py    Thu Dec 14 18:24:14 2006 +0000
@@ -68,6 +68,7 @@ class ImageHandler:
     def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
         self.vm = vm
 
+        self.bootloader = None
         self.kernel = None
         self.ramdisk = None
         self.cmdline = None
@@ -76,9 +77,10 @@ class ImageHandler:
 
     def configure(self, vmConfig, imageConfig, _):
         """Config actions common to all unix-like domains."""
-        self.kernel = vmConfig['kernel_kernel']
-        self.cmdline = vmConfig['kernel_args']
-        self.ramdisk = vmConfig['kernel_initrd']
+        self.bootloader = vmConfig['PV_bootloader']
+        self.kernel = vmConfig['PV_kernel']
+        self.cmdline = vmConfig['PV_args']
+        self.ramdisk = vmConfig['PV_ramdisk']
         self.vm.storeVm(("image/ostype", self.ostype),
                         ("image/kernel", self.kernel),
                         ("image/cmdline", self.cmdline),
@@ -86,8 +88,9 @@ class ImageHandler:
 
 
     def cleanupBootloading(self):
-        self.unlink(self.kernel)
-        self.unlink(self.ramdisk)
+        if self.bootloader:
+            self.unlink(self.kernel)
+            self.unlink(self.ramdisk)
 
 
     def unlink(self, f):

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.