Revision b74de5e8

b/lib/backend.py
1646 1646

  
1647 1647
  """
1648 1648
  hyper = hypervisor.GetHypervisor(instance.hypervisor)
1649
  try:
1650
    hyper.VerifyHotplugSupport(instance, action, dev_type)
1651
  except errors.HotplugError, err:
1652
    _Fail("Hotplug is not supported: %s", err)
1653

  
1649 1654
  if action == constants.HOTPLUG_ACTION_ADD:
1650 1655
    fn = hyper.HotAddDevice
1651 1656
  elif action == constants.HOTPLUG_ACTION_REMOVE:
......
1655 1660
  else:
1656 1661
    assert action in constants.HOTPLUG_ALL_ACTIONS
1657 1662
  # This will raise an exception if hotplug is no supported for this case
1658
  hyper.HotplugSupported(instance, action, dev_type)
1659 1663
  return fn(instance, dev_type, device, extra, seq)
1660 1664

  
1661 1665

  
1666
def HotplugSupported(instance):
1667
  """Checks if hotplug is generally supported.
1668

  
1669
  """
1670
  hyper = hypervisor.GetHypervisor(instance.hypervisor)
1671
  try:
1672
    hyper.HotplugSupported(instance)
1673
  except errors.HotplugError, err:
1674
    _Fail("Hotplug is not supported: %s", err)
1675

  
1676

  
1662 1677
def BlockdevCreate(disk, size, owner, on_primary, info, excl_stor):
1663 1678
  """Creates a block device for an instance.
1664 1679

  
b/lib/cmdlib/instance.py
2665 2665
    # dictionary with instance information after the modification
2666 2666
    ispec = {}
2667 2667

  
2668
    if self.op.hotplug:
2669
      result = self.rpc.call_hotplug_supported(self.instance.primary_node,
2670
                                               self.instance)
2671
      result.Raise("Hotplug is not supported.")
2672

  
2668 2673
    # Check disk modifications. This is done here and not in CheckArguments
2669 2674
    # (as with NICs), because we need to know the instance's disk template
2670 2675
    if instance.disk_template == constants.DT_EXT:
b/lib/hypervisor/hv_base.py
557 557
    """
558 558
    pass
559 559

  
560
  def HotplugSupported(self, instance, action, dev_type):
560
  def VerifyHotplugSupport(self, instance, action, dev_type):
561 561
    """Whether hotplug is supported.
562 562

  
563
    Given the target device and hotplug action checks if hotplug is
564
    actually supported.
565

  
566
    @type instance: L{objects.Instance}
567
    @param instance: the instance object
568
    @type action: string
569
    @param action: one of the supported hotplug commands
570
    @type dev_type: string
571
    @param dev_type: one of the supported device types to hotplug
572
    @raise errors.HotplugError: if hotplugging is not supported
573

  
563 574
    Depends on instance's hvparam, the action. and the dev_type
564 575
    """
565
    pass
576
    raise errors.HotplugError("Hotplug is not supported.")
577

  
578
  def HotplugSupported(self, instance):
579
    """Checks if hotplug is supported.
580

  
581
    By default is not. Currently only KVM hypervisor supports it.
582

  
583
    """
584
    raise errors.HotplugError("Hotplug is not supported by this hypervisor")
b/lib/hypervisor/hv_kvm.py
1953 1953

  
1954 1954
    dev.pci = int(free)
1955 1955

  
1956
  def HotplugSupported(self, instance, action, dev_type):
1956
  def VerifyHotplugSupport(self, instance, action, dev_type):
1957 1957
    """Check if hotplug is supported.
1958 1958

  
1959 1959
    Hotplug is *not* supported in case of:
1960
     - qemu versions < 1.0
1961 1960
     - security models and chroot (disk hotplug)
1962 1961
     - fdsend module is missing (nic hot-add)
1963 1962

  
1964 1963
    @raise errors.HypervisorError: in previous cases
1965 1964

  
1966 1965
    """
1967
    output = self._CallMonitorCommand(instance.name, self._INFO_VERSION_CMD)
1968
    # TODO: search for netdev_add, drive_add, device_add.....
1969
    match = self._INFO_VERSION_RE.search(output.stdout)
1970
    if not match:
1971
      raise errors.HotplugError("Try hotplug only in running instances.")
1972
    v_major, v_min, _, _ = match.groups()
1973
    if (v_major, v_min) <= (1, 0):
1974
      raise errors.HotplugError("Hotplug not supported for qemu versions < 1.0")
1975

  
1976 1966
    if dev_type == constants.HOTPLUG_TARGET_DISK:
1977 1967
      hvp = instance.hvparams
1978 1968
      security_model = hvp[constants.HV_SECURITY_MODEL]
......
1990 1980
                                " fdsend python module is missing.")
1991 1981
    return True
1992 1982

  
1983
  def HotplugSupported(self, instance):
1984
    """Checks if hotplug is generally supported.
1985

  
1986
    Hotplug is *not* supported in case of:
1987
     - qemu versions < 1.0
1988
     - for stopped instances
1989

  
1990
    @raise errors.HypervisorError: in one of the previous cases
1991

  
1992
    """
1993
    output = self._CallMonitorCommand(instance.name, self._INFO_VERSION_CMD)
1994
    # TODO: search for netdev_add, drive_add, device_add.....
1995
    match = self._INFO_VERSION_RE.search(output.stdout)
1996
    if not match:
1997
      raise errors.HotplugError("Try hotplug only in running instances.")
1998
    v_major, v_min, _, _ = match.groups()
1999
    if (int(v_major), int(v_min)) < (1, 0):
2000
      raise errors.HotplugError("Hotplug not supported for qemu versions < 1.0")
2001

  
1993 2002
  def _CallHotplugCommand(self, name, cmd):
1994 2003
    output = self._CallMonitorCommand(name, cmd)
1995 2004
    # TODO: parse output and check if succeeded
b/lib/rpc_defs.py
295 295
    ("extra", None, "Extra info for device (dev_path for disk)"),
296 296
    ("seq", None, "Device seq"),
297 297
    ], None, None, "Hoplug a device to a running instance"),
298
  ("hotplug_supported", SINGLE, None, constants.RPC_TMO_NORMAL, [
299
    ("instance", ED_INST_DICT, "Instance object"),
300
    ], None, None, "Check if hotplug is supported"),
298 301
  ]
299 302

  
300 303
_IMPEXP_CALLS = [
b/lib/server/noded.py
620 620
    return backend.HotplugDevice(instance, action, dev_type, device, extra, seq)
621 621

  
622 622
  @staticmethod
623
  def perspective_hotplug_supported(params):
624
    """Checks if hotplug is supported.
625

  
626
    """
627
    instance = objects.Instance.FromDict(params[0])
628
    return backend.HotplugSupported(instance)
629

  
630
  @staticmethod
623 631
  def perspective_migration_info(params):
624 632
    """Gather information about an instance to be migrated.
625 633

  

Also available in: Unified diff