diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index 8327f98be7783cf33c801787ffffb162fdbb779d..8bc84519a0b1c965bf4fd24bd7d128708957c412 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2008, 2009, 2010, 2011 Google Inc. +# Copyright (C) 2008, 2009, 2010, 2011, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -420,7 +420,7 @@ class KVMHypervisor(hv_base.BaseHypervisor): # a separate directory, called 'chroot-quarantine'. _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine" _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR, _NICS_DIR, - _CHROOT_DIR, _CHROOT_QUARANTINE_DIR] + _CHROOT_DIR, _CHROOT_QUARANTINE_DIR, _KEYMAP_DIR] PARAMETERS = { constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK, @@ -944,6 +944,13 @@ class KVMHypervisor(hv_base.BaseHypervisor): def _GenerateKVMRuntime(self, instance, block_devices, startup_paused): """Generate KVM information to start an instance. + @attention: this function must not have any side-effects; for + example, it must not write to the filesystem, or read values + from the current system the are expected to differ between + nodes, since it is only run once at instance startup; + actions/kvm arguments that can vary between systems should be + done in L{_ExecuteKVMRuntime} + """ # pylint: disable=R0914,R0915 _, v_major, v_min, _ = self._GetKVMVersion() @@ -1099,16 +1106,6 @@ class KVMHypervisor(hv_base.BaseHypervisor): elif vnc_bind_address: kvm_cmd.extend(["-usbdevice", constants.HT_MOUSE_TABLET]) - keymap = hvp[constants.HV_KEYMAP] - if keymap: - keymap_path = self._InstanceKeymapFile(instance.name) - # If a keymap file is specified, KVM won't use its internal defaults. By - # first including the "en-us" layout, an error on loading the actual - # layout (e.g. because it can't be found) won't lead to a non-functional - # keyboard. A keyboard with incorrect keys is still better than none. - utils.WriteFile(keymap_path, data="include en-us\ninclude %s\n" % keymap) - kvm_cmd.extend(["-k", keymap_path]) - if vnc_bind_address: if netutils.IP4Address.IsValid(vnc_bind_address): if instance.network_port > constants.VNC_BASE_PORT: @@ -1144,6 +1141,8 @@ class KVMHypervisor(hv_base.BaseHypervisor): kvm_cmd.extend(["-vnc", vnc_arg]) elif spice_bind: + # FIXME: this is wrong here; the iface ip address differs + # between systems, so it should be done in _ExecuteKVMRuntime if netutils.IsValidInterface(spice_bind): # The user specified a network interface, we have to figure out the IP # address. @@ -1314,7 +1313,7 @@ class KVMHypervisor(hv_base.BaseHypervisor): raise errors.HypervisorError("Failed to start instance %s" % name) def _ExecuteKVMRuntime(self, instance, kvm_runtime, incoming=None): - """Execute a KVM cmd, after completing it with some last minute data + """Execute a KVM cmd, after completing it with some last minute data. @type incoming: tuple of strings @param incoming: (target_host_ip, port) @@ -1345,6 +1344,16 @@ class KVMHypervisor(hv_base.BaseHypervisor): if security_model == constants.HT_SM_USER: kvm_cmd.extend(["-runas", conf_hvp[constants.HV_SECURITY_DOMAIN]]) + keymap = conf_hvp[constants.HV_KEYMAP] + if keymap: + keymap_path = self._InstanceKeymapFile(name) + # If a keymap file is specified, KVM won't use its internal defaults. By + # first including the "en-us" layout, an error on loading the actual + # layout (e.g. because it can't be found) won't lead to a non-functional + # keyboard. A keyboard with incorrect keys is still better than none. + utils.WriteFile(keymap_path, data="include en-us\ninclude %s\n" % keymap) + kvm_cmd.extend(["-k", keymap_path]) + # We have reasons to believe changing something like the nic driver/type # upon migration won't exactly fly with the instance kernel, so for nic # related parameters we'll use up_hvp