Statistics
| Branch: | Tag: | Revision:

root / lib / hypervisor / hv_kvm.py @ b52d85c1

History | View | Annotate | Download (37.9 kB)

1 eb58f9b1 Guido Trotter
#
2 eb58f9b1 Guido Trotter
#
3 eb58f9b1 Guido Trotter
4 783a6c0b Iustin Pop
# Copyright (C) 2008, 2009, 2010 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 783a6c0b Iustin Pop
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
198 6b970cef Jun Futagawa
    constants.HV_USE_LOCALTIME: hv_base.NO_CHECK,
199 19572932 Iustin Pop
    constants.HV_DISK_CACHE:
200 19572932 Iustin Pop
      hv_base.ParamInSet(True, constants.HT_VALID_CACHE_TYPES),
201 d19d94db Guido Trotter
    constants.HV_SECURITY_MODEL:
202 d19d94db Guido Trotter
      hv_base.ParamInSet(True, constants.HT_KVM_VALID_SM_TYPES),
203 d19d94db Guido Trotter
    constants.HV_SECURITY_DOMAIN: hv_base.NO_CHECK,
204 7ba594c0 Guido Trotter
    constants.HV_KVM_FLAG:
205 7ba594c0 Guido Trotter
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
206 fbe27e2b Guido Trotter
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
207 547a63b7 Balazs Lecz
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
208 205ab586 Iustin Pop
    }
209 6b5605e8 Iustin Pop
210 30e42c4e Guido Trotter
  _MIGRATION_STATUS_RE = re.compile('Migration\s+status:\s+(\w+)',
211 30e42c4e Guido Trotter
                                    re.M | re.I)
212 c4e388a5 Guido Trotter
  _MIGRATION_INFO_MAX_BAD_ANSWERS = 5
213 c4e388a5 Guido Trotter
  _MIGRATION_INFO_RETRY_DELAY = 2
214 30e42c4e Guido Trotter
215 b52d85c1 Guido Trotter
  _VERSION_RE = re.compile(r"\b(\d+)\.(\d+)\.(\d+)\b")
216 b52d85c1 Guido Trotter
217 64bfbc08 Guido Trotter
  ANCILLARY_FILES = [
218 64bfbc08 Guido Trotter
    _KVM_NETWORK_SCRIPT,
219 64bfbc08 Guido Trotter
    ]
220 64bfbc08 Guido Trotter
221 eb58f9b1 Guido Trotter
  def __init__(self):
222 eb58f9b1 Guido Trotter
    hv_base.BaseHypervisor.__init__(self)
223 eb58f9b1 Guido Trotter
    # Let's make sure the directories we need exist, even if the RUN_DIR lives
224 eb58f9b1 Guido Trotter
    # in a tmpfs filesystem or has been otherwise wiped out.
225 29921401 Iustin Pop
    dirs = [(dname, constants.RUN_DIRS_MODE) for dname in self._DIRS]
226 9afb67fe Guido Trotter
    utils.EnsureDirs(dirs)
227 eb58f9b1 Guido Trotter
228 30786fc9 Iustin Pop
  @classmethod
229 30786fc9 Iustin Pop
  def _InstancePidFile(cls, instance_name):
230 98ec75d6 Iustin Pop
    """Returns the instance pidfile.
231 98ec75d6 Iustin Pop

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

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

246 263b8de6 Guido Trotter
    Check that a pid file is associated with an instance, and retrieve
247 263b8de6 Guido Trotter
    information from its command line.
248 263b8de6 Guido Trotter

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

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

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

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

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

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

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

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

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

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

354 547a63b7 Balazs Lecz
    """
355 547a63b7 Balazs Lecz
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
356 547a63b7 Balazs Lecz
357 547a63b7 Balazs Lecz
  @classmethod
358 7548396c Guido Trotter
  def _TryReadUidFile(cls, uid_file):
359 7548396c Guido Trotter
    """Try to read a uid file
360 7548396c Guido Trotter

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

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

409 eb58f9b1 Guido Trotter
    This can be used by any qemu-type hypervisor.
410 eb58f9b1 Guido Trotter

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

805 6567aff3 Guido Trotter
    """
806 6567aff3 Guido Trotter
    socat = ("echo %s | %s STDIO UNIX-CONNECT:%s" %
807 6567aff3 Guido Trotter
             (utils.ShellQuote(command),
808 6567aff3 Guido Trotter
              constants.SOCAT_PATH,
809 6567aff3 Guido Trotter
              utils.ShellQuote(self._InstanceMonitor(instance_name))))
810 6567aff3 Guido Trotter
    result = utils.RunCmd(socat)
811 6567aff3 Guido Trotter
    if result.failed:
812 6567aff3 Guido Trotter
      msg = ("Failed to send command '%s' to instance %s."
813 6567aff3 Guido Trotter
             " output: %s, error: %s, fail_reason: %s" %
814 9798fcae Guido Trotter
             (command, instance_name,
815 9798fcae Guido Trotter
              result.stdout, result.stderr, result.fail_reason))
816 6567aff3 Guido Trotter
      raise errors.HypervisorError(msg)
817 6567aff3 Guido Trotter
818 6567aff3 Guido Trotter
    return result
819 6567aff3 Guido Trotter
820 b52d85c1 Guido Trotter
  @classmethod
821 b52d85c1 Guido Trotter
  def _GetKVMVersion(cls):
822 b52d85c1 Guido Trotter
    """Return the installed KVM version
823 b52d85c1 Guido Trotter

824 b52d85c1 Guido Trotter
    @return: (version, v_maj, v_min, v_rev), or None
825 b52d85c1 Guido Trotter

826 b52d85c1 Guido Trotter
    """
827 b52d85c1 Guido Trotter
    result = utils.RunCmd([constants.KVM_PATH, "--help"])
828 b52d85c1 Guido Trotter
    if result.failed:
829 b52d85c1 Guido Trotter
      return None
830 b52d85c1 Guido Trotter
    match = cls._VERSION_RE.search(result.output.splitlines()[0])
831 b52d85c1 Guido Trotter
    if not match:
832 b52d85c1 Guido Trotter
      return None
833 b52d85c1 Guido Trotter
    return (match.group(0), match.group(1), match.group(2), match.group(3))
834 b52d85c1 Guido Trotter
835 bbcf7ad0 Iustin Pop
  def StopInstance(self, instance, force=False, retry=False, name=None):
836 eb58f9b1 Guido Trotter
    """Stop an instance.
837 eb58f9b1 Guido Trotter

838 eb58f9b1 Guido Trotter
    """
839 bbcf7ad0 Iustin Pop
    if name is not None and not force:
840 bbcf7ad0 Iustin Pop
      raise errors.HypervisorError("Cannot shutdown cleanly by name only")
841 bbcf7ad0 Iustin Pop
    if name is None:
842 bbcf7ad0 Iustin Pop
      name = instance.name
843 bbcf7ad0 Iustin Pop
      acpi = instance.hvparams[constants.HV_ACPI]
844 bbcf7ad0 Iustin Pop
    else:
845 bbcf7ad0 Iustin Pop
      acpi = False
846 8904b35c Guido Trotter
    _, pid, alive = self._InstancePidAlive(name)
847 1f8b3a27 Guido Trotter
    if pid > 0 and alive:
848 bbcf7ad0 Iustin Pop
      if force or not acpi:
849 eb58f9b1 Guido Trotter
        utils.KillProcess(pid)
850 eb58f9b1 Guido Trotter
      else:
851 bbcf7ad0 Iustin Pop
        self._CallMonitorCommand(name, 'system_powerdown')
852 eb58f9b1 Guido Trotter
853 8904b35c Guido Trotter
  def CleanupInstance(self, instance_name):
854 8904b35c Guido Trotter
    """Cleanup after a stopped instance
855 8904b35c Guido Trotter

856 8904b35c Guido Trotter
    """
857 8904b35c Guido Trotter
    pidfile, pid, alive = self._InstancePidAlive(instance_name)
858 8904b35c Guido Trotter
    if pid > 0 and alive:
859 8904b35c Guido Trotter
      raise errors.HypervisorError("Cannot cleanup a live instance")
860 8904b35c Guido Trotter
    self._RemoveInstanceRuntimeFiles(pidfile, instance_name)
861 eb58f9b1 Guido Trotter
862 eb58f9b1 Guido Trotter
  def RebootInstance(self, instance):
863 eb58f9b1 Guido Trotter
    """Reboot an instance.
864 eb58f9b1 Guido Trotter

865 eb58f9b1 Guido Trotter
    """
866 eb58f9b1 Guido Trotter
    # For some reason if we do a 'send-key ctrl-alt-delete' to the control
867 eb58f9b1 Guido Trotter
    # socket the instance will stop, but now power up again. So we'll resort
868 eb58f9b1 Guido Trotter
    # to shutdown and restart.
869 1122eb25 Iustin Pop
    _, _, alive = self._InstancePidAlive(instance.name)
870 1f8b3a27 Guido Trotter
    if not alive:
871 78411c60 Iustin Pop
      raise errors.HypervisorError("Failed to reboot instance %s:"
872 78411c60 Iustin Pop
                                   " not running" % instance.name)
873 f02881e0 Guido Trotter
    # StopInstance will delete the saved KVM runtime so:
874 f02881e0 Guido Trotter
    # ...first load it...
875 f02881e0 Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance)
876 f02881e0 Guido Trotter
    # ...now we can safely call StopInstance...
877 f02881e0 Guido Trotter
    if not self.StopInstance(instance):
878 f02881e0 Guido Trotter
      self.StopInstance(instance, force=True)
879 f02881e0 Guido Trotter
    # ...and finally we can save it again, and execute it...
880 f02881e0 Guido Trotter
    self._SaveKVMRuntime(instance, kvm_runtime)
881 f02881e0 Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime)
882 eb58f9b1 Guido Trotter
883 30e42c4e Guido Trotter
  def MigrationInfo(self, instance):
884 30e42c4e Guido Trotter
    """Get instance information to perform a migration.
885 30e42c4e Guido Trotter

886 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
887 30e42c4e Guido Trotter
    @param instance: instance to be migrated
888 30e42c4e Guido Trotter
    @rtype: string
889 30e42c4e Guido Trotter
    @return: content of the KVM runtime file
890 30e42c4e Guido Trotter

891 30e42c4e Guido Trotter
    """
892 30e42c4e Guido Trotter
    return self._ReadKVMRuntime(instance.name)
893 30e42c4e Guido Trotter
894 30e42c4e Guido Trotter
  def AcceptInstance(self, instance, info, target):
895 30e42c4e Guido Trotter
    """Prepare to accept an instance.
896 30e42c4e Guido Trotter

897 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
898 30e42c4e Guido Trotter
    @param instance: instance to be accepted
899 30e42c4e Guido Trotter
    @type info: string
900 30e42c4e Guido Trotter
    @param info: content of the KVM runtime file on the source node
901 30e42c4e Guido Trotter
    @type target: string
902 30e42c4e Guido Trotter
    @param target: target host (usually ip), on this node
903 30e42c4e Guido Trotter

904 30e42c4e Guido Trotter
    """
905 30e42c4e Guido Trotter
    kvm_runtime = self._LoadKVMRuntime(instance, serialized_runtime=info)
906 641ae041 Iustin Pop
    incoming_address = (target, instance.hvparams[constants.HV_MIGRATION_PORT])
907 30e42c4e Guido Trotter
    self._ExecuteKVMRuntime(instance, kvm_runtime, incoming=incoming_address)
908 30e42c4e Guido Trotter
909 30e42c4e Guido Trotter
  def FinalizeMigration(self, instance, info, success):
910 30e42c4e Guido Trotter
    """Finalize an instance migration.
911 30e42c4e Guido Trotter

912 30e42c4e Guido Trotter
    Stop the incoming mode KVM.
913 30e42c4e Guido Trotter

914 30e42c4e Guido Trotter
    @type instance: L{objects.Instance}
915 fea922fa Guido Trotter
    @param instance: instance whose migration is being finalized
916 30e42c4e Guido Trotter

917 30e42c4e Guido Trotter
    """
918 30e42c4e Guido Trotter
    if success:
919 30e42c4e Guido Trotter
      self._WriteKVMRuntime(instance.name, info)
920 30e42c4e Guido Trotter
    else:
921 30e42c4e Guido Trotter
      self.StopInstance(instance, force=True)
922 30e42c4e Guido Trotter
923 58d38b02 Iustin Pop
  def MigrateInstance(self, instance, target, live):
924 30e42c4e Guido Trotter
    """Migrate an instance to a target node.
925 30e42c4e Guido Trotter

926 30e42c4e Guido Trotter
    The migration will not be attempted if the instance is not
927 30e42c4e Guido Trotter
    currently running.
928 30e42c4e Guido Trotter

929 58d38b02 Iustin Pop
    @type instance: L{objects.Instance}
930 58d38b02 Iustin Pop
    @param instance: the instance to be migrated
931 30e42c4e Guido Trotter
    @type target: string
932 30e42c4e Guido Trotter
    @param target: ip address of the target node
933 30e42c4e Guido Trotter
    @type live: boolean
934 30e42c4e Guido Trotter
    @param live: perform a live migration
935 30e42c4e Guido Trotter

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

997 572e52bf Iustin Pop
    This is just a wrapper over the base GetLinuxNodeInfo method.
998 572e52bf Iustin Pop

999 c41eea6e Iustin Pop
    @return: a dict with the following keys (values in MiB):
1000 c41eea6e Iustin Pop
          - memory_total: the total memory size on the node
1001 c41eea6e Iustin Pop
          - memory_free: the available memory on the node for instances
1002 c41eea6e Iustin Pop
          - memory_dom0: the memory used by the node itself, if available
1003 eb58f9b1 Guido Trotter

1004 eb58f9b1 Guido Trotter
    """
1005 572e52bf Iustin Pop
    return self.GetLinuxNodeInfo()
1006 eb58f9b1 Guido Trotter
1007 637ce7f9 Guido Trotter
  @classmethod
1008 5431b2e4 Guido Trotter
  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
1009 eb58f9b1 Guido Trotter
    """Return a command for connecting to the console of an instance.
1010 eb58f9b1 Guido Trotter

1011 eb58f9b1 Guido Trotter
    """
1012 a2faf9ee Guido Trotter
    if hvparams[constants.HV_SERIAL_CONSOLE]:
1013 86d6bc2a Guido Trotter
      shell_command = ("%s STDIO,%s UNIX-CONNECT:%s" %
1014 86d6bc2a Guido Trotter
                       (constants.SOCAT_PATH, cls._SocatUnixConsoleParams(),
1015 a2faf9ee Guido Trotter
                        utils.ShellQuote(cls._InstanceSerial(instance.name))))
1016 a2faf9ee Guido Trotter
    else:
1017 a2faf9ee Guido Trotter
      shell_command = "echo 'No serial shell for instance %s'" % instance.name
1018 3be34f57 Guido Trotter
1019 3be34f57 Guido Trotter
    vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
1020 3be34f57 Guido Trotter
    if vnc_bind_address:
1021 377d74c9 Guido Trotter
      if instance.network_port > constants.VNC_BASE_PORT:
1022 377d74c9 Guido Trotter
        display = instance.network_port - constants.VNC_BASE_PORT
1023 3be34f57 Guido Trotter
        vnc_command = ("echo 'Instance has VNC listening on %s:%d"
1024 3be34f57 Guido Trotter
                       " (display: %d)'" % (vnc_bind_address,
1025 3be34f57 Guido Trotter
                                            instance.network_port,
1026 3be34f57 Guido Trotter
                                            display))
1027 3be34f57 Guido Trotter
        shell_command = "%s; %s" % (vnc_command, shell_command)
1028 3be34f57 Guido Trotter
1029 a2faf9ee Guido Trotter
    return shell_command
1030 eb58f9b1 Guido Trotter
1031 eb58f9b1 Guido Trotter
  def Verify(self):
1032 eb58f9b1 Guido Trotter
    """Verify the hypervisor.
1033 eb58f9b1 Guido Trotter

1034 eb58f9b1 Guido Trotter
    Check that the binary exists.
1035 eb58f9b1 Guido Trotter

1036 eb58f9b1 Guido Trotter
    """
1037 eb58f9b1 Guido Trotter
    if not os.path.exists(constants.KVM_PATH):
1038 eb58f9b1 Guido Trotter
      return "The kvm binary ('%s') does not exist." % constants.KVM_PATH
1039 14aa53cb Guido Trotter
    if not os.path.exists(constants.SOCAT_PATH):
1040 14aa53cb Guido Trotter
      return "The socat binary ('%s') does not exist." % constants.SOCAT_PATH
1041 14aa53cb Guido Trotter
1042 6b5605e8 Iustin Pop
1043 6b5605e8 Iustin Pop
  @classmethod
1044 6b5605e8 Iustin Pop
  def CheckParameterSyntax(cls, hvparams):
1045 6b5605e8 Iustin Pop
    """Check the given parameters for validity.
1046 6b5605e8 Iustin Pop

1047 6b5605e8 Iustin Pop
    @type hvparams:  dict
1048 6b5605e8 Iustin Pop
    @param hvparams: dictionary with parameter names/value
1049 6b5605e8 Iustin Pop
    @raise errors.HypervisorError: when a parameter is not valid
1050 6b5605e8 Iustin Pop

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

1087 d19d94db Guido Trotter
    @type hvparams:  dict
1088 d19d94db Guido Trotter
    @param hvparams: dictionary with parameter names/value
1089 d19d94db Guido Trotter
    @raise errors.HypervisorError: when a parameter is not valid
1090 d19d94db Guido Trotter

1091 d19d94db Guido Trotter
    """
1092 d19d94db Guido Trotter
    super(KVMHypervisor, cls).ValidateParameters(hvparams)
1093 d19d94db Guido Trotter
1094 d19d94db Guido Trotter
    security_model = hvparams[constants.HV_SECURITY_MODEL]
1095 d19d94db Guido Trotter
    if security_model == constants.HT_SM_USER:
1096 d19d94db Guido Trotter
      username = hvparams[constants.HV_SECURITY_DOMAIN]
1097 d19d94db Guido Trotter
      try:
1098 1feb39ec Guido Trotter
        pwd.getpwnam(username)
1099 d19d94db Guido Trotter
      except KeyError:
1100 d19d94db Guido Trotter
        raise errors.HypervisorError("Unknown security domain user %s"
1101 d19d94db Guido Trotter
                                     % username)
1102 d19d94db Guido Trotter
1103 f5118ade Iustin Pop
  @classmethod
1104 f5118ade Iustin Pop
  def PowercycleNode(cls):
1105 f5118ade Iustin Pop
    """KVM powercycle, just a wrapper over Linux powercycle.
1106 f5118ade Iustin Pop

1107 f5118ade Iustin Pop
    """
1108 f5118ade Iustin Pop
    cls.LinuxPowercycle()