Revision af2f716d

b/lib/hypervisor/hv_kvm.py
1965 1965
    if not match:
1966 1966
      raise errors.HotplugError("Try hotplug only in running instances.")
1967 1967
    v_major, v_min, _, _ = match.groups()
1968
    if (v_major, v_min) < (1, 0):
1968
    if (int(v_major), int(v_min)) < (1, 0):
1969 1969
      raise errors.HotplugError("Hotplug not supported for qemu versions < 1.0")
1970 1970

  
1971 1971
    if dev_type == constants.HOTPLUG_TARGET_DISK:
......
1991 1991
    for line in output.stdout.splitlines():
1992 1992
      logging.info("%s", line)
1993 1993

  
1994
  def HotAddDevice(self, instance, dev_type, device, extra, seq):
1995
    """ Helper method to hot-add a new device
1996

  
1997
    It gets free pci slot generates the device name and invokes the
1998
    device specific method.
1999

  
2000
    """
2001
    # in case of hot-mod this is given
2002
    if device.pci is None:
2003
      self._GetFreePCISlot(instance, device)
2004
    kvm_devid = _GenerateDeviceKVMId(dev_type, device)
2005
    runtime = self._LoadKVMRuntime(instance)
2006
    if dev_type == constants.HOTPLUG_TARGET_DISK:
2007
      command = "drive_add dummy file=%s,if=none,id=%s,format=raw\n" % \
2008
                 (extra, kvm_devid)
2009
      command += ("device_add virtio-blk-pci,bus=pci.0,addr=%s,drive=%s,id=%s" %
2010
                  (hex(device.pci), kvm_devid, kvm_devid))
2011
    elif dev_type == constants.HOTPLUG_TARGET_NIC:
2012
      (tap, fd) = _OpenTap()
2013
      self._ConfigureNIC(instance, seq, device, tap)
2014
      self._PassTapFd(instance, fd, device)
2015
      command = "netdev_add tap,id=%s,fd=%s\n" % (kvm_devid, kvm_devid)
2016
      args = "virtio-net-pci,bus=pci.0,addr=%s,mac=%s,netdev=%s,id=%s" % \
2017
               (hex(device.pci), device.mac, kvm_devid, kvm_devid)
2018
      command += "device_add %s" % args
2019
      utils.WriteFile(self._InstanceNICFile(instance.name, seq), data=tap)
2020

  
2021
    self._CallHotplugCommand(instance.name, command)
2022
    # update relevant entries in runtime file
2023
    index = _DEVICE_RUNTIME_INDEX[dev_type]
2024
    entry = _RUNTIME_ENTRY[dev_type](device, extra)
2025
    runtime[index].append(entry)
2026
    self._SaveKVMRuntime(instance, runtime)
2027

  
2028
  def HotDelDevice(self, instance, dev_type, device, _, seq):
2029
    """ Helper method for hot-del device
2030

  
2031
    It gets device info from runtime file, generates the device name and
2032
    invokes the device specific method.
2033

  
2034
    """
2035
    runtime = self._LoadKVMRuntime(instance)
2036
    entry = _GetExistingDeviceInfo(dev_type, device, runtime)
2037
    kvm_device = _RUNTIME_DEVICE[dev_type](entry)
2038
    kvm_devid = _GenerateDeviceKVMId(dev_type, kvm_device)
2039
    if dev_type == constants.HOTPLUG_TARGET_DISK:
2040
      command = "device_del %s" % kvm_devid
2041
    elif dev_type == constants.HOTPLUG_TARGET_NIC:
2042
      command = "device_del %s\n" % kvm_devid
2043
      command += "netdev_del %s" % kvm_devid
2044
      utils.RemoveFile(self._InstanceNICFile(instance.name, seq))
2045
    self._CallHotplugCommand(instance.name, command)
2046
    index = _DEVICE_RUNTIME_INDEX[dev_type]
2047
    runtime[index].remove(entry)
2048
    self._SaveKVMRuntime(instance, runtime)
2049

  
2050
    return kvm_device.pci
2051

  
2052
  def HotModDevice(self, instance, dev_type, device, _, seq):
2053
    """ Helper method for hot-mod device
2054

  
2055
    It gets device info from runtime file, generates the device name and
2056
    invokes the device specific method. Currently only NICs support hot-mod
2057

  
2058
    """
2059
    if dev_type == constants.HOTPLUG_TARGET_NIC:
2060
      # putting it back in the same pci slot
2061
      device.pci = self.HotDelDevice(instance, dev_type, device, _, seq)
2062
      # TODO: remove sleep when socat gets removed
2063
      time.sleep(2)
2064
      self.HotAddDevice(instance, dev_type, device, _, seq)
2065

  
2066
  def _PassTapFd(self, instance, fd, nic):
2067
    """Pass file descriptor to kvm process via monitor socket using SCM_RIGHTS
2068

  
2069
    """
2070
    # TODO: factor out code related to unix sockets.
2071
    #       squash common parts between monitor and qmp
2072
    kvm_devid = _GenerateDeviceKVMId(constants.HOTPLUG_TARGET_NIC, nic)
2073
    command = "getfd %s\n" % kvm_devid
2074
    fds = [fd]
2075
    logging.info("%s", fds)
2076
    try:
2077
      monsock = MonitorSocket(self._InstanceMonitor(instance.name))
2078
      monsock.connect()
2079
      fdsend.sendfds(monsock.sock, command, fds=fds)
2080
    finally:
2081
      monsock.close()
2082

  
1994 2083
  @classmethod
1995 2084
  def _ParseKVMVersion(cls, text):
1996 2085
    """Parse the KVM version from the --help output.

Also available in: Unified diff