Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ 596b2459

History | View | Annotate | Download (49.7 kB)

1 eb58f9b1 Guido Trotter
#
2 eb58f9b1 Guido Trotter
#
3 eb58f9b1 Guido Trotter
4 41e794f6 Apollon Oikonomopoulos
# Copyright (C) 2008, 2009, 2010, 2011 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 eb58f9b1 Guido Trotter
38 eb58f9b1 Guido Trotter
from ganeti import utils
39 eb58f9b1 Guido Trotter
from ganeti import constants
40 eb58f9b1 Guido Trotter
from ganeti import errors
41 38e250ba Guido Trotter
from ganeti import serializer
42 38e250ba Guido Trotter
from ganeti import objects
43 76431533 Guido Trotter
from ganeti import uidpool
44 76431533 Guido Trotter
from ganeti import ssconf
45 eb58f9b1 Guido Trotter
from ganeti.hypervisor import hv_base
46 a744b676 Manuel Franceschini
from ganeti import netutils
47 5d9bfd87 Apollon Oikonomopoulos
from ganeti.utils import wrapper as utils_wrapper
48 eb58f9b1 Guido Trotter
49 eb58f9b1 Guido Trotter
50 748e4b5a Michael Hanselmann
_KVM_NETWORK_SCRIPT = constants.SYSCONFDIR + "/ganeti/kvm-vif-bridge"
51 748e4b5a Michael Hanselmann
52 199b2053 Apollon Oikonomopoulos
# TUN/TAP driver constants, taken from <linux/if_tun.h>
53 199b2053 Apollon Oikonomopoulos
# They are architecture-independent and already hardcoded in qemu-kvm source,
54 199b2053 Apollon Oikonomopoulos
# so we can safely include them here.
55 199b2053 Apollon Oikonomopoulos
TUNSETIFF = 0x400454ca
56 199b2053 Apollon Oikonomopoulos
TUNGETIFF = 0x800454d2
57 199b2053 Apollon Oikonomopoulos
TUNGETFEATURES = 0x800454cf
58 199b2053 Apollon Oikonomopoulos
IFF_TAP = 0x0002
59 199b2053 Apollon Oikonomopoulos
IFF_NO_PI = 0x1000
60 199b2053 Apollon Oikonomopoulos
IFF_VNET_HDR = 0x4000
61 199b2053 Apollon Oikonomopoulos
62 199b2053 Apollon Oikonomopoulos
63 199b2053 Apollon Oikonomopoulos
def _ProbeTapVnetHdr(fd):
64 199b2053 Apollon Oikonomopoulos
  """Check whether to enable the IFF_VNET_HDR flag.
65 199b2053 Apollon Oikonomopoulos

66 199b2053 Apollon Oikonomopoulos
  To do this, _all_ of the following conditions must be met:
67 199b2053 Apollon Oikonomopoulos
   1. TUNGETFEATURES ioctl() *must* be implemented
68 199b2053 Apollon Oikonomopoulos
   2. TUNGETFEATURES ioctl() result *must* contain the IFF_VNET_HDR flag
69 199b2053 Apollon Oikonomopoulos
   3. TUNGETIFF ioctl() *must* be implemented; reading the kernel code in
70 199b2053 Apollon Oikonomopoulos
      drivers/net/tun.c there is no way to test this until after the tap device
71 199b2053 Apollon Oikonomopoulos
      has been created using TUNSETIFF, and there is no way to change the
72 199b2053 Apollon Oikonomopoulos
      IFF_VNET_HDR flag after creating the interface, catch-22! However both
73 199b2053 Apollon Oikonomopoulos
      TUNGETIFF and TUNGETFEATURES were introduced in kernel version 2.6.27,
74 199b2053 Apollon Oikonomopoulos
      thus we can expect TUNGETIFF to be present if TUNGETFEATURES is.
75 199b2053 Apollon Oikonomopoulos

76 199b2053 Apollon Oikonomopoulos
   @type fd: int
77 199b2053 Apollon Oikonomopoulos
   @param fd: the file descriptor of /dev/net/tun
78 199b2053 Apollon Oikonomopoulos

79 199b2053 Apollon Oikonomopoulos
  """
80 199b2053 Apollon Oikonomopoulos
  req = struct.pack("I", 0)
81 199b2053 Apollon Oikonomopoulos
  try:
82 199b2053 Apollon Oikonomopoulos
    res = fcntl.ioctl(fd, TUNGETFEATURES, req)
83 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
84 199b2053 Apollon Oikonomopoulos
    logging.warning("TUNGETFEATURES ioctl() not implemented")
85 199b2053 Apollon Oikonomopoulos
    return False
86 199b2053 Apollon Oikonomopoulos
87 199b2053 Apollon Oikonomopoulos
  tunflags = struct.unpack("I", res)[0]
88 199b2053 Apollon Oikonomopoulos
  if tunflags & IFF_VNET_HDR:
89 199b2053 Apollon Oikonomopoulos
    return True
90 199b2053 Apollon Oikonomopoulos
  else:
91 199b2053 Apollon Oikonomopoulos
    logging.warning("Host does not support IFF_VNET_HDR, not enabling")
92 199b2053 Apollon Oikonomopoulos
    return False
93 199b2053 Apollon Oikonomopoulos
94 199b2053 Apollon Oikonomopoulos
95 199b2053 Apollon Oikonomopoulos
def _OpenTap(vnet_hdr=True):
96 199b2053 Apollon Oikonomopoulos
  """Open a new tap device and return its file descriptor.
97 199b2053 Apollon Oikonomopoulos

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

101 199b2053 Apollon Oikonomopoulos
  @type vnet_hdr: boolean
102 199b2053 Apollon Oikonomopoulos
  @param vnet_hdr: Enable the VNET Header
103 199b2053 Apollon Oikonomopoulos
  @return: (ifname, tapfd)
104 199b2053 Apollon Oikonomopoulos
  @rtype: tuple
105 199b2053 Apollon Oikonomopoulos

106 199b2053 Apollon Oikonomopoulos
  """
107 199b2053 Apollon Oikonomopoulos
  try:
108 199b2053 Apollon Oikonomopoulos
    tapfd = os.open("/dev/net/tun", os.O_RDWR)
109 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
110 199b2053 Apollon Oikonomopoulos
    raise errors.HypervisorError("Failed to open /dev/net/tun")
111 199b2053 Apollon Oikonomopoulos
112 199b2053 Apollon Oikonomopoulos
  flags = IFF_TAP | IFF_NO_PI
113 199b2053 Apollon Oikonomopoulos
114 199b2053 Apollon Oikonomopoulos
  if vnet_hdr and _ProbeTapVnetHdr(tapfd):
115 199b2053 Apollon Oikonomopoulos
    flags |= IFF_VNET_HDR
116 199b2053 Apollon Oikonomopoulos
117 199b2053 Apollon Oikonomopoulos
  # The struct ifreq ioctl request (see netdevice(7))
118 199b2053 Apollon Oikonomopoulos
  ifr = struct.pack("16sh", "", flags)
119 199b2053 Apollon Oikonomopoulos
120 199b2053 Apollon Oikonomopoulos
  try:
121 199b2053 Apollon Oikonomopoulos
    res = fcntl.ioctl(tapfd, TUNSETIFF, ifr)
122 199b2053 Apollon Oikonomopoulos
  except EnvironmentError:
123 199b2053 Apollon Oikonomopoulos
    raise errors.HypervisorError("Failed to allocate a new TAP device")
124 199b2053 Apollon Oikonomopoulos
125 199b2053 Apollon Oikonomopoulos
  # Get the interface name from the ioctl
126 199b2053 Apollon Oikonomopoulos
  ifname = struct.unpack("16sh", res)[0].strip("\x00")
127 199b2053 Apollon Oikonomopoulos
  return (ifname, tapfd)
128 199b2053 Apollon Oikonomopoulos
129 748e4b5a Michael Hanselmann
130 eb58f9b1 Guido Trotter
class KVMHypervisor(hv_base.BaseHypervisor):
131 c4469f75 Guido Trotter
  """KVM hypervisor interface"""
132 d271c6fd Iustin Pop
  CAN_MIGRATE = True
133 eb58f9b1 Guido Trotter
134 eb58f9b1 Guido Trotter
  _ROOT_DIR = constants.RUN_GANETI_DIR + "/kvm-hypervisor"
135 a1d79fc6 Guido Trotter
  _PIDS_DIR = _ROOT_DIR + "/pid" # contains live instances pids
136 7548396c Guido Trotter
  _UIDS_DIR = _ROOT_DIR + "/uid" # contains instances reserved uids
137 a1d79fc6 Guido Trotter
  _CTRL_DIR = _ROOT_DIR + "/ctrl" # contains instances control sockets
138 a1d79fc6 Guido Trotter
  _CONF_DIR = _ROOT_DIR + "/conf" # contains instances startup data
139 5d9bfd87 Apollon Oikonomopoulos
  _NICS_DIR = _ROOT_DIR + "/nic" # contains instances nic <-> tap associations
140 4f580fef Sรฉbastien Bocahu
  _KEYMAP_DIR = _ROOT_DIR + "/keymap" # contains instances keymaps
141 547a63b7 Balazs Lecz
  # KVM instances with chroot enabled are started in empty chroot directories.
142 547a63b7 Balazs Lecz
  _CHROOT_DIR = _ROOT_DIR + "/chroot" # for empty chroot directories
143 547a63b7 Balazs Lecz
  # After an instance is stopped, its chroot directory is removed.
144 547a63b7 Balazs Lecz
  # If the chroot directory is not empty, it can't be removed.
145 547a63b7 Balazs Lecz
  # A non-empty chroot directory indicates a possible security incident.
146 547a63b7 Balazs Lecz
  # To support forensics, the non-empty chroot directory is quarantined in
147 547a63b7 Balazs Lecz
  # a separate directory, called 'chroot-quarantine'.
148 547a63b7 Balazs Lecz
  _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine"
149 5d9bfd87 Apollon Oikonomopoulos
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR, _NICS_DIR,
150 547a63b7 Balazs Lecz
           _CHROOT_DIR, _CHROOT_QUARANTINE_DIR]
151 eb58f9b1 Guido Trotter
152 205ab586 Iustin Pop
  PARAMETERS = {
153 205ab586 Iustin Pop
    constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK,
154 205ab586 Iustin Pop
    constants.HV_INITRD_PATH: hv_base.OPT_FILE_CHECK,
155 205ab586 Iustin Pop
    constants.HV_ROOT_PATH: hv_base.NO_CHECK,
156 205ab586 Iustin Pop
    constants.HV_KERNEL_ARGS: hv_base.NO_CHECK,
157 205ab586 Iustin Pop
    constants.HV_ACPI: hv_base.NO_CHECK,
158 205ab586 Iustin Pop
    constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
159 d73ef63f Michael Hanselmann
    constants.HV_VNC_BIND_ADDRESS:
160 8b312c1d Manuel Franceschini
      (False, lambda x: (netutils.IP4Address.IsValid(x) or
161 8b312c1d Manuel Franceschini
                         utils.IsNormAbsPath(x)),
162 d73ef63f Michael Hanselmann
       "the VNC bind address must be either a valid IP address or an absolute"
163 d73ef63f Michael Hanselmann
       " pathname", None, None),
164 205ab586 Iustin Pop
    constants.HV_VNC_TLS: hv_base.NO_CHECK,
165 205ab586 Iustin Pop
    constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
166 205ab586 Iustin Pop
    constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
167 6e6bb8d5 Guido Trotter
    constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
168 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_BIND: hv_base.NO_CHECK, # will be checked later
169 b1cb62bd Andrea Spadaccini
    constants.HV_KVM_SPICE_IP_VERSION:
170 b1cb62bd Andrea Spadaccini
      (False, lambda x: (x == constants.IFACE_NO_IP_VERSION_SPECIFIED or
171 b1cb62bd Andrea Spadaccini
                         x in constants.VALID_IP_VERSIONS),
172 b1cb62bd Andrea Spadaccini
       "the SPICE IP version should be 4 or 6",
173 b1cb62bd Andrea Spadaccini
       None, None),
174 cc130cc7 Marco Casavecchia
    constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
175 205ab586 Iustin Pop
    constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
176 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
177 d73ef63f Michael Hanselmann
    constants.HV_BOOT_ORDER:
178 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
179 d73ef63f Michael Hanselmann
    constants.HV_NIC_TYPE:
180 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_NIC_TYPES),
181 d73ef63f Michael Hanselmann
    constants.HV_DISK_TYPE:
182 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_DISK_TYPES),
183 cc130cc7 Marco Casavecchia
    constants.HV_KVM_CDROM_DISK_TYPE:
184 cc130cc7 Marco Casavecchia
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_DISK_TYPES),
185 d73ef63f Michael Hanselmann
    constants.HV_USB_MOUSE:
186 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_MOUSE_TYPES),
187 4f580fef Sรฉbastien Bocahu
    constants.HV_KEYMAP: hv_base.NO_CHECK,
188 e2d14329 Andrea Spadaccini
    constants.HV_MIGRATION_PORT: hv_base.REQ_NET_PORT_CHECK,
189 e43d4f9f Apollon Oikonomopoulos
    constants.HV_MIGRATION_BANDWIDTH: hv_base.NO_CHECK,
190 e43d4f9f Apollon Oikonomopoulos
    constants.HV_MIGRATION_DOWNTIME: hv_base.NO_CHECK,
191 783a6c0b Iustin Pop
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
192 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
193 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
194 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
195 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
196 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
197 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
198 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
199 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
200 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
201 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
202 4f958b0b Miguel Di Ciurcio Filho
    constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
203 990ade2d Stephen Shirley
    constants.HV_REBOOT_BEHAVIOR:
204 990ade2d Stephen Shirley
      hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS)
205 205ab586 Iustin Pop
    }
206 6b5605e8 Iustin Pop
207 d0c8c01d Iustin Pop
  _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)",
208 30e42c4e Guido Trotter
                                    re.M | re.I)
209 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
210 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
211 30e42c4e Guido Trotter
212 585c8187 Guido Trotter
  _VERSION_RE = re.compile(r"\b(\d+)\.(\d+)(\.(\d+))?\b")
213 b52d85c1 Guido Trotter
214 64bfbc08 Guido Trotter
  ANCILLARY_FILES = [
215 64bfbc08 Guido Trotter
    _KVM_NETWORK_SCRIPT,
216 64bfbc08 Guido Trotter
    ]
217 64bfbc08 Guido Trotter
218 eb58f9b1 Guido Trotter
  def __init__(self):
219 eb58f9b1 Guido Trotter
    hv_base.BaseHypervisor.__init__(self)
220 eb58f9b1 Guido Trotter
    # Let's make sure the directories we need exist, even if the RUN_DIR lives
221 eb58f9b1 Guido Trotter
    # in a tmpfs filesystem or has been otherwise wiped out.
222 29921401 Iustin Pop
    dirs = [(dname, constants.RUN_DIRS_MODE) for dname in self._DIRS]
223 9afb67fe Guido Trotter
    utils.EnsureDirs(dirs)
224 eb58f9b1 Guido Trotter
225 30786fc9 Iustin Pop
  @classmethod
226 30786fc9 Iustin Pop
  def _InstancePidFile(cls, instance_name):
227 98ec75d6 Iustin Pop
    """Returns the instance pidfile.
228 98ec75d6 Iustin Pop

229 98ec75d6 Iustin Pop
    """
230 30786fc9 Iustin Pop
    return utils.PathJoin(cls._PIDS_DIR, instance_name)
231 98ec75d6 Iustin Pop
232 263b8de6 Guido Trotter
  @classmethod
233 7548396c Guido Trotter
  def _InstanceUidFile(cls, instance_name):
234 7548396c Guido Trotter
    """Returns the instance uidfile.
235 7548396c Guido Trotter

236 7548396c Guido Trotter
    """
237 7548396c Guido Trotter
    return utils.PathJoin(cls._UIDS_DIR, instance_name)
238 7548396c Guido Trotter
239 7548396c Guido Trotter
  @classmethod
240 263b8de6 Guido Trotter
  def _InstancePidInfo(cls, pid):
241 263b8de6 Guido Trotter
    """Check pid file for instance information.
242 263b8de6 Guido Trotter

243 263b8de6 Guido Trotter
    Check that a pid file is associated with an instance, and retrieve
244 263b8de6 Guido Trotter
    information from its command line.
245 263b8de6 Guido Trotter

246 263b8de6 Guido Trotter
    @type pid: string or int
247 263b8de6 Guido Trotter
    @param pid: process id of the instance to check
248 263b8de6 Guido Trotter
    @rtype: tuple
249 263b8de6 Guido Trotter
    @return: (instance_name, memory, vcpus)
250 263b8de6 Guido Trotter
    @raise errors.HypervisorError: when an instance cannot be found
251 263b8de6 Guido Trotter

252 263b8de6 Guido Trotter
    """
253 263b8de6 Guido Trotter
    alive = utils.IsProcessAlive(pid)
254 263b8de6 Guido Trotter
    if not alive:
255 263b8de6 Guido Trotter
      raise errors.HypervisorError("Cannot get info for pid %s" % pid)
256 263b8de6 Guido Trotter
257 263b8de6 Guido Trotter
    cmdline_file = utils.PathJoin("/proc", str(pid), "cmdline")
258 263b8de6 Guido Trotter
    try:
259 263b8de6 Guido Trotter
      cmdline = utils.ReadFile(cmdline_file)
260 263b8de6 Guido Trotter
    except EnvironmentError, err:
261 263b8de6 Guido Trotter
      raise errors.HypervisorError("Can't open cmdline file for pid %s: %s" %
262 263b8de6 Guido Trotter
                                   (pid, err))
263 263b8de6 Guido Trotter
264 263b8de6 Guido Trotter
    instance = None
265 263b8de6 Guido Trotter
    memory = 0
266 263b8de6 Guido Trotter
    vcpus = 0
267 263b8de6 Guido Trotter
268 d0c8c01d Iustin Pop
    arg_list = cmdline.split("\x00")
269 263b8de6 Guido Trotter
    while arg_list:
270 e687ec01 Michael Hanselmann
      arg = arg_list.pop(0)
271 263b8de6 Guido Trotter
      if arg == "-name":
272 263b8de6 Guido Trotter
        instance = arg_list.pop(0)
273 263b8de6 Guido Trotter
      elif arg == "-m":
274 263b8de6 Guido Trotter
        memory = int(arg_list.pop(0))
275 263b8de6 Guido Trotter
      elif arg == "-smp":
276 263b8de6 Guido Trotter
        vcpus = int(arg_list.pop(0))
277 263b8de6 Guido Trotter
278 263b8de6 Guido Trotter
    if instance is None:
279 263b8de6 Guido Trotter
      raise errors.HypervisorError("Pid %s doesn't contain a ganeti kvm"
280 263b8de6 Guido Trotter
                                   " instance" % pid)
281 263b8de6 Guido Trotter
282 263b8de6 Guido Trotter
    return (instance, memory, vcpus)
283 263b8de6 Guido Trotter
284 1f8b3a27 Guido Trotter
  def _InstancePidAlive(self, instance_name):
285 263b8de6 Guido Trotter
    """Returns the instance pidfile, pid, and liveness.
286 263b8de6 Guido Trotter

287 263b8de6 Guido Trotter
    @type instance_name: string
288 263b8de6 Guido Trotter
    @param instance_name: instance name
289 263b8de6 Guido Trotter
    @rtype: tuple
290 263b8de6 Guido Trotter
    @return: (pid file name, pid, liveness)
291 1f8b3a27 Guido Trotter

292 1f8b3a27 Guido Trotter
    """
293 98ec75d6 Iustin Pop
    pidfile = self._InstancePidFile(instance_name)
294 1f8b3a27 Guido Trotter
    pid = utils.ReadPidFile(pidfile)
295 263b8de6 Guido Trotter
296 263b8de6 Guido Trotter
    alive = False
297 263b8de6 Guido Trotter
    try:
298 263b8de6 Guido Trotter
      cmd_instance = self._InstancePidInfo(pid)[0]
299 263b8de6 Guido Trotter
      alive = (cmd_instance == instance_name)
300 263b8de6 Guido Trotter
    except errors.HypervisorError:
301 263b8de6 Guido Trotter
      pass
302 1f8b3a27 Guido Trotter
303 1f8b3a27 Guido Trotter
    return (pidfile, pid, alive)
304 1f8b3a27 Guido Trotter
305 5905901c Iustin Pop
  def _CheckDown(self, instance_name):
306 5905901c Iustin Pop
    """Raises an error unless the given instance is down.
307 5905901c Iustin Pop

308 5905901c Iustin Pop
    """
309 5905901c Iustin Pop
    alive = self._InstancePidAlive(instance_name)[2]
310 5905901c Iustin Pop
    if alive:
311 5905901c Iustin Pop
      raise errors.HypervisorError("Failed to start instance %s: %s" %
312 5905901c Iustin Pop
                                   (instance_name, "already running"))
313 5905901c Iustin Pop
314 0df4d98a Guido Trotter
  @classmethod
315 0df4d98a Guido Trotter
  def _InstanceMonitor(cls, instance_name):
316 c4fbefc8 Guido Trotter
    """Returns the instance monitor socket name
317 c4fbefc8 Guido Trotter

318 c4fbefc8 Guido Trotter
    """
319 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.monitor" % instance_name)
320 c4fbefc8 Guido Trotter
321 0df4d98a Guido Trotter
  @classmethod
322 0df4d98a Guido Trotter
  def _InstanceSerial(cls, instance_name):
323 c4fbefc8 Guido Trotter
    """Returns the instance serial socket name
324 c4fbefc8 Guido Trotter

325 c4fbefc8 Guido Trotter
    """
326 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CTRL_DIR, "%s.serial" % instance_name)
327 c4fbefc8 Guido Trotter
328 86d6bc2a Guido Trotter
  @staticmethod
329 86d6bc2a Guido Trotter
  def _SocatUnixConsoleParams():
330 86d6bc2a Guido Trotter
    """Returns the correct parameters for socat
331 86d6bc2a Guido Trotter

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

334 86d6bc2a Guido Trotter
    """
335 fe5b0c42 Michael Hanselmann
    if constants.SOCAT_USE_ESCAPE:
336 86d6bc2a Guido Trotter
      return "raw,echo=0,escape=%s" % constants.SOCAT_ESCAPE_CODE
337 86d6bc2a Guido Trotter
    else:
338 86d6bc2a Guido Trotter
      return "echo=0,icanon=0"
339 86d6bc2a Guido Trotter
340 0df4d98a Guido Trotter
  @classmethod
341 0df4d98a Guido Trotter
  def _InstanceKVMRuntime(cls, instance_name):
342 38e250ba Guido Trotter
    """Returns the instance KVM runtime filename
343 38e250ba Guido Trotter

344 38e250ba Guido Trotter
    """
345 30786fc9 Iustin Pop
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
346 38e250ba Guido Trotter
347 7e66c35b Guido Trotter
  @classmethod
348 547a63b7 Balazs Lecz
  def _InstanceChrootDir(cls, instance_name):
349 547a63b7 Balazs Lecz
    """Returns the name of the KVM chroot dir of the instance
350 547a63b7 Balazs Lecz

351 547a63b7 Balazs Lecz
    """
352 547a63b7 Balazs Lecz
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
353 547a63b7 Balazs Lecz
354 547a63b7 Balazs Lecz
  @classmethod
355 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICDir(cls, instance_name):
356 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the directory holding the tap device files for a
357 5d9bfd87 Apollon Oikonomopoulos
    given instance.
358 5d9bfd87 Apollon Oikonomopoulos

359 5d9bfd87 Apollon Oikonomopoulos
    """
360 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._NICS_DIR, instance_name)
361 5d9bfd87 Apollon Oikonomopoulos
362 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
363 5d9bfd87 Apollon Oikonomopoulos
  def _InstanceNICFile(cls, instance_name, seq):
364 5d9bfd87 Apollon Oikonomopoulos
    """Returns the name of the file containing the tap device for a given NIC
365 5d9bfd87 Apollon Oikonomopoulos

366 5d9bfd87 Apollon Oikonomopoulos
    """
367 5d9bfd87 Apollon Oikonomopoulos
    return utils.PathJoin(cls._InstanceNICDir(instance_name), str(seq))
368 5d9bfd87 Apollon Oikonomopoulos
369 5d9bfd87 Apollon Oikonomopoulos
  @classmethod
370 4f580fef Sรฉbastien Bocahu
  def _InstanceKeymapFile(cls, instance_name):
371 4f580fef Sรฉbastien Bocahu
    """Returns the name of the file containing the keymap for a given instance
372 4f580fef Sรฉbastien Bocahu

373 4f580fef Sรฉbastien Bocahu
    """
374 4f580fef Sรฉbastien Bocahu
    return utils.PathJoin(cls._KEYMAP_DIR, instance_name)
375 4f580fef Sรฉbastien Bocahu
376 4f580fef Sรฉbastien Bocahu
  @classmethod
377 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
378 7548396c Guido Trotter
    """Try to read a uid file
379 7548396c Guido Trotter

380 7548396c Guido Trotter
    """
381 7548396c Guido Trotter
    if os.path.exists(uid_file):
382 7548396c Guido Trotter
      try:
383 682f7601 Guido Trotter
        uid = int(utils.ReadOneLineFile(uid_file))
384 aa0b600b Guido Trotter
        return uid
385 7548396c Guido Trotter
      except EnvironmentError:
386 7548396c Guido Trotter
        logging.warning("Can't read uid file", exc_info=True)
387 7548396c Guido Trotter
      except (TypeError, ValueError):
388 7548396c Guido Trotter
        logging.warning("Can't parse uid file contents", exc_info=True)
389 aa0b600b Guido Trotter
    return None
390 7548396c Guido Trotter
391 7548396c Guido Trotter
  @classmethod
392 7e66c35b Guido Trotter
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
393 547a63b7 Balazs Lecz
    """Removes an instance's rutime sockets/files/dirs.
394 7e66c35b Guido Trotter

395 7e66c35b Guido Trotter
    """
396 7e66c35b Guido Trotter
    utils.RemoveFile(pidfile)
397 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceMonitor(instance_name))
398 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceSerial(instance_name))
399 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceKVMRuntime(instance_name))
400 4f580fef Sรฉbastien Bocahu
    utils.RemoveFile(cls._InstanceKeymapFile(instance_name))
401 7548396c Guido Trotter
    uid_file = cls._InstanceUidFile(instance_name)
402 7548396c Guido Trotter
    uid = cls._TryReadUidFile(uid_file)
403 7548396c Guido Trotter
    utils.RemoveFile(uid_file)
404 7548396c Guido Trotter
    if uid is not None:
405 7548396c Guido Trotter
      uidpool.ReleaseUid(uid)
406 7be85163 Guido Trotter
    try:
407 7be85163 Guido Trotter
      shutil.rmtree(cls._InstanceNICDir(instance_name))
408 7be85163 Guido Trotter
    except OSError, err:
409 7be85163 Guido Trotter
      if err.errno != errno.ENOENT:
410 7be85163 Guido Trotter
        raise
411 547a63b7 Balazs Lecz
    try:
412 547a63b7 Balazs Lecz
      chroot_dir = cls._InstanceChrootDir(instance_name)
413 547a63b7 Balazs Lecz
      utils.RemoveDir(chroot_dir)
414 547a63b7 Balazs Lecz
    except OSError, err:
415 547a63b7 Balazs Lecz
      if err.errno == errno.ENOTEMPTY:
416 547a63b7 Balazs Lecz
        # The chroot directory is expected to be empty, but it isn't.
417 547a63b7 Balazs Lecz
        new_chroot_dir = tempfile.mkdtemp(dir=cls._CHROOT_QUARANTINE_DIR,
418 547a63b7 Balazs Lecz
                                          prefix="%s-%s-" %
419 547a63b7 Balazs Lecz
                                          (instance_name,
420 547a63b7 Balazs Lecz
                                           utils.TimestampForFilename()))
421 547a63b7 Balazs Lecz
        logging.warning("The chroot directory of instance %s can not be"
422 547a63b7 Balazs Lecz
                        " removed as it is not empty. Moving it to the"
423 547a63b7 Balazs Lecz
                        " quarantine instead. Please investigate the"
424 547a63b7 Balazs Lecz
                        " contents (%s) and clean up manually",
425 547a63b7 Balazs Lecz
                        instance_name, new_chroot_dir)
426 547a63b7 Balazs Lecz
        utils.RenameFile(chroot_dir, new_chroot_dir)
427 547a63b7 Balazs Lecz
      else:
428 547a63b7 Balazs Lecz
        raise
429 7e66c35b Guido Trotter
430 748e4b5a Michael Hanselmann
  @staticmethod
431 5d9bfd87 Apollon Oikonomopoulos
  def _ConfigureNIC(instance, seq, nic, tap):
432 5d9bfd87 Apollon Oikonomopoulos
    """Run the network configuration script for a specified NIC
433 eb58f9b1 Guido Trotter

434 eb58f9b1 Guido Trotter
    @param instance: instance we're acting on
435 eb58f9b1 Guido Trotter
    @type instance: instance object
436 eb58f9b1 Guido Trotter
    @param seq: nic sequence number
437 eb58f9b1 Guido Trotter
    @type seq: int
438 eb58f9b1 Guido Trotter
    @param nic: nic we're acting on
439 eb58f9b1 Guido Trotter
    @type nic: nic object
440 5d9bfd87 Apollon Oikonomopoulos
    @param tap: the host's tap interface this NIC corresponds to
441 5d9bfd87 Apollon Oikonomopoulos
    @type tap: str
442 eb58f9b1 Guido Trotter

443 eb58f9b1 Guido Trotter
    """
444 748e4b5a Michael Hanselmann
445 5d9bfd87 Apollon Oikonomopoulos
    if instance.tags:
446 5d9bfd87 Apollon Oikonomopoulos
      tags = " ".join(instance.tags)
447 5d9bfd87 Apollon Oikonomopoulos
    else:
448 5d9bfd87 Apollon Oikonomopoulos
      tags = ""
449 5d9bfd87 Apollon Oikonomopoulos
450 5d9bfd87 Apollon Oikonomopoulos
    env = {
451 5d9bfd87 Apollon Oikonomopoulos
      "PATH": "%s:/sbin:/usr/sbin" % os.environ["PATH"],
452 5d9bfd87 Apollon Oikonomopoulos
      "INSTANCE": instance.name,
453 5d9bfd87 Apollon Oikonomopoulos
      "MAC": nic.mac,
454 5d9bfd87 Apollon Oikonomopoulos
      "MODE": nic.nicparams[constants.NIC_MODE],
455 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE": tap,
456 5d9bfd87 Apollon Oikonomopoulos
      "INTERFACE_INDEX": str(seq),
457 5d9bfd87 Apollon Oikonomopoulos
      "TAGS": tags,
458 5d9bfd87 Apollon Oikonomopoulos
    }
459 5d9bfd87 Apollon Oikonomopoulos
460 5d9bfd87 Apollon Oikonomopoulos
    if nic.ip:
461 5d9bfd87 Apollon Oikonomopoulos
      env["IP"] = nic.ip
462 5d9bfd87 Apollon Oikonomopoulos
463 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_LINK]:
464 5d9bfd87 Apollon Oikonomopoulos
      env["LINK"] = nic.nicparams[constants.NIC_LINK]
465 5d9bfd87 Apollon Oikonomopoulos
466 5d9bfd87 Apollon Oikonomopoulos
    if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
467 5d9bfd87 Apollon Oikonomopoulos
      env["BRIDGE"] = nic.nicparams[constants.NIC_LINK]
468 5d9bfd87 Apollon Oikonomopoulos
469 5d9bfd87 Apollon Oikonomopoulos
    result = utils.RunCmd([constants.KVM_IFUP, tap], env=env)
470 5d9bfd87 Apollon Oikonomopoulos
    if result.failed:
471 5d9bfd87 Apollon Oikonomopoulos
      raise errors.HypervisorError("Failed to configure interface %s: %s."
472 5d9bfd87 Apollon Oikonomopoulos
                                   " Network configuration script output: %s" %
473 5d9bfd87 Apollon Oikonomopoulos
                                   (tap, result.fail_reason, result.output))
474 eb58f9b1 Guido Trotter
475 eb58f9b1 Guido Trotter
  def ListInstances(self):
476 eb58f9b1 Guido Trotter
    """Get the list of running instances.
477 eb58f9b1 Guido Trotter

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

481 eb58f9b1 Guido Trotter
    """
482 eb58f9b1 Guido Trotter
    result = []
483 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
484 263b8de6 Guido Trotter
      if self._InstancePidAlive(name)[2]:
485 eb58f9b1 Guido Trotter
        result.append(name)
486 eb58f9b1 Guido Trotter
    return result
487 eb58f9b1 Guido Trotter
488 eb58f9b1 Guido Trotter
  def GetInstanceInfo(self, instance_name):
489 eb58f9b1 Guido Trotter
    """Get instance properties.
490 eb58f9b1 Guido Trotter

491 4fbb3c60 Guido Trotter
    @type instance_name: string
492 c41eea6e Iustin Pop
    @param instance_name: the instance name
493 4fbb3c60 Guido Trotter
    @rtype: tuple of strings
494 4fbb3c60 Guido Trotter
    @return: (name, id, memory, vcpus, stat, times)
495 eb58f9b1 Guido Trotter

496 eb58f9b1 Guido Trotter
    """
497 1122eb25 Iustin Pop
    _, pid, alive = self._InstancePidAlive(instance_name)
498 1f8b3a27 Guido Trotter
    if not alive:
499 eb58f9b1 Guido Trotter
      return None
500 eb58f9b1 Guido Trotter
501 263b8de6 Guido Trotter
    _, memory, vcpus = self._InstancePidInfo(pid)
502 eb58f9b1 Guido Trotter
    stat = "---b-"
503 eb58f9b1 Guido Trotter
    times = "0"
504 eb58f9b1 Guido Trotter
505 eb58f9b1 Guido Trotter
    return (instance_name, pid, memory, vcpus, stat, times)
506 eb58f9b1 Guido Trotter
507 eb58f9b1 Guido Trotter
  def GetAllInstancesInfo(self):
508 eb58f9b1 Guido Trotter
    """Get properties of all instances.
509 eb58f9b1 Guido Trotter

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

512 eb58f9b1 Guido Trotter
    """
513 eb58f9b1 Guido Trotter
    data = []
514 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
515 263b8de6 Guido Trotter
      try:
516 263b8de6 Guido Trotter
        info = self.GetInstanceInfo(name)
517 263b8de6 Guido Trotter
      except errors.HypervisorError:
518 263b8de6 Guido Trotter
        continue
519 263b8de6 Guido Trotter
      if info:
520 263b8de6 Guido Trotter
        data.append(info)
521 eb58f9b1 Guido Trotter
    return data
522 eb58f9b1 Guido Trotter
523 323f9095 Stephen Shirley
  def _GenerateKVMRuntime(self, instance, block_devices, startup_paused):
524 ee5f20b0 Guido Trotter
    """Generate KVM information to start an instance.
525 eb58f9b1 Guido Trotter

526 eb58f9b1 Guido Trotter
    """
527 440351f8 Andrea Spadaccini
    _, v_major, v_min, _ = self._GetKVMVersion()
528 4304964a Guido Trotter
529 e687ec01 Michael Hanselmann
    pidfile = self._InstancePidFile(instance.name)
530 eb58f9b1 Guido Trotter
    kvm = constants.KVM_PATH
531 eb58f9b1 Guido Trotter
    kvm_cmd = [kvm]
532 c6a39fc2 Guido Trotter
    # used just by the vnc server, if enabled
533 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-name", instance.name])
534 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-m", instance.beparams[constants.BE_MEMORY]])
535 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-smp", instance.beparams[constants.BE_VCPUS]])
536 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-pidfile", pidfile])
537 d0c8c01d Iustin Pop
    kvm_cmd.extend(["-daemonize"])
538 6b5605e8 Iustin Pop
    if not instance.hvparams[constants.HV_ACPI]:
539 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-no-acpi"])
540 323f9095 Stephen Shirley
    if startup_paused:
541 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-S"])
542 990ade2d Stephen Shirley
    if instance.hvparams[constants.HV_REBOOT_BEHAVIOR] == \
543 990ade2d Stephen Shirley
        constants.INSTANCE_REBOOT_EXIT:
544 990ade2d Stephen Shirley
      kvm_cmd.extend(["-no-reboot"])
545 eb58f9b1 Guido Trotter
546 a985b417 Iustin Pop
    hvp = instance.hvparams
547 835528af Iustin Pop
    boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK
548 835528af Iustin Pop
    boot_cdrom = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_CDROM
549 cc130cc7 Marco Casavecchia
    boot_floppy = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_FLOPPY
550 835528af Iustin Pop
    boot_network = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_NETWORK
551 8745c3d7 Guido Trotter
552 b1cb62bd Andrea Spadaccini
    self.ValidateParameters(hvp)
553 b1cb62bd Andrea Spadaccini
554 7ba594c0 Guido Trotter
    if hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED:
555 7ba594c0 Guido Trotter
      kvm_cmd.extend(["-enable-kvm"])
556 7ba594c0 Guido Trotter
    elif hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_DISABLED:
557 7ba594c0 Guido Trotter
      kvm_cmd.extend(["-disable-kvm"])
558 7ba594c0 Guido Trotter
559 8745c3d7 Guido Trotter
    if boot_network:
560 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-boot", "n"])
561 1213604d Guido Trotter
562 a985b417 Iustin Pop
    disk_type = hvp[constants.HV_DISK_TYPE]
563 1213604d Guido Trotter
    if disk_type == constants.HT_DISK_PARAVIRTUAL:
564 d0c8c01d Iustin Pop
      if_val = ",if=virtio"
565 1213604d Guido Trotter
    else:
566 d0c8c01d Iustin Pop
      if_val = ",if=%s" % disk_type
567 19572932 Iustin Pop
    # Cache mode
568 19572932 Iustin Pop
    disk_cache = hvp[constants.HV_DISK_CACHE]
569 41e794f6 Apollon Oikonomopoulos
    if instance.disk_template in constants.DTS_EXT_MIRROR:
570 41e794f6 Apollon Oikonomopoulos
      if disk_cache != "none":
571 41e794f6 Apollon Oikonomopoulos
        # TODO: make this a hard error, instead of a silent overwrite
572 41e794f6 Apollon Oikonomopoulos
        logging.warning("KVM: overriding disk_cache setting '%s' with 'none'"
573 41e794f6 Apollon Oikonomopoulos
                        " to prevent shared storage corruption on migration",
574 41e794f6 Apollon Oikonomopoulos
                        disk_cache)
575 41e794f6 Apollon Oikonomopoulos
      cache_val = ",cache=none"
576 41e794f6 Apollon Oikonomopoulos
    elif disk_cache != constants.HT_CACHE_DEFAULT:
577 19572932 Iustin Pop
      cache_val = ",cache=%s" % disk_cache
578 19572932 Iustin Pop
    else:
579 19572932 Iustin Pop
      cache_val = ""
580 069cfbf1 Iustin Pop
    for cfdev, dev_path in block_devices:
581 d34b16d7 Iustin Pop
      if cfdev.mode != constants.DISK_RDWR:
582 d34b16d7 Iustin Pop
        raise errors.HypervisorError("Instance has read-only disks which"
583 d34b16d7 Iustin Pop
                                     " are not supported by KVM")
584 eb58f9b1 Guido Trotter
      # TODO: handle FD_LOOP and FD_BLKTAP (?)
585 4304964a Guido Trotter
      boot_val = ""
586 66d5dbef Guido Trotter
      if boot_disk:
587 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-boot", "c"])
588 66d5dbef Guido Trotter
        boot_disk = False
589 4304964a Guido Trotter
        if (v_major, v_min) < (0, 14) and disk_type != constants.HT_DISK_IDE:
590 4304964a Guido Trotter
          boot_val = ",boot=on"
591 eb58f9b1 Guido Trotter
592 d0c8c01d Iustin Pop
      drive_val = "file=%s,format=raw%s%s%s" % (dev_path, if_val, boot_val,
593 19572932 Iustin Pop
                                                cache_val)
594 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
595 eb58f9b1 Guido Trotter
596 cc130cc7 Marco Casavecchia
    #Now we can specify a different device type for CDROM devices.
597 cc130cc7 Marco Casavecchia
    cdrom_disk_type = hvp[constants.HV_KVM_CDROM_DISK_TYPE]
598 cc130cc7 Marco Casavecchia
    if not cdrom_disk_type:
599 cc130cc7 Marco Casavecchia
      cdrom_disk_type = disk_type
600 cc130cc7 Marco Casavecchia
601 a985b417 Iustin Pop
    iso_image = hvp[constants.HV_CDROM_IMAGE_PATH]
602 66d5dbef Guido Trotter
    if iso_image:
603 d0c8c01d Iustin Pop
      options = ",format=raw,media=cdrom"
604 66d5dbef Guido Trotter
      if boot_cdrom:
605 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-boot", "d"])
606 cc130cc7 Marco Casavecchia
        if cdrom_disk_type != constants.HT_DISK_IDE:
607 d0c8c01d Iustin Pop
          options = "%s,boot=on,if=%s" % (options, constants.HT_DISK_IDE)
608 cc130cc7 Marco Casavecchia
        else:
609 d0c8c01d Iustin Pop
          options = "%s,boot=on" % options
610 9dd363eb Guido Trotter
      else:
611 cc130cc7 Marco Casavecchia
        if cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
612 d0c8c01d Iustin Pop
          if_val = ",if=virtio"
613 9cf4321f Apollon Oikonomopoulos
        else:
614 d0c8c01d Iustin Pop
          if_val = ",if=%s" % cdrom_disk_type
615 d0c8c01d Iustin Pop
        options = "%s%s" % (options, if_val)
616 d0c8c01d Iustin Pop
      drive_val = "file=%s%s" % (iso_image, options)
617 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
618 66d5dbef Guido Trotter
619 cc130cc7 Marco Casavecchia
    iso_image2 = hvp[constants.HV_KVM_CDROM2_IMAGE_PATH]
620 cc130cc7 Marco Casavecchia
    if iso_image2:
621 d0c8c01d Iustin Pop
      options = ",format=raw,media=cdrom"
622 cc130cc7 Marco Casavecchia
      if cdrom_disk_type == constants.HT_DISK_PARAVIRTUAL:
623 d0c8c01d Iustin Pop
        if_val = ",if=virtio"
624 cc130cc7 Marco Casavecchia
      else:
625 d0c8c01d Iustin Pop
        if_val = ",if=%s" % cdrom_disk_type
626 d0c8c01d Iustin Pop
      options = "%s%s" % (options, if_val)
627 d0c8c01d Iustin Pop
      drive_val = "file=%s%s" % (iso_image2, options)
628 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
629 cc130cc7 Marco Casavecchia
630 cc130cc7 Marco Casavecchia
    floppy_image = hvp[constants.HV_KVM_FLOPPY_IMAGE_PATH]
631 cc130cc7 Marco Casavecchia
    if floppy_image:
632 d0c8c01d Iustin Pop
      options = ",format=raw,media=disk"
633 cc130cc7 Marco Casavecchia
      if boot_floppy:
634 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-boot", "a"])
635 d0c8c01d Iustin Pop
        options = "%s,boot=on" % options
636 d0c8c01d Iustin Pop
      if_val = ",if=floppy"
637 d0c8c01d Iustin Pop
      options = "%s%s" % (options, if_val)
638 d0c8c01d Iustin Pop
      drive_val = "file=%s%s" % (floppy_image, options)
639 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-drive", drive_val])
640 cc130cc7 Marco Casavecchia
641 a985b417 Iustin Pop
    kernel_path = hvp[constants.HV_KERNEL_PATH]
642 df5ab9f0 Guido Trotter
    if kernel_path:
643 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-kernel", kernel_path])
644 a985b417 Iustin Pop
      initrd_path = hvp[constants.HV_INITRD_PATH]
645 df5ab9f0 Guido Trotter
      if initrd_path:
646 d0c8c01d Iustin Pop
        kvm_cmd.extend(["-initrd", initrd_path])
647 d0c8c01d Iustin Pop
      root_append = ["root=%s" % hvp[constants.HV_ROOT_PATH],
648 07813a9e Iustin Pop
                     hvp[constants.HV_KERNEL_ARGS]]
649 07813a9e Iustin Pop
      if hvp[constants.HV_SERIAL_CONSOLE]:
650 d0c8c01d Iustin Pop
        root_append.append("console=ttyS0,38400")
651 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-append", " ".join(root_append)])
652 eb58f9b1 Guido Trotter
653 4f958b0b Miguel Di Ciurcio Filho
    mem_path = hvp[constants.HV_MEM_PATH]
654 4f958b0b Miguel Di Ciurcio Filho
    if mem_path:
655 9d3015f9 Guido Trotter
      kvm_cmd.extend(["-mem-path", mem_path, "-mem-prealloc"])
656 4f958b0b Miguel Di Ciurcio Filho
657 596b2459 Guido Trotter
    monitor_dev = ("unix:%s,server,nowait" %
658 596b2459 Guido Trotter
                   self._InstanceMonitor(instance.name))
659 596b2459 Guido Trotter
    kvm_cmd.extend(["-monitor", monitor_dev])
660 596b2459 Guido Trotter
    if hvp[constants.HV_SERIAL_CONSOLE]:
661 596b2459 Guido Trotter
      serial_dev = ("unix:%s,server,nowait" %
662 596b2459 Guido Trotter
                    self._InstanceSerial(instance.name))
663 596b2459 Guido Trotter
      kvm_cmd.extend(["-serial", serial_dev])
664 596b2459 Guido Trotter
    else:
665 596b2459 Guido Trotter
      kvm_cmd.extend(["-serial", "none"])
666 596b2459 Guido Trotter
667 a985b417 Iustin Pop
    mouse_type = hvp[constants.HV_USB_MOUSE]
668 31f6f67a Guido Trotter
    vnc_bind_address = hvp[constants.HV_VNC_BIND_ADDRESS]
669 596b2459 Guido Trotter
    spice_bind = hvp[constants.HV_KVM_SPICE_BIND]
670 596b2459 Guido Trotter
    spice_ip_version = None
671 31f6f67a Guido Trotter
672 11344a50 Guido Trotter
    if mouse_type:
673 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usb"])
674 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usbdevice", mouse_type])
675 31f6f67a Guido Trotter
    elif vnc_bind_address:
676 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-usbdevice", constants.HT_MOUSE_TABLET])
677 11344a50 Guido Trotter
678 4f580fef Sรฉbastien Bocahu
    keymap = hvp[constants.HV_KEYMAP]
679 4f580fef Sรฉbastien Bocahu
    if keymap:
680 4f580fef Sรฉbastien Bocahu
      keymap_path = self._InstanceKeymapFile(instance.name)
681 4f580fef Sรฉbastien Bocahu
      # If a keymap file is specified, KVM won't use its internal defaults. By
682 4f580fef Sรฉbastien Bocahu
      # first including the "en-us" layout, an error on loading the actual
683 4f580fef Sรฉbastien Bocahu
      # layout (e.g. because it can't be found) won't lead to a non-functional
684 4f580fef Sรฉbastien Bocahu
      # keyboard. A keyboard with incorrect keys is still better than none.
685 4f580fef Sรฉbastien Bocahu
      utils.WriteFile(keymap_path, data="include en-us\ninclude %s\n" % keymap)
686 4f580fef Sรฉbastien Bocahu
      kvm_cmd.extend(["-k", keymap_path])
687 4f580fef Sรฉbastien Bocahu
688 8470c8db Guido Trotter
    if vnc_bind_address:
689 8b312c1d Manuel Franceschini
      if netutils.IP4Address.IsValid(vnc_bind_address):
690 377d74c9 Guido Trotter
        if instance.network_port > constants.VNC_BASE_PORT:
691 377d74c9 Guido Trotter
          display = instance.network_port - constants.VNC_BASE_PORT
692 14f5f1b6 Manuel Franceschini
          if vnc_bind_address == constants.IP4_ADDRESS_ANY:
693 d0c8c01d Iustin Pop
            vnc_arg = ":%d" % (display)
694 8447f52b Guido Trotter
          else:
695 d0c8c01d Iustin Pop
            vnc_arg = "%s:%d" % (vnc_bind_address, display)
696 8470c8db Guido Trotter
        else:
697 8447f52b Guido Trotter
          logging.error("Network port is not a valid VNC display (%d < %d)."
698 07b8a2b5 Iustin Pop
                        " Not starting VNC", instance.network_port,
699 07b8a2b5 Iustin Pop
                        constants.VNC_BASE_PORT)
700 d0c8c01d Iustin Pop
          vnc_arg = "none"
701 8b2d1013 Guido Trotter
702 8b2d1013 Guido Trotter
        # Only allow tls and other option when not binding to a file, for now.
703 8b2d1013 Guido Trotter
        # kvm/qemu gets confused otherwise about the filename to use.
704 d0c8c01d Iustin Pop
        vnc_append = ""
705 a985b417 Iustin Pop
        if hvp[constants.HV_VNC_TLS]:
706 d0c8c01d Iustin Pop
          vnc_append = "%s,tls" % vnc_append
707 a985b417 Iustin Pop
          if hvp[constants.HV_VNC_X509_VERIFY]:
708 d0c8c01d Iustin Pop
            vnc_append = "%s,x509verify=%s" % (vnc_append,
709 a985b417 Iustin Pop
                                               hvp[constants.HV_VNC_X509])
710 a985b417 Iustin Pop
          elif hvp[constants.HV_VNC_X509]:
711 d0c8c01d Iustin Pop
            vnc_append = "%s,x509=%s" % (vnc_append,
712 a985b417 Iustin Pop
                                         hvp[constants.HV_VNC_X509])
713 6e6bb8d5 Guido Trotter
        if hvp[constants.HV_VNC_PASSWORD_FILE]:
714 d0c8c01d Iustin Pop
          vnc_append = "%s,password" % vnc_append
715 6e6bb8d5 Guido Trotter
716 d0c8c01d Iustin Pop
        vnc_arg = "%s%s" % (vnc_arg, vnc_append)
717 8b2d1013 Guido Trotter
718 8470c8db Guido Trotter
      else:
719 d0c8c01d Iustin Pop
        vnc_arg = "unix:%s/%s.vnc" % (vnc_bind_address, instance.name)
720 8b2d1013 Guido Trotter
721 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-vnc", vnc_arg])
722 596b2459 Guido Trotter
    elif spice_bind:
723 b1cb62bd Andrea Spadaccini
      if netutils.IsValidInterface(spice_bind):
724 b1cb62bd Andrea Spadaccini
        # The user specified a network interface, we have to figure out the IP
725 b1cb62bd Andrea Spadaccini
        # address.
726 b1cb62bd Andrea Spadaccini
        addresses = netutils.GetInterfaceIpAddresses(spice_bind)
727 b1cb62bd Andrea Spadaccini
        spice_ip_version = hvp[constants.HV_KVM_SPICE_IP_VERSION]
728 b1cb62bd Andrea Spadaccini
729 b1cb62bd Andrea Spadaccini
        # if the user specified an IP version and the interface does not
730 b1cb62bd Andrea Spadaccini
        # have that kind of IP addresses, throw an exception
731 b1cb62bd Andrea Spadaccini
        if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
732 b1cb62bd Andrea Spadaccini
          if not addresses[spice_ip_version]:
733 b1cb62bd Andrea Spadaccini
            raise errors.HypervisorError("spice: unable to get an IPv%s address"
734 b1cb62bd Andrea Spadaccini
                                         " for %s" % (spice_ip_version,
735 b1cb62bd Andrea Spadaccini
                                                      spice_bind))
736 b1cb62bd Andrea Spadaccini
737 b1cb62bd Andrea Spadaccini
        # the user did not specify an IP version, we have to figure it out
738 b1cb62bd Andrea Spadaccini
        elif (addresses[constants.IP4_VERSION] and
739 b1cb62bd Andrea Spadaccini
              addresses[constants.IP6_VERSION]):
740 b1cb62bd Andrea Spadaccini
          # we have both ipv4 and ipv6, let's use the cluster default IP
741 b1cb62bd Andrea Spadaccini
          # version
742 b1cb62bd Andrea Spadaccini
          cluster_family = ssconf.SimpleStore().GetPrimaryIPFamily()
743 b1cb62bd Andrea Spadaccini
          spice_ip_version = netutils.IPAddress.GetVersionFromAddressFamily(
744 b1cb62bd Andrea Spadaccini
              cluster_family)
745 b1cb62bd Andrea Spadaccini
        elif addresses[constants.IP4_VERSION]:
746 b1cb62bd Andrea Spadaccini
          spice_ip_version = constants.IP4_VERSION
747 b845c8a1 Andrea Spadaccini
        elif addresses[constants.IP6_VERSION]:
748 b1cb62bd Andrea Spadaccini
          spice_ip_version = constants.IP6_VERSION
749 b845c8a1 Andrea Spadaccini
        else:
750 b845c8a1 Andrea Spadaccini
          raise errors.HypervisorError("spice: unable to get an IP address"
751 b845c8a1 Andrea Spadaccini
                                       " for %s" % (spice_bind))
752 b1cb62bd Andrea Spadaccini
753 b1cb62bd Andrea Spadaccini
        spice_address = addresses[spice_ip_version][0]
754 b1cb62bd Andrea Spadaccini
755 b1cb62bd Andrea Spadaccini
      else:
756 b1cb62bd Andrea Spadaccini
        # spice_bind is known to be a valid IP address, because
757 b1cb62bd Andrea Spadaccini
        # ValidateParameters checked it.
758 b1cb62bd Andrea Spadaccini
        spice_address = spice_bind
759 b1cb62bd Andrea Spadaccini
760 11ae7a0a Andrea Spadaccini
      spice_arg = "addr=%s,port=%s,disable-ticketing" % (spice_address,
761 11ae7a0a Andrea Spadaccini
                                                         instance.network_port)
762 11ae7a0a Andrea Spadaccini
      if spice_ip_version:
763 11ae7a0a Andrea Spadaccini
        spice_arg = "%s,ipv%s" % (spice_arg, spice_ip_version)
764 b1cb62bd Andrea Spadaccini
765 b1cb62bd Andrea Spadaccini
      logging.info("KVM: SPICE will listen on port %s", instance.network_port)
766 b1cb62bd Andrea Spadaccini
      kvm_cmd.extend(["-spice", spice_arg])
767 b1cb62bd Andrea Spadaccini
768 596b2459 Guido Trotter
    else:
769 596b2459 Guido Trotter
      kvm_cmd.extend(["-nographic"])
770 596b2459 Guido Trotter
771 6b970cef Jun Futagawa
    if hvp[constants.HV_USE_LOCALTIME]:
772 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-localtime"])
773 6b970cef Jun Futagawa
774 547a63b7 Balazs Lecz
    if hvp[constants.HV_KVM_USE_CHROOT]:
775 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-chroot", self._InstanceChrootDir(instance.name)])
776 547a63b7 Balazs Lecz
777 ee5f20b0 Guido Trotter
    # Save the current instance nics, but defer their expansion as parameters,
778 ee5f20b0 Guido Trotter
    # as we'll need to generate executable temp files for them.
779 ee5f20b0 Guido Trotter
    kvm_nics = instance.nics
780 a985b417 Iustin Pop
    hvparams = hvp
781 ee5f20b0 Guido Trotter
782 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
783 ee5f20b0 Guido Trotter
784 38e250ba Guido Trotter
  def _WriteKVMRuntime(self, instance_name, data):
785 38e250ba Guido Trotter
    """Write an instance's KVM runtime
786 38e250ba Guido Trotter

787 38e250ba Guido Trotter
    """
788 38e250ba Guido Trotter
    try:
789 38e250ba Guido Trotter
      utils.WriteFile(self._InstanceKVMRuntime(instance_name),
790 38e250ba Guido Trotter
                      data=data)
791 90c024f6 Guido Trotter
    except EnvironmentError, err:
792 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to save KVM runtime file: %s" % err)
793 38e250ba Guido Trotter
794 38e250ba Guido Trotter
  def _ReadKVMRuntime(self, instance_name):
795 38e250ba Guido Trotter
    """Read an instance's KVM runtime
796 38e250ba Guido Trotter

797 38e250ba Guido Trotter
    """
798 38e250ba Guido Trotter
    try:
799 38e250ba Guido Trotter
      file_content = utils.ReadFile(self._InstanceKVMRuntime(instance_name))
800 90c024f6 Guido Trotter
    except EnvironmentError, err:
801 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to load KVM runtime file: %s" % err)
802 38e250ba Guido Trotter
    return file_content
803 38e250ba Guido Trotter
804 38e250ba Guido Trotter
  def _SaveKVMRuntime(self, instance, kvm_runtime):
805 38e250ba Guido Trotter
    """Save an instance's KVM runtime
806 38e250ba Guido Trotter

807 38e250ba Guido Trotter
    """
808 c2672466 Guido Trotter
    kvm_cmd, kvm_nics, hvparams = kvm_runtime
809 38e250ba Guido Trotter
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
810 c2672466 Guido Trotter
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams))
811 38e250ba Guido Trotter
    self._WriteKVMRuntime(instance.name, serialized_form)
812 38e250ba Guido Trotter
813 30e42c4e Guido Trotter
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
814 38e250ba Guido Trotter
    """Load an instance's KVM runtime
815 38e250ba Guido Trotter

816 38e250ba Guido Trotter
    """
817 30e42c4e Guido Trotter
    if not serialized_runtime:
818 30e42c4e Guido Trotter
      serialized_runtime = self._ReadKVMRuntime(instance.name)
819 30e42c4e Guido Trotter
    loaded_runtime = serializer.Load(serialized_runtime)
820 c2672466 Guido Trotter
    kvm_cmd, serialized_nics, hvparams = loaded_runtime
821 38e250ba Guido Trotter
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
822 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
823 38e250ba Guido Trotter
824 5d9bfd87 Apollon Oikonomopoulos
  def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None):
825 76431533 Guido Trotter
    """Run the KVM cmd and check for errors
826 76431533 Guido Trotter

827 76431533 Guido Trotter
    @type name: string
828 76431533 Guido Trotter
    @param name: instance name
829 76431533 Guido Trotter
    @type kvm_cmd: list of strings
830 76431533 Guido Trotter
    @param kvm_cmd: runcmd input for kvm
831 5d9bfd87 Apollon Oikonomopoulos
    @type tap_fds: list of int
832 5d9bfd87 Apollon Oikonomopoulos
    @param tap_fds: fds of tap devices opened by Ganeti
833 76431533 Guido Trotter

834 76431533 Guido Trotter
    """
835 5d9bfd87 Apollon Oikonomopoulos
    try:
836 5d9bfd87 Apollon Oikonomopoulos
      result = utils.RunCmd(kvm_cmd, noclose_fds=tap_fds)
837 5d9bfd87 Apollon Oikonomopoulos
    finally:
838 5d9bfd87 Apollon Oikonomopoulos
      for fd in tap_fds:
839 5d9bfd87 Apollon Oikonomopoulos
        utils_wrapper.CloseFdNoError(fd)
840 5d9bfd87 Apollon Oikonomopoulos
841 76431533 Guido Trotter
    if result.failed:
842 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
843 76431533 Guido Trotter
                                   (name, result.fail_reason, result.output))
844 76431533 Guido Trotter
    if not self._InstancePidAlive(name)[2]:
845 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s" % name)
846 76431533 Guido Trotter
847 30e42c4e Guido Trotter
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, incoming=None):
848 ee5f20b0 Guido Trotter
    """Execute a KVM cmd, after completing it with some last minute data
849 ee5f20b0 Guido Trotter

850 30e42c4e Guido Trotter
    @type incoming: tuple of strings
851 30e42c4e Guido Trotter
    @param incoming: (target_host_ip, port)
852 30e42c4e Guido Trotter

853 ee5f20b0 Guido Trotter
    """
854 297e6e53 Guido Trotter
    # Small _ExecuteKVMRuntime hv parameters programming howto:
855 297e6e53 Guido Trotter
    #  - conf_hvp contains the parameters as configured on ganeti. they might
856 297e6e53 Guido Trotter
    #    have changed since the instance started; only use them if the change
857 297e6e53 Guido Trotter
    #    won't affect the inside of the instance (which hasn't been rebooted).
858 297e6e53 Guido Trotter
    #  - up_hvp contains the parameters as they were when the instance was
859 297e6e53 Guido Trotter
    #    started, plus any new parameter which has been added between ganeti
860 297e6e53 Guido Trotter
    #    versions: it is paramount that those default to a value which won't
861 297e6e53 Guido Trotter
    #    affect the inside of the instance as well.
862 297e6e53 Guido Trotter
    conf_hvp = instance.hvparams
863 5905901c Iustin Pop
    name = instance.name
864 5905901c Iustin Pop
    self._CheckDown(name)
865 ee5f20b0 Guido Trotter
866 ee5f20b0 Guido Trotter
    temp_files = []
867 ee5f20b0 Guido Trotter
868 297e6e53 Guido Trotter
    kvm_cmd, kvm_nics, up_hvp = kvm_runtime
869 297e6e53 Guido Trotter
    up_hvp = objects.FillDict(conf_hvp, up_hvp)
870 ee5f20b0 Guido Trotter
871 440351f8 Andrea Spadaccini
    _, v_major, v_min, _ = self._GetKVMVersion()
872 4b784cf8 Miguel Di Ciurcio Filho
873 297e6e53 Guido Trotter
    # We know it's safe to run as a different user upon migration, so we'll use
874 297e6e53 Guido Trotter
    # the latest conf, from conf_hvp.
875 297e6e53 Guido Trotter
    security_model = conf_hvp[constants.HV_SECURITY_MODEL]
876 cef34868 Guido Trotter
    if security_model == constants.HT_SM_USER:
877 297e6e53 Guido Trotter
      kvm_cmd.extend(["-runas", conf_hvp[constants.HV_SECURITY_DOMAIN]])
878 cef34868 Guido Trotter
879 297e6e53 Guido Trotter
    # We have reasons to believe changing something like the nic driver/type
880 297e6e53 Guido Trotter
    # upon migration won't exactly fly with the instance kernel, so for nic
881 297e6e53 Guido Trotter
    # related parameters we'll use up_hvp
882 5d9bfd87 Apollon Oikonomopoulos
    tapfds = []
883 5d9bfd87 Apollon Oikonomopoulos
    taps = []
884 ee5f20b0 Guido Trotter
    if not kvm_nics:
885 fbe27e2b Guido Trotter
      kvm_cmd.extend(["-net", "none"])
886 ee5f20b0 Guido Trotter
    else:
887 5d9bfd87 Apollon Oikonomopoulos
      vnet_hdr = False
888 fbe27e2b Guido Trotter
      tap_extra = ""
889 297e6e53 Guido Trotter
      nic_type = up_hvp[constants.HV_NIC_TYPE]
890 37f88dc6 Guido Trotter
      if nic_type == constants.HT_NIC_PARAVIRTUAL:
891 4b784cf8 Miguel Di Ciurcio Filho
        # From version 0.12.0, kvm uses a new sintax for network configuration.
892 049383d9 Adeodato Simo
        if (v_major, v_min) >= (0, 12):
893 4b784cf8 Miguel Di Ciurcio Filho
          nic_model = "virtio-net-pci"
894 5d9bfd87 Apollon Oikonomopoulos
          vnet_hdr = True
895 4b784cf8 Miguel Di Ciurcio Filho
        else:
896 4b784cf8 Miguel Di Ciurcio Filho
          nic_model = "virtio"
897 4b784cf8 Miguel Di Ciurcio Filho
898 297e6e53 Guido Trotter
        if up_hvp[constants.HV_VHOST_NET]:
899 4b784cf8 Miguel Di Ciurcio Filho
          # vhost_net is only available from version 0.13.0 or newer
900 049383d9 Adeodato Simo
          if (v_major, v_min) >= (0, 13):
901 4b784cf8 Miguel Di Ciurcio Filho
            tap_extra = ",vhost=on"
902 4b784cf8 Miguel Di Ciurcio Filho
          else:
903 4b784cf8 Miguel Di Ciurcio Filho
            raise errors.HypervisorError("vhost_net is configured"
904 4b784cf8 Miguel Di Ciurcio Filho
                                        " but it is not available")
905 37f88dc6 Guido Trotter
      else:
906 4b784cf8 Miguel Di Ciurcio Filho
        nic_model = nic_type
907 37f88dc6 Guido Trotter
908 ee5f20b0 Guido Trotter
      for nic_seq, nic in enumerate(kvm_nics):
909 5d9bfd87 Apollon Oikonomopoulos
        tapname, tapfd = _OpenTap(vnet_hdr)
910 5d9bfd87 Apollon Oikonomopoulos
        tapfds.append(tapfd)
911 5d9bfd87 Apollon Oikonomopoulos
        taps.append(tapname)
912 049383d9 Adeodato Simo
        if (v_major, v_min) >= (0, 12):
913 4b784cf8 Miguel Di Ciurcio Filho
          nic_val = "%s,mac=%s,netdev=netdev%s" % (nic_model, nic.mac, nic_seq)
914 5d9bfd87 Apollon Oikonomopoulos
          tap_val = "type=tap,id=netdev%s,fd=%d%s" % (nic_seq, tapfd, tap_extra)
915 4b784cf8 Miguel Di Ciurcio Filho
          kvm_cmd.extend(["-netdev", tap_val, "-device", nic_val])
916 4b784cf8 Miguel Di Ciurcio Filho
        else:
917 049383d9 Adeodato Simo
          nic_val = "nic,vlan=%s,macaddr=%s,model=%s" % (nic_seq,
918 049383d9 Adeodato Simo
                                                         nic.mac, nic_model)
919 5d9bfd87 Apollon Oikonomopoulos
          tap_val = "tap,vlan=%s,fd=%d" % (nic_seq, tapfd)
920 4b784cf8 Miguel Di Ciurcio Filho
          kvm_cmd.extend(["-net", tap_val, "-net", nic_val])
921 ee5f20b0 Guido Trotter
922 30e42c4e Guido Trotter
    if incoming:
923 30e42c4e Guido Trotter
      target, port = incoming
924 d0c8c01d Iustin Pop
      kvm_cmd.extend(["-incoming", "tcp:%s:%s" % (target, port)])
925 30e42c4e Guido Trotter
926 297e6e53 Guido Trotter
    # Changing the vnc password doesn't bother the guest that much. At most it
927 297e6e53 Guido Trotter
    # will surprise people who connect to it. Whether positively or negatively
928 297e6e53 Guido Trotter
    # it's debatable.
929 297e6e53 Guido Trotter
    vnc_pwd_file = conf_hvp[constants.HV_VNC_PASSWORD_FILE]
930 6e6bb8d5 Guido Trotter
    vnc_pwd = None
931 6e6bb8d5 Guido Trotter
    if vnc_pwd_file:
932 6e6bb8d5 Guido Trotter
      try:
933 682f7601 Guido Trotter
        vnc_pwd = utils.ReadOneLineFile(vnc_pwd_file, strict=True)
934 6e6bb8d5 Guido Trotter
      except EnvironmentError, err:
935 6e6bb8d5 Guido Trotter
        raise errors.HypervisorError("Failed to open VNC password file %s: %s"
936 6e6bb8d5 Guido Trotter
                                     % (vnc_pwd_file, err))
937 6e6bb8d5 Guido Trotter
938 297e6e53 Guido Trotter
    if conf_hvp[constants.HV_KVM_USE_CHROOT]:
939 547a63b7 Balazs Lecz
      utils.EnsureDirs([(self._InstanceChrootDir(name),
940 547a63b7 Balazs Lecz
                         constants.SECURE_DIR_MODE)])
941 547a63b7 Balazs Lecz
942 cc8a8ed7 Apollon Oikonomopoulos
    # Configure the network now for starting instances and bridged interfaces,
943 cc8a8ed7 Apollon Oikonomopoulos
    # during FinalizeMigration for incoming instances' routed interfaces
944 cc8a8ed7 Apollon Oikonomopoulos
    for nic_seq, nic in enumerate(kvm_nics):
945 cc8a8ed7 Apollon Oikonomopoulos
      if (incoming and
946 cc8a8ed7 Apollon Oikonomopoulos
          nic.nicparams[constants.NIC_MODE] != constants.NIC_MODE_BRIDGED):
947 cc8a8ed7 Apollon Oikonomopoulos
        continue
948 cc8a8ed7 Apollon Oikonomopoulos
      self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
949 5d9bfd87 Apollon Oikonomopoulos
950 76431533 Guido Trotter
    if security_model == constants.HT_SM_POOL:
951 76431533 Guido Trotter
      ss = ssconf.SimpleStore()
952 76431533 Guido Trotter
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n")
953 76431533 Guido Trotter
      all_uids = set(uidpool.ExpandUidPool(uid_pool))
954 76431533 Guido Trotter
      uid = uidpool.RequestUnusedUid(all_uids)
955 76431533 Guido Trotter
      try:
956 76431533 Guido Trotter
        username = pwd.getpwuid(uid.GetUid()).pw_name
957 76431533 Guido Trotter
        kvm_cmd.extend(["-runas", username])
958 5d9bfd87 Apollon Oikonomopoulos
        self._RunKVMCmd(name, kvm_cmd, tapfds)
959 76431533 Guido Trotter
      except:
960 76431533 Guido Trotter
        uidpool.ReleaseUid(uid)
961 76431533 Guido Trotter
        raise
962 76431533 Guido Trotter
      else:
963 76431533 Guido Trotter
        uid.Unlock()
964 3af16328 Apollon Oikonomopoulos
        utils.WriteFile(self._InstanceUidFile(name), data=uid.AsStr())
965 76431533 Guido Trotter
    else:
966 5d9bfd87 Apollon Oikonomopoulos
      self._RunKVMCmd(name, kvm_cmd, tapfds)
967 5d9bfd87 Apollon Oikonomopoulos
968 5d9bfd87 Apollon Oikonomopoulos
    utils.EnsureDirs([(self._InstanceNICDir(instance.name),
969 5d9bfd87 Apollon Oikonomopoulos
                     constants.RUN_DIRS_MODE)])
970 5d9bfd87 Apollon Oikonomopoulos
    for nic_seq, tap in enumerate(taps):
971 5d9bfd87 Apollon Oikonomopoulos
      utils.WriteFile(self._InstanceNICFile(instance.name, nic_seq),
972 5d9bfd87 Apollon Oikonomopoulos
                      data=tap)
973 eb58f9b1 Guido Trotter
974 6e6bb8d5 Guido Trotter
    if vnc_pwd:
975 d0c8c01d Iustin Pop
      change_cmd = "change vnc password %s" % vnc_pwd
976 6e6bb8d5 Guido Trotter
      self._CallMonitorCommand(instance.name, change_cmd)
977 6e6bb8d5 Guido Trotter
978 08137f9e Iustin Pop
    for filename in temp_files:
979 08137f9e Iustin Pop
      utils.RemoveFile(filename)
980 eb58f9b1 Guido Trotter
981 323f9095 Stephen Shirley
  def StartInstance(self, instance, block_devices, startup_paused):
982 ee5f20b0 Guido Trotter
    """Start an instance.
983 ee5f20b0 Guido Trotter

984 ee5f20b0 Guido Trotter
    """
985 5905901c Iustin Pop
    self._CheckDown(instance.name)
986 7238edb5 Iustin Pop
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices,
987 7238edb5 Iustin Pop
                                           startup_paused)
988 38e250ba Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
989 ee5f20b0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
990 ee5f20b0 Guido Trotter
991 6567aff3 Guido Trotter
  def _CallMonitorCommand(self, instance_name, command):
992 6567aff3 Guido Trotter
    """Invoke a command on the instance monitor.
993 6567aff3 Guido Trotter

994 6567aff3 Guido Trotter
    """
995 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
996 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
997 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
998 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
999 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
1000 6567aff3 Guido Trotter
    if result.failed:
1001 6567aff3 Guido Trotter
      msg = ("Failed to send command '%s' to instance %s."
1002 6567aff3 Guido Trotter
             " output: %s, error: %s, fail_reason: %s" %
1003 9798fcae Guido Trotter
             (command, instance_name,
1004 9798fcae Guido Trotter
              result.stdout, result.stderr, result.fail_reason))
1005 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
1006 6567aff3 Guido Trotter
1007 6567aff3 Guido Trotter
    return result
1008 6567aff3 Guido Trotter
1009 b52d85c1 Guido Trotter
  @classmethod
1010 585c8187 Guido Trotter
  def _ParseKVMVersion(cls, text):
1011 585c8187 Guido Trotter
    """Parse the KVM version from the --help output.
1012 585c8187 Guido Trotter

1013 585c8187 Guido Trotter
    @type text: string
1014 585c8187 Guido Trotter
    @param text: output of kvm --help
1015 585c8187 Guido Trotter
    @return: (version, v_maj, v_min, v_rev)
1016 585c8187 Guido Trotter
    @raise L{errors.HypervisorError}: when the KVM version cannot be retrieved
1017 585c8187 Guido Trotter

1018 585c8187 Guido Trotter
    """
1019 585c8187 Guido Trotter
    match = cls._VERSION_RE.search(text.splitlines()[0])
1020 585c8187 Guido Trotter
    if not match:
1021 585c8187 Guido Trotter
      raise errors.HypervisorError("Unable to get KVM version")
1022 585c8187 Guido Trotter
1023 585c8187 Guido Trotter
    v_all = match.group(0)
1024 585c8187 Guido Trotter
    v_maj = int(match.group(1))
1025 585c8187 Guido Trotter
    v_min = int(match.group(2))
1026 585c8187 Guido Trotter
    if match.group(4):
1027 585c8187 Guido Trotter
      v_rev = int(match.group(4))
1028 585c8187 Guido Trotter
    else:
1029 585c8187 Guido Trotter
      v_rev = 0
1030 585c8187 Guido Trotter
    return (v_all, v_maj, v_min, v_rev)
1031 585c8187 Guido Trotter
1032 585c8187 Guido Trotter
  @classmethod
1033 b52d85c1 Guido Trotter
  def _GetKVMVersion(cls):
1034 d7e4a2b1 Andrea Spadaccini
    """Return the installed KVM version.
1035 b52d85c1 Guido Trotter

1036 440351f8 Andrea Spadaccini
    @return: (version, v_maj, v_min, v_rev)
1037 d7e4a2b1 Andrea Spadaccini
    @raise L{errors.HypervisorError}: when the KVM version cannot be retrieved
1038 b52d85c1 Guido Trotter

1039 b52d85c1 Guido Trotter
    """
1040 b52d85c1 Guido Trotter
    result = utils.RunCmd([constants.KVM_PATH, "--help"])
1041 b52d85c1 Guido Trotter
    if result.failed:
1042 440351f8 Andrea Spadaccini
      raise errors.HypervisorError("Unable to get KVM version")
1043 585c8187 Guido Trotter
    return cls._ParseKVMVersion(result.output)
1044 b52d85c1 Guido Trotter
1045 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
1046 eb58f9b1 Guido Trotter
    """Stop an instance.
1047 eb58f9b1 Guido Trotter

1048 eb58f9b1 Guido Trotter
    """
1049 bbcf7ad0 Iustin Pop
    if name is not None and not force:
1050 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
1051 bbcf7ad0 Iustin Pop
    if name is None:
1052 bbcf7ad0 Iustin Pop
      name = instance.name
1053 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
1054 bbcf7ad0 Iustin Pop
    else:
1055 bbcf7ad0 Iustin Pop
      acpi = False
1056 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
1057 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
1058 bbcf7ad0 Iustin Pop
      if force or not acpi:
1059 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
1060 eb58f9b1 Guido Trotter
      else:
1061 d0c8c01d Iustin Pop
        self._CallMonitorCommand(name, "system_powerdown")
1062 eb58f9b1 Guido Trotter
1063 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
1064 8904b35c Guido Trotter
    """Cleanup after a stopped instance
1065 8904b35c Guido Trotter

1066 8904b35c Guido Trotter
    """
1067 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
1068 8904b35c Guido Trotter
    if pid > 0 and alive:
1069 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
1070 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
1071 eb58f9b1 Guido Trotter
1072 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
1073 eb58f9b1 Guido Trotter
    """Reboot an instance.
1074 eb58f9b1 Guido Trotter

1075 eb58f9b1 Guido Trotter
    """
1076 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
1077 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
1078 eb58f9b1 Guido Trotter
    # to shutdown and restart.
1079 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
1080 1f8b3a27 Guido Trotter
    if not alive:
1081 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
1082 78411c60 Iustin Pop
                                   " not running" % instance.name)
1083 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
1084 f02881e0 Guido Trotter
    # ...first load it...
1085 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
1086 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
1087 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
1088 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
1089 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
1090 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
1091 f02881e0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
1092 eb58f9b1 Guido Trotter
1093 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
1094 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
1095 30e42c4e Guido Trotter

1096 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1097 30e42c4e Guido Trotter
    @param instance: instance to be migrated
1098 30e42c4e Guido Trotter
    @rtype: string
1099 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
1100 30e42c4e Guido Trotter

1101 30e42c4e Guido Trotter
    """
1102 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
1103 30e42c4e Guido Trotter
1104 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
1105 30e42c4e Guido Trotter
    """Prepare to accept an instance.
1106 30e42c4e Guido Trotter

1107 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1108 30e42c4e Guido Trotter
    @param instance: instance to be accepted
1109 30e42c4e Guido Trotter
    @type info: string
1110 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
1111 30e42c4e Guido Trotter
    @type target: string
1112 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
1113 30e42c4e Guido Trotter

1114 30e42c4e Guido Trotter
    """
1115 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1116 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
1117 30e42c4e Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, incoming=incoming_address)
1118 30e42c4e Guido Trotter
1119 30e42c4e Guido Trotter
  def FinalizeMigration(self, instance, info, success):
1120 30e42c4e Guido Trotter
    """Finalize an instance migration.
1121 30e42c4e Guido Trotter

1122 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
1123 30e42c4e Guido Trotter

1124 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
1125 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
1126 30e42c4e Guido Trotter

1127 30e42c4e Guido Trotter
    """
1128 30e42c4e Guido Trotter
    if success:
1129 5d9bfd87 Apollon Oikonomopoulos
      kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
1130 5d9bfd87 Apollon Oikonomopoulos
      kvm_nics = kvm_runtime[1]
1131 5d9bfd87 Apollon Oikonomopoulos
1132 5d9bfd87 Apollon Oikonomopoulos
      for nic_seq, nic in enumerate(kvm_nics):
1133 cc8a8ed7 Apollon Oikonomopoulos
        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
1134 cc8a8ed7 Apollon Oikonomopoulos
          # Bridged interfaces have already been configured
1135 cc8a8ed7 Apollon Oikonomopoulos
          continue
1136 5d9bfd87 Apollon Oikonomopoulos
        try:
1137 5d9bfd87 Apollon Oikonomopoulos
          tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
1138 5d9bfd87 Apollon Oikonomopoulos
        except EnvironmentError, err:
1139 5d9bfd87 Apollon Oikonomopoulos
          logging.warning("Failed to find host interface for %s NIC #%d: %s",
1140 5d9bfd87 Apollon Oikonomopoulos
                          instance.name, nic_seq, str(err))
1141 5d9bfd87 Apollon Oikonomopoulos
          continue
1142 5d9bfd87 Apollon Oikonomopoulos
        try:
1143 5d9bfd87 Apollon Oikonomopoulos
          self._ConfigureNIC(instance, nic_seq, nic, tap)
1144 5d9bfd87 Apollon Oikonomopoulos
        except errors.HypervisorError, err:
1145 5d9bfd87 Apollon Oikonomopoulos
          logging.warning(str(err))
1146 5d9bfd87 Apollon Oikonomopoulos
1147 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
1148 30e42c4e Guido Trotter
    else:
1149 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
1150 30e42c4e Guido Trotter
1151 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
1152 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
1153 30e42c4e Guido Trotter

1154 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
1155 30e42c4e Guido Trotter
    currently running.
1156 30e42c4e Guido Trotter

1157 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
1158 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
1159 30e42c4e Guido Trotter
    @type target: string
1160 30e42c4e Guido Trotter
    @param target: ip address of the target node
1161 30e42c4e Guido Trotter
    @type live: boolean
1162 30e42c4e Guido Trotter
    @param live: perform a live migration
1163 30e42c4e Guido Trotter

1164 30e42c4e Guido Trotter
    """
1165 58d38b02 Iustin Pop
    instance_name = instance.name
1166 50716be0 Iustin Pop
    port = instance.hvparams[constants.HV_MIGRATION_PORT]
1167 30e42c4e Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
1168 30e42c4e Guido Trotter
    if not alive:
1169 30e42c4e Guido Trotter
      raise errors.HypervisorError("Instance not running, cannot migrate")
1170 30e42c4e Guido Trotter
1171 30e42c4e Guido Trotter
    if not live:
1172 d0c8c01d Iustin Pop
      self._CallMonitorCommand(instance_name, "stop")
1173 30e42c4e Guido Trotter
1174 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_speed %dm" %
1175 e43d4f9f Apollon Oikonomopoulos
        instance.hvparams[constants.HV_MIGRATION_BANDWIDTH])
1176 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
1177 e43d4f9f Apollon Oikonomopoulos
1178 d0c8c01d Iustin Pop
    migrate_command = ("migrate_set_downtime %dms" %
1179 e43d4f9f Apollon Oikonomopoulos
        instance.hvparams[constants.HV_MIGRATION_DOWNTIME])
1180 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
1181 e43d4f9f Apollon Oikonomopoulos
1182 d0c8c01d Iustin Pop
    migrate_command = "migrate -d tcp:%s:%s" % (target, port)
1183 30e42c4e Guido Trotter
    self._CallMonitorCommand(instance_name, migrate_command)
1184 30e42c4e Guido Trotter
1185 d0c8c01d Iustin Pop
    info_command = "info migrate"
1186 30e42c4e Guido Trotter
    done = False
1187 c4e388a5 Guido Trotter
    broken_answers = 0
1188 30e42c4e Guido Trotter
    while not done:
1189 30e42c4e Guido Trotter
      result = self._CallMonitorCommand(instance_name, info_command)
1190 30e42c4e Guido Trotter
      match = self._MIGRATION_STATUS_RE.search(result.stdout)
1191 30e42c4e Guido Trotter
      if not match:
1192 c4e388a5 Guido Trotter
        broken_answers += 1
1193 c4e388a5 Guido Trotter
        if not result.stdout:
1194 c4e388a5 Guido Trotter
          logging.info("KVM: empty 'info migrate' result")
1195 c4e388a5 Guido Trotter
        else:
1196 e4dd2299 Guido Trotter
          logging.warning("KVM: unknown 'info migrate' result: %s",
1197 c4e388a5 Guido Trotter
                          result.stdout)
1198 c4e388a5 Guido Trotter
        time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
1199 30e42c4e Guido Trotter
      else:
1200 30e42c4e Guido Trotter
        status = match.group(1)
1201 d0c8c01d Iustin Pop
        if status == "completed":
1202 30e42c4e Guido Trotter
          done = True
1203 d0c8c01d Iustin Pop
        elif status == "active":
1204 c4e388a5 Guido Trotter
          # reset the broken answers count
1205 c4e388a5 Guido Trotter
          broken_answers = 0
1206 c4e388a5 Guido Trotter
          time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
1207 d0c8c01d Iustin Pop
        elif status == "failed" or status == "cancelled":
1208 c087266c Guido Trotter
          if not live:
1209 c087266c Guido Trotter
            self._CallMonitorCommand(instance_name, 'cont')
1210 c087266c Guido Trotter
          raise errors.HypervisorError("Migration %s at the kvm level" %
1211 c087266c Guido Trotter
                                       status)
1212 30e42c4e Guido Trotter
        else:
1213 c4e388a5 Guido Trotter
          logging.warning("KVM: unknown migration status '%s'", status)
1214 c4e388a5 Guido Trotter
          broken_answers += 1
1215 c4e388a5 Guido Trotter
          time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
1216 c4e388a5 Guido Trotter
      if broken_answers >= self._MIGRATION_INFO_MAX_BAD_ANSWERS:
1217 c4e388a5 Guido Trotter
        raise errors.HypervisorError("Too many 'info migrate' broken answers")
1218 30e42c4e Guido Trotter
1219 30e42c4e Guido Trotter
    utils.KillProcess(pid)
1220 7b381438 Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
1221 30e42c4e Guido Trotter
1222 eb58f9b1 Guido Trotter
  def GetNodeInfo(self):
1223 eb58f9b1 Guido Trotter
    """Return information about the node.
1224 eb58f9b1 Guido Trotter

1225 572e52bf Iustin Pop
    This is just a wrapper over the base GetLinuxNodeInfo method.
1226 572e52bf Iustin Pop

1227 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
1228 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
1229 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
1230 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
1231 eb58f9b1 Guido Trotter

1232 eb58f9b1 Guido Trotter
    """
1233 572e52bf Iustin Pop
    return self.GetLinuxNodeInfo()
1234 eb58f9b1 Guido Trotter
1235 637ce7f9 Guido Trotter
  @classmethod
1236 55cc0a44 Michael Hanselmann
  def GetInstanceConsole(cls, instance, hvparams, beparams):
1237 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
1238 eb58f9b1 Guido Trotter

1239 eb58f9b1 Guido Trotter
    """
1240 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
1241 2f4c951e Stephen Shirley
      cmd = [constants.KVM_CONSOLE_WRAPPER,
1242 2f4c951e Stephen Shirley
             constants.SOCAT_PATH, utils.ShellQuote(instance.name),
1243 2f4c951e Stephen Shirley
             utils.ShellQuote(cls._InstanceMonitor(instance.name)),
1244 55cc0a44 Michael Hanselmann
             "STDIO,%s" % cls._SocatUnixConsoleParams(),
1245 55cc0a44 Michael Hanselmann
             "UNIX-CONNECT:%s" % cls._InstanceSerial(instance.name)]
1246 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
1247 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_SSH,
1248 55cc0a44 Michael Hanselmann
                                     host=instance.primary_node,
1249 55cc0a44 Michael Hanselmann
                                     user=constants.GANETI_RUNAS,
1250 55cc0a44 Michael Hanselmann
                                     command=cmd)
1251 3be34f57 Guido Trotter
1252 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
1253 55cc0a44 Michael Hanselmann
    if vnc_bind_address and instance.network_port > constants.VNC_BASE_PORT:
1254 55cc0a44 Michael Hanselmann
      display = instance.network_port - constants.VNC_BASE_PORT
1255 55cc0a44 Michael Hanselmann
      return objects.InstanceConsole(instance=instance.name,
1256 55cc0a44 Michael Hanselmann
                                     kind=constants.CONS_VNC,
1257 55cc0a44 Michael Hanselmann
                                     host=vnc_bind_address,
1258 55cc0a44 Michael Hanselmann
                                     port=instance.network_port,
1259 55cc0a44 Michael Hanselmann
                                     display=display)
1260 55cc0a44 Michael Hanselmann
1261 55cc0a44 Michael Hanselmann
    return objects.InstanceConsole(instance=instance.name,
1262 55cc0a44 Michael Hanselmann
                                   kind=constants.CONS_MESSAGE,
1263 55cc0a44 Michael Hanselmann
                                   message=("No serial shell for instance %s" %
1264 55cc0a44 Michael Hanselmann
                                            instance.name))
1265 eb58f9b1 Guido Trotter
1266 eb58f9b1 Guido Trotter
  def Verify(self):
1267 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
1268 eb58f9b1 Guido Trotter

1269 eb58f9b1 Guido Trotter
    Check that the binary exists.
1270 eb58f9b1 Guido Trotter

1271 eb58f9b1 Guido Trotter
    """
1272 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
1273 eb58f9b1 Guido Trotter
      return "The kvm binary ('%s') does not exist." % constants.KVM_PATH
1274 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
1275 14aa53cb Guido Trotter
      return "The socat binary ('%s') does not exist." % constants.SOCAT_PATH
1276 14aa53cb Guido Trotter
1277 6b5605e8 Iustin Pop
  @classmethod
1278 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
1279 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
1280 6b5605e8 Iustin Pop

1281 6b5605e8 Iustin Pop
    @type hvparams:  dict
1282 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
1283 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
1284 6b5605e8 Iustin Pop

1285 6b5605e8 Iustin Pop
    """
1286 47387b1e Guido Trotter
    super(KVMHypervisor, cls).CheckParameterSyntax(hvparams)
1287 6b5605e8 Iustin Pop
1288 df5ab9f0 Guido Trotter
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
1289 df5ab9f0 Guido Trotter
    if kernel_path:
1290 df5ab9f0 Guido Trotter
      if not hvparams[constants.HV_ROOT_PATH]:
1291 205ab586 Iustin Pop
        raise errors.HypervisorError("Need a root partition for the instance,"
1292 205ab586 Iustin Pop
                                     " if a kernel is defined")
1293 6b5605e8 Iustin Pop
1294 205ab586 Iustin Pop
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
1295 205ab586 Iustin Pop
        not hvparams[constants.HV_VNC_X509]):
1296 205ab586 Iustin Pop
      raise errors.HypervisorError("%s must be defined, if %s is" %
1297 205ab586 Iustin Pop
                                   (constants.HV_VNC_X509,
1298 205ab586 Iustin Pop
                                    constants.HV_VNC_X509_VERIFY))
1299 66d5dbef Guido Trotter
1300 66d5dbef Guido Trotter
    boot_order = hvparams[constants.HV_BOOT_ORDER]
1301 205ab586 Iustin Pop
    if (boot_order == constants.HT_BO_CDROM and
1302 205ab586 Iustin Pop
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
1303 835528af Iustin Pop
      raise errors.HypervisorError("Cannot boot from cdrom without an"
1304 835528af Iustin Pop
                                   " ISO path")
1305 f5118ade Iustin Pop
1306 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1307 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1308 d19d94db Guido Trotter
      if not hvparams[constants.HV_SECURITY_DOMAIN]:
1309 d19d94db Guido Trotter
        raise errors.HypervisorError("A security domain (user to run kvm as)"
1310 d19d94db Guido Trotter
                                     " must be specified")
1311 d19d94db Guido Trotter
    elif (security_model == constants.HT_SM_NONE or
1312 d19d94db Guido Trotter
          security_model == constants.HT_SM_POOL):
1313 d19d94db Guido Trotter
      if hvparams[constants.HV_SECURITY_DOMAIN]:
1314 d19d94db Guido Trotter
        raise errors.HypervisorError("Cannot have a security domain when the"
1315 d19d94db Guido Trotter
                                     " security model is 'none' or 'pool'")
1316 d19d94db Guido Trotter
1317 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
1318 b1cb62bd Andrea Spadaccini
    if spice_bind:
1319 b1cb62bd Andrea Spadaccini
      spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
1320 b1cb62bd Andrea Spadaccini
      if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
1321 b1cb62bd Andrea Spadaccini
        # if an IP version is specified, the spice_bind parameter must be an
1322 b1cb62bd Andrea Spadaccini
        # IP of that family
1323 b1cb62bd Andrea Spadaccini
        if (netutils.IP4Address.IsValid(spice_bind) and
1324 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP4_VERSION):
1325 b1cb62bd Andrea Spadaccini
          raise errors.HypervisorError("spice: got an IPv4 address (%s), but"
1326 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
1327 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
1328 b1cb62bd Andrea Spadaccini
1329 b1cb62bd Andrea Spadaccini
        if (netutils.IP6Address.IsValid(spice_bind) and
1330 b1cb62bd Andrea Spadaccini
            spice_ip_version != constants.IP6_VERSION):
1331 b1cb62bd Andrea Spadaccini
          raise errors.HypervisorError("spice: got an IPv6 address (%s), but"
1332 b1cb62bd Andrea Spadaccini
                                       " the specified IP version is %s" %
1333 b1cb62bd Andrea Spadaccini
                                       (spice_bind, spice_ip_version))
1334 b1cb62bd Andrea Spadaccini
1335 d19d94db Guido Trotter
  @classmethod
1336 d19d94db Guido Trotter
  def ValidateParameters(cls, hvparams):
1337 d19d94db Guido Trotter
    """Check the given parameters for validity.
1338 d19d94db Guido Trotter

1339 d19d94db Guido Trotter
    @type hvparams:  dict
1340 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
1341 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
1342 d19d94db Guido Trotter

1343 d19d94db Guido Trotter
    """
1344 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
1345 d19d94db Guido Trotter
1346 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1347 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1348 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
1349 d19d94db Guido Trotter
      try:
1350 1feb39ec Guido Trotter
        pwd.getpwnam(username)
1351 d19d94db Guido Trotter
      except KeyError:
1352 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
1353 d19d94db Guido Trotter
                                     % username)
1354 d19d94db Guido Trotter
1355 b1cb62bd Andrea Spadaccini
    spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
1356 b1cb62bd Andrea Spadaccini
    if spice_bind:
1357 b1cb62bd Andrea Spadaccini
      # only one of VNC and SPICE can be used currently.
1358 b1cb62bd Andrea Spadaccini
      if hvparams[constants.HV_VNC_BIND_ADDRESS]:
1359 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("both SPICE and VNC are configured, but"
1360 b1cb62bd Andrea Spadaccini
                                     " only one of them can be used at a"
1361 b1cb62bd Andrea Spadaccini
                                     " given time.")
1362 b1cb62bd Andrea Spadaccini
1363 b1cb62bd Andrea Spadaccini
      # KVM version should be >= 0.14.0
1364 b1cb62bd Andrea Spadaccini
      _, v_major, v_min, _ = cls._GetKVMVersion()
1365 b1cb62bd Andrea Spadaccini
      if (v_major, v_min) < (0, 14):
1366 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("spice is configured, but it is not"
1367 b1cb62bd Andrea Spadaccini
                                     " available in versions of KVM < 0.14")
1368 b1cb62bd Andrea Spadaccini
1369 b1cb62bd Andrea Spadaccini
      # if spice_bind is not an IP address, it must be a valid interface
1370 b1cb62bd Andrea Spadaccini
      bound_to_addr = (netutils.IP4Address.IsValid(spice_bind)
1371 b1cb62bd Andrea Spadaccini
                       or netutils.IP6Address.IsValid(spice_bind))
1372 b1cb62bd Andrea Spadaccini
      if not bound_to_addr and not netutils.IsValidInterface(spice_bind):
1373 b1cb62bd Andrea Spadaccini
        raise errors.HypervisorError("spice: the %s parameter must be either"
1374 b1cb62bd Andrea Spadaccini
                                     " a valid IP address or interface name" %
1375 b1cb62bd Andrea Spadaccini
                                     constants.HV_KVM_SPICE_BIND)
1376 b1cb62bd Andrea Spadaccini
1377 f5118ade Iustin Pop
  @classmethod
1378 f5118ade Iustin Pop
  def PowercycleNode(cls):
1379 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
1380 f5118ade Iustin Pop

1381 f5118ade Iustin Pop
    """
1382 f5118ade Iustin Pop
    cls.LinuxPowercycle()