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

Implement block device renaming

This patch add code for renaming a device; more precisely, for changing
the unique_id of the device. This means:
  - logical volumes, rename the volume
  - drbd8, change the remote peer

This is needed for the being able to replace disks for drbd8.

Reviewed-by: imsnah
parent cc0451f3
......@@ -112,6 +112,14 @@ class ServerObject(pb.Avatar):
bdev = objects.Disk.FromDict(bdev_s)
return backend.RemoveBlockDevice(bdev)
def perspective_blockdev_rename(params):
"""Remove a block device.
devlist = [(objects.Disk.FromDict(ds), uid) for ds, uid in params]
return backend.RenameBlockDevices(devlist)
def perspective_blockdev_assemble(params):
"""Assemble a block device.
......@@ -1337,6 +1337,29 @@ def RemoveExport(export):
return True
def RenameBlockDevices(devlist):
"""Rename a list of block devices.
The devlist argument is a list of tuples (disk, new_logical,
new_physical). The return value will be a combined boolean result
(True only if all renames succeeded).
result = True
for disk, unique_id in devlist:
dev = _RecursiveFindBD(disk)
if dev is None:
result = False
except errors.BlockDeviceError, err:
logger.Error("Can't rename device '%s' to '%s': %s" %
(dev, unique_id, err))
result = False
return result
class HooksRunner(object):
"""Hook runner.
......@@ -172,6 +172,15 @@ class BlockDev(object):
raise NotImplementedError
def Rename(self, new_id):
"""Rename this device.
This may or may not make sense for a given device type.
raise NotImplementedError
def GetStatus(self):
"""Return the status of the device.
......@@ -368,6 +377,21 @@ class LogicalVolume(BlockDev):
return not result.failed
def Rename(self, new_id):
"""Rename this logical volume.
if not isinstance(new_id, (tuple, list)) or len(new_id) != 2:
raise errors.ProgrammerError("Invalid new logical id '%s'" % new_id)
new_vg, new_name = new_id
if new_vg != self._vg_name:
raise errors.ProgrammerError("Can't move a logical volume across"
" volume groups (from %s to to %s)" %
(self._vg_name, new_vg))
result = utils.RunCmd(["lvrename", new_vg, self._lv_name, new_name])
if result.failed:
raise errors.BlockDeviceError("Failed to rename the logical volume: %s" %
def Attach(self):
"""Attach to an existing LV.
......@@ -700,6 +724,13 @@ class MDRaid1(BlockDev):
#TODO: maybe zero superblock on child devices?
return self.Shutdown()
def Rename(self, new_id):
"""Rename a device.
This is not supported for md raid1 devices.
raise errors.ProgrammerError("Can't rename a md raid1 device")
def AddChildren(self, devices):
"""Add new member(s) to the md raid1.
......@@ -1056,6 +1087,14 @@ class BaseDRBD(BlockDev):
return False
return True
def Rename(self, new_id):
"""Rename a device.
This is not supported for drbd devices.
raise errors.ProgrammerError("Can't rename a drbd device")
class DRBDev(BaseDRBD):
"""DRBD block device.
......@@ -1562,6 +1601,7 @@ class DRBDev(BaseDRBD):
return self.Shutdown()
class DRBD8(BaseDRBD):
"""DRBD v8.x block device.
......@@ -2041,6 +2081,17 @@ class DRBD8(BaseDRBD):
return True
def _ShutdownNet(cls, minor):
"""Disconnect from the remote peer.
This fails if we don't have a local device.
result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "disconnect"])
logger.Error("Can't shutdown network: %s" % result.output)
return not result.failed
def _ShutdownAll(cls, minor):
"""Deactivate the device.
......@@ -2066,6 +2117,27 @@ class DRBD8(BaseDRBD):
self.dev_path = None
return True
def Rename(self, new_uid):
"""Re-connect this device to another peer.
if self.minor is None:
raise errors.BlockDeviceError("Device not attached during rename")
if self._rhost is not None:
# this means we did have a host when we attached, so we are connected
if not self._ShutdownNet(self.minor):
raise errors.BlockDeviceError("Can't disconnect from remote peer")
old_id = self.unique_id
old_id = None
self.unique_id = new_uid
if not self._AssembleNet(self.minor, self.unique_id, "C"):
logger.Error("Can't attach to new peer!")
if self.old_id is not None:
self._AssembleNet(self.minor, old_id, "C")
self.unique_id = old_id
raise errors.BlockDeviceError("Can't attach to new peer")
def Remove(self):
"""Stub remove for DRBD devices.
......@@ -514,6 +514,19 @@ def call_blockdev_remove(node, bdev):
return c.getresult().get(node, False)
def call_blockdev_rename(node, devlist):
"""Request rename of the given block devices.
This is a single-node call.
params = [(d.ToDict(), uid) for d, uid in devlist]
c = Client("blockdev_rename", params)
return c.getresult().get(node, False)
def call_blockdev_assemble(node, disk, on_primary):
"""Request assembling of a given block device.
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