aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEwan Mellor <ewan@xensource.com>2006-12-14 18:24:14 +0000
committerEwan Mellor <ewan@xensource.com>2006-12-14 18:24:14 +0000
commit184500f7fc7fd3cd61365d9d6770b74ff971c2e9 (patch)
tree459a21c1ef802136f80eaa47653c6bda60bf2fba
parenta7416ebe65679cab912c2d0f6f1f70f11669e0a2 (diff)
downloadxen-184500f7fc7fd3cd61365d9d6770b74ff971c2e9.tar.gz
xen-184500f7fc7fd3cd61365d9d6770b74ff971c2e9.tar.bz2
xen-184500f7fc7fd3cd61365d9d6770b74ff971c2e9.zip
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@xensource.com>
-rw-r--r--tools/libxen/include/xen_vm.h155
-rw-r--r--tools/libxen/src/xen_vm.c227
-rw-r--r--tools/python/xen/xend/XendAPI.py149
-rw-r--r--tools/python/xen/xend/XendBootloader.py17
-rw-r--r--tools/python/xen/xend/XendConfig.py81
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py160
-rw-r--r--tools/python/xen/xend/image.py13
7 files changed, 385 insertions, 417 deletions
diff --git a/tools/libxen/include/xen_vm.h b/tools/libxen/include/xen_vm.h
index 02ae5220cd..5287be5873 100644
--- a/tools/libxen/include/xen_vm.h
+++ b/tools/libxen/include/xen_vm.h
@@ -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,87 +464,80 @@ xen_vm_get_vtpms(xen_session *session, struct xen_vtpm_set **result, xen_vm vm);
/**
- * Get the bios/boot field of the given VM.
+ * Get the PV/bootloader field of the given VM.
*/
extern 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);
/**
- * Get the platform/std_VGA field of the given VM.
+ * Get the PV/kernel field of the given VM.
*/
extern bool
-xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm);
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm);
/**
- * Get the platform/serial field of the given VM.
+ * Get the PV/ramdisk field of the given VM.
*/
extern bool
-xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm);
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm);
/**
- * Get the platform/localtime field of the given VM.
+ * Get the PV/args field of the given VM.
*/
extern bool
-xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm);
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm);
/**
- * Get the platform/clock_offset field of the given VM.
+ * Get the PV/bootloader_args field of the given VM.
*/
extern bool
-xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm);
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
/**
- * Get the platform/enable_audio field of the given VM.
+ * Get the HVM/boot field of the given VM.
*/
extern bool
-xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm);
+xen_vm_get_hvm_boot(xen_session *session, char **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.
+ * Get the platform/std_VGA field of the given VM.
*/
extern bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, xen_vm vm);
+xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm);
/**
- * Get the kernel/kernel field of the given VM.
+ * Get the platform/serial field of the given VM.
*/
extern bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm);
+xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm);
/**
- * Get the kernel/initrd field of the given VM.
+ * Get the platform/localtime field of the given VM.
*/
extern bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm);
+xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm);
/**
- * Get the kernel/args field of the given VM.
+ * Get the platform/clock_offset field of the given VM.
*/
extern bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm);
+xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm);
/**
- * Get the grub/cmdline field of the given VM.
+ * Get the platform/enable_audio field of the given VM.
*/
extern bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm);
+xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm);
/**
@@ -688,87 +706,80 @@ xen_vm_set_actions_after_crash(xen_session *session, xen_vm vm, enum xen_on_cras
/**
- * Set the bios/boot field of the given VM.
+ * Set the PV/bootloader field of the given VM.
*/
extern 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);
/**
- * Set the platform/std_VGA field of the given VM.
+ * Set the PV/kernel field of the given VM.
*/
extern bool
-xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga);
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel);
/**
- * Set the platform/serial field of the given VM.
+ * Set the PV/ramdisk field of the given VM.
*/
extern bool
-xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial);
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk);
/**
- * Set the platform/localtime field of the given VM.
+ * Set the PV/args field of the given VM.
*/
extern bool
-xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime);
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args);
/**
- * Set the platform/clock_offset field of the given VM.
+ * Set the PV/bootloader_args field of the given VM.
*/
extern bool
-xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset);
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char *bootloader_args);
/**
- * Set the platform/enable_audio field of the given VM.
+ * Set the HVM/boot field of the given VM.
*/
extern bool
-xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio);
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
/**
- * 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.
+ * Set the platform/std_VGA field of the given VM.
*/
extern bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type boot_method);
+xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga);
/**
- * Set the kernel/kernel field of the given VM.
+ * Set the platform/serial field of the given VM.
*/
extern bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel);
+xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial);
/**
- * Set the kernel/initrd field of the given VM.
+ * Set the platform/localtime field of the given VM.
*/
extern bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd);
+xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime);
/**
- * Set the kernel/args field of the given VM.
+ * Set the platform/clock_offset field of the given VM.
*/
extern bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args);
+xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset);
/**
- * Set the grub/cmdline field of the given VM.
+ * Set the platform/enable_audio field of the given VM.
*/
extern bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline);
+xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio);
/**
@@ -814,8 +825,8 @@ xen_vm_unpause(xen_session *session, xen_vm vm);
/**
* 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 *session, xen_vm vm);
/**
* 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 --git a/tools/libxen/src/xen_vm.c b/tools/libxen/src/xen_vm.c
index bffab2bab9..1914b86959 100644
--- a/tools/libxen/src/xen_vm.c
+++ b/tools/libxen/src/xen_vm.c
@@ -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_struct_members[] =
{ .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_struct_members[] =
{ .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, struct xen_vtpm_set **result, xen_vm vm)
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,29 +793,13 @@ xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("VM.get_bios_boot");
- return session->ok;
-}
-
-
-bool
-xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = abstract_type_bool;
-
- XEN_CALL_("VM.get_platform_std_VGA");
+ XEN_CALL_("VM.get_PV_bootloader");
return session->ok;
}
bool
-xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -830,13 +810,13 @@ xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("VM.get_platform_serial");
+ XEN_CALL_("VM.get_PV_kernel");
return session->ok;
}
bool
-xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm)
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -844,15 +824,16 @@ xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm)
.u.string_val = vm }
};
- abstract_type result_type = abstract_type_bool;
+ abstract_type result_type = abstract_type_string;
- XEN_CALL_("VM.get_platform_localtime");
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_ramdisk");
return session->ok;
}
bool
-xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm)
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -860,15 +841,16 @@ xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm)
.u.string_val = vm }
};
- abstract_type result_type = abstract_type_bool;
+ abstract_type result_type = abstract_type_string;
- XEN_CALL_("VM.get_platform_clock_offset");
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_args");
return session->ok;
}
bool
-xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm)
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -876,15 +858,16 @@ xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm)
.u.string_val = vm }
};
- abstract_type result_type = abstract_type_bool;
+ abstract_type result_type = abstract_type_string;
- XEN_CALL_("VM.get_platform_enable_audio");
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_bootloader_args");
return session->ok;
}
bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -895,13 +878,13 @@ xen_vm_get_builder(xen_session *session, char **result, xen_vm vm)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("VM.get_builder");
+ XEN_CALL_("VM.get_HVM_boot");
return session->ok;
}
bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, xen_vm vm)
+xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -909,16 +892,15 @@ xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result, xen_vm
.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);
+ abstract_type result_type = abstract_type_bool;
+
+ XEN_CALL_("VM.get_platform_std_VGA");
return session->ok;
}
bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -929,13 +911,13 @@ xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm)
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("VM.get_kernel_kernel");
+ XEN_CALL_("VM.get_platform_serial");
return session->ok;
}
bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -943,16 +925,15 @@ xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm)
.u.string_val = vm }
};
- abstract_type result_type = abstract_type_string;
+ abstract_type result_type = abstract_type_bool;
- *result = NULL;
- XEN_CALL_("VM.get_kernel_initrd");
+ XEN_CALL_("VM.get_platform_localtime");
return session->ok;
}
bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -960,16 +941,15 @@ xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm)
.u.string_val = vm }
};
- abstract_type result_type = abstract_type_string;
+ abstract_type result_type = abstract_type_bool;
- *result = NULL;
- XEN_CALL_("VM.get_kernel_args");
+ XEN_CALL_("VM.get_platform_clock_offset");
return session->ok;
}
bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -977,10 +957,9 @@ xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm)
.u.string_val = vm }
};
- abstract_type result_type = abstract_type_string;
+ abstract_type result_type = abstract_type_bool;
- *result = NULL;
- XEN_CALL_("VM.get_grub_cmdline");
+ XEN_CALL_("VM.get_platform_enable_audio");
return session->ok;
}
@@ -1357,193 +1336,177 @@ xen_vm_set_actions_after_crash(xen_session *session, xen_vm vm, enum xen_on_cras
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 = boot }
+ .u.string_val = bootloader }
};
- xen_call_(session, "VM.set_bios_boot", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_PV_bootloader", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga)
+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_bool,
- .u.bool_val = std_vga }
+ { .type = &abstract_type_string,
+ .u.string_val = kernel }
};
- xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_PV_kernel", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial)
+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 = serial }
+ .u.string_val = ramdisk }
};
- xen_call_(session, "VM.set_platform_serial", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_PV_ramdisk", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime)
+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_bool,
- .u.bool_val = localtime }
- };
-
- xen_call_(session, "VM.set_platform_localtime", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset)
-{
- abstract_value param_values[] =
- {
{ .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &abstract_type_bool,
- .u.bool_val = clock_offset }
+ .u.string_val = args }
};
- xen_call_(session, "VM.set_platform_clock_offset", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_PV_args", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio)
+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_bool,
- .u.bool_val = enable_audio }
+ { .type = &abstract_type_string,
+ .u.string_val = bootloader_args }
};
- xen_call_(session, "VM.set_platform_enable_audio", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_PV_bootloader_args", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder)
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
{ .type = &abstract_type_string,
- .u.string_val = builder }
+ .u.string_val = boot }
};
- xen_call_(session, "VM.set_builder", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_HVM_boot", 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)
+xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga)
{
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) }
+ { .type = &abstract_type_bool,
+ .u.bool_val = std_vga }
};
- xen_call_(session, "VM.set_boot_method", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel)
+xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
{ .type = &abstract_type_string,
- .u.string_val = kernel }
+ .u.string_val = serial }
};
- xen_call_(session, "VM.set_kernel_kernel", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_platform_serial", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd)
+xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = initrd }
+ { .type = &abstract_type_bool,
+ .u.bool_val = localtime }
};
- xen_call_(session, "VM.set_kernel_initrd", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_platform_localtime", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args)
+xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = args }
+ { .type = &abstract_type_bool,
+ .u.bool_val = clock_offset }
};
- xen_call_(session, "VM.set_kernel_args", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_platform_clock_offset", param_values, 2, NULL, NULL);
return session->ok;
}
bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline)
+xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio)
{
abstract_value param_values[] =
{
{ .type = &abstract_type_string,
.u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = cmdline }
+ { .type = &abstract_type_bool,
+ .u.bool_val = enable_audio }
};
- xen_call_(session, "VM.set_grub_cmdline", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_platform_enable_audio", param_values, 2, NULL, NULL);
return session->ok;
}
diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py
index 466b4fb9d0..62b36a738b 100644
--- a/tools/python/xen/xend/XendAPI.py
+++ b/tools/python/xen/xend/XendAPI.py
@@ -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()
@@ -904,30 +920,6 @@ class XendAPI:
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()
-
def VM_set_otherConfig(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 --git a/tools/python/xen/xend/XendBootloader.py b/tools/python/xen/xend/XendBootloader.py
index 48ebb55e66..170b637222 100644
--- a/tools/python/xen/xend/XendBootloader.py
+++ b/tools/python/xen/xend/XendBootloader.py
@@ -21,7 +21,8 @@ from xen.util import mkdir
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, blargs = None, imgcfg = None):
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, blargs = None, imgcfg = None):
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, blargs = None, imgcfg = None):
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 --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py
index be00fb9585..e80422eaaa 100644
--- a/tools/python/xen/xend/XendConfig.py
+++ b/tools/python/xen/xend/XendConfig.py
@@ -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,23 +590,12 @@ 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))
@@ -622,15 +603,6 @@ class XendConfig(dict):
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:
self['memory_static_max'] = self['memory_static_min']
@@ -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 --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 1bff2a3861..de405c9a94 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -51,6 +51,7 @@ from xen.xend.XendConstants 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)
+ 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)
+ 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 --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
index 59353021c0..d3876e2749 100644
--- a/tools/python/xen/xend/image.py
+++ b/tools/python/xen/xend/image.py
@@ -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):