Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ dbb4f850

History | View | Annotate | Download (72.8 kB)

1 eb58f9b1 Guido Trotter
#
2 eb58f9b1 Guido Trotter
#
3 eb58f9b1 Guido Trotter
4 2911f46c Iustin Pop
# Copyright (C) 2008, 2009, 2010, 2011, 2012 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 199b2053 Apollon Oikonomopoulos
83 199b2053 Apollon Oikonomopoulos
def _ProbeTapVnetHdr(fd):
84 199b2053 Apollon Oikonomopoulos
  """Check whether to enable the IFF_VNET_HDR flag.
85 199b2053 Apollon Oikonomopoulos

86 199b2053 Apollon Oikonomopoulos
  To do this, _all_ of the following conditions must be met:
87 199b2053 Apollon Oikonomopoulos
   1. TUNGETFEATURES ioctl() *must* be implemented
88 199b2053 Apollon Oikonomopoulos
   2. TUNGETFEATURES ioctl() result *must* contain the IFF_VNET_HDR flag
89 199b2053 Apollon Oikonomopoulos
   3. TUNGETIFF ioctl() *must* be implemented; reading the kernel code in
90 199b2053 Apollon Oikonomopoulos
      drivers/net/tun.c there is no way to test this until after the tap device
91 199b2053 Apollon Oikonomopoulos
      has been created using TUNSETIFF, and there is no way to change the
92 199b2053 Apollon Oikonomopoulos
      IFF_VNET_HDR flag after creating the interface, catch-22! However both
93 199b2053 Apollon Oikonomopoulos
      TUNGETIFF and TUNGETFEATURES were introduced in kernel version 2.6.27,
94 199b2053 Apollon Oikonomopoulos
      thus we can expect TUNGETIFF to be present if TUNGETFEATURES is.
95 199b2053 Apollon Oikonomopoulos

96 199b2053 Apollon Oikonomopoulos
   @type fd: int
97 199b2053 Apollon Oikonomopoulos
   @param fd: the file descriptor of /dev/net/tun
98 199b2053 Apollon Oikonomopoulos

99 199b2053 Apollon Oikonomopoulos
  """
100 199b2053 Apollon Oikonomopoulos
  req = struct.pack("I", 0)
101 199b2053 Apollon Oikonomopoulos
  try:
102 199b2053 Apollon Oikonomopoulos
    res = fcntl.ioctl(fd, TUNGETFEATURES, req)
103 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
104 199b2053 Apollon Oikonomopoulos
    logging.warning("TUNGETFEATURES ioctl() not implemented")
105 199b2053 Apollon Oikonomopoulos
    return False
106 199b2053 Apollon Oikonomopoulos
107 199b2053 Apollon Oikonomopoulos
  tunflags = struct.unpack("I", res)[0]
108 199b2053 Apollon Oikonomopoulos
  if tunflags & IFF_VNET_HDR:
109 199b2053 Apollon Oikonomopoulos
    return True
110 199b2053 Apollon Oikonomopoulos
  else:
111 199b2053 Apollon Oikonomopoulos
    logging.warning("Host does not support IFF_VNET_HDR, not enabling")
112 199b2053 Apollon Oikonomopoulos
    return False
113 199b2053 Apollon Oikonomopoulos
114 199b2053 Apollon Oikonomopoulos
115 199b2053 Apollon Oikonomopoulos
def _OpenTap(vnet_hdr=True):
116 199b2053 Apollon Oikonomopoulos
  """Open a new tap device and return its file descriptor.
117 199b2053 Apollon Oikonomopoulos

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

121 199b2053 Apollon Oikonomopoulos
  @type vnet_hdr: boolean
122 199b2053 Apollon Oikonomopoulos
  @param vnet_hdr: Enable the VNET Header
123 199b2053 Apollon Oikonomopoulos
  @return: (ifname, tapfd)
124 199b2053 Apollon Oikonomopoulos
  @rtype: tuple
125 199b2053 Apollon Oikonomopoulos

126 199b2053 Apollon Oikonomopoulos
  """
127 199b2053 Apollon Oikonomopoulos
  try:
128 199b2053 Apollon Oikonomopoulos
    tapfd = os.open("/dev/net/tun", os.O_RDWR)
129 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
130 199b2053 Apollon Oikonomopoulos
    raise errors.HypervisorError("Failed to open /dev/net/tun")
131 199b2053 Apollon Oikonomopoulos
132 199b2053 Apollon Oikonomopoulos
  flags = IFF_TAP | IFF_NO_PI
133 199b2053 Apollon Oikonomopoulos
134 199b2053 Apollon Oikonomopoulos
  if vnet_hdr and _ProbeTapVnetHdr(tapfd):
135 199b2053 Apollon Oikonomopoulos
    flags |= IFF_VNET_HDR
136 199b2053 Apollon Oikonomopoulos
137 199b2053 Apollon Oikonomopoulos
  # The struct ifreq ioctl request (see netdevice(7))
138 199b2053 Apollon Oikonomopoulos
  ifr = struct.pack("16sh", "", flags)
139 199b2053 Apollon Oikonomopoulos
140 199b2053 Apollon Oikonomopoulos
  try:
141 199b2053 Apollon Oikonomopoulos
    res = fcntl.ioctl(tapfd, TUNSETIFF, ifr)
142 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
143 199b2053 Apollon Oikonomopoulos
    raise errors.HypervisorError("Failed to allocate a new TAP device")
144 199b2053 Apollon Oikonomopoulos
145 199b2053 Apollon Oikonomopoulos
  # Get the interface name from the ioctl
146 199b2053 Apollon Oikonomopoulos
  ifname = struct.unpack("16sh", res)[0].strip("\x00")
147 199b2053 Apollon Oikonomopoulos
  return (ifname, tapfd)
148 199b2053 Apollon Oikonomopoulos
149 748e4b5a Michael Hanselmann
150 8df21834 Dimitris Aragiorgis
def _BuildNetworkEnv(name, network, gateway, network6, gateway6,
151 8df21834 Dimitris Aragiorgis
                     network_type, mac_prefix, tags, env):
152 8df21834 Dimitris Aragiorgis
  """Build environment variables concerning a Network.
153 8df21834 Dimitris Aragiorgis

154 8df21834 Dimitris Aragiorgis
  """
155 8df21834 Dimitris Aragiorgis
  if name:
156 8df21834 Dimitris Aragiorgis
    env["NETWORK_NAME"] = name
157 8df21834 Dimitris Aragiorgis
  if network:
158 8df21834 Dimitris Aragiorgis
    env["NETWORK_SUBNET"] = network
159 8df21834 Dimitris Aragiorgis
  if gateway:
160 8df21834 Dimitris Aragiorgis
    env["NETWORK_GATEWAY"] = gateway
161 8df21834 Dimitris Aragiorgis
  if network6:
162 8df21834 Dimitris Aragiorgis
    env["NETWORK_SUBNET6"] = network6
163 8df21834 Dimitris Aragiorgis
  if gateway6:
164 8df21834 Dimitris Aragiorgis
    env["NETWORK_GATEWAY6"] = gateway6
165 8df21834 Dimitris Aragiorgis
  if mac_prefix:
166 8df21834 Dimitris Aragiorgis
    env["NETWORK_MAC_PREFIX"] = mac_prefix
167 8df21834 Dimitris Aragiorgis
  if network_type:
168 8df21834 Dimitris Aragiorgis
    env["NETWORK_TYPE"] = network_type
169 8df21834 Dimitris Aragiorgis
  if tags:
170 8df21834 Dimitris Aragiorgis
    env["NETWORK_TAGS"] = " ".join(tags)
171 8df21834 Dimitris Aragiorgis
172 8df21834 Dimitris Aragiorgis
  return env
173 8df21834 Dimitris Aragiorgis
174 8df21834 Dimitris Aragiorgis
175 91c10532 Andrea Spadaccini
class QmpMessage:
176 91c10532 Andrea Spadaccini
  """QEMU Messaging Protocol (QMP) message.
177 91c10532 Andrea Spadaccini

178 91c10532 Andrea Spadaccini
  """
179 91c10532 Andrea Spadaccini
  def __init__(self, data):
180 91c10532 Andrea Spadaccini
    """Creates a new QMP message based on the passed data.
181 91c10532 Andrea Spadaccini

182 91c10532 Andrea Spadaccini
    """
183 91c10532 Andrea Spadaccini
    if not isinstance(data, dict):
184 91c10532 Andrea Spadaccini
      raise TypeError("QmpMessage must be initialized with a dict")
185 91c10532 Andrea Spadaccini
186 91c10532 Andrea Spadaccini
    self.data = data
187 91c10532 Andrea Spadaccini
188 91c10532 Andrea Spadaccini
  def __getitem__(self, field_name):
189 91c10532 Andrea Spadaccini
    """Get the value of the required field if present, or None.
190 91c10532 Andrea Spadaccini

191 91c10532 Andrea Spadaccini
    Overrides the [] operator to provide access to the message data,
192 91c10532 Andrea Spadaccini
    returning None if the required item is not in the message
193 91c10532 Andrea Spadaccini
    @return: the value of the field_name field, or None if field_name
194 91c10532 Andrea Spadaccini
             is not contained in the message
195 91c10532 Andrea Spadaccini

196 91c10532 Andrea Spadaccini
    """
197 9b87c2cf Michael Hanselmann
    return self.data.get(field_name, None)
198 91c10532 Andrea Spadaccini
199 91c10532 Andrea Spadaccini
  def __setitem__(self, field_name, field_value):
200 91c10532 Andrea Spadaccini
    """Set the value of the required field_name to field_value.
201 91c10532 Andrea Spadaccini

202 91c10532 Andrea Spadaccini
    """
203 91c10532 Andrea Spadaccini
    self.data[field_name] = field_value
204 91c10532 Andrea Spadaccini
205 91c10532 Andrea Spadaccini
  @staticmethod
206 91c10532 Andrea Spadaccini
  def BuildFromJsonString(json_string):
207 91c10532 Andrea Spadaccini
    """Build a QmpMessage from a JSON encoded string.
208 91c10532 Andrea Spadaccini

209 91c10532 Andrea Spadaccini
    @type json_string: str
210 91c10532 Andrea Spadaccini
    @param json_string: JSON string representing the message
211 91c10532 Andrea Spadaccini
    @rtype: L{QmpMessage}
212 91c10532 Andrea Spadaccini
    @return: a L{QmpMessage} built from json_string
213 91c10532 Andrea Spadaccini

214 91c10532 Andrea Spadaccini
    """
215 91c10532 Andrea Spadaccini
    # Parse the string
216 91c10532 Andrea Spadaccini
    data = serializer.LoadJson(json_string)
217 91c10532 Andrea Spadaccini
    return QmpMessage(data)
218 91c10532 Andrea Spadaccini
219 91c10532 Andrea Spadaccini
  def __str__(self):
220 a182a3ed Michael Hanselmann
    # The protocol expects the JSON object to be sent as a single line.
221 a182a3ed Michael Hanselmann
    return serializer.DumpJson(self.data)
222 91c10532 Andrea Spadaccini
223 91c10532 Andrea Spadaccini
  def __eq__(self, other):
224 91c10532 Andrea Spadaccini
    # When comparing two QmpMessages, we are interested in comparing
225 91c10532 Andrea Spadaccini
    # their internal representation of the message data
226 91c10532 Andrea Spadaccini
    return self.data == other.data
227 91c10532 Andrea Spadaccini
228 91c10532 Andrea Spadaccini
229 91c10532 Andrea Spadaccini
class QmpConnection:
230 91c10532 Andrea Spadaccini
  """Connection to the QEMU Monitor using the QEMU Monitor Protocol (QMP).
231 91c10532 Andrea Spadaccini

232 91c10532 Andrea Spadaccini
  """
233 91c10532 Andrea Spadaccini
  _FIRST_MESSAGE_KEY = "QMP"
234 91c10532 Andrea Spadaccini
  _EVENT_KEY = "event"
235 91c10532 Andrea Spadaccini
  _ERROR_KEY = "error"
236 89da2ff3 Guido Trotter
  _RETURN_KEY = RETURN_KEY = "return"
237 89da2ff3 Guido Trotter
  _ACTUAL_KEY = ACTUAL_KEY = "actual"
238 91c10532 Andrea Spadaccini
  _ERROR_CLASS_KEY = "class"
239 91c10532 Andrea Spadaccini
  _ERROR_DATA_KEY = "data"
240 91c10532 Andrea Spadaccini
  _ERROR_DESC_KEY = "desc"
241 91c10532 Andrea Spadaccini
  _EXECUTE_KEY = "execute"
242 91c10532 Andrea Spadaccini
  _ARGUMENTS_KEY = "arguments"
243 91c10532 Andrea Spadaccini
  _CAPABILITIES_COMMAND = "qmp_capabilities"
244 91c10532 Andrea Spadaccini
  _MESSAGE_END_TOKEN = "\r\n"
245 91c10532 Andrea Spadaccini
  _SOCKET_TIMEOUT = 5
246 91c10532 Andrea Spadaccini
247 91c10532 Andrea Spadaccini
  def __init__(self, monitor_filename):
248 91c10532 Andrea Spadaccini
    """Instantiates the QmpConnection object.
249 91c10532 Andrea Spadaccini

250 91c10532 Andrea Spadaccini
    @type monitor_filename: string
251 91c10532 Andrea Spadaccini
    @param monitor_filename: the filename of the UNIX raw socket on which the
252 91c10532 Andrea Spadaccini
                             QMP monitor is listening
253 91c10532 Andrea Spadaccini

254 91c10532 Andrea Spadaccini
    """
255 91c10532 Andrea Spadaccini
    self.monitor_filename = monitor_filename
256 91c10532 Andrea Spadaccini
    self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
257 91c10532 Andrea Spadaccini
    # We want to fail if the server doesn't send a complete message
258 91c10532 Andrea Spadaccini
    # in a reasonable amount of time
259 91c10532 Andrea Spadaccini
    self.sock.settimeout(self._SOCKET_TIMEOUT)
260 91c10532 Andrea Spadaccini
    self._connected = False
261 91c10532 Andrea Spadaccini
    self._buf = ""
262 91c10532 Andrea Spadaccini
263 fc84cd5d Guido Trotter
  def _check_socket(self):
264 fc84cd5d Guido Trotter
    sock_stat = None
265 fc84cd5d Guido Trotter
    try:
266 fc84cd5d Guido Trotter
      sock_stat = os.stat(self.monitor_filename)
267 fc84cd5d Guido Trotter
    except EnvironmentError, err:
268 fc84cd5d Guido Trotter
      if err.errno == errno.ENOENT:
269 fc84cd5d Guido Trotter
        raise errors.HypervisorError("No qmp socket found")
270 fc84cd5d Guido Trotter
      else:
271 fc84cd5d Guido Trotter
        raise errors.HypervisorError("Error checking qmp socket: %s",
272 fc84cd5d Guido Trotter
                                     utils.ErrnoOrStr(err))
273 fc84cd5d Guido Trotter
    if not stat.S_ISSOCK(sock_stat.st_mode):
274 fc84cd5d Guido Trotter
      raise errors.HypervisorError("Qmp socket is not a socket")
275 fc84cd5d Guido Trotter
276 91c10532 Andrea Spadaccini
  def _check_connection(self):
277 91c10532 Andrea Spadaccini
    """Make sure that the connection is established.
278 91c10532 Andrea Spadaccini

279 91c10532 Andrea Spadaccini
    """
280 91c10532 Andrea Spadaccini
    if not self._connected:
281 91c10532 Andrea Spadaccini
      raise errors.ProgrammerError("To use a QmpConnection you need to first"
282 91c10532 Andrea Spadaccini
                                   " invoke connect() on it")
283 91c10532 Andrea Spadaccini
284 91c10532 Andrea Spadaccini
  def connect(self):
285 91c10532 Andrea Spadaccini
    """Connects to the QMP monitor.
286 91c10532 Andrea Spadaccini

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

290 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
291 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
292 91c10532 Andrea Spadaccini

293 91c10532 Andrea Spadaccini
    """
294 fc84cd5d Guido Trotter
    if self._connected:
295 fc84cd5d Guido Trotter
      raise errors.ProgrammerError("Cannot connect twice")
296 fc84cd5d Guido Trotter
297 fc84cd5d Guido Trotter
    self._check_socket()
298 fc84cd5d Guido Trotter
299 fc84cd5d Guido Trotter
    # Check file existance/stuff
300 fc84cd5d Guido Trotter
    try:
301 fc84cd5d Guido Trotter
      self.sock.connect(self.monitor_filename)
302 fc84cd5d Guido Trotter
    except EnvironmentError:
303 fc84cd5d Guido Trotter
      raise errors.HypervisorError("Can't connect to qmp socket")
304 91c10532 Andrea Spadaccini
    self._connected = True
305 91c10532 Andrea Spadaccini
306 91c10532 Andrea Spadaccini
    # Check if we receive a correct greeting message from the server
307 91c10532 Andrea Spadaccini
    # (As per the QEMU Protocol Specification 0.1 - section 2.2)
308 91c10532 Andrea Spadaccini
    greeting = self._Recv()
309 91c10532 Andrea Spadaccini
    if not greeting[self._FIRST_MESSAGE_KEY]:
310 91c10532 Andrea Spadaccini
      self._connected = False
311 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("kvm: qmp communication error (wrong"
312 91c10532 Andrea Spadaccini
                                   " server greeting")
313 91c10532 Andrea Spadaccini
314 91c10532 Andrea Spadaccini
    # Let's put the monitor in command mode using the qmp_capabilities
315 91c10532 Andrea Spadaccini
    # command, or else no command will be executable.
316 91c10532 Andrea Spadaccini
    # (As per the QEMU Protocol Specification 0.1 - section 4)
317 91c10532 Andrea Spadaccini
    self.Execute(self._CAPABILITIES_COMMAND)
318 91c10532 Andrea Spadaccini
319 91c10532 Andrea Spadaccini
  def _ParseMessage(self, buf):
320 91c10532 Andrea Spadaccini
    """Extract and parse a QMP message from the given buffer.
321 91c10532 Andrea Spadaccini

322 91c10532 Andrea Spadaccini
    Seeks for a QMP message in the given buf. If found, it parses it and
323 91c10532 Andrea Spadaccini
    returns it together with the rest of the characters in the buf.
324 91c10532 Andrea Spadaccini
    If no message is found, returns None and the whole buffer.
325 91c10532 Andrea Spadaccini

326 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
327 91c10532 Andrea Spadaccini

328 91c10532 Andrea Spadaccini
    """
329 91c10532 Andrea Spadaccini
    message = None
330 91c10532 Andrea Spadaccini
    # Check if we got the message end token (CRLF, as per the QEMU Protocol
331 91c10532 Andrea Spadaccini
    # Specification 0.1 - Section 2.1.1)
332 91c10532 Andrea Spadaccini
    pos = buf.find(self._MESSAGE_END_TOKEN)
333 91c10532 Andrea Spadaccini
    if pos >= 0:
334 91c10532 Andrea Spadaccini
      try:
335 91c10532 Andrea Spadaccini
        message = QmpMessage.BuildFromJsonString(buf[:pos + 1])
336 91c10532 Andrea Spadaccini
      except Exception, err:
337 91c10532 Andrea Spadaccini
        raise errors.ProgrammerError("QMP data serialization error: %s" % err)
338 91c10532 Andrea Spadaccini
      buf = buf[pos + 1:]
339 91c10532 Andrea Spadaccini
340 91c10532 Andrea Spadaccini
    return (message, buf)
341 91c10532 Andrea Spadaccini
342 91c10532 Andrea Spadaccini
  def _Recv(self):
343 91c10532 Andrea Spadaccini
    """Receives a message from QMP and decodes the received JSON object.
344 91c10532 Andrea Spadaccini

345 91c10532 Andrea Spadaccini
    @rtype: QmpMessage
346 91c10532 Andrea Spadaccini
    @return: the received message
347 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
348 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
349 91c10532 Andrea Spadaccini

350 91c10532 Andrea Spadaccini
    """
351 91c10532 Andrea Spadaccini
    self._check_connection()
352 91c10532 Andrea Spadaccini
353 91c10532 Andrea Spadaccini
    # Check if there is already a message in the buffer
354 91c10532 Andrea Spadaccini
    (message, self._buf) = self._ParseMessage(self._buf)
355 91c10532 Andrea Spadaccini
    if message:
356 91c10532 Andrea Spadaccini
      return message
357 91c10532 Andrea Spadaccini
358 91c10532 Andrea Spadaccini
    recv_buffer = StringIO.StringIO(self._buf)
359 91c10532 Andrea Spadaccini
    recv_buffer.seek(len(self._buf))
360 91c10532 Andrea Spadaccini
    try:
361 91c10532 Andrea Spadaccini
      while True:
362 91c10532 Andrea Spadaccini
        data = self.sock.recv(4096)
363 91c10532 Andrea Spadaccini
        if not data:
364 91c10532 Andrea Spadaccini
          break
365 91c10532 Andrea Spadaccini
        recv_buffer.write(data)
366 91c10532 Andrea Spadaccini
367 91c10532 Andrea Spadaccini
        (message, self._buf) = self._ParseMessage(recv_buffer.getvalue())
368 91c10532 Andrea Spadaccini
        if message:
369 91c10532 Andrea Spadaccini
          return message
370 91c10532 Andrea Spadaccini
371 91c10532 Andrea Spadaccini
    except socket.timeout, err:
372 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Timeout while receiving a QMP message: "
373 91c10532 Andrea Spadaccini
                                   "%s" % (err))
374 91c10532 Andrea Spadaccini
    except socket.error, err:
375 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Unable to receive data from KVM using the"
376 91c10532 Andrea Spadaccini
                                   " QMP protocol: %s" % err)
377 91c10532 Andrea Spadaccini
378 91c10532 Andrea Spadaccini
  def _Send(self, message):
379 91c10532 Andrea Spadaccini
    """Encodes and sends a message to KVM using QMP.
380 91c10532 Andrea Spadaccini

381 91c10532 Andrea Spadaccini
    @type message: QmpMessage
382 91c10532 Andrea Spadaccini
    @param message: message to send to KVM
383 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
384 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
385 91c10532 Andrea Spadaccini

386 91c10532 Andrea Spadaccini
    """
387 91c10532 Andrea Spadaccini
    self._check_connection()
388 91c10532 Andrea Spadaccini
    try:
389 91c10532 Andrea Spadaccini
      message_str = str(message)
390 91c10532 Andrea Spadaccini
    except Exception, err:
391 91c10532 Andrea Spadaccini
      raise errors.ProgrammerError("QMP data deserialization error: %s" % err)
392 91c10532 Andrea Spadaccini
393 91c10532 Andrea Spadaccini
    try:
394 91c10532 Andrea Spadaccini
      self.sock.sendall(message_str)
395 91c10532 Andrea Spadaccini
    except socket.timeout, err:
396 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Timeout while sending a QMP message: "
397 91c10532 Andrea Spadaccini
                                   "%s (%s)" % (err.string, err.errno))
398 91c10532 Andrea Spadaccini
    except socket.error, err:
399 91c10532 Andrea Spadaccini
      raise errors.HypervisorError("Unable to send data from KVM using the"
400 91c10532 Andrea Spadaccini
                                   " QMP protocol: %s" % err)
401 91c10532 Andrea Spadaccini
402 91c10532 Andrea Spadaccini
  def Execute(self, command, arguments=None):
403 91c10532 Andrea Spadaccini
    """Executes a QMP command and returns the response of the server.
404 91c10532 Andrea Spadaccini

405 91c10532 Andrea Spadaccini
    @type command: str
406 91c10532 Andrea Spadaccini
    @param command: the command to execute
407 91c10532 Andrea Spadaccini
    @type arguments: dict
408 91c10532 Andrea Spadaccini
    @param arguments: dictionary of arguments to be passed to the command
409 91c10532 Andrea Spadaccini
    @rtype: dict
410 91c10532 Andrea Spadaccini
    @return: dictionary representing the received JSON object
411 91c10532 Andrea Spadaccini
    @raise errors.HypervisorError: when there are communication errors
412 91c10532 Andrea Spadaccini
    @raise errors.ProgrammerError: when there are data serialization errors
413 91c10532 Andrea Spadaccini

414 91c10532 Andrea Spadaccini
    """
415 91c10532 Andrea Spadaccini
    self._check_connection()
416 91c10532 Andrea Spadaccini
    message = QmpMessage({self._EXECUTE_KEY: command})
417 91c10532 Andrea Spadaccini
    if arguments:
418 91c10532 Andrea Spadaccini
      message[self._ARGUMENTS_KEY] = arguments
419 91c10532 Andrea Spadaccini
    self._Send(message)
420 91c10532 Andrea Spadaccini
421 91c10532 Andrea Spadaccini
    # Events can occur between the sending of the command and the reception
422 91c10532 Andrea Spadaccini
    # of the response, so we need to filter out messages with the event key.
423 91c10532 Andrea Spadaccini
    while True:
424 91c10532 Andrea Spadaccini
      response = self._Recv()
425 91c10532 Andrea Spadaccini
      err = response[self._ERROR_KEY]
426 91c10532 Andrea Spadaccini
      if err:
427 91c10532 Andrea Spadaccini
        raise errors.HypervisorError("kvm: error executing the %s"
428 91c10532 Andrea Spadaccini
                                     " command: %s (%s, %s):" %
429 91c10532 Andrea Spadaccini
                                     (command,
430 91c10532 Andrea Spadaccini
                                      err[self._ERROR_DESC_KEY],
431 91c10532 Andrea Spadaccini
                                      err[self._ERROR_CLASS_KEY],
432 91c10532 Andrea Spadaccini
                                      err[self._ERROR_DATA_KEY]))
433 91c10532 Andrea Spadaccini
434 91c10532 Andrea Spadaccini
      elif not response[self._EVENT_KEY]:
435 91c10532 Andrea Spadaccini
        return response
436 91c10532 Andrea Spadaccini
437 91c10532 Andrea Spadaccini
438 eb58f9b1 Guido Trotter
class KVMHypervisor(hv_base.BaseHypervisor):
439 65107a2f Michael Hanselmann
  """KVM hypervisor interface
440 65107a2f Michael Hanselmann

441 65107a2f Michael Hanselmann
  """
442 d271c6fd Iustin Pop
  CAN_MIGRATE = True
443 eb58f9b1 Guido Trotter
444 9d9bded1 Michael Hanselmann
  _ROOT_DIR = pathutils.RUN_DIR + "/kvm-hypervisor"
445 a1d79fc6 Guido Trotter
  _PIDS_DIR = _ROOT_DIR + "/pid" # contains live instances pids
446 7548396c Guido Trotter
  _UIDS_DIR = _ROOT_DIR + "/uid" # contains instances reserved uids
447 a1d79fc6 Guido Trotter
  _CTRL_DIR = _ROOT_DIR + "/ctrl" # contains instances control sockets
448 a1d79fc6 Guido Trotter
  _CONF_DIR = _ROOT_DIR + "/conf" # contains instances startup data
449 5d9bfd87 Apollon Oikonomopoulos
  _NICS_DIR = _ROOT_DIR + "/nic" # contains instances nic <-> tap associations
450 4f580fef Sébastien Bocahu
  _KEYMAP_DIR = _ROOT_DIR + "/keymap" # contains instances keymaps
451 547a63b7 Balazs Lecz
  # KVM instances with chroot enabled are started in empty chroot directories.
452 547a63b7 Balazs Lecz
  _CHROOT_DIR = _ROOT_DIR + "/chroot" # for empty chroot directories
453 547a63b7 Balazs Lecz
  # After an instance is stopped, its chroot directory is removed.
454 547a63b7 Balazs Lecz
  # If the chroot directory is not empty, it can't be removed.
455 547a63b7 Balazs Lecz
  # A non-empty chroot directory indicates a possible security incident.
456 547a63b7 Balazs Lecz
  # To support forensics, the non-empty chroot directory is quarantined in
457 547a63b7 Balazs Lecz
  # a separate directory, called 'chroot-quarantine'.
458 547a63b7 Balazs Lecz
  _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine"
459 5d9bfd87 Apollon Oikonomopoulos
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR, _NICS_DIR,
460 2911f46c Iustin Pop
           _CHROOT_DIR, _CHROOT_QUARANTINE_DIR, _KEYMAP_DIR]
461 eb58f9b1 Guido Trotter
462 205ab586 Iustin Pop
  PARAMETERS = {
463 205ab586 Iustin Pop
    constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK,
464 205ab586 Iustin Pop
    constants.HV_INITRD_PATH: hv_base.OPT_FILE_CHECK,
465 205ab586 Iustin Pop
    constants.HV_ROOT_PATH: hv_base.NO_CHECK,
466 205ab586 Iustin Pop
    constants.HV_KERNEL_ARGS: hv_base.NO_CHECK,
467 205ab586 Iustin Pop
    constants.HV_ACPI: hv_base.NO_CHECK,
468 205ab586 Iustin Pop
    constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
469 d73ef63f Michael Hanselmann
    constants.HV_VNC_BIND_ADDRESS:
470 8b312c1d Manuel Franceschini
      (False, lambda x: (netutils.IP4Address.IsValid(x) or
471 8b312c1d Manuel Franceschini
                         utils.IsNormAbsPath(x)),
472 d73ef63f Michael Hanselmann
       "the VNC bind address must be either a valid IP address or an absolute"
473 d73ef63f Michael Hanselmann
       " pathname", None, None),
474 205ab586 Iustin Pop
    constants.HV_VNC_TLS: hv_base.NO_CHECK,
475 205ab586 Iustin Pop
    constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
476 205ab586 Iustin Pop
    constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
477 6e6bb8d5 Guido Trotter
    constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
478 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_BIND: hv_base.NO_CHECK, # will be checked later
479 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_IP_VERSION:
480 b1cb62bd Andrea Spadaccini
      (False, lambda x: (x == constants.IFACE_NO_IP_VERSION_SPECIFIED or
481 b1cb62bd Andrea Spadaccini
                         x in constants.VALID_IP_VERSIONS),
482 b1cb62bd Andrea Spadaccini
       "the SPICE IP version should be 4 or 6",
483 b1cb62bd Andrea Spadaccini
       None, None),
484 b451c4c7 Andrea Spadaccini
    constants.HV_KVM_SPICE_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
485 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR:
486 5ae4945a Iustin Pop
      hv_base.ParamInSet(
487 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSLESS_IMG_COMPR_OPTIONS),
488 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_JPEG_IMG_COMPR:
489 5ae4945a Iustin Pop
      hv_base.ParamInSet(
490 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
491 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR:
492 5ae4945a Iustin Pop
      hv_base.ParamInSet(
493 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
494 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION:
495 5ae4945a Iustin Pop
      hv_base.ParamInSet(
496 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_VIDEO_STREAM_DETECTION_OPTIONS),
497 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_AUDIO_COMPR: hv_base.NO_CHECK,
498 bfe86c76 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_TLS: hv_base.NO_CHECK,
499 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_TLS_CIPHERS: hv_base.NO_CHECK,
500 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_VDAGENT: hv_base.NO_CHECK,
501 cc130cc7 Marco Casavecchia
    constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
502 205ab586 Iustin Pop
    constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
503 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
504 d73ef63f Michael Hanselmann
    constants.HV_BOOT_ORDER:
505 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
506 d73ef63f Michael Hanselmann
    constants.HV_NIC_TYPE:
507 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_NIC_TYPES),
508 d73ef63f Michael Hanselmann
    constants.HV_DISK_TYPE:
509 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_DISK_TYPES),
510 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM_DISK_TYPE:
511 cc130cc7 Marco Casavecchia
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_DISK_TYPES),
512 d73ef63f Michael Hanselmann
    constants.HV_USB_MOUSE:
513 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_MOUSE_TYPES),
514 4f580fef Sébastien Bocahu
    constants.HV_KEYMAP: hv_base.NO_CHECK,
515 e2d14329 Andrea Spadaccini
    constants.HV_MIGRATION_PORT: hv_base.REQ_NET_PORT_CHECK,
516 e43d4f9f Apollon Oikonomopoulos
    constants.HV_MIGRATION_BANDWIDTH: hv_base.NO_CHECK,
517 e43d4f9f Apollon Oikonomopoulos
    constants.HV_MIGRATION_DOWNTIME: hv_base.NO_CHECK,
518 783a6c0b Iustin Pop
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
519 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
520 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
521 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
522 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
523 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
524 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
525 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
526 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
527 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
528 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
529 4f958b0b Miguel Di Ciurcio Filho
    constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
530 990ade2d Stephen Shirley
    constants.HV_REBOOT_BEHAVIOR:
531 a7f884d3 Tsachy Shacham
      hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
532 a7f884d3 Tsachy Shacham
    constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
533 3c286190 Dimitris Aragiorgis
    constants.HV_CPU_TYPE: hv_base.NO_CHECK,
534 205ab586 Iustin Pop
    }
535 6b5605e8 Iustin Pop
536 d0c8c01d Iustin Pop
  _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)",
537 30e42c4e Guido Trotter
                                    re.M | re.I)
538 65107a2f Michael Hanselmann
  _MIGRATION_PROGRESS_RE = \
539 527c0cf7 Michael Hanselmann
    re.compile(r"\s*transferred\s+ram:\s+(?P<transferred>\d+)\s+kbytes\s*\n"
540 527c0cf7 Michael Hanselmann
               r"\s*remaining\s+ram:\s+(?P<remaining>\d+)\s+kbytes\s*\n"
541 527c0cf7 Michael Hanselmann
               r"\s*total\s+ram:\s+(?P<total>\d+)\s+kbytes\s*\n", re.I)
542 61643226 Andrea Spadaccini
543 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
544 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
545 30e42c4e Guido Trotter
546 585c8187 Guido Trotter
  _VERSION_RE = re.compile(r"\b(\d+)\.(\d+)(\.(\d+))?\b")
547 b52d85c1 Guido Trotter
548 b693125f Tsachy Shacham
  _CPU_INFO_RE = re.compile(r"cpu\s+\#(\d+).*thread_id\s*=\s*(\d+)", re.I)
549 b693125f Tsachy Shacham
  _CPU_INFO_CMD = "info cpus"
550 b693125f Tsachy Shacham
  _CONT_CMD = "cont"
551 b693125f Tsachy Shacham
552 64bfbc08 Guido Trotter
  ANCILLARY_FILES = [
553 64bfbc08 Guido Trotter
    _KVM_NETWORK_SCRIPT,
554 64bfbc08 Guido Trotter
    ]
555 69ab2e12 Guido Trotter
  ANCILLARY_FILES_OPT = [
556 69ab2e12 Guido Trotter
    _KVM_NETWORK_SCRIPT,
557 69ab2e12 Guido Trotter
    ]
558 64bfbc08 Guido Trotter
559 eb58f9b1 Guido Trotter
  def __init__(self):
560 eb58f9b1 Guido Trotter
    hv_base.BaseHypervisor.__init__(self)
561 eb58f9b1 Guido Trotter
    # Let's make sure the directories we need exist, even if the RUN_DIR lives
562 eb58f9b1 Guido Trotter
    # in a tmpfs filesystem or has been otherwise wiped out.
563 29921401 Iustin Pop
    dirs = [(dname, constants.RUN_DIRS_MODE) for dname in self._DIRS]
564 9afb67fe Guido Trotter
    utils.EnsureDirs(dirs)
565 eb58f9b1 Guido Trotter
566 30786fc9 Iustin Pop
  @classmethod
567 30786fc9 Iustin Pop
  def _InstancePidFile(cls, instance_name):
568 98ec75d6 Iustin Pop
    """Returns the instance pidfile.
569 98ec75d6 Iustin Pop

570 98ec75d6 Iustin Pop
    """
571 30786fc9 Iustin Pop
    return utils.PathJoin(cls._PIDS_DIR, instance_name)
572 98ec75d6 Iustin Pop
573 263b8de6 Guido Trotter
  @classmethod
574 7548396c Guido Trotter
  def _InstanceUidFile(cls, instance_name):
575 7548396c Guido Trotter
    """Returns the instance uidfile.
576 7548396c Guido Trotter

577 7548396c Guido Trotter
    """
578 7548396c Guido Trotter
    return utils.PathJoin(cls._UIDS_DIR, instance_name)
579 7548396c Guido Trotter
580 7548396c Guido Trotter
  @classmethod
581 263b8de6 Guido Trotter
  def _InstancePidInfo(cls, pid):
582 263b8de6 Guido Trotter
    """Check pid file for instance information.
583 263b8de6 Guido Trotter

584 263b8de6 Guido Trotter
    Check that a pid file is associated with an instance, and retrieve
585 263b8de6 Guido Trotter
    information from its command line.
586 263b8de6 Guido Trotter

587 263b8de6 Guido Trotter
    @type pid: string or int
588 263b8de6 Guido Trotter
    @param pid: process id of the instance to check
589 263b8de6 Guido Trotter
    @rtype: tuple
590 263b8de6 Guido Trotter
    @return: (instance_name, memory, vcpus)
591 263b8de6 Guido Trotter
    @raise errors.HypervisorError: when an instance cannot be found
592 263b8de6 Guido Trotter

593 263b8de6 Guido Trotter
    """
594 263b8de6 Guido Trotter
    alive = utils.IsProcessAlive(pid)
595 263b8de6 Guido Trotter
    if not alive:
596 263b8de6 Guido Trotter
      raise errors.HypervisorError("Cannot get info for pid %s" % pid)
597 263b8de6 Guido Trotter
598 263b8de6 Guido Trotter
    cmdline_file = utils.PathJoin("/proc", str(pid), "cmdline")
599 263b8de6 Guido Trotter
    try:
600 263b8de6 Guido Trotter
      cmdline = utils.ReadFile(cmdline_file)
601 263b8de6 Guido Trotter
    except EnvironmentError, err:
602 263b8de6 Guido Trotter
      raise errors.HypervisorError("Can't open cmdline file for pid %s: %s" %
603 263b8de6 Guido Trotter
                                   (pid, err))
604 263b8de6 Guido Trotter
605 263b8de6 Guido Trotter
    instance = None
606 263b8de6 Guido Trotter
    memory = 0
607 263b8de6 Guido Trotter
    vcpus = 0
608 263b8de6 Guido Trotter
609 d0c8c01d Iustin Pop
    arg_list = cmdline.split("\x00")
610 263b8de6 Guido Trotter
    while arg_list:
611 e687ec01 Michael Hanselmann
      arg = arg_list.pop(0)
612 263b8de6 Guido Trotter
      if arg == "-name":
613 263b8de6 Guido Trotter
        instance = arg_list.pop(0)
614 263b8de6 Guido Trotter
      elif arg == "-m":
615 263b8de6 Guido Trotter
        memory = int(arg_list.pop(0))
616 263b8de6 Guido Trotter
      elif arg == "-smp":
617 263b8de6 Guido Trotter
        vcpus = int(arg_list.pop(0))
618 263b8de6 Guido Trotter
619 263b8de6 Guido Trotter
    if instance is None:
620 263b8de6 Guido Trotter
      raise errors.HypervisorError("Pid %s doesn't contain a ganeti kvm"
621 263b8de6 Guido Trotter
                                   " instance" % pid)
622 263b8de6 Guido Trotter
623 263b8de6 Guido Trotter
    return (instance, memory, vcpus)
624 263b8de6 Guido Trotter
625 1f8b3a27 Guido Trotter
  def _InstancePidAlive(self, instance_name):
626 263b8de6 Guido Trotter
    """Returns the instance pidfile, pid, and liveness.
627 263b8de6 Guido Trotter

628 263b8de6 Guido Trotter
    @type instance_name: string
629 263b8de6 Guido Trotter
    @param instance_name: instance name
630 263b8de6 Guido Trotter
    @rtype: tuple
631 263b8de6 Guido Trotter
    @return: (pid file name, pid, liveness)
632 1f8b3a27 Guido Trotter

633 1f8b3a27 Guido Trotter
    """
634 98ec75d6 Iustin Pop
    pidfile = self._InstancePidFile(instance_name)
635 1f8b3a27 Guido Trotter
    pid = utils.ReadPidFile(pidfile)
636 263b8de6 Guido Trotter
637 263b8de6 Guido Trotter
    alive = False
638 263b8de6 Guido Trotter
    try:
639 263b8de6 Guido Trotter
      cmd_instance = self._InstancePidInfo(pid)[0]
640 263b8de6 Guido Trotter
      alive = (cmd_instance == instance_name)
641 263b8de6 Guido Trotter
    except errors.HypervisorError:
642 263b8de6 Guido Trotter
      pass
643 1f8b3a27 Guido Trotter
644 1f8b3a27 Guido Trotter
    return (pidfile, pid, alive)
645 1f8b3a27 Guido Trotter
646 5905901c Iustin Pop
  def _CheckDown(self, instance_name):
647 5905901c Iustin Pop
    """Raises an error unless the given instance is down.
648 5905901c Iustin Pop

649 5905901c Iustin Pop
    """
650 5905901c Iustin Pop
    alive = self._InstancePidAlive(instance_name)[2]
651 5905901c Iustin Pop
    if alive:
652 5905901c Iustin Pop
      raise errors.HypervisorError("Failed to start instance %s: %s" %
653 5905901c Iustin Pop
                                   (instance_name, "already running"))
654 5905901c Iustin Pop
655 0df4d98a Guido Trotter
  @classmethod
656 0df4d98a Guido Trotter
  def _InstanceMonitor(cls, instance_name):
657 c4fbefc8 Guido Trotter
    """Returns the instance monitor socket name
658 c4fbefc8 Guido Trotter

659 c4fbefc8 Guido Trotter
    """
660 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.monitor" % instance_name)
661 c4fbefc8 Guido Trotter
662 0df4d98a Guido Trotter
  @classmethod
663 0df4d98a Guido Trotter
  def _InstanceSerial(cls, instance_name):
664 c4fbefc8 Guido Trotter
    """Returns the instance serial socket name
665 c4fbefc8 Guido Trotter

666 c4fbefc8 Guido Trotter
    """
667 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.serial" % instance_name)
668 c4fbefc8 Guido Trotter
669 91c10532 Andrea Spadaccini
  @classmethod
670 91c10532 Andrea Spadaccini
  def _InstanceQmpMonitor(cls, instance_name):
671 91c10532 Andrea Spadaccini
    """Returns the instance serial QMP socket name
672 91c10532 Andrea Spadaccini

673 91c10532 Andrea Spadaccini
    """
674 91c10532 Andrea Spadaccini
    return utils.PathJoin(cls._CTRL_DIR, "%s.qmp" % instance_name)
675 91c10532 Andrea Spadaccini
676 86d6bc2a Guido Trotter
  @staticmethod
677 86d6bc2a Guido Trotter
  def _SocatUnixConsoleParams():
678 86d6bc2a Guido Trotter
    """Returns the correct parameters for socat
679 86d6bc2a Guido Trotter

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

682 86d6bc2a Guido Trotter
    """
683 fe5b0c42 Michael Hanselmann
    if constants.SOCAT_USE_ESCAPE:
684 86d6bc2a Guido Trotter
      return "raw,echo=0,escape=%s" % constants.SOCAT_ESCAPE_CODE
685 86d6bc2a Guido Trotter
    else:
686 86d6bc2a Guido Trotter
      return "echo=0,icanon=0"
687 86d6bc2a Guido Trotter
688 0df4d98a Guido Trotter
  @classmethod
689 0df4d98a Guido Trotter
  def _InstanceKVMRuntime(cls, instance_name):
690 38e250ba Guido Trotter
    """Returns the instance KVM runtime filename
691 38e250ba Guido Trotter

692 38e250ba Guido Trotter
    """
693 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
694 38e250ba Guido Trotter
695 7e66c35b Guido Trotter
  @classmethod
696 547a63b7 Balazs Lecz
  def _InstanceChrootDir(cls, instance_name):
697 547a63b7 Balazs Lecz
    """Returns the name of the KVM chroot dir of the instance
698 547a63b7 Balazs Lecz

699 547a63b7 Balazs Lecz
    """
700 547a63b7 Balazs Lecz
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
701 547a63b7 Balazs Lecz
702 547a63b7 Balazs Lecz
  @classmethod
703 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICDir(cls, instance_name):
704 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the directory holding the tap device files for a
705 5d9bfd87 Apollon Oikonomopoulos
    given instance.
706 5d9bfd87 Apollon Oikonomopoulos

707 5d9bfd87 Apollon Oikonomopoulos
    """
708 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._NICS_DIR, instance_name)
709 5d9bfd87 Apollon Oikonomopoulos
710 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
711 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICFile(cls, instance_name, seq):
712 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the file containing the tap device for a given NIC
713 5d9bfd87 Apollon Oikonomopoulos

714 5d9bfd87 Apollon Oikonomopoulos
    """
715 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._InstanceNICDir(instance_name), str(seq))
716 5d9bfd87 Apollon Oikonomopoulos
717 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
718 4f580fef Sébastien Bocahu
  def _InstanceKeymapFile(cls, instance_name):
719 4f580fef Sébastien Bocahu
    """Returns the name of the file containing the keymap for a given instance
720 4f580fef Sébastien Bocahu

721 4f580fef Sébastien Bocahu
    """
722 4f580fef Sébastien Bocahu
    return utils.PathJoin(cls._KEYMAP_DIR, instance_name)
723 4f580fef Sébastien Bocahu
724 4f580fef Sébastien Bocahu
  @classmethod
725 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
726 7548396c Guido Trotter
    """Try to read a uid file
727 7548396c Guido Trotter

728 7548396c Guido Trotter
    """
729 7548396c Guido Trotter
    if os.path.exists(uid_file):
730 7548396c Guido Trotter
      try:
731 682f7601 Guido Trotter
        uid = int(utils.ReadOneLineFile(uid_file))
732 aa0b600b Guido Trotter
        return uid
733 7548396c Guido Trotter
      except EnvironmentError:
734 7548396c Guido Trotter
        logging.warning("Can't read uid file", exc_info=True)
735 7548396c Guido Trotter
      except (TypeError, ValueError):
736 7548396c Guido Trotter
        logging.warning("Can't parse uid file contents", exc_info=True)
737 aa0b600b Guido Trotter
    return None
738 7548396c Guido Trotter
739 7548396c Guido Trotter
  @classmethod
740 7e66c35b Guido Trotter
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
741 547a63b7 Balazs Lecz
    """Removes an instance's rutime sockets/files/dirs.
742 7e66c35b Guido Trotter

743 7e66c35b Guido Trotter
    """
744 7e66c35b Guido Trotter
    utils.RemoveFile(pidfile)
745 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceMonitor(instance_name))
746 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceSerial(instance_name))
747 91c10532 Andrea Spadaccini
    utils.RemoveFile(cls._InstanceQmpMonitor(instance_name))
748 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceKVMRuntime(instance_name))
749 4f580fef Sébastien Bocahu
    utils.RemoveFile(cls._InstanceKeymapFile(instance_name))
750 7548396c Guido Trotter
    uid_file = cls._InstanceUidFile(instance_name)
751 7548396c Guido Trotter
    uid = cls._TryReadUidFile(uid_file)
752 7548396c Guido Trotter
    utils.RemoveFile(uid_file)
753 7548396c Guido Trotter
    if uid is not None:
754 7548396c Guido Trotter
      uidpool.ReleaseUid(uid)
755 7be85163 Guido Trotter
    try:
756 7be85163 Guido Trotter
      shutil.rmtree(cls._InstanceNICDir(instance_name))
757 7be85163 Guido Trotter
    except OSError, err:
758 7be85163 Guido Trotter
      if err.errno != errno.ENOENT:
759 7be85163 Guido Trotter
        raise
760 547a63b7 Balazs Lecz
    try:
761 547a63b7 Balazs Lecz
      chroot_dir = cls._InstanceChrootDir(instance_name)
762 547a63b7 Balazs Lecz
      utils.RemoveDir(chroot_dir)
763 547a63b7 Balazs Lecz
    except OSError, err:
764 547a63b7 Balazs Lecz
      if err.errno == errno.ENOTEMPTY:
765 547a63b7 Balazs Lecz
        # The chroot directory is expected to be empty, but it isn't.
766 547a63b7 Balazs Lecz
        new_chroot_dir = tempfile.mkdtemp(dir=cls._CHROOT_QUARANTINE_DIR,
767 547a63b7 Balazs Lecz
                                          prefix="%s-%s-" %
768 547a63b7 Balazs Lecz
                                          (instance_name,
769 547a63b7 Balazs Lecz
                                           utils.TimestampForFilename()))
770 547a63b7 Balazs Lecz
        logging.warning("The chroot directory of instance %s can not be"
771 547a63b7 Balazs Lecz
                        " removed as it is not empty. Moving it to the"
772 547a63b7 Balazs Lecz
                        " quarantine instead. Please investigate the"
773 547a63b7 Balazs Lecz
                        " contents (%s) and clean up manually",
774 547a63b7 Balazs Lecz
                        instance_name, new_chroot_dir)
775 547a63b7 Balazs Lecz
        utils.RenameFile(chroot_dir, new_chroot_dir)
776 547a63b7 Balazs Lecz
      else:
777 547a63b7 Balazs Lecz
        raise
778 7e66c35b Guido Trotter
779 748e4b5a Michael Hanselmann
  @staticmethod
780 5d9bfd87 Apollon Oikonomopoulos
  def _ConfigureNIC(instance, seq, nic, tap):
781 5d9bfd87 Apollon Oikonomopoulos
    """Run the network configuration script for a specified NIC
782 eb58f9b1 Guido Trotter

783 eb58f9b1 Guido Trotter
    @param instance: instance we're acting on
784 eb58f9b1 Guido Trotter
    @type instance: instance object
785 eb58f9b1 Guido Trotter
    @param seq: nic sequence number
786 eb58f9b1 Guido Trotter
    @type seq: int
787 eb58f9b1 Guido Trotter
    @param nic: nic we're acting on
788 eb58f9b1 Guido Trotter
    @type nic: nic object
789 5d9bfd87 Apollon Oikonomopoulos
    @param tap: the host's tap interface this NIC corresponds to
790 5d9bfd87 Apollon Oikonomopoulos
    @type tap: str
791 eb58f9b1 Guido Trotter

792 eb58f9b1 Guido Trotter
    """
793 5d9bfd87 Apollon Oikonomopoulos
    if instance.tags:
794 5d9bfd87 Apollon Oikonomopoulos
      tags = " ".join(instance.tags)
795 5d9bfd87 Apollon Oikonomopoulos
    else:
796 5d9bfd87 Apollon Oikonomopoulos
      tags = ""
797 5d9bfd87 Apollon Oikonomopoulos
798 5d9bfd87 Apollon Oikonomopoulos
    env = {
799 5d9bfd87 Apollon Oikonomopoulos
      "PATH": "%s:/sbin:/usr/sbin" % os.environ["PATH"],
800 5d9bfd87 Apollon Oikonomopoulos
      "INSTANCE": instance.name,
801 5d9bfd87 Apollon Oikonomopoulos
      "MAC": nic.mac,
802 5d9bfd87 Apollon Oikonomopoulos
      "MODE": nic.nicparams[constants.NIC_MODE],
803 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE": tap,
804 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE_INDEX": str(seq),
805 5d9bfd87 Apollon Oikonomopoulos
      "TAGS": tags,
806 5d9bfd87 Apollon Oikonomopoulos
    }
807 5d9bfd87 Apollon Oikonomopoulos
808 5d9bfd87 Apollon Oikonomopoulos
    if nic.ip:
809 5d9bfd87 Apollon Oikonomopoulos
      env["IP"] = nic.ip
810 5d9bfd87 Apollon Oikonomopoulos
811 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_LINK]:
812 5d9bfd87 Apollon Oikonomopoulos
      env["LINK"] = nic.nicparams[constants.NIC_LINK]
813 5d9bfd87 Apollon Oikonomopoulos
814 a5ad5e58 Apollon Oikonomopoulos
    if nic.network:
815 cbe4a0a5 Dimitris Aragiorgis
      n = objects.Network.FromDict(nic.netinfo)
816 cbe4a0a5 Dimitris Aragiorgis
      _BuildNetworkEnv(nic.network, n.network, n.gateway,
817 cbe4a0a5 Dimitris Aragiorgis
                       n.network6, n.gateway6, n.network_type,
818 cbe4a0a5 Dimitris Aragiorgis
                       n.mac_prefix, n.tags, env)
819 a5ad5e58 Apollon Oikonomopoulos
820 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
821 5d9bfd87 Apollon Oikonomopoulos
      env["BRIDGE"] = nic.nicparams[constants.NIC_LINK]
822 5d9bfd87 Apollon Oikonomopoulos
823 9d9bded1 Michael Hanselmann
    result = utils.RunCmd([pathutils.KVM_IFUP, tap], env=env)
824 5d9bfd87 Apollon Oikonomopoulos
    if result.failed:
825 5d9bfd87 Apollon Oikonomopoulos
      raise errors.HypervisorError("Failed to configure interface %s: %s."
826 5d9bfd87 Apollon Oikonomopoulos
                                   " Network configuration script output: %s" %
827 5d9bfd87 Apollon Oikonomopoulos
                                   (tap, result.fail_reason, result.output))
828 eb58f9b1 Guido Trotter
829 b693125f Tsachy Shacham
  @staticmethod
830 b693125f Tsachy Shacham
  def _VerifyAffinityPackage():
831 b693125f Tsachy Shacham
    if affinity is None:
832 b693125f Tsachy Shacham
      raise errors.HypervisorError("affinity Python package not"
833 5ae4945a Iustin Pop
                                   " found; cannot use CPU pinning under KVM")
834 b693125f Tsachy Shacham
835 b693125f Tsachy Shacham
  @staticmethod
836 b693125f Tsachy Shacham
  def _BuildAffinityCpuMask(cpu_list):
837 b693125f Tsachy Shacham
    """Create a CPU mask suitable for sched_setaffinity from a list of
838 b693125f Tsachy Shacham
    CPUs.
839 b693125f Tsachy Shacham

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

843 b693125f Tsachy Shacham
    @type cpu_list: list of int
844 b693125f Tsachy Shacham
    @param cpu_list: list of physical CPU numbers to map to vCPUs in order
845 b693125f Tsachy Shacham
    @rtype: int
846 b693125f Tsachy Shacham
    @return: a bit mask of CPU affinities
847 b693125f Tsachy Shacham

848 b693125f Tsachy Shacham
    """
849 b693125f Tsachy Shacham
    if cpu_list == constants.CPU_PINNING_OFF:
850 b693125f Tsachy Shacham
      return constants.CPU_PINNING_ALL_KVM
851 b693125f Tsachy Shacham
    else:
852 b693125f Tsachy Shacham
      return sum(2 ** cpu for cpu in cpu_list)
853 b693125f Tsachy Shacham
854 b693125f Tsachy Shacham
  @classmethod
855 b693125f Tsachy Shacham
  def _AssignCpuAffinity(cls, cpu_mask, process_id, thread_dict):
856 b693125f Tsachy Shacham
    """Change CPU affinity for running VM according to given CPU mask.
857 b693125f Tsachy Shacham

858 b693125f Tsachy Shacham
    @param cpu_mask: CPU mask as given by the user. e.g. "0-2,4:all:1,3"
859 b693125f Tsachy Shacham
    @type cpu_mask: string
860 b693125f Tsachy Shacham
    @param process_id: process ID of KVM process. Used to pin entire VM
861 b693125f Tsachy Shacham
                       to physical CPUs.
862 b693125f Tsachy Shacham
    @type process_id: int
863 b693125f Tsachy Shacham
    @param thread_dict: map of virtual CPUs to KVM thread IDs
864 b693125f Tsachy Shacham
    @type thread_dict: dict int:int
865 b693125f Tsachy Shacham

866 b693125f Tsachy Shacham
    """
867 b693125f Tsachy Shacham
    # Convert the string CPU mask to a list of list of int's
868 b693125f Tsachy Shacham
    cpu_list = utils.ParseMultiCpuMask(cpu_mask)
869 b693125f Tsachy Shacham
870 b693125f Tsachy Shacham
    if len(cpu_list) == 1:
871 b693125f Tsachy Shacham
      all_cpu_mapping = cpu_list[0]
872 b693125f Tsachy Shacham
      if all_cpu_mapping == constants.CPU_PINNING_OFF:
873 b693125f Tsachy Shacham
        # If CPU pinning has 1 entry that's "all", then do nothing
874 b693125f Tsachy Shacham
        pass
875 b693125f Tsachy Shacham
      else:
876 b693125f Tsachy Shacham
        # If CPU pinning has one non-all entry, map the entire VM to
877 b693125f Tsachy Shacham
        # one set of physical CPUs
878 b693125f Tsachy Shacham
        cls._VerifyAffinityPackage()
879 5ae4945a Iustin Pop
        affinity.set_process_affinity_mask(
880 5ae4945a Iustin Pop
          process_id, cls._BuildAffinityCpuMask(all_cpu_mapping))
881 b693125f Tsachy Shacham
    else:
882 b693125f Tsachy Shacham
      # The number of vCPUs mapped should match the number of vCPUs
883 b693125f Tsachy Shacham
      # reported by KVM. This was already verified earlier, so
884 b693125f Tsachy Shacham
      # here only as a sanity check.
885 b693125f Tsachy Shacham
      assert len(thread_dict) == len(cpu_list)
886 b693125f Tsachy Shacham
      cls._VerifyAffinityPackage()
887 b693125f Tsachy Shacham
888 b693125f Tsachy Shacham
      # For each vCPU, map it to the proper list of physical CPUs
889 b693125f Tsachy Shacham
      for vcpu, i in zip(cpu_list, range(len(cpu_list))):
890 b693125f Tsachy Shacham
        affinity.set_process_affinity_mask(thread_dict[i],
891 5ae4945a Iustin Pop
                                           cls._BuildAffinityCpuMask(vcpu))
892 b693125f Tsachy Shacham
893 b693125f Tsachy Shacham
  def _GetVcpuThreadIds(self, instance_name):
894 b693125f Tsachy Shacham
    """Get a mapping of vCPU no. to thread IDs for the instance
895 b693125f Tsachy Shacham

896 b693125f Tsachy Shacham
    @type instance_name: string
897 b693125f Tsachy Shacham
    @param instance_name: instance in question
898 b693125f Tsachy Shacham
    @rtype: dictionary of int:int
899 b693125f Tsachy Shacham
    @return: a dictionary mapping vCPU numbers to thread IDs
900 b693125f Tsachy Shacham

901 b693125f Tsachy Shacham
    """
902 b693125f Tsachy Shacham
    result = {}
903 b693125f Tsachy Shacham
    output = self._CallMonitorCommand(instance_name, self._CPU_INFO_CMD)
904 b693125f Tsachy Shacham
    for line in output.stdout.splitlines():
905 b693125f Tsachy Shacham
      match = self._CPU_INFO_RE.search(line)
906 b693125f Tsachy Shacham
      if not match:
907 b693125f Tsachy Shacham
        continue
908 b693125f Tsachy Shacham
      grp = map(int, match.groups())
909 b693125f Tsachy Shacham
      result[grp[0]] = grp[1]
910 b693125f Tsachy Shacham
911 b693125f Tsachy Shacham
    return result
912 b693125f Tsachy Shacham
913 1d8a7812 Andrea Spadaccini
  def _ExecuteCpuAffinity(self, instance_name, cpu_mask):
914 1d8a7812 Andrea Spadaccini
    """Complete CPU pinning.
915 b693125f Tsachy Shacham

916 b693125f Tsachy Shacham
    @type instance_name: string
917 b693125f Tsachy Shacham
    @param instance_name: name of instance
918 b693125f Tsachy Shacham
    @type cpu_mask: string
919 b693125f Tsachy Shacham
    @param cpu_mask: CPU pinning mask as entered by user
920 b693125f Tsachy Shacham

921 b693125f Tsachy Shacham
    """
922 1d8a7812 Andrea Spadaccini
    # Get KVM process ID, to be used if need to pin entire VM
923 1d8a7812 Andrea Spadaccini
    _, pid, _ = self._InstancePidAlive(instance_name)
924 1d8a7812 Andrea Spadaccini
    # Get vCPU thread IDs, to be used if need to pin vCPUs separately
925 1d8a7812 Andrea Spadaccini
    thread_dict = self._GetVcpuThreadIds(instance_name)
926 1d8a7812 Andrea Spadaccini
    # Run CPU pinning, based on configured mask
927 1d8a7812 Andrea Spadaccini
    self._AssignCpuAffinity(cpu_mask, pid, thread_dict)
928 b693125f Tsachy Shacham
929 eb58f9b1 Guido Trotter
  def ListInstances(self):
930 eb58f9b1 Guido Trotter
    """Get the list of running instances.
931 eb58f9b1 Guido Trotter

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

935 eb58f9b1 Guido Trotter
    """
936 eb58f9b1 Guido Trotter
    result = []
937 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
938 263b8de6 Guido Trotter
      if self._InstancePidAlive(name)[2]:
939 eb58f9b1 Guido Trotter
        result.append(name)
940 eb58f9b1 Guido Trotter
    return result
941 eb58f9b1 Guido Trotter
942 eb58f9b1 Guido Trotter
  def GetInstanceInfo(self, instance_name):
943 eb58f9b1 Guido Trotter
    """Get instance properties.
944 eb58f9b1 Guido Trotter

945 4fbb3c60 Guido Trotter
    @type instance_name: string
946 c41eea6e Iustin Pop
    @param instance_name: the instance name
947 4fbb3c60 Guido Trotter
    @rtype: tuple of strings
948 4fbb3c60 Guido Trotter
    @return: (name, id, memory, vcpus, stat, times)
949 eb58f9b1 Guido Trotter

950 eb58f9b1 Guido Trotter
    """
951 1122eb25 Iustin Pop
    _, pid, alive = self._InstancePidAlive(instance_name)
952 1f8b3a27 Guido Trotter
    if not alive:
953 eb58f9b1 Guido Trotter
      return None
954 eb58f9b1 Guido Trotter
955 263b8de6 Guido Trotter
    _, memory, vcpus = self._InstancePidInfo(pid)
956 fc84cd5d Guido Trotter
    istat = "---b-"
957 eb58f9b1 Guido Trotter
    times = "0"
958 eb58f9b1 Guido Trotter
959 89da2ff3 Guido Trotter
    try:
960 89da2ff3 Guido Trotter
      qmp = QmpConnection(self._InstanceQmpMonitor(instance_name))
961 89da2ff3 Guido Trotter
      qmp.connect()
962 89da2ff3 Guido Trotter
      vcpus = len(qmp.Execute("query-cpus")[qmp.RETURN_KEY])
963 89da2ff3 Guido Trotter
      # Will fail if ballooning is not enabled, but we can then just resort to
964 89da2ff3 Guido Trotter
      # the value above.
965 89da2ff3 Guido Trotter
      mem_bytes = qmp.Execute("query-balloon")[qmp.RETURN_KEY][qmp.ACTUAL_KEY]
966 89da2ff3 Guido Trotter
      memory = mem_bytes / 1048576
967 89da2ff3 Guido Trotter
    except errors.HypervisorError:
968 89da2ff3 Guido Trotter
      pass
969 89da2ff3 Guido Trotter
970 fc84cd5d Guido Trotter
    return (instance_name, pid, memory, vcpus, istat, times)
971 eb58f9b1 Guido Trotter
972 eb58f9b1 Guido Trotter
  def GetAllInstancesInfo(self):
973 eb58f9b1 Guido Trotter
    """Get properties of all instances.
974 eb58f9b1 Guido Trotter

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

977 eb58f9b1 Guido Trotter
    """
978 eb58f9b1 Guido Trotter
    data = []
979 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
980 263b8de6 Guido Trotter
      try:
981 263b8de6 Guido Trotter
        info = self.GetInstanceInfo(name)
982 263b8de6 Guido Trotter
      except errors.HypervisorError:
983 3bc145d8 Bernardo Dal Seno
        # Ignore exceptions due to instances being shut down
984 263b8de6 Guido Trotter
        continue
985 263b8de6 Guido Trotter
      if info:
986 263b8de6 Guido Trotter
        data.append(info)
987 eb58f9b1 Guido Trotter
    return data
988 eb58f9b1 Guido Trotter
989 323f9095 Stephen Shirley
  def _GenerateKVMRuntime(self, instance, block_devices, startup_paused):
990 ee5f20b0 Guido Trotter
    """Generate KVM information to start an instance.
991 eb58f9b1 Guido Trotter

992 839642c2 Iustin Pop
    @attention: this function must not have any side-effects; for
993 839642c2 Iustin Pop
        example, it must not write to the filesystem, or read values
994 839642c2 Iustin Pop
        from the current system the are expected to differ between
995 839642c2 Iustin Pop
        nodes, since it is only run once at instance startup;
996 839642c2 Iustin Pop
        actions/kvm arguments that can vary between systems should be
997 839642c2 Iustin Pop
        done in L{_ExecuteKVMRuntime}
998 839642c2 Iustin Pop

999 eb58f9b1 Guido Trotter
    """
1000 b6267745 Andrea Spadaccini
    # pylint: disable=R0914,R0915
1001 440351f8 Andrea Spadaccini
    _, v_major, v_min, _ = self._GetKVMVersion()
1002 4304964a Guido Trotter
1003 e687ec01 Michael Hanselmann
    pidfile = self._InstancePidFile(instance.name)
1004 eb58f9b1 Guido Trotter
    kvm = constants.KVM_PATH
1005 eb58f9b1 Guido Trotter
    kvm_cmd = [kvm]
1006 c6a39fc2 Guido Trotter
    # used just by the vnc server, if enabled
1007 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-name", instance.name])
1008 f5a4b9ce Guido Trotter
    kvm_cmd.extend(["-m", instance.beparams[constants.BE_MAXMEM]])
1009 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-smp", instance.beparams[constants.BE_VCPUS]])
1010 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-pidfile", pidfile])
1011 fcf5b670 Guido Trotter
    kvm_cmd.extend(["-balloon", "virtio"])
1012 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-daemonize"])
1013 6b5605e8 Iustin Pop
    if not instance.hvparams[constants.HV_ACPI]:
1014 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-no-acpi"])
1015 990ade2d Stephen Shirley
    if instance.hvparams[constants.HV_REBOOT_BEHAVIOR] == \
1016 990ade2d Stephen Shirley
        constants.INSTANCE_REBOOT_EXIT:
1017 990ade2d Stephen Shirley
      kvm_cmd.extend(["-no-reboot"])
1018 eb58f9b1 Guido Trotter
1019 a985b417 Iustin Pop
    hvp = instance.hvparams
1020 2b846304 Iustin Pop
    kernel_path = hvp[constants.HV_KERNEL_PATH]
1021 2b846304 Iustin Pop
    if kernel_path:
1022 2b846304 Iustin Pop
      boot_disk = boot_cdrom = boot_floppy = boot_network = False
1023 2b846304 Iustin Pop
    else:
1024 2b846304 Iustin Pop
      boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK
1025 2b846304 Iustin Pop
      boot_cdrom = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_CDROM
1026 2b846304 Iustin Pop
      boot_floppy = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_FLOPPY
1027 2b846304 Iustin Pop
      boot_network = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_NETWORK
1028 8745c3d7 Guido Trotter
1029 b1cb62bd Andrea Spadaccini
    self.ValidateParameters(hvp)
1030 b1cb62bd Andrea Spadaccini
1031 b693125f Tsachy Shacham
    if startup_paused:
1032 b693125f Tsachy Shacham
      kvm_cmd.extend([_KVM_START_PAUSED_FLAG])
1033 b693125f Tsachy Shacham
1034 7ba594c0 Guido Trotter
    if hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED:
1035 7ba594c0 Guido Trotter
      kvm_cmd.extend(["-enable-kvm"])
1036 7ba594c0 Guido Trotter
    elif hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_DISABLED:
1037 7ba594c0 Guido Trotter
      kvm_cmd.extend(["-disable-kvm"])
1038 7ba594c0 Guido Trotter
1039 8745c3d7 Guido Trotter
    if boot_network:
1040 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-boot", "n"])
1041 1213604d Guido Trotter
1042 24be50e0 Iustin Pop
    # whether this is an older KVM version that uses the boot=on flag
1043 24be50e0 Iustin Pop
    # on devices
1044 24be50e0 Iustin Pop
    needs_boot_flag = (v_major, v_min) < (0, 14)
1045 24be50e0 Iustin Pop
1046 a985b417 Iustin Pop
    disk_type = hvp[constants.HV_DISK_TYPE]
1047 1213604d Guido Trotter
    if disk_type == constants.HT_DISK_PARAVIRTUAL:
1048 d0c8c01d Iustin Pop
      if_val = ",if=virtio"
1049 1213604d Guido Trotter
    else:
1050 d0c8c01d Iustin Pop
      if_val = ",if=%s" % disk_type
1051 19572932 Iustin Pop
    # Cache mode
1052 19572932 Iustin Pop
    disk_cache = hvp[constants.HV_DISK_CACHE]
1053 41e794f6 Apollon Oikonomopoulos
    if instance.disk_template in constants.DTS_EXT_MIRROR:
1054 41e794f6 Apollon Oikonomopoulos
      if disk_cache != "none":
1055 41e794f6 Apollon Oikonomopoulos
        # TODO: make this a hard error, instead of a silent overwrite
1056 41e794f6 Apollon Oikonomopoulos
        logging.warning("KVM: overriding disk_cache setting '%s' with 'none'"
1057 41e794f6 Apollon Oikonomopoulos
                        " to prevent shared storage corruption on migration",
1058 41e794f6 Apollon Oikonomopoulos
                        disk_cache)
1059 41e794f6 Apollon Oikonomopoulos
      cache_val = ",cache=none"
1060 41e794f6 Apollon Oikonomopoulos
    elif disk_cache != constants.HT_CACHE_DEFAULT:
1061 19572932 Iustin Pop
      cache_val = ",cache=%s" % disk_cache
1062 19572932 Iustin Pop
    else:
1063 19572932 Iustin Pop
      cache_val = ""
1064 069cfbf1 Iustin Pop
    for cfdev, dev_path in block_devices:
1065 d34b16d7 Iustin Pop
      if cfdev.mode != constants.DISK_RDWR:
1066 d34b16d7 Iustin Pop
        raise errors.HypervisorError("Instance has read-only disks which"
1067 d34b16d7 Iustin Pop
                                     " are not supported by KVM")
1068 eb58f9b1 Guido Trotter
      # TODO: handle FD_LOOP and FD_BLKTAP (?)
1069 4304964a Guido Trotter
      boot_val = ""
1070 66d5dbef Guido Trotter
      if boot_disk:
1071 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-boot", "c"])
1072 66d5dbef Guido Trotter
        boot_disk = False
1073 24be50e0 Iustin Pop
        if needs_boot_flag and disk_type != constants.HT_DISK_IDE:
1074 4304964a Guido Trotter
          boot_val = ",boot=on"
1075 eb58f9b1 Guido Trotter
1076 d0c8c01d Iustin Pop
      drive_val = "file=%s,format=raw%s%s%s" % (dev_path, if_val, boot_val,
1077 19572932 Iustin Pop
                                                cache_val)
1078 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1079 eb58f9b1 Guido Trotter
1080 cc130cc7 Marco Casavecchia
    #Now we can specify a different device type for CDROM devices.
1081 cc130cc7 Marco Casavecchia
    cdrom_disk_type = hvp[constants.HV_KVM_CDROM_DISK_TYPE]
1082 cc130cc7 Marco Casavecchia
    if not cdrom_disk_type:
1083 cc130cc7 Marco Casavecchia
      cdrom_disk_type = disk_type
1084 cc130cc7 Marco Casavecchia
1085 a985b417 Iustin Pop
    iso_image = hvp[constants.HV_CDROM_IMAGE_PATH]
1086 66d5dbef Guido Trotter
    if iso_image:
1087 d0c8c01d Iustin Pop
      options = ",format=raw,media=cdrom"
1088 24be50e0 Iustin Pop
      # set cdrom 'if' type
1089 66d5dbef Guido Trotter
      if boot_cdrom:
1090 24be50e0 Iustin Pop
        actual_cdrom_type = constants.HT_DISK_IDE
1091 24be50e0 Iustin Pop
      elif cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
1092 24be50e0 Iustin Pop
        actual_cdrom_type = "virtio"
1093 9dd363eb Guido Trotter
      else:
1094 24be50e0 Iustin Pop
        actual_cdrom_type = cdrom_disk_type
1095 24be50e0 Iustin Pop
      if_val = ",if=%s" % actual_cdrom_type
1096 24be50e0 Iustin Pop
      # set boot flag, if needed
1097 24be50e0 Iustin Pop
      boot_val = ""
1098 24be50e0 Iustin Pop
      if boot_cdrom:
1099 24be50e0 Iustin Pop
        kvm_cmd.extend(["-boot", "d"])
1100 24be50e0 Iustin Pop
        if needs_boot_flag:
1101 24be50e0 Iustin Pop
          boot_val = ",boot=on"
1102 24be50e0 Iustin Pop
      # and finally build the entire '-drive' value
1103 24be50e0 Iustin Pop
      drive_val = "file=%s%s%s%s" % (iso_image, options, if_val, boot_val)
1104 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1105 66d5dbef Guido Trotter
1106 cc130cc7 Marco Casavecchia
    iso_image2 = hvp[constants.HV_KVM_CDROM2_IMAGE_PATH]
1107 cc130cc7 Marco Casavecchia
    if iso_image2:
1108 d0c8c01d Iustin Pop
      options = ",format=raw,media=cdrom"
1109 cc130cc7 Marco Casavecchia
      if cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
1110 d0c8c01d Iustin Pop
        if_val = ",if=virtio"
1111 cc130cc7 Marco Casavecchia
      else:
1112 d0c8c01d Iustin Pop
        if_val = ",if=%s" % cdrom_disk_type
1113 24be50e0 Iustin Pop
      drive_val = "file=%s%s%s" % (iso_image2, options, if_val)
1114 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1115 cc130cc7 Marco Casavecchia
1116 cc130cc7 Marco Casavecchia
    floppy_image = hvp[constants.HV_KVM_FLOPPY_IMAGE_PATH]
1117 cc130cc7 Marco Casavecchia
    if floppy_image:
1118 d0c8c01d Iustin Pop
      options = ",format=raw,media=disk"
1119 cc130cc7 Marco Casavecchia
      if boot_floppy:
1120 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-boot", "a"])
1121 d0c8c01d Iustin Pop
        options = "%s,boot=on" % options
1122 d0c8c01d Iustin Pop
      if_val = ",if=floppy"
1123 d0c8c01d Iustin Pop
      options = "%s%s" % (options, if_val)
1124 d0c8c01d Iustin Pop
      drive_val = "file=%s%s" % (floppy_image, options)
1125 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
1126 cc130cc7 Marco Casavecchia
1127 df5ab9f0 Guido Trotter
    if kernel_path:
1128 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-kernel", kernel_path])
1129 a985b417 Iustin Pop
      initrd_path = hvp[constants.HV_INITRD_PATH]
1130 df5ab9f0 Guido Trotter
      if initrd_path:
1131 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-initrd", initrd_path])
1132 d0c8c01d Iustin Pop
      root_append = ["root=%s" % hvp[constants.HV_ROOT_PATH],
1133 07813a9e Iustin Pop
                     hvp[constants.HV_KERNEL_ARGS]]
1134 07813a9e Iustin Pop
      if hvp[constants.HV_SERIAL_CONSOLE]:
1135 d0c8c01d Iustin Pop
        root_append.append("console=ttyS0,38400")
1136 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-append", " ".join(root_append)])
1137 eb58f9b1 Guido Trotter
1138 4f958b0b Miguel Di Ciurcio Filho
    mem_path = hvp[constants.HV_MEM_PATH]
1139 4f958b0b Miguel Di Ciurcio Filho
    if mem_path:
1140 9d3015f9 Guido Trotter
      kvm_cmd.extend(["-mem-path", mem_path, "-mem-prealloc"])
1141 4f958b0b Miguel Di Ciurcio Filho
1142 596b2459 Guido Trotter
    monitor_dev = ("unix:%s,server,nowait" %
1143 596b2459 Guido Trotter
                   self._InstanceMonitor(instance.name))
1144 596b2459 Guido Trotter
    kvm_cmd.extend(["-monitor", monitor_dev])
1145 596b2459 Guido Trotter
    if hvp[constants.HV_SERIAL_CONSOLE]:
1146 596b2459 Guido Trotter
      serial_dev = ("unix:%s,server,nowait" %
1147 596b2459 Guido Trotter
                    self._InstanceSerial(instance.name))
1148 596b2459 Guido Trotter
      kvm_cmd.extend(["-serial", serial_dev])
1149 596b2459 Guido Trotter
    else:
1150 596b2459 Guido Trotter
      kvm_cmd.extend(["-serial", "none"])
1151 596b2459 Guido Trotter
1152 a985b417 Iustin Pop
    mouse_type = hvp[constants.HV_USB_MOUSE]
1153 31f6f67a Guido Trotter
    vnc_bind_address = hvp[constants.HV_VNC_BIND_ADDRESS]
1154 596b2459 Guido Trotter
    spice_bind = hvp[constants.HV_KVM_SPICE_BIND]
1155 596b2459 Guido Trotter
    spice_ip_version = None
1156 31f6f67a Guido Trotter
1157 11344a50 Guido Trotter
    if mouse_type:
1158 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usb"])
1159 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usbdevice", mouse_type])
1160 31f6f67a Guido Trotter
    elif vnc_bind_address:
1161 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usbdevice", constants.HT_MOUSE_TABLET])
1162 11344a50 Guido Trotter
1163 8470c8db Guido Trotter
    if vnc_bind_address:
1164 8b312c1d Manuel Franceschini
      if netutils.IP4Address.IsValid(vnc_bind_address):
1165 377d74c9 Guido Trotter
        if instance.network_port > constants.VNC_BASE_PORT:
1166 377d74c9 Guido Trotter
          display = instance.network_port - constants.VNC_BASE_PORT
1167 14f5f1b6 Manuel Franceschini
          if vnc_bind_address == constants.IP4_ADDRESS_ANY:
1168 d0c8c01d Iustin Pop
            vnc_arg = ":%d" % (display)
1169 8447f52b Guido Trotter
          else:
1170 d0c8c01d Iustin Pop
            vnc_arg = "%s:%d" % (vnc_bind_address, display)
1171 8470c8db Guido Trotter
        else:
1172 8447f52b Guido Trotter
          logging.error("Network port is not a valid VNC display (%d < %d)."
1173 07b8a2b5 Iustin Pop
                        " Not starting VNC", instance.network_port,
1174 07b8a2b5 Iustin Pop
                        constants.VNC_BASE_PORT)
1175 d0c8c01d Iustin Pop
          vnc_arg = "none"
1176 8b2d1013 Guido Trotter
1177 8b2d1013 Guido Trotter
        # Only allow tls and other option when not binding to a file, for now.
1178 8b2d1013 Guido Trotter
        # kvm/qemu gets confused otherwise about the filename to use.
1179 d0c8c01d Iustin Pop
        vnc_append = ""
1180 a985b417 Iustin Pop
        if hvp[constants.HV_VNC_TLS]:
1181 d0c8c01d Iustin Pop
          vnc_append = "%s,tls" % vnc_append
1182 a985b417 Iustin Pop
          if hvp[constants.HV_VNC_X509_VERIFY]:
1183 d0c8c01d Iustin Pop
            vnc_append = "%s,x509verify=%s" % (vnc_append,
1184 a985b417 Iustin Pop
                                               hvp[constants.HV_VNC_X509])
1185 a985b417 Iustin Pop
          elif hvp[constants.HV_VNC_X509]:
1186 d0c8c01d Iustin Pop
            vnc_append = "%s,x509=%s" % (vnc_append,
1187 a985b417 Iustin Pop
                                         hvp[constants.HV_VNC_X509])
1188 6e6bb8d5 Guido Trotter
        if hvp[constants.HV_VNC_PASSWORD_FILE]:
1189 d0c8c01d Iustin Pop
          vnc_append = "%s,password" % vnc_append
1190 6e6bb8d5 Guido Trotter
1191 d0c8c01d Iustin Pop
        vnc_arg = "%s%s" % (vnc_arg, vnc_append)
1192 8b2d1013 Guido Trotter
1193 8470c8db Guido Trotter
      else:
1194 d0c8c01d Iustin Pop
        vnc_arg = "unix:%s/%s.vnc" % (vnc_bind_address, instance.name)
1195 8b2d1013 Guido Trotter
1196 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-vnc", vnc_arg])
1197 596b2459 Guido Trotter
    elif spice_bind:
1198 839642c2 Iustin Pop
      # FIXME: this is wrong here; the iface ip address differs
1199 839642c2 Iustin Pop
      # between systems, so it should be done in _ExecuteKVMRuntime
1200 b1cb62bd Andrea Spadaccini
      if netutils.IsValidInterface(spice_bind):
1201 b1cb62bd Andrea Spadaccini
        # The user specified a network interface, we have to figure out the IP
1202 b1cb62bd Andrea Spadaccini
        # address.
1203 b1cb62bd Andrea Spadaccini
        addresses = netutils.GetInterfaceIpAddresses(spice_bind)
1204 b1cb62bd Andrea Spadaccini
        spice_ip_version = hvp[constants.HV_KVM_SPICE_IP_VERSION]
1205 b1cb62bd Andrea Spadaccini
1206 b1cb62bd Andrea Spadaccini
        # if the user specified an IP version and the interface does not
1207 b1cb62bd Andrea Spadaccini
        # have that kind of IP addresses, throw an exception
1208 b1cb62bd Andrea Spadaccini
        if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
1209 b1cb62bd Andrea Spadaccini
          if not addresses[spice_ip_version]:
1210 b1cb62bd Andrea Spadaccini
            raise errors.HypervisorError("spice: unable to get an IPv%s address"
1211 b1cb62bd Andrea Spadaccini
                                         " for %s" % (spice_ip_version,
1212 b1cb62bd Andrea Spadaccini
                                                      spice_bind))
1213 b1cb62bd Andrea Spadaccini
1214 b1cb62bd Andrea Spadaccini
        # the user did not specify an IP version, we have to figure it out
1215 b1cb62bd Andrea Spadaccini
        elif (addresses[constants.IP4_VERSION] and
1216 b1cb62bd Andrea Spadaccini
              addresses[constants.IP6_VERSION]):
1217 b1cb62bd Andrea Spadaccini
          # we have both ipv4 and ipv6, let's use the cluster default IP
1218 b1cb62bd Andrea Spadaccini
          # version
1219 b1cb62bd Andrea Spadaccini
          cluster_family = ssconf.SimpleStore().GetPrimaryIPFamily()
1220 65107a2f Michael Hanselmann
          spice_ip_version = \
1221 65107a2f Michael Hanselmann
            netutils.IPAddress.GetVersionFromAddressFamily(cluster_family)
1222 b1cb62bd Andrea Spadaccini
        elif addresses[constants.IP4_VERSION]:
1223 b1cb62bd Andrea Spadaccini
          spice_ip_version = constants.IP4_VERSION
1224 b845c8a1 Andrea Spadaccini
        elif addresses[constants.IP6_VERSION]:
1225 b1cb62bd Andrea Spadaccini
          spice_ip_version = constants.IP6_VERSION
1226 b845c8a1 Andrea Spadaccini
        else:
1227 b845c8a1 Andrea Spadaccini
          raise errors.HypervisorError("spice: unable to get an IP address"
1228 b845c8a1 Andrea Spadaccini
                                       " for %s" % (spice_bind))
1229 b1cb62bd Andrea Spadaccini
1230 b1cb62bd Andrea Spadaccini
        spice_address = addresses[spice_ip_version][0]
1231 b1cb62bd Andrea Spadaccini
1232 b1cb62bd Andrea Spadaccini
      else:
1233 b1cb62bd Andrea Spadaccini
        # spice_bind is known to be a valid IP address, because
1234 b1cb62bd Andrea Spadaccini
        # ValidateParameters checked it.
1235 b1cb62bd Andrea Spadaccini
        spice_address = spice_bind
1236 b1cb62bd Andrea Spadaccini
1237 bfe86c76 Andrea Spadaccini
      spice_arg = "addr=%s" % spice_address
1238 bfe86c76 Andrea Spadaccini
      if hvp[constants.HV_KVM_SPICE_USE_TLS]:
1239 5ae4945a Iustin Pop
        spice_arg = ("%s,tls-port=%s,x509-cacert-file=%s" %
1240 5ae4945a Iustin Pop
                     (spice_arg, instance.network_port,
1241 9d9bded1 Michael Hanselmann
                      pathutils.SPICE_CACERT_FILE))
1242 5ae4945a Iustin Pop
        spice_arg = ("%s,x509-key-file=%s,x509-cert-file=%s" %
1243 9d9bded1 Michael Hanselmann
                     (spice_arg, pathutils.SPICE_CERT_FILE,
1244 9d9bded1 Michael Hanselmann
                      pathutils.SPICE_CERT_FILE))
1245 3e40b587 Andrea Spadaccini
        tls_ciphers = hvp[constants.HV_KVM_SPICE_TLS_CIPHERS]
1246 3e40b587 Andrea Spadaccini
        if tls_ciphers:
1247 3e40b587 Andrea Spadaccini
          spice_arg = "%s,tls-ciphers=%s" % (spice_arg, tls_ciphers)
1248 bfe86c76 Andrea Spadaccini
      else:
1249 bfe86c76 Andrea Spadaccini
        spice_arg = "%s,port=%s" % (spice_arg, instance.network_port)
1250 bfe86c76 Andrea Spadaccini
1251 b451c4c7 Andrea Spadaccini
      if not hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]:
1252 b451c4c7 Andrea Spadaccini
        spice_arg = "%s,disable-ticketing" % spice_arg
1253 b451c4c7 Andrea Spadaccini
1254 11ae7a0a Andrea Spadaccini
      if spice_ip_version:
1255 11ae7a0a Andrea Spadaccini
        spice_arg = "%s,ipv%s" % (spice_arg, spice_ip_version)
1256 b1cb62bd Andrea Spadaccini
1257 ea064d24 Andrea Spadaccini
      # Image compression options
1258 ea064d24 Andrea Spadaccini
      img_lossless = hvp[constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR]
1259 ea064d24 Andrea Spadaccini
      img_jpeg = hvp[constants.HV_KVM_SPICE_JPEG_IMG_COMPR]
1260 ea064d24 Andrea Spadaccini
      img_zlib_glz = hvp[constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR]
1261 ea064d24 Andrea Spadaccini
      if img_lossless:
1262 ea064d24 Andrea Spadaccini
        spice_arg = "%s,image-compression=%s" % (spice_arg, img_lossless)
1263 ea064d24 Andrea Spadaccini
      if img_jpeg:
1264 ea064d24 Andrea Spadaccini
        spice_arg = "%s,jpeg-wan-compression=%s" % (spice_arg, img_jpeg)
1265 ea064d24 Andrea Spadaccini
      if img_zlib_glz:
1266 ea064d24 Andrea Spadaccini
        spice_arg = "%s,zlib-glz-wan-compression=%s" % (spice_arg, img_zlib_glz)
1267 ea064d24 Andrea Spadaccini
1268 ea064d24 Andrea Spadaccini
      # Video stream detection
1269 ea064d24 Andrea Spadaccini
      video_streaming = hvp[constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION]
1270 ea064d24 Andrea Spadaccini
      if video_streaming:
1271 ea064d24 Andrea Spadaccini
        spice_arg = "%s,streaming-video=%s" % (spice_arg, video_streaming)
1272 ea064d24 Andrea Spadaccini
1273 ea064d24 Andrea Spadaccini
      # Audio compression, by default in qemu-kvm it is on
1274 ea064d24 Andrea Spadaccini
      if not hvp[constants.HV_KVM_SPICE_AUDIO_COMPR]:
1275 ea064d24 Andrea Spadaccini
        spice_arg = "%s,playback-compression=off" % spice_arg
1276 3e40b587 Andrea Spadaccini
      if not hvp[constants.HV_KVM_SPICE_USE_VDAGENT]:
1277 3e40b587 Andrea Spadaccini
        spice_arg = "%s,agent-mouse=off" % spice_arg
1278 447af814 Nikos Skalkotos
      else:
1279 447af814 Nikos Skalkotos
        # Enable the spice agent communication channel between the host and the
1280 447af814 Nikos Skalkotos
        # agent.
1281 447af814 Nikos Skalkotos
        kvm_cmd.extend(["-device", "virtio-serial-pci"])
1282 447af814 Nikos Skalkotos
        kvm_cmd.extend(["-device", "virtserialport,chardev=spicechannel0,"
1283 447af814 Nikos Skalkotos
                                                   "name=com.redhat.spice.0"])
1284 447af814 Nikos Skalkotos
        kvm_cmd.extend(["-chardev", "spicevmc,id=spicechannel0,name=vdagent"])
1285 ea064d24 Andrea Spadaccini
1286 b1cb62bd Andrea Spadaccini
      logging.info("KVM: SPICE will listen on port %s", instance.network_port)
1287 b1cb62bd Andrea Spadaccini
      kvm_cmd.extend(["-spice", spice_arg])
1288 b1cb62bd Andrea Spadaccini
1289 2ebdfbb5 Andrea Spadaccini
      # Tell kvm to use the paravirtualized graphic card, optimized for SPICE
1290 2ebdfbb5 Andrea Spadaccini
      kvm_cmd.extend(["-vga", "qxl"])
1291 2ebdfbb5 Andrea Spadaccini
1292 596b2459 Guido Trotter
    else:
1293 596b2459 Guido Trotter
      kvm_cmd.extend(["-nographic"])
1294 596b2459 Guido Trotter
1295 6b970cef Jun Futagawa
    if hvp[constants.HV_USE_LOCALTIME]:
1296 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-localtime"])
1297 6b970cef Jun Futagawa
1298 547a63b7 Balazs Lecz
    if hvp[constants.HV_KVM_USE_CHROOT]:
1299 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-chroot", self._InstanceChrootDir(instance.name)])
1300 547a63b7 Balazs Lecz
1301 7cb42171 Nikita Staroverov
    # Add qemu-KVM -cpu param
1302 7cb42171 Nikita Staroverov
    if hvp[constants.HV_CPU_TYPE]:
1303 7cb42171 Nikita Staroverov
      kvm_cmd.extend(["-cpu", hvp[constants.HV_CPU_TYPE]])
1304 7cb42171 Nikita Staroverov
1305 ee5f20b0 Guido Trotter
    # Save the current instance nics, but defer their expansion as parameters,
1306 ee5f20b0 Guido Trotter
    # as we'll need to generate executable temp files for them.
1307 ee5f20b0 Guido Trotter
    kvm_nics = instance.nics
1308 a985b417 Iustin Pop
    hvparams = hvp
1309 ee5f20b0 Guido Trotter
1310 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
1311 ee5f20b0 Guido Trotter
1312 38e250ba Guido Trotter
  def _WriteKVMRuntime(self, instance_name, data):
1313 38e250ba Guido Trotter
    """Write an instance's KVM runtime
1314 38e250ba Guido Trotter

1315 38e250ba Guido Trotter
    """
1316 38e250ba Guido Trotter
    try:
1317 38e250ba Guido Trotter
      utils.WriteFile(self._InstanceKVMRuntime(instance_name),
1318 38e250ba Guido Trotter
                      data=data)
1319 90c024f6 Guido Trotter
    except EnvironmentError, err:
1320 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to save KVM runtime file: %s" % err)
1321 38e250ba Guido Trotter
1322 38e250ba Guido Trotter
  def _ReadKVMRuntime(self, instance_name):
1323 38e250ba Guido Trotter
    """Read an instance's KVM runtime
1324 38e250ba Guido Trotter

1325 38e250ba Guido Trotter
    """
1326 38e250ba Guido Trotter
    try:
1327 38e250ba Guido Trotter
      file_content = utils.ReadFile(self._InstanceKVMRuntime(instance_name))
1328 90c024f6 Guido Trotter
    except EnvironmentError, err:
1329 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to load KVM runtime file: %s" % err)
1330 38e250ba Guido Trotter
    return file_content
1331 38e250ba Guido Trotter
1332 38e250ba Guido Trotter
  def _SaveKVMRuntime(self, instance, kvm_runtime):
1333 38e250ba Guido Trotter
    """Save an instance's KVM runtime
1334 38e250ba Guido Trotter

1335 38e250ba Guido Trotter
    """
1336 c2672466 Guido Trotter
    kvm_cmd, kvm_nics, hvparams = kvm_runtime
1337 38e250ba Guido Trotter
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
1338 c2672466 Guido Trotter
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams))
1339 38e250ba Guido Trotter
    self._WriteKVMRuntime(instance.name, serialized_form)
1340 38e250ba Guido Trotter
1341 30e42c4e Guido Trotter
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
1342 38e250ba Guido Trotter
    """Load an instance's KVM runtime
1343 38e250ba Guido Trotter

1344 38e250ba Guido Trotter
    """
1345 30e42c4e Guido Trotter
    if not serialized_runtime:
1346 30e42c4e Guido Trotter
      serialized_runtime = self._ReadKVMRuntime(instance.name)
1347 30e42c4e Guido Trotter
    loaded_runtime = serializer.Load(serialized_runtime)
1348 c2672466 Guido Trotter
    kvm_cmd, serialized_nics, hvparams = loaded_runtime
1349 38e250ba Guido Trotter
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
1350 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
1351 38e250ba Guido Trotter
1352 5d9bfd87 Apollon Oikonomopoulos
  def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None):
1353 76431533 Guido Trotter
    """Run the KVM cmd and check for errors
1354 76431533 Guido Trotter

1355 76431533 Guido Trotter
    @type name: string
1356 76431533 Guido Trotter
    @param name: instance name
1357 76431533 Guido Trotter
    @type kvm_cmd: list of strings
1358 76431533 Guido Trotter
    @param kvm_cmd: runcmd input for kvm
1359 5d9bfd87 Apollon Oikonomopoulos
    @type tap_fds: list of int
1360 5d9bfd87 Apollon Oikonomopoulos
    @param tap_fds: fds of tap devices opened by Ganeti
1361 76431533 Guido Trotter

1362 76431533 Guido Trotter
    """
1363 5d9bfd87 Apollon Oikonomopoulos
    try:
1364 5d9bfd87 Apollon Oikonomopoulos
      result = utils.RunCmd(kvm_cmd, noclose_fds=tap_fds)
1365 5d9bfd87 Apollon Oikonomopoulos
    finally:
1366 5d9bfd87 Apollon Oikonomopoulos
      for fd in tap_fds:
1367 5d9bfd87 Apollon Oikonomopoulos
        utils_wrapper.CloseFdNoError(fd)
1368 5d9bfd87 Apollon Oikonomopoulos
1369 76431533 Guido Trotter
    if result.failed:
1370 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
1371 76431533 Guido Trotter
                                   (name, result.fail_reason, result.output))
1372 76431533 Guido Trotter
    if not self._InstancePidAlive(name)[2]:
1373 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s" % name)
1374 76431533 Guido Trotter
1375 30e42c4e Guido Trotter
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, incoming=None):
1376 839642c2 Iustin Pop
    """Execute a KVM cmd, after completing it with some last minute data.
1377 ee5f20b0 Guido Trotter

1378 30e42c4e Guido Trotter
    @type incoming: tuple of strings
1379 30e42c4e Guido Trotter
    @param incoming: (target_host_ip, port)
1380 30e42c4e Guido Trotter

1381 ee5f20b0 Guido Trotter
    """
1382 297e6e53 Guido Trotter
    # Small _ExecuteKVMRuntime hv parameters programming howto:
1383 297e6e53 Guido Trotter
    #  - conf_hvp contains the parameters as configured on ganeti. they might
1384 297e6e53 Guido Trotter
    #    have changed since the instance started; only use them if the change
1385 297e6e53 Guido Trotter
    #    won't affect the inside of the instance (which hasn't been rebooted).
1386 297e6e53 Guido Trotter
    #  - up_hvp contains the parameters as they were when the instance was
1387 297e6e53 Guido Trotter
    #    started, plus any new parameter which has been added between ganeti
1388 297e6e53 Guido Trotter
    #    versions: it is paramount that those default to a value which won't
1389 297e6e53 Guido Trotter
    #    affect the inside of the instance as well.
1390 297e6e53 Guido Trotter
    conf_hvp = instance.hvparams
1391 5905901c Iustin Pop
    name = instance.name
1392 5905901c Iustin Pop
    self._CheckDown(name)
1393 ee5f20b0 Guido Trotter
1394 ee5f20b0 Guido Trotter
    temp_files = []
1395 ee5f20b0 Guido Trotter
1396 297e6e53 Guido Trotter
    kvm_cmd, kvm_nics, up_hvp = kvm_runtime
1397 297e6e53 Guido Trotter
    up_hvp = objects.FillDict(conf_hvp, up_hvp)
1398 ee5f20b0 Guido Trotter
1399 440351f8 Andrea Spadaccini
    _, v_major, v_min, _ = self._GetKVMVersion()
1400 4b784cf8 Miguel Di Ciurcio Filho
1401 297e6e53 Guido Trotter
    # We know it's safe to run as a different user upon migration, so we'll use
1402 297e6e53 Guido Trotter
    # the latest conf, from conf_hvp.
1403 297e6e53 Guido Trotter
    security_model = conf_hvp[constants.HV_SECURITY_MODEL]
1404 cef34868 Guido Trotter
    if security_model == constants.HT_SM_USER:
1405 297e6e53 Guido Trotter
      kvm_cmd.extend(["-runas", conf_hvp[constants.HV_SECURITY_DOMAIN]])
1406 cef34868 Guido Trotter
1407 839642c2 Iustin Pop
    keymap = conf_hvp[constants.HV_KEYMAP]
1408 839642c2 Iustin Pop
    if keymap:
1409 839642c2 Iustin Pop
      keymap_path = self._InstanceKeymapFile(name)
1410 839642c2 Iustin Pop
      # If a keymap file is specified, KVM won't use its internal defaults. By
1411 839642c2 Iustin Pop
      # first including the "en-us" layout, an error on loading the actual
1412 839642c2 Iustin Pop
      # layout (e.g. because it can't be found) won't lead to a non-functional
1413 839642c2 Iustin Pop
      # keyboard. A keyboard with incorrect keys is still better than none.
1414 839642c2 Iustin Pop
      utils.WriteFile(keymap_path, data="include en-us\ninclude %s\n" % keymap)
1415 839642c2 Iustin Pop
      kvm_cmd.extend(["-k", keymap_path])
1416 839642c2 Iustin Pop
1417 297e6e53 Guido Trotter
    # We have reasons to believe changing something like the nic driver/type
1418 297e6e53 Guido Trotter
    # upon migration won't exactly fly with the instance kernel, so for nic
1419 297e6e53 Guido Trotter
    # related parameters we'll use up_hvp
1420 5d9bfd87 Apollon Oikonomopoulos
    tapfds = []
1421 5d9bfd87 Apollon Oikonomopoulos
    taps = []
1422 ee5f20b0 Guido Trotter
    if not kvm_nics:
1423 fbe27e2b Guido Trotter
      kvm_cmd.extend(["-net", "none"])
1424 ee5f20b0 Guido Trotter
    else:
1425 5d9bfd87 Apollon Oikonomopoulos
      vnet_hdr = False
1426 fbe27e2b Guido Trotter
      tap_extra = ""
1427 297e6e53 Guido Trotter
      nic_type = up_hvp[constants.HV_NIC_TYPE]
1428 37f88dc6 Guido Trotter
      if nic_type == constants.HT_NIC_PARAVIRTUAL:
1429 4b784cf8 Miguel Di Ciurcio Filho
        # From version 0.12.0, kvm uses a new sintax for network configuration.
1430 049383d9 Adeodato Simo
        if (v_major, v_min) >= (0, 12):
1431 4b784cf8 Miguel Di Ciurcio Filho
          nic_model = "virtio-net-pci"
1432 5d9bfd87 Apollon Oikonomopoulos
          vnet_hdr = True
1433 4b784cf8 Miguel Di Ciurcio Filho
        else:
1434 4b784cf8 Miguel Di Ciurcio Filho
          nic_model = "virtio"
1435 4b784cf8 Miguel Di Ciurcio Filho
1436 297e6e53 Guido Trotter
        if up_hvp[constants.HV_VHOST_NET]:
1437 4b784cf8 Miguel Di Ciurcio Filho
          # vhost_net is only available from version 0.13.0 or newer
1438 049383d9 Adeodato Simo
          if (v_major, v_min) >= (0, 13):
1439 4b784cf8 Miguel Di Ciurcio Filho
            tap_extra = ",vhost=on"
1440 4b784cf8 Miguel Di Ciurcio Filho
          else:
1441 4b784cf8 Miguel Di Ciurcio Filho
            raise errors.HypervisorError("vhost_net is configured"
1442 5ae4945a Iustin Pop
                                         " but it is not available")
1443 37f88dc6 Guido Trotter
      else:
1444 4b784cf8 Miguel Di Ciurcio Filho
        nic_model = nic_type
1445 37f88dc6 Guido Trotter
1446 ee5f20b0 Guido Trotter
      for nic_seq, nic in enumerate(kvm_nics):
1447 5d9bfd87 Apollon Oikonomopoulos
        tapname, tapfd = _OpenTap(vnet_hdr)
1448 5d9bfd87 Apollon Oikonomopoulos
        tapfds.append(tapfd)
1449 5d9bfd87 Apollon Oikonomopoulos
        taps.append(tapname)
1450 049383d9 Adeodato Simo
        if (v_major, v_min) >= (0, 12):
1451 4b784cf8 Miguel Di Ciurcio Filho
          nic_val = "%s,mac=%s,netdev=netdev%s" % (nic_model, nic.mac, nic_seq)
1452 5d9bfd87 Apollon Oikonomopoulos
          tap_val = "type=tap,id=netdev%s,fd=%d%s" % (nic_seq, tapfd, tap_extra)
1453 4b784cf8 Miguel Di Ciurcio Filho
          kvm_cmd.extend(["-netdev", tap_val, "-device", nic_val])
1454 4b784cf8 Miguel Di Ciurcio Filho
        else:
1455 049383d9 Adeodato Simo
          nic_val = "nic,vlan=%s,macaddr=%s,model=%s" % (nic_seq,
1456 049383d9 Adeodato Simo
                                                         nic.mac, nic_model)
1457 5d9bfd87 Apollon Oikonomopoulos
          tap_val = "tap,vlan=%s,fd=%d" % (nic_seq, tapfd)
1458 4b784cf8 Miguel Di Ciurcio Filho
          kvm_cmd.extend(["-net", tap_val, "-net", nic_val])
1459 ee5f20b0 Guido Trotter
1460 30e42c4e Guido Trotter
    if incoming:
1461 30e42c4e Guido Trotter
      target, port = incoming
1462 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-incoming", "tcp:%s:%s" % (target, port)])
1463 30e42c4e Guido Trotter
1464 297e6e53 Guido Trotter
    # Changing the vnc password doesn't bother the guest that much. At most it
1465 297e6e53 Guido Trotter
    # will surprise people who connect to it. Whether positively or negatively
1466 297e6e53 Guido Trotter
    # it's debatable.
1467 297e6e53 Guido Trotter
    vnc_pwd_file = conf_hvp[constants.HV_VNC_PASSWORD_FILE]
1468 6e6bb8d5 Guido Trotter
    vnc_pwd = None
1469 6e6bb8d5 Guido Trotter
    if vnc_pwd_file:
1470 6e6bb8d5 Guido Trotter
      try:
1471 682f7601 Guido Trotter
        vnc_pwd = utils.ReadOneLineFile(vnc_pwd_file, strict=True)
1472 6e6bb8d5 Guido Trotter
      except EnvironmentError, err:
1473 6e6bb8d5 Guido Trotter
        raise errors.HypervisorError("Failed to open VNC password file %s: %s"
1474 6e6bb8d5 Guido Trotter
                                     % (vnc_pwd_file, err))
1475 6e6bb8d5 Guido Trotter
1476 297e6e53 Guido Trotter
    if conf_hvp[constants.HV_KVM_USE_CHROOT]:
1477 547a63b7 Balazs Lecz
      utils.EnsureDirs([(self._InstanceChrootDir(name),
1478 547a63b7 Balazs Lecz
                         constants.SECURE_DIR_MODE)])
1479 547a63b7 Balazs Lecz
1480 91c10532 Andrea Spadaccini
    # Automatically enable QMP if version is >= 0.14
1481 91c10532 Andrea Spadaccini
    if (v_major, v_min) >= (0, 14):
1482 91c10532 Andrea Spadaccini
      logging.debug("Enabling QMP")
1483 91c10532 Andrea Spadaccini
      kvm_cmd.extend(["-qmp", "unix:%s,server,nowait" %
1484 5ae4945a Iustin Pop
                      self._InstanceQmpMonitor(instance.name)])
1485 91c10532 Andrea Spadaccini
1486 cc8a8ed7 Apollon Oikonomopoulos
    # Configure the network now for starting instances and bridged interfaces,
1487 cc8a8ed7 Apollon Oikonomopoulos
    # during FinalizeMigration for incoming instances' routed interfaces
1488 cc8a8ed7 Apollon Oikonomopoulos
    for nic_seq, nic in enumerate(kvm_nics):
1489 cc8a8ed7 Apollon Oikonomopoulos
      if (incoming and
1490 cc8a8ed7 Apollon Oikonomopoulos
          nic.nicparams[constants.NIC_MODE] != constants.NIC_MODE_BRIDGED):
1491 cc8a8ed7 Apollon Oikonomopoulos
        continue
1492 cc8a8ed7 Apollon Oikonomopoulos
      self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
1493 5d9bfd87 Apollon Oikonomopoulos
1494 1d8a7812 Andrea Spadaccini
    # CPU affinity requires kvm to start paused, so we set this flag if the
1495 1d8a7812 Andrea Spadaccini
    # instance is not already paused and if we are not going to accept a
1496 1d8a7812 Andrea Spadaccini
    # migrating instance. In the latter case, pausing is not needed.
1497 1d8a7812 Andrea Spadaccini
    start_kvm_paused = not (_KVM_START_PAUSED_FLAG in kvm_cmd) and not incoming
1498 945a7e67 Guido Trotter
    if start_kvm_paused:
1499 945a7e67 Guido Trotter
      kvm_cmd.extend([_KVM_START_PAUSED_FLAG])
1500 b693125f Tsachy Shacham
1501 b693125f Tsachy Shacham
    # Note: CPU pinning is using up_hvp since changes take effect
1502 b693125f Tsachy Shacham
    # during instance startup anyway, and to avoid problems when soft
1503 b693125f Tsachy Shacham
    # rebooting the instance.
1504 c607b1f7 Tsachy Shacham
    cpu_pinning = False
1505 b693125f Tsachy Shacham
    if up_hvp.get(constants.HV_CPU_MASK, None):
1506 b693125f Tsachy Shacham
      cpu_pinning = True
1507 b693125f Tsachy Shacham
1508 76431533 Guido Trotter
    if security_model == constants.HT_SM_POOL:
1509 76431533 Guido Trotter
      ss = ssconf.SimpleStore()
1510 76431533 Guido Trotter
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n")
1511 76431533 Guido Trotter
      all_uids = set(uidpool.ExpandUidPool(uid_pool))
1512 76431533 Guido Trotter
      uid = uidpool.RequestUnusedUid(all_uids)
1513 76431533 Guido Trotter
      try:
1514 76431533 Guido Trotter
        username = pwd.getpwuid(uid.GetUid()).pw_name
1515 76431533 Guido Trotter
        kvm_cmd.extend(["-runas", username])
1516 5d9bfd87 Apollon Oikonomopoulos
        self._RunKVMCmd(name, kvm_cmd, tapfds)
1517 76431533 Guido Trotter
      except:
1518 76431533 Guido Trotter
        uidpool.ReleaseUid(uid)
1519 76431533 Guido Trotter
        raise
1520 76431533 Guido Trotter
      else:
1521 76431533 Guido Trotter
        uid.Unlock()
1522 3af16328 Apollon Oikonomopoulos
        utils.WriteFile(self._InstanceUidFile(name), data=uid.AsStr())
1523 76431533 Guido Trotter
    else:
1524 5d9bfd87 Apollon Oikonomopoulos
      self._RunKVMCmd(name, kvm_cmd, tapfds)
1525 5d9bfd87 Apollon Oikonomopoulos
1526 5d9bfd87 Apollon Oikonomopoulos
    utils.EnsureDirs([(self._InstanceNICDir(instance.name),
1527 5d9bfd87 Apollon Oikonomopoulos
                     constants.RUN_DIRS_MODE)])
1528 5d9bfd87 Apollon Oikonomopoulos
    for nic_seq, tap in enumerate(taps):
1529 5d9bfd87 Apollon Oikonomopoulos
      utils.WriteFile(self._InstanceNICFile(instance.name, nic_seq),
1530 5d9bfd87 Apollon Oikonomopoulos
                      data=tap)
1531 eb58f9b1 Guido Trotter
1532 6e6bb8d5 Guido Trotter
    if vnc_pwd:
1533 d0c8c01d Iustin Pop
      change_cmd = "change vnc password %s" % vnc_pwd
1534 6e6bb8d5 Guido Trotter
      self._CallMonitorCommand(instance.name, change_cmd)
1535 6e6bb8d5 Guido Trotter
1536 b451c4c7 Andrea Spadaccini
    # Setting SPICE password. We are not vulnerable to malicious passwordless
1537 b451c4c7 Andrea Spadaccini
    # connection attempts because SPICE by default does not allow connections
1538 b451c4c7 Andrea Spadaccini
    # if neither a password nor the "disable_ticketing" options are specified.
1539 b451c4c7 Andrea Spadaccini
    # As soon as we send the password via QMP, that password is a valid ticket
1540 b451c4c7 Andrea Spadaccini
    # for connection.
1541 b451c4c7 Andrea Spadaccini
    spice_password_file = conf_hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]
1542 b451c4c7 Andrea Spadaccini
    if spice_password_file:
1543 fc84cd5d Guido Trotter
      spice_pwd = ""
1544 b451c4c7 Andrea Spadaccini
      try:
1545 b451c4c7 Andrea Spadaccini
        spice_pwd = utils.ReadOneLineFile(spice_password_file, strict=True)
1546 b451c4c7 Andrea Spadaccini
      except EnvironmentError, err:
1547 b451c4c7 Andrea Spadaccini
        raise errors.HypervisorError("Failed to open SPICE password file %s: %s"
1548 b451c4c7 Andrea Spadaccini
                                     % (spice_password_file, err))
1549 b451c4c7 Andrea Spadaccini
1550 fc84cd5d Guido Trotter
      qmp = QmpConnection(self._InstanceQmpMonitor(instance.name))
1551 fc84cd5d Guido Trotter
      qmp.connect()
1552 fc84cd5d Guido Trotter
      arguments = {
1553 fc84cd5d Guido Trotter
          "protocol": "spice",
1554 fc84cd5d Guido Trotter
          "password": spice_pwd,
1555 fc84cd5d Guido Trotter
      }
1556 fc84cd5d Guido Trotter
      qmp.Execute("set_password", arguments)
1557 fc84cd5d Guido Trotter
1558 08137f9e Iustin Pop
    for filename in temp_files:
1559 08137f9e Iustin Pop
      utils.RemoveFile(filename)
1560 eb58f9b1 Guido Trotter
1561 b693125f Tsachy Shacham
    # If requested, set CPU affinity and resume instance execution
1562 b693125f Tsachy Shacham
    if cpu_pinning:
1563 945a7e67 Guido Trotter
      self._ExecuteCpuAffinity(instance.name, up_hvp[constants.HV_CPU_MASK])
1564 945a7e67 Guido Trotter
1565 61eb1a46 Guido Trotter
    start_memory = self._InstanceStartupMemory(instance)
1566 61eb1a46 Guido Trotter
    if start_memory < instance.beparams[constants.BE_MAXMEM]:
1567 61eb1a46 Guido Trotter
      self.BalloonInstanceMemory(instance, start_memory)
1568 61eb1a46 Guido Trotter
1569 945a7e67 Guido Trotter
    if start_kvm_paused:
1570 2ed0e208 Iustin Pop
      # To control CPU pinning, ballooning, and vnc/spice passwords
1571 2ed0e208 Iustin Pop
      # the VM was started in a frozen state. If freezing was not
1572 2ed0e208 Iustin Pop
      # explicitly requested resume the vm status.
1573 945a7e67 Guido Trotter
      self._CallMonitorCommand(instance.name, self._CONT_CMD)
1574 b693125f Tsachy Shacham
1575 323f9095 Stephen Shirley
  def StartInstance(self, instance, block_devices, startup_paused):
1576 ee5f20b0 Guido Trotter
    """Start an instance.
1577 ee5f20b0 Guido Trotter

1578 ee5f20b0 Guido Trotter
    """
1579 5905901c Iustin Pop
    self._CheckDown(instance.name)
1580 7238edb5 Iustin Pop
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices,
1581 7238edb5 Iustin Pop
                                           startup_paused)
1582 38e250ba Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1583 ee5f20b0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
1584 ee5f20b0 Guido Trotter
1585 6567aff3 Guido Trotter
  def _CallMonitorCommand(self, instance_name, command):
1586 6567aff3 Guido Trotter
    """Invoke a command on the instance monitor.
1587 6567aff3 Guido Trotter

1588 6567aff3 Guido Trotter
    """
1589 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
1590 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
1591 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
1592 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
1593 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
1594 6567aff3 Guido Trotter
    if result.failed:
1595 6567aff3 Guido Trotter
      msg = ("Failed to send command '%s' to instance %s."
1596 6567aff3 Guido Trotter
             " output: %s, error: %s, fail_reason: %s" %
1597 9798fcae Guido Trotter
             (command, instance_name,
1598 9798fcae Guido Trotter
              result.stdout, result.stderr, result.fail_reason))
1599 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
1600 6567aff3 Guido Trotter
1601 6567aff3 Guido Trotter
    return result
1602 6567aff3 Guido Trotter
1603 b52d85c1 Guido Trotter
  @classmethod
1604 585c8187 Guido Trotter
  def _ParseKVMVersion(cls, text):
1605 585c8187 Guido Trotter
    """Parse the KVM version from the --help output.
1606 585c8187 Guido Trotter

1607 585c8187 Guido Trotter
    @type text: string
1608 585c8187 Guido Trotter
    @param text: output of kvm --help
1609 585c8187 Guido Trotter
    @return: (version, v_maj, v_min, v_rev)
1610 5c3d5dfd Iustin Pop
    @raise errors.HypervisorError: when the KVM version cannot be retrieved
1611 585c8187 Guido Trotter

1612 585c8187 Guido Trotter
    """
1613 585c8187 Guido Trotter
    match = cls._VERSION_RE.search(text.splitlines()[0])
1614 585c8187 Guido Trotter
    if not match:
1615 585c8187 Guido Trotter
      raise errors.HypervisorError("Unable to get KVM version")
1616 585c8187 Guido Trotter
1617 585c8187 Guido Trotter
    v_all = match.group(0)
1618 585c8187 Guido Trotter
    v_maj = int(match.group(1))
1619 585c8187 Guido Trotter
    v_min = int(match.group(2))
1620 585c8187 Guido Trotter
    if match.group(4):
1621 585c8187 Guido Trotter
      v_rev = int(match.group(4))
1622 585c8187 Guido Trotter
    else:
1623 585c8187 Guido Trotter
      v_rev = 0
1624 585c8187 Guido Trotter
    return (v_all, v_maj, v_min, v_rev)
1625 585c8187 Guido Trotter
1626 585c8187 Guido Trotter
  @classmethod
1627 b52d85c1 Guido Trotter
  def _GetKVMVersion(cls):
1628 d7e4a2b1 Andrea Spadaccini
    """Return the installed KVM version.
1629 b52d85c1 Guido Trotter

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

1633 b52d85c1 Guido Trotter
    """
1634 b52d85c1 Guido Trotter
    result = utils.RunCmd([constants.KVM_PATH, "--help"])
1635 b52d85c1 Guido Trotter
    if result.failed:
1636 440351f8 Andrea Spadaccini
      raise errors.HypervisorError("Unable to get KVM version")
1637 585c8187 Guido Trotter
    return cls._ParseKVMVersion(result.output)
1638 b52d85c1 Guido Trotter
1639 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
1640 eb58f9b1 Guido Trotter
    """Stop an instance.
1641 eb58f9b1 Guido Trotter

1642 eb58f9b1 Guido Trotter
    """
1643 bbcf7ad0 Iustin Pop
    if name is not None and not force:
1644 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
1645 bbcf7ad0 Iustin Pop
    if name is None:
1646 bbcf7ad0 Iustin Pop
      name = instance.name
1647 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
1648 bbcf7ad0 Iustin Pop
    else:
1649 bbcf7ad0 Iustin Pop
      acpi = False
1650 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
1651 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
1652 bbcf7ad0 Iustin Pop
      if force or not acpi:
1653 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
1654 eb58f9b1 Guido Trotter
      else:
1655 d0c8c01d Iustin Pop
        self._CallMonitorCommand(name, "system_powerdown")
1656 eb58f9b1 Guido Trotter
1657 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
1658 8904b35c Guido Trotter
    """Cleanup after a stopped instance
1659 8904b35c Guido Trotter

1660 8904b35c Guido Trotter
    """
1661 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
1662 8904b35c Guido Trotter
    if pid > 0 and alive:
1663 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
1664 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
1665 eb58f9b1 Guido Trotter
1666 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
1667 eb58f9b1 Guido Trotter
    """Reboot an instance.
1668 eb58f9b1 Guido Trotter

1669 eb58f9b1 Guido Trotter
    """
1670 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
1671 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
1672 eb58f9b1 Guido Trotter
    # to shutdown and restart.
1673 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
1674 1f8b3a27 Guido Trotter
    if not alive:
1675 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
1676 78411c60 Iustin Pop
                                   " not running" % instance.name)
1677 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
1678 f02881e0 Guido Trotter
    # ...first load it...
1679 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
1680 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
1681 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
1682 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
1683 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
1684 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1685 f02881e0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
1686 eb58f9b1 Guido Trotter
1687 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
1688 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
1689 30e42c4e Guido Trotter

1690 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1691 30e42c4e Guido Trotter
    @param instance: instance to be migrated
1692 30e42c4e Guido Trotter
    @rtype: string
1693 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
1694 30e42c4e Guido Trotter

1695 30e42c4e Guido Trotter
    """
1696 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
1697 30e42c4e Guido Trotter
1698 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
1699 30e42c4e Guido Trotter
    """Prepare to accept an instance.
1700 30e42c4e Guido Trotter

1701 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1702 30e42c4e Guido Trotter
    @param instance: instance to be accepted
1703 30e42c4e Guido Trotter
    @type info: string
1704 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
1705 30e42c4e Guido Trotter
    @type target: string
1706 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
1707 30e42c4e Guido Trotter

1708 30e42c4e Guido Trotter
    """
1709 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1710 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
1711 30e42c4e Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, incoming=incoming_address)
1712 30e42c4e Guido Trotter
1713 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
1714 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
1715 30e42c4e Guido Trotter

1716 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
1717 30e42c4e Guido Trotter

1718 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1719 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
1720 30e42c4e Guido Trotter

1721 30e42c4e Guido Trotter
    """
1722 30e42c4e Guido Trotter
    if success:
1723 5d9bfd87 Apollon Oikonomopoulos
      kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1724 5d9bfd87 Apollon Oikonomopoulos
      kvm_nics = kvm_runtime[1]
1725 5d9bfd87 Apollon Oikonomopoulos
1726 5d9bfd87 Apollon Oikonomopoulos
      for nic_seq, nic in enumerate(kvm_nics):
1727 cc8a8ed7 Apollon Oikonomopoulos
        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
1728 cc8a8ed7 Apollon Oikonomopoulos
          # Bridged interfaces have already been configured
1729 cc8a8ed7 Apollon Oikonomopoulos
          continue
1730 5d9bfd87 Apollon Oikonomopoulos
        try:
1731 5d9bfd87 Apollon Oikonomopoulos
          tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
1732 5d9bfd87 Apollon Oikonomopoulos
        except EnvironmentError, err:
1733 5d9bfd87 Apollon Oikonomopoulos
          logging.warning("Failed to find host interface for %s NIC #%d: %s",
1734 5d9bfd87 Apollon Oikonomopoulos
                          instance.name, nic_seq, str(err))
1735 5d9bfd87 Apollon Oikonomopoulos
          continue
1736 5d9bfd87 Apollon Oikonomopoulos
        try:
1737 5d9bfd87 Apollon Oikonomopoulos
          self._ConfigureNIC(instance, nic_seq, nic, tap)
1738 5d9bfd87 Apollon Oikonomopoulos
        except errors.HypervisorError, err:
1739 5d9bfd87 Apollon Oikonomopoulos
          logging.warning(str(err))
1740 5d9bfd87 Apollon Oikonomopoulos
1741 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
1742 30e42c4e Guido Trotter
    else:
1743 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
1744 30e42c4e Guido Trotter
1745 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
1746 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
1747 30e42c4e Guido Trotter

1748 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
1749 30e42c4e Guido Trotter
    currently running.
1750 30e42c4e Guido Trotter

1751 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
1752 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
1753 30e42c4e Guido Trotter
    @type target: string
1754 30e42c4e Guido Trotter
    @param target: ip address of the target node
1755 30e42c4e Guido Trotter
    @type live: boolean
1756 30e42c4e Guido Trotter
    @param live: perform a live migration
1757 30e42c4e Guido Trotter

1758 30e42c4e Guido Trotter
    """
1759 58d38b02 Iustin Pop
    instance_name = instance.name
1760 50716be0 Iustin Pop
    port = instance.hvparams[constants.HV_MIGRATION_PORT]
1761 6a1434d7 Andrea Spadaccini
    _, _, alive = self._InstancePidAlive(instance_name)
1762 30e42c4e Guido Trotter
    if not alive:
1763 30e42c4e Guido Trotter
      raise errors.HypervisorError("Instance not running, cannot migrate")
1764 30e42c4e Guido Trotter
1765 30e42c4e Guido Trotter
    if not live:
1766 d0c8c01d Iustin Pop
      self._CallMonitorCommand(instance_name, "stop")
1767 30e42c4e Guido Trotter
1768 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_speed %dm" %
1769 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_BANDWIDTH])
1770 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
1771 e43d4f9f Apollon Oikonomopoulos
1772 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_downtime %dms" %
1773 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_DOWNTIME])
1774 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
1775 e43d4f9f Apollon Oikonomopoulos
1776 d0c8c01d Iustin Pop
    migrate_command = "migrate -d tcp:%s:%s" % (target, port)
1777 30e42c4e Guido Trotter
    self._CallMonitorCommand(instance_name, migrate_command)
1778 30e42c4e Guido Trotter
1779 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
1780 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
1781 6a1434d7 Andrea Spadaccini

1782 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
1783 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
1784 6a1434d7 Andrea Spadaccini
    @type success: bool
1785 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
1786 6a1434d7 Andrea Spadaccini
    @type live: bool
1787 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
1788 6a1434d7 Andrea Spadaccini

1789 6a1434d7 Andrea Spadaccini
    """
1790 6a1434d7 Andrea Spadaccini
    if success:
1791 6a1434d7 Andrea Spadaccini
      pidfile, pid, _ = self._InstancePidAlive(instance.name)
1792 6a1434d7 Andrea Spadaccini
      utils.KillProcess(pid)
1793 6a1434d7 Andrea Spadaccini
      self._RemoveInstanceRuntimeFiles(pidfile, instance.name)
1794 6a1434d7 Andrea Spadaccini
    elif live:
1795 6a1434d7 Andrea Spadaccini
      self._CallMonitorCommand(instance.name, self._CONT_CMD)
1796 6a1434d7 Andrea Spadaccini
1797 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
1798 6a1434d7 Andrea Spadaccini
    """Get the migration status
1799 6a1434d7 Andrea Spadaccini

1800 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
1801 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
1802 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
1803 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
1804 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
1805 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
1806 6a1434d7 Andrea Spadaccini

1807 6a1434d7 Andrea Spadaccini
    """
1808 d0c8c01d Iustin Pop
    info_command = "info migrate"
1809 6a1434d7 Andrea Spadaccini
    for _ in range(self._MIGRATION_INFO_MAX_BAD_ANSWERS):
1810 6a1434d7 Andrea Spadaccini
      result = self._CallMonitorCommand(instance.name, info_command)
1811 30e42c4e Guido Trotter
      match = self._MIGRATION_STATUS_RE.search(result.stdout)
1812 30e42c4e Guido Trotter
      if not match:
1813 c4e388a5 Guido Trotter
        if not result.stdout:
1814 c4e388a5 Guido Trotter
          logging.info("KVM: empty 'info migrate' result")
1815 c4e388a5 Guido Trotter
        else:
1816 e4dd2299 Guido Trotter
          logging.warning("KVM: unknown 'info migrate' result: %s",
1817 c4e388a5 Guido Trotter
                          result.stdout)
1818 30e42c4e Guido Trotter
      else:
1819 30e42c4e Guido Trotter
        status = match.group(1)
1820 6a1434d7 Andrea Spadaccini
        if status in constants.HV_KVM_MIGRATION_VALID_STATUSES:
1821 6a1434d7 Andrea Spadaccini
          migration_status = objects.MigrationStatus(status=status)
1822 61643226 Andrea Spadaccini
          match = self._MIGRATION_PROGRESS_RE.search(result.stdout)
1823 61643226 Andrea Spadaccini
          if match:
1824 61643226 Andrea Spadaccini
            migration_status.transferred_ram = match.group("transferred")
1825 61643226 Andrea Spadaccini
            migration_status.total_ram = match.group("total")
1826 61643226 Andrea Spadaccini
1827 6a1434d7 Andrea Spadaccini
          return migration_status
1828 30e42c4e Guido Trotter
1829 6a1434d7 Andrea Spadaccini
        logging.warning("KVM: unknown migration status '%s'", status)
1830 6a1434d7 Andrea Spadaccini
1831 6a1434d7 Andrea Spadaccini
      time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
1832 6a1434d7 Andrea Spadaccini
1833 62457f51 Iustin Pop
    return objects.MigrationStatus(status=constants.HV_MIGRATION_FAILED)
1834 30e42c4e Guido Trotter
1835 3d836750 Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
1836 3d836750 Guido Trotter
    """Balloon an instance memory to a certain value.
1837 3d836750 Guido Trotter

1838 3d836750 Guido Trotter
    @type instance: L{objects.Instance}
1839 3d836750 Guido Trotter
    @param instance: instance to be accepted
1840 3d836750 Guido Trotter
    @type mem: int
1841 3d836750 Guido Trotter
    @param mem: actual memory size to use for instance runtime
1842 3d836750 Guido Trotter

1843 3d836750 Guido Trotter
    """
1844 3d836750 Guido Trotter
    self._CallMonitorCommand(instance.name, "balloon %d" % mem)
1845 3d836750 Guido Trotter
1846 eb58f9b1 Guido Trotter
  def GetNodeInfo(self):
1847 eb58f9b1 Guido Trotter
    """Return information about the node.
1848 eb58f9b1 Guido Trotter

1849 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
1850 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
1851 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
1852 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
1853 34fbc862 Andrea Spadaccini
          - hv_version: the hypervisor version in the form (major, minor,
1854 34fbc862 Andrea Spadaccini
                        revision)
1855 eb58f9b1 Guido Trotter

1856 eb58f9b1 Guido Trotter
    """
1857 34fbc862 Andrea Spadaccini
    result = self.GetLinuxNodeInfo()
1858 34fbc862 Andrea Spadaccini
    _, v_major, v_min, v_rev = self._GetKVMVersion()
1859 34fbc862 Andrea Spadaccini
    result[constants.HV_NODEINFO_KEY_VERSION] = (v_major, v_min, v_rev)
1860 34fbc862 Andrea Spadaccini
    return result
1861 eb58f9b1 Guido Trotter
1862 637ce7f9 Guido Trotter
  @classmethod
1863 55cc0a44 Michael Hanselmann
  def GetInstanceConsole(cls, instance, hvparams, beparams):
1864 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
1865 eb58f9b1 Guido Trotter

1866 eb58f9b1 Guido Trotter
    """
1867 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
1868 9d9bded1 Michael Hanselmann
      cmd = [pathutils.KVM_CONSOLE_WRAPPER,
1869 2f4c951e Stephen Shirley
             constants.SOCAT_PATH, utils.ShellQuote(instance.name),
1870 2f4c951e Stephen Shirley
             utils.ShellQuote(cls._InstanceMonitor(instance.name)),
1871 55cc0a44 Michael Hanselmann
             "STDIO,%s" % cls._SocatUnixConsoleParams(),
1872 55cc0a44 Michael Hanselmann
             "UNIX-CONNECT:%s" % cls._InstanceSerial(instance.name)]
1873 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
1874 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_SSH,
1875 55cc0a44 Michael Hanselmann
                                     host=instance.primary_node,
1876 052783ff Michael Hanselmann
                                     user=constants.SSH_CONSOLE_USER,
1877 55cc0a44 Michael Hanselmann
                                     command=cmd)
1878 3be34f57 Guido Trotter
1879 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
1880 55cc0a44 Michael Hanselmann
    if vnc_bind_address and instance.network_port > constants.VNC_BASE_PORT:
1881 55cc0a44 Michael Hanselmann
      display = instance.network_port - constants.VNC_BASE_PORT
1882 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
1883 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_VNC,
1884 55cc0a44 Michael Hanselmann
                                     host=vnc_bind_address,
1885 55cc0a44 Michael Hanselmann
                                     port=instance.network_port,
1886 55cc0a44 Michael Hanselmann
                                     display=display)
1887 55cc0a44 Michael Hanselmann
1888 4d2cdb5a Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
1889 4d2cdb5a Andrea Spadaccini
    if spice_bind:
1890 4d2cdb5a Andrea Spadaccini
      return objects.InstanceConsole(instance=instance.name,
1891 4d2cdb5a Andrea Spadaccini
                                     kind=constants.CONS_SPICE,
1892 4d2cdb5a Andrea Spadaccini
                                     host=spice_bind,
1893 4d2cdb5a Andrea Spadaccini
                                     port=instance.network_port)
1894 4d2cdb5a Andrea Spadaccini
1895 55cc0a44 Michael Hanselmann
    return objects.InstanceConsole(instance=instance.name,
1896 55cc0a44 Michael Hanselmann
                                   kind=constants.CONS_MESSAGE,
1897 55cc0a44 Michael Hanselmann
                                   message=("No serial shell for instance %s" %
1898 55cc0a44 Michael Hanselmann
                                            instance.name))
1899 eb58f9b1 Guido Trotter
1900 eb58f9b1 Guido Trotter
  def Verify(self):
1901 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
1902 eb58f9b1 Guido Trotter

1903 eb58f9b1 Guido Trotter
    Check that the binary exists.
1904 eb58f9b1 Guido Trotter

1905 eb58f9b1 Guido Trotter
    """
1906 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
1907 eb58f9b1 Guido Trotter
      return "The kvm binary ('%s') does not exist." % constants.KVM_PATH
1908 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
1909 14aa53cb Guido Trotter
      return "The socat binary ('%s') does not exist." % constants.SOCAT_PATH
1910 14aa53cb Guido Trotter
1911 6b5605e8 Iustin Pop
  @classmethod
1912 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
1913 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
1914 6b5605e8 Iustin Pop

1915 6b5605e8 Iustin Pop
    @type hvparams:  dict
1916 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
1917 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
1918 6b5605e8 Iustin Pop

1919 6b5605e8 Iustin Pop
    """
1920 47387b1e Guido Trotter
    super(KVMHypervisor, cls).CheckParameterSyntax(hvparams)
1921 6b5605e8 Iustin Pop
1922 df5ab9f0 Guido Trotter
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
1923 df5ab9f0 Guido Trotter
    if kernel_path:
1924 df5ab9f0 Guido Trotter
      if not hvparams[constants.HV_ROOT_PATH]:
1925 205ab586 Iustin Pop
        raise errors.HypervisorError("Need a root partition for the instance,"
1926 205ab586 Iustin Pop
                                     " if a kernel is defined")
1927 6b5605e8 Iustin Pop
1928 205ab586 Iustin Pop
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
1929 205ab586 Iustin Pop
        not hvparams[constants.HV_VNC_X509]):
1930 205ab586 Iustin Pop
      raise errors.HypervisorError("%s must be defined, if %s is" %
1931 205ab586 Iustin Pop
                                   (constants.HV_VNC_X509,
1932 205ab586 Iustin Pop
                                    constants.HV_VNC_X509_VERIFY))
1933 66d5dbef Guido Trotter
1934 66d5dbef Guido Trotter
    boot_order = hvparams[constants.HV_BOOT_ORDER]
1935 205ab586 Iustin Pop
    if (boot_order == constants.HT_BO_CDROM and
1936 205ab586 Iustin Pop
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
1937 835528af Iustin Pop
      raise errors.HypervisorError("Cannot boot from cdrom without an"
1938 835528af Iustin Pop
                                   " ISO path")
1939 f5118ade Iustin Pop
1940 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1941 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1942 d19d94db Guido Trotter
      if not hvparams[constants.HV_SECURITY_DOMAIN]:
1943 d19d94db Guido Trotter
        raise errors.HypervisorError("A security domain (user to run kvm as)"
1944 d19d94db Guido Trotter
                                     " must be specified")
1945 d19d94db Guido Trotter
    elif (security_model == constants.HT_SM_NONE or
1946 d19d94db Guido Trotter
          security_model == constants.HT_SM_POOL):
1947 d19d94db Guido Trotter
      if hvparams[constants.HV_SECURITY_DOMAIN]:
1948 d19d94db Guido Trotter
        raise errors.HypervisorError("Cannot have a security domain when the"
1949 d19d94db Guido Trotter
                                     " security model is 'none' or 'pool'")
1950 d19d94db Guido Trotter
1951 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
1952 b451c4c7 Andrea Spadaccini
    spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
1953 b1cb62bd Andrea Spadaccini
    if spice_bind:
1954 b1cb62bd Andrea Spadaccini
      if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
1955 b1cb62bd Andrea Spadaccini
        # if an IP version is specified, the spice_bind parameter must be an
1956 b1cb62bd Andrea Spadaccini
        # IP of that family
1957 b1cb62bd Andrea Spadaccini
        if (netutils.IP4Address.IsValid(spice_bind) and
1958 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP4_VERSION):
1959 b1cb62bd Andrea Spadaccini
          raise errors.HypervisorError("spice: got an IPv4 address (%s), but"
1960 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
1961 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
1962 b1cb62bd Andrea Spadaccini
1963 b1cb62bd Andrea Spadaccini
        if (netutils.IP6Address.IsValid(spice_bind) and
1964 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP6_VERSION):
1965 b1cb62bd Andrea Spadaccini
          raise errors.HypervisorError("spice: got an IPv6 address (%s), but"
1966 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
1967 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
1968 b451c4c7 Andrea Spadaccini
    else:
1969 0e1b03b9 Andrea Spadaccini
      # All the other SPICE parameters depend on spice_bind being set. Raise an
1970 0e1b03b9 Andrea Spadaccini
      # error if any of them is set without it.
1971 07788a0b Michael Hanselmann
      for param in _SPICE_ADDITIONAL_PARAMS:
1972 0e1b03b9 Andrea Spadaccini
        if hvparams[param]:
1973 0e1b03b9 Andrea Spadaccini
          raise errors.HypervisorError("spice: %s requires %s to be set" %
1974 0e1b03b9 Andrea Spadaccini
                                       (param, constants.HV_KVM_SPICE_BIND))
1975 b1cb62bd Andrea Spadaccini
1976 d19d94db Guido Trotter
  @classmethod
1977 d19d94db Guido Trotter
  def ValidateParameters(cls, hvparams):
1978 d19d94db Guido Trotter
    """Check the given parameters for validity.
1979 d19d94db Guido Trotter

1980 d19d94db Guido Trotter
    @type hvparams:  dict
1981 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
1982 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
1983 d19d94db Guido Trotter

1984 d19d94db Guido Trotter
    """
1985 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
1986 d19d94db Guido Trotter
1987 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1988 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1989 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
1990 d19d94db Guido Trotter
      try:
1991 1feb39ec Guido Trotter
        pwd.getpwnam(username)
1992 d19d94db Guido Trotter
      except KeyError:
1993 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
1994 d19d94db Guido Trotter
                                     % username)
1995 d19d94db Guido Trotter
1996 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
1997 b1cb62bd Andrea Spadaccini
    if spice_bind:
1998 b1cb62bd Andrea Spadaccini
      # only one of VNC and SPICE can be used currently.
1999 b1cb62bd Andrea Spadaccini
      if hvparams[constants.HV_VNC_BIND_ADDRESS]:
2000 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("both SPICE and VNC are configured, but"
2001 b1cb62bd Andrea Spadaccini
                                     " only one of them can be used at a"
2002 b1cb62bd Andrea Spadaccini
                                     " given time.")
2003 b1cb62bd Andrea Spadaccini
2004 b1cb62bd Andrea Spadaccini
      # KVM version should be >= 0.14.0
2005 b1cb62bd Andrea Spadaccini
      _, v_major, v_min, _ = cls._GetKVMVersion()
2006 b1cb62bd Andrea Spadaccini
      if (v_major, v_min) < (0, 14):
2007 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("spice is configured, but it is not"
2008 b1cb62bd Andrea Spadaccini
                                     " available in versions of KVM < 0.14")
2009 b1cb62bd Andrea Spadaccini
2010 b1cb62bd Andrea Spadaccini
      # if spice_bind is not an IP address, it must be a valid interface
2011 b1cb62bd Andrea Spadaccini
      bound_to_addr = (netutils.IP4Address.IsValid(spice_bind)
2012 b1cb62bd Andrea Spadaccini
                       or netutils.IP6Address.IsValid(spice_bind))
2013 b1cb62bd Andrea Spadaccini
      if not bound_to_addr and not netutils.IsValidInterface(spice_bind):
2014 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("spice: the %s parameter must be either"
2015 b1cb62bd Andrea Spadaccini
                                     " a valid IP address or interface name" %
2016 b1cb62bd Andrea Spadaccini
                                     constants.HV_KVM_SPICE_BIND)
2017 b1cb62bd Andrea Spadaccini
2018 f5118ade Iustin Pop
  @classmethod
2019 f5118ade Iustin Pop
  def PowercycleNode(cls):
2020 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
2021 f5118ade Iustin Pop

2022 f5118ade Iustin Pop
    """
2023 f5118ade Iustin Pop
    cls.LinuxPowercycle()