Revision 58502c9e 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, u) for (d, l, u) 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, None)
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

  
133

  
134
def _AnalyzeSerializedRuntime(serialized_runtime):
135
  """Return runtime entries for a serialized runtime file
136

  
137
  @type serialized_runtime: string
138
  @param serialized_runtime: raw text data read from actual runtime file
139
  @return: (cmd, nics, hvparams, bdevs)
140
  @rtype: list
141

  
142
  """
143
  loaded_runtime = serializer.Load(serialized_runtime)
144
  if len(loaded_runtime) == 3:
145
    serialized_blockdevs = []
146
    kvm_cmd, serialized_nics, hvparams = loaded_runtime
147
  else:
148
    kvm_cmd, serialized_nics, hvparams, serialized_blockdevs = loaded_runtime
149

  
150
  kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
151
  block_devices = [(objects.Disk.FromDict(sdisk), link, uri)
152
                   for sdisk, link, uri in serialized_blockdevs]
153

  
154
  return (kvm_cmd, kvm_nics, hvparams, block_devices)
155

  
82 156

  
83 157
def _GetTunFeatures(fd, _ioctl=fcntl.ioctl):
84 158
  """Retrieves supported TUN features from file descriptor.
......
1418 1492
    if hvp[constants.HV_KVM_EXTRA]:
1419 1493
      kvm_cmd.extend(hvp[constants.HV_KVM_EXTRA].split(" "))
1420 1494

  
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
1495
    kvm_disks = []
1496
    for disk, dev_path in block_devices:
1497
      kvm_disks.append((disk, dev_path))
1498

  
1499
    kvm_nics = []
1500
    for nic in instance.nics:
1501
      kvm_nics.append(nic)
1502

  
1428 1503
    hvparams = hvp
1429 1504

  
1430
    return (kvm_cmd, kvm_nics, hvparams)
1505
    return (kvm_cmd, kvm_nics, hvparams, kvm_disks)
1431 1506

  
1432 1507
  def _WriteKVMRuntime(self, instance_name, data):
1433 1508
    """Write an instance's KVM runtime
......
1453 1528
    """Save an instance's KVM runtime
1454 1529

  
1455 1530
    """
1456
    kvm_cmd, kvm_nics, hvparams = kvm_runtime
1531
    kvm_cmd, kvm_nics, hvparams, block_devices = kvm_runtime
1532

  
1457 1533
    serialized_nics = [nic.ToDict() for nic in kvm_nics]
1458
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams))
1534
    serialized_blockdevs = [(blk.ToDict(), link, uri)
1535
                            for blk, link, uri in block_devices]
1536
    serialized_form = serializer.Dump((kvm_cmd, serialized_nics, hvparams,
1537
                                      serialized_blockdevs))
1538

  
1459 1539
    self._WriteKVMRuntime(instance.name, serialized_form)
1460 1540

  
1461 1541
  def _LoadKVMRuntime(self, instance, serialized_runtime=None):
......
1464 1544
    """
1465 1545
    if not serialized_runtime:
1466 1546
      serialized_runtime = self._ReadKVMRuntime(instance.name)
1467
    loaded_runtime = serializer.Load(serialized_runtime)
1468
    kvm_cmd, serialized_nics, hvparams = loaded_runtime
1469
    kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics]
1470
    return (kvm_cmd, kvm_nics, hvparams)
1547

  
1548
    return _AnalyzeSerializedRuntime(serialized_runtime)
1471 1549

  
1472 1550
  def _RunKVMCmd(self, name, kvm_cmd, tap_fds=None):
1473 1551
    """Run the KVM cmd and check for errors
......
1492 1570
    if not self._InstancePidAlive(name)[2]:
1493 1571
      raise errors.HypervisorError("Failed to start instance %s" % name)
1494 1572

  
1573
  # 52/50 local variables
1574
  # pylint: disable=R0914
1495 1575
  def _ExecuteKVMRuntime(self, instance, kvm_runtime, kvmhelp, incoming=None):
1496 1576
    """Execute a KVM cmd, after completing it with some last minute data.
1497 1577

  
......
1515 1595

  
1516 1596
    temp_files = []
1517 1597

  
1518
    kvm_cmd, kvm_nics, up_hvp = kvm_runtime
1598
    kvm_cmd, kvm_nics, up_hvp, block_devices = kvm_runtime
1519 1599
    # the first element of kvm_cmd is always the path to the kvm binary
1520 1600
    kvm_path = kvm_cmd[0]
1521 1601
    up_hvp = objects.FillDict(conf_hvp, up_hvp)
......
1619 1699
        continue
1620 1700
      self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
1621 1701

  
1702
    bdev_opts = self._GenerateKVMBlockDevicesOptions(instance,
1703
                                                     block_devices,
1704
                                                     kvmhelp)
1705
    kvm_cmd.extend(bdev_opts)
1622 1706
    # CPU affinity requires kvm to start paused, so we set this flag if the
1623 1707
    # instance is not already paused and if we are not going to accept a
1624 1708
    # migrating instance. In the latter case, pausing is not needed.

Also available in: Unified diff