Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ 0ad7f5d8

History | View | Annotate | Download (75.4 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 14fd6c81 Guido Trotter
    constants.HV_SERIAL_SPEED: hv_base.NO_CHECK,
470 d73ef63f Michael Hanselmann
    constants.HV_VNC_BIND_ADDRESS:
471 8b312c1d Manuel Franceschini
      (False, lambda x: (netutils.IP4Address.IsValid(x) or
472 8b312c1d Manuel Franceschini
                         utils.IsNormAbsPath(x)),
473 d73ef63f Michael Hanselmann
       "the VNC bind address must be either a valid IP address or an absolute"
474 d73ef63f Michael Hanselmann
       " pathname", None, None),
475 205ab586 Iustin Pop
    constants.HV_VNC_TLS: hv_base.NO_CHECK,
476 205ab586 Iustin Pop
    constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
477 205ab586 Iustin Pop
    constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
478 6e6bb8d5 Guido Trotter
    constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
479 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_BIND: hv_base.NO_CHECK, # will be checked later
480 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_IP_VERSION:
481 b1cb62bd Andrea Spadaccini
      (False, lambda x: (x == constants.IFACE_NO_IP_VERSION_SPECIFIED or
482 b1cb62bd Andrea Spadaccini
                         x in constants.VALID_IP_VERSIONS),
483 b1cb62bd Andrea Spadaccini
       "the SPICE IP version should be 4 or 6",
484 b1cb62bd Andrea Spadaccini
       None, None),
485 b451c4c7 Andrea Spadaccini
    constants.HV_KVM_SPICE_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
486 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_LOSSLESS_IMG_COMPR:
487 5ae4945a Iustin Pop
      hv_base.ParamInSet(
488 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSLESS_IMG_COMPR_OPTIONS),
489 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_JPEG_IMG_COMPR:
490 5ae4945a Iustin Pop
      hv_base.ParamInSet(
491 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
492 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR:
493 5ae4945a Iustin Pop
      hv_base.ParamInSet(
494 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_LOSSY_IMG_COMPR_OPTIONS),
495 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION:
496 5ae4945a Iustin Pop
      hv_base.ParamInSet(
497 5ae4945a Iustin Pop
        False, constants.HT_KVM_SPICE_VALID_VIDEO_STREAM_DETECTION_OPTIONS),
498 ea064d24 Andrea Spadaccini
    constants.HV_KVM_SPICE_AUDIO_COMPR: hv_base.NO_CHECK,
499 bfe86c76 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_TLS: hv_base.NO_CHECK,
500 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_TLS_CIPHERS: hv_base.NO_CHECK,
501 3e40b587 Andrea Spadaccini
    constants.HV_KVM_SPICE_USE_VDAGENT: hv_base.NO_CHECK,
502 cc130cc7 Marco Casavecchia
    constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
503 205ab586 Iustin Pop
    constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
504 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
505 d73ef63f Michael Hanselmann
    constants.HV_BOOT_ORDER:
506 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
507 d73ef63f Michael Hanselmann
    constants.HV_NIC_TYPE:
508 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_NIC_TYPES),
509 d73ef63f Michael Hanselmann
    constants.HV_DISK_TYPE:
510 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_DISK_TYPES),
511 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM_DISK_TYPE:
512 cc130cc7 Marco Casavecchia
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_DISK_TYPES),
513 d73ef63f Michael Hanselmann
    constants.HV_USB_MOUSE:
514 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_MOUSE_TYPES),
515 4f580fef Sébastien Bocahu
    constants.HV_KEYMAP: hv_base.NO_CHECK,
516 e2d14329 Andrea Spadaccini
    constants.HV_MIGRATION_PORT: hv_base.REQ_NET_PORT_CHECK,
517 2c368f28 Guido Trotter
    constants.HV_MIGRATION_BANDWIDTH: hv_base.REQ_NONNEGATIVE_INT_CHECK,
518 2c368f28 Guido Trotter
    constants.HV_MIGRATION_DOWNTIME: hv_base.REQ_NONNEGATIVE_INT_CHECK,
519 783a6c0b Iustin Pop
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
520 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
521 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
522 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
523 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
524 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
525 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
526 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
527 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
528 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
529 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
530 4f958b0b Miguel Di Ciurcio Filho
    constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
531 990ade2d Stephen Shirley
    constants.HV_REBOOT_BEHAVIOR:
532 a7f884d3 Tsachy Shacham
      hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
533 a7f884d3 Tsachy Shacham
    constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
534 3c286190 Dimitris Aragiorgis
    constants.HV_CPU_TYPE: hv_base.NO_CHECK,
535 2c368f28 Guido Trotter
    constants.HV_CPU_CORES: hv_base.OPT_NONNEGATIVE_INT_CHECK,
536 2c368f28 Guido Trotter
    constants.HV_CPU_THREADS: hv_base.OPT_NONNEGATIVE_INT_CHECK,
537 2c368f28 Guido Trotter
    constants.HV_CPU_SOCKETS: hv_base.OPT_NONNEGATIVE_INT_CHECK,
538 205ab586 Iustin Pop
    }
539 6b5605e8 Iustin Pop
540 d0c8c01d Iustin Pop
  _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)",
541 30e42c4e Guido Trotter
                                    re.M | re.I)
542 65107a2f Michael Hanselmann
  _MIGRATION_PROGRESS_RE = \
543 527c0cf7 Michael Hanselmann
    re.compile(r"\s*transferred\s+ram:\s+(?P<transferred>\d+)\s+kbytes\s*\n"
544 527c0cf7 Michael Hanselmann
               r"\s*remaining\s+ram:\s+(?P<remaining>\d+)\s+kbytes\s*\n"
545 527c0cf7 Michael Hanselmann
               r"\s*total\s+ram:\s+(?P<total>\d+)\s+kbytes\s*\n", re.I)
546 61643226 Andrea Spadaccini
547 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
548 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
549 30e42c4e Guido Trotter
550 585c8187 Guido Trotter
  _VERSION_RE = re.compile(r"\b(\d+)\.(\d+)(\.(\d+))?\b")
551 b52d85c1 Guido Trotter
552 b693125f Tsachy Shacham
  _CPU_INFO_RE = re.compile(r"cpu\s+\#(\d+).*thread_id\s*=\s*(\d+)", re.I)
553 b693125f Tsachy Shacham
  _CPU_INFO_CMD = "info cpus"
554 b693125f Tsachy Shacham
  _CONT_CMD = "cont"
555 b693125f Tsachy Shacham
556 e6ba3320 Dimitris Aragiorgis
  _DEFAULT_MACHINE_VERSION_RE = re.compile(r"(\S+).*\(default\)")
557 e6ba3320 Dimitris Aragiorgis
558 0ad7f5d8 Guido Trotter
  _QMP_RE = re.compile(r"^-qmp\s", re.M)
559 0ad7f5d8 Guido Trotter
  _SPICE_RE = re.compile(r"^-spice\s", re.M)
560 0ad7f5d8 Guido Trotter
  _VHOST_RE = re.compile(r"^-net\s.*,vhost=on|off", re.M)
561 0ad7f5d8 Guido Trotter
  _ENABLE_KVM_RE = re.compile(r"^-enable-kvm\s", re.M)
562 0ad7f5d8 Guido Trotter
  _DISABLE_KVM_RE = re.compile(r"^-disable-kvm\s", re.M)
563 0ad7f5d8 Guido Trotter
  _NETDEV_RE = re.compile(r"^-netdev\s", re.M)
564 0ad7f5d8 Guido Trotter
  # match  -drive.*boot=on|off on different lines, but in between accept only
565 0ad7f5d8 Guido Trotter
  # dashes not preceeded by a new line (which would mean another option
566 0ad7f5d8 Guido Trotter
  # different than -drive is starting)
567 0ad7f5d8 Guido Trotter
  _BOOT_RE = re.compile(r"^-drive\s([^-]|(?<!^)-)*,boot=on\|off", re.M | re.S)
568 0ad7f5d8 Guido Trotter
569 64bfbc08 Guido Trotter
  ANCILLARY_FILES = [
570 64bfbc08 Guido Trotter
    _KVM_NETWORK_SCRIPT,
571 64bfbc08 Guido Trotter
    ]
572 69ab2e12 Guido Trotter
  ANCILLARY_FILES_OPT = [
573 69ab2e12 Guido Trotter
    _KVM_NETWORK_SCRIPT,
574 69ab2e12 Guido Trotter
    ]
575 64bfbc08 Guido Trotter
576 eb58f9b1 Guido Trotter
  def __init__(self):
577 eb58f9b1 Guido Trotter
    hv_base.BaseHypervisor.__init__(self)
578 eb58f9b1 Guido Trotter
    # Let's make sure the directories we need exist, even if the RUN_DIR lives
579 eb58f9b1 Guido Trotter
    # in a tmpfs filesystem or has been otherwise wiped out.
580 29921401 Iustin Pop
    dirs = [(dname, constants.RUN_DIRS_MODE) for dname in self._DIRS]
581 9afb67fe Guido Trotter
    utils.EnsureDirs(dirs)
582 eb58f9b1 Guido Trotter
583 30786fc9 Iustin Pop
  @classmethod
584 30786fc9 Iustin Pop
  def _InstancePidFile(cls, instance_name):
585 98ec75d6 Iustin Pop
    """Returns the instance pidfile.
586 98ec75d6 Iustin Pop

587 98ec75d6 Iustin Pop
    """
588 30786fc9 Iustin Pop
    return utils.PathJoin(cls._PIDS_DIR, instance_name)
589 98ec75d6 Iustin Pop
590 263b8de6 Guido Trotter
  @classmethod
591 7548396c Guido Trotter
  def _InstanceUidFile(cls, instance_name):
592 7548396c Guido Trotter
    """Returns the instance uidfile.
593 7548396c Guido Trotter

594 7548396c Guido Trotter
    """
595 7548396c Guido Trotter
    return utils.PathJoin(cls._UIDS_DIR, instance_name)
596 7548396c Guido Trotter
597 7548396c Guido Trotter
  @classmethod
598 263b8de6 Guido Trotter
  def _InstancePidInfo(cls, pid):
599 263b8de6 Guido Trotter
    """Check pid file for instance information.
600 263b8de6 Guido Trotter

601 263b8de6 Guido Trotter
    Check that a pid file is associated with an instance, and retrieve
602 263b8de6 Guido Trotter
    information from its command line.
603 263b8de6 Guido Trotter

604 263b8de6 Guido Trotter
    @type pid: string or int
605 263b8de6 Guido Trotter
    @param pid: process id of the instance to check
606 263b8de6 Guido Trotter
    @rtype: tuple
607 263b8de6 Guido Trotter
    @return: (instance_name, memory, vcpus)
608 263b8de6 Guido Trotter
    @raise errors.HypervisorError: when an instance cannot be found
609 263b8de6 Guido Trotter

610 263b8de6 Guido Trotter
    """
611 263b8de6 Guido Trotter
    alive = utils.IsProcessAlive(pid)
612 263b8de6 Guido Trotter
    if not alive:
613 263b8de6 Guido Trotter
      raise errors.HypervisorError("Cannot get info for pid %s" % pid)
614 263b8de6 Guido Trotter
615 263b8de6 Guido Trotter
    cmdline_file = utils.PathJoin("/proc", str(pid), "cmdline")
616 263b8de6 Guido Trotter
    try:
617 263b8de6 Guido Trotter
      cmdline = utils.ReadFile(cmdline_file)
618 263b8de6 Guido Trotter
    except EnvironmentError, err:
619 263b8de6 Guido Trotter
      raise errors.HypervisorError("Can't open cmdline file for pid %s: %s" %
620 263b8de6 Guido Trotter
                                   (pid, err))
621 263b8de6 Guido Trotter
622 263b8de6 Guido Trotter
    instance = None
623 263b8de6 Guido Trotter
    memory = 0
624 263b8de6 Guido Trotter
    vcpus = 0
625 263b8de6 Guido Trotter
626 d0c8c01d Iustin Pop
    arg_list = cmdline.split("\x00")
627 263b8de6 Guido Trotter
    while arg_list:
628 e687ec01 Michael Hanselmann
      arg = arg_list.pop(0)
629 263b8de6 Guido Trotter
      if arg == "-name":
630 263b8de6 Guido Trotter
        instance = arg_list.pop(0)
631 263b8de6 Guido Trotter
      elif arg == "-m":
632 263b8de6 Guido Trotter
        memory = int(arg_list.pop(0))
633 263b8de6 Guido Trotter
      elif arg == "-smp":
634 4888a609 Guido Trotter
        vcpus = int(arg_list.pop(0).split(",")[0])
635 263b8de6 Guido Trotter
636 263b8de6 Guido Trotter
    if instance is None:
637 263b8de6 Guido Trotter
      raise errors.HypervisorError("Pid %s doesn't contain a ganeti kvm"
638 263b8de6 Guido Trotter
                                   " instance" % pid)
639 263b8de6 Guido Trotter
640 263b8de6 Guido Trotter
    return (instance, memory, vcpus)
641 263b8de6 Guido Trotter
642 1f8b3a27 Guido Trotter
  def _InstancePidAlive(self, instance_name):
643 263b8de6 Guido Trotter
    """Returns the instance pidfile, pid, and liveness.
644 263b8de6 Guido Trotter

645 263b8de6 Guido Trotter
    @type instance_name: string
646 263b8de6 Guido Trotter
    @param instance_name: instance name
647 263b8de6 Guido Trotter
    @rtype: tuple
648 263b8de6 Guido Trotter
    @return: (pid file name, pid, liveness)
649 1f8b3a27 Guido Trotter

650 1f8b3a27 Guido Trotter
    """
651 98ec75d6 Iustin Pop
    pidfile = self._InstancePidFile(instance_name)
652 1f8b3a27 Guido Trotter
    pid = utils.ReadPidFile(pidfile)
653 263b8de6 Guido Trotter
654 263b8de6 Guido Trotter
    alive = False
655 263b8de6 Guido Trotter
    try:
656 263b8de6 Guido Trotter
      cmd_instance = self._InstancePidInfo(pid)[0]
657 263b8de6 Guido Trotter
      alive = (cmd_instance == instance_name)
658 263b8de6 Guido Trotter
    except errors.HypervisorError:
659 263b8de6 Guido Trotter
      pass
660 1f8b3a27 Guido Trotter
661 1f8b3a27 Guido Trotter
    return (pidfile, pid, alive)
662 1f8b3a27 Guido Trotter
663 5905901c Iustin Pop
  def _CheckDown(self, instance_name):
664 5905901c Iustin Pop
    """Raises an error unless the given instance is down.
665 5905901c Iustin Pop

666 5905901c Iustin Pop
    """
667 5905901c Iustin Pop
    alive = self._InstancePidAlive(instance_name)[2]
668 5905901c Iustin Pop
    if alive:
669 5905901c Iustin Pop
      raise errors.HypervisorError("Failed to start instance %s: %s" %
670 5905901c Iustin Pop
                                   (instance_name, "already running"))
671 5905901c Iustin Pop
672 0df4d98a Guido Trotter
  @classmethod
673 0df4d98a Guido Trotter
  def _InstanceMonitor(cls, instance_name):
674 c4fbefc8 Guido Trotter
    """Returns the instance monitor socket name
675 c4fbefc8 Guido Trotter

676 c4fbefc8 Guido Trotter
    """
677 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.monitor" % instance_name)
678 c4fbefc8 Guido Trotter
679 0df4d98a Guido Trotter
  @classmethod
680 0df4d98a Guido Trotter
  def _InstanceSerial(cls, instance_name):
681 c4fbefc8 Guido Trotter
    """Returns the instance serial socket name
682 c4fbefc8 Guido Trotter

683 c4fbefc8 Guido Trotter
    """
684 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.serial" % instance_name)
685 c4fbefc8 Guido Trotter
686 91c10532 Andrea Spadaccini
  @classmethod
687 91c10532 Andrea Spadaccini
  def _InstanceQmpMonitor(cls, instance_name):
688 91c10532 Andrea Spadaccini
    """Returns the instance serial QMP socket name
689 91c10532 Andrea Spadaccini

690 91c10532 Andrea Spadaccini
    """
691 91c10532 Andrea Spadaccini
    return utils.PathJoin(cls._CTRL_DIR, "%s.qmp" % instance_name)
692 91c10532 Andrea Spadaccini
693 86d6bc2a Guido Trotter
  @staticmethod
694 86d6bc2a Guido Trotter
  def _SocatUnixConsoleParams():
695 86d6bc2a Guido Trotter
    """Returns the correct parameters for socat
696 86d6bc2a Guido Trotter

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

699 86d6bc2a Guido Trotter
    """
700 fe5b0c42 Michael Hanselmann
    if constants.SOCAT_USE_ESCAPE:
701 86d6bc2a Guido Trotter
      return "raw,echo=0,escape=%s" % constants.SOCAT_ESCAPE_CODE
702 86d6bc2a Guido Trotter
    else:
703 86d6bc2a Guido Trotter
      return "echo=0,icanon=0"
704 86d6bc2a Guido Trotter
705 0df4d98a Guido Trotter
  @classmethod
706 0df4d98a Guido Trotter
  def _InstanceKVMRuntime(cls, instance_name):
707 38e250ba Guido Trotter
    """Returns the instance KVM runtime filename
708 38e250ba Guido Trotter

709 38e250ba Guido Trotter
    """
710 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
711 38e250ba Guido Trotter
712 7e66c35b Guido Trotter
  @classmethod
713 547a63b7 Balazs Lecz
  def _InstanceChrootDir(cls, instance_name):
714 547a63b7 Balazs Lecz
    """Returns the name of the KVM chroot dir of the instance
715 547a63b7 Balazs Lecz

716 547a63b7 Balazs Lecz
    """
717 547a63b7 Balazs Lecz
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
718 547a63b7 Balazs Lecz
719 547a63b7 Balazs Lecz
  @classmethod
720 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICDir(cls, instance_name):
721 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the directory holding the tap device files for a
722 5d9bfd87 Apollon Oikonomopoulos
    given instance.
723 5d9bfd87 Apollon Oikonomopoulos

724 5d9bfd87 Apollon Oikonomopoulos
    """
725 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._NICS_DIR, instance_name)
726 5d9bfd87 Apollon Oikonomopoulos
727 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
728 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICFile(cls, instance_name, seq):
729 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the file containing the tap device for a given NIC
730 5d9bfd87 Apollon Oikonomopoulos

731 5d9bfd87 Apollon Oikonomopoulos
    """
732 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._InstanceNICDir(instance_name), str(seq))
733 5d9bfd87 Apollon Oikonomopoulos
734 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
735 4f580fef Sébastien Bocahu
  def _InstanceKeymapFile(cls, instance_name):
736 4f580fef Sébastien Bocahu
    """Returns the name of the file containing the keymap for a given instance
737 4f580fef Sébastien Bocahu

738 4f580fef Sébastien Bocahu
    """
739 4f580fef Sébastien Bocahu
    return utils.PathJoin(cls._KEYMAP_DIR, instance_name)
740 4f580fef Sébastien Bocahu
741 4f580fef Sébastien Bocahu
  @classmethod
742 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
743 7548396c Guido Trotter
    """Try to read a uid file
744 7548396c Guido Trotter

745 7548396c Guido Trotter
    """
746 7548396c Guido Trotter
    if os.path.exists(uid_file):
747 7548396c Guido Trotter
      try:
748 682f7601 Guido Trotter
        uid = int(utils.ReadOneLineFile(uid_file))
749 aa0b600b Guido Trotter
        return uid
750 7548396c Guido Trotter
      except EnvironmentError:
751 7548396c Guido Trotter
        logging.warning("Can't read uid file", exc_info=True)
752 7548396c Guido Trotter
      except (TypeError, ValueError):
753 7548396c Guido Trotter
        logging.warning("Can't parse uid file contents", exc_info=True)
754 aa0b600b Guido Trotter
    return None
755 7548396c Guido Trotter
756 7548396c Guido Trotter
  @classmethod
757 7e66c35b Guido Trotter
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
758 547a63b7 Balazs Lecz
    """Removes an instance's rutime sockets/files/dirs.
759 7e66c35b Guido Trotter

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

800 eb58f9b1 Guido Trotter
    @param instance: instance we're acting on
801 eb58f9b1 Guido Trotter
    @type instance: instance object
802 eb58f9b1 Guido Trotter
    @param seq: nic sequence number
803 eb58f9b1 Guido Trotter
    @type seq: int
804 eb58f9b1 Guido Trotter
    @param nic: nic we're acting on
805 eb58f9b1 Guido Trotter
    @type nic: nic object
806 5d9bfd87 Apollon Oikonomopoulos
    @param tap: the host's tap interface this NIC corresponds to
807 5d9bfd87 Apollon Oikonomopoulos
    @type tap: str
808 eb58f9b1 Guido Trotter

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

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

860 b693125f Tsachy Shacham
    @type cpu_list: list of int
861 b693125f Tsachy Shacham
    @param cpu_list: list of physical CPU numbers to map to vCPUs in order
862 b693125f Tsachy Shacham
    @rtype: int
863 b693125f Tsachy Shacham
    @return: a bit mask of CPU affinities
864 b693125f Tsachy Shacham

865 b693125f Tsachy Shacham
    """
866 b693125f Tsachy Shacham
    if cpu_list == constants.CPU_PINNING_OFF:
867 b693125f Tsachy Shacham
      return constants.CPU_PINNING_ALL_KVM
868 b693125f Tsachy Shacham
    else:
869 b693125f Tsachy Shacham
      return sum(2 ** cpu for cpu in cpu_list)
870 b693125f Tsachy Shacham
871 b693125f Tsachy Shacham
  @classmethod
872 b693125f Tsachy Shacham
  def _AssignCpuAffinity(cls, cpu_mask, process_id, thread_dict):
873 b693125f Tsachy Shacham
    """Change CPU affinity for running VM according to given CPU mask.
874 b693125f Tsachy Shacham

875 b693125f Tsachy Shacham
    @param cpu_mask: CPU mask as given by the user. e.g. "0-2,4:all:1,3"
876 b693125f Tsachy Shacham
    @type cpu_mask: string
877 b693125f Tsachy Shacham
    @param process_id: process ID of KVM process. Used to pin entire VM
878 b693125f Tsachy Shacham
                       to physical CPUs.
879 b693125f Tsachy Shacham
    @type process_id: int
880 b693125f Tsachy Shacham
    @param thread_dict: map of virtual CPUs to KVM thread IDs
881 b693125f Tsachy Shacham
    @type thread_dict: dict int:int
882 b693125f Tsachy Shacham

883 b693125f Tsachy Shacham
    """
884 b693125f Tsachy Shacham
    # Convert the string CPU mask to a list of list of int's
885 b693125f Tsachy Shacham
    cpu_list = utils.ParseMultiCpuMask(cpu_mask)
886 b693125f Tsachy Shacham
887 b693125f Tsachy Shacham
    if len(cpu_list) == 1:
888 b693125f Tsachy Shacham
      all_cpu_mapping = cpu_list[0]
889 b693125f Tsachy Shacham
      if all_cpu_mapping == constants.CPU_PINNING_OFF:
890 b693125f Tsachy Shacham
        # If CPU pinning has 1 entry that's "all", then do nothing
891 b693125f Tsachy Shacham
        pass
892 b693125f Tsachy Shacham
      else:
893 b693125f Tsachy Shacham
        # If CPU pinning has one non-all entry, map the entire VM to
894 b693125f Tsachy Shacham
        # one set of physical CPUs
895 b693125f Tsachy Shacham
        cls._VerifyAffinityPackage()
896 5ae4945a Iustin Pop
        affinity.set_process_affinity_mask(
897 5ae4945a Iustin Pop
          process_id, cls._BuildAffinityCpuMask(all_cpu_mapping))
898 b693125f Tsachy Shacham
    else:
899 b693125f Tsachy Shacham
      # The number of vCPUs mapped should match the number of vCPUs
900 b693125f Tsachy Shacham
      # reported by KVM. This was already verified earlier, so
901 b693125f Tsachy Shacham
      # here only as a sanity check.
902 b693125f Tsachy Shacham
      assert len(thread_dict) == len(cpu_list)
903 b693125f Tsachy Shacham
      cls._VerifyAffinityPackage()
904 b693125f Tsachy Shacham
905 b693125f Tsachy Shacham
      # For each vCPU, map it to the proper list of physical CPUs
906 b693125f Tsachy Shacham
      for vcpu, i in zip(cpu_list, range(len(cpu_list))):
907 b693125f Tsachy Shacham
        affinity.set_process_affinity_mask(thread_dict[i],
908 5ae4945a Iustin Pop
                                           cls._BuildAffinityCpuMask(vcpu))
909 b693125f Tsachy Shacham
910 b693125f Tsachy Shacham
  def _GetVcpuThreadIds(self, instance_name):
911 b693125f Tsachy Shacham
    """Get a mapping of vCPU no. to thread IDs for the instance
912 b693125f Tsachy Shacham

913 b693125f Tsachy Shacham
    @type instance_name: string
914 b693125f Tsachy Shacham
    @param instance_name: instance in question
915 b693125f Tsachy Shacham
    @rtype: dictionary of int:int
916 b693125f Tsachy Shacham
    @return: a dictionary mapping vCPU numbers to thread IDs
917 b693125f Tsachy Shacham

918 b693125f Tsachy Shacham
    """
919 b693125f Tsachy Shacham
    result = {}
920 b693125f Tsachy Shacham
    output = self._CallMonitorCommand(instance_name, self._CPU_INFO_CMD)
921 b693125f Tsachy Shacham
    for line in output.stdout.splitlines():
922 b693125f Tsachy Shacham
      match = self._CPU_INFO_RE.search(line)
923 b693125f Tsachy Shacham
      if not match:
924 b693125f Tsachy Shacham
        continue
925 b693125f Tsachy Shacham
      grp = map(int, match.groups())
926 b693125f Tsachy Shacham
      result[grp[0]] = grp[1]
927 b693125f Tsachy Shacham
928 b693125f Tsachy Shacham
    return result
929 b693125f Tsachy Shacham
930 1d8a7812 Andrea Spadaccini
  def _ExecuteCpuAffinity(self, instance_name, cpu_mask):
931 1d8a7812 Andrea Spadaccini
    """Complete CPU pinning.
932 b693125f Tsachy Shacham

933 b693125f Tsachy Shacham
    @type instance_name: string
934 b693125f Tsachy Shacham
    @param instance_name: name of instance
935 b693125f Tsachy Shacham
    @type cpu_mask: string
936 b693125f Tsachy Shacham
    @param cpu_mask: CPU pinning mask as entered by user
937 b693125f Tsachy Shacham

938 b693125f Tsachy Shacham
    """
939 1d8a7812 Andrea Spadaccini
    # Get KVM process ID, to be used if need to pin entire VM
940 1d8a7812 Andrea Spadaccini
    _, pid, _ = self._InstancePidAlive(instance_name)
941 1d8a7812 Andrea Spadaccini
    # Get vCPU thread IDs, to be used if need to pin vCPUs separately
942 1d8a7812 Andrea Spadaccini
    thread_dict = self._GetVcpuThreadIds(instance_name)
943 1d8a7812 Andrea Spadaccini
    # Run CPU pinning, based on configured mask
944 1d8a7812 Andrea Spadaccini
    self._AssignCpuAffinity(cpu_mask, pid, thread_dict)
945 b693125f Tsachy Shacham
946 eb58f9b1 Guido Trotter
  def ListInstances(self):
947 eb58f9b1 Guido Trotter
    """Get the list of running instances.
948 eb58f9b1 Guido Trotter

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

952 eb58f9b1 Guido Trotter
    """
953 eb58f9b1 Guido Trotter
    result = []
954 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
955 263b8de6 Guido Trotter
      if self._InstancePidAlive(name)[2]:
956 eb58f9b1 Guido Trotter
        result.append(name)
957 eb58f9b1 Guido Trotter
    return result
958 eb58f9b1 Guido Trotter
959 eb58f9b1 Guido Trotter
  def GetInstanceInfo(self, instance_name):
960 eb58f9b1 Guido Trotter
    """Get instance properties.
961 eb58f9b1 Guido Trotter

962 4fbb3c60 Guido Trotter
    @type instance_name: string
963 c41eea6e Iustin Pop
    @param instance_name: the instance name
964 4fbb3c60 Guido Trotter
    @rtype: tuple of strings
965 4fbb3c60 Guido Trotter
    @return: (name, id, memory, vcpus, stat, times)
966 eb58f9b1 Guido Trotter

967 eb58f9b1 Guido Trotter
    """
968 1122eb25 Iustin Pop
    _, pid, alive = self._InstancePidAlive(instance_name)
969 1f8b3a27 Guido Trotter
    if not alive:
970 eb58f9b1 Guido Trotter
      return None
971 eb58f9b1 Guido Trotter
972 263b8de6 Guido Trotter
    _, memory, vcpus = self._InstancePidInfo(pid)
973 fc84cd5d Guido Trotter
    istat = "---b-"
974 eb58f9b1 Guido Trotter
    times = "0"
975 eb58f9b1 Guido Trotter
976 89da2ff3 Guido Trotter
    try:
977 89da2ff3 Guido Trotter
      qmp = QmpConnection(self._InstanceQmpMonitor(instance_name))
978 89da2ff3 Guido Trotter
      qmp.connect()
979 89da2ff3 Guido Trotter
      vcpus = len(qmp.Execute("query-cpus")[qmp.RETURN_KEY])
980 89da2ff3 Guido Trotter
      # Will fail if ballooning is not enabled, but we can then just resort to
981 89da2ff3 Guido Trotter
      # the value above.
982 89da2ff3 Guido Trotter
      mem_bytes = qmp.Execute("query-balloon")[qmp.RETURN_KEY][qmp.ACTUAL_KEY]
983 89da2ff3 Guido Trotter
      memory = mem_bytes / 1048576
984 89da2ff3 Guido Trotter
    except errors.HypervisorError:
985 89da2ff3 Guido Trotter
      pass
986 89da2ff3 Guido Trotter
987 fc84cd5d Guido Trotter
    return (instance_name, pid, memory, vcpus, istat, times)
988 eb58f9b1 Guido Trotter
989 eb58f9b1 Guido Trotter
  def GetAllInstancesInfo(self):
990 eb58f9b1 Guido Trotter
    """Get properties of all instances.
991 eb58f9b1 Guido Trotter

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

994 eb58f9b1 Guido Trotter
    """
995 eb58f9b1 Guido Trotter
    data = []
996 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
997 263b8de6 Guido Trotter
      try:
998 263b8de6 Guido Trotter
        info = self.GetInstanceInfo(name)
999 263b8de6 Guido Trotter
      except errors.HypervisorError:
1000 3bc145d8 Bernardo Dal Seno
        # Ignore exceptions due to instances being shut down
1001 263b8de6 Guido Trotter
        continue
1002 263b8de6 Guido Trotter
      if info:
1003 263b8de6 Guido Trotter
        data.append(info)
1004 eb58f9b1 Guido Trotter
    return data
1005 eb58f9b1 Guido Trotter
1006 323f9095 Stephen Shirley
  def _GenerateKVMRuntime(self, instance, block_devices, startup_paused):
1007 ee5f20b0 Guido Trotter
    """Generate KVM information to start an instance.
1008 eb58f9b1 Guido Trotter

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

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

1347 38e250ba Guido Trotter
    """
1348 38e250ba Guido Trotter
    try:
1349 38e250ba Guido Trotter
      utils.WriteFile(self._InstanceKVMRuntime(instance_name),
1350 38e250ba Guido Trotter
                      data=data)
1351 90c024f6 Guido Trotter
    except EnvironmentError, err:
1352 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to save KVM runtime file: %s" % err)
1353 38e250ba Guido Trotter
1354 38e250ba Guido Trotter
  def _ReadKVMRuntime(self, instance_name):
1355 38e250ba Guido Trotter
    """Read an instance's KVM runtime
1356 38e250ba Guido Trotter

1357 38e250ba Guido Trotter
    """
1358 38e250ba Guido Trotter
    try:
1359 38e250ba Guido Trotter
      file_content = utils.ReadFile(self._InstanceKVMRuntime(instance_name))
1360 90c024f6 Guido Trotter
    except EnvironmentError, err:
1361 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to load KVM runtime file: %s" % err)
1362 38e250ba Guido Trotter
    return file_content
1363 38e250ba Guido Trotter
1364 38e250ba Guido Trotter
  def _SaveKVMRuntime(self, instance, kvm_runtime):
1365 38e250ba Guido Trotter
    """Save an instance's KVM runtime
1366 38e250ba Guido Trotter

1367 38e250ba Guido Trotter
    """
1368 c2672466 Guido Trotter
    kvm_cmd, kvm_nics, hvparams = kvm_runtime
1369 38e250ba Guido Trotter
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
1370 c2672466 Guido Trotter
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams))
1371 38e250ba Guido Trotter
    self._WriteKVMRuntime(instance.name, serialized_form)
1372 38e250ba Guido Trotter
1373 30e42c4e Guido Trotter
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
1374 38e250ba Guido Trotter
    """Load an instance's KVM runtime
1375 38e250ba Guido Trotter

1376 38e250ba Guido Trotter
    """
1377 30e42c4e Guido Trotter
    if not serialized_runtime:
1378 30e42c4e Guido Trotter
      serialized_runtime = self._ReadKVMRuntime(instance.name)
1379 30e42c4e Guido Trotter
    loaded_runtime = serializer.Load(serialized_runtime)
1380 c2672466 Guido Trotter
    kvm_cmd, serialized_nics, hvparams = loaded_runtime
1381 38e250ba Guido Trotter
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
1382 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
1383 38e250ba Guido Trotter
1384 5d9bfd87 Apollon Oikonomopoulos
  def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None):
1385 76431533 Guido Trotter
    """Run the KVM cmd and check for errors
1386 76431533 Guido Trotter

1387 76431533 Guido Trotter
    @type name: string
1388 76431533 Guido Trotter
    @param name: instance name
1389 76431533 Guido Trotter
    @type kvm_cmd: list of strings
1390 76431533 Guido Trotter
    @param kvm_cmd: runcmd input for kvm
1391 5d9bfd87 Apollon Oikonomopoulos
    @type tap_fds: list of int
1392 5d9bfd87 Apollon Oikonomopoulos
    @param tap_fds: fds of tap devices opened by Ganeti
1393 76431533 Guido Trotter

1394 76431533 Guido Trotter
    """
1395 5d9bfd87 Apollon Oikonomopoulos
    try:
1396 5d9bfd87 Apollon Oikonomopoulos
      result = utils.RunCmd(kvm_cmd, noclose_fds=tap_fds)
1397 5d9bfd87 Apollon Oikonomopoulos
    finally:
1398 5d9bfd87 Apollon Oikonomopoulos
      for fd in tap_fds:
1399 5d9bfd87 Apollon Oikonomopoulos
        utils_wrapper.CloseFdNoError(fd)
1400 5d9bfd87 Apollon Oikonomopoulos
1401 76431533 Guido Trotter
    if result.failed:
1402 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
1403 76431533 Guido Trotter
                                   (name, result.fail_reason, result.output))
1404 76431533 Guido Trotter
    if not self._InstancePidAlive(name)[2]:
1405 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s" % name)
1406 76431533 Guido Trotter
1407 30e42c4e Guido Trotter
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, incoming=None):
1408 839642c2 Iustin Pop
    """Execute a KVM cmd, after completing it with some last minute data.
1409 ee5f20b0 Guido Trotter

1410 30e42c4e Guido Trotter
    @type incoming: tuple of strings
1411 30e42c4e Guido Trotter
    @param incoming: (target_host_ip, port)
1412 30e42c4e Guido Trotter

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

1611 ee5f20b0 Guido Trotter
    """
1612 5905901c Iustin Pop
    self._CheckDown(instance.name)
1613 7238edb5 Iustin Pop
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices,
1614 7238edb5 Iustin Pop
                                           startup_paused)
1615 38e250ba Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1616 ee5f20b0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
1617 ee5f20b0 Guido Trotter
1618 6567aff3 Guido Trotter
  def _CallMonitorCommand(self, instance_name, command):
1619 6567aff3 Guido Trotter
    """Invoke a command on the instance monitor.
1620 6567aff3 Guido Trotter

1621 6567aff3 Guido Trotter
    """
1622 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
1623 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
1624 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
1625 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
1626 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
1627 6567aff3 Guido Trotter
    if result.failed:
1628 6567aff3 Guido Trotter
      msg = ("Failed to send command '%s' to instance %s."
1629 6567aff3 Guido Trotter
             " output: %s, error: %s, fail_reason: %s" %
1630 9798fcae Guido Trotter
             (command, instance_name,
1631 9798fcae Guido Trotter
              result.stdout, result.stderr, result.fail_reason))
1632 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
1633 6567aff3 Guido Trotter
1634 6567aff3 Guido Trotter
    return result
1635 6567aff3 Guido Trotter
1636 b52d85c1 Guido Trotter
  @classmethod
1637 585c8187 Guido Trotter
  def _ParseKVMVersion(cls, text):
1638 585c8187 Guido Trotter
    """Parse the KVM version from the --help output.
1639 585c8187 Guido Trotter

1640 585c8187 Guido Trotter
    @type text: string
1641 585c8187 Guido Trotter
    @param text: output of kvm --help
1642 585c8187 Guido Trotter
    @return: (version, v_maj, v_min, v_rev)
1643 5c3d5dfd Iustin Pop
    @raise errors.HypervisorError: when the KVM version cannot be retrieved
1644 585c8187 Guido Trotter

1645 585c8187 Guido Trotter
    """
1646 585c8187 Guido Trotter
    match = cls._VERSION_RE.search(text.splitlines()[0])
1647 585c8187 Guido Trotter
    if not match:
1648 585c8187 Guido Trotter
      raise errors.HypervisorError("Unable to get KVM version")
1649 585c8187 Guido Trotter
1650 585c8187 Guido Trotter
    v_all = match.group(0)
1651 585c8187 Guido Trotter
    v_maj = int(match.group(1))
1652 585c8187 Guido Trotter
    v_min = int(match.group(2))
1653 585c8187 Guido Trotter
    if match.group(4):
1654 585c8187 Guido Trotter
      v_rev = int(match.group(4))
1655 585c8187 Guido Trotter
    else:
1656 585c8187 Guido Trotter
      v_rev = 0
1657 585c8187 Guido Trotter
    return (v_all, v_maj, v_min, v_rev)
1658 585c8187 Guido Trotter
1659 585c8187 Guido Trotter
  @classmethod
1660 e3b89628 Guido Trotter
  def _GetKVMHelpOutput(cls):
1661 e3b89628 Guido Trotter
    """Return the KVM help output.
1662 e3b89628 Guido Trotter

1663 e3b89628 Guido Trotter
    @return: output of kvm --help
1664 e3b89628 Guido Trotter
    @raise errors.HypervisorError: when the KVM help output cannot be retrieved
1665 e3b89628 Guido Trotter

1666 e3b89628 Guido Trotter
    """
1667 e3b89628 Guido Trotter
    result = utils.RunCmd([constants.KVM_PATH, "--help"])
1668 e3b89628 Guido Trotter
    if result.failed:
1669 e3b89628 Guido Trotter
      raise errors.HypervisorError("Unable to get KVM help output")
1670 e3b89628 Guido Trotter
    return result.output
1671 e3b89628 Guido Trotter
1672 e3b89628 Guido Trotter
  @classmethod
1673 b52d85c1 Guido Trotter
  def _GetKVMVersion(cls):
1674 d7e4a2b1 Andrea Spadaccini
    """Return the installed KVM version.
1675 b52d85c1 Guido Trotter

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

1679 b52d85c1 Guido Trotter
    """
1680 e3b89628 Guido Trotter
    return cls._ParseKVMVersion(cls._GetKVMHelpOutput())
1681 b52d85c1 Guido Trotter
1682 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
1683 eb58f9b1 Guido Trotter
    """Stop an instance.
1684 eb58f9b1 Guido Trotter

1685 eb58f9b1 Guido Trotter
    """
1686 bbcf7ad0 Iustin Pop
    if name is not None and not force:
1687 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
1688 bbcf7ad0 Iustin Pop
    if name is None:
1689 bbcf7ad0 Iustin Pop
      name = instance.name
1690 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
1691 bbcf7ad0 Iustin Pop
    else:
1692 bbcf7ad0 Iustin Pop
      acpi = False
1693 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
1694 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
1695 bbcf7ad0 Iustin Pop
      if force or not acpi:
1696 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
1697 eb58f9b1 Guido Trotter
      else:
1698 d0c8c01d Iustin Pop
        self._CallMonitorCommand(name, "system_powerdown")
1699 eb58f9b1 Guido Trotter
1700 e6ba3320 Dimitris Aragiorgis
  @classmethod
1701 e6ba3320 Dimitris Aragiorgis
  def _GetDefaultMachineVersion(cls):
1702 e6ba3320 Dimitris Aragiorgis
    """Return the default hardware revision (e.g. pc-1.1)
1703 e6ba3320 Dimitris Aragiorgis

1704 e6ba3320 Dimitris Aragiorgis
    """
1705 e6ba3320 Dimitris Aragiorgis
    result = utils.RunCmd([constants.KVM_PATH, "-M", "?"])
1706 e6ba3320 Dimitris Aragiorgis
    if result.failed:
1707 e6ba3320 Dimitris Aragiorgis
      raise errors.HypervisorError("Unable to get default hardware revision")
1708 e6ba3320 Dimitris Aragiorgis
    for line in result.output.splitlines():
1709 e6ba3320 Dimitris Aragiorgis
      match = cls._DEFAULT_MACHINE_VERSION_RE.match(line)
1710 e6ba3320 Dimitris Aragiorgis
      if match:
1711 e6ba3320 Dimitris Aragiorgis
        return match.group(1)
1712 e6ba3320 Dimitris Aragiorgis
1713 e6ba3320 Dimitris Aragiorgis
    return "pc"
1714 e6ba3320 Dimitris Aragiorgis
1715 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
1716 8904b35c Guido Trotter
    """Cleanup after a stopped instance
1717 8904b35c Guido Trotter

1718 8904b35c Guido Trotter
    """
1719 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
1720 8904b35c Guido Trotter
    if pid > 0 and alive:
1721 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
1722 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
1723 eb58f9b1 Guido Trotter
1724 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
1725 eb58f9b1 Guido Trotter
    """Reboot an instance.
1726 eb58f9b1 Guido Trotter

1727 eb58f9b1 Guido Trotter
    """
1728 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
1729 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
1730 eb58f9b1 Guido Trotter
    # to shutdown and restart.
1731 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
1732 1f8b3a27 Guido Trotter
    if not alive:
1733 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
1734 78411c60 Iustin Pop
                                   " not running" % instance.name)
1735 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
1736 f02881e0 Guido Trotter
    # ...first load it...
1737 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
1738 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
1739 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
1740 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
1741 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
1742 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1743 f02881e0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
1744 eb58f9b1 Guido Trotter
1745 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
1746 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
1747 30e42c4e Guido Trotter

1748 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1749 30e42c4e Guido Trotter
    @param instance: instance to be migrated
1750 30e42c4e Guido Trotter
    @rtype: string
1751 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
1752 30e42c4e Guido Trotter

1753 30e42c4e Guido Trotter
    """
1754 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
1755 30e42c4e Guido Trotter
1756 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
1757 30e42c4e Guido Trotter
    """Prepare to accept an instance.
1758 30e42c4e Guido Trotter

1759 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1760 30e42c4e Guido Trotter
    @param instance: instance to be accepted
1761 30e42c4e Guido Trotter
    @type info: string
1762 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
1763 30e42c4e Guido Trotter
    @type target: string
1764 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
1765 30e42c4e Guido Trotter

1766 30e42c4e Guido Trotter
    """
1767 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1768 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
1769 30e42c4e Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, incoming=incoming_address)
1770 30e42c4e Guido Trotter
1771 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationDst(self, instance, info, success):
1772 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the target node.
1773 30e42c4e Guido Trotter

1774 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
1775 30e42c4e Guido Trotter

1776 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1777 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
1778 30e42c4e Guido Trotter

1779 30e42c4e Guido Trotter
    """
1780 30e42c4e Guido Trotter
    if success:
1781 5d9bfd87 Apollon Oikonomopoulos
      kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1782 5d9bfd87 Apollon Oikonomopoulos
      kvm_nics = kvm_runtime[1]
1783 5d9bfd87 Apollon Oikonomopoulos
1784 5d9bfd87 Apollon Oikonomopoulos
      for nic_seq, nic in enumerate(kvm_nics):
1785 cc8a8ed7 Apollon Oikonomopoulos
        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
1786 cc8a8ed7 Apollon Oikonomopoulos
          # Bridged interfaces have already been configured
1787 cc8a8ed7 Apollon Oikonomopoulos
          continue
1788 5d9bfd87 Apollon Oikonomopoulos
        try:
1789 5d9bfd87 Apollon Oikonomopoulos
          tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
1790 5d9bfd87 Apollon Oikonomopoulos
        except EnvironmentError, err:
1791 5d9bfd87 Apollon Oikonomopoulos
          logging.warning("Failed to find host interface for %s NIC #%d: %s",
1792 5d9bfd87 Apollon Oikonomopoulos
                          instance.name, nic_seq, str(err))
1793 5d9bfd87 Apollon Oikonomopoulos
          continue
1794 5d9bfd87 Apollon Oikonomopoulos
        try:
1795 5d9bfd87 Apollon Oikonomopoulos
          self._ConfigureNIC(instance, nic_seq, nic, tap)
1796 5d9bfd87 Apollon Oikonomopoulos
        except errors.HypervisorError, err:
1797 5d9bfd87 Apollon Oikonomopoulos
          logging.warning(str(err))
1798 5d9bfd87 Apollon Oikonomopoulos
1799 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
1800 30e42c4e Guido Trotter
    else:
1801 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
1802 30e42c4e Guido Trotter
1803 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
1804 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
1805 30e42c4e Guido Trotter

1806 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
1807 30e42c4e Guido Trotter
    currently running.
1808 30e42c4e Guido Trotter

1809 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
1810 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
1811 30e42c4e Guido Trotter
    @type target: string
1812 30e42c4e Guido Trotter
    @param target: ip address of the target node
1813 30e42c4e Guido Trotter
    @type live: boolean
1814 30e42c4e Guido Trotter
    @param live: perform a live migration
1815 30e42c4e Guido Trotter

1816 30e42c4e Guido Trotter
    """
1817 58d38b02 Iustin Pop
    instance_name = instance.name
1818 50716be0 Iustin Pop
    port = instance.hvparams[constants.HV_MIGRATION_PORT]
1819 6a1434d7 Andrea Spadaccini
    _, _, alive = self._InstancePidAlive(instance_name)
1820 30e42c4e Guido Trotter
    if not alive:
1821 30e42c4e Guido Trotter
      raise errors.HypervisorError("Instance not running, cannot migrate")
1822 30e42c4e Guido Trotter
1823 30e42c4e Guido Trotter
    if not live:
1824 d0c8c01d Iustin Pop
      self._CallMonitorCommand(instance_name, "stop")
1825 30e42c4e Guido Trotter
1826 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_speed %dm" %
1827 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_BANDWIDTH])
1828 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
1829 e43d4f9f Apollon Oikonomopoulos
1830 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_downtime %dms" %
1831 5ae4945a Iustin Pop
                       instance.hvparams[constants.HV_MIGRATION_DOWNTIME])
1832 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
1833 e43d4f9f Apollon Oikonomopoulos
1834 d0c8c01d Iustin Pop
    migrate_command = "migrate -d tcp:%s:%s" % (target, port)
1835 30e42c4e Guido Trotter
    self._CallMonitorCommand(instance_name, migrate_command)
1836 30e42c4e Guido Trotter
1837 6a1434d7 Andrea Spadaccini
  def FinalizeMigrationSource(self, instance, success, live):
1838 6a1434d7 Andrea Spadaccini
    """Finalize the instance migration on the source node.
1839 6a1434d7 Andrea Spadaccini

1840 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
1841 6a1434d7 Andrea Spadaccini
    @param instance: the instance that was migrated
1842 6a1434d7 Andrea Spadaccini
    @type success: bool
1843 6a1434d7 Andrea Spadaccini
    @param success: whether the migration succeeded or not
1844 6a1434d7 Andrea Spadaccini
    @type live: bool
1845 6a1434d7 Andrea Spadaccini
    @param live: whether the user requested a live migration or not
1846 6a1434d7 Andrea Spadaccini

1847 6a1434d7 Andrea Spadaccini
    """
1848 6a1434d7 Andrea Spadaccini
    if success:
1849 6a1434d7 Andrea Spadaccini
      pidfile, pid, _ = self._InstancePidAlive(instance.name)
1850 6a1434d7 Andrea Spadaccini
      utils.KillProcess(pid)
1851 6a1434d7 Andrea Spadaccini
      self._RemoveInstanceRuntimeFiles(pidfile, instance.name)
1852 6a1434d7 Andrea Spadaccini
    elif live:
1853 6a1434d7 Andrea Spadaccini
      self._CallMonitorCommand(instance.name, self._CONT_CMD)
1854 6a1434d7 Andrea Spadaccini
1855 6a1434d7 Andrea Spadaccini
  def GetMigrationStatus(self, instance):
1856 6a1434d7 Andrea Spadaccini
    """Get the migration status
1857 6a1434d7 Andrea Spadaccini

1858 6a1434d7 Andrea Spadaccini
    @type instance: L{objects.Instance}
1859 6a1434d7 Andrea Spadaccini
    @param instance: the instance that is being migrated
1860 6a1434d7 Andrea Spadaccini
    @rtype: L{objects.MigrationStatus}
1861 6a1434d7 Andrea Spadaccini
    @return: the status of the current migration (one of
1862 6a1434d7 Andrea Spadaccini
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
1863 6a1434d7 Andrea Spadaccini
             progress info that can be retrieved from the hypervisor
1864 6a1434d7 Andrea Spadaccini

1865 6a1434d7 Andrea Spadaccini
    """
1866 d0c8c01d Iustin Pop
    info_command = "info migrate"
1867 6a1434d7 Andrea Spadaccini
    for _ in range(self._MIGRATION_INFO_MAX_BAD_ANSWERS):
1868 6a1434d7 Andrea Spadaccini
      result = self._CallMonitorCommand(instance.name, info_command)
1869 30e42c4e Guido Trotter
      match = self._MIGRATION_STATUS_RE.search(result.stdout)
1870 30e42c4e Guido Trotter
      if not match:
1871 c4e388a5 Guido Trotter
        if not result.stdout:
1872 c4e388a5 Guido Trotter
          logging.info("KVM: empty 'info migrate' result")
1873 c4e388a5 Guido Trotter
        else:
1874 e4dd2299 Guido Trotter
          logging.warning("KVM: unknown 'info migrate' result: %s",
1875 c4e388a5 Guido Trotter
                          result.stdout)
1876 30e42c4e Guido Trotter
      else:
1877 30e42c4e Guido Trotter
        status = match.group(1)
1878 6a1434d7 Andrea Spadaccini
        if status in constants.HV_KVM_MIGRATION_VALID_STATUSES:
1879 6a1434d7 Andrea Spadaccini
          migration_status = objects.MigrationStatus(status=status)
1880 61643226 Andrea Spadaccini
          match = self._MIGRATION_PROGRESS_RE.search(result.stdout)
1881 61643226 Andrea Spadaccini
          if match:
1882 61643226 Andrea Spadaccini
            migration_status.transferred_ram = match.group("transferred")
1883 61643226 Andrea Spadaccini
            migration_status.total_ram = match.group("total")
1884 61643226 Andrea Spadaccini
1885 6a1434d7 Andrea Spadaccini
          return migration_status
1886 30e42c4e Guido Trotter
1887 6a1434d7 Andrea Spadaccini
        logging.warning("KVM: unknown migration status '%s'", status)
1888 6a1434d7 Andrea Spadaccini
1889 6a1434d7 Andrea Spadaccini
      time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
1890 6a1434d7 Andrea Spadaccini
1891 62457f51 Iustin Pop
    return objects.MigrationStatus(status=constants.HV_MIGRATION_FAILED)
1892 30e42c4e Guido Trotter
1893 3d836750 Guido Trotter
  def BalloonInstanceMemory(self, instance, mem):
1894 3d836750 Guido Trotter
    """Balloon an instance memory to a certain value.
1895 3d836750 Guido Trotter

1896 3d836750 Guido Trotter
    @type instance: L{objects.Instance}
1897 3d836750 Guido Trotter
    @param instance: instance to be accepted
1898 3d836750 Guido Trotter
    @type mem: int
1899 3d836750 Guido Trotter
    @param mem: actual memory size to use for instance runtime
1900 3d836750 Guido Trotter

1901 3d836750 Guido Trotter
    """
1902 3d836750 Guido Trotter
    self._CallMonitorCommand(instance.name, "balloon %d" % mem)
1903 3d836750 Guido Trotter
1904 eb58f9b1 Guido Trotter
  def GetNodeInfo(self):
1905 eb58f9b1 Guido Trotter
    """Return information about the node.
1906 eb58f9b1 Guido Trotter

1907 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
1908 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
1909 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
1910 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
1911 34fbc862 Andrea Spadaccini
          - hv_version: the hypervisor version in the form (major, minor,
1912 34fbc862 Andrea Spadaccini
                        revision)
1913 eb58f9b1 Guido Trotter

1914 eb58f9b1 Guido Trotter
    """
1915 34fbc862 Andrea Spadaccini
    result = self.GetLinuxNodeInfo()
1916 34fbc862 Andrea Spadaccini
    _, v_major, v_min, v_rev = self._GetKVMVersion()
1917 34fbc862 Andrea Spadaccini
    result[constants.HV_NODEINFO_KEY_VERSION] = (v_major, v_min, v_rev)
1918 34fbc862 Andrea Spadaccini
    return result
1919 eb58f9b1 Guido Trotter
1920 637ce7f9 Guido Trotter
  @classmethod
1921 55cc0a44 Michael Hanselmann
  def GetInstanceConsole(cls, instance, hvparams, beparams):
1922 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
1923 eb58f9b1 Guido Trotter

1924 eb58f9b1 Guido Trotter
    """
1925 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
1926 9d9bded1 Michael Hanselmann
      cmd = [pathutils.KVM_CONSOLE_WRAPPER,
1927 2f4c951e Stephen Shirley
             constants.SOCAT_PATH, utils.ShellQuote(instance.name),
1928 2f4c951e Stephen Shirley
             utils.ShellQuote(cls._InstanceMonitor(instance.name)),
1929 55cc0a44 Michael Hanselmann
             "STDIO,%s" % cls._SocatUnixConsoleParams(),
1930 55cc0a44 Michael Hanselmann
             "UNIX-CONNECT:%s" % cls._InstanceSerial(instance.name)]
1931 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
1932 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_SSH,
1933 55cc0a44 Michael Hanselmann
                                     host=instance.primary_node,
1934 052783ff Michael Hanselmann
                                     user=constants.SSH_CONSOLE_USER,
1935 55cc0a44 Michael Hanselmann
                                     command=cmd)
1936 3be34f57 Guido Trotter
1937 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
1938 55cc0a44 Michael Hanselmann
    if vnc_bind_address and instance.network_port > constants.VNC_BASE_PORT:
1939 55cc0a44 Michael Hanselmann
      display = instance.network_port - constants.VNC_BASE_PORT
1940 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
1941 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_VNC,
1942 55cc0a44 Michael Hanselmann
                                     host=vnc_bind_address,
1943 55cc0a44 Michael Hanselmann
                                     port=instance.network_port,
1944 55cc0a44 Michael Hanselmann
                                     display=display)
1945 55cc0a44 Michael Hanselmann
1946 4d2cdb5a Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
1947 4d2cdb5a Andrea Spadaccini
    if spice_bind:
1948 4d2cdb5a Andrea Spadaccini
      return objects.InstanceConsole(instance=instance.name,
1949 4d2cdb5a Andrea Spadaccini
                                     kind=constants.CONS_SPICE,
1950 4d2cdb5a Andrea Spadaccini
                                     host=spice_bind,
1951 4d2cdb5a Andrea Spadaccini
                                     port=instance.network_port)
1952 4d2cdb5a Andrea Spadaccini
1953 55cc0a44 Michael Hanselmann
    return objects.InstanceConsole(instance=instance.name,
1954 55cc0a44 Michael Hanselmann
                                   kind=constants.CONS_MESSAGE,
1955 55cc0a44 Michael Hanselmann
                                   message=("No serial shell for instance %s" %
1956 55cc0a44 Michael Hanselmann
                                            instance.name))
1957 eb58f9b1 Guido Trotter
1958 eb58f9b1 Guido Trotter
  def Verify(self):
1959 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
1960 eb58f9b1 Guido Trotter

1961 eb58f9b1 Guido Trotter
    Check that the binary exists.
1962 eb58f9b1 Guido Trotter

1963 eb58f9b1 Guido Trotter
    """
1964 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
1965 eb58f9b1 Guido Trotter
      return "The kvm binary ('%s') does not exist." % constants.KVM_PATH
1966 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
1967 14aa53cb Guido Trotter
      return "The socat binary ('%s') does not exist." % constants.SOCAT_PATH
1968 14aa53cb Guido Trotter
1969 6b5605e8 Iustin Pop
  @classmethod
1970 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
1971 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
1972 6b5605e8 Iustin Pop

1973 6b5605e8 Iustin Pop
    @type hvparams:  dict
1974 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
1975 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
1976 6b5605e8 Iustin Pop

1977 6b5605e8 Iustin Pop
    """
1978 47387b1e Guido Trotter
    super(KVMHypervisor, cls).CheckParameterSyntax(hvparams)
1979 6b5605e8 Iustin Pop
1980 df5ab9f0 Guido Trotter
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
1981 df5ab9f0 Guido Trotter
    if kernel_path:
1982 df5ab9f0 Guido Trotter
      if not hvparams[constants.HV_ROOT_PATH]:
1983 205ab586 Iustin Pop
        raise errors.HypervisorError("Need a root partition for the instance,"
1984 205ab586 Iustin Pop
                                     " if a kernel is defined")
1985 6b5605e8 Iustin Pop
1986 205ab586 Iustin Pop
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
1987 205ab586 Iustin Pop
        not hvparams[constants.HV_VNC_X509]):
1988 205ab586 Iustin Pop
      raise errors.HypervisorError("%s must be defined, if %s is" %
1989 205ab586 Iustin Pop
                                   (constants.HV_VNC_X509,
1990 205ab586 Iustin Pop
                                    constants.HV_VNC_X509_VERIFY))
1991 66d5dbef Guido Trotter
1992 14fd6c81 Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
1993 14fd6c81 Guido Trotter
      serial_speed = hvparams[constants.HV_SERIAL_SPEED]
1994 14fd6c81 Guido Trotter
      valid_speeds = constants.VALID_SERIAL_SPEEDS
1995 14fd6c81 Guido Trotter
      if not serial_speed or serial_speed not in valid_speeds:
1996 14fd6c81 Guido Trotter
        raise errors.HypervisorError("Invalid serial console speed, must be"
1997 14fd6c81 Guido Trotter
                                     " one of: %s" %
1998 14fd6c81 Guido Trotter
                                     utils.CommaJoin(valid_speeds))
1999 14fd6c81 Guido Trotter
2000 66d5dbef Guido Trotter
    boot_order = hvparams[constants.HV_BOOT_ORDER]
2001 205ab586 Iustin Pop
    if (boot_order == constants.HT_BO_CDROM and
2002 205ab586 Iustin Pop
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
2003 835528af Iustin Pop
      raise errors.HypervisorError("Cannot boot from cdrom without an"
2004 835528af Iustin Pop
                                   " ISO path")
2005 f5118ade Iustin Pop
2006 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
2007 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
2008 d19d94db Guido Trotter
      if not hvparams[constants.HV_SECURITY_DOMAIN]:
2009 d19d94db Guido Trotter
        raise errors.HypervisorError("A security domain (user to run kvm as)"
2010 d19d94db Guido Trotter
                                     " must be specified")
2011 d19d94db Guido Trotter
    elif (security_model == constants.HT_SM_NONE or
2012 d19d94db Guido Trotter
          security_model == constants.HT_SM_POOL):
2013 d19d94db Guido Trotter
      if hvparams[constants.HV_SECURITY_DOMAIN]:
2014 d19d94db Guido Trotter
        raise errors.HypervisorError("Cannot have a security domain when the"
2015 d19d94db Guido Trotter
                                     " security model is 'none' or 'pool'")
2016 d19d94db Guido Trotter
2017 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2018 b451c4c7 Andrea Spadaccini
    spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
2019 b1cb62bd Andrea Spadaccini
    if spice_bind:
2020 b1cb62bd Andrea Spadaccini
      if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
2021 b1cb62bd Andrea Spadaccini
        # if an IP version is specified, the spice_bind parameter must be an
2022 b1cb62bd Andrea Spadaccini
        # IP of that family
2023 b1cb62bd Andrea Spadaccini
        if (netutils.IP4Address.IsValid(spice_bind) and
2024 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP4_VERSION):
2025 b1cb62bd Andrea Spadaccini
          raise errors.HypervisorError("spice: got an IPv4 address (%s), but"
2026 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
2027 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
2028 b1cb62bd Andrea Spadaccini
2029 b1cb62bd Andrea Spadaccini
        if (netutils.IP6Address.IsValid(spice_bind) and
2030 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP6_VERSION):
2031 b1cb62bd Andrea Spadaccini
          raise errors.HypervisorError("spice: got an IPv6 address (%s), but"
2032 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
2033 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
2034 b451c4c7 Andrea Spadaccini
    else:
2035 0e1b03b9 Andrea Spadaccini
      # All the other SPICE parameters depend on spice_bind being set. Raise an
2036 0e1b03b9 Andrea Spadaccini
      # error if any of them is set without it.
2037 07788a0b Michael Hanselmann
      for param in _SPICE_ADDITIONAL_PARAMS:
2038 0e1b03b9 Andrea Spadaccini
        if hvparams[param]:
2039 0e1b03b9 Andrea Spadaccini
          raise errors.HypervisorError("spice: %s requires %s to be set" %
2040 0e1b03b9 Andrea Spadaccini
                                       (param, constants.HV_KVM_SPICE_BIND))
2041 b1cb62bd Andrea Spadaccini
2042 d19d94db Guido Trotter
  @classmethod
2043 d19d94db Guido Trotter
  def ValidateParameters(cls, hvparams):
2044 d19d94db Guido Trotter
    """Check the given parameters for validity.
2045 d19d94db Guido Trotter

2046 d19d94db Guido Trotter
    @type hvparams:  dict
2047 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
2048 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
2049 d19d94db Guido Trotter

2050 d19d94db Guido Trotter
    """
2051 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
2052 d19d94db Guido Trotter
2053 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
2054 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
2055 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
2056 d19d94db Guido Trotter
      try:
2057 1feb39ec Guido Trotter
        pwd.getpwnam(username)
2058 d19d94db Guido Trotter
      except KeyError:
2059 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
2060 d19d94db Guido Trotter
                                     % username)
2061 d19d94db Guido Trotter
2062 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
2063 b1cb62bd Andrea Spadaccini
    if spice_bind:
2064 b1cb62bd Andrea Spadaccini
      # only one of VNC and SPICE can be used currently.
2065 b1cb62bd Andrea Spadaccini
      if hvparams[constants.HV_VNC_BIND_ADDRESS]:
2066 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("both SPICE and VNC are configured, but"
2067 b1cb62bd Andrea Spadaccini
                                     " only one of them can be used at a"
2068 b1cb62bd Andrea Spadaccini
                                     " given time.")
2069 b1cb62bd Andrea Spadaccini
2070 b1cb62bd Andrea Spadaccini
      # KVM version should be >= 0.14.0
2071 0ad7f5d8 Guido Trotter
      kvmhelp = cls._GetKVMHelpOutput()
2072 0ad7f5d8 Guido Trotter
      if not cls._SPICE_RE.search(kvmhelp):
2073 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("spice is configured, but it is not"
2074 0ad7f5d8 Guido Trotter
                                     " supported according to kvm --help")
2075 b1cb62bd Andrea Spadaccini
2076 b1cb62bd Andrea Spadaccini
      # if spice_bind is not an IP address, it must be a valid interface
2077 b1cb62bd Andrea Spadaccini
      bound_to_addr = (netutils.IP4Address.IsValid(spice_bind)
2078 b1cb62bd Andrea Spadaccini
                       or netutils.IP6Address.IsValid(spice_bind))
2079 b1cb62bd Andrea Spadaccini
      if not bound_to_addr and not netutils.IsValidInterface(spice_bind):
2080 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("spice: the %s parameter must be either"
2081 b1cb62bd Andrea Spadaccini
                                     " a valid IP address or interface name" %
2082 b1cb62bd Andrea Spadaccini
                                     constants.HV_KVM_SPICE_BIND)
2083 b1cb62bd Andrea Spadaccini
2084 f5118ade Iustin Pop
  @classmethod
2085 f5118ade Iustin Pop
  def PowercycleNode(cls):
2086 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
2087 f5118ade Iustin Pop

2088 f5118ade Iustin Pop
    """
2089 f5118ade Iustin Pop
    cls.LinuxPowercycle()