Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ 96f82929

History | View | Annotate | Download (84.9 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 b693125f Tsachy Shacham
try:
41 471a31b6 Andrea Spadaccini
  import affinity   # pylint: disable=F0401
42 b693125f Tsachy Shacham
except ImportError:
43 b693125f Tsachy Shacham
  affinity = None
44 eb58f9b1 Guido Trotter
45 eb58f9b1 Guido Trotter
from ganeti import utils
46 eb58f9b1 Guido Trotter
from ganeti import constants
47 eb58f9b1 Guido Trotter
from ganeti import errors
48 38e250ba Guido Trotter
from ganeti import serializer
49 38e250ba Guido Trotter
from ganeti import objects
50 76431533 Guido Trotter
from ganeti import uidpool
51 76431533 Guido Trotter
from ganeti import ssconf
52 a744b676 Manuel Franceschini
from ganeti import netutils
53 9d9bded1 Michael Hanselmann
from ganeti import pathutils
54 9d9bded1 Michael Hanselmann
from ganeti.hypervisor import hv_base
55 5d9bfd87 Apollon Oikonomopoulos
from ganeti.utils import wrapper as utils_wrapper
56 eb58f9b1 Guido Trotter
57 eb58f9b1 Guido Trotter
58 0e1e0b6a Michael Hanselmann
_KVM_NETWORK_SCRIPT = pathutils.CONF_DIR + "/kvm-vif-bridge"
59 b693125f Tsachy Shacham
_KVM_START_PAUSED_FLAG = "-S"
60 748e4b5a Michael Hanselmann
61 199b2053 Apollon Oikonomopoulos
# TUN/TAP driver constants, taken from <linux/if_tun.h>
62 199b2053 Apollon Oikonomopoulos
# They are architecture-independent and already hardcoded in qemu-kvm source,
63 199b2053 Apollon Oikonomopoulos
# so we can safely include them here.
64 199b2053 Apollon Oikonomopoulos
TUNSETIFF = 0x400454ca
65 199b2053 Apollon Oikonomopoulos
TUNGETIFF = 0x800454d2
66 199b2053 Apollon Oikonomopoulos
TUNGETFEATURES = 0x800454cf
67 199b2053 Apollon Oikonomopoulos
IFF_TAP = 0x0002
68 199b2053 Apollon Oikonomopoulos
IFF_NO_PI = 0x1000
69 199b2053 Apollon Oikonomopoulos
IFF_VNET_HDR = 0x4000
70 199b2053 Apollon Oikonomopoulos
71 07788a0b Michael Hanselmann
#: SPICE parameters which depend on L{constants.HV_KVM_SPICE_BIND}
72 07788a0b Michael Hanselmann
_SPICE_ADDITIONAL_PARAMS = frozenset([
73 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_IP_VERSION,
74 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_PASSWORD_FILE,
75 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR,
76 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_JPEG_IMG_COMPR,
77 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR,
78 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION,
79 07788a0b Michael Hanselmann
  constants.HV_KVM_SPICE_USE_TLS,
80 07788a0b Michael Hanselmann
  ])
81 07788a0b Michael Hanselmann
82 96f82929 Dimitris Aragiorgis
# below constants show the format of runtime file
83 96f82929 Dimitris Aragiorgis
# the nics are in second possition, while the disks in 4th (last)
84 96f82929 Dimitris Aragiorgis
# moreover disk entries are stored in tupples of L{objects.Disk}, dev_path
85 96f82929 Dimitris Aragiorgis
_KVM_NICS_RUNTIME_INDEX = 1
86 96f82929 Dimitris Aragiorgis
_KVM_DISKS_RUNTIME_INDEX = 3
87 96f82929 Dimitris Aragiorgis
_DEVICE_RUNTIME_INDEX = {
88 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK: _KVM_DISKS_RUNTIME_INDEX,
89 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC: _KVM_NICS_RUNTIME_INDEX
90 96f82929 Dimitris Aragiorgis
  }
91 96f82929 Dimitris Aragiorgis
_FIND_RUNTIME_ENTRY = {
92 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC:
93 96f82929 Dimitris Aragiorgis
    lambda nic, kvm_nics: [n for n in kvm_nics if n.uuid == nic.uuid],
94 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK:
95 96f82929 Dimitris Aragiorgis
    lambda disk, kvm_disks: [(d, l) for (d, l) in kvm_disks
96 96f82929 Dimitris Aragiorgis
                             if d.uuid == disk.uuid]
97 96f82929 Dimitris Aragiorgis
  }
98 96f82929 Dimitris Aragiorgis
_RUNTIME_DEVICE = {
99 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC: lambda d: d,
100 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK: lambda (d, e): d
101 96f82929 Dimitris Aragiorgis
  }
102 96f82929 Dimitris Aragiorgis
_RUNTIME_ENTRY = {
103 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_NIC: lambda d, e: d,
104 96f82929 Dimitris Aragiorgis
  constants.HOTPLUG_TARGET_DISK: lambda d, e: (d, e)
105 96f82929 Dimitris Aragiorgis
  }
106 96f82929 Dimitris Aragiorgis
107 96f82929 Dimitris Aragiorgis
108 96f82929 Dimitris Aragiorgis
def _GetExistingDeviceInfo(dev_type, device, runtime):
109 96f82929 Dimitris Aragiorgis
  """Helper function to get an existing device inside the runtime file
110 96f82929 Dimitris Aragiorgis

111 96f82929 Dimitris Aragiorgis
  Used when an instance is running. Load kvm runtime file and search
112 96f82929 Dimitris Aragiorgis
  for a device based on its type and uuid.
113 96f82929 Dimitris Aragiorgis

114 96f82929 Dimitris Aragiorgis
  @type dev_type: sting
115 96f82929 Dimitris Aragiorgis
  @param dev_type: device type of param dev
116 96f82929 Dimitris Aragiorgis
  @type device: L{objects.Disk} or L{objects.NIC}
117 96f82929 Dimitris Aragiorgis
  @param device: the device object for which we generate a kvm name
118 96f82929 Dimitris Aragiorgis
  @type runtime: tuple (cmd, nics, hvparams, disks)
119 96f82929 Dimitris Aragiorgis
  @param runtime: the runtime data to search for the device
120 96f82929 Dimitris Aragiorgis
  @raise errors.HotplugError: in case the requested device does not
121 96f82929 Dimitris Aragiorgis
    exist (e.g. device has been added without --hotplug option) or
122 96f82929 Dimitris Aragiorgis
    device info has not pci slot (e.g. old devices in the cluster)
123 96f82929 Dimitris Aragiorgis

124 96f82929 Dimitris Aragiorgis
  """
125 96f82929 Dimitris Aragiorgis
  index = _DEVICE_RUNTIME_INDEX[dev_type]
126 96f82929 Dimitris Aragiorgis
  found = _FIND_RUNTIME_ENTRY[dev_type](device, runtime[index])
127 96f82929 Dimitris Aragiorgis
  if not found:
128 96f82929 Dimitris Aragiorgis
    raise errors.HotplugError("Cannot find runtime info for %s with UUID %s" %
129 96f82929 Dimitris Aragiorgis
                              (dev_type, device.uuid))
130 96f82929 Dimitris Aragiorgis
131 96f82929 Dimitris Aragiorgis
  return found[0]
132 96f82929 Dimitris Aragiorgis
133 199b2053 Apollon Oikonomopoulos
134 ea2bcb82 Michael Hanselmann
def _GetTunFeatures(fd, _ioctl=fcntl.ioctl):
135 ea2bcb82 Michael Hanselmann
  """Retrieves supported TUN features from file descriptor.
136 ea2bcb82 Michael Hanselmann

137 ea2bcb82 Michael Hanselmann
  @see: L{_ProbeTapVnetHdr}
138 ea2bcb82 Michael Hanselmann

139 ea2bcb82 Michael Hanselmann
  """
140 ea2bcb82 Michael Hanselmann
  req = struct.pack("I", 0)
141 ea2bcb82 Michael Hanselmann
  try:
142 ea2bcb82 Michael Hanselmann
    buf = _ioctl(fd, TUNGETFEATURES, req)
143 ea2bcb82 Michael Hanselmann
  except EnvironmentError, err:
144 cfc24646 Iustin Pop
    logging.warning("ioctl(TUNGETFEATURES) failed: %s", err)
145 ea2bcb82 Michael Hanselmann
    return None
146 ea2bcb82 Michael Hanselmann
  else:
147 ea2bcb82 Michael Hanselmann
    (flags, ) = struct.unpack("I", buf)
148 ea2bcb82 Michael Hanselmann
    return flags
149 ea2bcb82 Michael Hanselmann
150 ea2bcb82 Michael Hanselmann
151 ea2bcb82 Michael Hanselmann
def _ProbeTapVnetHdr(fd, _features_fn=_GetTunFeatures):
152 199b2053 Apollon Oikonomopoulos
  """Check whether to enable the IFF_VNET_HDR flag.
153 199b2053 Apollon Oikonomopoulos

154 199b2053 Apollon Oikonomopoulos
  To do this, _all_ of the following conditions must be met:
155 199b2053 Apollon Oikonomopoulos
   1. TUNGETFEATURES ioctl() *must* be implemented
156 199b2053 Apollon Oikonomopoulos
   2. TUNGETFEATURES ioctl() result *must* contain the IFF_VNET_HDR flag
157 199b2053 Apollon Oikonomopoulos
   3. TUNGETIFF ioctl() *must* be implemented; reading the kernel code in
158 199b2053 Apollon Oikonomopoulos
      drivers/net/tun.c there is no way to test this until after the tap device
159 199b2053 Apollon Oikonomopoulos
      has been created using TUNSETIFF, and there is no way to change the
160 199b2053 Apollon Oikonomopoulos
      IFF_VNET_HDR flag after creating the interface, catch-22! However both
161 199b2053 Apollon Oikonomopoulos
      TUNGETIFF and TUNGETFEATURES were introduced in kernel version 2.6.27,
162 199b2053 Apollon Oikonomopoulos
      thus we can expect TUNGETIFF to be present if TUNGETFEATURES is.
163 199b2053 Apollon Oikonomopoulos

164 199b2053 Apollon Oikonomopoulos
   @type fd: int
165 199b2053 Apollon Oikonomopoulos
   @param fd: the file descriptor of /dev/net/tun
166 199b2053 Apollon Oikonomopoulos

167 199b2053 Apollon Oikonomopoulos
  """
168 ea2bcb82 Michael Hanselmann
  flags = _features_fn(fd)
169 199b2053 Apollon Oikonomopoulos
170 ea2bcb82 Michael Hanselmann
  if flags is None:
171 ea2bcb82 Michael Hanselmann
    # Not supported
172 199b2053 Apollon Oikonomopoulos
    return False
173 199b2053 Apollon Oikonomopoulos
174 ea2bcb82 Michael Hanselmann
  result = bool(flags & IFF_VNET_HDR)
175 ea2bcb82 Michael Hanselmann
176 ea2bcb82 Michael Hanselmann
  if not result:
177 ea2bcb82 Michael Hanselmann
    logging.warning("Kernel does not support IFF_VNET_HDR, not enabling")
178 ea2bcb82 Michael Hanselmann
179 ea2bcb82 Michael Hanselmann
  return result
180 ea2bcb82 Michael Hanselmann
181 199b2053 Apollon Oikonomopoulos
182 199b2053 Apollon Oikonomopoulos
def _OpenTap(vnet_hdr=True):
183 199b2053 Apollon Oikonomopoulos
  """Open a new tap device and return its file descriptor.
184 199b2053 Apollon Oikonomopoulos

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

188 199b2053 Apollon Oikonomopoulos
  @type vnet_hdr: boolean
189 199b2053 Apollon Oikonomopoulos
  @param vnet_hdr: Enable the VNET Header
190 199b2053 Apollon Oikonomopoulos
  @return: (ifname, tapfd)
191 199b2053 Apollon Oikonomopoulos
  @rtype: tuple
192 199b2053 Apollon Oikonomopoulos

193 199b2053 Apollon Oikonomopoulos
  """
194 199b2053 Apollon Oikonomopoulos
  try:
195 199b2053 Apollon Oikonomopoulos
    tapfd = os.open("/dev/net/tun", os.O_RDWR)
196 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
197 199b2053 Apollon Oikonomopoulos
    raise errors.HypervisorError("Failed to open /dev/net/tun")
198 199b2053 Apollon Oikonomopoulos
199 199b2053 Apollon Oikonomopoulos
  flags = IFF_TAP | IFF_NO_PI
200 199b2053 Apollon Oikonomopoulos
201 199b2053 Apollon Oikonomopoulos
  if vnet_hdr and _ProbeTapVnetHdr(tapfd):
202 199b2053 Apollon Oikonomopoulos
    flags |= IFF_VNET_HDR
203 199b2053 Apollon Oikonomopoulos
204 199b2053 Apollon Oikonomopoulos
  # The struct ifreq ioctl request (see netdevice(7))
205 199b2053 Apollon Oikonomopoulos
  ifr = struct.pack("16sh", "", flags)
206 199b2053 Apollon Oikonomopoulos
207 199b2053 Apollon Oikonomopoulos
  try:
208 199b2053 Apollon Oikonomopoulos
    res = fcntl.ioctl(tapfd, TUNSETIFF, ifr)
209 6f1e1921 Michael Hanselmann
  except EnvironmentError, err:
210 6f1e1921 Michael Hanselmann
    raise errors.HypervisorError("Failed to allocate a new TAP device: %s" %
211 6f1e1921 Michael Hanselmann
                                 err)
212 199b2053 Apollon Oikonomopoulos
213 199b2053 Apollon Oikonomopoulos
  # Get the interface name from the ioctl
214 199b2053 Apollon Oikonomopoulos
  ifname = struct.unpack("16sh", res)[0].strip("\x00")
215 199b2053 Apollon Oikonomopoulos
  return (ifname, tapfd)
216 199b2053 Apollon Oikonomopoulos
217 748e4b5a Michael Hanselmann
218 91c10532 Andrea Spadaccini
class QmpMessage:
219 91c10532 Andrea Spadaccini
  """QEMU Messaging Protocol (QMP) message.
220 91c10532 Andrea Spadaccini

221 91c10532 Andrea Spadaccini
  """
222 91c10532 Andrea Spadaccini
  def __init__(self, data):
223 91c10532 Andrea Spadaccini
    """Creates a new QMP message based on the passed data.
224 91c10532 Andrea Spadaccini

225 91c10532 Andrea Spadaccini
    """
226 91c10532 Andrea Spadaccini
    if not isinstance(data, dict):
227 91c10532 Andrea Spadaccini
      raise TypeError("QmpMessage must be initialized with a dict")
228 91c10532 Andrea Spadaccini
229 91c10532 Andrea Spadaccini
    self.data = data
230 91c10532 Andrea Spadaccini
231 91c10532 Andrea Spadaccini
  def __getitem__(self, field_name):
232 91c10532 Andrea Spadaccini
    """Get the value of the required field if present, or None.
233 91c10532 Andrea Spadaccini

234 91c10532 Andrea Spadaccini
    Overrides the [] operator to provide access to the message data,
235 91c10532 Andrea Spadaccini
    returning None if the required item is not in the message
236 91c10532 Andrea Spadaccini
    @return: the value of the field_name field, or None if field_name
237 91c10532 Andrea Spadaccini
             is not contained in the message
238 91c10532 Andrea Spadaccini

239 91c10532 Andrea Spadaccini
    """
240 9b87c2cf Michael Hanselmann
    return self.data.get(field_name, None)
241 91c10532 Andrea Spadaccini
242 91c10532 Andrea Spadaccini
  def __setitem__(self, field_name, field_value):
243 91c10532 Andrea Spadaccini
    """Set the value of the required field_name to field_value.
244 91c10532 Andrea Spadaccini

245 91c10532 Andrea Spadaccini
    """
246 91c10532 Andrea Spadaccini
    self.data[field_name] = field_value
247 91c10532 Andrea Spadaccini
248 91c10532 Andrea Spadaccini
  @staticmethod
249 91c10532 Andrea Spadaccini
  def BuildFromJsonString(json_string):
250 91c10532 Andrea Spadaccini
    """Build a QmpMessage from a JSON encoded string.
251 91c10532 Andrea Spadaccini

252 91c10532 Andrea Spadaccini
    @type json_string: str
253 91c10532 Andrea Spadaccini
    @param json_string: JSON string representing the message
254 91c10532 Andrea Spadaccini
    @rtype: L{QmpMessage}
255 91c10532 Andrea Spadaccini
    @return: a L{QmpMessage} built from json_string
256 91c10532 Andrea Spadaccini

257 91c10532 Andrea Spadaccini
    """
258 91c10532 Andrea Spadaccini
    # Parse the string
259 91c10532 Andrea Spadaccini
    data = serializer.LoadJson(json_string)
260 91c10532 Andrea Spadaccini
    return QmpMessage(data)
261 91c10532 Andrea Spadaccini
262 91c10532 Andrea Spadaccini
  def __str__(self):
263 a182a3ed Michael Hanselmann
    # The protocol expects the JSON object to be sent as a single line.
264 a182a3ed Michael Hanselmann
    return serializer.DumpJson(self.data)
265 91c10532 Andrea Spadaccini
266 91c10532 Andrea Spadaccini
  def __eq__(self, other):
267 91c10532 Andrea Spadaccini
    # When comparing two QmpMessages, we are interested in comparing
268 91c10532 Andrea Spadaccini
    # their internal representation of the message data
269 91c10532 Andrea Spadaccini
    return self.data == other.data
270 91c10532 Andrea Spadaccini
271 91c10532 Andrea Spadaccini
272 91c10532 Andrea Spadaccini
class QmpConnection:
273 91c10532 Andrea Spadaccini
  """Connection to the QEMU Monitor using the QEMU Monitor Protocol (QMP).
274 91c10532 Andrea Spadaccini

275 91c10532 Andrea Spadaccini
  """
276 91c10532 Andrea Spadaccini
  _FIRST_MESSAGE_KEY = "QMP"
277 91c10532 Andrea Spadaccini
  _EVENT_KEY = "event"
278 91c10532 Andrea Spadaccini
  _ERROR_KEY = "error"
279 89da2ff3 Guido Trotter
  _RETURN_KEY = RETURN_KEY = "return"
280 89da2ff3 Guido Trotter
  _ACTUAL_KEY = ACTUAL_KEY = "actual"
281 91c10532 Andrea Spadaccini
  _ERROR_CLASS_KEY = "class"
282 91c10532 Andrea Spadaccini
  _ERROR_DATA_KEY = "data"
283 91c10532 Andrea Spadaccini
  _ERROR_DESC_KEY = "desc"
284 91c10532 Andrea Spadaccini
  _EXECUTE_KEY = "execute"
285 91c10532 Andrea Spadaccini
  _ARGUMENTS_KEY = "arguments"
286 91c10532 Andrea Spadaccini
  _CAPABILITIES_COMMAND = "qmp_capabilities"
287 91c10532 Andrea Spadaccini
  _MESSAGE_END_TOKEN = "\r\n"
288 91c10532 Andrea Spadaccini
  _SOCKET_TIMEOUT = 5
289 91c10532 Andrea Spadaccini
290 91c10532 Andrea Spadaccini
  def __init__(self, monitor_filename):
291 91c10532 Andrea Spadaccini
    """Instantiates the QmpConnection object.
292 91c10532 Andrea Spadaccini

293 91c10532 Andrea Spadaccini
    @type monitor_filename: string
294 91c10532 Andrea Spadaccini
    @param monitor_filename: the filename of the UNIX raw socket on which the
295 91c10532 Andrea Spadaccini
                             QMP monitor is listening
296 91c10532 Andrea Spadaccini

297 91c10532 Andrea Spadaccini
    """
298 91c10532 Andrea Spadaccini
    self.monitor_filename = monitor_filename
299 91c10532 Andrea Spadaccini
    self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
300 91c10532 Andrea Spadaccini
    # We want to fail if the server doesn't send a complete message
301 91c10532 Andrea Spadaccini
    # in a reasonable amount of time
302 91c10532 Andrea Spadaccini
    self.sock.settimeout(self._SOCKET_TIMEOUT)
303 91c10532 Andrea Spadaccini
    self._connected = False
304 91c10532 Andrea Spadaccini
    self._buf = ""
305 91c10532 Andrea Spadaccini
306 fc84cd5d Guido Trotter
  def _check_socket(self):
307 fc84cd5d Guido Trotter
    sock_stat = None
308 fc84cd5d Guido Trotter
    try:
309 fc84cd5d Guido Trotter
      sock_stat = os.stat(self.monitor_filename)
310 fc84cd5d Guido Trotter
    except EnvironmentError, err:
311 fc84cd5d Guido Trotter
      if err.errno == errno.ENOENT:
312 fc84cd5d Guido Trotter
        raise errors.HypervisorError("No qmp socket found")
313 fc84cd5d Guido Trotter
      else:
314 fc84cd5d Guido Trotter
        raise errors.HypervisorError("Error checking qmp socket: %s",
315 fc84cd5d Guido Trotter
                                     utils.ErrnoOrStr(err))
316 fc84cd5d Guido Trotter
    if not stat.S_ISSOCK(sock_stat.st_mode):
317 fc84cd5d Guido Trotter
      raise errors.HypervisorError("Qmp socket is not a socket")
318 fc84cd5d Guido Trotter
319 91c10532 Andrea Spadaccini
  def _check_connection(self):
320 91c10532 Andrea Spadaccini
    """Make sure that the connection is established.
321 91c10532 Andrea Spadaccini

322 91c10532 Andrea Spadaccini
    """
323 91c10532 Andrea Spadaccini
    if not self._connected:
324 91c10532 Andrea Spadaccini
      raise errors.ProgrammerError("To use a QmpConnection you need to first"
325 91c10532 Andrea Spadaccini
                                   " invoke connect() on it")
326 91c10532 Andrea Spadaccini
327 91c10532 Andrea Spadaccini
  def connect(self):
328 91c10532 Andrea Spadaccini
    """Connects to the QMP monitor.
329 91c10532 Andrea Spadaccini

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

333 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
334 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
335 91c10532 Andrea Spadaccini

336 91c10532 Andrea Spadaccini
    """
337 fc84cd5d Guido Trotter
    if self._connected:
338 fc84cd5d Guido Trotter
      raise errors.ProgrammerError("Cannot connect twice")
339 fc84cd5d Guido Trotter
340 fc84cd5d Guido Trotter
    self._check_socket()
341 fc84cd5d Guido Trotter
342 fc84cd5d Guido Trotter
    # Check file existance/stuff
343 fc84cd5d Guido Trotter
    try:
344 fc84cd5d Guido Trotter
      self.sock.connect(self.monitor_filename)
345 fc84cd5d Guido Trotter
    except EnvironmentError:
346 fc84cd5d Guido Trotter
      raise errors.HypervisorError("Can't connect to qmp socket")
347 91c10532 Andrea Spadaccini
    self._connected = True
348 91c10532 Andrea Spadaccini
349 91c10532 Andrea Spadaccini
    # Check if we receive a correct greeting message from the server
350 91c10532 Andrea Spadaccini
    # (As per the QEMU Protocol Specification 0.1 - section 2.2)
351 91c10532 Andrea Spadaccini
    greeting = self._Recv()
352 91c10532 Andrea Spadaccini
    if not greeting[self._FIRST_MESSAGE_KEY]:
353 91c10532 Andrea Spadaccini
      self._connected = False
354 afa9bb2e Michael Hanselmann
      raise errors.HypervisorError("kvm: QMP communication error (wrong"
355 91c10532 Andrea Spadaccini
                                   " server greeting")
356 91c10532 Andrea Spadaccini
357 91c10532 Andrea Spadaccini
    # Let's put the monitor in command mode using the qmp_capabilities
358 91c10532 Andrea Spadaccini
    # command, or else no command will be executable.
359 91c10532 Andrea Spadaccini
    # (As per the QEMU Protocol Specification 0.1 - section 4)
360 91c10532 Andrea Spadaccini
    self.Execute(self._CAPABILITIES_COMMAND)
361 91c10532 Andrea Spadaccini
362 91c10532 Andrea Spadaccini
  def _ParseMessage(self, buf):
363 91c10532 Andrea Spadaccini
    """Extract and parse a QMP message from the given buffer.
364 91c10532 Andrea Spadaccini

365 91c10532 Andrea Spadaccini
    Seeks for a QMP message in the given buf. If found, it parses it and
366 91c10532 Andrea Spadaccini
    returns it together with the rest of the characters in the buf.
367 91c10532 Andrea Spadaccini
    If no message is found, returns None and the whole buffer.
368 91c10532 Andrea Spadaccini

369 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
370 91c10532 Andrea Spadaccini

371 91c10532 Andrea Spadaccini
    """
372 91c10532 Andrea Spadaccini
    message = None
373 91c10532 Andrea Spadaccini
    # Check if we got the message end token (CRLF, as per the QEMU Protocol
374 91c10532 Andrea Spadaccini
    # Specification 0.1 - Section 2.1.1)
375 91c10532 Andrea Spadaccini
    pos = buf.find(self._MESSAGE_END_TOKEN)
376 91c10532 Andrea Spadaccini
    if pos >= 0:
377 91c10532 Andrea Spadaccini
      try:
378 91c10532 Andrea Spadaccini
        message = QmpMessage.BuildFromJsonString(buf[:pos + 1])
379 91c10532 Andrea Spadaccini
      except Exception, err:
380 91c10532 Andrea Spadaccini
        raise errors.ProgrammerError("QMP data serialization error: %s" % err)
381 91c10532 Andrea Spadaccini
      buf = buf[pos + 1:]
382 91c10532 Andrea Spadaccini
383 91c10532 Andrea Spadaccini
    return (message, buf)
384 91c10532 Andrea Spadaccini
385 91c10532 Andrea Spadaccini
  def _Recv(self):
386 91c10532 Andrea Spadaccini
    """Receives a message from QMP and decodes the received JSON object.
387 91c10532 Andrea Spadaccini

388 91c10532 Andrea Spadaccini
    @rtype: QmpMessage
389 91c10532 Andrea Spadaccini
    @return: the received message
390 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
391 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
392 91c10532 Andrea Spadaccini

393 91c10532 Andrea Spadaccini
    """
394 91c10532 Andrea Spadaccini
    self._check_connection()
395 91c10532 Andrea Spadaccini
396 91c10532 Andrea Spadaccini
    # Check if there is already a message in the buffer
397 91c10532 Andrea Spadaccini
    (message, self._buf) = self._ParseMessage(self._buf)
398 91c10532 Andrea Spadaccini
    if message:
399 91c10532 Andrea Spadaccini
      return message
400 91c10532 Andrea Spadaccini
401 91c10532 Andrea Spadaccini
    recv_buffer = StringIO.StringIO(self._buf)
402 91c10532 Andrea Spadaccini
    recv_buffer.seek(len(self._buf))
403 91c10532 Andrea Spadaccini
    try:
404 91c10532 Andrea Spadaccini
      while True:
405 91c10532 Andrea Spadaccini
        data = self.sock.recv(4096)
406 91c10532 Andrea Spadaccini
        if not data:
407 91c10532 Andrea Spadaccini
          break
408 91c10532 Andrea Spadaccini
        recv_buffer.write(data)
409 91c10532 Andrea Spadaccini
410 91c10532 Andrea Spadaccini
        (message, self._buf) = self._ParseMessage(recv_buffer.getvalue())
411 91c10532 Andrea Spadaccini
        if message:
412 91c10532 Andrea Spadaccini
          return message
413 91c10532 Andrea Spadaccini
414 91c10532 Andrea Spadaccini
    except socket.timeout, err:
415 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Timeout while receiving a QMP message: "
416 91c10532 Andrea Spadaccini
                                   "%s" % (err))
417 91c10532 Andrea Spadaccini
    except socket.error, err:
418 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Unable to receive data from KVM using the"
419 91c10532 Andrea Spadaccini
                                   " QMP protocol: %s" % err)
420 91c10532 Andrea Spadaccini
421 91c10532 Andrea Spadaccini
  def _Send(self, message):
422 91c10532 Andrea Spadaccini
    """Encodes and sends a message to KVM using QMP.
423 91c10532 Andrea Spadaccini

424 91c10532 Andrea Spadaccini
    @type message: QmpMessage
425 91c10532 Andrea Spadaccini
    @param message: message to send to KVM
426 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
427 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
428 91c10532 Andrea Spadaccini

429 91c10532 Andrea Spadaccini
    """
430 91c10532 Andrea Spadaccini
    self._check_connection()
431 91c10532 Andrea Spadaccini
    try:
432 91c10532 Andrea Spadaccini
      message_str = str(message)
433 91c10532 Andrea Spadaccini
    except Exception, err:
434 91c10532 Andrea Spadaccini
      raise errors.ProgrammerError("QMP data deserialization error: %s" % err)
435 91c10532 Andrea Spadaccini
436 91c10532 Andrea Spadaccini
    try:
437 91c10532 Andrea Spadaccini
      self.sock.sendall(message_str)
438 91c10532 Andrea Spadaccini
    except socket.timeout, err:
439 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Timeout while sending a QMP message: "
440 91c10532 Andrea Spadaccini
                                   "%s (%s)" % (err.string, err.errno))
441 91c10532 Andrea Spadaccini
    except socket.error, err:
442 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Unable to send data from KVM using the"
443 91c10532 Andrea Spadaccini
                                   " QMP protocol: %s" % err)
444 91c10532 Andrea Spadaccini
445 91c10532 Andrea Spadaccini
  def Execute(self, command, arguments=None):
446 91c10532 Andrea Spadaccini
    """Executes a QMP command and returns the response of the server.
447 91c10532 Andrea Spadaccini

448 91c10532 Andrea Spadaccini
    @type command: str
449 91c10532 Andrea Spadaccini
    @param command: the command to execute
450 91c10532 Andrea Spadaccini
    @type arguments: dict
451 91c10532 Andrea Spadaccini
    @param arguments: dictionary of arguments to be passed to the command
452 91c10532 Andrea Spadaccini
    @rtype: dict
453 91c10532 Andrea Spadaccini
    @return: dictionary representing the received JSON object
454 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
455 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
456 91c10532 Andrea Spadaccini

457 91c10532 Andrea Spadaccini
    """
458 91c10532 Andrea Spadaccini
    self._check_connection()
459 91c10532 Andrea Spadaccini
    message = QmpMessage({self._EXECUTE_KEY: command})
460 91c10532 Andrea Spadaccini
    if arguments:
461 91c10532 Andrea Spadaccini
      message[self._ARGUMENTS_KEY] = arguments
462 91c10532 Andrea Spadaccini
    self._Send(message)
463 91c10532 Andrea Spadaccini
464 91c10532 Andrea Spadaccini
    # Events can occur between the sending of the command and the reception
465 91c10532 Andrea Spadaccini
    # of the response, so we need to filter out messages with the event key.
466 91c10532 Andrea Spadaccini
    while True:
467 91c10532 Andrea Spadaccini
      response = self._Recv()
468 91c10532 Andrea Spadaccini
      err = response[self._ERROR_KEY]
469 91c10532 Andrea Spadaccini
      if err:
470 91c10532 Andrea Spadaccini
        raise errors.HypervisorError("kvm: error executing the %s"
471 91c10532 Andrea Spadaccini
                                     " command: %s (%s, %s):" %
472 91c10532 Andrea Spadaccini
                                     (command,
473 91c10532 Andrea Spadaccini
                                      err[self._ERROR_DESC_KEY],
474 91c10532 Andrea Spadaccini
                                      err[self._ERROR_CLASS_KEY],
475 91c10532 Andrea Spadaccini
                                      err[self._ERROR_DATA_KEY]))
476 91c10532 Andrea Spadaccini
477 91c10532 Andrea Spadaccini
      elif not response[self._EVENT_KEY]:
478 91c10532 Andrea Spadaccini
        return response
479 91c10532 Andrea Spadaccini
480 91c10532 Andrea Spadaccini
481 eb58f9b1 Guido Trotter
class KVMHypervisor(hv_base.BaseHypervisor):
482 65107a2f Michael Hanselmann
  """KVM hypervisor interface
483 65107a2f Michael Hanselmann

484 65107a2f Michael Hanselmann
  """
485 d271c6fd Iustin Pop
  CAN_MIGRATE = True
486 eb58f9b1 Guido Trotter
487 9d9bded1 Michael Hanselmann
  _ROOT_DIR = pathutils.RUN_DIR + "/kvm-hypervisor"
488 a1d79fc6 Guido Trotter
  _PIDS_DIR = _ROOT_DIR + "/pid" # contains live instances pids
489 7548396c Guido Trotter
  _UIDS_DIR = _ROOT_DIR + "/uid" # contains instances reserved uids
490 a1d79fc6 Guido Trotter
  _CTRL_DIR = _ROOT_DIR + "/ctrl" # contains instances control sockets
491 a1d79fc6 Guido Trotter
  _CONF_DIR = _ROOT_DIR + "/conf" # contains instances startup data
492 5d9bfd87 Apollon Oikonomopoulos
  _NICS_DIR = _ROOT_DIR + "/nic" # contains instances nic <-> tap associations
493 4f580fef Sébastien Bocahu
  _KEYMAP_DIR = _ROOT_DIR + "/keymap" # contains instances keymaps
494 547a63b7 Balazs Lecz
  # KVM instances with chroot enabled are started in empty chroot directories.
495 547a63b7 Balazs Lecz
  _CHROOT_DIR = _ROOT_DIR + "/chroot" # for empty chroot directories
496 547a63b7 Balazs Lecz
  # After an instance is stopped, its chroot directory is removed.
497 547a63b7 Balazs Lecz
  # If the chroot directory is not empty, it can't be removed.
498 547a63b7 Balazs Lecz
  # A non-empty chroot directory indicates a possible security incident.
499 547a63b7 Balazs Lecz
  # To support forensics, the non-empty chroot directory is quarantined in
500 547a63b7 Balazs Lecz
  # a separate directory, called 'chroot-quarantine'.
501 547a63b7 Balazs Lecz
  _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine"
502 5d9bfd87 Apollon Oikonomopoulos
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR, _NICS_DIR,
503 2911f46c Iustin Pop
           _CHROOT_DIR, _CHROOT_QUARANTINE_DIR, _KEYMAP_DIR]
504 eb58f9b1 Guido Trotter
505 205ab586 Iustin Pop
  PARAMETERS = {
506 4b9638dc Guido Trotter
    constants.HV_KVM_PATH: hv_base.REQ_FILE_CHECK,
507 205ab586 Iustin Pop
    constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK,
508 205ab586 Iustin Pop
    constants.HV_INITRD_PATH: hv_base.OPT_FILE_CHECK,
509 205ab586 Iustin Pop
    constants.HV_ROOT_PATH: hv_base.NO_CHECK,
510 205ab586 Iustin Pop
    constants.HV_KERNEL_ARGS: hv_base.NO_CHECK,
511 205ab586 Iustin Pop
    constants.HV_ACPI: hv_base.NO_CHECK,
512 205ab586 Iustin Pop
    constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
513 14fd6c81 Guido Trotter
    constants.HV_SERIAL_SPEED: hv_base.NO_CHECK,
514 d6e5767e Klaus Aehlig
    constants.HV_VNC_BIND_ADDRESS: hv_base.NO_CHECK, # will be checked later
515 205ab586 Iustin Pop
    constants.HV_VNC_TLS: hv_base.NO_CHECK,
516 205ab586 Iustin Pop
    constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
517 205ab586 Iustin Pop
    constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
518 6e6bb8d5 Guido Trotter
    constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
519 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_BIND: hv_base.NO_CHECK, # will be checked later
520 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_IP_VERSION:
521 b1cb62bd Andrea Spadaccini
      (False, lambda x: (x == constants.IFACE_NO_IP_VERSION_SPECIFIED or
522 b1cb62bd Andrea Spadaccini
                         x in constants.VALID_IP_VERSIONS),
523 afa9bb2e Michael Hanselmann
       "The SPICE IP version should be 4 or 6",
524 b1cb62bd Andrea Spadaccini
       None, None),
525 b451c4c7 Andrea Spadaccini
    constants.HV_KVM_SPICE_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
526 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR:
527 5ae4945a Iustin Pop
      hv_base.ParamInSet(
528 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSLESS_IMG_COMPR_OPTIONS),
529 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_JPEG_IMG_COMPR:
530 5ae4945a Iustin Pop
      hv_base.ParamInSet(
531 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
532 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR:
533 5ae4945a Iustin Pop
      hv_base.ParamInSet(
534 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
535 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION:
536 5ae4945a Iustin Pop
      hv_base.ParamInSet(
537 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_VIDEO_STREAM_DETECTION_OPTIONS),
538 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_AUDIO_COMPR: hv_base.NO_CHECK,
539 bfe86c76 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_TLS: hv_base.NO_CHECK,
540 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_TLS_CIPHERS: hv_base.NO_CHECK,
541 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_VDAGENT: hv_base.NO_CHECK,
542 cc130cc7 Marco Casavecchia
    constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
543 205ab586 Iustin Pop
    constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
544 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
545 d73ef63f Michael Hanselmann
    constants.HV_BOOT_ORDER:
546 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
547 d73ef63f Michael Hanselmann
    constants.HV_NIC_TYPE:
548 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_NIC_TYPES),
549 d73ef63f Michael Hanselmann
    constants.HV_DISK_TYPE:
550 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_DISK_TYPES),
551 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM_DISK_TYPE:
552 cc130cc7 Marco Casavecchia
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_DISK_TYPES),
553 d73ef63f Michael Hanselmann
    constants.HV_USB_MOUSE:
554 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_MOUSE_TYPES),
555 4f580fef Sébastien Bocahu
    constants.HV_KEYMAP: hv_base.NO_CHECK,
556 e2d14329 Andrea Spadaccini
    constants.HV_MIGRATION_PORT: hv_base.REQ_NET_PORT_CHECK,
557 2c368f28 Guido Trotter
    constants.HV_MIGRATION_BANDWIDTH: hv_base.REQ_NONNEGATIVE_INT_CHECK,
558 2c368f28 Guido Trotter
    constants.HV_MIGRATION_DOWNTIME: hv_base.REQ_NONNEGATIVE_INT_CHECK,
559 783a6c0b Iustin Pop
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
560 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
561 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
562 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
563 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
564 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
565 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
566 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
567 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
568 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
569 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
570 4f958b0b Miguel Di Ciurcio Filho
    constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
571 990ade2d Stephen Shirley
    constants.HV_REBOOT_BEHAVIOR:
572 a7f884d3 Tsachy Shacham
      hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
573 a7f884d3 Tsachy Shacham
    constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
574 3c286190 Dimitris Aragiorgis
    constants.HV_CPU_TYPE: hv_base.NO_CHECK,
575 2c368f28 Guido Trotter
    constants.HV_CPU_CORES: hv_base.OPT_NONNEGATIVE_INT_CHECK,
576 2c368f28 Guido Trotter
    constants.HV_CPU_THREADS: hv_base.OPT_NONNEGATIVE_INT_CHECK,
577 2c368f28 Guido Trotter
    constants.HV_CPU_SOCKETS: hv_base.OPT_NONNEGATIVE_INT_CHECK,
578 2fddb144 Guido Trotter
    constants.HV_SOUNDHW: hv_base.NO_CHECK,
579 156681c1 Guido Trotter
    constants.HV_USB_DEVICES: hv_base.NO_CHECK,
580 7589346f Guido Trotter
    constants.HV_VGA: hv_base.NO_CHECK,
581 e6f24d89 Guido Trotter
    constants.HV_KVM_EXTRA: hv_base.NO_CHECK,
582 4ab75599 Dimitris Aragiorgis
    constants.HV_KVM_MACHINE_VERSION: hv_base.NO_CHECK,
583 8a534fbe Stratos Psomdakis
    constants.HV_VNET_HDR: hv_base.NO_CHECK,
584 205ab586 Iustin Pop
    }
585 6b5605e8 Iustin Pop
586 f0db563d Guido Trotter
  _VIRTIO = "virtio"
587 f0db563d Guido Trotter
  _VIRTIO_NET_PCI = "virtio-net-pci"
588 cbdaf62a Dimitris Aragiorgis
  _VIRTIO_BLK_PCI = "virtio-blk-pci"
589 f0db563d Guido Trotter
590 d0c8c01d Iustin Pop
  _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)",
591 30e42c4e Guido Trotter
                                    re.M | re.I)
592 65107a2f Michael Hanselmann
  _MIGRATION_PROGRESS_RE = \
593 527c0cf7 Michael Hanselmann
    re.compile(r"\s*transferred\s+ram:\s+(?P<transferred>\d+)\s+kbytes\s*\n"
594 527c0cf7 Michael Hanselmann
               r"\s*remaining\s+ram:\s+(?P<remaining>\d+)\s+kbytes\s*\n"
595 527c0cf7 Michael Hanselmann
               r"\s*total\s+ram:\s+(?P<total>\d+)\s+kbytes\s*\n", re.I)
596 61643226 Andrea Spadaccini
597 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
598 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
599 30e42c4e Guido Trotter
600 585c8187 Guido Trotter
  _VERSION_RE = re.compile(r"\b(\d+)\.(\d+)(\.(\d+))?\b")
601 b52d85c1 Guido Trotter
602 b693125f Tsachy Shacham
  _CPU_INFO_RE = re.compile(r"cpu\s+\#(\d+).*thread_id\s*=\s*(\d+)", re.I)
603 b693125f Tsachy Shacham
  _CPU_INFO_CMD = "info cpus"
604 b693125f Tsachy Shacham
  _CONT_CMD = "cont"
605 b693125f Tsachy Shacham
606 7f83345f Guido Trotter
  _DEFAULT_MACHINE_VERSION_RE = re.compile(r"^(\S+).*\(default\)", re.M)
607 82e3bf85 Dimitris Aragiorgis
  _CHECK_MACHINE_VERSION_RE = \
608 82e3bf85 Dimitris Aragiorgis
    staticmethod(lambda x: re.compile(r"^(%s)[ ]+.*PC" % x, re.M))
609 e6ba3320 Dimitris Aragiorgis
610 0ad7f5d8 Guido Trotter
  _QMP_RE = re.compile(r"^-qmp\s", re.M)
611 0ad7f5d8 Guido Trotter
  _SPICE_RE = re.compile(r"^-spice\s", re.M)
612 0ad7f5d8 Guido Trotter
  _VHOST_RE = re.compile(r"^-net\s.*,vhost=on|off", re.M)
613 0ad7f5d8 Guido Trotter
  _ENABLE_KVM_RE = re.compile(r"^-enable-kvm\s", re.M)
614 0ad7f5d8 Guido Trotter
  _DISABLE_KVM_RE = re.compile(r"^-disable-kvm\s", re.M)
615 0ad7f5d8 Guido Trotter
  _NETDEV_RE = re.compile(r"^-netdev\s", re.M)
616 99c7cd5b Guido Trotter
  _DISPLAY_RE = re.compile(r"^-display\s", re.M)
617 8cb5634a Guido Trotter
  _MACHINE_RE = re.compile(r"^-machine\s", re.M)
618 cbdaf62a Dimitris Aragiorgis
  _VIRTIO_NET_RE = re.compile(r"^name \"%s\"" % _VIRTIO_NET_PCI, re.M)
619 cbdaf62a Dimitris Aragiorgis
  _VIRTIO_BLK_RE = re.compile(r"^name \"%s\"" % _VIRTIO_BLK_PCI, re.M)
620 0ad7f5d8 Guido Trotter
  # match  -drive.*boot=on|off on different lines, but in between accept only
621 0ad7f5d8 Guido Trotter
  # dashes not preceeded by a new line (which would mean another option
622 0ad7f5d8 Guido Trotter
  # different than -drive is starting)
623 0ad7f5d8 Guido Trotter
  _BOOT_RE = re.compile(r"^-drive\s([^-]|(?<!^)-)*,boot=on\|off", re.M | re.S)
624 8feeb253 Christos Stavrakakis
  _UUID_RE = re.compile(r"^-uuid\s", re.M)
625 0ad7f5d8 Guido Trotter
626 64bfbc08 Guido Trotter
  ANCILLARY_FILES = [
627 64bfbc08 Guido Trotter
    _KVM_NETWORK_SCRIPT,
628 64bfbc08 Guido Trotter
    ]
629 69ab2e12 Guido Trotter
  ANCILLARY_FILES_OPT = [
630 69ab2e12 Guido Trotter
    _KVM_NETWORK_SCRIPT,
631 69ab2e12 Guido Trotter
    ]
632 64bfbc08 Guido Trotter
633 6e043e60 Guido Trotter
  # Supported kvm options to get output from
634 6e043e60 Guido Trotter
  _KVMOPT_HELP = "help"
635 6e043e60 Guido Trotter
  _KVMOPT_MLIST = "mlist"
636 f0db563d Guido Trotter
  _KVMOPT_DEVICELIST = "devicelist"
637 bc0fed4b Guido Trotter
638 bc0fed4b Guido Trotter
  # Command to execute to get the output from kvm, and whether to
639 bc0fed4b Guido Trotter
  # accept the output even on failure.
640 6e043e60 Guido Trotter
  _KVMOPTS_CMDS = {
641 bc0fed4b Guido Trotter
    _KVMOPT_HELP: (["--help"], False),
642 bc0fed4b Guido Trotter
    _KVMOPT_MLIST: (["-M", "?"], False),
643 bc0fed4b Guido Trotter
    _KVMOPT_DEVICELIST: (["-device", "?"], True),
644 6e043e60 Guido Trotter
  }
645 6e043e60 Guido Trotter
646 eb58f9b1 Guido Trotter
  def __init__(self):
647 eb58f9b1 Guido Trotter
    hv_base.BaseHypervisor.__init__(self)
648 eb58f9b1 Guido Trotter
    # Let's make sure the directories we need exist, even if the RUN_DIR lives
649 eb58f9b1 Guido Trotter
    # in a tmpfs filesystem or has been otherwise wiped out.
650 29921401 Iustin Pop
    dirs = [(dname, constants.RUN_DIRS_MODE) for dname in self._DIRS]
651 9afb67fe Guido Trotter
    utils.EnsureDirs(dirs)
652 eb58f9b1 Guido Trotter
653 30786fc9 Iustin Pop
  @classmethod
654 30786fc9 Iustin Pop
  def _InstancePidFile(cls, instance_name):
655 98ec75d6 Iustin Pop
    """Returns the instance pidfile.
656 98ec75d6 Iustin Pop

657 98ec75d6 Iustin Pop
    """
658 30786fc9 Iustin Pop
    return utils.PathJoin(cls._PIDS_DIR, instance_name)
659 98ec75d6 Iustin Pop
660 263b8de6 Guido Trotter
  @classmethod
661 7548396c Guido Trotter
  def _InstanceUidFile(cls, instance_name):
662 7548396c Guido Trotter
    """Returns the instance uidfile.
663 7548396c Guido Trotter

664 7548396c Guido Trotter
    """
665 7548396c Guido Trotter
    return utils.PathJoin(cls._UIDS_DIR, instance_name)
666 7548396c Guido Trotter
667 7548396c Guido Trotter
  @classmethod
668 263b8de6 Guido Trotter
  def _InstancePidInfo(cls, pid):
669 263b8de6 Guido Trotter
    """Check pid file for instance information.
670 263b8de6 Guido Trotter

671 263b8de6 Guido Trotter
    Check that a pid file is associated with an instance, and retrieve
672 263b8de6 Guido Trotter
    information from its command line.
673 263b8de6 Guido Trotter

674 263b8de6 Guido Trotter
    @type pid: string or int
675 263b8de6 Guido Trotter
    @param pid: process id of the instance to check
676 263b8de6 Guido Trotter
    @rtype: tuple
677 263b8de6 Guido Trotter
    @return: (instance_name, memory, vcpus)
678 263b8de6 Guido Trotter
    @raise errors.HypervisorError: when an instance cannot be found
679 263b8de6 Guido Trotter

680 263b8de6 Guido Trotter
    """
681 263b8de6 Guido Trotter
    alive = utils.IsProcessAlive(pid)
682 263b8de6 Guido Trotter
    if not alive:
683 263b8de6 Guido Trotter
      raise errors.HypervisorError("Cannot get info for pid %s" % pid)
684 263b8de6 Guido Trotter
685 263b8de6 Guido Trotter
    cmdline_file = utils.PathJoin("/proc", str(pid), "cmdline")
686 263b8de6 Guido Trotter
    try:
687 263b8de6 Guido Trotter
      cmdline = utils.ReadFile(cmdline_file)
688 263b8de6 Guido Trotter
    except EnvironmentError, err:
689 263b8de6 Guido Trotter
      raise errors.HypervisorError("Can't open cmdline file for pid %s: %s" %
690 263b8de6 Guido Trotter
                                   (pid, err))
691 263b8de6 Guido Trotter
692 263b8de6 Guido Trotter
    instance = None
693 263b8de6 Guido Trotter
    memory = 0
694 263b8de6 Guido Trotter
    vcpus = 0
695 263b8de6 Guido Trotter
696 d0c8c01d Iustin Pop
    arg_list = cmdline.split("\x00")
697 263b8de6 Guido Trotter
    while arg_list:
698 e687ec01 Michael Hanselmann
      arg = arg_list.pop(0)
699 263b8de6 Guido Trotter
      if arg == "-name":
700 263b8de6 Guido Trotter
        instance = arg_list.pop(0)
701 263b8de6 Guido Trotter
      elif arg == "-m":
702 263b8de6 Guido Trotter
        memory = int(arg_list.pop(0))
703 263b8de6 Guido Trotter
      elif arg == "-smp":
704 4888a609 Guido Trotter
        vcpus = int(arg_list.pop(0).split(",")[0])
705 263b8de6 Guido Trotter
706 263b8de6 Guido Trotter
    if instance is None:
707 263b8de6 Guido Trotter
      raise errors.HypervisorError("Pid %s doesn't contain a ganeti kvm"
708 263b8de6 Guido Trotter
                                   " instance" % pid)
709 263b8de6 Guido Trotter
710 263b8de6 Guido Trotter
    return (instance, memory, vcpus)
711 263b8de6 Guido Trotter
712 1f8b3a27 Guido Trotter
  def _InstancePidAlive(self, instance_name):
713 263b8de6 Guido Trotter
    """Returns the instance pidfile, pid, and liveness.
714 263b8de6 Guido Trotter

715 263b8de6 Guido Trotter
    @type instance_name: string
716 263b8de6 Guido Trotter
    @param instance_name: instance name
717 263b8de6 Guido Trotter
    @rtype: tuple
718 263b8de6 Guido Trotter
    @return: (pid file name, pid, liveness)
719 1f8b3a27 Guido Trotter

720 1f8b3a27 Guido Trotter
    """
721 98ec75d6 Iustin Pop
    pidfile = self._InstancePidFile(instance_name)
722 1f8b3a27 Guido Trotter
    pid = utils.ReadPidFile(pidfile)
723 263b8de6 Guido Trotter
724 263b8de6 Guido Trotter
    alive = False
725 263b8de6 Guido Trotter
    try:
726 263b8de6 Guido Trotter
      cmd_instance = self._InstancePidInfo(pid)[0]
727 263b8de6 Guido Trotter
      alive = (cmd_instance == instance_name)
728 263b8de6 Guido Trotter
    except errors.HypervisorError:
729 263b8de6 Guido Trotter
      pass
730 1f8b3a27 Guido Trotter
731 1f8b3a27 Guido Trotter
    return (pidfile, pid, alive)
732 1f8b3a27 Guido Trotter
733 5905901c Iustin Pop
  def _CheckDown(self, instance_name):
734 5905901c Iustin Pop
    """Raises an error unless the given instance is down.
735 5905901c Iustin Pop

736 5905901c Iustin Pop
    """
737 5905901c Iustin Pop
    alive = self._InstancePidAlive(instance_name)[2]
738 5905901c Iustin Pop
    if alive:
739 5905901c Iustin Pop
      raise errors.HypervisorError("Failed to start instance %s: %s" %
740 5905901c Iustin Pop
                                   (instance_name, "already running"))
741 5905901c Iustin Pop
742 0df4d98a Guido Trotter
  @classmethod
743 0df4d98a Guido Trotter
  def _InstanceMonitor(cls, instance_name):
744 c4fbefc8 Guido Trotter
    """Returns the instance monitor socket name
745 c4fbefc8 Guido Trotter

746 c4fbefc8 Guido Trotter
    """
747 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.monitor" % instance_name)
748 c4fbefc8 Guido Trotter
749 0df4d98a Guido Trotter
  @classmethod
750 0df4d98a Guido Trotter
  def _InstanceSerial(cls, instance_name):
751 c4fbefc8 Guido Trotter
    """Returns the instance serial socket name
752 c4fbefc8 Guido Trotter

753 c4fbefc8 Guido Trotter
    """
754 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.serial" % instance_name)
755 c4fbefc8 Guido Trotter
756 91c10532 Andrea Spadaccini
  @classmethod
757 91c10532 Andrea Spadaccini
  def _InstanceQmpMonitor(cls, instance_name):
758 91c10532 Andrea Spadaccini
    """Returns the instance serial QMP socket name
759 91c10532 Andrea Spadaccini

760 91c10532 Andrea Spadaccini
    """
761 91c10532 Andrea Spadaccini
    return utils.PathJoin(cls._CTRL_DIR, "%s.qmp" % instance_name)
762 91c10532 Andrea Spadaccini
763 86d6bc2a Guido Trotter
  @staticmethod
764 86d6bc2a Guido Trotter
  def _SocatUnixConsoleParams():
765 86d6bc2a Guido Trotter
    """Returns the correct parameters for socat
766 86d6bc2a Guido Trotter

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

769 86d6bc2a Guido Trotter
    """
770 fe5b0c42 Michael Hanselmann
    if constants.SOCAT_USE_ESCAPE:
771 86d6bc2a Guido Trotter
      return "raw,echo=0,escape=%s" % constants.SOCAT_ESCAPE_CODE
772 86d6bc2a Guido Trotter
    else:
773 86d6bc2a Guido Trotter
      return "echo=0,icanon=0"
774 86d6bc2a Guido Trotter
775 0df4d98a Guido Trotter
  @classmethod
776 0df4d98a Guido Trotter
  def _InstanceKVMRuntime(cls, instance_name):
777 38e250ba Guido Trotter
    """Returns the instance KVM runtime filename
778 38e250ba Guido Trotter

779 38e250ba Guido Trotter
    """
780 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
781 38e250ba Guido Trotter
782 7e66c35b Guido Trotter
  @classmethod
783 547a63b7 Balazs Lecz
  def _InstanceChrootDir(cls, instance_name):
784 547a63b7 Balazs Lecz
    """Returns the name of the KVM chroot dir of the instance
785 547a63b7 Balazs Lecz

786 547a63b7 Balazs Lecz
    """
787 547a63b7 Balazs Lecz
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
788 547a63b7 Balazs Lecz
789 547a63b7 Balazs Lecz
  @classmethod
790 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICDir(cls, instance_name):
791 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the directory holding the tap device files for a
792 5d9bfd87 Apollon Oikonomopoulos
    given instance.
793 5d9bfd87 Apollon Oikonomopoulos

794 5d9bfd87 Apollon Oikonomopoulos
    """
795 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._NICS_DIR, instance_name)
796 5d9bfd87 Apollon Oikonomopoulos
797 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
798 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICFile(cls, instance_name, seq):
799 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the file containing the tap device for a given NIC
800 5d9bfd87 Apollon Oikonomopoulos

801 5d9bfd87 Apollon Oikonomopoulos
    """
802 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._InstanceNICDir(instance_name), str(seq))
803 5d9bfd87 Apollon Oikonomopoulos
804 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
805 4f580fef Sébastien Bocahu
  def _InstanceKeymapFile(cls, instance_name):
806 4f580fef Sébastien Bocahu
    """Returns the name of the file containing the keymap for a given instance
807 4f580fef Sébastien Bocahu

808 4f580fef Sébastien Bocahu
    """
809 4f580fef Sébastien Bocahu
    return utils.PathJoin(cls._KEYMAP_DIR, instance_name)
810 4f580fef Sébastien Bocahu
811 4f580fef Sébastien Bocahu
  @classmethod
812 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
813 7548396c Guido Trotter
    """Try to read a uid file
814 7548396c Guido Trotter

815 7548396c Guido Trotter
    """
816 7548396c Guido Trotter
    if os.path.exists(uid_file):
817 7548396c Guido Trotter
      try:
818 682f7601 Guido Trotter
        uid = int(utils.ReadOneLineFile(uid_file))
819 aa0b600b Guido Trotter
        return uid
820 7548396c Guido Trotter
      except EnvironmentError:
821 7548396c Guido Trotter
        logging.warning("Can't read uid file", exc_info=True)
822 7548396c Guido Trotter
      except (TypeError, ValueError):
823 7548396c Guido Trotter
        logging.warning("Can't parse uid file contents", exc_info=True)
824 aa0b600b Guido Trotter
    return None
825 7548396c Guido Trotter
826 7548396c Guido Trotter
  @classmethod
827 7e66c35b Guido Trotter
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
828 547a63b7 Balazs Lecz
    """Removes an instance's rutime sockets/files/dirs.
829 7e66c35b Guido Trotter

830 7e66c35b Guido Trotter
    """
831 7e66c35b Guido Trotter
    utils.RemoveFile(pidfile)
832 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceMonitor(instance_name))
833 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceSerial(instance_name))
834 91c10532 Andrea Spadaccini
    utils.RemoveFile(cls._InstanceQmpMonitor(instance_name))
835 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceKVMRuntime(instance_name))
836 4f580fef Sébastien Bocahu
    utils.RemoveFile(cls._InstanceKeymapFile(instance_name))
837 7548396c Guido Trotter
    uid_file = cls._InstanceUidFile(instance_name)
838 7548396c Guido Trotter
    uid = cls._TryReadUidFile(uid_file)
839 7548396c Guido Trotter
    utils.RemoveFile(uid_file)
840 7548396c Guido Trotter
    if uid is not None:
841 7548396c Guido Trotter
      uidpool.ReleaseUid(uid)
842 7be85163 Guido Trotter
    try:
843 7be85163 Guido Trotter
      shutil.rmtree(cls._InstanceNICDir(instance_name))
844 7be85163 Guido Trotter
    except OSError, err:
845 7be85163 Guido Trotter
      if err.errno != errno.ENOENT:
846 7be85163 Guido Trotter
        raise
847 547a63b7 Balazs Lecz
    try:
848 547a63b7 Balazs Lecz
      chroot_dir = cls._InstanceChrootDir(instance_name)
849 547a63b7 Balazs Lecz
      utils.RemoveDir(chroot_dir)
850 547a63b7 Balazs Lecz
    except OSError, err:
851 547a63b7 Balazs Lecz
      if err.errno == errno.ENOTEMPTY:
852 547a63b7 Balazs Lecz
        # The chroot directory is expected to be empty, but it isn't.
853 547a63b7 Balazs Lecz
        new_chroot_dir = tempfile.mkdtemp(dir=cls._CHROOT_QUARANTINE_DIR,
854 547a63b7 Balazs Lecz
                                          prefix="%s-%s-" %
855 547a63b7 Balazs Lecz
                                          (instance_name,
856 547a63b7 Balazs Lecz
                                           utils.TimestampForFilename()))
857 547a63b7 Balazs Lecz
        logging.warning("The chroot directory of instance %s can not be"
858 547a63b7 Balazs Lecz
                        " removed as it is not empty. Moving it to the"
859 547a63b7 Balazs Lecz
                        " quarantine instead. Please investigate the"
860 547a63b7 Balazs Lecz
                        " contents (%s) and clean up manually",
861 547a63b7 Balazs Lecz
                        instance_name, new_chroot_dir)
862 547a63b7 Balazs Lecz
        utils.RenameFile(chroot_dir, new_chroot_dir)
863 547a63b7 Balazs Lecz
      else:
864 547a63b7 Balazs Lecz
        raise
865 7e66c35b Guido Trotter
866 748e4b5a Michael Hanselmann
  @staticmethod
867 5d9bfd87 Apollon Oikonomopoulos
  def _ConfigureNIC(instance, seq, nic, tap):
868 5d9bfd87 Apollon Oikonomopoulos
    """Run the network configuration script for a specified NIC
869 eb58f9b1 Guido Trotter

870 eb58f9b1 Guido Trotter
    @param instance: instance we're acting on
871 eb58f9b1 Guido Trotter
    @type instance: instance object
872 eb58f9b1 Guido Trotter
    @param seq: nic sequence number
873 eb58f9b1 Guido Trotter
    @type seq: int
874 eb58f9b1 Guido Trotter
    @param nic: nic we're acting on
875 eb58f9b1 Guido Trotter
    @type nic: nic object
876 5d9bfd87 Apollon Oikonomopoulos
    @param tap: the host's tap interface this NIC corresponds to
877 5d9bfd87 Apollon Oikonomopoulos
    @type tap: str
878 eb58f9b1 Guido Trotter

879 eb58f9b1 Guido Trotter
    """
880 5d9bfd87 Apollon Oikonomopoulos
    if instance.tags:
881 5d9bfd87 Apollon Oikonomopoulos
      tags = " ".join(instance.tags)
882 5d9bfd87 Apollon Oikonomopoulos
    else:
883 5d9bfd87 Apollon Oikonomopoulos
      tags = ""
884 5d9bfd87 Apollon Oikonomopoulos
885 5d9bfd87 Apollon Oikonomopoulos
    env = {
886 5d9bfd87 Apollon Oikonomopoulos
      "PATH": "%s:/sbin:/usr/sbin" % os.environ["PATH"],
887 5d9bfd87 Apollon Oikonomopoulos
      "INSTANCE": instance.name,
888 5d9bfd87 Apollon Oikonomopoulos
      "MAC": nic.mac,
889 5d9bfd87 Apollon Oikonomopoulos
      "MODE": nic.nicparams[constants.NIC_MODE],
890 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE": tap,
891 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE_INDEX": str(seq),
892 5d9bfd87 Apollon Oikonomopoulos
      "TAGS": tags,
893 5d9bfd87 Apollon Oikonomopoulos
    }
894 5d9bfd87 Apollon Oikonomopoulos
895 5d9bfd87 Apollon Oikonomopoulos
    if nic.ip:
896 5d9bfd87 Apollon Oikonomopoulos
      env["IP"] = nic.ip
897 5d9bfd87 Apollon Oikonomopoulos
898 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_LINK]:
899 5d9bfd87 Apollon Oikonomopoulos
      env["LINK"] = nic.nicparams[constants.NIC_LINK]
900 5d9bfd87 Apollon Oikonomopoulos
901 a5ad5e58 Apollon Oikonomopoulos
    if nic.network:
902 cbe4a0a5 Dimitris Aragiorgis
      n = objects.Network.FromDict(nic.netinfo)
903 7e8f03e3 Dimitris Aragiorgis
      env.update(n.HooksDict())
904 a5ad5e58 Apollon Oikonomopoulos
905 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
906 5d9bfd87 Apollon Oikonomopoulos
      env["BRIDGE"] = nic.nicparams[constants.NIC_LINK]
907 5d9bfd87 Apollon Oikonomopoulos
908 9d9bded1 Michael Hanselmann
    result = utils.RunCmd([pathutils.KVM_IFUP, tap], env=env)
909 5d9bfd87 Apollon Oikonomopoulos
    if result.failed:
910 afa9bb2e Michael Hanselmann
      raise errors.HypervisorError("Failed to configure interface %s: %s;"
911 afa9bb2e Michael Hanselmann
                                   " network configuration script output: %s" %
912 5d9bfd87 Apollon Oikonomopoulos
                                   (tap, result.fail_reason, result.output))
913 eb58f9b1 Guido Trotter
914 b693125f Tsachy Shacham
  @staticmethod
915 b693125f Tsachy Shacham
  def _VerifyAffinityPackage():
916 b693125f Tsachy Shacham
    if affinity is None:
917 b693125f Tsachy Shacham
      raise errors.HypervisorError("affinity Python package not"
918 5ae4945a Iustin Pop
                                   " found; cannot use CPU pinning under KVM")
919 b693125f Tsachy Shacham
920 b693125f Tsachy Shacham
  @staticmethod
921 b693125f Tsachy Shacham
  def _BuildAffinityCpuMask(cpu_list):
922 b693125f Tsachy Shacham
    """Create a CPU mask suitable for sched_setaffinity from a list of
923 b693125f Tsachy Shacham
    CPUs.
924 b693125f Tsachy Shacham

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

928 b693125f Tsachy Shacham
    @type cpu_list: list of int
929 b693125f Tsachy Shacham
    @param cpu_list: list of physical CPU numbers to map to vCPUs in order
930 b693125f Tsachy Shacham
    @rtype: int
931 b693125f Tsachy Shacham
    @return: a bit mask of CPU affinities
932 b693125f Tsachy Shacham

933 b693125f Tsachy Shacham
    """
934 b693125f Tsachy Shacham
    if cpu_list == constants.CPU_PINNING_OFF:
935 b693125f Tsachy Shacham
      return constants.CPU_PINNING_ALL_KVM
936 b693125f Tsachy Shacham
    else:
937 b693125f Tsachy Shacham
      return sum(2 ** cpu for cpu in cpu_list)
938 b693125f Tsachy Shacham
939 b693125f Tsachy Shacham
  @classmethod
940 b693125f Tsachy Shacham
  def _AssignCpuAffinity(cls, cpu_mask, process_id, thread_dict):
941 b693125f Tsachy Shacham
    """Change CPU affinity for running VM according to given CPU mask.
942 b693125f Tsachy Shacham

943 b693125f Tsachy Shacham
    @param cpu_mask: CPU mask as given by the user. e.g. "0-2,4:all:1,3"
944 b693125f Tsachy Shacham
    @type cpu_mask: string
945 b693125f Tsachy Shacham
    @param process_id: process ID of KVM process. Used to pin entire VM
946 b693125f Tsachy Shacham
                       to physical CPUs.
947 b693125f Tsachy Shacham
    @type process_id: int
948 b693125f Tsachy Shacham
    @param thread_dict: map of virtual CPUs to KVM thread IDs
949 b693125f Tsachy Shacham
    @type thread_dict: dict int:int
950 b693125f Tsachy Shacham

951 b693125f Tsachy Shacham
    """
952 b693125f Tsachy Shacham
    # Convert the string CPU mask to a list of list of int's
953 b693125f Tsachy Shacham
    cpu_list = utils.ParseMultiCpuMask(cpu_mask)
954 b693125f Tsachy Shacham
955 b693125f Tsachy Shacham
    if len(cpu_list) == 1:
956 b693125f Tsachy Shacham
      all_cpu_mapping = cpu_list[0]
957 b693125f Tsachy Shacham
      if all_cpu_mapping == constants.CPU_PINNING_OFF:
958 b693125f Tsachy Shacham
        # If CPU pinning has 1 entry that's "all", then do nothing
959 b693125f Tsachy Shacham
        pass
960 b693125f Tsachy Shacham
      else:
961 b693125f Tsachy Shacham
        # If CPU pinning has one non-all entry, map the entire VM to
962 b693125f Tsachy Shacham
        # one set of physical CPUs
963 b693125f Tsachy Shacham
        cls._VerifyAffinityPackage()
964 5ae4945a Iustin Pop
        affinity.set_process_affinity_mask(
965 5ae4945a Iustin Pop
          process_id, cls._BuildAffinityCpuMask(all_cpu_mapping))
966 b693125f Tsachy Shacham
    else:
967 b693125f Tsachy Shacham
      # The number of vCPUs mapped should match the number of vCPUs
968 b693125f Tsachy Shacham
      # reported by KVM. This was already verified earlier, so
969 b693125f Tsachy Shacham
      # here only as a sanity check.
970 b693125f Tsachy Shacham
      assert len(thread_dict) == len(cpu_list)
971 b693125f Tsachy Shacham
      cls._VerifyAffinityPackage()
972 b693125f Tsachy Shacham
973 b693125f Tsachy Shacham
      # For each vCPU, map it to the proper list of physical CPUs
974 b693125f Tsachy Shacham
      for vcpu, i in zip(cpu_list, range(len(cpu_list))):
975 b693125f Tsachy Shacham
        affinity.set_process_affinity_mask(thread_dict[i],
976 5ae4945a Iustin Pop
                                           cls._BuildAffinityCpuMask(vcpu))
977 b693125f Tsachy Shacham
978 b693125f Tsachy Shacham
  def _GetVcpuThreadIds(self, instance_name):
979 b693125f Tsachy Shacham
    """Get a mapping of vCPU no. to thread IDs for the instance
980 b693125f Tsachy Shacham

981 b693125f Tsachy Shacham
    @type instance_name: string
982 b693125f Tsachy Shacham
    @param instance_name: instance in question
983 b693125f Tsachy Shacham
    @rtype: dictionary of int:int
984 b693125f Tsachy Shacham
    @return: a dictionary mapping vCPU numbers to thread IDs
985 b693125f Tsachy Shacham

986 b693125f Tsachy Shacham
    """
987 b693125f Tsachy Shacham
    result = {}
988 b693125f Tsachy Shacham
    output = self._CallMonitorCommand(instance_name, self._CPU_INFO_CMD)
989 b693125f Tsachy Shacham
    for line in output.stdout.splitlines():
990 b693125f Tsachy Shacham
      match = self._CPU_INFO_RE.search(line)
991 b693125f Tsachy Shacham
      if not match:
992 b693125f Tsachy Shacham
        continue
993 b693125f Tsachy Shacham
      grp = map(int, match.groups())
994 b693125f Tsachy Shacham
      result[grp[0]] = grp[1]
995 b693125f Tsachy Shacham
996 b693125f Tsachy Shacham
    return result
997 b693125f Tsachy Shacham
998 1d8a7812 Andrea Spadaccini
  def _ExecuteCpuAffinity(self, instance_name, cpu_mask):
999 1d8a7812 Andrea Spadaccini
    """Complete CPU pinning.
1000 b693125f Tsachy Shacham

1001 b693125f Tsachy Shacham
    @type instance_name: string
1002 b693125f Tsachy Shacham
    @param instance_name: name of instance
1003 b693125f Tsachy Shacham
    @type cpu_mask: string
1004 b693125f Tsachy Shacham
    @param cpu_mask: CPU pinning mask as entered by user
1005 b693125f Tsachy Shacham

1006 b693125f Tsachy Shacham
    """
1007 1d8a7812 Andrea Spadaccini
    # Get KVM process ID, to be used if need to pin entire VM
1008 1d8a7812 Andrea Spadaccini
    _, pid, _ = self._InstancePidAlive(instance_name)
1009 1d8a7812 Andrea Spadaccini
    # Get vCPU thread IDs, to be used if need to pin vCPUs separately
1010 1d8a7812 Andrea Spadaccini
    thread_dict = self._GetVcpuThreadIds(instance_name)
1011 1d8a7812 Andrea Spadaccini
    # Run CPU pinning, based on configured mask
1012 1d8a7812 Andrea Spadaccini
    self._AssignCpuAffinity(cpu_mask, pid, thread_dict)
1013 b693125f Tsachy Shacham
1014 58e356a9 Helga Velroyen
  def ListInstances(self, hvparams=None):
1015 eb58f9b1 Guido Trotter
    """Get the list of running instances.
1016 eb58f9b1 Guido Trotter

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

1020 eb58f9b1 Guido Trotter
    """
1021 eb58f9b1 Guido Trotter
    result = []
1022 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
1023 263b8de6 Guido Trotter
      if self._InstancePidAlive(name)[2]:
1024 eb58f9b1 Guido Trotter
        result.append(name)
1025 eb58f9b1 Guido Trotter
    return result
1026 eb58f9b1 Guido Trotter
1027 0bbec3af Helga Velroyen
  def GetInstanceInfo(self, instance_name, hvparams=None):
1028 eb58f9b1 Guido Trotter
    """Get instance properties.
1029 eb58f9b1 Guido Trotter

1030 4fbb3c60 Guido Trotter
    @type instance_name: string
1031 c41eea6e Iustin Pop
    @param instance_name: the instance name
1032 0bbec3af Helga Velroyen
    @type hvparams: dict of strings
1033 0bbec3af Helga Velroyen
    @param hvparams: hvparams to be used with this instance
1034 4fbb3c60 Guido Trotter
    @rtype: tuple of strings
1035 4fbb3c60 Guido Trotter
    @return: (name, id, memory, vcpus, stat, times)
1036 eb58f9b1 Guido Trotter

1037 eb58f9b1 Guido Trotter
    """
1038 1122eb25 Iustin Pop
    _, pid, alive = self._InstancePidAlive(instance_name)
1039 1f8b3a27 Guido Trotter
    if not alive:
1040 eb58f9b1 Guido Trotter
      return None
1041 eb58f9b1 Guido Trotter
1042 263b8de6 Guido Trotter
    _, memory, vcpus = self._InstancePidInfo(pid)
1043 fc84cd5d Guido Trotter
    istat = "---b-"
1044 eb58f9b1 Guido Trotter
    times = "0"
1045 eb58f9b1 Guido Trotter
1046 89da2ff3 Guido Trotter
    try:
1047 89da2ff3 Guido Trotter
      qmp = QmpConnection(self._InstanceQmpMonitor(instance_name))
1048 89da2ff3 Guido Trotter
      qmp.connect()
1049 89da2ff3 Guido Trotter
      vcpus = len(qmp.Execute("query-cpus")[qmp.RETURN_KEY])
1050 89da2ff3 Guido Trotter
      # Will fail if ballooning is not enabled, but we can then just resort to
1051 89da2ff3 Guido Trotter
      # the value above.
1052 89da2ff3 Guido Trotter
      mem_bytes = qmp.Execute("query-balloon")[qmp.RETURN_KEY][qmp.ACTUAL_KEY]
1053 89da2ff3 Guido Trotter
      memory = mem_bytes / 1048576
1054 89da2ff3 Guido Trotter
    except errors.HypervisorError:
1055 89da2ff3 Guido Trotter
      pass
1056 89da2ff3 Guido Trotter
1057 fc84cd5d Guido Trotter
    return (instance_name, pid, memory, vcpus, istat, times)
1058 eb58f9b1 Guido Trotter
1059 0200a1af Helga Velroyen
  def GetAllInstancesInfo(self, hvparams=None):
1060 eb58f9b1 Guido Trotter
    """Get properties of all instances.
1061 eb58f9b1 Guido Trotter

1062 0200a1af Helga Velroyen
    @type hvparams: dict of strings
1063 0200a1af Helga Velroyen
    @param hvparams: hypervisor parameter
1064 c41eea6e Iustin Pop
    @return: list of tuples (name, id, memory, vcpus, stat, times)
1065 c41eea6e Iustin Pop

1066 eb58f9b1 Guido Trotter
    """
1067 eb58f9b1 Guido Trotter
    data = []
1068 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
1069 263b8de6 Guido Trotter
      try:
1070 263b8de6 Guido Trotter
        info = self.GetInstanceInfo(name)
1071 263b8de6 Guido Trotter
      except errors.HypervisorError:
1072 3bc145d8 Bernardo Dal Seno
        # Ignore exceptions due to instances being shut down
1073 263b8de6 Guido Trotter
        continue
1074 263b8de6 Guido Trotter
      if info:
1075 263b8de6 Guido Trotter
        data.append(info)
1076 eb58f9b1 Guido Trotter
    return data
1077 eb58f9b1 Guido Trotter
1078 6ebbbbc2 Dimitris Aragiorgis
  def _GenerateKVMBlockDevicesOptions(self, instance, block_devices, kvmhelp):
1079 6ebbbbc2 Dimitris Aragiorgis
1080 6ebbbbc2 Dimitris Aragiorgis
    hvp = instance.hvparams
1081 6ebbbbc2 Dimitris Aragiorgis
    boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK
1082 cbdaf62a Dimitris Aragiorgis
    kvm_path = hvp[constants.HV_KVM_PATH]
1083 6ebbbbc2 Dimitris Aragiorgis
1084 6ebbbbc2 Dimitris Aragiorgis
    # whether this is an older KVM version that uses the boot=on flag
1085 6ebbbbc2 Dimitris Aragiorgis
    # on devices
1086 6ebbbbc2 Dimitris Aragiorgis
    needs_boot_flag = self._BOOT_RE.search(kvmhelp)
1087 6ebbbbc2 Dimitris Aragiorgis
1088 6ebbbbc2 Dimitris Aragiorgis
    dev_opts = []
1089 cbdaf62a Dimitris Aragiorgis
    device_driver = None
1090 6ebbbbc2 Dimitris Aragiorgis
    disk_type = hvp[constants.HV_DISK_TYPE]
1091 6ebbbbc2 Dimitris Aragiorgis
    if disk_type == constants.HT_DISK_PARAVIRTUAL:
1092 6ebbbbc2 Dimitris Aragiorgis
      if_val = ",if=%s" % self._VIRTIO
1093 cbdaf62a Dimitris Aragiorgis
      try:
1094 cbdaf62a Dimitris Aragiorgis
        devlist = self._GetKVMOutput(kvm_path, self._KVMOPT_DEVICELIST)
1095 cbdaf62a Dimitris Aragiorgis
        if self._VIRTIO_BLK_RE.search(devlist):
1096 cbdaf62a Dimitris Aragiorgis
          # TODO: uncomment when -device is used
1097 cbdaf62a Dimitris Aragiorgis
          # if_val = ",if=none"
1098 cbdaf62a Dimitris Aragiorgis
          # will be passed in -device option as driver
1099 cbdaf62a Dimitris Aragiorgis
          device_driver = self._VIRTIO_BLK_PCI
1100 cbdaf62a Dimitris Aragiorgis
      except errors.HypervisorError, _:
1101 cbdaf62a Dimitris Aragiorgis
        pass
1102 6ebbbbc2 Dimitris Aragiorgis
    else:
1103 6ebbbbc2 Dimitris Aragiorgis
      if_val = ",if=%s" % disk_type
1104 6ebbbbc2 Dimitris Aragiorgis
    # Cache mode
1105 6ebbbbc2 Dimitris Aragiorgis
    disk_cache = hvp[constants.HV_DISK_CACHE]
1106 6ebbbbc2 Dimitris Aragiorgis
    if instance.disk_template in constants.DTS_EXT_MIRROR:
1107 6ebbbbc2 Dimitris Aragiorgis
      if disk_cache != "none":
1108 6ebbbbc2 Dimitris Aragiorgis
        # TODO: make this a hard error, instead of a silent overwrite
1109 6ebbbbc2 Dimitris Aragiorgis
        logging.warning("KVM: overriding disk_cache setting '%s' with 'none'"
1110 6ebbbbc2 Dimitris Aragiorgis
                        " to prevent shared storage corruption on migration",
1111 6ebbbbc2 Dimitris Aragiorgis
                        disk_cache)
1112 6ebbbbc2 Dimitris Aragiorgis
      cache_val = ",cache=none"
1113 6ebbbbc2 Dimitris Aragiorgis
    elif disk_cache != constants.HT_CACHE_DEFAULT:
1114 6ebbbbc2 Dimitris Aragiorgis
      cache_val = ",cache=%s" % disk_cache
1115 6ebbbbc2 Dimitris Aragiorgis
    else:
1116 6ebbbbc2 Dimitris Aragiorgis
      cache_val = ""
1117 6ebbbbc2 Dimitris Aragiorgis
    for cfdev, dev_path in block_devices:
1118 6ebbbbc2 Dimitris Aragiorgis
      if cfdev.mode != constants.DISK_RDWR:
1119 6ebbbbc2 Dimitris Aragiorgis
        raise errors.HypervisorError("Instance has read-only disks which"
1120 6ebbbbc2 Dimitris Aragiorgis
                                     " are not supported by KVM")
1121 6ebbbbc2 Dimitris Aragiorgis
      # TODO: handle FD_LOOP and FD_BLKTAP (?)
1122 6ebbbbc2 Dimitris Aragiorgis
      boot_val = ""
1123 6ebbbbc2 Dimitris Aragiorgis
      if boot_disk:
1124 6ebbbbc2 Dimitris Aragiorgis
        dev_opts.extend(["-boot", "c"])
1125 6ebbbbc2 Dimitris Aragiorgis
        boot_disk = False
1126 6ebbbbc2 Dimitris Aragiorgis
        if needs_boot_flag and disk_type != constants.HT_DISK_IDE:
1127 6ebbbbc2 Dimitris Aragiorgis
          boot_val = ",boot=on"
1128 6ebbbbc2 Dimitris Aragiorgis
      drive_val = "file=%s,format=raw%s%s%s" % \
1129 6ebbbbc2 Dimitris Aragiorgis
                  (dev_path, if_val, boot_val, cache_val)
1130 6ebbbbc2 Dimitris Aragiorgis
1131 cbdaf62a Dimitris Aragiorgis
      if device_driver:
1132 cbdaf62a Dimitris Aragiorgis
        pass
1133 6ebbbbc2 Dimitris Aragiorgis
      dev_opts.extend(["-drive", drive_val])
1134 6ebbbbc2 Dimitris Aragiorgis
1135 6ebbbbc2 Dimitris Aragiorgis
    return dev_opts
1136 6ebbbbc2 Dimitris Aragiorgis
1137 b73f1c59 Guido Trotter
  def _GenerateKVMRuntime(self, instance, block_devices, startup_paused,
1138 b73f1c59 Guido Trotter
                          kvmhelp):
1139 ee5f20b0 Guido Trotter
    """Generate KVM information to start an instance.
1140 eb58f9b1 Guido Trotter

1141 b73f1c59 Guido Trotter
    @type kvmhelp: string
1142 b73f1c59 Guido Trotter
    @param kvmhelp: output of kvm --help
1143 839642c2 Iustin Pop
    @attention: this function must not have any side-effects; for
1144 839642c2 Iustin Pop
        example, it must not write to the filesystem, or read values
1145 839642c2 Iustin Pop
        from the current system the are expected to differ between
1146 839642c2 Iustin Pop
        nodes, since it is only run once at instance startup;
1147 839642c2 Iustin Pop
        actions/kvm arguments that can vary between systems should be
1148 839642c2 Iustin Pop
        done in L{_ExecuteKVMRuntime}
1149 839642c2 Iustin Pop

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

1500 38e250ba Guido Trotter
    """
1501 38e250ba Guido Trotter
    try:
1502 38e250ba Guido Trotter
      utils.WriteFile(self._InstanceKVMRuntime(instance_name),
1503 38e250ba Guido Trotter
                      data=data)
1504 90c024f6 Guido Trotter
    except EnvironmentError, err:
1505 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to save KVM runtime file: %s" % err)
1506 38e250ba Guido Trotter
1507 38e250ba Guido Trotter
  def _ReadKVMRuntime(self, instance_name):
1508 38e250ba Guido Trotter
    """Read an instance's KVM runtime
1509 38e250ba Guido Trotter

1510 38e250ba Guido Trotter
    """
1511 38e250ba Guido Trotter
    try:
1512 38e250ba Guido Trotter
      file_content = utils.ReadFile(self._InstanceKVMRuntime(instance_name))
1513 90c024f6 Guido Trotter
    except EnvironmentError, err:
1514 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to load KVM runtime file: %s" % err)
1515 38e250ba Guido Trotter
    return file_content
1516 38e250ba Guido Trotter
1517 38e250ba Guido Trotter
  def _SaveKVMRuntime(self, instance, kvm_runtime):
1518 38e250ba Guido Trotter
    """Save an instance's KVM runtime
1519 38e250ba Guido Trotter

1520 38e250ba Guido Trotter
    """
1521 96f82929 Dimitris Aragiorgis
    kvm_cmd, kvm_nics, hvparams, block_devices = kvm_runtime
1522 96f82929 Dimitris Aragiorgis
1523 38e250ba Guido Trotter
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
1524 96f82929 Dimitris Aragiorgis
    serialized_blockdevs = [(blk.ToDict(), link) for blk, link in block_devices]
1525 96f82929 Dimitris Aragiorgis
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams,
1526 96f82929 Dimitris Aragiorgis
                                      serialized_blockdevs))
1527 96f82929 Dimitris Aragiorgis
1528 38e250ba Guido Trotter
    self._WriteKVMRuntime(instance.name, serialized_form)
1529 38e250ba Guido Trotter
1530 30e42c4e Guido Trotter
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
1531 38e250ba Guido Trotter
    """Load an instance's KVM runtime
1532 38e250ba Guido Trotter

1533 38e250ba Guido Trotter
    """
1534 30e42c4e Guido Trotter
    if not serialized_runtime:
1535 30e42c4e Guido Trotter
      serialized_runtime = self._ReadKVMRuntime(instance.name)
1536 96f82929 Dimitris Aragiorgis
1537 30e42c4e Guido Trotter
    loaded_runtime = serializer.Load(serialized_runtime)
1538 96f82929 Dimitris Aragiorgis
    if len(loaded_runtime) == 3:
1539 96f82929 Dimitris Aragiorgis
      serialized_blockdevs = []
1540 96f82929 Dimitris Aragiorgis
      kvm_cmd, serialized_nics, hvparams = loaded_runtime
1541 96f82929 Dimitris Aragiorgis
    else:
1542 96f82929 Dimitris Aragiorgis
      kvm_cmd, serialized_nics, hvparams, serialized_blockdevs = loaded_runtime
1543 96f82929 Dimitris Aragiorgis
1544 38e250ba Guido Trotter
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
1545 96f82929 Dimitris Aragiorgis
    block_devices = [(objects.Disk.FromDict(sdisk), link)
1546 96f82929 Dimitris Aragiorgis
                     for sdisk, link in serialized_blockdevs]
1547 96f82929 Dimitris Aragiorgis
1548 96f82929 Dimitris Aragiorgis
    return (kvm_cmd, kvm_nics, hvparams, block_devices)
1549 38e250ba Guido Trotter
1550 5d9bfd87 Apollon Oikonomopoulos
  def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None):
1551 76431533 Guido Trotter
    """Run the KVM cmd and check for errors
1552 76431533 Guido Trotter

1553 76431533 Guido Trotter
    @type name: string
1554 76431533 Guido Trotter
    @param name: instance name
1555 76431533 Guido Trotter
    @type kvm_cmd: list of strings
1556 76431533 Guido Trotter
    @param kvm_cmd: runcmd input for kvm
1557 5d9bfd87 Apollon Oikonomopoulos
    @type tap_fds: list of int
1558 5d9bfd87 Apollon Oikonomopoulos
    @param tap_fds: fds of tap devices opened by Ganeti
1559 76431533 Guido Trotter

1560 76431533 Guido Trotter
    """
1561 5d9bfd87 Apollon Oikonomopoulos
    try:
1562 5d9bfd87 Apollon Oikonomopoulos
      result = utils.RunCmd(kvm_cmd, noclose_fds=tap_fds)
1563 5d9bfd87 Apollon Oikonomopoulos
    finally:
1564 5d9bfd87 Apollon Oikonomopoulos
      for fd in tap_fds:
1565 5d9bfd87 Apollon Oikonomopoulos
        utils_wrapper.CloseFdNoError(fd)
1566 5d9bfd87 Apollon Oikonomopoulos
1567 76431533 Guido Trotter
    if result.failed:
1568 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
1569 76431533 Guido Trotter
                                   (name, result.fail_reason, result.output))
1570 76431533 Guido Trotter
    if not self._InstancePidAlive(name)[2]:
1571 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s" % name)
1572 76431533 Guido Trotter
1573 96f82929 Dimitris Aragiorgis
  # 52/50 local variables
1574 96f82929 Dimitris Aragiorgis
  # pylint: disable=R0914
1575 b73f1c59 Guido Trotter
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, kvmhelp, incoming=None):
1576 839642c2 Iustin Pop
    """Execute a KVM cmd, after completing it with some last minute data.
1577 ee5f20b0 Guido Trotter

1578 30e42c4e Guido Trotter
    @type incoming: tuple of strings
1579 30e42c4e Guido Trotter
    @param incoming: (target_host_ip, port)
1580 b73f1c59 Guido Trotter
    @type kvmhelp: string
1581 b73f1c59 Guido Trotter
    @param kvmhelp: output of kvm --help
1582 30e42c4e Guido Trotter

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

1790 ee5f20b0 Guido Trotter
    """
1791 5905901c Iustin Pop
    self._CheckDown(instance.name)
1792 4b9638dc Guido Trotter
    kvmpath = instance.hvparams[constants.HV_KVM_PATH]
1793 6e043e60 Guido Trotter
    kvmhelp = self._GetKVMOutput(kvmpath, self._KVMOPT_HELP)
1794 7238edb5 Iustin Pop
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices,
1795 b73f1c59 Guido Trotter
                                           startup_paused, kvmhelp)
1796 38e250ba Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1797 b73f1c59 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, kvmhelp)
1798 ee5f20b0 Guido Trotter
1799 6567aff3 Guido Trotter
  def _CallMonitorCommand(self, instance_name, command):
1800 6567aff3 Guido Trotter
    """Invoke a command on the instance monitor.
1801 6567aff3 Guido Trotter

1802 6567aff3 Guido Trotter
    """
1803 eace6157 Michael Hanselmann
    # TODO: Replace monitor calls with QMP once KVM >= 0.14 is the minimum
1804 eace6157 Michael Hanselmann
    # version. The monitor protocol is designed for human consumption, whereas
1805 eace6157 Michael Hanselmann
    # QMP is made for programmatic usage. In the worst case QMP can also
1806 eace6157 Michael Hanselmann
    # execute monitor commands. As it is, all calls to socat take at least
1807 eace6157 Michael Hanselmann
    # 500ms and likely more: socat can't detect the end of the reply and waits
1808 eace6157 Michael Hanselmann
    # for 500ms of no data received before exiting (500 ms is the default for
1809 eace6157 Michael Hanselmann
    # the "-t" parameter).
1810 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
1811 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
1812 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
1813 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
1814 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
1815 6567aff3 Guido Trotter
    if result.failed:
1816 afa9bb2e Michael Hanselmann
      msg = ("Failed to send command '%s' to instance '%s', reason '%s',"
1817 afa9bb2e Michael Hanselmann
             " output: %s" %
1818 afa9bb2e Michael Hanselmann
             (command, instance_name, result.fail_reason, result.output))
1819 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
1820 6567aff3 Guido Trotter
1821 6567aff3 Guido Trotter
    return result
1822 6567aff3 Guido Trotter
1823 b52d85c1 Guido Trotter
  @classmethod
1824 585c8187 Guido Trotter
  def _ParseKVMVersion(cls, text):
1825 585c8187 Guido Trotter
    """Parse the KVM version from the --help output.
1826 585c8187 Guido Trotter

1827 585c8187 Guido Trotter
    @type text: string
1828 585c8187 Guido Trotter
    @param text: output of kvm --help
1829 585c8187 Guido Trotter
    @return: (version, v_maj, v_min, v_rev)
1830 5c3d5dfd Iustin Pop
    @raise errors.HypervisorError: when the KVM version cannot be retrieved
1831 585c8187 Guido Trotter

1832 585c8187 Guido Trotter
    """
1833 585c8187 Guido Trotter
    match = cls._VERSION_RE.search(text.splitlines()[0])
1834 585c8187 Guido Trotter
    if not match:
1835 585c8187 Guido Trotter
      raise errors.HypervisorError("Unable to get KVM version")
1836 585c8187 Guido Trotter
1837 585c8187 Guido Trotter
    v_all = match.group(0)
1838 585c8187 Guido Trotter
    v_maj = int(match.group(1))
1839 585c8187 Guido Trotter
    v_min = int(match.group(2))
1840 585c8187 Guido Trotter
    if match.group(4):
1841 585c8187 Guido Trotter
      v_rev = int(match.group(4))
1842 585c8187 Guido Trotter
    else:
1843 585c8187 Guido Trotter
      v_rev = 0
1844 585c8187 Guido Trotter
    return (v_all, v_maj, v_min, v_rev)
1845 585c8187 Guido Trotter
1846 585c8187 Guido Trotter
  @classmethod
1847 6e043e60 Guido Trotter
  def _GetKVMOutput(cls, kvm_path, option):
1848 6e043e60 Guido Trotter
    """Return the output of a kvm invocation
1849 e3b89628 Guido Trotter

1850 bc0fed4b Guido Trotter
    @type kvm_path: string
1851 bc0fed4b Guido Trotter
    @param kvm_path: path to the kvm executable
1852 bc0fed4b Guido Trotter
    @type option: a key of _KVMOPTS_CMDS
1853 bc0fed4b Guido Trotter
    @param option: kvm option to fetch the output from
1854 6e043e60 Guido Trotter
    @return: output a supported kvm invocation
1855 e3b89628 Guido Trotter
    @raise errors.HypervisorError: when the KVM help output cannot be retrieved
1856 e3b89628 Guido Trotter

1857 e3b89628 Guido Trotter
    """
1858 6e043e60 Guido Trotter
    assert option in cls._KVMOPTS_CMDS, "Invalid output option"
1859 6e043e60 Guido Trotter
1860 bc0fed4b Guido Trotter
    optlist, can_fail = cls._KVMOPTS_CMDS[option]
1861 bc0fed4b Guido Trotter
1862 bc0fed4b Guido Trotter
    result = utils.RunCmd([kvm_path] + optlist)
1863 bc0fed4b Guido Trotter
    if result.failed and not can_fail:
1864 af89fa76 Helga Velroyen
      raise errors.HypervisorError("Unable to get KVM %s output" %
1865 af89fa76 Helga Velroyen
                                    " ".join(cls._KVMOPTS_CMDS[option]))
1866 e3b89628 Guido Trotter
    return result.output
1867 e3b89628 Guido Trotter
1868 e3b89628 Guido Trotter
  @classmethod
1869 3b59ec02 Guido Trotter
  def _GetKVMVersion(cls, kvm_path):
1870 d7e4a2b1 Andrea Spadaccini
    """Return the installed KVM version.
1871 b52d85c1 Guido Trotter

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

1875 b52d85c1 Guido Trotter
    """
1876 6e043e60 Guido Trotter
    return cls._ParseKVMVersion(cls._GetKVMOutput(kvm_path, cls._KVMOPT_HELP))
1877 82e3bf85 Dimitris Aragiorgis
1878 82e3bf85 Dimitris Aragiorgis
  @classmethod
1879 82e3bf85 Dimitris Aragiorgis
  def _GetDefaultMachineVersion(cls, kvm_path):
1880 82e3bf85 Dimitris Aragiorgis
    """Return the default hardware revision (e.g. pc-1.1)
1881 82e3bf85 Dimitris Aragiorgis

1882 82e3bf85 Dimitris Aragiorgis
    """
1883 6e043e60 Guido Trotter
    output = cls._GetKVMOutput(kvm_path, cls._KVMOPT_MLIST)
1884 82e3bf85 Dimitris Aragiorgis
    match = cls._DEFAULT_MACHINE_VERSION_RE.search(output)
1885 82e3bf85 Dimitris Aragiorgis
    if match:
1886 82e3bf85 Dimitris Aragiorgis
      return match.group(1)
1887 82e3bf85 Dimitris Aragiorgis
    else:
1888 82e3bf85 Dimitris Aragiorgis
      return "pc"
1889 82e3bf85 Dimitris Aragiorgis
1890 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
1891 eb58f9b1 Guido Trotter
    """Stop an instance.
1892 eb58f9b1 Guido Trotter

1893 eb58f9b1 Guido Trotter
    """
1894 bbcf7ad0 Iustin Pop
    if name is not None and not force:
1895 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
1896 bbcf7ad0 Iustin Pop
    if name is None:
1897 bbcf7ad0 Iustin Pop
      name = instance.name
1898 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
1899 bbcf7ad0 Iustin Pop
    else:
1900 bbcf7ad0 Iustin Pop
      acpi = False
1901 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
1902 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
1903 bbcf7ad0 Iustin Pop
      if force or not acpi:
1904 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
1905 eb58f9b1 Guido Trotter
      else:
1906 d0c8c01d Iustin Pop
        self._CallMonitorCommand(name, "system_powerdown")
1907 eb58f9b1 Guido Trotter
1908 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
1909 8904b35c Guido Trotter
    """Cleanup after a stopped instance
1910 8904b35c Guido Trotter

1911 8904b35c Guido Trotter
    """
1912 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
1913 8904b35c Guido Trotter
    if pid > 0 and alive:
1914 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
1915 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
1916 eb58f9b1 Guido Trotter
1917 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
1918 eb58f9b1 Guido Trotter
    """Reboot an instance.
1919 eb58f9b1 Guido Trotter

1920 eb58f9b1 Guido Trotter
    """
1921 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
1922 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
1923 eb58f9b1 Guido Trotter
    # to shutdown and restart.
1924 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
1925 1f8b3a27 Guido Trotter
    if not alive:
1926 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
1927 78411c60 Iustin Pop
                                   " not running" % instance.name)
1928 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
1929 f02881e0 Guido Trotter
    # ...first load it...
1930 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
1931 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
1932 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
1933 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
1934 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
1935 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1936 4b9638dc Guido Trotter
    kvmpath = instance.hvparams[constants.HV_KVM_PATH]
1937 6e043e60 Guido Trotter
    kvmhelp = self._GetKVMOutput(kvmpath, self._KVMOPT_HELP)
1938 b73f1c59 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, kvmhelp)
1939 eb58f9b1 Guido Trotter
1940 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
1941 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
1942 30e42c4e Guido Trotter

1943 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1944 30e42c4e Guido Trotter
    @param instance: instance to be migrated
1945 30e42c4e Guido Trotter
    @rtype: string
1946 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
1947 30e42c4e Guido Trotter

1948 30e42c4e Guido Trotter
    """
1949 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
1950 30e42c4e Guido Trotter
1951 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
1952 30e42c4e Guido Trotter
    """Prepare to accept an instance.
1953 30e42c4e Guido Trotter

1954 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1955 30e42c4e Guido Trotter
    @param instance: instance to be accepted
1956 30e42c4e Guido Trotter
    @type info: string
1957 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
1958 30e42c4e Guido Trotter
    @type target: string
1959 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
1960 30e42c4e Guido Trotter

1961 30e42c4e Guido Trotter
    """
1962 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1963 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
1964 4b9638dc Guido Trotter
    kvmpath = instance.hvparams[constants.HV_KVM_PATH]
1965 6e043e60 Guido Trotter
    kvmhelp = self._GetKVMOutput(kvmpath, self._KVMOPT_HELP)
1966 b73f1c59 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, kvmhelp,
1967 b73f1c59 Guido Trotter
                            incoming=incoming_address)
1968 30e42c4e Guido Trotter
1969 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
1970 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
1971 30e42c4e Guido Trotter

1972 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
1973 30e42c4e Guido Trotter

1974 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1975 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
1976 30e42c4e Guido Trotter

1977 30e42c4e Guido Trotter
    """
1978 30e42c4e Guido Trotter
    if success:
1979 5d9bfd87 Apollon Oikonomopoulos
      kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1980 5d9bfd87 Apollon Oikonomopoulos
      kvm_nics = kvm_runtime[1]
1981 5d9bfd87 Apollon Oikonomopoulos
1982 5d9bfd87 Apollon Oikonomopoulos
      for nic_seq, nic in enumerate(kvm_nics):
1983 cc8a8ed7 Apollon Oikonomopoulos
        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
1984 cc8a8ed7 Apollon Oikonomopoulos
          # Bridged interfaces have already been configured
1985 cc8a8ed7 Apollon Oikonomopoulos
          continue
1986 5d9bfd87 Apollon Oikonomopoulos
        try:
1987 5d9bfd87 Apollon Oikonomopoulos
          tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
1988 5d9bfd87 Apollon Oikonomopoulos
        except EnvironmentError, err:
1989 5d9bfd87 Apollon Oikonomopoulos
          logging.warning("Failed to find host interface for %s NIC #%d: %s",
1990 5d9bfd87 Apollon Oikonomopoulos
                          instance.name, nic_seq, str(err))
1991 5d9bfd87 Apollon Oikonomopoulos
          continue
1992 5d9bfd87 Apollon Oikonomopoulos
        try:
1993 5d9bfd87 Apollon Oikonomopoulos
          self._ConfigureNIC(instance, nic_seq, nic, tap)
1994 5d9bfd87 Apollon Oikonomopoulos
        except errors.HypervisorError, err:
1995 5d9bfd87 Apollon Oikonomopoulos
          logging.warning(str(err))
1996 5d9bfd87 Apollon Oikonomopoulos
1997 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
1998 30e42c4e Guido Trotter
    else:
1999 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
2000 30e42c4e Guido Trotter
2001 bc0a2284 Helga Velroyen
  def MigrateInstance(self, cluster_name, instance, target, live):
2002 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
2003 30e42c4e Guido Trotter

2004 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
2005 30e42c4e Guido Trotter
    currently running.
2006 30e42c4e Guido Trotter

2007 bc0a2284 Helga Velroyen
    @type cluster_name: string
2008 bc0a2284 Helga Velroyen
    @param cluster_name: name of the cluster
2009 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
2010 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
2011 30e42c4e Guido Trotter
    @type target: string
2012 30e42c4e Guido Trotter
    @param target: ip address of the target node
2013 30e42c4e Guido Trotter
    @type live: boolean
2014 30e42c4e Guido Trotter
    @param live: perform a live migration
2015 30e42c4e Guido Trotter

2016 30e42c4e Guido Trotter
    """
2017 58d38b02 Iustin Pop
    instance_name = instance.name
2018 50716be0 Iustin Pop
    port = instance.hvparams[constants.HV_MIGRATION_PORT]
2019 6a1434d7 Andrea Spadaccini
    _, _, alive = self._InstancePidAlive(instance_name)
2020 30e42c4e Guido Trotter
    if not alive:
2021 30e42c4e Guido Trotter
      raise errors.HypervisorError("Instance not running, cannot migrate")
2022 30e42c4e Guido Trotter
2023 30e42c4e Guido Trotter
    if not live:
2024 d0c8c01d Iustin Pop
      self._CallMonitorCommand(instance_name, "stop")
2025 30e42c4e Guido Trotter
2026 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_speed %dm" %
2027 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_BANDWIDTH])
2028 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
2029 e43d4f9f Apollon Oikonomopoulos
2030 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_downtime %dms" %
2031 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_DOWNTIME])
2032 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
2033 e43d4f9f Apollon Oikonomopoulos
2034 d0c8c01d Iustin Pop
    migrate_command = "migrate -d tcp:%s:%s" % (target, port)
2035 30e42c4e Guido Trotter
    self._CallMonitorCommand(instance_name, migrate_command)
2036 30e42c4e Guido Trotter
2037 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
2038 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
2039 6a1434d7 Andrea Spadaccini

2040 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
2041 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
2042 6a1434d7 Andrea Spadaccini
    @type success: bool
2043 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
2044 6a1434d7 Andrea Spadaccini
    @type live: bool
2045 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
2046 6a1434d7 Andrea Spadaccini

2047 6a1434d7 Andrea Spadaccini
    """
2048 6a1434d7 Andrea Spadaccini
    if success:
2049 6a1434d7 Andrea Spadaccini
      pidfile, pid, _ = self._InstancePidAlive(instance.name)
2050 6a1434d7 Andrea Spadaccini
      utils.KillProcess(pid)
2051 6a1434d7 Andrea Spadaccini
      self._RemoveInstanceRuntimeFiles(pidfile, instance.name)
2052 6a1434d7 Andrea Spadaccini
    elif live:
2053 6a1434d7 Andrea Spadaccini
      self._CallMonitorCommand(instance.name, self._CONT_CMD)
2054 6a1434d7 Andrea Spadaccini
2055 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
2056 6a1434d7 Andrea Spadaccini
    """Get the migration status
2057 6a1434d7 Andrea Spadaccini

2058 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
2059 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
2060 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
2061 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
2062 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
2063 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
2064 6a1434d7 Andrea Spadaccini

2065 6a1434d7 Andrea Spadaccini
    """
2066 d0c8c01d Iustin Pop
    info_command = "info migrate"
2067 6a1434d7 Andrea Spadaccini
    for _ in range(self._MIGRATION_INFO_MAX_BAD_ANSWERS):
2068 6a1434d7 Andrea Spadaccini
      result = self._CallMonitorCommand(instance.name, info_command)
2069 30e42c4e Guido Trotter
      match = self._MIGRATION_STATUS_RE.search(result.stdout)
2070 30e42c4e Guido Trotter
      if not match:
2071 c4e388a5 Guido Trotter
        if not result.stdout:
2072 c4e388a5 Guido Trotter
          logging.info("KVM: empty 'info migrate' result")
2073 c4e388a5 Guido Trotter
        else:
2074 e4dd2299 Guido Trotter
          logging.warning("KVM: unknown 'info migrate' result: %s",
2075 c4e388a5 Guido Trotter
                          result.stdout)
2076 30e42c4e Guido Trotter
      else:
2077 30e42c4e Guido Trotter
        status = match.group(1)
2078 6a1434d7 Andrea Spadaccini
        if status in constants.HV_KVM_MIGRATION_VALID_STATUSES:
2079 6a1434d7 Andrea Spadaccini
          migration_status = objects.MigrationStatus(status=status)
2080 61643226 Andrea Spadaccini
          match = self._MIGRATION_PROGRESS_RE.search(result.stdout)
2081 61643226 Andrea Spadaccini
          if match:
2082 61643226 Andrea Spadaccini
            migration_status.transferred_ram = match.group("transferred")
2083 61643226 Andrea Spadaccini
            migration_status.total_ram = match.group("total")
2084 61643226 Andrea Spadaccini
2085 6a1434d7 Andrea Spadaccini
          return migration_status
2086 30e42c4e Guido Trotter
2087 6a1434d7 Andrea Spadaccini
        logging.warning("KVM: unknown migration status '%s'", status)
2088 6a1434d7 Andrea Spadaccini
2089 6a1434d7 Andrea Spadaccini
      time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
2090 6a1434d7 Andrea Spadaccini
2091 62457f51 Iustin Pop
    return objects.MigrationStatus(status=constants.HV_MIGRATION_FAILED)
2092 30e42c4e Guido Trotter
2093 3d836750 Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
2094 3d836750 Guido Trotter
    """Balloon an instance memory to a certain value.
2095 3d836750 Guido Trotter

2096 3d836750 Guido Trotter
    @type instance: L{objects.Instance}
2097 3d836750 Guido Trotter
    @param instance: instance to be accepted
2098 3d836750 Guido Trotter
    @type mem: int
2099 3d836750 Guido Trotter
    @param mem: actual memory size to use for instance runtime
2100 3d836750 Guido Trotter

2101 3d836750 Guido Trotter
    """
2102 3d836750 Guido Trotter
    self._CallMonitorCommand(instance.name, "balloon %d" % mem)
2103 3d836750 Guido Trotter
2104 fac489a5 Helga Velroyen
  def GetNodeInfo(self, hvparams=None):
2105 eb58f9b1 Guido Trotter
    """Return information about the node.
2106 eb58f9b1 Guido Trotter

2107 fac489a5 Helga Velroyen
    @type hvparams: dict of strings
2108 fac489a5 Helga Velroyen
    @param hvparams: hypervisor parameters, not used in this class
2109 fac489a5 Helga Velroyen

2110 ef14e128 Bernardo Dal Seno
    @return: a dict as returned by L{BaseHypervisor.GetLinuxNodeInfo} plus
2111 ef14e128 Bernardo Dal Seno
        the following keys:
2112 34fbc862 Andrea Spadaccini
          - hv_version: the hypervisor version in the form (major, minor,
2113 34fbc862 Andrea Spadaccini
                        revision)
2114 eb58f9b1 Guido Trotter

2115 eb58f9b1 Guido Trotter
    """
2116 34fbc862 Andrea Spadaccini
    result = self.GetLinuxNodeInfo()
2117 4b9638dc Guido Trotter
    # FIXME: this is the global kvm version, but the actual version can be
2118 4b9638dc Guido Trotter
    # customized as an hv parameter. we should use the nodegroup's default kvm
2119 4b9638dc Guido Trotter
    # path parameter here.
2120 3b59ec02 Guido Trotter
    _, v_major, v_min, v_rev = self._GetKVMVersion(constants.KVM_PATH)
2121 34fbc862 Andrea Spadaccini
    result[constants.HV_NODEINFO_KEY_VERSION] = (v_major, v_min, v_rev)
2122 34fbc862 Andrea Spadaccini
    return result
2123 eb58f9b1 Guido Trotter
2124 637ce7f9 Guido Trotter
  @classmethod
2125 1c3231aa Thomas Thrainer
  def GetInstanceConsole(cls, instance, primary_node, hvparams, beparams):
2126 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
2127 eb58f9b1 Guido Trotter

2128 eb58f9b1 Guido Trotter
    """
2129 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
2130 9d9bded1 Michael Hanselmann
      cmd = [pathutils.KVM_CONSOLE_WRAPPER,
2131 2f4c951e Stephen Shirley
             constants.SOCAT_PATH, utils.ShellQuote(instance.name),
2132 2f4c951e Stephen Shirley
             utils.ShellQuote(cls._InstanceMonitor(instance.name)),
2133 55cc0a44 Michael Hanselmann
             "STDIO,%s" % cls._SocatUnixConsoleParams(),
2134 55cc0a44 Michael Hanselmann
             "UNIX-CONNECT:%s" % cls._InstanceSerial(instance.name)]
2135 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
2136 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_SSH,
2137 1c3231aa Thomas Thrainer
                                     host=primary_node.name,
2138 052783ff Michael Hanselmann
                                     user=constants.SSH_CONSOLE_USER,
2139 55cc0a44 Michael Hanselmann
                                     command=cmd)
2140 3be34f57 Guido Trotter
2141 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
2142 55cc0a44 Michael Hanselmann
    if vnc_bind_address and instance.network_port > constants.VNC_BASE_PORT:
2143 55cc0a44 Michael Hanselmann
      display = instance.network_port - constants.VNC_BASE_PORT
2144 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
2145 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_VNC,
2146 55cc0a44 Michael Hanselmann
                                     host=vnc_bind_address,
2147 55cc0a44 Michael Hanselmann
                                     port=instance.network_port,
2148 55cc0a44 Michael Hanselmann
                                     display=display)
2149 55cc0a44 Michael Hanselmann
2150 4d2cdb5a Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2151 4d2cdb5a Andrea Spadaccini
    if spice_bind:
2152 4d2cdb5a Andrea Spadaccini
      return objects.InstanceConsole(instance=instance.name,
2153 4d2cdb5a Andrea Spadaccini
                                     kind=constants.CONS_SPICE,
2154 4d2cdb5a Andrea Spadaccini
                                     host=spice_bind,
2155 4d2cdb5a Andrea Spadaccini
                                     port=instance.network_port)
2156 4d2cdb5a Andrea Spadaccini
2157 55cc0a44 Michael Hanselmann
    return objects.InstanceConsole(instance=instance.name,
2158 55cc0a44 Michael Hanselmann
                                   kind=constants.CONS_MESSAGE,
2159 55cc0a44 Michael Hanselmann
                                   message=("No serial shell for instance %s" %
2160 55cc0a44 Michael Hanselmann
                                            instance.name))
2161 eb58f9b1 Guido Trotter
2162 75bf3149 Helga Velroyen
  def Verify(self, hvparams=None):
2163 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
2164 eb58f9b1 Guido Trotter

2165 cd04dfd2 Michael Hanselmann
    Check that the required binaries exist.
2166 cd04dfd2 Michael Hanselmann

2167 75bf3149 Helga Velroyen
    @type hvparams: dict of strings
2168 75bf3149 Helga Velroyen
    @param hvparams: hypervisor parameters to be verified against, not used here
2169 75bf3149 Helga Velroyen

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

2172 eb58f9b1 Guido Trotter
    """
2173 1f4b9d39 Iustin Pop
    msgs = []
2174 1f4b9d39 Iustin Pop
    # FIXME: this is the global kvm binary, but the actual path can be
2175 1f4b9d39 Iustin Pop
    # customized as an hv parameter; we should use the nodegroup's
2176 1f4b9d39 Iustin Pop
    # default kvm path parameter here.
2177 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
2178 1f4b9d39 Iustin Pop
      msgs.append("The KVM binary ('%s') does not exist" % constants.KVM_PATH)
2179 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
2180 1f4b9d39 Iustin Pop
      msgs.append("The socat binary ('%s') does not exist" %
2181 1f4b9d39 Iustin Pop
                  constants.SOCAT_PATH)
2182 1f4b9d39 Iustin Pop
2183 1f4b9d39 Iustin Pop
    return self._FormatVerifyResults(msgs)
2184 14aa53cb Guido Trotter
2185 6b5605e8 Iustin Pop
  @classmethod
2186 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
2187 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
2188 6b5605e8 Iustin Pop

2189 6b5605e8 Iustin Pop
    @type hvparams:  dict
2190 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
2191 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
2192 6b5605e8 Iustin Pop

2193 6b5605e8 Iustin Pop
    """
2194 47387b1e Guido Trotter
    super(KVMHypervisor, cls).CheckParameterSyntax(hvparams)
2195 6b5605e8 Iustin Pop
2196 df5ab9f0 Guido Trotter
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
2197 df5ab9f0 Guido Trotter
    if kernel_path:
2198 df5ab9f0 Guido Trotter
      if not hvparams[constants.HV_ROOT_PATH]:
2199 205ab586 Iustin Pop
        raise errors.HypervisorError("Need a root partition for the instance,"
2200 205ab586 Iustin Pop
                                     " if a kernel is defined")
2201 6b5605e8 Iustin Pop
2202 205ab586 Iustin Pop
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
2203 205ab586 Iustin Pop
        not hvparams[constants.HV_VNC_X509]):
2204 205ab586 Iustin Pop
      raise errors.HypervisorError("%s must be defined, if %s is" %
2205 205ab586 Iustin Pop
                                   (constants.HV_VNC_X509,
2206 205ab586 Iustin Pop
                                    constants.HV_VNC_X509_VERIFY))
2207 66d5dbef Guido Trotter
2208 14fd6c81 Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
2209 14fd6c81 Guido Trotter
      serial_speed = hvparams[constants.HV_SERIAL_SPEED]
2210 14fd6c81 Guido Trotter
      valid_speeds = constants.VALID_SERIAL_SPEEDS
2211 14fd6c81 Guido Trotter
      if not serial_speed or serial_speed not in valid_speeds:
2212 14fd6c81 Guido Trotter
        raise errors.HypervisorError("Invalid serial console speed, must be"
2213 14fd6c81 Guido Trotter
                                     " one of: %s" %
2214 14fd6c81 Guido Trotter
                                     utils.CommaJoin(valid_speeds))
2215 14fd6c81 Guido Trotter
2216 66d5dbef Guido Trotter
    boot_order = hvparams[constants.HV_BOOT_ORDER]
2217 205ab586 Iustin Pop
    if (boot_order == constants.HT_BO_CDROM and
2218 205ab586 Iustin Pop
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
2219 835528af Iustin Pop
      raise errors.HypervisorError("Cannot boot from cdrom without an"
2220 835528af Iustin Pop
                                   " ISO path")
2221 f5118ade Iustin Pop
2222 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
2223 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
2224 d19d94db Guido Trotter
      if not hvparams[constants.HV_SECURITY_DOMAIN]:
2225 d19d94db Guido Trotter
        raise errors.HypervisorError("A security domain (user to run kvm as)"
2226 d19d94db Guido Trotter
                                     " must be specified")
2227 d19d94db Guido Trotter
    elif (security_model == constants.HT_SM_NONE or
2228 d19d94db Guido Trotter
          security_model == constants.HT_SM_POOL):
2229 d19d94db Guido Trotter
      if hvparams[constants.HV_SECURITY_DOMAIN]:
2230 d19d94db Guido Trotter
        raise errors.HypervisorError("Cannot have a security domain when the"
2231 d19d94db Guido Trotter
                                     " security model is 'none' or 'pool'")
2232 d19d94db Guido Trotter
2233 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2234 b451c4c7 Andrea Spadaccini
    spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
2235 b1cb62bd Andrea Spadaccini
    if spice_bind:
2236 b1cb62bd Andrea Spadaccini
      if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
2237 b1cb62bd Andrea Spadaccini
        # if an IP version is specified, the spice_bind parameter must be an
2238 b1cb62bd Andrea Spadaccini
        # IP of that family
2239 b1cb62bd Andrea Spadaccini
        if (netutils.IP4Address.IsValid(spice_bind) and
2240 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP4_VERSION):
2241 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: Got an IPv4 address (%s), but"
2242 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
2243 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
2244 b1cb62bd Andrea Spadaccini
2245 b1cb62bd Andrea Spadaccini
        if (netutils.IP6Address.IsValid(spice_bind) and
2246 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP6_VERSION):
2247 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: Got an IPv6 address (%s), but"
2248 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
2249 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
2250 b451c4c7 Andrea Spadaccini
    else:
2251 0e1b03b9 Andrea Spadaccini
      # All the other SPICE parameters depend on spice_bind being set. Raise an
2252 0e1b03b9 Andrea Spadaccini
      # error if any of them is set without it.
2253 07788a0b Michael Hanselmann
      for param in _SPICE_ADDITIONAL_PARAMS:
2254 0e1b03b9 Andrea Spadaccini
        if hvparams[param]:
2255 afa9bb2e Michael Hanselmann
          raise errors.HypervisorError("SPICE: %s requires %s to be set" %
2256 0e1b03b9 Andrea Spadaccini
                                       (param, constants.HV_KVM_SPICE_BIND))
2257 b1cb62bd Andrea Spadaccini
2258 d19d94db Guido Trotter
  @classmethod
2259 d19d94db Guido Trotter
  def ValidateParameters(cls, hvparams):
2260 d19d94db Guido Trotter
    """Check the given parameters for validity.
2261 d19d94db Guido Trotter

2262 d19d94db Guido Trotter
    @type hvparams:  dict
2263 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
2264 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
2265 d19d94db Guido Trotter

2266 d19d94db Guido Trotter
    """
2267 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
2268 d19d94db Guido Trotter
2269 82e3bf85 Dimitris Aragiorgis
    kvm_path = hvparams[constants.HV_KVM_PATH]
2270 82e3bf85 Dimitris Aragiorgis
2271 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
2272 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
2273 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
2274 d19d94db Guido Trotter
      try:
2275 1feb39ec Guido Trotter
        pwd.getpwnam(username)
2276 d19d94db Guido Trotter
      except KeyError:
2277 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
2278 d19d94db Guido Trotter
                                     % username)
2279 d6e5767e Klaus Aehlig
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
2280 d6e5767e Klaus Aehlig
    if vnc_bind_address:
2281 d6e5767e Klaus Aehlig
      bound_to_addr = netutils.IP4Address.IsValid(vnc_bind_address)
2282 d6e5767e Klaus Aehlig
      is_interface = netutils.IsValidInterface(vnc_bind_address)
2283 d6e5767e Klaus Aehlig
      is_path = utils.IsNormAbsPath(vnc_bind_address)
2284 d6e5767e Klaus Aehlig
      if not bound_to_addr and not is_interface and not is_path:
2285 d6e5767e Klaus Aehlig
        raise errors.HypervisorError("VNC: The %s parameter must be either"
2286 d6e5767e Klaus Aehlig
                                     " a valid IP address, an interface name,"
2287 d6e5767e Klaus Aehlig
                                     " or an absolute path" %
2288 d6e5767e Klaus Aehlig
                                     constants.HV_KVM_SPICE_BIND)
2289 d19d94db Guido Trotter
2290 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2291 b1cb62bd Andrea Spadaccini
    if spice_bind:
2292 b1cb62bd Andrea Spadaccini
      # only one of VNC and SPICE can be used currently.
2293 b1cb62bd Andrea Spadaccini
      if hvparams[constants.HV_VNC_BIND_ADDRESS]:
2294 afa9bb2e Michael Hanselmann
        raise errors.HypervisorError("Both SPICE and VNC are configured, but"
2295 b1cb62bd Andrea Spadaccini
                                     " only one of them can be used at a"
2296 afa9bb2e Michael Hanselmann
                                     " given time")
2297 b1cb62bd Andrea Spadaccini
2298 3b59ec02 Guido Trotter
      # check that KVM supports SPICE
2299 6e043e60 Guido Trotter
      kvmhelp = cls._GetKVMOutput(kvm_path, cls._KVMOPT_HELP)
2300 0ad7f5d8 Guido Trotter
      if not cls._SPICE_RE.search(kvmhelp):
2301 afa9bb2e Michael Hanselmann
        raise errors.HypervisorError("SPICE is configured, but it is not"
2302 afa9bb2e Michael Hanselmann
                                     " supported according to 'kvm --help'")
2303 b1cb62bd Andrea Spadaccini
2304 b1cb62bd Andrea Spadaccini
      # if spice_bind is not an IP address, it must be a valid interface
2305 afa9bb2e Michael Hanselmann
      bound_to_addr = (netutils.IP4Address.IsValid(spice_bind) or
2306 afa9bb2e Michael Hanselmann
                       netutils.IP6Address.IsValid(spice_bind))
2307 b1cb62bd Andrea Spadaccini
      if not bound_to_addr and not netutils.IsValidInterface(spice_bind):
2308 afa9bb2e Michael Hanselmann
        raise errors.HypervisorError("SPICE: The %s parameter must be either"
2309 b1cb62bd Andrea Spadaccini
                                     " a valid IP address or interface name" %
2310 b1cb62bd Andrea Spadaccini
                                     constants.HV_KVM_SPICE_BIND)
2311 b1cb62bd Andrea Spadaccini
2312 82e3bf85 Dimitris Aragiorgis
    machine_version = hvparams[constants.HV_KVM_MACHINE_VERSION]
2313 82e3bf85 Dimitris Aragiorgis
    if machine_version:
2314 6e043e60 Guido Trotter
      output = cls._GetKVMOutput(kvm_path, cls._KVMOPT_MLIST)
2315 82e3bf85 Dimitris Aragiorgis
      if not cls._CHECK_MACHINE_VERSION_RE(machine_version).search(output):
2316 82e3bf85 Dimitris Aragiorgis
        raise errors.HypervisorError("Unsupported machine version: %s" %
2317 82e3bf85 Dimitris Aragiorgis
                                     machine_version)
2318 82e3bf85 Dimitris Aragiorgis
2319 f5118ade Iustin Pop
  @classmethod
2320 8ef418bb Helga Velroyen
  def PowercycleNode(cls, hvparams=None):
2321 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
2322 f5118ade Iustin Pop

2323 8ef418bb Helga Velroyen
    @type hvparams: dict of strings
2324 8ef418bb Helga Velroyen
    @param hvparams: hypervisor params to be used on this node
2325 8ef418bb Helga Velroyen

2326 f5118ade Iustin Pop
    """
2327 f5118ade Iustin Pop
    cls.LinuxPowercycle()