Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ 748e4b5a

History | View | Annotate | Download (37.7 kB)

1 eb58f9b1 Guido Trotter
#
2 eb58f9b1 Guido Trotter
#
3 eb58f9b1 Guido Trotter
4 eb58f9b1 Guido Trotter
# Copyright (C) 2008 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 eb58f9b1 Guido Trotter
from cStringIO import StringIO
35 eb58f9b1 Guido Trotter
36 eb58f9b1 Guido Trotter
from ganeti import utils
37 eb58f9b1 Guido Trotter
from ganeti import constants
38 eb58f9b1 Guido Trotter
from ganeti import errors
39 38e250ba Guido Trotter
from ganeti import serializer
40 38e250ba Guido Trotter
from ganeti import objects
41 76431533 Guido Trotter
from ganeti import uidpool
42 76431533 Guido Trotter
from ganeti import ssconf
43 eb58f9b1 Guido Trotter
from ganeti.hypervisor import hv_base
44 a744b676 Manuel Franceschini
from ganeti import netutils
45 eb58f9b1 Guido Trotter
46 eb58f9b1 Guido Trotter
47 748e4b5a Michael Hanselmann
_KVM_NETWORK_SCRIPT = constants.SYSCONFDIR + "/ganeti/kvm-vif-bridge"
48 748e4b5a Michael Hanselmann
49 748e4b5a Michael Hanselmann
50 748e4b5a Michael Hanselmann
def _WriteNetScript(instance, nic, index):
51 748e4b5a Michael Hanselmann
  """Write a script to connect a net interface to the proper bridge.
52 748e4b5a Michael Hanselmann

53 748e4b5a Michael Hanselmann
  This can be used by any qemu-type hypervisor.
54 748e4b5a Michael Hanselmann

55 748e4b5a Michael Hanselmann
  @type instance: L{objects.Instance}
56 748e4b5a Michael Hanselmann
  @param instance: Instance object
57 748e4b5a Michael Hanselmann
  @type nic: L{objects.NIC}
58 748e4b5a Michael Hanselmann
  @param nic: NIC object
59 748e4b5a Michael Hanselmann
  @type index: int
60 748e4b5a Michael Hanselmann
  @param index: NIC index
61 748e4b5a Michael Hanselmann
  @return: Script
62 748e4b5a Michael Hanselmann
  @rtype: string
63 748e4b5a Michael Hanselmann

64 748e4b5a Michael Hanselmann
  """
65 748e4b5a Michael Hanselmann
  if instance.tags:
66 748e4b5a Michael Hanselmann
    tags = " ".join(instance.tags)
67 748e4b5a Michael Hanselmann
  else:
68 748e4b5a Michael Hanselmann
    tags = ""
69 748e4b5a Michael Hanselmann
70 748e4b5a Michael Hanselmann
  buf = StringIO()
71 748e4b5a Michael Hanselmann
  sw = utils.ShellWriter(buf)
72 748e4b5a Michael Hanselmann
  sw.Write("#!/bin/sh")
73 748e4b5a Michael Hanselmann
  sw.Write("# this is autogenerated by Ganeti, please do not edit")
74 748e4b5a Michael Hanselmann
  sw.Write("export PATH=$PATH:/sbin:/usr/sbin")
75 748e4b5a Michael Hanselmann
  sw.Write("export INSTANCE=%s", utils.ShellQuote(instance.name))
76 748e4b5a Michael Hanselmann
  sw.Write("export MAC=%s", utils.ShellQuote(nic.mac))
77 748e4b5a Michael Hanselmann
  sw.Write("export MODE=%s",
78 748e4b5a Michael Hanselmann
           utils.ShellQuote(nic.nicparams[constants.NIC_MODE]))
79 748e4b5a Michael Hanselmann
  sw.Write("export INTERFACE=\"$1\"")
80 748e4b5a Michael Hanselmann
  sw.Write("export TAGS=%s", utils.ShellQuote(tags))
81 748e4b5a Michael Hanselmann
82 748e4b5a Michael Hanselmann
  if nic.ip:
83 748e4b5a Michael Hanselmann
    sw.Write("export IP=%s", utils.ShellQuote(nic.ip))
84 748e4b5a Michael Hanselmann
85 748e4b5a Michael Hanselmann
  if nic.nicparams[constants.NIC_LINK]:
86 748e4b5a Michael Hanselmann
    sw.Write("export LINK=%s",
87 748e4b5a Michael Hanselmann
             utils.ShellQuote(nic.nicparams[constants.NIC_LINK]))
88 748e4b5a Michael Hanselmann
89 748e4b5a Michael Hanselmann
  if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
90 748e4b5a Michael Hanselmann
    sw.Write("export BRIDGE=%s",
91 748e4b5a Michael Hanselmann
             utils.ShellQuote(nic.nicparams[constants.NIC_LINK]))
92 748e4b5a Michael Hanselmann
93 748e4b5a Michael Hanselmann
  # TODO: make this configurable at ./configure time
94 748e4b5a Michael Hanselmann
  sw.Write("if [ -x %s ]; then", utils.ShellQuote(_KVM_NETWORK_SCRIPT))
95 748e4b5a Michael Hanselmann
  sw.IncIndent()
96 748e4b5a Michael Hanselmann
  try:
97 748e4b5a Michael Hanselmann
    sw.Write("# Execute the user-specific vif file")
98 748e4b5a Michael Hanselmann
    sw.Write(_KVM_NETWORK_SCRIPT)
99 748e4b5a Michael Hanselmann
  finally:
100 748e4b5a Michael Hanselmann
    sw.DecIndent()
101 748e4b5a Michael Hanselmann
  sw.Write("else")
102 748e4b5a Michael Hanselmann
  sw.IncIndent()
103 748e4b5a Michael Hanselmann
  try:
104 748e4b5a Michael Hanselmann
    sw.Write("ifconfig $INTERFACE 0.0.0.0 up")
105 748e4b5a Michael Hanselmann
106 748e4b5a Michael Hanselmann
    if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
107 748e4b5a Michael Hanselmann
      sw.Write("# Connect the interface to the bridge")
108 748e4b5a Michael Hanselmann
      sw.Write("brctl addif $BRIDGE $INTERFACE")
109 748e4b5a Michael Hanselmann
110 748e4b5a Michael Hanselmann
    elif nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_ROUTED:
111 748e4b5a Michael Hanselmann
      if not nic.ip:
112 748e4b5a Michael Hanselmann
        raise errors.HypervisorError("nic/%d is routed, but has no IP"
113 748e4b5a Michael Hanselmann
                                     " address" % index)
114 748e4b5a Michael Hanselmann
115 748e4b5a Michael Hanselmann
      sw.Write("# Route traffic targeted at the IP to the interface")
116 748e4b5a Michael Hanselmann
      if nic.nicparams[constants.NIC_LINK]:
117 748e4b5a Michael Hanselmann
        sw.Write("while ip rule del dev $INTERFACE; do :; done")
118 748e4b5a Michael Hanselmann
        sw.Write("ip rule add dev $INTERFACE table $LINK")
119 748e4b5a Michael Hanselmann
        sw.Write("ip route replace $IP table $LINK proto static"
120 748e4b5a Michael Hanselmann
                 " dev $INTERFACE")
121 748e4b5a Michael Hanselmann
      else:
122 748e4b5a Michael Hanselmann
        sw.Write("ip route replace $IP proto static dev $INTERFACE")
123 748e4b5a Michael Hanselmann
124 748e4b5a Michael Hanselmann
      interface_v4_conf = "/proc/sys/net/ipv4/conf/$INTERFACE"
125 748e4b5a Michael Hanselmann
      sw.Write(" if [ -d %s ]; then", interface_v4_conf)
126 748e4b5a Michael Hanselmann
      sw.IncIndent()
127 748e4b5a Michael Hanselmann
      try:
128 748e4b5a Michael Hanselmann
        sw.Write("echo 1 > %s/proxy_arp", interface_v4_conf)
129 748e4b5a Michael Hanselmann
        sw.Write("echo 1 > %s/forwarding", interface_v4_conf)
130 748e4b5a Michael Hanselmann
      finally:
131 748e4b5a Michael Hanselmann
        sw.DecIndent()
132 748e4b5a Michael Hanselmann
      sw.Write("fi")
133 748e4b5a Michael Hanselmann
134 748e4b5a Michael Hanselmann
      interface_v6_conf = "/proc/sys/net/ipv6/conf/$INTERFACE"
135 748e4b5a Michael Hanselmann
      sw.Write("if [ -d %s ]; then", interface_v6_conf)
136 748e4b5a Michael Hanselmann
      sw.IncIndent()
137 748e4b5a Michael Hanselmann
      try:
138 748e4b5a Michael Hanselmann
        sw.Write("echo 1 > %s/proxy_ndp", interface_v6_conf)
139 748e4b5a Michael Hanselmann
        sw.Write("echo 1 > %s/forwarding", interface_v6_conf)
140 748e4b5a Michael Hanselmann
      finally:
141 748e4b5a Michael Hanselmann
        sw.DecIndent()
142 748e4b5a Michael Hanselmann
      sw.Write("fi")
143 748e4b5a Michael Hanselmann
  finally:
144 748e4b5a Michael Hanselmann
    sw.DecIndent()
145 748e4b5a Michael Hanselmann
  sw.Write("fi")
146 748e4b5a Michael Hanselmann
147 748e4b5a Michael Hanselmann
  return buf.getvalue()
148 748e4b5a Michael Hanselmann
149 748e4b5a Michael Hanselmann
150 eb58f9b1 Guido Trotter
class KVMHypervisor(hv_base.BaseHypervisor):
151 c4469f75 Guido Trotter
  """KVM hypervisor interface"""
152 d271c6fd Iustin Pop
  CAN_MIGRATE = True
153 eb58f9b1 Guido Trotter
154 eb58f9b1 Guido Trotter
  _ROOT_DIR = constants.RUN_GANETI_DIR + "/kvm-hypervisor"
155 a1d79fc6 Guido Trotter
  _PIDS_DIR = _ROOT_DIR + "/pid" # contains live instances pids
156 7548396c Guido Trotter
  _UIDS_DIR = _ROOT_DIR + "/uid" # contains instances reserved uids
157 a1d79fc6 Guido Trotter
  _CTRL_DIR = _ROOT_DIR + "/ctrl" # contains instances control sockets
158 a1d79fc6 Guido Trotter
  _CONF_DIR = _ROOT_DIR + "/conf" # contains instances startup data
159 547a63b7 Balazs Lecz
  # KVM instances with chroot enabled are started in empty chroot directories.
160 547a63b7 Balazs Lecz
  _CHROOT_DIR = _ROOT_DIR + "/chroot" # for empty chroot directories
161 547a63b7 Balazs Lecz
  # After an instance is stopped, its chroot directory is removed.
162 547a63b7 Balazs Lecz
  # If the chroot directory is not empty, it can't be removed.
163 547a63b7 Balazs Lecz
  # A non-empty chroot directory indicates a possible security incident.
164 547a63b7 Balazs Lecz
  # To support forensics, the non-empty chroot directory is quarantined in
165 547a63b7 Balazs Lecz
  # a separate directory, called 'chroot-quarantine'.
166 547a63b7 Balazs Lecz
  _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine"
167 547a63b7 Balazs Lecz
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR,
168 547a63b7 Balazs Lecz
           _CHROOT_DIR, _CHROOT_QUARANTINE_DIR]
169 eb58f9b1 Guido Trotter
170 205ab586 Iustin Pop
  PARAMETERS = {
171 205ab586 Iustin Pop
    constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK,
172 205ab586 Iustin Pop
    constants.HV_INITRD_PATH: hv_base.OPT_FILE_CHECK,
173 205ab586 Iustin Pop
    constants.HV_ROOT_PATH: hv_base.NO_CHECK,
174 205ab586 Iustin Pop
    constants.HV_KERNEL_ARGS: hv_base.NO_CHECK,
175 205ab586 Iustin Pop
    constants.HV_ACPI: hv_base.NO_CHECK,
176 205ab586 Iustin Pop
    constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
177 d73ef63f Michael Hanselmann
    constants.HV_VNC_BIND_ADDRESS:
178 a744b676 Manuel Franceschini
      (False, lambda x: (netutils.IsValidIP4(x) or utils.IsNormAbsPath(x)),
179 d73ef63f Michael Hanselmann
       "the VNC bind address must be either a valid IP address or an absolute"
180 d73ef63f Michael Hanselmann
       " pathname", None, None),
181 205ab586 Iustin Pop
    constants.HV_VNC_TLS: hv_base.NO_CHECK,
182 205ab586 Iustin Pop
    constants.HV_VNC_X509: hv_base.OPT_DIR_CHECK,
183 205ab586 Iustin Pop
    constants.HV_VNC_X509_VERIFY: hv_base.NO_CHECK,
184 6e6bb8d5 Guido Trotter
    constants.HV_VNC_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
185 205ab586 Iustin Pop
    constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
186 d73ef63f Michael Hanselmann
    constants.HV_BOOT_ORDER:
187 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_BO_TYPES),
188 d73ef63f Michael Hanselmann
    constants.HV_NIC_TYPE:
189 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_NIC_TYPES),
190 d73ef63f Michael Hanselmann
    constants.HV_DISK_TYPE:
191 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_DISK_TYPES),
192 d73ef63f Michael Hanselmann
    constants.HV_USB_MOUSE:
193 d73ef63f Michael Hanselmann
      hv_base.ParamInSet(False, constants.HT_KVM_VALID_MOUSE_TYPES),
194 78411c60 Iustin Pop
    constants.HV_MIGRATION_PORT: hv_base.NET_PORT_CHECK,
195 e43d4f9f Apollon Oikonomopoulos
    constants.HV_MIGRATION_BANDWIDTH: hv_base.NO_CHECK,
196 e43d4f9f Apollon Oikonomopoulos
    constants.HV_MIGRATION_DOWNTIME: hv_base.NO_CHECK,
197 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
198 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
199 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
200 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
201 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
202 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
203 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
204 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
205 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
206 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
207 205ab586 Iustin Pop
    }
208 6b5605e8 Iustin Pop
209 30e42c4e Guido Trotter
  _MIGRATION_STATUS_RE = re.compile('Migration\s+status:\s+(\w+)',
210 30e42c4e Guido Trotter
                                    re.M | re.I)
211 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
212 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
213 30e42c4e 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 263b8de6 Guido Trotter
    arg_list = cmdline.split('\x00')
269 263b8de6 Guido Trotter
    while arg_list:
270 263b8de6 Guido Trotter
      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 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
356 7548396c Guido Trotter
    """Try to read a uid file
357 7548396c Guido Trotter

358 7548396c Guido Trotter
    """
359 7548396c Guido Trotter
    if os.path.exists(uid_file):
360 7548396c Guido Trotter
      try:
361 682f7601 Guido Trotter
        uid = int(utils.ReadOneLineFile(uid_file))
362 aa0b600b Guido Trotter
        return uid
363 7548396c Guido Trotter
      except EnvironmentError:
364 7548396c Guido Trotter
        logging.warning("Can't read uid file", exc_info=True)
365 7548396c Guido Trotter
      except (TypeError, ValueError):
366 7548396c Guido Trotter
        logging.warning("Can't parse uid file contents", exc_info=True)
367 aa0b600b Guido Trotter
    return None
368 7548396c Guido Trotter
369 7548396c Guido Trotter
  @classmethod
370 7e66c35b Guido Trotter
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
371 547a63b7 Balazs Lecz
    """Removes an instance's rutime sockets/files/dirs.
372 7e66c35b Guido Trotter

373 7e66c35b Guido Trotter
    """
374 7e66c35b Guido Trotter
    utils.RemoveFile(pidfile)
375 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceMonitor(instance_name))
376 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceSerial(instance_name))
377 7e66c35b Guido Trotter
    utils.RemoveFile(cls._InstanceKVMRuntime(instance_name))
378 7548396c Guido Trotter
    uid_file = cls._InstanceUidFile(instance_name)
379 7548396c Guido Trotter
    uid = cls._TryReadUidFile(uid_file)
380 7548396c Guido Trotter
    utils.RemoveFile(uid_file)
381 7548396c Guido Trotter
    if uid is not None:
382 7548396c Guido Trotter
      uidpool.ReleaseUid(uid)
383 547a63b7 Balazs Lecz
    try:
384 547a63b7 Balazs Lecz
      chroot_dir = cls._InstanceChrootDir(instance_name)
385 547a63b7 Balazs Lecz
      utils.RemoveDir(chroot_dir)
386 547a63b7 Balazs Lecz
    except OSError, err:
387 547a63b7 Balazs Lecz
      if err.errno == errno.ENOTEMPTY:
388 547a63b7 Balazs Lecz
        # The chroot directory is expected to be empty, but it isn't.
389 547a63b7 Balazs Lecz
        new_chroot_dir = tempfile.mkdtemp(dir=cls._CHROOT_QUARANTINE_DIR,
390 547a63b7 Balazs Lecz
                                          prefix="%s-%s-" %
391 547a63b7 Balazs Lecz
                                          (instance_name,
392 547a63b7 Balazs Lecz
                                           utils.TimestampForFilename()))
393 547a63b7 Balazs Lecz
        logging.warning("The chroot directory of instance %s can not be"
394 547a63b7 Balazs Lecz
                        " removed as it is not empty. Moving it to the"
395 547a63b7 Balazs Lecz
                        " quarantine instead. Please investigate the"
396 547a63b7 Balazs Lecz
                        " contents (%s) and clean up manually",
397 547a63b7 Balazs Lecz
                        instance_name, new_chroot_dir)
398 547a63b7 Balazs Lecz
        utils.RenameFile(chroot_dir, new_chroot_dir)
399 547a63b7 Balazs Lecz
      else:
400 547a63b7 Balazs Lecz
        raise
401 7e66c35b Guido Trotter
402 748e4b5a Michael Hanselmann
  @staticmethod
403 748e4b5a Michael Hanselmann
  def _WriteNetScriptFile(instance, seq, nic):
404 eb58f9b1 Guido Trotter
    """Write a script to connect a net interface to the proper bridge.
405 eb58f9b1 Guido Trotter

406 eb58f9b1 Guido Trotter
    This can be used by any qemu-type hypervisor.
407 eb58f9b1 Guido Trotter

408 eb58f9b1 Guido Trotter
    @param instance: instance we're acting on
409 eb58f9b1 Guido Trotter
    @type instance: instance object
410 eb58f9b1 Guido Trotter
    @param seq: nic sequence number
411 eb58f9b1 Guido Trotter
    @type seq: int
412 eb58f9b1 Guido Trotter
    @param nic: nic we're acting on
413 eb58f9b1 Guido Trotter
    @type nic: nic object
414 eb58f9b1 Guido Trotter
    @return: netscript file name
415 eb58f9b1 Guido Trotter
    @rtype: string
416 eb58f9b1 Guido Trotter

417 eb58f9b1 Guido Trotter
    """
418 748e4b5a Michael Hanselmann
    script = _WriteNetScript(instance, nic, seq)
419 748e4b5a Michael Hanselmann
420 eb58f9b1 Guido Trotter
    # As much as we'd like to put this in our _ROOT_DIR, that will happen to be
421 eb58f9b1 Guido Trotter
    # mounted noexec sometimes, so we'll have to find another place.
422 eb58f9b1 Guido Trotter
    (tmpfd, tmpfile_name) = tempfile.mkstemp()
423 eb58f9b1 Guido Trotter
    tmpfile = os.fdopen(tmpfd, 'w')
424 d73ef63f Michael Hanselmann
    try:
425 748e4b5a Michael Hanselmann
      tmpfile.write(script)
426 d73ef63f Michael Hanselmann
    finally:
427 d73ef63f Michael Hanselmann
      tmpfile.close()
428 eb58f9b1 Guido Trotter
    os.chmod(tmpfile_name, 0755)
429 eb58f9b1 Guido Trotter
    return tmpfile_name
430 eb58f9b1 Guido Trotter
431 eb58f9b1 Guido Trotter
  def ListInstances(self):
432 eb58f9b1 Guido Trotter
    """Get the list of running instances.
433 eb58f9b1 Guido Trotter

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

437 eb58f9b1 Guido Trotter
    """
438 eb58f9b1 Guido Trotter
    result = []
439 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
440 263b8de6 Guido Trotter
      if self._InstancePidAlive(name)[2]:
441 eb58f9b1 Guido Trotter
        result.append(name)
442 eb58f9b1 Guido Trotter
    return result
443 eb58f9b1 Guido Trotter
444 eb58f9b1 Guido Trotter
  def GetInstanceInfo(self, instance_name):
445 eb58f9b1 Guido Trotter
    """Get instance properties.
446 eb58f9b1 Guido Trotter

447 4fbb3c60 Guido Trotter
    @type instance_name: string
448 c41eea6e Iustin Pop
    @param instance_name: the instance name
449 4fbb3c60 Guido Trotter
    @rtype: tuple of strings
450 4fbb3c60 Guido Trotter
    @return: (name, id, memory, vcpus, stat, times)
451 eb58f9b1 Guido Trotter

452 eb58f9b1 Guido Trotter
    """
453 1122eb25 Iustin Pop
    _, pid, alive = self._InstancePidAlive(instance_name)
454 1f8b3a27 Guido Trotter
    if not alive:
455 eb58f9b1 Guido Trotter
      return None
456 eb58f9b1 Guido Trotter
457 263b8de6 Guido Trotter
    _, memory, vcpus = self._InstancePidInfo(pid)
458 eb58f9b1 Guido Trotter
    stat = "---b-"
459 eb58f9b1 Guido Trotter
    times = "0"
460 eb58f9b1 Guido Trotter
461 eb58f9b1 Guido Trotter
    return (instance_name, pid, memory, vcpus, stat, times)
462 eb58f9b1 Guido Trotter
463 eb58f9b1 Guido Trotter
  def GetAllInstancesInfo(self):
464 eb58f9b1 Guido Trotter
    """Get properties of all instances.
465 eb58f9b1 Guido Trotter

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

468 eb58f9b1 Guido Trotter
    """
469 eb58f9b1 Guido Trotter
    data = []
470 eb58f9b1 Guido Trotter
    for name in os.listdir(self._PIDS_DIR):
471 263b8de6 Guido Trotter
      try:
472 263b8de6 Guido Trotter
        info = self.GetInstanceInfo(name)
473 263b8de6 Guido Trotter
      except errors.HypervisorError:
474 263b8de6 Guido Trotter
        continue
475 263b8de6 Guido Trotter
      if info:
476 263b8de6 Guido Trotter
        data.append(info)
477 eb58f9b1 Guido Trotter
    return data
478 eb58f9b1 Guido Trotter
479 07813a9e Iustin Pop
  def _GenerateKVMRuntime(self, instance, block_devices):
480 ee5f20b0 Guido Trotter
    """Generate KVM information to start an instance.
481 eb58f9b1 Guido Trotter

482 eb58f9b1 Guido Trotter
    """
483 98ec75d6 Iustin Pop
    pidfile  = self._InstancePidFile(instance.name)
484 eb58f9b1 Guido Trotter
    kvm = constants.KVM_PATH
485 eb58f9b1 Guido Trotter
    kvm_cmd = [kvm]
486 c6a39fc2 Guido Trotter
    # used just by the vnc server, if enabled
487 c6a39fc2 Guido Trotter
    kvm_cmd.extend(['-name', instance.name])
488 8b3fd458 Iustin Pop
    kvm_cmd.extend(['-m', instance.beparams[constants.BE_MEMORY]])
489 8b3fd458 Iustin Pop
    kvm_cmd.extend(['-smp', instance.beparams[constants.BE_VCPUS]])
490 eb58f9b1 Guido Trotter
    kvm_cmd.extend(['-pidfile', pidfile])
491 eb58f9b1 Guido Trotter
    kvm_cmd.extend(['-daemonize'])
492 6b5605e8 Iustin Pop
    if not instance.hvparams[constants.HV_ACPI]:
493 eb58f9b1 Guido Trotter
      kvm_cmd.extend(['-no-acpi'])
494 eb58f9b1 Guido Trotter
495 a985b417 Iustin Pop
    hvp = instance.hvparams
496 835528af Iustin Pop
    boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK
497 835528af Iustin Pop
    boot_cdrom = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_CDROM
498 835528af Iustin Pop
    boot_network = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_NETWORK
499 8745c3d7 Guido Trotter
500 7ba594c0 Guido Trotter
    if hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED:
501 7ba594c0 Guido Trotter
      kvm_cmd.extend(["-enable-kvm"])
502 7ba594c0 Guido Trotter
    elif hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_DISABLED:
503 7ba594c0 Guido Trotter
      kvm_cmd.extend(["-disable-kvm"])
504 7ba594c0 Guido Trotter
505 8745c3d7 Guido Trotter
    if boot_network:
506 8745c3d7 Guido Trotter
      kvm_cmd.extend(['-boot', 'n'])
507 1213604d Guido Trotter
508 a985b417 Iustin Pop
    disk_type = hvp[constants.HV_DISK_TYPE]
509 1213604d Guido Trotter
    if disk_type == constants.HT_DISK_PARAVIRTUAL:
510 1213604d Guido Trotter
      if_val = ',if=virtio'
511 1213604d Guido Trotter
    else:
512 1213604d Guido Trotter
      if_val = ',if=%s' % disk_type
513 19572932 Iustin Pop
    # Cache mode
514 19572932 Iustin Pop
    disk_cache = hvp[constants.HV_DISK_CACHE]
515 19572932 Iustin Pop
    if disk_cache != constants.HT_CACHE_DEFAULT:
516 19572932 Iustin Pop
      cache_val = ",cache=%s" % disk_cache
517 19572932 Iustin Pop
    else:
518 19572932 Iustin Pop
      cache_val = ""
519 069cfbf1 Iustin Pop
    for cfdev, dev_path in block_devices:
520 d34b16d7 Iustin Pop
      if cfdev.mode != constants.DISK_RDWR:
521 d34b16d7 Iustin Pop
        raise errors.HypervisorError("Instance has read-only disks which"
522 d34b16d7 Iustin Pop
                                     " are not supported by KVM")
523 eb58f9b1 Guido Trotter
      # TODO: handle FD_LOOP and FD_BLKTAP (?)
524 66d5dbef Guido Trotter
      if boot_disk:
525 9dd363eb Guido Trotter
        kvm_cmd.extend(['-boot', 'c'])
526 9cf4321f Apollon Oikonomopoulos
        if disk_type != constants.HT_DISK_IDE:
527 74a4c11b Guido Trotter
          boot_val = ',boot=on'
528 9cf4321f Apollon Oikonomopoulos
        else:
529 74a4c11b Guido Trotter
          boot_val = ''
530 8745c3d7 Guido Trotter
        # We only boot from the first disk
531 66d5dbef Guido Trotter
        boot_disk = False
532 eb58f9b1 Guido Trotter
      else:
533 eb58f9b1 Guido Trotter
        boot_val = ''
534 eb58f9b1 Guido Trotter
535 19572932 Iustin Pop
      drive_val = 'file=%s,format=raw%s%s%s' % (dev_path, if_val, boot_val,
536 19572932 Iustin Pop
                                                cache_val)
537 eb58f9b1 Guido Trotter
      kvm_cmd.extend(['-drive', drive_val])
538 eb58f9b1 Guido Trotter
539 a985b417 Iustin Pop
    iso_image = hvp[constants.HV_CDROM_IMAGE_PATH]
540 66d5dbef Guido Trotter
    if iso_image:
541 9dd363eb Guido Trotter
      options = ',format=raw,media=cdrom'
542 66d5dbef Guido Trotter
      if boot_cdrom:
543 9dd363eb Guido Trotter
        kvm_cmd.extend(['-boot', 'd'])
544 9cf4321f Apollon Oikonomopoulos
        if disk_type != constants.HT_DISK_IDE:
545 74a4c11b Guido Trotter
          options = '%s,boot=on' % options
546 9dd363eb Guido Trotter
      else:
547 9cf4321f Apollon Oikonomopoulos
        if disk_type == constants.HT_DISK_PARAVIRTUAL:
548 9cf4321f Apollon Oikonomopoulos
          if_val = ',if=virtio'
549 9cf4321f Apollon Oikonomopoulos
        else:
550 9cf4321f Apollon Oikonomopoulos
          if_val = ',if=%s' % disk_type
551 9cf4321f Apollon Oikonomopoulos
        options = '%s%s' % (options, if_val)
552 66d5dbef Guido Trotter
      drive_val = 'file=%s%s' % (iso_image, options)
553 66d5dbef Guido Trotter
      kvm_cmd.extend(['-drive', drive_val])
554 66d5dbef Guido Trotter
555 a985b417 Iustin Pop
    kernel_path = hvp[constants.HV_KERNEL_PATH]
556 df5ab9f0 Guido Trotter
    if kernel_path:
557 df5ab9f0 Guido Trotter
      kvm_cmd.extend(['-kernel', kernel_path])
558 a985b417 Iustin Pop
      initrd_path = hvp[constants.HV_INITRD_PATH]
559 df5ab9f0 Guido Trotter
      if initrd_path:
560 df5ab9f0 Guido Trotter
        kvm_cmd.extend(['-initrd', initrd_path])
561 07813a9e Iustin Pop
      root_append = ['root=%s' % hvp[constants.HV_ROOT_PATH],
562 07813a9e Iustin Pop
                     hvp[constants.HV_KERNEL_ARGS]]
563 07813a9e Iustin Pop
      if hvp[constants.HV_SERIAL_CONSOLE]:
564 07813a9e Iustin Pop
        root_append.append('console=ttyS0,38400')
565 07813a9e Iustin Pop
      kvm_cmd.extend(['-append', ' '.join(root_append)])
566 eb58f9b1 Guido Trotter
567 a985b417 Iustin Pop
    mouse_type = hvp[constants.HV_USB_MOUSE]
568 11344a50 Guido Trotter
    if mouse_type:
569 11344a50 Guido Trotter
      kvm_cmd.extend(['-usb'])
570 11344a50 Guido Trotter
      kvm_cmd.extend(['-usbdevice', mouse_type])
571 11344a50 Guido Trotter
572 a985b417 Iustin Pop
    vnc_bind_address = hvp[constants.HV_VNC_BIND_ADDRESS]
573 8470c8db Guido Trotter
    if vnc_bind_address:
574 a744b676 Manuel Franceschini
      if netutils.IsValidIP4(vnc_bind_address):
575 377d74c9 Guido Trotter
        if instance.network_port > constants.VNC_BASE_PORT:
576 377d74c9 Guido Trotter
          display = instance.network_port - constants.VNC_BASE_PORT
577 14f5f1b6 Manuel Franceschini
          if vnc_bind_address == constants.IP4_ADDRESS_ANY:
578 8447f52b Guido Trotter
            vnc_arg = ':%d' % (display)
579 8447f52b Guido Trotter
          else:
580 19498d6c Guido Trotter
            vnc_arg = '%s:%d' % (vnc_bind_address, display)
581 8470c8db Guido Trotter
        else:
582 8447f52b Guido Trotter
          logging.error("Network port is not a valid VNC display (%d < %d)."
583 07b8a2b5 Iustin Pop
                        " Not starting VNC", instance.network_port,
584 07b8a2b5 Iustin Pop
                        constants.VNC_BASE_PORT)
585 8447f52b Guido Trotter
          vnc_arg = 'none'
586 8b2d1013 Guido Trotter
587 8b2d1013 Guido Trotter
        # Only allow tls and other option when not binding to a file, for now.
588 8b2d1013 Guido Trotter
        # kvm/qemu gets confused otherwise about the filename to use.
589 8b2d1013 Guido Trotter
        vnc_append = ''
590 a985b417 Iustin Pop
        if hvp[constants.HV_VNC_TLS]:
591 8b2d1013 Guido Trotter
          vnc_append = '%s,tls' % vnc_append
592 a985b417 Iustin Pop
          if hvp[constants.HV_VNC_X509_VERIFY]:
593 8b2d1013 Guido Trotter
            vnc_append = '%s,x509verify=%s' % (vnc_append,
594 a985b417 Iustin Pop
                                               hvp[constants.HV_VNC_X509])
595 a985b417 Iustin Pop
          elif hvp[constants.HV_VNC_X509]:
596 8b2d1013 Guido Trotter
            vnc_append = '%s,x509=%s' % (vnc_append,
597 a985b417 Iustin Pop
                                         hvp[constants.HV_VNC_X509])
598 6e6bb8d5 Guido Trotter
        if hvp[constants.HV_VNC_PASSWORD_FILE]:
599 6e6bb8d5 Guido Trotter
          vnc_append = '%s,password' % vnc_append
600 6e6bb8d5 Guido Trotter
601 8b2d1013 Guido Trotter
        vnc_arg = '%s%s' % (vnc_arg, vnc_append)
602 8b2d1013 Guido Trotter
603 8470c8db Guido Trotter
      else:
604 8b2d1013 Guido Trotter
        vnc_arg = 'unix:%s/%s.vnc' % (vnc_bind_address, instance.name)
605 8b2d1013 Guido Trotter
606 8447f52b Guido Trotter
      kvm_cmd.extend(['-vnc', vnc_arg])
607 5b062a58 Apollon Oikonomopoulos
608 5b062a58 Apollon Oikonomopoulos
      # Also add a tablet USB device to act as a mouse
609 5b062a58 Apollon Oikonomopoulos
      # This solves various mouse alignment issues
610 5b062a58 Apollon Oikonomopoulos
      kvm_cmd.extend(['-usbdevice', 'tablet'])
611 8470c8db Guido Trotter
    else:
612 8470c8db Guido Trotter
      kvm_cmd.extend(['-nographic'])
613 8470c8db Guido Trotter
614 69b99987 Michael Hanselmann
    monitor_dev = ("unix:%s,server,nowait" %
615 69b99987 Michael Hanselmann
                   self._InstanceMonitor(instance.name))
616 eb58f9b1 Guido Trotter
    kvm_cmd.extend(['-monitor', monitor_dev])
617 a985b417 Iustin Pop
    if hvp[constants.HV_SERIAL_CONSOLE]:
618 a985b417 Iustin Pop
      serial_dev = ('unix:%s,server,nowait' %
619 a985b417 Iustin Pop
                    self._InstanceSerial(instance.name))
620 a2faf9ee Guido Trotter
      kvm_cmd.extend(['-serial', serial_dev])
621 a2faf9ee Guido Trotter
    else:
622 a2faf9ee Guido Trotter
      kvm_cmd.extend(['-serial', 'none'])
623 eb58f9b1 Guido Trotter
624 6b970cef Jun Futagawa
    if hvp[constants.HV_USE_LOCALTIME]:
625 6b970cef Jun Futagawa
      kvm_cmd.extend(['-localtime'])
626 6b970cef Jun Futagawa
627 547a63b7 Balazs Lecz
    if hvp[constants.HV_KVM_USE_CHROOT]:
628 547a63b7 Balazs Lecz
      kvm_cmd.extend(['-chroot', self._InstanceChrootDir(instance.name)])
629 547a63b7 Balazs Lecz
630 ee5f20b0 Guido Trotter
    # Save the current instance nics, but defer their expansion as parameters,
631 ee5f20b0 Guido Trotter
    # as we'll need to generate executable temp files for them.
632 ee5f20b0 Guido Trotter
    kvm_nics = instance.nics
633 a985b417 Iustin Pop
    hvparams = hvp
634 ee5f20b0 Guido Trotter
635 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
636 ee5f20b0 Guido Trotter
637 38e250ba Guido Trotter
  def _WriteKVMRuntime(self, instance_name, data):
638 38e250ba Guido Trotter
    """Write an instance's KVM runtime
639 38e250ba Guido Trotter

640 38e250ba Guido Trotter
    """
641 38e250ba Guido Trotter
    try:
642 38e250ba Guido Trotter
      utils.WriteFile(self._InstanceKVMRuntime(instance_name),
643 38e250ba Guido Trotter
                      data=data)
644 90c024f6 Guido Trotter
    except EnvironmentError, err:
645 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to save KVM runtime file: %s" % err)
646 38e250ba Guido Trotter
647 38e250ba Guido Trotter
  def _ReadKVMRuntime(self, instance_name):
648 38e250ba Guido Trotter
    """Read an instance's KVM runtime
649 38e250ba Guido Trotter

650 38e250ba Guido Trotter
    """
651 38e250ba Guido Trotter
    try:
652 38e250ba Guido Trotter
      file_content = utils.ReadFile(self._InstanceKVMRuntime(instance_name))
653 90c024f6 Guido Trotter
    except EnvironmentError, err:
654 38e250ba Guido Trotter
      raise errors.HypervisorError("Failed to load KVM runtime file: %s" % err)
655 38e250ba Guido Trotter
    return file_content
656 38e250ba Guido Trotter
657 38e250ba Guido Trotter
  def _SaveKVMRuntime(self, instance, kvm_runtime):
658 38e250ba Guido Trotter
    """Save an instance's KVM runtime
659 38e250ba Guido Trotter

660 38e250ba Guido Trotter
    """
661 c2672466 Guido Trotter
    kvm_cmd, kvm_nics, hvparams = kvm_runtime
662 38e250ba Guido Trotter
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
663 c2672466 Guido Trotter
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams))
664 38e250ba Guido Trotter
    self._WriteKVMRuntime(instance.name, serialized_form)
665 38e250ba Guido Trotter
666 30e42c4e Guido Trotter
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
667 38e250ba Guido Trotter
    """Load an instance's KVM runtime
668 38e250ba Guido Trotter

669 38e250ba Guido Trotter
    """
670 30e42c4e Guido Trotter
    if not serialized_runtime:
671 30e42c4e Guido Trotter
      serialized_runtime = self._ReadKVMRuntime(instance.name)
672 30e42c4e Guido Trotter
    loaded_runtime = serializer.Load(serialized_runtime)
673 c2672466 Guido Trotter
    kvm_cmd, serialized_nics, hvparams = loaded_runtime
674 38e250ba Guido Trotter
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
675 c2672466 Guido Trotter
    return (kvm_cmd, kvm_nics, hvparams)
676 38e250ba Guido Trotter
677 76431533 Guido Trotter
  def _RunKVMCmd(self, name, kvm_cmd):
678 76431533 Guido Trotter
    """Run the KVM cmd and check for errors
679 76431533 Guido Trotter

680 76431533 Guido Trotter
    @type name: string
681 76431533 Guido Trotter
    @param name: instance name
682 76431533 Guido Trotter
    @type kvm_cmd: list of strings
683 76431533 Guido Trotter
    @param kvm_cmd: runcmd input for kvm
684 76431533 Guido Trotter

685 76431533 Guido Trotter
    """
686 76431533 Guido Trotter
    result = utils.RunCmd(kvm_cmd)
687 76431533 Guido Trotter
    if result.failed:
688 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
689 76431533 Guido Trotter
                                   (name, result.fail_reason, result.output))
690 76431533 Guido Trotter
    if not self._InstancePidAlive(name)[2]:
691 76431533 Guido Trotter
      raise errors.HypervisorError("Failed to start instance %s" % name)
692 76431533 Guido Trotter
693 30e42c4e Guido Trotter
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, incoming=None):
694 ee5f20b0 Guido Trotter
    """Execute a KVM cmd, after completing it with some last minute data
695 ee5f20b0 Guido Trotter

696 30e42c4e Guido Trotter
    @type incoming: tuple of strings
697 30e42c4e Guido Trotter
    @param incoming: (target_host_ip, port)
698 30e42c4e Guido Trotter

699 ee5f20b0 Guido Trotter
    """
700 297e6e53 Guido Trotter
    # Small _ExecuteKVMRuntime hv parameters programming howto:
701 297e6e53 Guido Trotter
    #  - conf_hvp contains the parameters as configured on ganeti. they might
702 297e6e53 Guido Trotter
    #    have changed since the instance started; only use them if the change
703 297e6e53 Guido Trotter
    #    won't affect the inside of the instance (which hasn't been rebooted).
704 297e6e53 Guido Trotter
    #  - up_hvp contains the parameters as they were when the instance was
705 297e6e53 Guido Trotter
    #    started, plus any new parameter which has been added between ganeti
706 297e6e53 Guido Trotter
    #    versions: it is paramount that those default to a value which won't
707 297e6e53 Guido Trotter
    #    affect the inside of the instance as well.
708 297e6e53 Guido Trotter
    conf_hvp = instance.hvparams
709 5905901c Iustin Pop
    name = instance.name
710 5905901c Iustin Pop
    self._CheckDown(name)
711 ee5f20b0 Guido Trotter
712 ee5f20b0 Guido Trotter
    temp_files = []
713 ee5f20b0 Guido Trotter
714 297e6e53 Guido Trotter
    kvm_cmd, kvm_nics, up_hvp = kvm_runtime
715 297e6e53 Guido Trotter
    up_hvp = objects.FillDict(conf_hvp, up_hvp)
716 ee5f20b0 Guido Trotter
717 297e6e53 Guido Trotter
    # We know it's safe to run as a different user upon migration, so we'll use
718 297e6e53 Guido Trotter
    # the latest conf, from conf_hvp.
719 297e6e53 Guido Trotter
    security_model = conf_hvp[constants.HV_SECURITY_MODEL]
720 cef34868 Guido Trotter
    if security_model == constants.HT_SM_USER:
721 297e6e53 Guido Trotter
      kvm_cmd.extend(["-runas", conf_hvp[constants.HV_SECURITY_DOMAIN]])
722 cef34868 Guido Trotter
723 297e6e53 Guido Trotter
    # We have reasons to believe changing something like the nic driver/type
724 297e6e53 Guido Trotter
    # upon migration won't exactly fly with the instance kernel, so for nic
725 297e6e53 Guido Trotter
    # related parameters we'll use up_hvp
726 ee5f20b0 Guido Trotter
    if not kvm_nics:
727 fbe27e2b Guido Trotter
      kvm_cmd.extend(["-net", "none"])
728 ee5f20b0 Guido Trotter
    else:
729 fbe27e2b Guido Trotter
      tap_extra = ""
730 297e6e53 Guido Trotter
      nic_type = up_hvp[constants.HV_NIC_TYPE]
731 37f88dc6 Guido Trotter
      if nic_type == constants.HT_NIC_PARAVIRTUAL:
732 37f88dc6 Guido Trotter
        nic_model = "model=virtio"
733 297e6e53 Guido Trotter
        if up_hvp[constants.HV_VHOST_NET]:
734 fbe27e2b Guido Trotter
          tap_extra = ",vhost=on"
735 37f88dc6 Guido Trotter
      else:
736 37f88dc6 Guido Trotter
        nic_model = "model=%s" % nic_type
737 37f88dc6 Guido Trotter
738 ee5f20b0 Guido Trotter
      for nic_seq, nic in enumerate(kvm_nics):
739 760570a8 Timothy Kuhlman
        nic_val = "nic,vlan=%s,macaddr=%s,%s" % (nic_seq, nic.mac, nic_model)
740 748e4b5a Michael Hanselmann
        script = self._WriteNetScriptFile(instance, nic_seq, nic)
741 fbe27e2b Guido Trotter
        tap_val = "tap,vlan=%s,script=%s%s" % (nic_seq, script, tap_extra)
742 fbe27e2b Guido Trotter
        kvm_cmd.extend(["-net", nic_val])
743 fbe27e2b Guido Trotter
        kvm_cmd.extend(["-net", tap_val])
744 ee5f20b0 Guido Trotter
        temp_files.append(script)
745 ee5f20b0 Guido Trotter
746 30e42c4e Guido Trotter
    if incoming:
747 30e42c4e Guido Trotter
      target, port = incoming
748 30e42c4e Guido Trotter
      kvm_cmd.extend(['-incoming', 'tcp:%s:%s' % (target, port)])
749 30e42c4e Guido Trotter
750 297e6e53 Guido Trotter
    # Changing the vnc password doesn't bother the guest that much. At most it
751 297e6e53 Guido Trotter
    # will surprise people who connect to it. Whether positively or negatively
752 297e6e53 Guido Trotter
    # it's debatable.
753 297e6e53 Guido Trotter
    vnc_pwd_file = conf_hvp[constants.HV_VNC_PASSWORD_FILE]
754 6e6bb8d5 Guido Trotter
    vnc_pwd = None
755 6e6bb8d5 Guido Trotter
    if vnc_pwd_file:
756 6e6bb8d5 Guido Trotter
      try:
757 682f7601 Guido Trotter
        vnc_pwd = utils.ReadOneLineFile(vnc_pwd_file, strict=True)
758 6e6bb8d5 Guido Trotter
      except EnvironmentError, err:
759 6e6bb8d5 Guido Trotter
        raise errors.HypervisorError("Failed to open VNC password file %s: %s"
760 6e6bb8d5 Guido Trotter
                                     % (vnc_pwd_file, err))
761 6e6bb8d5 Guido Trotter
762 297e6e53 Guido Trotter
    if conf_hvp[constants.HV_KVM_USE_CHROOT]:
763 547a63b7 Balazs Lecz
      utils.EnsureDirs([(self._InstanceChrootDir(name),
764 547a63b7 Balazs Lecz
                         constants.SECURE_DIR_MODE)])
765 547a63b7 Balazs Lecz
766 76431533 Guido Trotter
    if security_model == constants.HT_SM_POOL:
767 76431533 Guido Trotter
      ss = ssconf.SimpleStore()
768 76431533 Guido Trotter
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n")
769 76431533 Guido Trotter
      all_uids = set(uidpool.ExpandUidPool(uid_pool))
770 76431533 Guido Trotter
      uid = uidpool.RequestUnusedUid(all_uids)
771 76431533 Guido Trotter
      try:
772 76431533 Guido Trotter
        username = pwd.getpwuid(uid.GetUid()).pw_name
773 76431533 Guido Trotter
        kvm_cmd.extend(["-runas", username])
774 76431533 Guido Trotter
        self._RunKVMCmd(name, kvm_cmd)
775 76431533 Guido Trotter
      except:
776 76431533 Guido Trotter
        uidpool.ReleaseUid(uid)
777 76431533 Guido Trotter
        raise
778 76431533 Guido Trotter
      else:
779 76431533 Guido Trotter
        uid.Unlock()
780 76431533 Guido Trotter
        utils.WriteFile(self._InstanceUidFile(name), data=str(uid))
781 76431533 Guido Trotter
    else:
782 76431533 Guido Trotter
      self._RunKVMCmd(name, kvm_cmd)
783 eb58f9b1 Guido Trotter
784 6e6bb8d5 Guido Trotter
    if vnc_pwd:
785 6e6bb8d5 Guido Trotter
      change_cmd = 'change vnc password %s' % vnc_pwd
786 6e6bb8d5 Guido Trotter
      self._CallMonitorCommand(instance.name, change_cmd)
787 6e6bb8d5 Guido Trotter
788 08137f9e Iustin Pop
    for filename in temp_files:
789 08137f9e Iustin Pop
      utils.RemoveFile(filename)
790 eb58f9b1 Guido Trotter
791 07813a9e Iustin Pop
  def StartInstance(self, instance, block_devices):
792 ee5f20b0 Guido Trotter
    """Start an instance.
793 ee5f20b0 Guido Trotter

794 ee5f20b0 Guido Trotter
    """
795 5905901c Iustin Pop
    self._CheckDown(instance.name)
796 07813a9e Iustin Pop
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices)
797 38e250ba Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
798 ee5f20b0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
799 ee5f20b0 Guido Trotter
800 6567aff3 Guido Trotter
  def _CallMonitorCommand(self, instance_name, command):
801 6567aff3 Guido Trotter
    """Invoke a command on the instance monitor.
802 6567aff3 Guido Trotter

803 6567aff3 Guido Trotter
    """
804 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
805 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
806 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
807 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
808 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
809 6567aff3 Guido Trotter
    if result.failed:
810 6567aff3 Guido Trotter
      msg = ("Failed to send command '%s' to instance %s."
811 6567aff3 Guido Trotter
             " output: %s, error: %s, fail_reason: %s" %
812 9798fcae Guido Trotter
             (command, instance_name,
813 9798fcae Guido Trotter
              result.stdout, result.stderr, result.fail_reason))
814 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
815 6567aff3 Guido Trotter
816 6567aff3 Guido Trotter
    return result
817 6567aff3 Guido Trotter
818 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
819 eb58f9b1 Guido Trotter
    """Stop an instance.
820 eb58f9b1 Guido Trotter

821 eb58f9b1 Guido Trotter
    """
822 bbcf7ad0 Iustin Pop
    if name is not None and not force:
823 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
824 bbcf7ad0 Iustin Pop
    if name is None:
825 bbcf7ad0 Iustin Pop
      name = instance.name
826 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
827 bbcf7ad0 Iustin Pop
    else:
828 bbcf7ad0 Iustin Pop
      acpi = False
829 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
830 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
831 bbcf7ad0 Iustin Pop
      if force or not acpi:
832 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
833 eb58f9b1 Guido Trotter
      else:
834 bbcf7ad0 Iustin Pop
        self._CallMonitorCommand(name, 'system_powerdown')
835 eb58f9b1 Guido Trotter
836 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
837 8904b35c Guido Trotter
    """Cleanup after a stopped instance
838 8904b35c Guido Trotter

839 8904b35c Guido Trotter
    """
840 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
841 8904b35c Guido Trotter
    if pid > 0 and alive:
842 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
843 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
844 eb58f9b1 Guido Trotter
845 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
846 eb58f9b1 Guido Trotter
    """Reboot an instance.
847 eb58f9b1 Guido Trotter

848 eb58f9b1 Guido Trotter
    """
849 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
850 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
851 eb58f9b1 Guido Trotter
    # to shutdown and restart.
852 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
853 1f8b3a27 Guido Trotter
    if not alive:
854 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
855 78411c60 Iustin Pop
                                   " not running" % instance.name)
856 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
857 f02881e0 Guido Trotter
    # ...first load it...
858 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
859 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
860 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
861 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
862 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
863 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
864 f02881e0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
865 eb58f9b1 Guido Trotter
866 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
867 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
868 30e42c4e Guido Trotter

869 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
870 30e42c4e Guido Trotter
    @param instance: instance to be migrated
871 30e42c4e Guido Trotter
    @rtype: string
872 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
873 30e42c4e Guido Trotter

874 30e42c4e Guido Trotter
    """
875 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
876 30e42c4e Guido Trotter
877 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
878 30e42c4e Guido Trotter
    """Prepare to accept an instance.
879 30e42c4e Guido Trotter

880 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
881 30e42c4e Guido Trotter
    @param instance: instance to be accepted
882 30e42c4e Guido Trotter
    @type info: string
883 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
884 30e42c4e Guido Trotter
    @type target: string
885 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
886 30e42c4e Guido Trotter

887 30e42c4e Guido Trotter
    """
888 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
889 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
890 30e42c4e Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, incoming=incoming_address)
891 30e42c4e Guido Trotter
892 30e42c4e Guido Trotter
  def FinalizeMigration(self, instance, info, success):
893 30e42c4e Guido Trotter
    """Finalize an instance migration.
894 30e42c4e Guido Trotter

895 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
896 30e42c4e Guido Trotter

897 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
898 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
899 30e42c4e Guido Trotter

900 30e42c4e Guido Trotter
    """
901 30e42c4e Guido Trotter
    if success:
902 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
903 30e42c4e Guido Trotter
    else:
904 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
905 30e42c4e Guido Trotter
906 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
907 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
908 30e42c4e Guido Trotter

909 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
910 30e42c4e Guido Trotter
    currently running.
911 30e42c4e Guido Trotter

912 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
913 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
914 30e42c4e Guido Trotter
    @type target: string
915 30e42c4e Guido Trotter
    @param target: ip address of the target node
916 30e42c4e Guido Trotter
    @type live: boolean
917 30e42c4e Guido Trotter
    @param live: perform a live migration
918 30e42c4e Guido Trotter

919 30e42c4e Guido Trotter
    """
920 58d38b02 Iustin Pop
    instance_name = instance.name
921 50716be0 Iustin Pop
    port = instance.hvparams[constants.HV_MIGRATION_PORT]
922 30e42c4e Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
923 30e42c4e Guido Trotter
    if not alive:
924 30e42c4e Guido Trotter
      raise errors.HypervisorError("Instance not running, cannot migrate")
925 30e42c4e Guido Trotter
926 a744b676 Manuel Franceschini
    if not netutils.TcpPing(target, port, live_port_needed=True):
927 50716be0 Iustin Pop
      raise errors.HypervisorError("Remote host %s not listening on port"
928 50716be0 Iustin Pop
                                   " %s, cannot migrate" % (target, port))
929 50716be0 Iustin Pop
930 30e42c4e Guido Trotter
    if not live:
931 30e42c4e Guido Trotter
      self._CallMonitorCommand(instance_name, 'stop')
932 30e42c4e Guido Trotter
933 e43d4f9f Apollon Oikonomopoulos
    migrate_command = ('migrate_set_speed %dm' %
934 e43d4f9f Apollon Oikonomopoulos
        instance.hvparams[constants.HV_MIGRATION_BANDWIDTH])
935 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
936 e43d4f9f Apollon Oikonomopoulos
937 e43d4f9f Apollon Oikonomopoulos
    migrate_command = ('migrate_set_downtime %dms' %
938 e43d4f9f Apollon Oikonomopoulos
        instance.hvparams[constants.HV_MIGRATION_DOWNTIME])
939 e43d4f9f Apollon Oikonomopoulos
    self._CallMonitorCommand(instance_name, migrate_command)
940 e43d4f9f Apollon Oikonomopoulos
941 641ae041 Iustin Pop
    migrate_command = 'migrate -d tcp:%s:%s' % (target, port)
942 30e42c4e Guido Trotter
    self._CallMonitorCommand(instance_name, migrate_command)
943 30e42c4e Guido Trotter
944 30e42c4e Guido Trotter
    info_command = 'info migrate'
945 30e42c4e Guido Trotter
    done = False
946 c4e388a5 Guido Trotter
    broken_answers = 0
947 30e42c4e Guido Trotter
    while not done:
948 30e42c4e Guido Trotter
      result = self._CallMonitorCommand(instance_name, info_command)
949 30e42c4e Guido Trotter
      match = self._MIGRATION_STATUS_RE.search(result.stdout)
950 30e42c4e Guido Trotter
      if not match:
951 c4e388a5 Guido Trotter
        broken_answers += 1
952 c4e388a5 Guido Trotter
        if not result.stdout:
953 c4e388a5 Guido Trotter
          logging.info("KVM: empty 'info migrate' result")
954 c4e388a5 Guido Trotter
        else:
955 e4dd2299 Guido Trotter
          logging.warning("KVM: unknown 'info migrate' result: %s",
956 c4e388a5 Guido Trotter
                          result.stdout)
957 c4e388a5 Guido Trotter
        time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
958 30e42c4e Guido Trotter
      else:
959 30e42c4e Guido Trotter
        status = match.group(1)
960 30e42c4e Guido Trotter
        if status == 'completed':
961 30e42c4e Guido Trotter
          done = True
962 30e42c4e Guido Trotter
        elif status == 'active':
963 c4e388a5 Guido Trotter
          # reset the broken answers count
964 c4e388a5 Guido Trotter
          broken_answers = 0
965 c4e388a5 Guido Trotter
          time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
966 c087266c Guido Trotter
        elif status == 'failed' or status == 'cancelled':
967 c087266c Guido Trotter
          if not live:
968 c087266c Guido Trotter
            self._CallMonitorCommand(instance_name, 'cont')
969 c087266c Guido Trotter
          raise errors.HypervisorError("Migration %s at the kvm level" %
970 c087266c Guido Trotter
                                       status)
971 30e42c4e Guido Trotter
        else:
972 c4e388a5 Guido Trotter
          logging.warning("KVM: unknown migration status '%s'", status)
973 c4e388a5 Guido Trotter
          broken_answers += 1
974 c4e388a5 Guido Trotter
          time.sleep(self._MIGRATION_INFO_RETRY_DELAY)
975 c4e388a5 Guido Trotter
      if broken_answers >= self._MIGRATION_INFO_MAX_BAD_ANSWERS:
976 c4e388a5 Guido Trotter
        raise errors.HypervisorError("Too many 'info migrate' broken answers")
977 30e42c4e Guido Trotter
978 30e42c4e Guido Trotter
    utils.KillProcess(pid)
979 7b381438 Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
980 30e42c4e Guido Trotter
981 eb58f9b1 Guido Trotter
  def GetNodeInfo(self):
982 eb58f9b1 Guido Trotter
    """Return information about the node.
983 eb58f9b1 Guido Trotter

984 572e52bf Iustin Pop
    This is just a wrapper over the base GetLinuxNodeInfo method.
985 572e52bf Iustin Pop

986 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
987 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
988 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
989 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
990 eb58f9b1 Guido Trotter

991 eb58f9b1 Guido Trotter
    """
992 572e52bf Iustin Pop
    return self.GetLinuxNodeInfo()
993 eb58f9b1 Guido Trotter
994 637ce7f9 Guido Trotter
  @classmethod
995 5431b2e4 Guido Trotter
  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
996 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
997 eb58f9b1 Guido Trotter

998 eb58f9b1 Guido Trotter
    """
999 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
1000 86d6bc2a Guido Trotter
      shell_command = ("%s STDIO,%s UNIX-CONNECT:%s" %
1001 86d6bc2a Guido Trotter
                       (constants.SOCAT_PATH, cls._SocatUnixConsoleParams(),
1002 a2faf9ee Guido Trotter
                        utils.ShellQuote(cls._InstanceSerial(instance.name))))
1003 a2faf9ee Guido Trotter
    else:
1004 a2faf9ee Guido Trotter
      shell_command = "echo 'No serial shell for instance %s'" % instance.name
1005 3be34f57 Guido Trotter
1006 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
1007 3be34f57 Guido Trotter
    if vnc_bind_address:
1008 377d74c9 Guido Trotter
      if instance.network_port > constants.VNC_BASE_PORT:
1009 377d74c9 Guido Trotter
        display = instance.network_port - constants.VNC_BASE_PORT
1010 3be34f57 Guido Trotter
        vnc_command = ("echo 'Instance has VNC listening on %s:%d"
1011 3be34f57 Guido Trotter
                       " (display: %d)'" % (vnc_bind_address,
1012 3be34f57 Guido Trotter
                                            instance.network_port,
1013 3be34f57 Guido Trotter
                                            display))
1014 3be34f57 Guido Trotter
        shell_command = "%s; %s" % (vnc_command, shell_command)
1015 3be34f57 Guido Trotter
1016 a2faf9ee Guido Trotter
    return shell_command
1017 eb58f9b1 Guido Trotter
1018 eb58f9b1 Guido Trotter
  def Verify(self):
1019 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
1020 eb58f9b1 Guido Trotter

1021 eb58f9b1 Guido Trotter
    Check that the binary exists.
1022 eb58f9b1 Guido Trotter

1023 eb58f9b1 Guido Trotter
    """
1024 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
1025 eb58f9b1 Guido Trotter
      return "The kvm binary ('%s') does not exist." % constants.KVM_PATH
1026 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
1027 14aa53cb Guido Trotter
      return "The socat binary ('%s') does not exist." % constants.SOCAT_PATH
1028 14aa53cb Guido Trotter
1029 6b5605e8 Iustin Pop
1030 6b5605e8 Iustin Pop
  @classmethod
1031 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
1032 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
1033 6b5605e8 Iustin Pop

1034 6b5605e8 Iustin Pop
    @type hvparams:  dict
1035 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
1036 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
1037 6b5605e8 Iustin Pop

1038 6b5605e8 Iustin Pop
    """
1039 47387b1e Guido Trotter
    super(KVMHypervisor, cls).CheckParameterSyntax(hvparams)
1040 6b5605e8 Iustin Pop
1041 df5ab9f0 Guido Trotter
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
1042 df5ab9f0 Guido Trotter
    if kernel_path:
1043 df5ab9f0 Guido Trotter
      if not hvparams[constants.HV_ROOT_PATH]:
1044 205ab586 Iustin Pop
        raise errors.HypervisorError("Need a root partition for the instance,"
1045 205ab586 Iustin Pop
                                     " if a kernel is defined")
1046 6b5605e8 Iustin Pop
1047 205ab586 Iustin Pop
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
1048 205ab586 Iustin Pop
        not hvparams[constants.HV_VNC_X509]):
1049 205ab586 Iustin Pop
      raise errors.HypervisorError("%s must be defined, if %s is" %
1050 205ab586 Iustin Pop
                                   (constants.HV_VNC_X509,
1051 205ab586 Iustin Pop
                                    constants.HV_VNC_X509_VERIFY))
1052 66d5dbef Guido Trotter
1053 66d5dbef Guido Trotter
    boot_order = hvparams[constants.HV_BOOT_ORDER]
1054 205ab586 Iustin Pop
    if (boot_order == constants.HT_BO_CDROM and
1055 205ab586 Iustin Pop
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
1056 835528af Iustin Pop
      raise errors.HypervisorError("Cannot boot from cdrom without an"
1057 835528af Iustin Pop
                                   " ISO path")
1058 f5118ade Iustin Pop
1059 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1060 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1061 d19d94db Guido Trotter
      if not hvparams[constants.HV_SECURITY_DOMAIN]:
1062 d19d94db Guido Trotter
        raise errors.HypervisorError("A security domain (user to run kvm as)"
1063 d19d94db Guido Trotter
                                     " must be specified")
1064 d19d94db Guido Trotter
    elif (security_model == constants.HT_SM_NONE or
1065 d19d94db Guido Trotter
          security_model == constants.HT_SM_POOL):
1066 d19d94db Guido Trotter
      if hvparams[constants.HV_SECURITY_DOMAIN]:
1067 d19d94db Guido Trotter
        raise errors.HypervisorError("Cannot have a security domain when the"
1068 d19d94db Guido Trotter
                                     " security model is 'none' or 'pool'")
1069 d19d94db Guido Trotter
1070 d19d94db Guido Trotter
  @classmethod
1071 d19d94db Guido Trotter
  def ValidateParameters(cls, hvparams):
1072 d19d94db Guido Trotter
    """Check the given parameters for validity.
1073 d19d94db Guido Trotter

1074 d19d94db Guido Trotter
    @type hvparams:  dict
1075 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
1076 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
1077 d19d94db Guido Trotter

1078 d19d94db Guido Trotter
    """
1079 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
1080 d19d94db Guido Trotter
1081 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1082 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1083 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
1084 d19d94db Guido Trotter
      try:
1085 1feb39ec Guido Trotter
        pwd.getpwnam(username)
1086 d19d94db Guido Trotter
      except KeyError:
1087 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
1088 d19d94db Guido Trotter
                                     % username)
1089 d19d94db Guido Trotter
1090 f5118ade Iustin Pop
  @classmethod
1091 f5118ade Iustin Pop
  def PowercycleNode(cls):
1092 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
1093 f5118ade Iustin Pop

1094 f5118ade Iustin Pop
    """
1095 f5118ade Iustin Pop
    cls.LinuxPowercycle()