Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ 0745fe0e

History | View | Annotate | Download (86 kB)

1 eb58f9b1 Guido Trotter
#
2 eb58f9b1 Guido Trotter
#
3 eb58f9b1 Guido Trotter
4 cfc24646 Iustin Pop
# Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5 eb58f9b1 Guido Trotter
#
6 eb58f9b1 Guido Trotter
# This program is free software; you can redistribute it and/or modify
7 eb58f9b1 Guido Trotter
# it under the terms of the GNU General Public License as published by
8 eb58f9b1 Guido Trotter
# the Free Software Foundation; either version 2 of the License, or
9 eb58f9b1 Guido Trotter
# (at your option) any later version.
10 eb58f9b1 Guido Trotter
#
11 eb58f9b1 Guido Trotter
# This program is distributed in the hope that it will be useful, but
12 eb58f9b1 Guido Trotter
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 eb58f9b1 Guido Trotter
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 eb58f9b1 Guido Trotter
# General Public License for more details.
15 eb58f9b1 Guido Trotter
#
16 eb58f9b1 Guido Trotter
# You should have received a copy of the GNU General Public License
17 eb58f9b1 Guido Trotter
# along with this program; if not, write to the Free Software
18 eb58f9b1 Guido Trotter
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 eb58f9b1 Guido Trotter
# 02110-1301, USA.
20 eb58f9b1 Guido Trotter
21 eb58f9b1 Guido Trotter
22 eb58f9b1 Guido Trotter
"""KVM hypervisor
23 eb58f9b1 Guido Trotter

24 eb58f9b1 Guido Trotter
"""
25 eb58f9b1 Guido Trotter
26 547a63b7 Balazs Lecz
import errno
27 eb58f9b1 Guido Trotter
import os
28 eb58f9b1 Guido Trotter
import os.path
29 eb58f9b1 Guido Trotter
import re
30 eb58f9b1 Guido Trotter
import tempfile
31 6567aff3 Guido Trotter
import time
32 30e42c4e Guido Trotter
import logging
33 d19d94db Guido Trotter
import pwd
34 199b2053 Apollon Oikonomopoulos
import struct
35 199b2053 Apollon Oikonomopoulos
import fcntl
36 5d9bfd87 Apollon Oikonomopoulos
import shutil
37 91c10532 Andrea Spadaccini
import socket
38 fc84cd5d Guido Trotter
import stat
39 91c10532 Andrea Spadaccini
import StringIO
40 0745fe0e Dimitris Aragiorgis
from bitarray import bitarray
41 b693125f Tsachy Shacham
try:
42 471a31b6 Andrea Spadaccini
  import affinity   # pylint: disable=F0401
43 b693125f Tsachy Shacham
except ImportError:
44 b693125f Tsachy Shacham
  affinity = None
45 eb58f9b1 Guido Trotter
46 eb58f9b1 Guido Trotter
from ganeti import utils
47 eb58f9b1 Guido Trotter
from ganeti import constants
48 eb58f9b1 Guido Trotter
from ganeti import errors
49 38e250ba Guido Trotter
from ganeti import serializer
50 38e250ba Guido Trotter
from ganeti import objects
51 76431533 Guido Trotter
from ganeti import uidpool
52 76431533 Guido Trotter
from ganeti import ssconf
53 a744b676 Manuel Franceschini
from ganeti import netutils
54 9d9bded1 Michael Hanselmann
from ganeti import pathutils
55 9d9bded1 Michael Hanselmann
from ganeti.hypervisor import hv_base
56 5d9bfd87 Apollon Oikonomopoulos
from ganeti.utils import wrapper as utils_wrapper
57 eb58f9b1 Guido Trotter
58 eb58f9b1 Guido Trotter
59 0e1e0b6a Michael Hanselmann
_KVM_NETWORK_SCRIPT = pathutils.CONF_DIR + "/kvm-vif-bridge"
60 b693125f Tsachy Shacham
_KVM_START_PAUSED_FLAG = "-S"
61 748e4b5a Michael Hanselmann
62 199b2053 Apollon Oikonomopoulos
# TUN/TAP driver constants, taken from <linux/if_tun.h>
63 199b2053 Apollon Oikonomopoulos
# They are architecture-independent and already hardcoded in qemu-kvm source,
64 199b2053 Apollon Oikonomopoulos
# so we can safely include them here.
65 199b2053 Apollon Oikonomopoulos
TUNSETIFF = 0x400454ca
66 199b2053 Apollon Oikonomopoulos
TUNGETIFF = 0x800454d2
67 199b2053 Apollon Oikonomopoulos
TUNGETFEATURES = 0x800454cf
68 199b2053 Apollon Oikonomopoulos
IFF_TAP = 0x0002
69 199b2053 Apollon Oikonomopoulos
IFF_NO_PI = 0x1000
70 199b2053 Apollon Oikonomopoulos
IFF_VNET_HDR = 0x4000
71 199b2053 Apollon Oikonomopoulos
72 07788a0b Michael Hanselmann
#: SPICE parameters which depend on L{constants.HV_KVM_SPICE_BIND}
73 07788a0b Michael Hanselmann
_SPICE_ADDITIONAL_PARAMS = frozenset([
74 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_IP_VERSION,
75 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_PASSWORD_FILE,
76 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR,
77 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_JPEG_IMG_COMPR,
78 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR,
79 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION,
80 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_USE_TLS,
81 07788a0b Michael Hanselmann
  ])
82 07788a0b Michael Hanselmann
83 0745fe0e Dimitris Aragiorgis
# Constant bitarray that reflects to a free pci slot
84 0745fe0e Dimitris Aragiorgis
# Use it with bitarray.search()
85 0745fe0e Dimitris Aragiorgis
_AVAILABLE_PCI_SLOT = bitarray("0")
86 0745fe0e Dimitris Aragiorgis
87 8bbcbb9e Dimitris Aragiorgis
# below constants show the format of runtime file
88 8bbcbb9e Dimitris Aragiorgis
# the nics are in second possition, while the disks in 4th (last)
89 8bbcbb9e Dimitris Aragiorgis
# moreover disk entries are stored in tupples of L{objects.Disk}, dev_path
90 8bbcbb9e Dimitris Aragiorgis
_KVM_NICS_RUNTIME_INDEX = 1
91 8bbcbb9e Dimitris Aragiorgis
_KVM_DISKS_RUNTIME_INDEX = 3
92 8bbcbb9e Dimitris Aragiorgis
_DEVICE_RUNTIME_INDEX = {
93 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK: _KVM_DISKS_RUNTIME_INDEX,
94 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC: _KVM_NICS_RUNTIME_INDEX
95 8bbcbb9e Dimitris Aragiorgis
  }
96 8bbcbb9e Dimitris Aragiorgis
_FIND_RUNTIME_ENTRY = {
97 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC:
98 8bbcbb9e Dimitris Aragiorgis
    lambda nic, kvm_nics: [n for n in kvm_nics if n.uuid == nic.uuid],
99 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK:
100 8bbcbb9e Dimitris Aragiorgis
    lambda disk, kvm_disks: [(d, l) for (d, l) in kvm_disks
101 8bbcbb9e Dimitris Aragiorgis
                             if d.uuid == disk.uuid]
102 8bbcbb9e Dimitris Aragiorgis
  }
103 8bbcbb9e Dimitris Aragiorgis
_RUNTIME_DEVICE = {
104 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC: lambda d: d,
105 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK: lambda (d, e): d
106 8bbcbb9e Dimitris Aragiorgis
  }
107 8bbcbb9e Dimitris Aragiorgis
_RUNTIME_ENTRY = {
108 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC: lambda d, e: d,
109 8bbcbb9e Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK: lambda d, e: (d, e)
110 8bbcbb9e Dimitris Aragiorgis
  }
111 8bbcbb9e Dimitris Aragiorgis
112 8bbcbb9e Dimitris Aragiorgis
113 0745fe0e Dimitris Aragiorgis
def _GenerateDeviceKVMId(dev_type, dev):
114 0745fe0e Dimitris Aragiorgis
  """Helper function to generate a unique device name used by KVM
115 0745fe0e Dimitris Aragiorgis

116 0745fe0e Dimitris Aragiorgis
  QEMU monitor commands use names to identify devices. Here we use their pci
117 0745fe0e Dimitris Aragiorgis
  slot and a part of their UUID to name them. dev.pci might be None for old
118 0745fe0e Dimitris Aragiorgis
  devices in the cluster.
119 0745fe0e Dimitris Aragiorgis

120 0745fe0e Dimitris Aragiorgis
  @type dev_type: sting
121 0745fe0e Dimitris Aragiorgis
  @param dev_type: device type of param dev
122 0745fe0e Dimitris Aragiorgis
  @type dev: L{objects.Disk} or L{objects.NIC}
123 0745fe0e Dimitris Aragiorgis
  @param dev: the device object for which we generate a kvm name
124 0745fe0e Dimitris Aragiorgis
  @raise errors.HotplugError: in case a device has no pci slot (old devices)
125 0745fe0e Dimitris Aragiorgis

126 0745fe0e Dimitris Aragiorgis
  """
127 0745fe0e Dimitris Aragiorgis
128 0745fe0e Dimitris Aragiorgis
  if not dev.pci:
129 0745fe0e Dimitris Aragiorgis
    raise errors.HotplugError("Hotplug is not supported for %s with UUID %s" %
130 0745fe0e Dimitris Aragiorgis
                              (dev_type, dev.uuid))
131 0745fe0e Dimitris Aragiorgis
132 0745fe0e Dimitris Aragiorgis
  return "%s-%s-pci-%d" % (dev_type.lower(), dev.uuid.split("-")[0], dev.pci)
133 0745fe0e Dimitris Aragiorgis
134 0745fe0e Dimitris Aragiorgis
135 0745fe0e Dimitris Aragiorgis
def _UpdatePCISlots(dev, pci_reservations):
136 0745fe0e Dimitris Aragiorgis
  """Update pci configuration for a stopped instance
137 0745fe0e Dimitris Aragiorgis

138 0745fe0e Dimitris Aragiorgis
  If dev has a pci slot the reserve it, else find first available
139 0745fe0e Dimitris Aragiorgis
  in pci_reservations bitarray. It acts on the same objects passed
140 0745fe0e Dimitris Aragiorgis
  as params so there is no need to return anything.
141 0745fe0e Dimitris Aragiorgis

142 0745fe0e Dimitris Aragiorgis
  @type dev: L{objects.Disk} or L{objects.NIC}
143 0745fe0e Dimitris Aragiorgis
  @param dev: the device object for which we update its pci slot
144 0745fe0e Dimitris Aragiorgis
  @type pci_reservations: bitarray
145 0745fe0e Dimitris Aragiorgis
  @param pci_reservations: existing pci reservations for an instance
146 0745fe0e Dimitris Aragiorgis
  @raise errors.HotplugError: in case an instance has all its slot occupied
147 0745fe0e Dimitris Aragiorgis

148 0745fe0e Dimitris Aragiorgis
  """
149 0745fe0e Dimitris Aragiorgis
  if dev.pci:
150 0745fe0e Dimitris Aragiorgis
    free = dev.pci
151 0745fe0e Dimitris Aragiorgis
  else: # pylint: disable=E1103
152 0745fe0e Dimitris Aragiorgis
    [free] = pci_reservations.search(_AVAILABLE_PCI_SLOT, 1)
153 0745fe0e Dimitris Aragiorgis
    if not free:
154 0745fe0e Dimitris Aragiorgis
      raise errors.HypervisorError("All PCI slots occupied")
155 0745fe0e Dimitris Aragiorgis
    dev.pci = int(free)
156 0745fe0e Dimitris Aragiorgis
157 0745fe0e Dimitris Aragiorgis
  pci_reservations[free] = True
158 0745fe0e Dimitris Aragiorgis
159 0745fe0e Dimitris Aragiorgis
160 8bbcbb9e Dimitris Aragiorgis
def _GetExistingDeviceInfo(dev_type, device, runtime):
161 8bbcbb9e Dimitris Aragiorgis
  """Helper function to get an existing device inside the runtime file
162 8bbcbb9e Dimitris Aragiorgis

163 8bbcbb9e Dimitris Aragiorgis
  Used when an instance is running. Load kvm runtime file and search
164 8bbcbb9e Dimitris Aragiorgis
  for a device based on its type and uuid.
165 8bbcbb9e Dimitris Aragiorgis

166 8bbcbb9e Dimitris Aragiorgis
  @type dev_type: sting
167 8bbcbb9e Dimitris Aragiorgis
  @param dev_type: device type of param dev
168 8bbcbb9e Dimitris Aragiorgis
  @type device: L{objects.Disk} or L{objects.NIC}
169 8bbcbb9e Dimitris Aragiorgis
  @param device: the device object for which we generate a kvm name
170 8bbcbb9e Dimitris Aragiorgis
  @type runtime: tuple (cmd, nics, hvparams, disks)
171 8bbcbb9e Dimitris Aragiorgis
  @param runtime: the runtime data to search for the device
172 8bbcbb9e Dimitris Aragiorgis
  @raise errors.HotplugError: in case the requested device does not
173 8bbcbb9e Dimitris Aragiorgis
    exist (e.g. device has been added without --hotplug option) or
174 8bbcbb9e Dimitris Aragiorgis
    device info has not pci slot (e.g. old devices in the cluster)
175 8bbcbb9e Dimitris Aragiorgis

176 8bbcbb9e Dimitris Aragiorgis
  """
177 8bbcbb9e Dimitris Aragiorgis
  index = _DEVICE_RUNTIME_INDEX[dev_type]
178 8bbcbb9e Dimitris Aragiorgis
  found = _FIND_RUNTIME_ENTRY[dev_type](device, runtime[index])
179 8bbcbb9e Dimitris Aragiorgis
  if not found:
180 8bbcbb9e Dimitris Aragiorgis
    raise errors.HotplugError("Cannot find runtime info for %s with UUID %s" %
181 8bbcbb9e Dimitris Aragiorgis
                              (dev_type, device.uuid))
182 8bbcbb9e Dimitris Aragiorgis
183 8bbcbb9e Dimitris Aragiorgis
  return found[0]
184 8bbcbb9e Dimitris Aragiorgis
185 199b2053 Apollon Oikonomopoulos
186 ea2bcb82 Michael Hanselmann
def _GetTunFeatures(fd, _ioctl=fcntl.ioctl):
187 ea2bcb82 Michael Hanselmann
  """Retrieves supported TUN features from file descriptor.
188 ea2bcb82 Michael Hanselmann

189 ea2bcb82 Michael Hanselmann
  @see: L{_ProbeTapVnetHdr}
190 ea2bcb82 Michael Hanselmann

191 ea2bcb82 Michael Hanselmann
  """
192 ea2bcb82 Michael Hanselmann
  req = struct.pack("I", 0)
193 ea2bcb82 Michael Hanselmann
  try:
194 ea2bcb82 Michael Hanselmann
    buf = _ioctl(fd, TUNGETFEATURES, req)
195 ea2bcb82 Michael Hanselmann
  except EnvironmentError, err:
196 cfc24646 Iustin Pop
    logging.warning("ioctl(TUNGETFEATURES) failed: %s", err)
197 ea2bcb82 Michael Hanselmann
    return None
198 ea2bcb82 Michael Hanselmann
  else:
199 ea2bcb82 Michael Hanselmann
    (flags, ) = struct.unpack("I", buf)
200 ea2bcb82 Michael Hanselmann
    return flags
201 ea2bcb82 Michael Hanselmann
202 ea2bcb82 Michael Hanselmann
203 ea2bcb82 Michael Hanselmann
def _ProbeTapVnetHdr(fd, _features_fn=_GetTunFeatures):
204 199b2053 Apollon Oikonomopoulos
  """Check whether to enable the IFF_VNET_HDR flag.
205 199b2053 Apollon Oikonomopoulos

206 199b2053 Apollon Oikonomopoulos
  To do this, _all_ of the following conditions must be met:
207 199b2053 Apollon Oikonomopoulos
   1. TUNGETFEATURES ioctl() *must* be implemented
208 199b2053 Apollon Oikonomopoulos
   2. TUNGETFEATURES ioctl() result *must* contain the IFF_VNET_HDR flag
209 199b2053 Apollon Oikonomopoulos
   3. TUNGETIFF ioctl() *must* be implemented; reading the kernel code in
210 199b2053 Apollon Oikonomopoulos
      drivers/net/tun.c there is no way to test this until after the tap device
211 199b2053 Apollon Oikonomopoulos
      has been created using TUNSETIFF, and there is no way to change the
212 199b2053 Apollon Oikonomopoulos
      IFF_VNET_HDR flag after creating the interface, catch-22! However both
213 199b2053 Apollon Oikonomopoulos
      TUNGETIFF and TUNGETFEATURES were introduced in kernel version 2.6.27,
214 199b2053 Apollon Oikonomopoulos
      thus we can expect TUNGETIFF to be present if TUNGETFEATURES is.
215 199b2053 Apollon Oikonomopoulos

216 199b2053 Apollon Oikonomopoulos
   @type fd: int
217 199b2053 Apollon Oikonomopoulos
   @param fd: the file descriptor of /dev/net/tun
218 199b2053 Apollon Oikonomopoulos

219 199b2053 Apollon Oikonomopoulos
  """
220 ea2bcb82 Michael Hanselmann
  flags = _features_fn(fd)
221 199b2053 Apollon Oikonomopoulos
222 ea2bcb82 Michael Hanselmann
  if flags is None:
223 ea2bcb82 Michael Hanselmann
    # Not supported
224 199b2053 Apollon Oikonomopoulos
    return False
225 199b2053 Apollon Oikonomopoulos
226 ea2bcb82 Michael Hanselmann
  result = bool(flags & IFF_VNET_HDR)
227 ea2bcb82 Michael Hanselmann
228 ea2bcb82 Michael Hanselmann
  if not result:
229 ea2bcb82 Michael Hanselmann
    logging.warning("Kernel does not support IFF_VNET_HDR, not enabling")
230 ea2bcb82 Michael Hanselmann
231 ea2bcb82 Michael Hanselmann
  return result
232 ea2bcb82 Michael Hanselmann
233 199b2053 Apollon Oikonomopoulos
234 199b2053 Apollon Oikonomopoulos
def _OpenTap(vnet_hdr=True):
235 199b2053 Apollon Oikonomopoulos
  """Open a new tap device and return its file descriptor.
236 199b2053 Apollon Oikonomopoulos

237 199b2053 Apollon Oikonomopoulos
  This is intended to be used by a qemu-type hypervisor together with the -net
238 199b2053 Apollon Oikonomopoulos
  tap,fd=<fd> command line parameter.
239 199b2053 Apollon Oikonomopoulos

240 199b2053 Apollon Oikonomopoulos
  @type vnet_hdr: boolean
241 199b2053 Apollon Oikonomopoulos
  @param vnet_hdr: Enable the VNET Header
242 199b2053 Apollon Oikonomopoulos
  @return: (ifname, tapfd)
243 199b2053 Apollon Oikonomopoulos
  @rtype: tuple
244 199b2053 Apollon Oikonomopoulos

245 199b2053 Apollon Oikonomopoulos
  """
246 199b2053 Apollon Oikonomopoulos
  try:
247 199b2053 Apollon Oikonomopoulos
    tapfd = os.open("/dev/net/tun", os.O_RDWR)
248 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
249 199b2053 Apollon Oikonomopoulos
    raise errors.HypervisorError("Failed to open /dev/net/tun")
250 199b2053 Apollon Oikonomopoulos
251 199b2053 Apollon Oikonomopoulos
  flags = IFF_TAP | IFF_NO_PI
252 199b2053 Apollon Oikonomopoulos
253 199b2053 Apollon Oikonomopoulos
  if vnet_hdr and _ProbeTapVnetHdr(tapfd):
254 199b2053 Apollon Oikonomopoulos
    flags |= IFF_VNET_HDR
255 199b2053 Apollon Oikonomopoulos
256 199b2053 Apollon Oikonomopoulos
  # The struct ifreq ioctl request (see netdevice(7))
257 199b2053 Apollon Oikonomopoulos
  ifr = struct.pack("16sh", "", flags)
258 199b2053 Apollon Oikonomopoulos
259 199b2053 Apollon Oikonomopoulos
  try:
260 199b2053 Apollon Oikonomopoulos
    res = fcntl.ioctl(tapfd, TUNSETIFF, ifr)
261 6f1e1921 Michael Hanselmann
  except EnvironmentError, err:
262 6f1e1921 Michael Hanselmann
    raise errors.HypervisorError("Failed to allocate a new TAP device: %s" %
263 6f1e1921 Michael Hanselmann
                                 err)
264 199b2053 Apollon Oikonomopoulos
265 199b2053 Apollon Oikonomopoulos
  # Get the interface name from the ioctl
266 199b2053 Apollon Oikonomopoulos
  ifname = struct.unpack("16sh", res)[0].strip("\x00")
267 199b2053 Apollon Oikonomopoulos
  return (ifname, tapfd)
268 199b2053 Apollon Oikonomopoulos
269 748e4b5a Michael Hanselmann
270 91c10532 Andrea Spadaccini
class QmpMessage:
271 91c10532 Andrea Spadaccini
  """QEMU Messaging Protocol (QMP) message.
272 91c10532 Andrea Spadaccini

273 91c10532 Andrea Spadaccini
  """
274 91c10532 Andrea Spadaccini
  def __init__(self, data):
275 91c10532 Andrea Spadaccini
    """Creates a new QMP message based on the passed data.
276 91c10532 Andrea Spadaccini

277 91c10532 Andrea Spadaccini
    """
278 91c10532 Andrea Spadaccini
    if not isinstance(data, dict):
279 91c10532 Andrea Spadaccini
      raise TypeError("QmpMessage must be initialized with a dict")
280 91c10532 Andrea Spadaccini
281 91c10532 Andrea Spadaccini
    self.data = data
282 91c10532 Andrea Spadaccini
283 91c10532 Andrea Spadaccini
  def __getitem__(self, field_name):
284 91c10532 Andrea Spadaccini
    """Get the value of the required field if present, or None.
285 91c10532 Andrea Spadaccini

286 91c10532 Andrea Spadaccini
    Overrides the [] operator to provide access to the message data,
287 91c10532 Andrea Spadaccini
    returning None if the required item is not in the message
288 91c10532 Andrea Spadaccini
    @return: the value of the field_name field, or None if field_name
289 91c10532 Andrea Spadaccini
             is not contained in the message
290 91c10532 Andrea Spadaccini

291 91c10532 Andrea Spadaccini
    """
292 9b87c2cf Michael Hanselmann
    return self.data.get(field_name, None)
293 91c10532 Andrea Spadaccini
294 91c10532 Andrea Spadaccini
  def __setitem__(self, field_name, field_value):
295 91c10532 Andrea Spadaccini
    """Set the value of the required field_name to field_value.
296 91c10532 Andrea Spadaccini

297 91c10532 Andrea Spadaccini
    """
298 91c10532 Andrea Spadaccini
    self.data[field_name] = field_value
299 91c10532 Andrea Spadaccini
300 91c10532 Andrea Spadaccini
  @staticmethod
301 91c10532 Andrea Spadaccini
  def BuildFromJsonString(json_string):
302 91c10532 Andrea Spadaccini
    """Build a QmpMessage from a JSON encoded string.
303 91c10532 Andrea Spadaccini

304 91c10532 Andrea Spadaccini
    @type json_string: str
305 91c10532 Andrea Spadaccini
    @param json_string: JSON string representing the message
306 91c10532 Andrea Spadaccini
    @rtype: L{QmpMessage}
307 91c10532 Andrea Spadaccini
    @return: a L{QmpMessage} built from json_string
308 91c10532 Andrea Spadaccini

309 91c10532 Andrea Spadaccini
    """
310 91c10532 Andrea Spadaccini
    # Parse the string
311 91c10532 Andrea Spadaccini
    data = serializer.LoadJson(json_string)
312 91c10532 Andrea Spadaccini
    return QmpMessage(data)
313 91c10532 Andrea Spadaccini
314 91c10532 Andrea Spadaccini
  def __str__(self):
315 a182a3ed Michael Hanselmann
    # The protocol expects the JSON object to be sent as a single line.
316 a182a3ed Michael Hanselmann
    return serializer.DumpJson(self.data)
317 91c10532 Andrea Spadaccini
318 91c10532 Andrea Spadaccini
  def __eq__(self, other):
319 91c10532 Andrea Spadaccini
    # When comparing two QmpMessages, we are interested in comparing
320 91c10532 Andrea Spadaccini
    # their internal representation of the message data
321 91c10532 Andrea Spadaccini
    return self.data == other.data
322 91c10532 Andrea Spadaccini
323 91c10532 Andrea Spadaccini
324 91c10532 Andrea Spadaccini
class QmpConnection:
325 91c10532 Andrea Spadaccini
  """Connection to the QEMU Monitor using the QEMU Monitor Protocol (QMP).
326 91c10532 Andrea Spadaccini

327 91c10532 Andrea Spadaccini
  """
328 91c10532 Andrea Spadaccini
  _FIRST_MESSAGE_KEY = "QMP"
329 91c10532 Andrea Spadaccini
  _EVENT_KEY = "event"
330 91c10532 Andrea Spadaccini
  _ERROR_KEY = "error"
331 89da2ff3 Guido Trotter
  _RETURN_KEY = RETURN_KEY = "return"
332 89da2ff3 Guido Trotter
  _ACTUAL_KEY = ACTUAL_KEY = "actual"
333 91c10532 Andrea Spadaccini
  _ERROR_CLASS_KEY = "class"
334 91c10532 Andrea Spadaccini
  _ERROR_DATA_KEY = "data"
335 91c10532 Andrea Spadaccini
  _ERROR_DESC_KEY = "desc"
336 91c10532 Andrea Spadaccini
  _EXECUTE_KEY = "execute"
337 91c10532 Andrea Spadaccini
  _ARGUMENTS_KEY = "arguments"
338 91c10532 Andrea Spadaccini
  _CAPABILITIES_COMMAND = "qmp_capabilities"
339 91c10532 Andrea Spadaccini
  _MESSAGE_END_TOKEN = "\r\n"
340 91c10532 Andrea Spadaccini
  _SOCKET_TIMEOUT = 5
341 91c10532 Andrea Spadaccini
342 91c10532 Andrea Spadaccini
  def __init__(self, monitor_filename):
343 91c10532 Andrea Spadaccini
    """Instantiates the QmpConnection object.
344 91c10532 Andrea Spadaccini

345 91c10532 Andrea Spadaccini
    @type monitor_filename: string
346 91c10532 Andrea Spadaccini
    @param monitor_filename: the filename of the UNIX raw socket on which the
347 91c10532 Andrea Spadaccini
                             QMP monitor is listening
348 91c10532 Andrea Spadaccini

349 91c10532 Andrea Spadaccini
    """
350 91c10532 Andrea Spadaccini
    self.monitor_filename = monitor_filename
351 91c10532 Andrea Spadaccini
    self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
352 91c10532 Andrea Spadaccini
    # We want to fail if the server doesn't send a complete message
353 91c10532 Andrea Spadaccini
    # in a reasonable amount of time
354 91c10532 Andrea Spadaccini
    self.sock.settimeout(self._SOCKET_TIMEOUT)
355 91c10532 Andrea Spadaccini
    self._connected = False
356 91c10532 Andrea Spadaccini
    self._buf = ""
357 91c10532 Andrea Spadaccini
358 fc84cd5d Guido Trotter
  def _check_socket(self):
359 fc84cd5d Guido Trotter
    sock_stat = None
360 fc84cd5d Guido Trotter
    try:
361 fc84cd5d Guido Trotter
      sock_stat = os.stat(self.monitor_filename)
362 fc84cd5d Guido Trotter
    except EnvironmentError, err:
363 fc84cd5d Guido Trotter
      if err.errno == errno.ENOENT:
364 fc84cd5d Guido Trotter
        raise errors.HypervisorError("No qmp socket found")
365 fc84cd5d Guido Trotter
      else:
366 fc84cd5d Guido Trotter
        raise errors.HypervisorError("Error checking qmp socket: %s",
367 fc84cd5d Guido Trotter
                                     utils.ErrnoOrStr(err))
368 fc84cd5d Guido Trotter
    if not stat.S_ISSOCK(sock_stat.st_mode):
369 fc84cd5d Guido Trotter
      raise errors.HypervisorError("Qmp socket is not a socket")
370 fc84cd5d Guido Trotter
371 91c10532 Andrea Spadaccini
  def _check_connection(self):
372 91c10532 Andrea Spadaccini
    """Make sure that the connection is established.
373 91c10532 Andrea Spadaccini

374 91c10532 Andrea Spadaccini
    """
375 91c10532 Andrea Spadaccini
    if not self._connected:
376 91c10532 Andrea Spadaccini
      raise errors.ProgrammerError("To use a QmpConnection you need to first"
377 91c10532 Andrea Spadaccini
                                   " invoke connect() on it")
378 91c10532 Andrea Spadaccini
379 91c10532 Andrea Spadaccini
  def connect(self):
380 91c10532 Andrea Spadaccini
    """Connects to the QMP monitor.
381 91c10532 Andrea Spadaccini

382 91c10532 Andrea Spadaccini
    Connects to the UNIX socket and makes sure that we can actually send and
383 91c10532 Andrea Spadaccini
    receive data to the kvm instance via QMP.
384 91c10532 Andrea Spadaccini

385 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
386 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
387 91c10532 Andrea Spadaccini

388 91c10532 Andrea Spadaccini
    """
389 fc84cd5d Guido Trotter
    if self._connected:
390 fc84cd5d Guido Trotter
      raise errors.ProgrammerError("Cannot connect twice")
391 fc84cd5d Guido Trotter
392 fc84cd5d Guido Trotter
    self._check_socket()
393 fc84cd5d Guido Trotter
394 fc84cd5d Guido Trotter
    # Check file existance/stuff
395 fc84cd5d Guido Trotter
    try:
396 fc84cd5d Guido Trotter
      self.sock.connect(self.monitor_filename)
397 fc84cd5d Guido Trotter
    except EnvironmentError:
398 fc84cd5d Guido Trotter
      raise errors.HypervisorError("Can't connect to qmp socket")
399 91c10532 Andrea Spadaccini
    self._connected = True
400 91c10532 Andrea Spadaccini
401 91c10532 Andrea Spadaccini
    # Check if we receive a correct greeting message from the server
402 91c10532 Andrea Spadaccini
    # (As per the QEMU Protocol Specification 0.1 - section 2.2)
403 91c10532 Andrea Spadaccini
    greeting = self._Recv()
404 91c10532 Andrea Spadaccini
    if not greeting[self._FIRST_MESSAGE_KEY]:
405 91c10532 Andrea Spadaccini
      self._connected = False
406 afa9bb2e Michael Hanselmann
      raise errors.HypervisorError("kvm: QMP communication error (wrong"
407 91c10532 Andrea Spadaccini
                                   " server greeting")
408 91c10532 Andrea Spadaccini
409 91c10532 Andrea Spadaccini
    # Let's put the monitor in command mode using the qmp_capabilities
410 91c10532 Andrea Spadaccini
    # command, or else no command will be executable.
411 91c10532 Andrea Spadaccini
    # (As per the QEMU Protocol Specification 0.1 - section 4)
412 91c10532 Andrea Spadaccini
    self.Execute(self._CAPABILITIES_COMMAND)
413 91c10532 Andrea Spadaccini
414 91c10532 Andrea Spadaccini
  def _ParseMessage(self, buf):
415 91c10532 Andrea Spadaccini
    """Extract and parse a QMP message from the given buffer.
416 91c10532 Andrea Spadaccini

417 91c10532 Andrea Spadaccini
    Seeks for a QMP message in the given buf. If found, it parses it and
418 91c10532 Andrea Spadaccini
    returns it together with the rest of the characters in the buf.
419 91c10532 Andrea Spadaccini
    If no message is found, returns None and the whole buffer.
420 91c10532 Andrea Spadaccini

421 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
422 91c10532 Andrea Spadaccini

423 91c10532 Andrea Spadaccini
    """
424 91c10532 Andrea Spadaccini
    message = None
425 91c10532 Andrea Spadaccini
    # Check if we got the message end token (CRLF, as per the QEMU Protocol
426 91c10532 Andrea Spadaccini
    # Specification 0.1 - Section 2.1.1)
427 91c10532 Andrea Spadaccini
    pos = buf.find(self._MESSAGE_END_TOKEN)
428 91c10532 Andrea Spadaccini
    if pos >= 0:
429 91c10532 Andrea Spadaccini
      try:
430 91c10532 Andrea Spadaccini
        message = QmpMessage.BuildFromJsonString(buf[:pos + 1])
431 91c10532 Andrea Spadaccini
      except Exception, err:
432 91c10532 Andrea Spadaccini
        raise errors.ProgrammerError("QMP data serialization error: %s" % err)
433 91c10532 Andrea Spadaccini
      buf = buf[pos + 1:]
434 91c10532 Andrea Spadaccini
435 91c10532 Andrea Spadaccini
    return (message, buf)
436 91c10532 Andrea Spadaccini
437 91c10532 Andrea Spadaccini
  def _Recv(self):
438 91c10532 Andrea Spadaccini
    """Receives a message from QMP and decodes the received JSON object.
439 91c10532 Andrea Spadaccini

440 91c10532 Andrea Spadaccini
    @rtype: QmpMessage
441 91c10532 Andrea Spadaccini
    @return: the received message
442 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
443 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
444 91c10532 Andrea Spadaccini

445 91c10532 Andrea Spadaccini
    """
446 91c10532 Andrea Spadaccini
    self._check_connection()
447 91c10532 Andrea Spadaccini
448 91c10532 Andrea Spadaccini
    # Check if there is already a message in the buffer
449 91c10532 Andrea Spadaccini
    (message, self._buf) = self._ParseMessage(self._buf)
450 91c10532 Andrea Spadaccini
    if message:
451 91c10532 Andrea Spadaccini
      return message
452 91c10532 Andrea Spadaccini
453 91c10532 Andrea Spadaccini
    recv_buffer = StringIO.StringIO(self._buf)
454 91c10532 Andrea Spadaccini
    recv_buffer.seek(len(self._buf))
455 91c10532 Andrea Spadaccini
    try:
456 91c10532 Andrea Spadaccini
      while True:
457 91c10532 Andrea Spadaccini
        data = self.sock.recv(4096)
458 91c10532 Andrea Spadaccini
        if not data:
459 91c10532 Andrea Spadaccini
          break
460 91c10532 Andrea Spadaccini
        recv_buffer.write(data)
461 91c10532 Andrea Spadaccini
462 91c10532 Andrea Spadaccini
        (message, self._buf) = self._ParseMessage(recv_buffer.getvalue())
463 91c10532 Andrea Spadaccini
        if message:
464 91c10532 Andrea Spadaccini
          return message
465 91c10532 Andrea Spadaccini
466 91c10532 Andrea Spadaccini
    except socket.timeout, err:
467 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Timeout while receiving a QMP message: "
468 91c10532 Andrea Spadaccini
                                   "%s" % (err))
469 91c10532 Andrea Spadaccini
    except socket.error, err:
470 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Unable to receive data from KVM using the"
471 91c10532 Andrea Spadaccini
                                   " QMP protocol: %s" % err)
472 91c10532 Andrea Spadaccini
473 91c10532 Andrea Spadaccini
  def _Send(self, message):
474 91c10532 Andrea Spadaccini
    """Encodes and sends a message to KVM using QMP.
475 91c10532 Andrea Spadaccini

476 91c10532 Andrea Spadaccini
    @type message: QmpMessage
477 91c10532 Andrea Spadaccini
    @param message: message to send to KVM
478 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
479 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
480 91c10532 Andrea Spadaccini

481 91c10532 Andrea Spadaccini
    """
482 91c10532 Andrea Spadaccini
    self._check_connection()
483 91c10532 Andrea Spadaccini
    try:
484 91c10532 Andrea Spadaccini
      message_str = str(message)
485 91c10532 Andrea Spadaccini
    except Exception, err:
486 91c10532 Andrea Spadaccini
      raise errors.ProgrammerError("QMP data deserialization error: %s" % err)
487 91c10532 Andrea Spadaccini
488 91c10532 Andrea Spadaccini
    try:
489 91c10532 Andrea Spadaccini
      self.sock.sendall(message_str)
490 91c10532 Andrea Spadaccini
    except socket.timeout, err:
491 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Timeout while sending a QMP message: "
492 91c10532 Andrea Spadaccini
                                   "%s (%s)" % (err.string, err.errno))
493 91c10532 Andrea Spadaccini
    except socket.error, err:
494 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Unable to send data from KVM using the"
495 91c10532 Andrea Spadaccini
                                   " QMP protocol: %s" % err)
496 91c10532 Andrea Spadaccini
497 91c10532 Andrea Spadaccini
  def Execute(self, command, arguments=None):
498 91c10532 Andrea Spadaccini
    """Executes a QMP command and returns the response of the server.
499 91c10532 Andrea Spadaccini

500 91c10532 Andrea Spadaccini
    @type command: str
501 91c10532 Andrea Spadaccini
    @param command: the command to execute
502 91c10532 Andrea Spadaccini
    @type arguments: dict
503 91c10532 Andrea Spadaccini
    @param arguments: dictionary of arguments to be passed to the command
504 91c10532 Andrea Spadaccini
    @rtype: dict
505 91c10532 Andrea Spadaccini
    @return: dictionary representing the received JSON object
506 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
507 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
508 91c10532 Andrea Spadaccini

509 91c10532 Andrea Spadaccini
    """
510 91c10532 Andrea Spadaccini
    self._check_connection()
511 91c10532 Andrea Spadaccini
    message = QmpMessage({self._EXECUTE_KEY: command})
512 91c10532 Andrea Spadaccini
    if arguments:
513 91c10532 Andrea Spadaccini
      message[self._ARGUMENTS_KEY] = arguments
514 91c10532 Andrea Spadaccini
    self._Send(message)
515 91c10532 Andrea Spadaccini
516 91c10532 Andrea Spadaccini
    # Events can occur between the sending of the command and the reception
517 91c10532 Andrea Spadaccini
    # of the response, so we need to filter out messages with the event key.
518 91c10532 Andrea Spadaccini
    while True:
519 91c10532 Andrea Spadaccini
      response = self._Recv()
520 91c10532 Andrea Spadaccini
      err = response[self._ERROR_KEY]
521 91c10532 Andrea Spadaccini
      if err:
522 91c10532 Andrea Spadaccini
        raise errors.HypervisorError("kvm: error executing the %s"
523 91c10532 Andrea Spadaccini
                                     " command: %s (%s, %s):" %
524 91c10532 Andrea Spadaccini
                                     (command,
525 91c10532 Andrea Spadaccini
                                      err[self._ERROR_DESC_KEY],
526 91c10532 Andrea Spadaccini
                                      err[self._ERROR_CLASS_KEY],
527 91c10532 Andrea Spadaccini
                                      err[self._ERROR_DATA_KEY]))
528 91c10532 Andrea Spadaccini
529 91c10532 Andrea Spadaccini
      elif not response[self._EVENT_KEY]:
530 91c10532 Andrea Spadaccini
        return response
531 91c10532 Andrea Spadaccini
532 91c10532 Andrea Spadaccini
533 eb58f9b1 Guido Trotter
class KVMHypervisor(hv_base.BaseHypervisor):
534 65107a2f Michael Hanselmann
  """KVM hypervisor interface
535 65107a2f Michael Hanselmann

536 65107a2f Michael Hanselmann
  """
537 d271c6fd Iustin Pop
  CAN_MIGRATE = True
538 eb58f9b1 Guido Trotter
539 9d9bded1 Michael Hanselmann
  _ROOT_DIR = pathutils.RUN_DIR + "/kvm-hypervisor"
540 a1d79fc6 Guido Trotter
  _PIDS_DIR = _ROOT_DIR + "/pid" # contains live instances pids
541 7548396c Guido Trotter
  _UIDS_DIR = _ROOT_DIR + "/uid" # contains instances reserved uids
542 a1d79fc6 Guido Trotter
  _CTRL_DIR = _ROOT_DIR + "/ctrl" # contains instances control sockets
543 a1d79fc6 Guido Trotter
  _CONF_DIR = _ROOT_DIR + "/conf" # contains instances startup data
544 5d9bfd87 Apollon Oikonomopoulos
  _NICS_DIR = _ROOT_DIR + "/nic" # contains instances nic <-> tap associations
545 4f580fef Sébastien Bocahu
  _KEYMAP_DIR = _ROOT_DIR + "/keymap" # contains instances keymaps
546 547a63b7 Balazs Lecz
  # KVM instances with chroot enabled are started in empty chroot directories.
547 547a63b7 Balazs Lecz
  _CHROOT_DIR = _ROOT_DIR + "/chroot" # for empty chroot directories
548 547a63b7 Balazs Lecz
  # After an instance is stopped, its chroot directory is removed.
549 547a63b7 Balazs Lecz
  # If the chroot directory is not empty, it can't be removed.
550 547a63b7 Balazs Lecz
  # A non-empty chroot directory indicates a possible security incident.
551 547a63b7 Balazs Lecz
  # To support forensics, the non-empty chroot directory is quarantined in
552 547a63b7 Balazs Lecz
  # a separate directory, called 'chroot-quarantine'.
553 547a63b7 Balazs Lecz
  _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine"
554 5d9bfd87 Apollon Oikonomopoulos
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR, _NICS_DIR,
555 2911f46c Iustin Pop
           _CHROOT_DIR, _CHROOT_QUARANTINE_DIR, _KEYMAP_DIR]
556 eb58f9b1 Guido Trotter
557 205ab586 Iustin Pop
  PARAMETERS = {
558 4b9638dc Guido Trotter
    constants.HV_KVM_PATH: hv_base.REQ_FILE_CHECK,
559 205ab586 Iustin Pop
    constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK,
560 205ab586 Iustin Pop
    constants.HV_INITRD_PATH: hv_base.OPT_FILE_CHECK,
561 205ab586 Iustin Pop
    constants.HV_ROOT_PATH: hv_base.NO_CHECK,
562 205ab586 Iustin Pop
    constants.HV_KERNEL_ARGS: hv_base.NO_CHECK,
563 205ab586 Iustin Pop
    constants.HV_ACPI: hv_base.NO_CHECK,
564 205ab586 Iustin Pop
    constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
565 14fd6c81 Guido Trotter
    constants.HV_SERIAL_SPEED: hv_base.NO_CHECK,
566 d73ef63f Michael Hanselmann
    constants.HV_VNC_BIND_ADDRESS:
567 8b312c1d Manuel Franceschini
      (False, lambda x: (netutils.IP4Address.IsValid(x) or
568 8b312c1d Manuel Franceschini
                         utils.IsNormAbsPath(x)),
569 afa9bb2e Michael Hanselmann
       "The VNC bind address must be either a valid IP address or an absolute"
570 d73ef63f Michael Hanselmann
       " pathname", None, None),
571 205ab586 Iustin Pop
    constants.HV_VNC_TLS: hv_base.NO_CHECK,
572 205ab586 Iustin Pop
    constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
573 205ab586 Iustin Pop
    constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
574 6e6bb8d5 Guido Trotter
    constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
575 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_BIND: hv_base.NO_CHECK, # will be checked later
576 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_IP_VERSION:
577 b1cb62bd Andrea Spadaccini
      (False, lambda x: (x == constants.IFACE_NO_IP_VERSION_SPECIFIED or
578 b1cb62bd Andrea Spadaccini
                         x in constants.VALID_IP_VERSIONS),
579 afa9bb2e Michael Hanselmann
       "The SPICE IP version should be 4 or 6",
580 b1cb62bd Andrea Spadaccini
       None, None),
581 b451c4c7 Andrea Spadaccini
    constants.HV_KVM_SPICE_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
582 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR:
583 5ae4945a Iustin Pop
      hv_base.ParamInSet(
584 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSLESS_IMG_COMPR_OPTIONS),
585 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_JPEG_IMG_COMPR:
586 5ae4945a Iustin Pop
      hv_base.ParamInSet(
587 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
588 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR:
589 5ae4945a Iustin Pop
      hv_base.ParamInSet(
590 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
591 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION:
592 5ae4945a Iustin Pop
      hv_base.ParamInSet(
593 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_VIDEO_STREAM_DETECTION_OPTIONS),
594 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_AUDIO_COMPR: hv_base.NO_CHECK,
595 bfe86c76 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_TLS: hv_base.NO_CHECK,
596 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_TLS_CIPHERS: hv_base.NO_CHECK,
597 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_VDAGENT: hv_base.NO_CHECK,
598 cc130cc7 Marco Casavecchia
    constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
599 205ab586 Iustin Pop
    constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
600 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
601 d73ef63f Michael Hanselmann
    constants.HV_BOOT_ORDER:
602 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
603 d73ef63f Michael Hanselmann
    constants.HV_NIC_TYPE:
604 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_NIC_TYPES),
605 d73ef63f Michael Hanselmann
    constants.HV_DISK_TYPE:
606 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_DISK_TYPES),
607 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM_DISK_TYPE:
608 cc130cc7 Marco Casavecchia
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_DISK_TYPES),
609 d73ef63f Michael Hanselmann
    constants.HV_USB_MOUSE:
610 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_MOUSE_TYPES),
611 4f580fef Sébastien Bocahu
    constants.HV_KEYMAP: hv_base.NO_CHECK,
612 e2d14329 Andrea Spadaccini
    constants.HV_MIGRATION_PORT: hv_base.REQ_NET_PORT_CHECK,
613 2c368f28 Guido Trotter
    constants.HV_MIGRATION_BANDWIDTH: hv_base.REQ_NONNEGATIVE_INT_CHECK,
614 2c368f28 Guido Trotter
    constants.HV_MIGRATION_DOWNTIME: hv_base.REQ_NONNEGATIVE_INT_CHECK,
615 783a6c0b Iustin Pop
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
616 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
617 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
618 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
619 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
620 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
621 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
622 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
623 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
624 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
625 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
626 4f958b0b Miguel Di Ciurcio Filho
    constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
627 990ade2d Stephen Shirley
    constants.HV_REBOOT_BEHAVIOR:
628 a7f884d3 Tsachy Shacham
      hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
629 a7f884d3 Tsachy Shacham
    constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
630 3c286190 Dimitris Aragiorgis
    constants.HV_CPU_TYPE: hv_base.NO_CHECK,
631 2c368f28 Guido Trotter
    constants.HV_CPU_CORES: hv_base.OPT_NONNEGATIVE_INT_CHECK,
632 2c368f28 Guido Trotter
    constants.HV_CPU_THREADS: hv_base.OPT_NONNEGATIVE_INT_CHECK,
633 2c368f28 Guido Trotter
    constants.HV_CPU_SOCKETS: hv_base.OPT_NONNEGATIVE_INT_CHECK,
634 2fddb144 Guido Trotter
    constants.HV_SOUNDHW: hv_base.NO_CHECK,
635 156681c1 Guido Trotter
    constants.HV_USB_DEVICES: hv_base.NO_CHECK,
636 7589346f Guido Trotter
    constants.HV_VGA: hv_base.NO_CHECK,
637 e6f24d89 Guido Trotter
    constants.HV_KVM_EXTRA: hv_base.NO_CHECK,
638 4ab75599 Dimitris Aragiorgis
    constants.HV_KVM_MACHINE_VERSION: hv_base.NO_CHECK,
639 8a534fbe Stratos Psomdakis
    constants.HV_VNET_HDR: hv_base.NO_CHECK,
640 205ab586 Iustin Pop
    }
641 6b5605e8 Iustin Pop
642 f0db563d Guido Trotter
  _VIRTIO = "virtio"
643 f0db563d Guido Trotter
  _VIRTIO_NET_PCI = "virtio-net-pci"
644 68c9f726 Dimitris Aragiorgis
  _VIRTIO_BLK_PCI = "virtio-blk-pci"
645 f0db563d Guido Trotter
646 d0c8c01d Iustin Pop
  _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)",
647 30e42c4e Guido Trotter
                                    re.M | re.I)
648 65107a2f Michael Hanselmann
  _MIGRATION_PROGRESS_RE = \
649 527c0cf7 Michael Hanselmann
    re.compile(r"\s*transferred\s+ram:\s+(?P<transferred>\d+)\s+kbytes\s*\n"
650 527c0cf7 Michael Hanselmann
               r"\s*remaining\s+ram:\s+(?P<remaining>\d+)\s+kbytes\s*\n"
651 527c0cf7 Michael Hanselmann
               r"\s*total\s+ram:\s+(?P<total>\d+)\s+kbytes\s*\n", re.I)
652 61643226 Andrea Spadaccini
653 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
654 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
655 30e42c4e Guido Trotter
656 585c8187 Guido Trotter
  _VERSION_RE = re.compile(r"\b(\d+)\.(\d+)(\.(\d+))?\b")
657 b52d85c1 Guido Trotter
658 b693125f Tsachy Shacham
  _CPU_INFO_RE = re.compile(r"cpu\s+\#(\d+).*thread_id\s*=\s*(\d+)", re.I)
659 b693125f Tsachy Shacham
  _CPU_INFO_CMD = "info cpus"
660 b693125f Tsachy Shacham
  _CONT_CMD = "cont"
661 b693125f Tsachy Shacham
662 7f83345f Guido Trotter
  _DEFAULT_MACHINE_VERSION_RE = re.compile(r"^(\S+).*\(default\)", re.M)
663 82e3bf85 Dimitris Aragiorgis
  _CHECK_MACHINE_VERSION_RE = \
664 82e3bf85 Dimitris Aragiorgis
    staticmethod(lambda x: re.compile(r"^(%s)[ ]+.*PC" % x, re.M))
665 e6ba3320 Dimitris Aragiorgis
666 0ad7f5d8 Guido Trotter
  _QMP_RE = re.compile(r"^-qmp\s", re.M)
667 0ad7f5d8 Guido Trotter
  _SPICE_RE = re.compile(r"^-spice\s", re.M)
668 0ad7f5d8 Guido Trotter
  _VHOST_RE = re.compile(r"^-net\s.*,vhost=on|off", re.M)
669 0ad7f5d8 Guido Trotter
  _ENABLE_KVM_RE = re.compile(r"^-enable-kvm\s", re.M)
670 0ad7f5d8 Guido Trotter
  _DISABLE_KVM_RE = re.compile(r"^-disable-kvm\s", re.M)
671 0ad7f5d8 Guido Trotter
  _NETDEV_RE = re.compile(r"^-netdev\s", re.M)
672 99c7cd5b Guido Trotter
  _DISPLAY_RE = re.compile(r"^-display\s", re.M)
673 8cb5634a Guido Trotter
  _MACHINE_RE = re.compile(r"^-machine\s", re.M)
674 68c9f726 Dimitris Aragiorgis
  _VIRTIO_NET_RE = re.compile(r"^name \"%s\"" % _VIRTIO_NET_PCI, re.M)
675 68c9f726 Dimitris Aragiorgis
  _VIRTIO_BLK_RE = re.compile(r"^name \"%s\"" % _VIRTIO_BLK_PCI, re.M)
676 0ad7f5d8 Guido Trotter
  # match  -drive.*boot=on|off on different lines, but in between accept only
677 0ad7f5d8 Guido Trotter
  # dashes not preceeded by a new line (which would mean another option
678 0ad7f5d8 Guido Trotter
  # different than -drive is starting)
679 0ad7f5d8 Guido Trotter
  _BOOT_RE = re.compile(r"^-drive\s([^-]|(?<!^)-)*,boot=on\|off", re.M | re.S)
680 0ad7f5d8 Guido Trotter
681 0745fe0e Dimitris Aragiorgis
  _INFO_PCI_RE = re.compile(r'Bus.*device[ ]*(\d+).*')
682 0745fe0e Dimitris Aragiorgis
  _INFO_PCI_CMD = "info pci"
683 0745fe0e Dimitris Aragiorgis
  _INFO_VERSION_RE = \
684 0745fe0e Dimitris Aragiorgis
    re.compile(r'^QEMU (\d+)\.(\d+)(\.(\d+))?.*monitor.*', re.M)
685 0745fe0e Dimitris Aragiorgis
  _INFO_VERSION_CMD = "info version"
686 0745fe0e Dimitris Aragiorgis
687 0745fe0e Dimitris Aragiorgis
  _DEFAULT_PCI_RESERVATIONS = "11110000000000000000000000000000"
688 0745fe0e Dimitris Aragiorgis
689 64bfbc08 Guido Trotter
  ANCILLARY_FILES = [
690 64bfbc08 Guido Trotter
    _KVM_NETWORK_SCRIPT,
691 64bfbc08 Guido Trotter
    ]
692 69ab2e12 Guido Trotter
  ANCILLARY_FILES_OPT = [
693 69ab2e12 Guido Trotter
    _KVM_NETWORK_SCRIPT,
694 69ab2e12 Guido Trotter
    ]
695 64bfbc08 Guido Trotter
696 6e043e60 Guido Trotter
  # Supported kvm options to get output from
697 6e043e60 Guido Trotter
  _KVMOPT_HELP = "help"
698 6e043e60 Guido Trotter
  _KVMOPT_MLIST = "mlist"
699 f0db563d Guido Trotter
  _KVMOPT_DEVICELIST = "devicelist"
700 bc0fed4b Guido Trotter
701 bc0fed4b Guido Trotter
  # Command to execute to get the output from kvm, and whether to
702 bc0fed4b Guido Trotter
  # accept the output even on failure.
703 6e043e60 Guido Trotter
  _KVMOPTS_CMDS = {
704 bc0fed4b Guido Trotter
    _KVMOPT_HELP: (["--help"], False),
705 bc0fed4b Guido Trotter
    _KVMOPT_MLIST: (["-M", "?"], False),
706 bc0fed4b Guido Trotter
    _KVMOPT_DEVICELIST: (["-device", "?"], True),
707 6e043e60 Guido Trotter
  }
708 6e043e60 Guido Trotter
709 eb58f9b1 Guido Trotter
  def __init__(self):
710 eb58f9b1 Guido Trotter
    hv_base.BaseHypervisor.__init__(self)
711 eb58f9b1 Guido Trotter
    # Let's make sure the directories we need exist, even if the RUN_DIR lives
712 eb58f9b1 Guido Trotter
    # in a tmpfs filesystem or has been otherwise wiped out.
713 29921401 Iustin Pop
    dirs = [(dname, constants.RUN_DIRS_MODE) for dname in self._DIRS]
714 9afb67fe Guido Trotter
    utils.EnsureDirs(dirs)
715 eb58f9b1 Guido Trotter
716 30786fc9 Iustin Pop
  @classmethod
717 30786fc9 Iustin Pop
  def _InstancePidFile(cls, instance_name):
718 98ec75d6 Iustin Pop
    """Returns the instance pidfile.
719 98ec75d6 Iustin Pop

720 98ec75d6 Iustin Pop
    """
721 30786fc9 Iustin Pop
    return utils.PathJoin(cls._PIDS_DIR, instance_name)
722 98ec75d6 Iustin Pop
723 263b8de6 Guido Trotter
  @classmethod
724 7548396c Guido Trotter
  def _InstanceUidFile(cls, instance_name):
725 7548396c Guido Trotter
    """Returns the instance uidfile.
726 7548396c Guido Trotter

727 7548396c Guido Trotter
    """
728 7548396c Guido Trotter
    return utils.PathJoin(cls._UIDS_DIR, instance_name)
729 7548396c Guido Trotter
730 7548396c Guido Trotter
  @classmethod
731 263b8de6 Guido Trotter
  def _InstancePidInfo(cls, pid):
732 263b8de6 Guido Trotter
    """Check pid file for instance information.
733 263b8de6 Guido Trotter

734 263b8de6 Guido Trotter
    Check that a pid file is associated with an instance, and retrieve
735 263b8de6 Guido Trotter
    information from its command line.
736 263b8de6 Guido Trotter

737 263b8de6 Guido Trotter
    @type pid: string or int
738 263b8de6 Guido Trotter
    @param pid: process id of the instance to check
739 263b8de6 Guido Trotter
    @rtype: tuple
740 263b8de6 Guido Trotter
    @return: (instance_name, memory, vcpus)
741 263b8de6 Guido Trotter
    @raise errors.HypervisorError: when an instance cannot be found
742 263b8de6 Guido Trotter

743 263b8de6 Guido Trotter
    """
744 263b8de6 Guido Trotter
    alive = utils.IsProcessAlive(pid)
745 263b8de6 Guido Trotter
    if not alive:
746 263b8de6 Guido Trotter
      raise errors.HypervisorError("Cannot get info for pid %s" % pid)
747 263b8de6 Guido Trotter
748 263b8de6 Guido Trotter
    cmdline_file = utils.PathJoin("/proc", str(pid), "cmdline")
749 263b8de6 Guido Trotter
    try:
750 263b8de6 Guido Trotter
      cmdline = utils.ReadFile(cmdline_file)
751 263b8de6 Guido Trotter
    except EnvironmentError, err:
752 263b8de6 Guido Trotter
      raise errors.HypervisorError("Can't open cmdline file for pid %s: %s" %
753 263b8de6 Guido Trotter
                                   (pid, err))
754 263b8de6 Guido Trotter
755 263b8de6 Guido Trotter
    instance = None
756 263b8de6 Guido Trotter
    memory = 0
757 263b8de6 Guido Trotter
    vcpus = 0
758 263b8de6 Guido Trotter
759 d0c8c01d Iustin Pop
    arg_list = cmdline.split("\x00")
760 263b8de6 Guido Trotter
    while arg_list:
761 e687ec01 Michael Hanselmann
      arg = arg_list.pop(0)
762 263b8de6 Guido Trotter
      if arg == "-name":
763 263b8de6 Guido Trotter
        instance = arg_list.pop(0)
764 263b8de6 Guido Trotter
      elif arg == "-m":
765 263b8de6 Guido Trotter
        memory = int(arg_list.pop(0))
766 263b8de6 Guido Trotter
      elif arg == "-smp":
767 4888a609 Guido Trotter
        vcpus = int(arg_list.pop(0).split(",")[0])
768 263b8de6 Guido Trotter
769 263b8de6 Guido Trotter
    if instance is None:
770 263b8de6 Guido Trotter
      raise errors.HypervisorError("Pid %s doesn't contain a ganeti kvm"
771 263b8de6 Guido Trotter
                                   " instance" % pid)
772 263b8de6 Guido Trotter
773 263b8de6 Guido Trotter
    return (instance, memory, vcpus)
774 263b8de6 Guido Trotter
775 1f8b3a27 Guido Trotter
  def _InstancePidAlive(self, instance_name):
776 263b8de6 Guido Trotter
    """Returns the instance pidfile, pid, and liveness.
777 263b8de6 Guido Trotter

778 263b8de6 Guido Trotter
    @type instance_name: string
779 263b8de6 Guido Trotter
    @param instance_name: instance name
780 263b8de6 Guido Trotter
    @rtype: tuple
781 263b8de6 Guido Trotter
    @return: (pid file name, pid, liveness)
782 1f8b3a27 Guido Trotter

783 1f8b3a27 Guido Trotter
    """
784 98ec75d6 Iustin Pop
    pidfile = self._InstancePidFile(instance_name)
785 1f8b3a27 Guido Trotter
    pid = utils.ReadPidFile(pidfile)
786 263b8de6 Guido Trotter
787 263b8de6 Guido Trotter
    alive = False
788 263b8de6 Guido Trotter
    try:
789 263b8de6 Guido Trotter
      cmd_instance = self._InstancePidInfo(pid)[0]
790 263b8de6 Guido Trotter
      alive = (cmd_instance == instance_name)
791 263b8de6 Guido Trotter
    except errors.HypervisorError:
792 263b8de6 Guido Trotter
      pass
793 1f8b3a27 Guido Trotter
794 1f8b3a27 Guido Trotter
    return (pidfile, pid, alive)
795 1f8b3a27 Guido Trotter
796 5905901c Iustin Pop
  def _CheckDown(self, instance_name):
797 5905901c Iustin Pop
    """Raises an error unless the given instance is down.
798 5905901c Iustin Pop

799 5905901c Iustin Pop
    """
800 5905901c Iustin Pop
    alive = self._InstancePidAlive(instance_name)[2]
801 5905901c Iustin Pop
    if alive:
802 5905901c Iustin Pop
      raise errors.HypervisorError("Failed to start instance %s: %s" %
803 5905901c Iustin Pop
                                   (instance_name, "already running"))
804 5905901c Iustin Pop
805 0df4d98a Guido Trotter
  @classmethod
806 0df4d98a Guido Trotter
  def _InstanceMonitor(cls, instance_name):
807 c4fbefc8 Guido Trotter
    """Returns the instance monitor socket name
808 c4fbefc8 Guido Trotter

809 c4fbefc8 Guido Trotter
    """
810 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.monitor" % instance_name)
811 c4fbefc8 Guido Trotter
812 0df4d98a Guido Trotter
  @classmethod
813 0df4d98a Guido Trotter
  def _InstanceSerial(cls, instance_name):
814 c4fbefc8 Guido Trotter
    """Returns the instance serial socket name
815 c4fbefc8 Guido Trotter

816 c4fbefc8 Guido Trotter
    """
817 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.serial" % instance_name)
818 c4fbefc8 Guido Trotter
819 91c10532 Andrea Spadaccini
  @classmethod
820 91c10532 Andrea Spadaccini
  def _InstanceQmpMonitor(cls, instance_name):
821 91c10532 Andrea Spadaccini
    """Returns the instance serial QMP socket name
822 91c10532 Andrea Spadaccini

823 91c10532 Andrea Spadaccini
    """
824 91c10532 Andrea Spadaccini
    return utils.PathJoin(cls._CTRL_DIR, "%s.qmp" % instance_name)
825 91c10532 Andrea Spadaccini
826 86d6bc2a Guido Trotter
  @staticmethod
827 86d6bc2a Guido Trotter
  def _SocatUnixConsoleParams():
828 86d6bc2a Guido Trotter
    """Returns the correct parameters for socat
829 86d6bc2a Guido Trotter

830 86d6bc2a Guido Trotter
    If we have a new-enough socat we can use raw mode with an escape character.
831 86d6bc2a Guido Trotter

832 86d6bc2a Guido Trotter
    """
833 fe5b0c42 Michael Hanselmann
    if constants.SOCAT_USE_ESCAPE:
834 86d6bc2a Guido Trotter
      return "raw,echo=0,escape=%s" % constants.SOCAT_ESCAPE_CODE
835 86d6bc2a Guido Trotter
    else:
836 86d6bc2a Guido Trotter
      return "echo=0,icanon=0"
837 86d6bc2a Guido Trotter
838 0df4d98a Guido Trotter
  @classmethod
839 0df4d98a Guido Trotter
  def _InstanceKVMRuntime(cls, instance_name):
840 38e250ba Guido Trotter
    """Returns the instance KVM runtime filename
841 38e250ba Guido Trotter

842 38e250ba Guido Trotter
    """
843 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
844 38e250ba Guido Trotter
845 7e66c35b Guido Trotter
  @classmethod
846 547a63b7 Balazs Lecz
  def _InstanceChrootDir(cls, instance_name):
847 547a63b7 Balazs Lecz
    """Returns the name of the KVM chroot dir of the instance
848 547a63b7 Balazs Lecz

849 547a63b7 Balazs Lecz
    """
850 547a63b7 Balazs Lecz
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
851 547a63b7 Balazs Lecz
852 547a63b7 Balazs Lecz
  @classmethod
853 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICDir(cls, instance_name):
854 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the directory holding the tap device files for a
855 5d9bfd87 Apollon Oikonomopoulos
    given instance.
856 5d9bfd87 Apollon Oikonomopoulos

857 5d9bfd87 Apollon Oikonomopoulos
    """
858 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._NICS_DIR, instance_name)
859 5d9bfd87 Apollon Oikonomopoulos
860 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
861 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICFile(cls, instance_name, seq):
862 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the file containing the tap device for a given NIC
863 5d9bfd87 Apollon Oikonomopoulos

864 5d9bfd87 Apollon Oikonomopoulos
    """
865 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._InstanceNICDir(instance_name), str(seq))
866 5d9bfd87 Apollon Oikonomopoulos
867 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
868 4f580fef Sébastien Bocahu
  def _InstanceKeymapFile(cls, instance_name):
869 4f580fef Sébastien Bocahu
    """Returns the name of the file containing the keymap for a given instance
870 4f580fef Sébastien Bocahu

871 4f580fef Sébastien Bocahu
    """
872 4f580fef Sébastien Bocahu
    return utils.PathJoin(cls._KEYMAP_DIR, instance_name)
873 4f580fef Sébastien Bocahu
874 4f580fef Sébastien Bocahu
  @classmethod
875 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
876 7548396c Guido Trotter
    """Try to read a uid file
877 7548396c Guido Trotter

878 7548396c Guido Trotter
    """
879 7548396c Guido Trotter
    if os.path.exists(uid_file):
880 7548396c Guido Trotter
      try:
881 682f7601 Guido Trotter
        uid = int(utils.ReadOneLineFile(uid_file))
882 aa0b600b Guido Trotter
        return uid
883 7548396c Guido Trotter
      except EnvironmentError:
884 7548396c Guido Trotter
        logging.warning("Can't read uid file", exc_info=True)
885 7548396c Guido Trotter
      except (TypeError, ValueError):
886 7548396c Guido Trotter
        logging.warning("Can't parse uid file contents", exc_info=True)
887 aa0b600b Guido Trotter
    return None
888 7548396c Guido Trotter
889 7548396c Guido Trotter
  @classmethod
890 7e66c35b Guido Trotter
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
891 547a63b7 Balazs Lecz
    """Removes an instance's rutime sockets/files/dirs.
892 7e66c35b Guido Trotter

893 7e66c35b Guido Trotter
    """
894 7e66c35b Guido Trotter
    utils.RemoveFile(pidfile)
895 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceMonitor(instance_name))
896 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceSerial(instance_name))
897 91c10532 Andrea Spadaccini
    utils.RemoveFile(cls._InstanceQmpMonitor(instance_name))
898 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceKVMRuntime(instance_name))
899 4f580fef Sébastien Bocahu
    utils.RemoveFile(cls._InstanceKeymapFile(instance_name))
900 7548396c Guido Trotter
    uid_file = cls._InstanceUidFile(instance_name)
901 7548396c Guido Trotter
    uid = cls._TryReadUidFile(uid_file)
902 7548396c Guido Trotter
    utils.RemoveFile(uid_file)
903 7548396c Guido Trotter
    if uid is not None:
904 7548396c Guido Trotter
      uidpool.ReleaseUid(uid)
905 7be85163 Guido Trotter
    try:
906 7be85163 Guido Trotter
      shutil.rmtree(cls._InstanceNICDir(instance_name))
907 7be85163 Guido Trotter
    except OSError, err:
908 7be85163 Guido Trotter
      if err.errno != errno.ENOENT:
909 7be85163 Guido Trotter
        raise
910 547a63b7 Balazs Lecz
    try:
911 547a63b7 Balazs Lecz
      chroot_dir = cls._InstanceChrootDir(instance_name)
912 547a63b7 Balazs Lecz
      utils.RemoveDir(chroot_dir)
913 547a63b7 Balazs Lecz
    except OSError, err:
914 547a63b7 Balazs Lecz
      if err.errno == errno.ENOTEMPTY:
915 547a63b7 Balazs Lecz
        # The chroot directory is expected to be empty, but it isn't.
916 547a63b7 Balazs Lecz
        new_chroot_dir = tempfile.mkdtemp(dir=cls._CHROOT_QUARANTINE_DIR,
917 547a63b7 Balazs Lecz
                                          prefix="%s-%s-" %
918 547a63b7 Balazs Lecz
                                          (instance_name,
919 547a63b7 Balazs Lecz
                                           utils.TimestampForFilename()))
920 547a63b7 Balazs Lecz
        logging.warning("The chroot directory of instance %s can not be"
921 547a63b7 Balazs Lecz
                        " removed as it is not empty. Moving it to the"
922 547a63b7 Balazs Lecz
                        " quarantine instead. Please investigate the"
923 547a63b7 Balazs Lecz
                        " contents (%s) and clean up manually",
924 547a63b7 Balazs Lecz
                        instance_name, new_chroot_dir)
925 547a63b7 Balazs Lecz
        utils.RenameFile(chroot_dir, new_chroot_dir)
926 547a63b7 Balazs Lecz
      else:
927 547a63b7 Balazs Lecz
        raise
928 7e66c35b Guido Trotter
929 748e4b5a Michael Hanselmann
  @staticmethod
930 5d9bfd87 Apollon Oikonomopoulos
  def _ConfigureNIC(instance, seq, nic, tap):
931 5d9bfd87 Apollon Oikonomopoulos
    """Run the network configuration script for a specified NIC
932 eb58f9b1 Guido Trotter

933 eb58f9b1 Guido Trotter
    @param instance: instance we're acting on
934 eb58f9b1 Guido Trotter
    @type instance: instance object
935 eb58f9b1 Guido Trotter
    @param seq: nic sequence number
936 eb58f9b1 Guido Trotter
    @type seq: int
937 eb58f9b1 Guido Trotter
    @param nic: nic we're acting on
938 eb58f9b1 Guido Trotter
    @type nic: nic object
939 5d9bfd87 Apollon Oikonomopoulos
    @param tap: the host's tap interface this NIC corresponds to
940 5d9bfd87 Apollon Oikonomopoulos
    @type tap: str
941 eb58f9b1 Guido Trotter

942 eb58f9b1 Guido Trotter
    """
943 5d9bfd87 Apollon Oikonomopoulos
    if instance.tags:
944 5d9bfd87 Apollon Oikonomopoulos
      tags = " ".join(instance.tags)
945 5d9bfd87 Apollon Oikonomopoulos
    else:
946 5d9bfd87 Apollon Oikonomopoulos
      tags = ""
947 5d9bfd87 Apollon Oikonomopoulos
948 5d9bfd87 Apollon Oikonomopoulos
    env = {
949 5d9bfd87 Apollon Oikonomopoulos
      "PATH": "%s:/sbin:/usr/sbin" % os.environ["PATH"],
950 5d9bfd87 Apollon Oikonomopoulos
      "INSTANCE": instance.name,
951 5d9bfd87 Apollon Oikonomopoulos
      "MAC": nic.mac,
952 5d9bfd87 Apollon Oikonomopoulos
      "MODE": nic.nicparams[constants.NIC_MODE],
953 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE": tap,
954 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE_INDEX": str(seq),
955 5d9bfd87 Apollon Oikonomopoulos
      "TAGS": tags,
956 5d9bfd87 Apollon Oikonomopoulos
    }
957 5d9bfd87 Apollon Oikonomopoulos
958 5d9bfd87 Apollon Oikonomopoulos
    if nic.ip:
959 5d9bfd87 Apollon Oikonomopoulos
      env["IP"] = nic.ip
960 5d9bfd87 Apollon Oikonomopoulos
961 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_LINK]:
962 5d9bfd87 Apollon Oikonomopoulos
      env["LINK"] = nic.nicparams[constants.NIC_LINK]
963 5d9bfd87 Apollon Oikonomopoulos
964 a5ad5e58 Apollon Oikonomopoulos
    if nic.network:
965 cbe4a0a5 Dimitris Aragiorgis
      n = objects.Network.FromDict(nic.netinfo)
966 7e8f03e3 Dimitris Aragiorgis
      env.update(n.HooksDict())
967 a5ad5e58 Apollon Oikonomopoulos
968 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
969 5d9bfd87 Apollon Oikonomopoulos
      env["BRIDGE"] = nic.nicparams[constants.NIC_LINK]
970 5d9bfd87 Apollon Oikonomopoulos
971 9d9bded1 Michael Hanselmann
    result = utils.RunCmd([pathutils.KVM_IFUP, tap], env=env)
972 5d9bfd87 Apollon Oikonomopoulos
    if result.failed:
973 afa9bb2e Michael Hanselmann
      raise errors.HypervisorError("Failed to configure interface %s: %s;"
974 afa9bb2e Michael Hanselmann
                                   " network configuration script output: %s" %
975 5d9bfd87 Apollon Oikonomopoulos
                                   (tap, result.fail_reason, result.output))
976 eb58f9b1 Guido Trotter
977 b693125f Tsachy Shacham
  @staticmethod
978 b693125f Tsachy Shacham
  def _VerifyAffinityPackage():
979 b693125f Tsachy Shacham
    if affinity is None:
980 b693125f Tsachy Shacham
      raise errors.HypervisorError("affinity Python package not"
981 5ae4945a Iustin Pop
                                   " found; cannot use CPU pinning under KVM")
982 b693125f Tsachy Shacham
983 b693125f Tsachy Shacham
  @staticmethod
984 b693125f Tsachy Shacham
  def _BuildAffinityCpuMask(cpu_list):
985 b693125f Tsachy Shacham
    """Create a CPU mask suitable for sched_setaffinity from a list of
986 b693125f Tsachy Shacham
    CPUs.
987 b693125f Tsachy Shacham

988 b693125f Tsachy Shacham
    See man taskset for more info on sched_setaffinity masks.
989 b693125f Tsachy Shacham
    For example: [ 0, 2, 5, 6 ] will return 101 (0x65, 0..01100101).
990 b693125f Tsachy Shacham

991 b693125f Tsachy Shacham
    @type cpu_list: list of int
992 b693125f Tsachy Shacham
    @param cpu_list: list of physical CPU numbers to map to vCPUs in order
993 b693125f Tsachy Shacham
    @rtype: int
994 b693125f Tsachy Shacham
    @return: a bit mask of CPU affinities
995 b693125f Tsachy Shacham

996 b693125f Tsachy Shacham
    """
997 b693125f Tsachy Shacham
    if cpu_list == constants.CPU_PINNING_OFF:
998 b693125f Tsachy Shacham
      return constants.CPU_PINNING_ALL_KVM
999 b693125f Tsachy Shacham
    else:
1000 b693125f Tsachy Shacham
      return sum(2 ** cpu for cpu in cpu_list)
1001 b693125f Tsachy Shacham
1002 b693125f Tsachy Shacham
  @classmethod
1003 b693125f Tsachy Shacham
  def _AssignCpuAffinity(cls, cpu_mask, process_id, thread_dict):
1004 b693125f Tsachy Shacham
    """Change CPU affinity for running VM according to given CPU mask.
1005 b693125f Tsachy Shacham

1006 b693125f Tsachy Shacham
    @param cpu_mask: CPU mask as given by the user. e.g. "0-2,4:all:1,3"
1007 b693125f Tsachy Shacham
    @type cpu_mask: string
1008 b693125f Tsachy Shacham
    @param process_id: process ID of KVM process. Used to pin entire VM
1009 b693125f Tsachy Shacham
                       to physical CPUs.
1010 b693125f Tsachy Shacham
    @type process_id: int
1011 b693125f Tsachy Shacham
    @param thread_dict: map of virtual CPUs to KVM thread IDs
1012 b693125f Tsachy Shacham
    @type thread_dict: dict int:int
1013 b693125f Tsachy Shacham

1014 b693125f Tsachy Shacham
    """
1015 b693125f Tsachy Shacham
    # Convert the string CPU mask to a list of list of int's
1016 b693125f Tsachy Shacham
    cpu_list = utils.ParseMultiCpuMask(cpu_mask)
1017 b693125f Tsachy Shacham
1018 b693125f Tsachy Shacham
    if len(cpu_list) == 1:
1019 b693125f Tsachy Shacham
      all_cpu_mapping = cpu_list[0]
1020 b693125f Tsachy Shacham
      if all_cpu_mapping == constants.CPU_PINNING_OFF:
1021 b693125f Tsachy Shacham
        # If CPU pinning has 1 entry that's "all", then do nothing
1022 b693125f Tsachy Shacham
        pass
1023 b693125f Tsachy Shacham
      else:
1024 b693125f Tsachy Shacham
        # If CPU pinning has one non-all entry, map the entire VM to
1025 b693125f Tsachy Shacham
        # one set of physical CPUs
1026 b693125f Tsachy Shacham
        cls._VerifyAffinityPackage()
1027 5ae4945a Iustin Pop
        affinity.set_process_affinity_mask(
1028 5ae4945a Iustin Pop
          process_id, cls._BuildAffinityCpuMask(all_cpu_mapping))
1029 b693125f Tsachy Shacham
    else:
1030 b693125f Tsachy Shacham
      # The number of vCPUs mapped should match the number of vCPUs
1031 b693125f Tsachy Shacham
      # reported by KVM. This was already verified earlier, so
1032 b693125f Tsachy Shacham
      # here only as a sanity check.
1033 b693125f Tsachy Shacham
      assert len(thread_dict) == len(cpu_list)
1034 b693125f Tsachy Shacham
      cls._VerifyAffinityPackage()
1035 b693125f Tsachy Shacham
1036 b693125f Tsachy Shacham
      # For each vCPU, map it to the proper list of physical CPUs
1037 b693125f Tsachy Shacham
      for vcpu, i in zip(cpu_list, range(len(cpu_list))):
1038 b693125f Tsachy Shacham
        affinity.set_process_affinity_mask(thread_dict[i],
1039 5ae4945a Iustin Pop
                                           cls._BuildAffinityCpuMask(vcpu))
1040 b693125f Tsachy Shacham
1041 b693125f Tsachy Shacham
  def _GetVcpuThreadIds(self, instance_name):
1042 b693125f Tsachy Shacham
    """Get a mapping of vCPU no. to thread IDs for the instance
1043 b693125f Tsachy Shacham

1044 b693125f Tsachy Shacham
    @type instance_name: string
1045 b693125f Tsachy Shacham
    @param instance_name: instance in question
1046 b693125f Tsachy Shacham
    @rtype: dictionary of int:int
1047 b693125f Tsachy Shacham
    @return: a dictionary mapping vCPU numbers to thread IDs
1048 b693125f Tsachy Shacham

1049 b693125f Tsachy Shacham
    """
1050 b693125f Tsachy Shacham
    result = {}
1051 b693125f Tsachy Shacham
    output = self._CallMonitorCommand(instance_name, self._CPU_INFO_CMD)
1052 b693125f Tsachy Shacham
    for line in output.stdout.splitlines():
1053 b693125f Tsachy Shacham
      match = self._CPU_INFO_RE.search(line)
1054 b693125f Tsachy Shacham
      if not match:
1055 b693125f Tsachy Shacham
        continue
1056 b693125f Tsachy Shacham
      grp = map(int, match.groups())
1057 b693125f Tsachy Shacham
      result[grp[0]] = grp[1]
1058 b693125f Tsachy Shacham
1059 b693125f Tsachy Shacham
    return result
1060 b693125f Tsachy Shacham
1061 1d8a7812 Andrea Spadaccini
  def _ExecuteCpuAffinity(self, instance_name, cpu_mask):
1062 1d8a7812 Andrea Spadaccini
    """Complete CPU pinning.
1063 b693125f Tsachy Shacham

1064 b693125f Tsachy Shacham
    @type instance_name: string
1065 b693125f Tsachy Shacham
    @param instance_name: name of instance
1066 b693125f Tsachy Shacham
    @type cpu_mask: string
1067 b693125f Tsachy Shacham
    @param cpu_mask: CPU pinning mask as entered by user
1068 b693125f Tsachy Shacham

1069 b693125f Tsachy Shacham
    """
1070 1d8a7812 Andrea Spadaccini
    # Get KVM process ID, to be used if need to pin entire VM
1071 1d8a7812 Andrea Spadaccini
    _, pid, _ = self._InstancePidAlive(instance_name)
1072 1d8a7812 Andrea Spadaccini
    # Get vCPU thread IDs, to be used if need to pin vCPUs separately
1073 1d8a7812 Andrea Spadaccini
    thread_dict = self._GetVcpuThreadIds(instance_name)
1074 1d8a7812 Andrea Spadaccini
    # Run CPU pinning, based on configured mask
1075 1d8a7812 Andrea Spadaccini
    self._AssignCpuAffinity(cpu_mask, pid, thread_dict)
1076 b693125f Tsachy Shacham
1077 eb58f9b1 Guido Trotter
  def ListInstances(self):
1078 eb58f9b1 Guido Trotter
    """Get the list of running instances.
1079 eb58f9b1 Guido Trotter

1080 c41eea6e Iustin Pop
    We can do this by listing our live instances directory and
1081 c41eea6e Iustin Pop
    checking whether the associated kvm process is still alive.
1082 eb58f9b1 Guido Trotter

1083 eb58f9b1 Guido Trotter
    """
1084 eb58f9b1 Guido Trotter
    result = []
1085 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
1086 263b8de6 Guido Trotter
      if self._InstancePidAlive(name)[2]:
1087 eb58f9b1 Guido Trotter
        result.append(name)
1088 eb58f9b1 Guido Trotter
    return result
1089 eb58f9b1 Guido Trotter
1090 eb58f9b1 Guido Trotter
  def GetInstanceInfo(self, instance_name):
1091 eb58f9b1 Guido Trotter
    """Get instance properties.
1092 eb58f9b1 Guido Trotter

1093 4fbb3c60 Guido Trotter
    @type instance_name: string
1094 c41eea6e Iustin Pop
    @param instance_name: the instance name
1095 4fbb3c60 Guido Trotter
    @rtype: tuple of strings
1096 4fbb3c60 Guido Trotter
    @return: (name, id, memory, vcpus, stat, times)
1097 eb58f9b1 Guido Trotter

1098 eb58f9b1 Guido Trotter
    """
1099 1122eb25 Iustin Pop
    _, pid, alive = self._InstancePidAlive(instance_name)
1100 1f8b3a27 Guido Trotter
    if not alive:
1101 eb58f9b1 Guido Trotter
      return None
1102 eb58f9b1 Guido Trotter
1103 263b8de6 Guido Trotter
    _, memory, vcpus = self._InstancePidInfo(pid)
1104 fc84cd5d Guido Trotter
    istat = "---b-"
1105 eb58f9b1 Guido Trotter
    times = "0"
1106 eb58f9b1 Guido Trotter
1107 89da2ff3 Guido Trotter
    try:
1108 89da2ff3 Guido Trotter
      qmp = QmpConnection(self._InstanceQmpMonitor(instance_name))
1109 89da2ff3 Guido Trotter
      qmp.connect()
1110 89da2ff3 Guido Trotter
      vcpus = len(qmp.Execute("query-cpus")[qmp.RETURN_KEY])
1111 89da2ff3 Guido Trotter
      # Will fail if ballooning is not enabled, but we can then just resort to
1112 89da2ff3 Guido Trotter
      # the value above.
1113 89da2ff3 Guido Trotter
      mem_bytes = qmp.Execute("query-balloon")[qmp.RETURN_KEY][qmp.ACTUAL_KEY]
1114 89da2ff3 Guido Trotter
      memory = mem_bytes / 1048576
1115 89da2ff3 Guido Trotter
    except errors.HypervisorError:
1116 89da2ff3 Guido Trotter
      pass
1117 89da2ff3 Guido Trotter
1118 fc84cd5d Guido Trotter
    return (instance_name, pid, memory, vcpus, istat, times)
1119 eb58f9b1 Guido Trotter
1120 eb58f9b1 Guido Trotter
  def GetAllInstancesInfo(self):
1121 eb58f9b1 Guido Trotter
    """Get properties of all instances.
1122 eb58f9b1 Guido Trotter

1123 c41eea6e Iustin Pop
    @return: list of tuples (name, id, memory, vcpus, stat, times)
1124 c41eea6e Iustin Pop

1125 eb58f9b1 Guido Trotter
    """
1126 eb58f9b1 Guido Trotter
    data = []
1127 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
1128 263b8de6 Guido Trotter
      try:
1129 263b8de6 Guido Trotter
        info = self.GetInstanceInfo(name)
1130 263b8de6 Guido Trotter
      except errors.HypervisorError:
1131 3bc145d8 Bernardo Dal Seno
        # Ignore exceptions due to instances being shut down
1132 263b8de6 Guido Trotter
        continue
1133 263b8de6 Guido Trotter
      if info:
1134 263b8de6 Guido Trotter
        data.append(info)
1135 eb58f9b1 Guido Trotter
    return data
1136 eb58f9b1 Guido Trotter
1137 ec3919aa Dimitris Aragiorgis
  def _GenerateKVMBlockDevicesOptions(self, instance, block_devices, kvmhelp):
1138 ec3919aa Dimitris Aragiorgis
1139 ec3919aa Dimitris Aragiorgis
    hvp = instance.hvparams
1140 ec3919aa Dimitris Aragiorgis
    boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK
1141 68c9f726 Dimitris Aragiorgis
    kvm_path = hvp[constants.HV_KVM_PATH]
1142 ec3919aa Dimitris Aragiorgis
1143 ec3919aa Dimitris Aragiorgis
    # whether this is an older KVM version that uses the boot=on flag
1144 ec3919aa Dimitris Aragiorgis
    # on devices
1145 ec3919aa Dimitris Aragiorgis
    needs_boot_flag = self._BOOT_RE.search(kvmhelp)
1146 ec3919aa Dimitris Aragiorgis
1147 ec3919aa Dimitris Aragiorgis
    dev_opts = []
1148 68c9f726 Dimitris Aragiorgis
    device_driver = None
1149 ec3919aa Dimitris Aragiorgis
    disk_type = hvp[constants.HV_DISK_TYPE]
1150 ec3919aa Dimitris Aragiorgis
    if disk_type == constants.HT_DISK_PARAVIRTUAL:
1151 ec3919aa Dimitris Aragiorgis
      if_val = ",if=%s" % self._VIRTIO
1152 68c9f726 Dimitris Aragiorgis
      try:
1153 68c9f726 Dimitris Aragiorgis
        devlist = self._GetKVMOutput(kvm_path, self._KVMOPT_DEVICELIST)
1154 68c9f726 Dimitris Aragiorgis
        if self._VIRTIO_BLK_RE.search(devlist):
1155 68c9f726 Dimitris Aragiorgis
          # TODO: uncomment when -device is used
1156 68c9f726 Dimitris Aragiorgis
          # if_val = ",if=none"
1157 68c9f726 Dimitris Aragiorgis
          # will be passed in -device option as driver
1158 68c9f726 Dimitris Aragiorgis
          device_driver = self._VIRTIO_BLK_PCI
1159 68c9f726 Dimitris Aragiorgis
      except errors.HypervisorError, _:
1160 68c9f726 Dimitris Aragiorgis
        pass
1161 ec3919aa Dimitris Aragiorgis
    else:
1162 ec3919aa Dimitris Aragiorgis
      if_val = ",if=%s" % disk_type
1163 ec3919aa Dimitris Aragiorgis
    # Cache mode
1164 ec3919aa Dimitris Aragiorgis
    disk_cache = hvp[constants.HV_DISK_CACHE]
1165 ec3919aa Dimitris Aragiorgis
    if instance.disk_template in constants.DTS_EXT_MIRROR:
1166 ec3919aa Dimitris Aragiorgis
      if disk_cache != "none":
1167 ec3919aa Dimitris Aragiorgis
        # TODO: make this a hard error, instead of a silent overwrite
1168 ec3919aa Dimitris Aragiorgis
        logging.warning("KVM: overriding disk_cache setting '%s' with 'none'"
1169 ec3919aa Dimitris Aragiorgis
                        " to prevent shared storage corruption on migration",
1170 ec3919aa Dimitris Aragiorgis
                        disk_cache)
1171 ec3919aa Dimitris Aragiorgis
      cache_val = ",cache=none"
1172 ec3919aa Dimitris Aragiorgis
    elif disk_cache != constants.HT_CACHE_DEFAULT:
1173 ec3919aa Dimitris Aragiorgis
      cache_val = ",cache=%s" % disk_cache
1174 ec3919aa Dimitris Aragiorgis
    else:
1175 ec3919aa Dimitris Aragiorgis
      cache_val = ""
1176 ec3919aa Dimitris Aragiorgis
    for cfdev, dev_path in block_devices:
1177 ec3919aa Dimitris Aragiorgis
      if cfdev.mode != constants.DISK_RDWR:
1178 ec3919aa Dimitris Aragiorgis
        raise errors.HypervisorError("Instance has read-only disks which"
1179 ec3919aa Dimitris Aragiorgis
                                     " are not supported by KVM")
1180 ec3919aa Dimitris Aragiorgis
      # TODO: handle FD_LOOP and FD_BLKTAP (?)
1181 ec3919aa Dimitris Aragiorgis
      boot_val = ""
1182 ec3919aa Dimitris Aragiorgis
      if boot_disk:
1183 ec3919aa Dimitris Aragiorgis
        dev_opts.extend(["-boot", "c"])
1184 ec3919aa Dimitris Aragiorgis
        boot_disk = False
1185 ec3919aa Dimitris Aragiorgis
        if needs_boot_flag and disk_type != constants.HT_DISK_IDE:
1186 ec3919aa Dimitris Aragiorgis
          boot_val = ",boot=on"
1187 ec3919aa Dimitris Aragiorgis
      drive_val = "file=%s,format=raw%s%s%s" % \
1188 ec3919aa Dimitris Aragiorgis
                  (dev_path, if_val, boot_val, cache_val)
1189 ec3919aa Dimitris Aragiorgis
1190 68c9f726 Dimitris Aragiorgis
      if device_driver:
1191 68c9f726 Dimitris Aragiorgis
        pass
1192 ec3919aa Dimitris Aragiorgis
      dev_opts.extend(["-drive", drive_val])
1193 ec3919aa Dimitris Aragiorgis
1194 ec3919aa Dimitris Aragiorgis
    return dev_opts
1195 ec3919aa Dimitris Aragiorgis
1196 b73f1c59 Guido Trotter
  def _GenerateKVMRuntime(self, instance, block_devices, startup_paused,
1197 b73f1c59 Guido Trotter
                          kvmhelp):
1198 ee5f20b0 Guido Trotter
    """Generate KVM information to start an instance.
1199 eb58f9b1 Guido Trotter

1200 b73f1c59 Guido Trotter
    @type kvmhelp: string
1201 b73f1c59 Guido Trotter
    @param kvmhelp: output of kvm --help
1202 839642c2 Iustin Pop
    @attention: this function must not have any side-effects; for
1203 839642c2 Iustin Pop
        example, it must not write to the filesystem, or read values
1204 839642c2 Iustin Pop
        from the current system the are expected to differ between
1205 839642c2 Iustin Pop
        nodes, since it is only run once at instance startup;
1206 839642c2 Iustin Pop
        actions/kvm arguments that can vary between systems should be
1207 839642c2 Iustin Pop
        done in L{_ExecuteKVMRuntime}
1208 839642c2 Iustin Pop

1209 eb58f9b1 Guido Trotter
    """
1210 4888a609 Guido Trotter
    # pylint: disable=R0912,R0914,R0915
1211 4888a609 Guido Trotter
    hvp = instance.hvparams
1212 81e265f5 Guido Trotter
    self.ValidateParameters(hvp)
1213 4304964a Guido Trotter
1214 e687ec01 Michael Hanselmann
    pidfile = self._InstancePidFile(instance.name)
1215 4b9638dc Guido Trotter
    kvm = hvp[constants.HV_KVM_PATH]
1216 eb58f9b1 Guido Trotter
    kvm_cmd = [kvm]
1217 c6a39fc2 Guido Trotter
    # used just by the vnc server, if enabled
1218 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-name", instance.name])
1219 f5a4b9ce Guido Trotter
    kvm_cmd.extend(["-m", instance.beparams[constants.BE_MAXMEM]])
1220 4888a609 Guido Trotter
1221 4888a609 Guido Trotter
    smp_list = ["%s" % instance.beparams[constants.BE_VCPUS]]
1222 4888a609 Guido Trotter
    if hvp[constants.HV_CPU_CORES]:
1223 4888a609 Guido Trotter
      smp_list.append("cores=%s" % hvp[constants.HV_CPU_CORES])
1224 4888a609 Guido Trotter
    if hvp[constants.HV_CPU_THREADS]:
1225 4888a609 Guido Trotter
      smp_list.append("threads=%s" % hvp[constants.HV_CPU_THREADS])
1226 4888a609 Guido Trotter
    if hvp[constants.HV_CPU_SOCKETS]:
1227 4888a609 Guido Trotter
      smp_list.append("sockets=%s" % hvp[constants.HV_CPU_SOCKETS])
1228 4888a609 Guido Trotter
1229 4888a609 Guido Trotter
    kvm_cmd.extend(["-smp", ",".join(smp_list)])
1230 4888a609 Guido Trotter
1231 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-pidfile", pidfile])
1232 fcf5b670 Guido Trotter
    kvm_cmd.extend(["-balloon", "virtio"])
1233 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-daemonize"])
1234 6b5605e8 Iustin Pop
    if not instance.hvparams[constants.HV_ACPI]:
1235 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-no-acpi"])
1236 990ade2d Stephen Shirley
    if instance.hvparams[constants.HV_REBOOT_BEHAVIOR] == \
1237 990ade2d Stephen Shirley
        constants.INSTANCE_REBOOT_EXIT:
1238 990ade2d Stephen Shirley
      kvm_cmd.extend(["-no-reboot"])
1239 eb58f9b1 Guido Trotter
1240 4ab75599 Dimitris Aragiorgis
    mversion = hvp[constants.HV_KVM_MACHINE_VERSION]
1241 4ab75599 Dimitris Aragiorgis
    if not mversion:
1242 4b9638dc Guido Trotter
      mversion = self._GetDefaultMachineVersion(kvm)
1243 8cb5634a Guido Trotter
    if self._MACHINE_RE.search(kvmhelp):
1244 8cb5634a Guido Trotter
      # TODO (2.8): kernel_irqchip and kvm_shadow_mem machine properties, as
1245 8cb5634a Guido Trotter
      # extra hypervisor parameters. We should also investigate whether and how
1246 8cb5634a Guido Trotter
      # shadow_mem should be considered for the resource model.
1247 8cb5634a Guido Trotter
      if (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED):
1248 8cb5634a Guido Trotter
        specprop = ",accel=kvm"
1249 8cb5634a Guido Trotter
      else:
1250 8cb5634a Guido Trotter
        specprop = ""
1251 8cb5634a Guido Trotter
      machinespec = "%s%s" % (mversion, specprop)
1252 8cb5634a Guido Trotter
      kvm_cmd.extend(["-machine", machinespec])
1253 8cb5634a Guido Trotter
    else:
1254 8cb5634a Guido Trotter
      kvm_cmd.extend(["-M", mversion])
1255 8cb5634a Guido Trotter
      if (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED and
1256 8cb5634a Guido Trotter
          self._ENABLE_KVM_RE.search(kvmhelp)):
1257 8cb5634a Guido Trotter
        kvm_cmd.extend(["-enable-kvm"])
1258 8cb5634a Guido Trotter
      elif (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_DISABLED and
1259 8cb5634a Guido Trotter
            self._DISABLE_KVM_RE.search(kvmhelp)):
1260 8cb5634a Guido Trotter
        kvm_cmd.extend(["-disable-kvm"])
1261 4ab75599 Dimitris Aragiorgis
1262 2b846304 Iustin Pop
    kernel_path = hvp[constants.HV_KERNEL_PATH]
1263 2b846304 Iustin Pop
    if kernel_path:
1264 ec3919aa Dimitris Aragiorgis
      boot_cdrom = boot_floppy = boot_network = False
1265 2b846304 Iustin Pop
    else:
1266 2b846304 Iustin Pop
      boot_cdrom = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_CDROM
1267 2b846304 Iustin Pop
      boot_floppy = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_FLOPPY
1268 2b846304 Iustin Pop
      boot_network = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_NETWORK
1269 8745c3d7 Guido Trotter
1270 b693125f Tsachy Shacham
    if startup_paused:
1271 b693125f Tsachy Shacham
      kvm_cmd.extend([_KVM_START_PAUSED_FLAG])
1272 b693125f Tsachy Shacham
1273 8745c3d7 Guido Trotter
    if boot_network:
1274 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-boot", "n"])
1275 1213604d Guido Trotter
1276 24be50e0 Iustin Pop
    # whether this is an older KVM version that uses the boot=on flag
1277 24be50e0 Iustin Pop
    # on devices
1278 0ad7f5d8 Guido Trotter
    needs_boot_flag = self._BOOT_RE.search(kvmhelp)
1279 24be50e0 Iustin Pop
1280 a985b417 Iustin Pop
    disk_type = hvp[constants.HV_DISK_TYPE]
1281 eb58f9b1 Guido Trotter
1282 cc130cc7 Marco Casavecchia
    #Now we can specify a different device type for CDROM devices.
1283 cc130cc7 Marco Casavecchia
    cdrom_disk_type = hvp[constants.HV_KVM_CDROM_DISK_TYPE]
1284 cc130cc7 Marco Casavecchia
    if not cdrom_disk_type:
1285 cc130cc7 Marco Casavecchia
      cdrom_disk_type = disk_type
1286 cc130cc7 Marco Casavecchia
1287 a985b417 Iustin Pop
    iso_image = hvp[constants.HV_CDROM_IMAGE_PATH]
1288 66d5dbef Guido Trotter
    if iso_image:
1289 d0c8c01d Iustin Pop
      options = ",format=raw,media=cdrom"
1290 24be50e0 Iustin Pop
      # set cdrom 'if' type
1291 66d5dbef Guido Trotter
      if boot_cdrom:
1292 24be50e0 Iustin Pop
        actual_cdrom_type = constants.HT_DISK_IDE
1293 24be50e0 Iustin Pop
      elif cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
1294 24be50e0 Iustin Pop
        actual_cdrom_type = "virtio"
1295 9dd363eb Guido Trotter
      else:
1296 24be50e0 Iustin Pop
        actual_cdrom_type = cdrom_disk_type
1297 24be50e0 Iustin Pop
      if_val = ",if=%s" % actual_cdrom_type
1298 24be50e0 Iustin Pop
      # set boot flag, if needed
1299 24be50e0 Iustin Pop
      boot_val = ""
1300 24be50e0 Iustin Pop
      if boot_cdrom:
1301 24be50e0 Iustin Pop
        kvm_cmd.extend(["-boot", "d"])
1302 24be50e0 Iustin Pop
        if needs_boot_flag:
1303 24be50e0 Iustin Pop
          boot_val = ",boot=on"
1304 24be50e0 Iustin Pop
      # and finally build the entire '-drive' value
1305 24be50e0 Iustin Pop
      drive_val = "file=%s%s%s%s" % (iso_image, options, if_val, boot_val)
1306 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1307 66d5dbef Guido Trotter
1308 cc130cc7 Marco Casavecchia
    iso_image2 = hvp[constants.HV_KVM_CDROM2_IMAGE_PATH]
1309 cc130cc7 Marco Casavecchia
    if iso_image2:
1310 d0c8c01d Iustin Pop
      options = ",format=raw,media=cdrom"
1311 cc130cc7 Marco Casavecchia
      if cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
1312 d0c8c01d Iustin Pop
        if_val = ",if=virtio"
1313 cc130cc7 Marco Casavecchia
      else:
1314 d0c8c01d Iustin Pop
        if_val = ",if=%s" % cdrom_disk_type
1315 24be50e0 Iustin Pop
      drive_val = "file=%s%s%s" % (iso_image2, options, if_val)
1316 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1317 cc130cc7 Marco Casavecchia
1318 cc130cc7 Marco Casavecchia
    floppy_image = hvp[constants.HV_KVM_FLOPPY_IMAGE_PATH]
1319 cc130cc7 Marco Casavecchia
    if floppy_image:
1320 d0c8c01d Iustin Pop
      options = ",format=raw,media=disk"
1321 cc130cc7 Marco Casavecchia
      if boot_floppy:
1322 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-boot", "a"])
1323 d0c8c01d Iustin Pop
        options = "%s,boot=on" % options
1324 d0c8c01d Iustin Pop
      if_val = ",if=floppy"
1325 d0c8c01d Iustin Pop
      options = "%s%s" % (options, if_val)
1326 d0c8c01d Iustin Pop
      drive_val = "file=%s%s" % (floppy_image, options)
1327 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1328 cc130cc7 Marco Casavecchia
1329 df5ab9f0 Guido Trotter
    if kernel_path:
1330 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-kernel", kernel_path])
1331 a985b417 Iustin Pop
      initrd_path = hvp[constants.HV_INITRD_PATH]
1332 df5ab9f0 Guido Trotter
      if initrd_path:
1333 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-initrd", initrd_path])
1334 d0c8c01d Iustin Pop
      root_append = ["root=%s" % hvp[constants.HV_ROOT_PATH],
1335 07813a9e Iustin Pop
                     hvp[constants.HV_KERNEL_ARGS]]
1336 07813a9e Iustin Pop
      if hvp[constants.HV_SERIAL_CONSOLE]:
1337 14fd6c81 Guido Trotter
        serial_speed = hvp[constants.HV_SERIAL_SPEED]
1338 14fd6c81 Guido Trotter
        root_append.append("console=ttyS0,%s" % serial_speed)
1339 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-append", " ".join(root_append)])
1340 eb58f9b1 Guido Trotter
1341 4f958b0b Miguel Di Ciurcio Filho
    mem_path = hvp[constants.HV_MEM_PATH]
1342 4f958b0b Miguel Di Ciurcio Filho
    if mem_path:
1343 9d3015f9 Guido Trotter
      kvm_cmd.extend(["-mem-path", mem_path, "-mem-prealloc"])
1344 4f958b0b Miguel Di Ciurcio Filho
1345 596b2459 Guido Trotter
    monitor_dev = ("unix:%s,server,nowait" %
1346 596b2459 Guido Trotter
                   self._InstanceMonitor(instance.name))
1347 596b2459 Guido Trotter
    kvm_cmd.extend(["-monitor", monitor_dev])
1348 596b2459 Guido Trotter
    if hvp[constants.HV_SERIAL_CONSOLE]:
1349 596b2459 Guido Trotter
      serial_dev = ("unix:%s,server,nowait" %
1350 596b2459 Guido Trotter
                    self._InstanceSerial(instance.name))
1351 596b2459 Guido Trotter
      kvm_cmd.extend(["-serial", serial_dev])
1352 596b2459 Guido Trotter
    else:
1353 596b2459 Guido Trotter
      kvm_cmd.extend(["-serial", "none"])
1354 596b2459 Guido Trotter
1355 a985b417 Iustin Pop
    mouse_type = hvp[constants.HV_USB_MOUSE]
1356 31f6f67a Guido Trotter
    vnc_bind_address = hvp[constants.HV_VNC_BIND_ADDRESS]
1357 596b2459 Guido Trotter
    spice_bind = hvp[constants.HV_KVM_SPICE_BIND]
1358 596b2459 Guido Trotter
    spice_ip_version = None
1359 31f6f67a Guido Trotter
1360 a900a30c Guido Trotter
    kvm_cmd.extend(["-usb"])
1361 a900a30c Guido Trotter
1362 11344a50 Guido Trotter
    if mouse_type:
1363 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usbdevice", mouse_type])
1364 31f6f67a Guido Trotter
    elif vnc_bind_address:
1365 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usbdevice", constants.HT_MOUSE_TABLET])
1366 11344a50 Guido Trotter
1367 8470c8db Guido Trotter
    if vnc_bind_address:
1368 8b312c1d Manuel Franceschini
      if netutils.IP4Address.IsValid(vnc_bind_address):
1369 377d74c9 Guido Trotter
        if instance.network_port > constants.VNC_BASE_PORT:
1370 377d74c9 Guido Trotter
          display = instance.network_port - constants.VNC_BASE_PORT
1371 14f5f1b6 Manuel Franceschini
          if vnc_bind_address == constants.IP4_ADDRESS_ANY:
1372 d0c8c01d Iustin Pop
            vnc_arg = ":%d" % (display)
1373 8447f52b Guido Trotter
          else:
1374 d0c8c01d Iustin Pop
            vnc_arg = "%s:%d" % (vnc_bind_address, display)
1375 8470c8db Guido Trotter
        else:
1376 afa9bb2e Michael Hanselmann
          logging.error("Network port is not a valid VNC display (%d < %d),"
1377 afa9bb2e Michael Hanselmann
                        " not starting VNC",
1378 afa9bb2e Michael Hanselmann
                        instance.network_port, constants.VNC_BASE_PORT)
1379 d0c8c01d Iustin Pop
          vnc_arg = "none"
1380 8b2d1013 Guido Trotter
1381 8b2d1013 Guido Trotter
        # Only allow tls and other option when not binding to a file, for now.
1382 8b2d1013 Guido Trotter
        # kvm/qemu gets confused otherwise about the filename to use.
1383 d0c8c01d Iustin Pop
        vnc_append = ""
1384 a985b417 Iustin Pop
        if hvp[constants.HV_VNC_TLS]:
1385 d0c8c01d Iustin Pop
          vnc_append = "%s,tls" % vnc_append
1386 a985b417 Iustin Pop
          if hvp[constants.HV_VNC_X509_VERIFY]:
1387 d0c8c01d Iustin Pop
            vnc_append = "%s,x509verify=%s" % (vnc_append,
1388 a985b417 Iustin Pop
                                               hvp[constants.HV_VNC_X509])
1389 a985b417 Iustin Pop
          elif hvp[constants.HV_VNC_X509]:
1390 d0c8c01d Iustin Pop
            vnc_append = "%s,x509=%s" % (vnc_append,
1391 a985b417 Iustin Pop
                                         hvp[constants.HV_VNC_X509])
1392 6e6bb8d5 Guido Trotter
        if hvp[constants.HV_VNC_PASSWORD_FILE]:
1393 d0c8c01d Iustin Pop
          vnc_append = "%s,password" % vnc_append
1394 6e6bb8d5 Guido Trotter
1395 d0c8c01d Iustin Pop
        vnc_arg = "%s%s" % (vnc_arg, vnc_append)
1396 8b2d1013 Guido Trotter
1397 8470c8db Guido Trotter
      else:
1398 d0c8c01d Iustin Pop
        vnc_arg = "unix:%s/%s.vnc" % (vnc_bind_address, instance.name)
1399 8b2d1013 Guido Trotter
1400 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-vnc", vnc_arg])
1401 596b2459 Guido Trotter
    elif spice_bind:
1402 839642c2 Iustin Pop
      # FIXME: this is wrong here; the iface ip address differs
1403 839642c2 Iustin Pop
      # between systems, so it should be done in _ExecuteKVMRuntime
1404 b1cb62bd Andrea Spadaccini
      if netutils.IsValidInterface(spice_bind):
1405 b1cb62bd Andrea Spadaccini
        # The user specified a network interface, we have to figure out the IP
1406 b1cb62bd Andrea Spadaccini
        # address.
1407 b1cb62bd Andrea Spadaccini
        addresses = netutils.GetInterfaceIpAddresses(spice_bind)
1408 b1cb62bd Andrea Spadaccini
        spice_ip_version = hvp[constants.HV_KVM_SPICE_IP_VERSION]
1409 b1cb62bd Andrea Spadaccini
1410 b1cb62bd Andrea Spadaccini
        # if the user specified an IP version and the interface does not
1411 b1cb62bd Andrea Spadaccini
        # have that kind of IP addresses, throw an exception
1412 b1cb62bd Andrea Spadaccini
        if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
1413 b1cb62bd Andrea Spadaccini
          if not addresses[spice_ip_version]:
1414 afa9bb2e Michael Hanselmann
            raise errors.HypervisorError("SPICE: Unable to get an IPv%s address"
1415 b1cb62bd Andrea Spadaccini
                                         " for %s" % (spice_ip_version,
1416 b1cb62bd Andrea Spadaccini
                                                      spice_bind))
1417 b1cb62bd Andrea Spadaccini
1418 b1cb62bd Andrea Spadaccini
        # the user did not specify an IP version, we have to figure it out
1419 b1cb62bd Andrea Spadaccini
        elif (addresses[constants.IP4_VERSION] and
1420 b1cb62bd Andrea Spadaccini
              addresses[constants.IP6_VERSION]):
1421 b1cb62bd Andrea Spadaccini
          # we have both ipv4 and ipv6, let's use the cluster default IP
1422 b1cb62bd Andrea Spadaccini
          # version
1423 b1cb62bd Andrea Spadaccini
          cluster_family = ssconf.SimpleStore().GetPrimaryIPFamily()
1424 65107a2f Michael Hanselmann
          spice_ip_version = \
1425 65107a2f Michael Hanselmann
            netutils.IPAddress.GetVersionFromAddressFamily(cluster_family)
1426 b1cb62bd Andrea Spadaccini
        elif addresses[constants.IP4_VERSION]:
1427 b1cb62bd Andrea Spadaccini
          spice_ip_version = constants.IP4_VERSION
1428 b845c8a1 Andrea Spadaccini
        elif addresses[constants.IP6_VERSION]:
1429 b1cb62bd Andrea Spadaccini
          spice_ip_version = constants.IP6_VERSION
1430 b845c8a1 Andrea Spadaccini
        else:
1431 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: Unable to get an IP address"
1432 b845c8a1 Andrea Spadaccini
                                       " for %s" % (spice_bind))
1433 b1cb62bd Andrea Spadaccini
1434 b1cb62bd Andrea Spadaccini
        spice_address = addresses[spice_ip_version][0]
1435 b1cb62bd Andrea Spadaccini
1436 b1cb62bd Andrea Spadaccini
      else:
1437 b1cb62bd Andrea Spadaccini
        # spice_bind is known to be a valid IP address, because
1438 b1cb62bd Andrea Spadaccini
        # ValidateParameters checked it.
1439 b1cb62bd Andrea Spadaccini
        spice_address = spice_bind
1440 b1cb62bd Andrea Spadaccini
1441 bfe86c76 Andrea Spadaccini
      spice_arg = "addr=%s" % spice_address
1442 bfe86c76 Andrea Spadaccini
      if hvp[constants.HV_KVM_SPICE_USE_TLS]:
1443 5ae4945a Iustin Pop
        spice_arg = ("%s,tls-port=%s,x509-cacert-file=%s" %
1444 5ae4945a Iustin Pop
                     (spice_arg, instance.network_port,
1445 9d9bded1 Michael Hanselmann
                      pathutils.SPICE_CACERT_FILE))
1446 5ae4945a Iustin Pop
        spice_arg = ("%s,x509-key-file=%s,x509-cert-file=%s" %
1447 9d9bded1 Michael Hanselmann
                     (spice_arg, pathutils.SPICE_CERT_FILE,
1448 9d9bded1 Michael Hanselmann
                      pathutils.SPICE_CERT_FILE))
1449 3e40b587 Andrea Spadaccini
        tls_ciphers = hvp[constants.HV_KVM_SPICE_TLS_CIPHERS]
1450 3e40b587 Andrea Spadaccini
        if tls_ciphers:
1451 3e40b587 Andrea Spadaccini
          spice_arg = "%s,tls-ciphers=%s" % (spice_arg, tls_ciphers)
1452 bfe86c76 Andrea Spadaccini
      else:
1453 bfe86c76 Andrea Spadaccini
        spice_arg = "%s,port=%s" % (spice_arg, instance.network_port)
1454 bfe86c76 Andrea Spadaccini
1455 b451c4c7 Andrea Spadaccini
      if not hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]:
1456 b451c4c7 Andrea Spadaccini
        spice_arg = "%s,disable-ticketing" % spice_arg
1457 b451c4c7 Andrea Spadaccini
1458 11ae7a0a Andrea Spadaccini
      if spice_ip_version:
1459 11ae7a0a Andrea Spadaccini
        spice_arg = "%s,ipv%s" % (spice_arg, spice_ip_version)
1460 b1cb62bd Andrea Spadaccini
1461 ea064d24 Andrea Spadaccini
      # Image compression options
1462 ea064d24 Andrea Spadaccini
      img_lossless = hvp[constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR]
1463 ea064d24 Andrea Spadaccini
      img_jpeg = hvp[constants.HV_KVM_SPICE_JPEG_IMG_COMPR]
1464 ea064d24 Andrea Spadaccini
      img_zlib_glz = hvp[constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR]
1465 ea064d24 Andrea Spadaccini
      if img_lossless:
1466 ea064d24 Andrea Spadaccini
        spice_arg = "%s,image-compression=%s" % (spice_arg, img_lossless)
1467 ea064d24 Andrea Spadaccini
      if img_jpeg:
1468 ea064d24 Andrea Spadaccini
        spice_arg = "%s,jpeg-wan-compression=%s" % (spice_arg, img_jpeg)
1469 ea064d24 Andrea Spadaccini
      if img_zlib_glz:
1470 ea064d24 Andrea Spadaccini
        spice_arg = "%s,zlib-glz-wan-compression=%s" % (spice_arg, img_zlib_glz)
1471 ea064d24 Andrea Spadaccini
1472 ea064d24 Andrea Spadaccini
      # Video stream detection
1473 ea064d24 Andrea Spadaccini
      video_streaming = hvp[constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION]
1474 ea064d24 Andrea Spadaccini
      if video_streaming:
1475 ea064d24 Andrea Spadaccini
        spice_arg = "%s,streaming-video=%s" % (spice_arg, video_streaming)
1476 ea064d24 Andrea Spadaccini
1477 ea064d24 Andrea Spadaccini
      # Audio compression, by default in qemu-kvm it is on
1478 ea064d24 Andrea Spadaccini
      if not hvp[constants.HV_KVM_SPICE_AUDIO_COMPR]:
1479 ea064d24 Andrea Spadaccini
        spice_arg = "%s,playback-compression=off" % spice_arg
1480 3e40b587 Andrea Spadaccini
      if not hvp[constants.HV_KVM_SPICE_USE_VDAGENT]:
1481 3e40b587 Andrea Spadaccini
        spice_arg = "%s,agent-mouse=off" % spice_arg
1482 447af814 Nikos Skalkotos
      else:
1483 447af814 Nikos Skalkotos
        # Enable the spice agent communication channel between the host and the
1484 447af814 Nikos Skalkotos
        # agent.
1485 447af814 Nikos Skalkotos
        kvm_cmd.extend(["-device", "virtio-serial-pci"])
1486 afa9bb2e Michael Hanselmann
        kvm_cmd.extend([
1487 afa9bb2e Michael Hanselmann
          "-device",
1488 afa9bb2e Michael Hanselmann
          "virtserialport,chardev=spicechannel0,name=com.redhat.spice.0",
1489 afa9bb2e Michael Hanselmann
          ])
1490 447af814 Nikos Skalkotos
        kvm_cmd.extend(["-chardev", "spicevmc,id=spicechannel0,name=vdagent"])
1491 ea064d24 Andrea Spadaccini
1492 b1cb62bd Andrea Spadaccini
      logging.info("KVM: SPICE will listen on port %s", instance.network_port)
1493 b1cb62bd Andrea Spadaccini
      kvm_cmd.extend(["-spice", spice_arg])
1494 b1cb62bd Andrea Spadaccini
1495 596b2459 Guido Trotter
    else:
1496 99c7cd5b Guido Trotter
      # From qemu 1.4 -nographic is incompatible with -daemonize. The new way
1497 99c7cd5b Guido Trotter
      # also works in earlier versions though (tested with 1.1 and 1.3)
1498 99c7cd5b Guido Trotter
      if self._DISPLAY_RE.search(kvmhelp):
1499 99c7cd5b Guido Trotter
        kvm_cmd.extend(["-display", "none"])
1500 99c7cd5b Guido Trotter
      else:
1501 99c7cd5b Guido Trotter
        kvm_cmd.extend(["-nographic"])
1502 596b2459 Guido Trotter
1503 6b970cef Jun Futagawa
    if hvp[constants.HV_USE_LOCALTIME]:
1504 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-localtime"])
1505 6b970cef Jun Futagawa
1506 547a63b7 Balazs Lecz
    if hvp[constants.HV_KVM_USE_CHROOT]:
1507 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-chroot", self._InstanceChrootDir(instance.name)])
1508 547a63b7 Balazs Lecz
1509 7cb42171 Nikita Staroverov
    # Add qemu-KVM -cpu param
1510 7cb42171 Nikita Staroverov
    if hvp[constants.HV_CPU_TYPE]:
1511 7cb42171 Nikita Staroverov
      kvm_cmd.extend(["-cpu", hvp[constants.HV_CPU_TYPE]])
1512 7cb42171 Nikita Staroverov
1513 2fddb144 Guido Trotter
    # As requested by music lovers
1514 2fddb144 Guido Trotter
    if hvp[constants.HV_SOUNDHW]:
1515 2fddb144 Guido Trotter
      kvm_cmd.extend(["-soundhw", hvp[constants.HV_SOUNDHW]])
1516 2fddb144 Guido Trotter
1517 7589346f Guido Trotter
    # Pass a -vga option if requested, or if spice is used, for backwards
1518 7589346f Guido Trotter
    # compatibility.
1519 7589346f Guido Trotter
    if hvp[constants.HV_VGA]:
1520 7589346f Guido Trotter
      kvm_cmd.extend(["-vga", hvp[constants.HV_VGA]])
1521 7589346f Guido Trotter
    elif spice_bind:
1522 7589346f Guido Trotter
      kvm_cmd.extend(["-vga", "qxl"])
1523 7589346f Guido Trotter
1524 156681c1 Guido Trotter
    # Various types of usb devices, comma separated
1525 156681c1 Guido Trotter
    if hvp[constants.HV_USB_DEVICES]:
1526 156681c1 Guido Trotter
      for dev in hvp[constants.HV_USB_DEVICES].split(","):
1527 156681c1 Guido Trotter
        kvm_cmd.extend(["-usbdevice", dev])
1528 156681c1 Guido Trotter
1529 e6f24d89 Guido Trotter
    if hvp[constants.HV_KVM_EXTRA]:
1530 a967416c Guido Trotter
      kvm_cmd.extend(hvp[constants.HV_KVM_EXTRA].split(" "))
1531 e6f24d89 Guido Trotter
1532 8bbcbb9e Dimitris Aragiorgis
    kvm_disks = []
1533 8bbcbb9e Dimitris Aragiorgis
    for disk, dev_path in block_devices:
1534 8bbcbb9e Dimitris Aragiorgis
      kvm_disks.append((disk, dev_path))
1535 8bbcbb9e Dimitris Aragiorgis
1536 8bbcbb9e Dimitris Aragiorgis
    kvm_nics = []
1537 8bbcbb9e Dimitris Aragiorgis
    for nic in instance.nics:
1538 8bbcbb9e Dimitris Aragiorgis
      kvm_nics.append(nic)
1539 8bbcbb9e Dimitris Aragiorgis
1540 a985b417 Iustin Pop
    hvparams = hvp
1541 ee5f20b0 Guido Trotter
1542 8bbcbb9e Dimitris Aragiorgis
    return (kvm_cmd, kvm_nics, hvparams, kvm_disks)
1543 ee5f20b0 Guido Trotter
1544 38e250ba Guido Trotter
  def _WriteKVMRuntime(self, instance_name, data):
1545 38e250ba Guido Trotter
    """Write an instance's KVM runtime
1546 38e250ba Guido Trotter

1547 38e250ba Guido Trotter
    """
1548 38e250ba Guido Trotter
    try:
1549 38e250ba Guido Trotter
      utils.WriteFile(self._InstanceKVMRuntime(instance_name),
1550 38e250ba Guido Trotter
                      data=data)
1551 90c024f6 Guido Trotter
    except EnvironmentError, err:
1552 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to save KVM runtime file: %s" % err)
1553 38e250ba Guido Trotter
1554 38e250ba Guido Trotter
  def _ReadKVMRuntime(self, instance_name):
1555 38e250ba Guido Trotter
    """Read an instance's KVM runtime
1556 38e250ba Guido Trotter

1557 38e250ba Guido Trotter
    """
1558 38e250ba Guido Trotter
    try:
1559 38e250ba Guido Trotter
      file_content = utils.ReadFile(self._InstanceKVMRuntime(instance_name))
1560 90c024f6 Guido Trotter
    except EnvironmentError, err:
1561 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to load KVM runtime file: %s" % err)
1562 38e250ba Guido Trotter
    return file_content
1563 38e250ba Guido Trotter
1564 38e250ba Guido Trotter
  def _SaveKVMRuntime(self, instance, kvm_runtime):
1565 38e250ba Guido Trotter
    """Save an instance's KVM runtime
1566 38e250ba Guido Trotter

1567 38e250ba Guido Trotter
    """
1568 8bbcbb9e Dimitris Aragiorgis
    kvm_cmd, kvm_nics, hvparams, block_devices = kvm_runtime
1569 8bbcbb9e Dimitris Aragiorgis
1570 38e250ba Guido Trotter
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
1571 8bbcbb9e Dimitris Aragiorgis
    serialized_blockdevs = [(blk.ToDict(), link) for blk, link in block_devices]
1572 8bbcbb9e Dimitris Aragiorgis
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams,
1573 8bbcbb9e Dimitris Aragiorgis
                                      serialized_blockdevs))
1574 8bbcbb9e Dimitris Aragiorgis
1575 38e250ba Guido Trotter
    self._WriteKVMRuntime(instance.name, serialized_form)
1576 38e250ba Guido Trotter
1577 30e42c4e Guido Trotter
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
1578 38e250ba Guido Trotter
    """Load an instance's KVM runtime
1579 38e250ba Guido Trotter

1580 38e250ba Guido Trotter
    """
1581 30e42c4e Guido Trotter
    if not serialized_runtime:
1582 30e42c4e Guido Trotter
      serialized_runtime = self._ReadKVMRuntime(instance.name)
1583 8bbcbb9e Dimitris Aragiorgis
1584 30e42c4e Guido Trotter
    loaded_runtime = serializer.Load(serialized_runtime)
1585 8bbcbb9e Dimitris Aragiorgis
    if len(loaded_runtime) == 3:
1586 8bbcbb9e Dimitris Aragiorgis
      serialized_blockdevs = []
1587 8bbcbb9e Dimitris Aragiorgis
      kvm_cmd, serialized_nics, hvparams = loaded_runtime
1588 8bbcbb9e Dimitris Aragiorgis
    else:
1589 8bbcbb9e Dimitris Aragiorgis
      kvm_cmd, serialized_nics, hvparams, serialized_blockdevs = loaded_runtime
1590 8bbcbb9e Dimitris Aragiorgis
1591 38e250ba Guido Trotter
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
1592 8bbcbb9e Dimitris Aragiorgis
    block_devices = [(objects.Disk.FromDict(sdisk), link)
1593 8bbcbb9e Dimitris Aragiorgis
                     for sdisk, link in serialized_blockdevs]
1594 8bbcbb9e Dimitris Aragiorgis
1595 8bbcbb9e Dimitris Aragiorgis
    return (kvm_cmd, kvm_nics, hvparams, block_devices)
1596 38e250ba Guido Trotter
1597 5d9bfd87 Apollon Oikonomopoulos
  def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None):
1598 76431533 Guido Trotter
    """Run the KVM cmd and check for errors
1599 76431533 Guido Trotter

1600 76431533 Guido Trotter
    @type name: string
1601 76431533 Guido Trotter
    @param name: instance name
1602 76431533 Guido Trotter
    @type kvm_cmd: list of strings
1603 76431533 Guido Trotter
    @param kvm_cmd: runcmd input for kvm
1604 5d9bfd87 Apollon Oikonomopoulos
    @type tap_fds: list of int
1605 5d9bfd87 Apollon Oikonomopoulos
    @param tap_fds: fds of tap devices opened by Ganeti
1606 76431533 Guido Trotter

1607 76431533 Guido Trotter
    """
1608 5d9bfd87 Apollon Oikonomopoulos
    try:
1609 5d9bfd87 Apollon Oikonomopoulos
      result = utils.RunCmd(kvm_cmd, noclose_fds=tap_fds)
1610 5d9bfd87 Apollon Oikonomopoulos
    finally:
1611 5d9bfd87 Apollon Oikonomopoulos
      for fd in tap_fds:
1612 5d9bfd87 Apollon Oikonomopoulos
        utils_wrapper.CloseFdNoError(fd)
1613 5d9bfd87 Apollon Oikonomopoulos
1614 76431533 Guido Trotter
    if result.failed:
1615 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
1616 76431533 Guido Trotter
                                   (name, result.fail_reason, result.output))
1617 76431533 Guido Trotter
    if not self._InstancePidAlive(name)[2]:
1618 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s" % name)
1619 76431533 Guido Trotter
1620 8bbcbb9e Dimitris Aragiorgis
  # 52/50 local variables
1621 8bbcbb9e Dimitris Aragiorgis
  # pylint: disable=R0914
1622 b73f1c59 Guido Trotter
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, kvmhelp, incoming=None):
1623 839642c2 Iustin Pop
    """Execute a KVM cmd, after completing it with some last minute data.
1624 ee5f20b0 Guido Trotter

1625 30e42c4e Guido Trotter
    @type incoming: tuple of strings
1626 30e42c4e Guido Trotter
    @param incoming: (target_host_ip, port)
1627 b73f1c59 Guido Trotter
    @type kvmhelp: string
1628 b73f1c59 Guido Trotter
    @param kvmhelp: output of kvm --help
1629 30e42c4e Guido Trotter

1630 ee5f20b0 Guido Trotter
    """
1631 297e6e53 Guido Trotter
    # Small _ExecuteKVMRuntime hv parameters programming howto:
1632 297e6e53 Guido Trotter
    #  - conf_hvp contains the parameters as configured on ganeti. they might
1633 297e6e53 Guido Trotter
    #    have changed since the instance started; only use them if the change
1634 297e6e53 Guido Trotter
    #    won't affect the inside of the instance (which hasn't been rebooted).
1635 297e6e53 Guido Trotter
    #  - up_hvp contains the parameters as they were when the instance was
1636 297e6e53 Guido Trotter
    #    started, plus any new parameter which has been added between ganeti
1637 297e6e53 Guido Trotter
    #    versions: it is paramount that those default to a value which won't
1638 297e6e53 Guido Trotter
    #    affect the inside of the instance as well.
1639 297e6e53 Guido Trotter
    conf_hvp = instance.hvparams
1640 5905901c Iustin Pop
    name = instance.name
1641 5905901c Iustin Pop
    self._CheckDown(name)
1642 ee5f20b0 Guido Trotter
1643 ee5f20b0 Guido Trotter
    temp_files = []
1644 ee5f20b0 Guido Trotter
1645 8bbcbb9e Dimitris Aragiorgis
    kvm_cmd, kvm_nics, up_hvp, block_devices = kvm_runtime
1646 f0db563d Guido Trotter
    # the first element of kvm_cmd is always the path to the kvm binary
1647 f0db563d Guido Trotter
    kvm_path = kvm_cmd[0]
1648 297e6e53 Guido Trotter
    up_hvp = objects.FillDict(conf_hvp, up_hvp)
1649 ee5f20b0 Guido Trotter
1650 297e6e53 Guido Trotter
    # We know it's safe to run as a different user upon migration, so we'll use
1651 297e6e53 Guido Trotter
    # the latest conf, from conf_hvp.
1652 297e6e53 Guido Trotter
    security_model = conf_hvp[constants.HV_SECURITY_MODEL]
1653 cef34868 Guido Trotter
    if security_model == constants.HT_SM_USER:
1654 297e6e53 Guido Trotter
      kvm_cmd.extend(["-runas", conf_hvp[constants.HV_SECURITY_DOMAIN]])
1655 cef34868 Guido Trotter
1656 839642c2 Iustin Pop
    keymap = conf_hvp[constants.HV_KEYMAP]
1657 839642c2 Iustin Pop
    if keymap:
1658 839642c2 Iustin Pop
      keymap_path = self._InstanceKeymapFile(name)
1659 839642c2 Iustin Pop
      # If a keymap file is specified, KVM won't use its internal defaults. By
1660 839642c2 Iustin Pop
      # first including the "en-us" layout, an error on loading the actual
1661 839642c2 Iustin Pop
      # layout (e.g. because it can't be found) won't lead to a non-functional
1662 839642c2 Iustin Pop
      # keyboard. A keyboard with incorrect keys is still better than none.
1663 839642c2 Iustin Pop
      utils.WriteFile(keymap_path, data="include en-us\ninclude %s\n" % keymap)
1664 839642c2 Iustin Pop
      kvm_cmd.extend(["-k", keymap_path])
1665 839642c2 Iustin Pop
1666 297e6e53 Guido Trotter
    # We have reasons to believe changing something like the nic driver/type
1667 297e6e53 Guido Trotter
    # upon migration won't exactly fly with the instance kernel, so for nic
1668 297e6e53 Guido Trotter
    # related parameters we'll use up_hvp
1669 5d9bfd87 Apollon Oikonomopoulos
    tapfds = []
1670 5d9bfd87 Apollon Oikonomopoulos
    taps = []
1671 ee5f20b0 Guido Trotter
    if not kvm_nics:
1672 fbe27e2b Guido Trotter
      kvm_cmd.extend(["-net", "none"])
1673 ee5f20b0 Guido Trotter
    else:
1674 5d9bfd87 Apollon Oikonomopoulos
      vnet_hdr = False
1675 fbe27e2b Guido Trotter
      tap_extra = ""
1676 297e6e53 Guido Trotter
      nic_type = up_hvp[constants.HV_NIC_TYPE]
1677 37f88dc6 Guido Trotter
      if nic_type == constants.HT_NIC_PARAVIRTUAL:
1678 f0db563d Guido Trotter
        nic_model = self._VIRTIO
1679 f0db563d Guido Trotter
        try:
1680 f0db563d Guido Trotter
          devlist = self._GetKVMOutput(kvm_path, self._KVMOPT_DEVICELIST)
1681 68c9f726 Dimitris Aragiorgis
          if self._VIRTIO_NET_RE.search(devlist):
1682 f0db563d Guido Trotter
            nic_model = self._VIRTIO_NET_PCI
1683 8a534fbe Stratos Psomdakis
            vnet_hdr = up_hvp[constants.HV_VNET_HDR]
1684 f0db563d Guido Trotter
        except errors.HypervisorError, _:
1685 f0db563d Guido Trotter
          # Older versions of kvm don't support DEVICE_LIST, but they don't
1686 f0db563d Guido Trotter
          # have new virtio syntax either.
1687 f0db563d Guido Trotter
          pass
1688 4b784cf8 Miguel Di Ciurcio Filho
1689 297e6e53 Guido Trotter
        if up_hvp[constants.HV_VHOST_NET]:
1690 3b59ec02 Guido Trotter
          # check for vhost_net support
1691 0ad7f5d8 Guido Trotter
          if self._VHOST_RE.search(kvmhelp):
1692 4b784cf8 Miguel Di Ciurcio Filho
            tap_extra = ",vhost=on"
1693 4b784cf8 Miguel Di Ciurcio Filho
          else:
1694 4b784cf8 Miguel Di Ciurcio Filho
            raise errors.HypervisorError("vhost_net is configured"
1695 5ae4945a Iustin Pop
                                         " but it is not available")
1696 37f88dc6 Guido Trotter
      else:
1697 4b784cf8 Miguel Di Ciurcio Filho
        nic_model = nic_type
1698 37f88dc6 Guido Trotter
1699 6f4070cd Guido Trotter
      kvm_supports_netdev = self._NETDEV_RE.search(kvmhelp)
1700 6f4070cd Guido Trotter
1701 ee5f20b0 Guido Trotter
      for nic_seq, nic in enumerate(kvm_nics):
1702 6f1e1921 Michael Hanselmann
        tapname, tapfd = _OpenTap(vnet_hdr=vnet_hdr)
1703 5d9bfd87 Apollon Oikonomopoulos
        tapfds.append(tapfd)
1704 5d9bfd87 Apollon Oikonomopoulos
        taps.append(tapname)
1705 6f4070cd Guido Trotter
        if kvm_supports_netdev:
1706 4b784cf8 Miguel Di Ciurcio Filho
          nic_val = "%s,mac=%s,netdev=netdev%s" % (nic_model, nic.mac, nic_seq)
1707 5d9bfd87 Apollon Oikonomopoulos
          tap_val = "type=tap,id=netdev%s,fd=%d%s" % (nic_seq, tapfd, tap_extra)
1708 4b784cf8 Miguel Di Ciurcio Filho
          kvm_cmd.extend(["-netdev", tap_val, "-device", nic_val])
1709 4b784cf8 Miguel Di Ciurcio Filho
        else:
1710 049383d9 Adeodato Simo
          nic_val = "nic,vlan=%s,macaddr=%s,model=%s" % (nic_seq,
1711 049383d9 Adeodato Simo
                                                         nic.mac, nic_model)
1712 5d9bfd87 Apollon Oikonomopoulos
          tap_val = "tap,vlan=%s,fd=%d" % (nic_seq, tapfd)
1713 4b784cf8 Miguel Di Ciurcio Filho
          kvm_cmd.extend(["-net", tap_val, "-net", nic_val])
1714 ee5f20b0 Guido Trotter
1715 30e42c4e Guido Trotter
    if incoming:
1716 30e42c4e Guido Trotter
      target, port = incoming
1717 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-incoming", "tcp:%s:%s" % (target, port)])
1718 30e42c4e Guido Trotter
1719 297e6e53 Guido Trotter
    # Changing the vnc password doesn't bother the guest that much. At most it
1720 297e6e53 Guido Trotter
    # will surprise people who connect to it. Whether positively or negatively
1721 297e6e53 Guido Trotter
    # it's debatable.
1722 297e6e53 Guido Trotter
    vnc_pwd_file = conf_hvp[constants.HV_VNC_PASSWORD_FILE]
1723 6e6bb8d5 Guido Trotter
    vnc_pwd = None
1724 6e6bb8d5 Guido Trotter
    if vnc_pwd_file:
1725 6e6bb8d5 Guido Trotter
      try:
1726 682f7601 Guido Trotter
        vnc_pwd = utils.ReadOneLineFile(vnc_pwd_file, strict=True)
1727 6e6bb8d5 Guido Trotter
      except EnvironmentError, err:
1728 6e6bb8d5 Guido Trotter
        raise errors.HypervisorError("Failed to open VNC password file %s: %s"
1729 6e6bb8d5 Guido Trotter
                                     % (vnc_pwd_file, err))
1730 6e6bb8d5 Guido Trotter
1731 297e6e53 Guido Trotter
    if conf_hvp[constants.HV_KVM_USE_CHROOT]:
1732 547a63b7 Balazs Lecz
      utils.EnsureDirs([(self._InstanceChrootDir(name),
1733 547a63b7 Balazs Lecz
                         constants.SECURE_DIR_MODE)])
1734 547a63b7 Balazs Lecz
1735 91c10532 Andrea Spadaccini
    # Automatically enable QMP if version is >= 0.14
1736 0ad7f5d8 Guido Trotter
    if self._QMP_RE.search(kvmhelp):
1737 91c10532 Andrea Spadaccini
      logging.debug("Enabling QMP")
1738 91c10532 Andrea Spadaccini
      kvm_cmd.extend(["-qmp", "unix:%s,server,nowait" %
1739 5ae4945a Iustin Pop
                      self._InstanceQmpMonitor(instance.name)])
1740 91c10532 Andrea Spadaccini
1741 cc8a8ed7 Apollon Oikonomopoulos
    # Configure the network now for starting instances and bridged interfaces,
1742 cc8a8ed7 Apollon Oikonomopoulos
    # during FinalizeMigration for incoming instances' routed interfaces
1743 cc8a8ed7 Apollon Oikonomopoulos
    for nic_seq, nic in enumerate(kvm_nics):
1744 cc8a8ed7 Apollon Oikonomopoulos
      if (incoming and
1745 cc8a8ed7 Apollon Oikonomopoulos
          nic.nicparams[constants.NIC_MODE] != constants.NIC_MODE_BRIDGED):
1746 cc8a8ed7 Apollon Oikonomopoulos
        continue
1747 cc8a8ed7 Apollon Oikonomopoulos
      self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
1748 5d9bfd87 Apollon Oikonomopoulos
1749 8bbcbb9e Dimitris Aragiorgis
    bdev_opts = self._GenerateKVMBlockDevicesOptions(instance,
1750 8bbcbb9e Dimitris Aragiorgis
                                                     block_devices,
1751 8bbcbb9e Dimitris Aragiorgis
                                                     kvmhelp)
1752 8bbcbb9e Dimitris Aragiorgis
    kvm_cmd.extend(bdev_opts)
1753 1d8a7812 Andrea Spadaccini
    # CPU affinity requires kvm to start paused, so we set this flag if the
1754 1d8a7812 Andrea Spadaccini
    # instance is not already paused and if we are not going to accept a
1755 1d8a7812 Andrea Spadaccini
    # migrating instance. In the latter case, pausing is not needed.
1756 1d8a7812 Andrea Spadaccini
    start_kvm_paused = not (_KVM_START_PAUSED_FLAG in kvm_cmd) and not incoming
1757 945a7e67 Guido Trotter
    if start_kvm_paused:
1758 945a7e67 Guido Trotter
      kvm_cmd.extend([_KVM_START_PAUSED_FLAG])
1759 b693125f Tsachy Shacham
1760 b693125f Tsachy Shacham
    # Note: CPU pinning is using up_hvp since changes take effect
1761 b693125f Tsachy Shacham
    # during instance startup anyway, and to avoid problems when soft
1762 b693125f Tsachy Shacham
    # rebooting the instance.
1763 c607b1f7 Tsachy Shacham
    cpu_pinning = False
1764 b693125f Tsachy Shacham
    if up_hvp.get(constants.HV_CPU_MASK, None):
1765 b693125f Tsachy Shacham
      cpu_pinning = True
1766 b693125f Tsachy Shacham
1767 76431533 Guido Trotter
    if security_model == constants.HT_SM_POOL:
1768 76431533 Guido Trotter
      ss = ssconf.SimpleStore()
1769 76431533 Guido Trotter
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n")
1770 76431533 Guido Trotter
      all_uids = set(uidpool.ExpandUidPool(uid_pool))
1771 76431533 Guido Trotter
      uid = uidpool.RequestUnusedUid(all_uids)
1772 76431533 Guido Trotter
      try:
1773 76431533 Guido Trotter
        username = pwd.getpwuid(uid.GetUid()).pw_name
1774 76431533 Guido Trotter
        kvm_cmd.extend(["-runas", username])
1775 5d9bfd87 Apollon Oikonomopoulos
        self._RunKVMCmd(name, kvm_cmd, tapfds)
1776 76431533 Guido Trotter
      except:
1777 76431533 Guido Trotter
        uidpool.ReleaseUid(uid)
1778 76431533 Guido Trotter
        raise
1779 76431533 Guido Trotter
      else:
1780 76431533 Guido Trotter
        uid.Unlock()
1781 3af16328 Apollon Oikonomopoulos
        utils.WriteFile(self._InstanceUidFile(name), data=uid.AsStr())
1782 76431533 Guido Trotter
    else:
1783 5d9bfd87 Apollon Oikonomopoulos
      self._RunKVMCmd(name, kvm_cmd, tapfds)
1784 5d9bfd87 Apollon Oikonomopoulos
1785 5d9bfd87 Apollon Oikonomopoulos
    utils.EnsureDirs([(self._InstanceNICDir(instance.name),
1786 5d9bfd87 Apollon Oikonomopoulos
                     constants.RUN_DIRS_MODE)])
1787 5d9bfd87 Apollon Oikonomopoulos
    for nic_seq, tap in enumerate(taps):
1788 5d9bfd87 Apollon Oikonomopoulos
      utils.WriteFile(self._InstanceNICFile(instance.name, nic_seq),
1789 5d9bfd87 Apollon Oikonomopoulos
                      data=tap)
1790 eb58f9b1 Guido Trotter
1791 6e6bb8d5 Guido Trotter
    if vnc_pwd:
1792 d0c8c01d Iustin Pop
      change_cmd = "change vnc password %s" % vnc_pwd
1793 6e6bb8d5 Guido Trotter
      self._CallMonitorCommand(instance.name, change_cmd)
1794 6e6bb8d5 Guido Trotter
1795 b451c4c7 Andrea Spadaccini
    # Setting SPICE password. We are not vulnerable to malicious passwordless
1796 b451c4c7 Andrea Spadaccini
    # connection attempts because SPICE by default does not allow connections
1797 b451c4c7 Andrea Spadaccini
    # if neither a password nor the "disable_ticketing" options are specified.
1798 b451c4c7 Andrea Spadaccini
    # As soon as we send the password via QMP, that password is a valid ticket
1799 b451c4c7 Andrea Spadaccini
    # for connection.
1800 b451c4c7 Andrea Spadaccini
    spice_password_file = conf_hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]
1801 b451c4c7 Andrea Spadaccini
    if spice_password_file:
1802 fc84cd5d Guido Trotter
      spice_pwd = ""
1803 b451c4c7 Andrea Spadaccini
      try:
1804 b451c4c7 Andrea Spadaccini
        spice_pwd = utils.ReadOneLineFile(spice_password_file, strict=True)
1805 b451c4c7 Andrea Spadaccini
      except EnvironmentError, err:
1806 b451c4c7 Andrea Spadaccini
        raise errors.HypervisorError("Failed to open SPICE password file %s: %s"
1807 b451c4c7 Andrea Spadaccini
                                     % (spice_password_file, err))
1808 b451c4c7 Andrea Spadaccini
1809 fc84cd5d Guido Trotter
      qmp = QmpConnection(self._InstanceQmpMonitor(instance.name))
1810 fc84cd5d Guido Trotter
      qmp.connect()
1811 fc84cd5d Guido Trotter
      arguments = {
1812 fc84cd5d Guido Trotter
          "protocol": "spice",
1813 fc84cd5d Guido Trotter
          "password": spice_pwd,
1814 fc84cd5d Guido Trotter
      }
1815 fc84cd5d Guido Trotter
      qmp.Execute("set_password", arguments)
1816 fc84cd5d Guido Trotter
1817 08137f9e Iustin Pop
    for filename in temp_files:
1818 08137f9e Iustin Pop
      utils.RemoveFile(filename)
1819 eb58f9b1 Guido Trotter
1820 b693125f Tsachy Shacham
    # If requested, set CPU affinity and resume instance execution
1821 b693125f Tsachy Shacham
    if cpu_pinning:
1822 945a7e67 Guido Trotter
      self._ExecuteCpuAffinity(instance.name, up_hvp[constants.HV_CPU_MASK])
1823 945a7e67 Guido Trotter
1824 61eb1a46 Guido Trotter
    start_memory = self._InstanceStartupMemory(instance)
1825 61eb1a46 Guido Trotter
    if start_memory < instance.beparams[constants.BE_MAXMEM]:
1826 61eb1a46 Guido Trotter
      self.BalloonInstanceMemory(instance, start_memory)
1827 61eb1a46 Guido Trotter
1828 945a7e67 Guido Trotter
    if start_kvm_paused:
1829 2ed0e208 Iustin Pop
      # To control CPU pinning, ballooning, and vnc/spice passwords
1830 2ed0e208 Iustin Pop
      # the VM was started in a frozen state. If freezing was not
1831 2ed0e208 Iustin Pop
      # explicitly requested resume the vm status.
1832 945a7e67 Guido Trotter
      self._CallMonitorCommand(instance.name, self._CONT_CMD)
1833 b693125f Tsachy Shacham
1834 323f9095 Stephen Shirley
  def StartInstance(self, instance, block_devices, startup_paused):
1835 ee5f20b0 Guido Trotter
    """Start an instance.
1836 ee5f20b0 Guido Trotter

1837 ee5f20b0 Guido Trotter
    """
1838 5905901c Iustin Pop
    self._CheckDown(instance.name)
1839 4b9638dc Guido Trotter
    kvmpath = instance.hvparams[constants.HV_KVM_PATH]
1840 6e043e60 Guido Trotter
    kvmhelp = self._GetKVMOutput(kvmpath, self._KVMOPT_HELP)
1841 7238edb5 Iustin Pop
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices,
1842 b73f1c59 Guido Trotter
                                           startup_paused, kvmhelp)
1843 38e250ba Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1844 b73f1c59 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, kvmhelp)
1845 ee5f20b0 Guido Trotter
1846 6567aff3 Guido Trotter
  def _CallMonitorCommand(self, instance_name, command):
1847 6567aff3 Guido Trotter
    """Invoke a command on the instance monitor.
1848 6567aff3 Guido Trotter

1849 6567aff3 Guido Trotter
    """
1850 eace6157 Michael Hanselmann
    # TODO: Replace monitor calls with QMP once KVM >= 0.14 is the minimum
1851 eace6157 Michael Hanselmann
    # version. The monitor protocol is designed for human consumption, whereas
1852 eace6157 Michael Hanselmann
    # QMP is made for programmatic usage. In the worst case QMP can also
1853 eace6157 Michael Hanselmann
    # execute monitor commands. As it is, all calls to socat take at least
1854 eace6157 Michael Hanselmann
    # 500ms and likely more: socat can't detect the end of the reply and waits
1855 eace6157 Michael Hanselmann
    # for 500ms of no data received before exiting (500 ms is the default for
1856 eace6157 Michael Hanselmann
    # the "-t" parameter).
1857 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
1858 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
1859 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
1860 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
1861 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
1862 6567aff3 Guido Trotter
    if result.failed:
1863 afa9bb2e Michael Hanselmann
      msg = ("Failed to send command '%s' to instance '%s', reason '%s',"
1864 afa9bb2e Michael Hanselmann
             " output: %s" %
1865 afa9bb2e Michael Hanselmann
             (command, instance_name, result.fail_reason, result.output))
1866 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
1867 6567aff3 Guido Trotter
1868 6567aff3 Guido Trotter
    return result
1869 6567aff3 Guido Trotter
1870 0745fe0e Dimitris Aragiorgis
  def _GetFreePCISlot(self, instance, dev):
1871 0745fe0e Dimitris Aragiorgis
    """Get the first available pci slot of a runnung instance.
1872 0745fe0e Dimitris Aragiorgis

1873 0745fe0e Dimitris Aragiorgis
    """
1874 0745fe0e Dimitris Aragiorgis
    slots = bitarray(32)
1875 0745fe0e Dimitris Aragiorgis
    slots.setall(False) # pylint: disable=E1101
1876 0745fe0e Dimitris Aragiorgis
    output = self._CallMonitorCommand(instance.name, self._INFO_PCI_CMD)
1877 0745fe0e Dimitris Aragiorgis
    for line in output.stdout.splitlines():
1878 0745fe0e Dimitris Aragiorgis
      match = self._INFO_PCI_RE.search(line)
1879 0745fe0e Dimitris Aragiorgis
      if match:
1880 0745fe0e Dimitris Aragiorgis
        slot = int(match.group(1))
1881 0745fe0e Dimitris Aragiorgis
        slots[slot] = True
1882 0745fe0e Dimitris Aragiorgis
1883 0745fe0e Dimitris Aragiorgis
    [free] = slots.search(_AVAILABLE_PCI_SLOT, 1) # pylint: disable=E1101
1884 0745fe0e Dimitris Aragiorgis
    if not free:
1885 0745fe0e Dimitris Aragiorgis
      raise errors.HypervisorError("All PCI slots occupied")
1886 0745fe0e Dimitris Aragiorgis
1887 0745fe0e Dimitris Aragiorgis
    dev.pci = int(free)
1888 0745fe0e Dimitris Aragiorgis
1889 b52d85c1 Guido Trotter
  @classmethod
1890 585c8187 Guido Trotter
  def _ParseKVMVersion(cls, text):
1891 585c8187 Guido Trotter
    """Parse the KVM version from the --help output.
1892 585c8187 Guido Trotter

1893 585c8187 Guido Trotter
    @type text: string
1894 585c8187 Guido Trotter
    @param text: output of kvm --help
1895 585c8187 Guido Trotter
    @return: (version, v_maj, v_min, v_rev)
1896 5c3d5dfd Iustin Pop
    @raise errors.HypervisorError: when the KVM version cannot be retrieved
1897 585c8187 Guido Trotter

1898 585c8187 Guido Trotter
    """
1899 585c8187 Guido Trotter
    match = cls._VERSION_RE.search(text.splitlines()[0])
1900 585c8187 Guido Trotter
    if not match:
1901 585c8187 Guido Trotter
      raise errors.HypervisorError("Unable to get KVM version")
1902 585c8187 Guido Trotter
1903 585c8187 Guido Trotter
    v_all = match.group(0)
1904 585c8187 Guido Trotter
    v_maj = int(match.group(1))
1905 585c8187 Guido Trotter
    v_min = int(match.group(2))
1906 585c8187 Guido Trotter
    if match.group(4):
1907 585c8187 Guido Trotter
      v_rev = int(match.group(4))
1908 585c8187 Guido Trotter
    else:
1909 585c8187 Guido Trotter
      v_rev = 0
1910 585c8187 Guido Trotter
    return (v_all, v_maj, v_min, v_rev)
1911 585c8187 Guido Trotter
1912 585c8187 Guido Trotter
  @classmethod
1913 6e043e60 Guido Trotter
  def _GetKVMOutput(cls, kvm_path, option):
1914 6e043e60 Guido Trotter
    """Return the output of a kvm invocation
1915 e3b89628 Guido Trotter

1916 bc0fed4b Guido Trotter
    @type kvm_path: string
1917 bc0fed4b Guido Trotter
    @param kvm_path: path to the kvm executable
1918 bc0fed4b Guido Trotter
    @type option: a key of _KVMOPTS_CMDS
1919 bc0fed4b Guido Trotter
    @param option: kvm option to fetch the output from
1920 6e043e60 Guido Trotter
    @return: output a supported kvm invocation
1921 e3b89628 Guido Trotter
    @raise errors.HypervisorError: when the KVM help output cannot be retrieved
1922 e3b89628 Guido Trotter

1923 e3b89628 Guido Trotter
    """
1924 6e043e60 Guido Trotter
    assert option in cls._KVMOPTS_CMDS, "Invalid output option"
1925 6e043e60 Guido Trotter
1926 bc0fed4b Guido Trotter
    optlist, can_fail = cls._KVMOPTS_CMDS[option]
1927 bc0fed4b Guido Trotter
1928 bc0fed4b Guido Trotter
    result = utils.RunCmd([kvm_path] + optlist)
1929 bc0fed4b Guido Trotter
    if result.failed and not can_fail:
1930 af89fa76 Helga Velroyen
      raise errors.HypervisorError("Unable to get KVM %s output" %
1931 af89fa76 Helga Velroyen
                                    " ".join(cls._KVMOPTS_CMDS[option]))
1932 e3b89628 Guido Trotter
    return result.output
1933 e3b89628 Guido Trotter
1934 e3b89628 Guido Trotter
  @classmethod
1935 3b59ec02 Guido Trotter
  def _GetKVMVersion(cls, kvm_path):
1936 d7e4a2b1 Andrea Spadaccini
    """Return the installed KVM version.
1937 b52d85c1 Guido Trotter

1938 440351f8 Andrea Spadaccini
    @return: (version, v_maj, v_min, v_rev)
1939 5c3d5dfd Iustin Pop
    @raise errors.HypervisorError: when the KVM version cannot be retrieved
1940 b52d85c1 Guido Trotter

1941 b52d85c1 Guido Trotter
    """
1942 6e043e60 Guido Trotter
    return cls._ParseKVMVersion(cls._GetKVMOutput(kvm_path, cls._KVMOPT_HELP))
1943 82e3bf85 Dimitris Aragiorgis
1944 82e3bf85 Dimitris Aragiorgis
  @classmethod
1945 82e3bf85 Dimitris Aragiorgis
  def _GetDefaultMachineVersion(cls, kvm_path):
1946 82e3bf85 Dimitris Aragiorgis
    """Return the default hardware revision (e.g. pc-1.1)
1947 82e3bf85 Dimitris Aragiorgis

1948 82e3bf85 Dimitris Aragiorgis
    """
1949 6e043e60 Guido Trotter
    output = cls._GetKVMOutput(kvm_path, cls._KVMOPT_MLIST)
1950 82e3bf85 Dimitris Aragiorgis
    match = cls._DEFAULT_MACHINE_VERSION_RE.search(output)
1951 82e3bf85 Dimitris Aragiorgis
    if match:
1952 82e3bf85 Dimitris Aragiorgis
      return match.group(1)
1953 82e3bf85 Dimitris Aragiorgis
    else:
1954 82e3bf85 Dimitris Aragiorgis
      return "pc"
1955 82e3bf85 Dimitris Aragiorgis
1956 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
1957 eb58f9b1 Guido Trotter
    """Stop an instance.
1958 eb58f9b1 Guido Trotter

1959 eb58f9b1 Guido Trotter
    """
1960 bbcf7ad0 Iustin Pop
    if name is not None and not force:
1961 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
1962 bbcf7ad0 Iustin Pop
    if name is None:
1963 bbcf7ad0 Iustin Pop
      name = instance.name
1964 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
1965 bbcf7ad0 Iustin Pop
    else:
1966 bbcf7ad0 Iustin Pop
      acpi = False
1967 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
1968 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
1969 bbcf7ad0 Iustin Pop
      if force or not acpi:
1970 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
1971 eb58f9b1 Guido Trotter
      else:
1972 d0c8c01d Iustin Pop
        self._CallMonitorCommand(name, "system_powerdown")
1973 eb58f9b1 Guido Trotter
1974 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
1975 8904b35c Guido Trotter
    """Cleanup after a stopped instance
1976 8904b35c Guido Trotter

1977 8904b35c Guido Trotter
    """
1978 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
1979 8904b35c Guido Trotter
    if pid > 0 and alive:
1980 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
1981 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
1982 eb58f9b1 Guido Trotter
1983 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
1984 eb58f9b1 Guido Trotter
    """Reboot an instance.
1985 eb58f9b1 Guido Trotter

1986 eb58f9b1 Guido Trotter
    """
1987 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
1988 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
1989 eb58f9b1 Guido Trotter
    # to shutdown and restart.
1990 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
1991 1f8b3a27 Guido Trotter
    if not alive:
1992 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
1993 78411c60 Iustin Pop
                                   " not running" % instance.name)
1994 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
1995 f02881e0 Guido Trotter
    # ...first load it...
1996 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
1997 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
1998 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
1999 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
2000 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
2001 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
2002 4b9638dc Guido Trotter
    kvmpath = instance.hvparams[constants.HV_KVM_PATH]
2003 6e043e60 Guido Trotter
    kvmhelp = self._GetKVMOutput(kvmpath, self._KVMOPT_HELP)
2004 b73f1c59 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, kvmhelp)
2005 eb58f9b1 Guido Trotter
2006 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
2007 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
2008 30e42c4e Guido Trotter

2009 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
2010 30e42c4e Guido Trotter
    @param instance: instance to be migrated
2011 30e42c4e Guido Trotter
    @rtype: string
2012 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
2013 30e42c4e Guido Trotter

2014 30e42c4e Guido Trotter
    """
2015 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
2016 30e42c4e Guido Trotter
2017 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
2018 30e42c4e Guido Trotter
    """Prepare to accept an instance.
2019 30e42c4e Guido Trotter

2020 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
2021 30e42c4e Guido Trotter
    @param instance: instance to be accepted
2022 30e42c4e Guido Trotter
    @type info: string
2023 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
2024 30e42c4e Guido Trotter
    @type target: string
2025 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
2026 30e42c4e Guido Trotter

2027 30e42c4e Guido Trotter
    """
2028 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
2029 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
2030 4b9638dc Guido Trotter
    kvmpath = instance.hvparams[constants.HV_KVM_PATH]
2031 6e043e60 Guido Trotter
    kvmhelp = self._GetKVMOutput(kvmpath, self._KVMOPT_HELP)
2032 b73f1c59 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, kvmhelp,
2033 b73f1c59 Guido Trotter
                            incoming=incoming_address)
2034 30e42c4e Guido Trotter
2035 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
2036 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
2037 30e42c4e Guido Trotter

2038 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
2039 30e42c4e Guido Trotter

2040 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
2041 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
2042 30e42c4e Guido Trotter

2043 30e42c4e Guido Trotter
    """
2044 30e42c4e Guido Trotter
    if success:
2045 5d9bfd87 Apollon Oikonomopoulos
      kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
2046 5d9bfd87 Apollon Oikonomopoulos
      kvm_nics = kvm_runtime[1]
2047 5d9bfd87 Apollon Oikonomopoulos
2048 5d9bfd87 Apollon Oikonomopoulos
      for nic_seq, nic in enumerate(kvm_nics):
2049 cc8a8ed7 Apollon Oikonomopoulos
        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
2050 cc8a8ed7 Apollon Oikonomopoulos
          # Bridged interfaces have already been configured
2051 cc8a8ed7 Apollon Oikonomopoulos
          continue
2052 5d9bfd87 Apollon Oikonomopoulos
        try:
2053 5d9bfd87 Apollon Oikonomopoulos
          tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
2054 5d9bfd87 Apollon Oikonomopoulos
        except EnvironmentError, err:
2055 5d9bfd87 Apollon Oikonomopoulos
          logging.warning("Failed to find host interface for %s NIC #%d: %s",
2056 5d9bfd87 Apollon Oikonomopoulos
                          instance.name, nic_seq, str(err))
2057 5d9bfd87 Apollon Oikonomopoulos
          continue
2058 5d9bfd87 Apollon Oikonomopoulos
        try:
2059 5d9bfd87 Apollon Oikonomopoulos
          self._ConfigureNIC(instance, nic_seq, nic, tap)
2060 5d9bfd87 Apollon Oikonomopoulos
        except errors.HypervisorError, err:
2061 5d9bfd87 Apollon Oikonomopoulos
          logging.warning(str(err))
2062 5d9bfd87 Apollon Oikonomopoulos
2063 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
2064 30e42c4e Guido Trotter
    else:
2065 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
2066 30e42c4e Guido Trotter
2067 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
2068 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
2069 30e42c4e Guido Trotter

2070 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
2071 30e42c4e Guido Trotter
    currently running.
2072 30e42c4e Guido Trotter

2073 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
2074 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
2075 30e42c4e Guido Trotter
    @type target: string
2076 30e42c4e Guido Trotter
    @param target: ip address of the target node
2077 30e42c4e Guido Trotter
    @type live: boolean
2078 30e42c4e Guido Trotter
    @param live: perform a live migration
2079 30e42c4e Guido Trotter

2080 30e42c4e Guido Trotter
    """
2081 58d38b02 Iustin Pop
    instance_name = instance.name
2082 50716be0 Iustin Pop
    port = instance.hvparams[constants.HV_MIGRATION_PORT]
2083 6a1434d7 Andrea Spadaccini
    _, _, alive = self._InstancePidAlive(instance_name)
2084 30e42c4e Guido Trotter
    if not alive:
2085 30e42c4e Guido Trotter
      raise errors.HypervisorError("Instance not running, cannot migrate")
2086 30e42c4e Guido Trotter
2087 30e42c4e Guido Trotter
    if not live:
2088 d0c8c01d Iustin Pop
      self._CallMonitorCommand(instance_name, "stop")
2089 30e42c4e Guido Trotter
2090 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_speed %dm" %
2091 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_BANDWIDTH])
2092 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
2093 e43d4f9f Apollon Oikonomopoulos
2094 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_downtime %dms" %
2095 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_DOWNTIME])
2096 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
2097 e43d4f9f Apollon Oikonomopoulos
2098 d0c8c01d Iustin Pop
    migrate_command = "migrate -d tcp:%s:%s" % (target, port)
2099 30e42c4e Guido Trotter
    self._CallMonitorCommand(instance_name, migrate_command)
2100 30e42c4e Guido Trotter
2101 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
2102 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
2103 6a1434d7 Andrea Spadaccini

2104 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
2105 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
2106 6a1434d7 Andrea Spadaccini
    @type success: bool
2107 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
2108 6a1434d7 Andrea Spadaccini
    @type live: bool
2109 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
2110 6a1434d7 Andrea Spadaccini

2111 6a1434d7 Andrea Spadaccini
    """
2112 6a1434d7 Andrea Spadaccini
    if success:
2113 6a1434d7 Andrea Spadaccini
      pidfile, pid, _ = self._InstancePidAlive(instance.name)
2114 6a1434d7 Andrea Spadaccini
      utils.KillProcess(pid)
2115 6a1434d7 Andrea Spadaccini
      self._RemoveInstanceRuntimeFiles(pidfile, instance.name)
2116 6a1434d7 Andrea Spadaccini
    elif live:
2117 6a1434d7 Andrea Spadaccini
      self._CallMonitorCommand(instance.name, self._CONT_CMD)
2118 6a1434d7 Andrea Spadaccini
2119 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
2120 6a1434d7 Andrea Spadaccini
    """Get the migration status
2121 6a1434d7 Andrea Spadaccini

2122 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
2123 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
2124 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
2125 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
2126 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
2127 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
2128 6a1434d7 Andrea Spadaccini

2129 6a1434d7 Andrea Spadaccini
    """
2130 d0c8c01d Iustin Pop
    info_command = "info migrate"
2131 6a1434d7 Andrea Spadaccini
    for _ in range(self._MIGRATION_INFO_MAX_BAD_ANSWERS):
2132 6a1434d7 Andrea Spadaccini
      result = self._CallMonitorCommand(instance.name, info_command)
2133 30e42c4e Guido Trotter
      match = self._MIGRATION_STATUS_RE.search(result.stdout)
2134 30e42c4e Guido Trotter
      if not match:
2135 c4e388a5 Guido Trotter
        if not result.stdout:
2136 c4e388a5 Guido Trotter
          logging.info("KVM: empty 'info migrate' result")
2137 c4e388a5 Guido Trotter
        else:
2138 e4dd2299 Guido Trotter
          logging.warning("KVM: unknown 'info migrate' result: %s",
2139 c4e388a5 Guido Trotter
                          result.stdout)
2140 30e42c4e Guido Trotter
      else:
2141 30e42c4e Guido Trotter
        status = match.group(1)
2142 6a1434d7 Andrea Spadaccini
        if status in constants.HV_KVM_MIGRATION_VALID_STATUSES:
2143 6a1434d7 Andrea Spadaccini
          migration_status = objects.MigrationStatus(status=status)
2144 61643226 Andrea Spadaccini
          match = self._MIGRATION_PROGRESS_RE.search(result.stdout)
2145 61643226 Andrea Spadaccini
          if match:
2146 61643226 Andrea Spadaccini
            migration_status.transferred_ram = match.group("transferred")
2147 61643226 Andrea Spadaccini
            migration_status.total_ram = match.group("total")
2148 61643226 Andrea Spadaccini
2149 6a1434d7 Andrea Spadaccini
          return migration_status
2150 30e42c4e Guido Trotter
2151 6a1434d7 Andrea Spadaccini
        logging.warning("KVM: unknown migration status '%s'", status)
2152 6a1434d7 Andrea Spadaccini
2153 6a1434d7 Andrea Spadaccini
      time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
2154 6a1434d7 Andrea Spadaccini
2155 62457f51 Iustin Pop
    return objects.MigrationStatus(status=constants.HV_MIGRATION_FAILED)
2156 30e42c4e Guido Trotter
2157 3d836750 Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
2158 3d836750 Guido Trotter
    """Balloon an instance memory to a certain value.
2159 3d836750 Guido Trotter

2160 3d836750 Guido Trotter
    @type instance: L{objects.Instance}
2161 3d836750 Guido Trotter
    @param instance: instance to be accepted
2162 3d836750 Guido Trotter
    @type mem: int
2163 3d836750 Guido Trotter
    @param mem: actual memory size to use for instance runtime
2164 3d836750 Guido Trotter

2165 3d836750 Guido Trotter
    """
2166 3d836750 Guido Trotter
    self._CallMonitorCommand(instance.name, "balloon %d" % mem)
2167 3d836750 Guido Trotter
2168 eb58f9b1 Guido Trotter
  def GetNodeInfo(self):
2169 eb58f9b1 Guido Trotter
    """Return information about the node.
2170 eb58f9b1 Guido Trotter

2171 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
2172 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
2173 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
2174 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
2175 34fbc862 Andrea Spadaccini
          - hv_version: the hypervisor version in the form (major, minor,
2176 34fbc862 Andrea Spadaccini
                        revision)
2177 eb58f9b1 Guido Trotter

2178 eb58f9b1 Guido Trotter
    """
2179 34fbc862 Andrea Spadaccini
    result = self.GetLinuxNodeInfo()
2180 4b9638dc Guido Trotter
    # FIXME: this is the global kvm version, but the actual version can be
2181 4b9638dc Guido Trotter
    # customized as an hv parameter. we should use the nodegroup's default kvm
2182 4b9638dc Guido Trotter
    # path parameter here.
2183 3b59ec02 Guido Trotter
    _, v_major, v_min, v_rev = self._GetKVMVersion(constants.KVM_PATH)
2184 34fbc862 Andrea Spadaccini
    result[constants.HV_NODEINFO_KEY_VERSION] = (v_major, v_min, v_rev)
2185 34fbc862 Andrea Spadaccini
    return result
2186 eb58f9b1 Guido Trotter
2187 637ce7f9 Guido Trotter
  @classmethod
2188 55cc0a44 Michael Hanselmann
  def GetInstanceConsole(cls, instance, hvparams, beparams):
2189 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
2190 eb58f9b1 Guido Trotter

2191 eb58f9b1 Guido Trotter
    """
2192 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
2193 9d9bded1 Michael Hanselmann
      cmd = [pathutils.KVM_CONSOLE_WRAPPER,
2194 2f4c951e Stephen Shirley
             constants.SOCAT_PATH, utils.ShellQuote(instance.name),
2195 2f4c951e Stephen Shirley
             utils.ShellQuote(cls._InstanceMonitor(instance.name)),
2196 55cc0a44 Michael Hanselmann
             "STDIO,%s" % cls._SocatUnixConsoleParams(),
2197 55cc0a44 Michael Hanselmann
             "UNIX-CONNECT:%s" % cls._InstanceSerial(instance.name)]
2198 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
2199 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_SSH,
2200 55cc0a44 Michael Hanselmann
                                     host=instance.primary_node,
2201 052783ff Michael Hanselmann
                                     user=constants.SSH_CONSOLE_USER,
2202 55cc0a44 Michael Hanselmann
                                     command=cmd)
2203 3be34f57 Guido Trotter
2204 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
2205 55cc0a44 Michael Hanselmann
    if vnc_bind_address and instance.network_port > constants.VNC_BASE_PORT:
2206 55cc0a44 Michael Hanselmann
      display = instance.network_port - constants.VNC_BASE_PORT
2207 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
2208 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_VNC,
2209 55cc0a44 Michael Hanselmann
                                     host=vnc_bind_address,
2210 55cc0a44 Michael Hanselmann
                                     port=instance.network_port,
2211 55cc0a44 Michael Hanselmann
                                     display=display)
2212 55cc0a44 Michael Hanselmann
2213 4d2cdb5a Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2214 4d2cdb5a Andrea Spadaccini
    if spice_bind:
2215 4d2cdb5a Andrea Spadaccini
      return objects.InstanceConsole(instance=instance.name,
2216 4d2cdb5a Andrea Spadaccini
                                     kind=constants.CONS_SPICE,
2217 4d2cdb5a Andrea Spadaccini
                                     host=spice_bind,
2218 4d2cdb5a Andrea Spadaccini
                                     port=instance.network_port)
2219 4d2cdb5a Andrea Spadaccini
2220 55cc0a44 Michael Hanselmann
    return objects.InstanceConsole(instance=instance.name,
2221 55cc0a44 Michael Hanselmann
                                   kind=constants.CONS_MESSAGE,
2222 55cc0a44 Michael Hanselmann
                                   message=("No serial shell for instance %s" %
2223 55cc0a44 Michael Hanselmann
                                            instance.name))
2224 eb58f9b1 Guido Trotter
2225 eb58f9b1 Guido Trotter
  def Verify(self):
2226 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
2227 eb58f9b1 Guido Trotter

2228 cd04dfd2 Michael Hanselmann
    Check that the required binaries exist.
2229 cd04dfd2 Michael Hanselmann

2230 cd04dfd2 Michael Hanselmann
    @return: Problem description if something is wrong, C{None} otherwise
2231 eb58f9b1 Guido Trotter

2232 eb58f9b1 Guido Trotter
    """
2233 1f4b9d39 Iustin Pop
    msgs = []
2234 1f4b9d39 Iustin Pop
    # FIXME: this is the global kvm binary, but the actual path can be
2235 1f4b9d39 Iustin Pop
    # customized as an hv parameter; we should use the nodegroup's
2236 1f4b9d39 Iustin Pop
    # default kvm path parameter here.
2237 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
2238 1f4b9d39 Iustin Pop
      msgs.append("The KVM binary ('%s') does not exist" % constants.KVM_PATH)
2239 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
2240 1f4b9d39 Iustin Pop
      msgs.append("The socat binary ('%s') does not exist" %
2241 1f4b9d39 Iustin Pop
                  constants.SOCAT_PATH)
2242 1f4b9d39 Iustin Pop
2243 1f4b9d39 Iustin Pop
    return self._FormatVerifyResults(msgs)
2244 14aa53cb Guido Trotter
2245 6b5605e8 Iustin Pop
  @classmethod
2246 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
2247 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
2248 6b5605e8 Iustin Pop

2249 6b5605e8 Iustin Pop
    @type hvparams:  dict
2250 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
2251 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
2252 6b5605e8 Iustin Pop

2253 6b5605e8 Iustin Pop
    """
2254 47387b1e Guido Trotter
    super(KVMHypervisor, cls).CheckParameterSyntax(hvparams)
2255 6b5605e8 Iustin Pop
2256 df5ab9f0 Guido Trotter
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
2257 df5ab9f0 Guido Trotter
    if kernel_path:
2258 df5ab9f0 Guido Trotter
      if not hvparams[constants.HV_ROOT_PATH]:
2259 205ab586 Iustin Pop
        raise errors.HypervisorError("Need a root partition for the instance,"
2260 205ab586 Iustin Pop
                                     " if a kernel is defined")
2261 6b5605e8 Iustin Pop
2262 205ab586 Iustin Pop
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
2263 205ab586 Iustin Pop
        not hvparams[constants.HV_VNC_X509]):
2264 205ab586 Iustin Pop
      raise errors.HypervisorError("%s must be defined, if %s is" %
2265 205ab586 Iustin Pop
                                   (constants.HV_VNC_X509,
2266 205ab586 Iustin Pop
                                    constants.HV_VNC_X509_VERIFY))
2267 66d5dbef Guido Trotter
2268 14fd6c81 Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
2269 14fd6c81 Guido Trotter
      serial_speed = hvparams[constants.HV_SERIAL_SPEED]
2270 14fd6c81 Guido Trotter
      valid_speeds = constants.VALID_SERIAL_SPEEDS
2271 14fd6c81 Guido Trotter
      if not serial_speed or serial_speed not in valid_speeds:
2272 14fd6c81 Guido Trotter
        raise errors.HypervisorError("Invalid serial console speed, must be"
2273 14fd6c81 Guido Trotter
                                     " one of: %s" %
2274 14fd6c81 Guido Trotter
                                     utils.CommaJoin(valid_speeds))
2275 14fd6c81 Guido Trotter
2276 66d5dbef Guido Trotter
    boot_order = hvparams[constants.HV_BOOT_ORDER]
2277 205ab586 Iustin Pop
    if (boot_order == constants.HT_BO_CDROM and
2278 205ab586 Iustin Pop
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
2279 835528af Iustin Pop
      raise errors.HypervisorError("Cannot boot from cdrom without an"
2280 835528af Iustin Pop
                                   " ISO path")
2281 f5118ade Iustin Pop
2282 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
2283 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
2284 d19d94db Guido Trotter
      if not hvparams[constants.HV_SECURITY_DOMAIN]:
2285 d19d94db Guido Trotter
        raise errors.HypervisorError("A security domain (user to run kvm as)"
2286 d19d94db Guido Trotter
                                     " must be specified")
2287 d19d94db Guido Trotter
    elif (security_model == constants.HT_SM_NONE or
2288 d19d94db Guido Trotter
          security_model == constants.HT_SM_POOL):
2289 d19d94db Guido Trotter
      if hvparams[constants.HV_SECURITY_DOMAIN]:
2290 d19d94db Guido Trotter
        raise errors.HypervisorError("Cannot have a security domain when the"
2291 d19d94db Guido Trotter
                                     " security model is 'none' or 'pool'")
2292 d19d94db Guido Trotter
2293 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2294 b451c4c7 Andrea Spadaccini
    spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
2295 b1cb62bd Andrea Spadaccini
    if spice_bind:
2296 b1cb62bd Andrea Spadaccini
      if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
2297 b1cb62bd Andrea Spadaccini
        # if an IP version is specified, the spice_bind parameter must be an
2298 b1cb62bd Andrea Spadaccini
        # IP of that family
2299 b1cb62bd Andrea Spadaccini
        if (netutils.IP4Address.IsValid(spice_bind) and
2300 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP4_VERSION):
2301 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: Got an IPv4 address (%s), but"
2302 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
2303 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
2304 b1cb62bd Andrea Spadaccini
2305 b1cb62bd Andrea Spadaccini
        if (netutils.IP6Address.IsValid(spice_bind) and
2306 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP6_VERSION):
2307 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: Got an IPv6 address (%s), but"
2308 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
2309 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
2310 b451c4c7 Andrea Spadaccini
    else:
2311 0e1b03b9 Andrea Spadaccini
      # All the other SPICE parameters depend on spice_bind being set. Raise an
2312 0e1b03b9 Andrea Spadaccini
      # error if any of them is set without it.
2313 07788a0b Michael Hanselmann
      for param in _SPICE_ADDITIONAL_PARAMS:
2314 0e1b03b9 Andrea Spadaccini
        if hvparams[param]:
2315 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: %s requires %s to be set" %
2316 0e1b03b9 Andrea Spadaccini
                                       (param, constants.HV_KVM_SPICE_BIND))
2317 b1cb62bd Andrea Spadaccini
2318 d19d94db Guido Trotter
  @classmethod
2319 d19d94db Guido Trotter
  def ValidateParameters(cls, hvparams):
2320 d19d94db Guido Trotter
    """Check the given parameters for validity.
2321 d19d94db Guido Trotter

2322 d19d94db Guido Trotter
    @type hvparams:  dict
2323 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
2324 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
2325 d19d94db Guido Trotter

2326 d19d94db Guido Trotter
    """
2327 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
2328 d19d94db Guido Trotter
2329 82e3bf85 Dimitris Aragiorgis
    kvm_path = hvparams[constants.HV_KVM_PATH]
2330 82e3bf85 Dimitris Aragiorgis
2331 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
2332 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
2333 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
2334 d19d94db Guido Trotter
      try:
2335 1feb39ec Guido Trotter
        pwd.getpwnam(username)
2336 d19d94db Guido Trotter
      except KeyError:
2337 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
2338 d19d94db Guido Trotter
                                     % username)
2339 d19d94db Guido Trotter
2340 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2341 b1cb62bd Andrea Spadaccini
    if spice_bind:
2342 b1cb62bd Andrea Spadaccini
      # only one of VNC and SPICE can be used currently.
2343 b1cb62bd Andrea Spadaccini
      if hvparams[constants.HV_VNC_BIND_ADDRESS]:
2344 afa9bb2e Michael Hanselmann
        raise errors.HypervisorError("Both SPICE and VNC are configured, but"
2345 b1cb62bd Andrea Spadaccini
                                     " only one of them can be used at a"
2346 afa9bb2e Michael Hanselmann
                                     " given time")
2347 b1cb62bd Andrea Spadaccini
2348 3b59ec02 Guido Trotter
      # check that KVM supports SPICE
2349 6e043e60 Guido Trotter
      kvmhelp = cls._GetKVMOutput(kvm_path, cls._KVMOPT_HELP)
2350 0ad7f5d8 Guido Trotter
      if not cls._SPICE_RE.search(kvmhelp):
2351 afa9bb2e Michael Hanselmann
        raise errors.HypervisorError("SPICE is configured, but it is not"
2352 afa9bb2e Michael Hanselmann
                                     " supported according to 'kvm --help'")
2353 b1cb62bd Andrea Spadaccini
2354 b1cb62bd Andrea Spadaccini
      # if spice_bind is not an IP address, it must be a valid interface
2355 afa9bb2e Michael Hanselmann
      bound_to_addr = (netutils.IP4Address.IsValid(spice_bind) or
2356 afa9bb2e Michael Hanselmann
                       netutils.IP6Address.IsValid(spice_bind))
2357 b1cb62bd Andrea Spadaccini
      if not bound_to_addr and not netutils.IsValidInterface(spice_bind):
2358 afa9bb2e Michael Hanselmann
        raise errors.HypervisorError("SPICE: The %s parameter must be either"
2359 b1cb62bd Andrea Spadaccini
                                     " a valid IP address or interface name" %
2360 b1cb62bd Andrea Spadaccini
                                     constants.HV_KVM_SPICE_BIND)
2361 b1cb62bd Andrea Spadaccini
2362 82e3bf85 Dimitris Aragiorgis
    machine_version = hvparams[constants.HV_KVM_MACHINE_VERSION]
2363 82e3bf85 Dimitris Aragiorgis
    if machine_version:
2364 6e043e60 Guido Trotter
      output = cls._GetKVMOutput(kvm_path, cls._KVMOPT_MLIST)
2365 82e3bf85 Dimitris Aragiorgis
      if not cls._CHECK_MACHINE_VERSION_RE(machine_version).search(output):
2366 82e3bf85 Dimitris Aragiorgis
        raise errors.HypervisorError("Unsupported machine version: %s" %
2367 82e3bf85 Dimitris Aragiorgis
                                     machine_version)
2368 82e3bf85 Dimitris Aragiorgis
2369 f5118ade Iustin Pop
  @classmethod
2370 f5118ade Iustin Pop
  def PowercycleNode(cls):
2371 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
2372 f5118ade Iustin Pop

2373 f5118ade Iustin Pop
    """
2374 f5118ade Iustin Pop
    cls.LinuxPowercycle()