mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
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>
This commit is contained in:
1 parent
a7416ebe65
commit
184500f7fc
7 files changed
+511
-543
No files matched your search
@@ -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()
|
||||
|
||||
@@ -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
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -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
|
||||
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 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)
|
||||
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
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||