constants.IDISK_NAME: name,
}
- if constants.IDISK_METAVG in disk:
- new_disk[constants.IDISK_METAVG] = disk[constants.IDISK_METAVG]
- if constants.IDISK_ADOPT in disk:
- new_disk[constants.IDISK_ADOPT] = disk[constants.IDISK_ADOPT]
+ for key in [
+ constants.IDISK_METAVG,
+ constants.IDISK_ADOPT,
+ constants.IDISK_SPINDLES,
+ ]:
+ if key in disk:
+ new_disk[key] = disk[key]
# For extstorage, demand the `provider' option and add any
# additional parameters (ext-params) to the dict
logical_id=logical_id_fn(idx, disk_index, disk),
iv_name="disk/%d" % disk_index,
mode=disk[constants.IDISK_MODE],
- params=params)
+ params=params,
+ spindles=disk.get(constants.IDISK_SPINDLES))
disk_dev.name = disk.get(constants.IDISK_NAME, None)
disk_dev.uuid = lu.cfg.GenerateUniqueID(lu.proc.GetECId())
disks.append(disk_dev)
return disks
+def CheckSpindlesExclusiveStorage(diskdict, es_flag):
+ """Check the presence of the spindle options with exclusive_storage.
+
+ @type diskdict: dict
+ @param diskdict: disk parameters
+ @type es_flag: bool
+ @param es_flag: the effective value of the exlusive_storage flag
+ @raise errors.OpPrereqError when spindles are given and they should not
+
+ """
+ if (not es_flag and constants.IDISK_SPINDLES in diskdict and
+ diskdict[constants.IDISK_SPINDLES] is not None):
+ raise errors.OpPrereqError("Spindles in instance disks cannot be specified"
+ " when exclusive storage is not active",
+ errors.ECODE_INVAL)
+
+
class LUInstanceRecreateDisks(LogicalUnit):
"""Recreate an instance's missing disks.
_MODIFYABLE = compat.UniqueFrozenset([
constants.IDISK_SIZE,
constants.IDISK_MODE,
+ constants.IDISK_SPINDLES,
])
# New or changed disk parameters may have different semantics
assert not self.glm.is_owned(locking.LEVEL_NODE_ALLOC)
+ if self.op.nodes:
+ nodes = self.op.nodes
+ else:
+ nodes = instance.all_nodes
+ excl_stor = compat.any(
+ rpc.GetExclusiveStorageForNodeNames(self.cfg, nodes).values()
+ )
+ for new_params in self.disks.values():
+ CheckSpindlesExclusiveStorage(new_params, excl_stor)
+
def Exec(self, feedback_fn):
"""Recreate the disks.
disk.logical_id = new_id
if changes:
disk.Update(size=changes.get(constants.IDISK_SIZE, None),
- mode=changes.get(constants.IDISK_MODE, None))
+ mode=changes.get(constants.IDISK_MODE, None),
+ spindles=changes.get(constants.IDISK_SPINDLES, None))
# change primary node, if needed
if self.op.nodes:
"""
es_flags = rpc.GetExclusiveStorageForNodeNames(lu.cfg, nodenames)
- nodeinfo = lu.rpc.call_node_info(nodenames, [vg], None, es_flags)
+ # FIXME: This maps everything to storage type 'lvm-vg' to maintain
+ # the current functionality. Refactor to make it more flexible.
+ nodeinfo = lu.rpc.call_node_info(nodenames, [(constants.ST_LVM_VG, vg)], None,
+ es_flags)
for node in nodenames:
info = nodeinfo[node]
info.Raise("Cannot get current information from node %s" % node,
else:
if not set(disks).issubset(instance.disks):
raise errors.ProgrammerError("Can only act on disks belonging to the"
- " target instance")
+ " target instance: expected a subset of %r,"
+ " got %r" % (instance.disks, disks))
return disks
if wipe_disks:
# Get disk size from primary node for wiping
- result = self.rpc.call_blockdev_getsize(instance.primary_node, [disk])
+ result = self.rpc.call_blockdev_getdimensions(instance.primary_node,
+ [disk])
result.Raise("Failed to retrieve disk size from node '%s'" %
instance.primary_node)
- (disk_size_in_bytes, ) = result.payload
+ (disk_dimensions, ) = result.payload
- if disk_size_in_bytes is None:
+ if disk_dimensions is None:
raise errors.OpExecError("Failed to retrieve disk size from primary"
" node '%s'" % instance.primary_node)
+ (disk_size_in_bytes, _) = disk_dimensions
old_disk_size = _DiskSizeInBytesToMebibytes(self, disk_size_in_bytes)
self.op.remote_node = ExpandNodeName(self.cfg, self.op.remote_node)
# Warning: do not remove the locking of the new secondary here
- # unless DRBD8.AddChildren is changed to work in parallel;
+ # unless DRBD8Dev.AddChildren is changed to work in parallel;
# currently it doesn't since parallel invocations of
# FindUnusedMinor will conflict
self.needed_locks[locking.LEVEL_NODE] = [self.op.remote_node]