Revision ad00ee21
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 | ||
---|---|---|
2663 | 2663 |
# dictionary with instance information after the modification |
2664 | 2664 |
ispec = {} |
2665 | 2665 |
|
2666 |
if self.op.hotplug: |
|
2667 |
result = self.rpc.call_hotplug_supported(self.instance.primary_node, |
|
2668 |
self.instance) |
|
2669 |
result.Raise("Hotplug is not supported.") |
|
2670 |
|
|
2666 | 2671 |
# Check disk modifications. This is done here and not in CheckArguments |
2667 | 2672 |
# (as with NICs), because we need to know the instance's disk template |
2668 | 2673 |
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 |
# pylint: disable=R0201,W0613 |
|
561 |
def VerifyHotplugSupport(self, instance, action, dev_type): |
|
561 | 562 |
"""Whether hotplug is supported. |
562 | 563 |
|
564 |
Given the target device and hotplug action checks if hotplug is |
|
565 |
actually supported. |
|
566 |
|
|
567 |
@type instance: L{objects.Instance} |
|
568 |
@param instance: the instance object |
|
569 |
@type action: string |
|
570 |
@param action: one of the supported hotplug commands |
|
571 |
@type dev_type: string |
|
572 |
@param dev_type: one of the supported device types to hotplug |
|
573 |
@raise errors.HotplugError: if hotplugging is not supported |
|
574 |
|
|
563 | 575 |
Depends on instance's hvparam, the action. and the dev_type |
564 | 576 |
""" |
565 |
pass |
|
577 |
raise errors.HotplugError("Hotplug is not supported.") |
|
578 |
|
|
579 |
# pylint: disable=R0201,W0613 |
|
580 |
def HotplugSupported(self, instance): |
|
581 |
"""Checks if hotplug is supported. |
|
582 |
|
|
583 |
By default is not. Currently only KVM hypervisor supports it. |
|
584 |
|
|
585 |
""" |
|
586 |
raise errors.HotplugError("Hotplug is not supported by this hypervisor") |
b/lib/hypervisor/hv_kvm.py | ||
---|---|---|
1952 | 1952 |
|
1953 | 1953 |
dev.pci = int(free) |
1954 | 1954 |
|
1955 |
def HotplugSupported(self, instance, action, dev_type):
|
|
1955 |
def VerifyHotplugSupport(self, instance, action, dev_type):
|
|
1956 | 1956 |
"""Check if hotplug is supported. |
1957 | 1957 |
|
1958 | 1958 |
Hotplug is *not* supported in case of: |
1959 |
- qemu versions < 1.0 |
|
1960 | 1959 |
- security models and chroot (disk hotplug) |
1961 | 1960 |
- fdsend module is missing (nic hot-add) |
1962 | 1961 |
|
1963 | 1962 |
@raise errors.HypervisorError: in previous cases |
1964 | 1963 |
|
1965 | 1964 |
""" |
1966 |
output = self._CallMonitorCommand(instance.name, self._INFO_VERSION_CMD) |
|
1967 |
# TODO: search for netdev_add, drive_add, device_add..... |
|
1968 |
match = self._INFO_VERSION_RE.search(output.stdout) |
|
1969 |
if not match: |
|
1970 |
raise errors.HotplugError("Try hotplug only in running instances.") |
|
1971 |
v_major, v_min, _, _ = match.groups() |
|
1972 |
if (v_major, v_min) <= (1, 0): |
|
1973 |
raise errors.HotplugError("Hotplug not supported for qemu versions < 1.0") |
|
1974 |
|
|
1975 | 1965 |
if dev_type == constants.HOTPLUG_TARGET_DISK: |
1976 | 1966 |
hvp = instance.hvparams |
1977 | 1967 |
security_model = hvp[constants.HV_SECURITY_MODEL] |
... | ... | |
1989 | 1979 |
" fdsend python module is missing.") |
1990 | 1980 |
return True |
1991 | 1981 |
|
1982 |
def HotplugSupported(self, instance): |
|
1983 |
"""Checks if hotplug is generally supported. |
|
1984 |
|
|
1985 |
Hotplug is *not* supported in case of: |
|
1986 |
- qemu versions < 1.0 |
|
1987 |
- for stopped instances |
|
1988 |
|
|
1989 |
@raise errors.HypervisorError: in one of the previous cases |
|
1990 |
|
|
1991 |
""" |
|
1992 |
output = self._CallMonitorCommand(instance.name, self._INFO_VERSION_CMD) |
|
1993 |
# TODO: search for netdev_add, drive_add, device_add..... |
|
1994 |
match = self._INFO_VERSION_RE.search(output.stdout) |
|
1995 |
if not match: |
|
1996 |
raise errors.HotplugError("Try hotplug only in running instances.") |
|
1997 |
v_major, v_min, _, _ = match.groups() |
|
1998 |
if (int(v_major), int(v_min)) < (1, 0): |
|
1999 |
raise errors.HotplugError("Hotplug not supported for qemu versions < 1.0") |
|
2000 |
|
|
1992 | 2001 |
def _CallHotplugCommand(self, name, cmd): |
1993 | 2002 |
output = self._CallMonitorCommand(name, cmd) |
1994 | 2003 |
# 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 | ||
---|---|---|
619 | 619 |
return backend.HotplugDevice(instance, action, dev_type, device, extra, seq) |
620 | 620 |
|
621 | 621 |
@staticmethod |
622 |
def perspective_hotplug_supported(params): |
|
623 |
"""Checks if hotplug is supported. |
|
624 |
|
|
625 |
""" |
|
626 |
instance = objects.Instance.FromDict(params[0]) |
|
627 |
return backend.HotplugSupported(instance) |
|
628 |
|
|
629 |
@staticmethod |
|
622 | 630 |
def perspective_migration_info(params): |
623 | 631 |
"""Gather information about an instance to be migrated. |
624 | 632 |
|
Also available in: Unified diff