Revision 8bbcbb9e lib/hypervisor/hv_kvm.py
b/lib/hypervisor/hv_kvm.py | ||
---|---|---|
79 | 79 |
constants.HV_KVM_SPICE_USE_TLS, |
80 | 80 |
]) |
81 | 81 |
|
82 |
# below constants show the format of runtime file |
|
83 |
# the nics are in second possition, while the disks in 4th (last) |
|
84 |
# moreover disk entries are stored in tupples of L{objects.Disk}, dev_path |
|
85 |
_KVM_NICS_RUNTIME_INDEX = 1 |
|
86 |
_KVM_DISKS_RUNTIME_INDEX = 3 |
|
87 |
_DEVICE_RUNTIME_INDEX = { |
|
88 |
constants.HOTPLUG_TARGET_DISK: _KVM_DISKS_RUNTIME_INDEX, |
|
89 |
constants.HOTPLUG_TARGET_NIC: _KVM_NICS_RUNTIME_INDEX |
|
90 |
} |
|
91 |
_FIND_RUNTIME_ENTRY = { |
|
92 |
constants.HOTPLUG_TARGET_NIC: |
|
93 |
lambda nic, kvm_nics: [n for n in kvm_nics if n.uuid == nic.uuid], |
|
94 |
constants.HOTPLUG_TARGET_DISK: |
|
95 |
lambda disk, kvm_disks: [(d, l) for (d, l) in kvm_disks |
|
96 |
if d.uuid == disk.uuid] |
|
97 |
} |
|
98 |
_RUNTIME_DEVICE = { |
|
99 |
constants.HOTPLUG_TARGET_NIC: lambda d: d, |
|
100 |
constants.HOTPLUG_TARGET_DISK: lambda (d, e): d |
|
101 |
} |
|
102 |
_RUNTIME_ENTRY = { |
|
103 |
constants.HOTPLUG_TARGET_NIC: lambda d, e: d, |
|
104 |
constants.HOTPLUG_TARGET_DISK: lambda d, e: (d, e) |
|
105 |
} |
|
106 |
|
|
107 |
|
|
108 |
def _GetExistingDeviceInfo(dev_type, device, runtime): |
|
109 |
"""Helper function to get an existing device inside the runtime file |
|
110 |
|
|
111 |
Used when an instance is running. Load kvm runtime file and search |
|
112 |
for a device based on its type and uuid. |
|
113 |
|
|
114 |
@type dev_type: sting |
|
115 |
@param dev_type: device type of param dev |
|
116 |
@type device: L{objects.Disk} or L{objects.NIC} |
|
117 |
@param device: the device object for which we generate a kvm name |
|
118 |
@type runtime: tuple (cmd, nics, hvparams, disks) |
|
119 |
@param runtime: the runtime data to search for the device |
|
120 |
@raise errors.HotplugError: in case the requested device does not |
|
121 |
exist (e.g. device has been added without --hotplug option) or |
|
122 |
device info has not pci slot (e.g. old devices in the cluster) |
|
123 |
|
|
124 |
""" |
|
125 |
index = _DEVICE_RUNTIME_INDEX[dev_type] |
|
126 |
found = _FIND_RUNTIME_ENTRY[dev_type](device, runtime[index]) |
|
127 |
if not found: |
|
128 |
raise errors.HotplugError("Cannot find runtime info for %s with UUID %s" % |
|
129 |
(dev_type, device.uuid)) |
|
130 |
|
|
131 |
return found[0] |
|
132 |
|
|
82 | 133 |
|
83 | 134 |
def _GetTunFeatures(fd, _ioctl=fcntl.ioctl): |
84 | 135 |
"""Retrieves supported TUN features from file descriptor. |
... | ... | |
1418 | 1469 |
if hvp[constants.HV_KVM_EXTRA]: |
1419 | 1470 |
kvm_cmd.extend(hvp[constants.HV_KVM_EXTRA].split(" ")) |
1420 | 1471 |
|
1421 |
bdev_opts = self._GenerateKVMBlockDevicesOptions(instance, |
|
1422 |
block_devices, |
|
1423 |
kvmhelp) |
|
1424 |
kvm_cmd.extend(bdev_opts) |
|
1425 |
# Save the current instance nics, but defer their expansion as parameters, |
|
1426 |
# as we'll need to generate executable temp files for them. |
|
1427 |
kvm_nics = instance.nics |
|
1472 |
kvm_disks = [] |
|
1473 |
for disk, dev_path in block_devices: |
|
1474 |
kvm_disks.append((disk, dev_path)) |
|
1475 |
|
|
1476 |
kvm_nics = [] |
|
1477 |
for nic in instance.nics: |
|
1478 |
kvm_nics.append(nic) |
|
1479 |
|
|
1428 | 1480 |
hvparams = hvp |
1429 | 1481 |
|
1430 |
return (kvm_cmd, kvm_nics, hvparams) |
|
1482 |
return (kvm_cmd, kvm_nics, hvparams, kvm_disks)
|
|
1431 | 1483 |
|
1432 | 1484 |
def _WriteKVMRuntime(self, instance_name, data): |
1433 | 1485 |
"""Write an instance's KVM runtime |
... | ... | |
1453 | 1505 |
"""Save an instance's KVM runtime |
1454 | 1506 |
|
1455 | 1507 |
""" |
1456 |
kvm_cmd, kvm_nics, hvparams = kvm_runtime |
|
1508 |
kvm_cmd, kvm_nics, hvparams, block_devices = kvm_runtime |
|
1509 |
|
|
1457 | 1510 |
serialized_nics = [nic.ToDict() for nic in kvm_nics] |
1458 |
serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams)) |
|
1511 |
serialized_blockdevs = [(blk.ToDict(), link) for blk, link in block_devices] |
|
1512 |
serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams, |
|
1513 |
serialized_blockdevs)) |
|
1514 |
|
|
1459 | 1515 |
self._WriteKVMRuntime(instance.name, serialized_form) |
1460 | 1516 |
|
1461 | 1517 |
def _LoadKVMRuntime(self, instance, serialized_runtime=None): |
... | ... | |
1464 | 1520 |
""" |
1465 | 1521 |
if not serialized_runtime: |
1466 | 1522 |
serialized_runtime = self._ReadKVMRuntime(instance.name) |
1523 |
|
|
1467 | 1524 |
loaded_runtime = serializer.Load(serialized_runtime) |
1468 |
kvm_cmd, serialized_nics, hvparams = loaded_runtime |
|
1525 |
if len(loaded_runtime) == 3: |
|
1526 |
serialized_blockdevs = [] |
|
1527 |
kvm_cmd, serialized_nics, hvparams = loaded_runtime |
|
1528 |
else: |
|
1529 |
kvm_cmd, serialized_nics, hvparams, serialized_blockdevs = loaded_runtime |
|
1530 |
|
|
1469 | 1531 |
kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics] |
1470 |
return (kvm_cmd, kvm_nics, hvparams) |
|
1532 |
block_devices = [(objects.Disk.FromDict(sdisk), link) |
|
1533 |
for sdisk, link in serialized_blockdevs] |
|
1534 |
|
|
1535 |
return (kvm_cmd, kvm_nics, hvparams, block_devices) |
|
1471 | 1536 |
|
1472 | 1537 |
def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None): |
1473 | 1538 |
"""Run the KVM cmd and check for errors |
... | ... | |
1492 | 1557 |
if not self._InstancePidAlive(name)[2]: |
1493 | 1558 |
raise errors.HypervisorError("Failed to start instance %s" % name) |
1494 | 1559 |
|
1560 |
# 52/50 local variables |
|
1561 |
# pylint: disable=R0914 |
|
1495 | 1562 |
def _ExecuteKVMRuntime(self, instance, kvm_runtime, kvmhelp, incoming=None): |
1496 | 1563 |
"""Execute a KVM cmd, after completing it with some last minute data. |
1497 | 1564 |
|
... | ... | |
1515 | 1582 |
|
1516 | 1583 |
temp_files = [] |
1517 | 1584 |
|
1518 |
kvm_cmd, kvm_nics, up_hvp = kvm_runtime |
|
1585 |
kvm_cmd, kvm_nics, up_hvp, block_devices = kvm_runtime
|
|
1519 | 1586 |
# the first element of kvm_cmd is always the path to the kvm binary |
1520 | 1587 |
kvm_path = kvm_cmd[0] |
1521 | 1588 |
up_hvp = objects.FillDict(conf_hvp, up_hvp) |
... | ... | |
1619 | 1686 |
continue |
1620 | 1687 |
self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq]) |
1621 | 1688 |
|
1689 |
bdev_opts = self._GenerateKVMBlockDevicesOptions(instance, |
|
1690 |
block_devices, |
|
1691 |
kvmhelp) |
|
1692 |
kvm_cmd.extend(bdev_opts) |
|
1622 | 1693 |
# CPU affinity requires kvm to start paused, so we set this flag if the |
1623 | 1694 |
# instance is not already paused and if we are not going to accept a |
1624 | 1695 |
# migrating instance. In the latter case, pausing is not needed. |
Also available in: Unified diff