Commit b768099e authored by Iustin Pop's avatar Iustin Pop
Browse files

Fix bug in recreate-disks for DRBD instances

The new functionality in 2.4.2 for recreate-disks to change nodes is
broken for DRBD instances: it simply changes the nodes without caring
for the DRBD minors mapping, which will lead to conflicts in non-empty

This patch changes Exec() method of this LU significantly, to both fix
the DRBD minor usage and make sure that we don't have partial
modification to the instance objects:

- the first half of the method makes all the checks and computes the
  needed configuration changes
- the second half then performs the configuration changes and
  recreates the disks

This way, instances will either be fully modified or not at all;
whether the disks are successfully recreate is another point, but at
least we'll have the configuration sane.
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent 78ff9e8f
......@@ -5524,31 +5524,44 @@ class LUInstanceRecreateDisks(LogicalUnit):
"""Recreate the disks.
# change primary node, if needed
if self.op.nodes:
self.instance.primary_node = self.op.nodes[0]
self.LogWarning("Changing the instance's nodes, you will have to"
" remove any disks left on the older nodes manually")
instance = self.instance
to_skip = []
for idx, disk in enumerate(self.instance.disks):
mods = [] # keeps track of needed logical_id changes
for idx, disk in enumerate(instance.disks):
if idx not in self.op.disks: # disk idx has not been passed in
# update secondaries for disks, if needed
if self.op.nodes:
if disk.dev_type == constants.LD_DRBD8:
# need to update the nodes
# need to update the nodes and minors
assert len(self.op.nodes) == 2
logical_id = list(disk.logical_id)
logical_id[0] = self.op.nodes[0]
logical_id[1] = self.op.nodes[1]
disk.logical_id = tuple(logical_id)
assert len(disk.logical_id) == 6 # otherwise disk internals
# have changed
(_, _, old_port, _, _, old_secret) = disk.logical_id
new_minors = self.cfg.AllocateDRBDMinor(self.op.nodes,
new_id = (self.op.nodes[0], self.op.nodes[1], old_port,
new_minors[0], new_minors[1], old_secret)
assert len(disk.logical_id) == len(new_id)
mods.append((idx, new_id))
# now that we have passed all asserts above, we can apply the mods
# in a single run (to avoid partial changes)
for idx, new_id in mods:
instance.disks[idx].logical_id = new_id
# change primary node, if needed
if self.op.nodes:
instance.primary_node = self.op.nodes[0]
self.LogWarning("Changing the instance's nodes, you will have to"
" remove any disks left on the older nodes manually")
if self.op.nodes:
self.cfg.Update(self.instance, feedback_fn)
self.cfg.Update(instance, feedback_fn)
_CreateDisks(self, self.instance, to_skip=to_skip)
_CreateDisks(self, instance, to_skip=to_skip)
class LUInstanceRename(LogicalUnit):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment