From ffa1c0dc146c9929b7baf7f2d3b18f9e0144fcbf Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Mon, 22 Sep 2008 11:32:16 +0000 Subject: [PATCH] Extend DRBD disks with minors attribute This patch converts the DRBD disks to contain also a minor (per each node) attribute. This minor is not yet used and is always initialized with None, so the patch does not have any real-world impact - except for automatically upgrading config files (it adds the minors as None, None). Reviewed-by: imsnah --- lib/bdev.py | 10 ++++++++-- lib/cmdlib.py | 42 ++++++++++++++++++++++++++++++------------ lib/config.py | 12 ++++++------ lib/objects.py | 15 +++++++++------ 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/lib/bdev.py b/lib/bdev.py index 7ba3470ea..c3f4a7c46 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -804,9 +804,15 @@ class DRBD8(BaseDRBD): if len(children) not in (0, 2): raise ValueError("Invalid configuration data %s" % str(children)) - if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 4: + if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 5: raise ValueError("Invalid configuration data %s" % str(unique_id)) - self._lhost, self._lport, self._rhost, self._rport = unique_id + (self._lhost, self._lport, + self._rhost, self._rport, + self._aminor) = unique_id + if (self._lhost is not None and self._lhost == self._rhost and + self._lport == self._rport): + raise ValueError("Invalid configuration data, same local/remote %s" % + (unique_id,)) self.Attach() @classmethod diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 3c8638745..224fc1666 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -30,6 +30,7 @@ import time import tempfile import re import platform +import logging from ganeti import rpc from ganeti import ssh @@ -2909,7 +2910,8 @@ def _GenerateUniqueNames(cfg, exts): return results -def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name): +def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name, + p_minor, s_minor): """Generate a drbd8 device complete with its children. """ @@ -2920,8 +2922,9 @@ def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name): dev_meta = objects.Disk(dev_type=constants.LD_LV, size=128, logical_id=(vgname, names[1])) drbd_dev = objects.Disk(dev_type=constants.LD_DRBD8, size=size, - logical_id = (primary, secondary, port), - children = [dev_data, dev_meta], + logical_id=(primary, secondary, port, + p_minor, s_minor), + children=[dev_data, dev_meta], iv_name=iv_name) return drbd_dev @@ -2954,12 +2957,17 @@ def _GenerateDiskTemplate(cfg, template_name, if len(secondary_nodes) != 1: raise errors.ProgrammerError("Wrong template configuration") remote_node = secondary_nodes[0] + (minor_pa, minor_pb, + minor_sa, minor_sb) = [None, None, None, None] + names = _GenerateUniqueNames(cfg, [".sda_data", ".sda_meta", ".sdb_data", ".sdb_meta"]) drbd_sda_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node, - disk_sz, names[0:2], "sda") + disk_sz, names[0:2], "sda", + minor_pa, minor_sa) drbd_sdb_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node, - swap_sz, names[2:4], "sdb") + swap_sz, names[2:4], "sdb", + minor_pb, minor_sb) disks = [drbd_sda_dev, drbd_sdb_dev] elif template_name == constants.DT_FILE: if len(secondary_nodes) != 0: @@ -4003,8 +4011,11 @@ class LUReplaceDisks(LogicalUnit): pri_node) # Step: create new storage + + minors = [None for dev in instance.disks] + logging.debug("Allocated minors %s" % (minors,)) self.proc.LogStep(3, steps_total, "allocate new storage") - for dev in instance.disks: + for idx, dev in enumerate(instance.disks): size = dev.size info("adding new local storage on %s for %s" % (new_node, dev.iv_name)) # since we *always* want to create this LV, we use the @@ -4017,16 +4028,22 @@ class LUReplaceDisks(LogicalUnit): " node '%s'" % (new_lv.logical_id[1], new_node)) - iv_names[dev.iv_name] = (dev, dev.children) + iv_names[dev.iv_name] = (dev, dev.children, minors[idx]) self.proc.LogStep(4, steps_total, "changing drbd configuration") for dev in instance.disks: size = dev.size info("activating a new drbd on %s for %s" % (new_node, dev.iv_name)) # create new devices on new_node + new_minor = iv_names[dev.iv_name][2] + if pri_node == dev.logical_id[0]: + new_logical_id = (pri_node, new_node, + dev.logical_id[2], dev.logical_id[3], new_minor) + else: + new_logical_id = (new_node, pri_node, + dev.logical_id[2], new_minor, dev.logical_id[4]) new_drbd = objects.Disk(dev_type=constants.LD_DRBD8, - logical_id=(pri_node, new_node, - dev.logical_id[2]), + logical_id=new_logical_id, children=dev.children) if not _CreateBlockDevOnSecondary(cfg, new_node, instance, new_drbd, False, @@ -4048,7 +4065,7 @@ class LUReplaceDisks(LogicalUnit): cfg.SetDiskID(dev, pri_node) # set the physical (unique in bdev terms) id to None, meaning # detach from network - dev.physical_id = (None,) * len(dev.physical_id) + dev.physical_id = (None, None, None, None, dev.physical_id[4]) # and 'find' the device, which will 'fix' it to match the # standalone state if rpc.call_blockdev_find(pri_node, dev): @@ -4078,6 +4095,7 @@ class LUReplaceDisks(LogicalUnit): # it will automatically activate the network, if the physical_id # is correct cfg.SetDiskID(dev, pri_node) + logging.debug("Disk to attach: %s", dev) if not rpc.call_blockdev_find(pri_node, dev): warning("can't attach drbd %s to new secondary!" % dev.iv_name, "please do a gnt-instance info to see the status of disks") @@ -4089,14 +4107,14 @@ class LUReplaceDisks(LogicalUnit): _WaitForSync(cfg, instance, self.proc, unlock=True) # so check manually all the devices - for name, (dev, old_lvs) in iv_names.iteritems(): + for name, (dev, old_lvs, _) in iv_names.iteritems(): cfg.SetDiskID(dev, pri_node) is_degr = rpc.call_blockdev_find(pri_node, dev)[5] if is_degr: raise errors.OpExecError("DRBD device %s is degraded!" % name) self.proc.LogStep(6, steps_total, "removing old storage") - for name, (dev, old_lvs) in iv_names.iteritems(): + for name, (dev, old_lvs, _) in iv_names.iteritems(): info("remove logical volumes for %s" % name) for lv in old_lvs: cfg.SetDiskID(lv, old_node) diff --git a/lib/config.py b/lib/config.py index efd24d4fe..87bf5572c 100644 --- a/lib/config.py +++ b/lib/config.py @@ -229,8 +229,8 @@ class ConfigWriter: if disk.logical_id is None and disk.physical_id is not None: return - if disk.dev_type in constants.LDS_DRBD: - pnode, snode, port = disk.logical_id + if disk.dev_type == constants.LD_DRBD8: + pnode, snode, port, pminor, sminor = disk.logical_id if node_name not in (pnode, snode): raise errors.ConfigurationError("DRBD device not knowing node %s" % node_name) @@ -239,12 +239,12 @@ class ConfigWriter: if pnode_info is None or snode_info is None: raise errors.ConfigurationError("Can't find primary or secondary node" " for %s" % str(disk)) + p_data = (pnode_info.secondary_ip, port) + s_data = (snode_info.secondary_ip, port) if pnode == node_name: - disk.physical_id = (pnode_info.secondary_ip, port, - snode_info.secondary_ip, port) + disk.physical_id = p_data + s_data + (pminor,) else: # it must be secondary, we tested above - disk.physical_id = (snode_info.secondary_ip, port, - pnode_info.secondary_ip, port) + disk.physical_id = s_data + p_data + (sminor,) else: disk.physical_id = disk.logical_id return diff --git a/lib/objects.py b/lib/objects.py index 5282e9fe8..a26907d83 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -412,7 +412,7 @@ class Disk(ConfigObject): if self.logical_id is None and self.physical_id is not None: return if self.dev_type in constants.LDS_DRBD: - pnode, snode, port = self.logical_id + pnode, snode, port, pminor, sminor = self.logical_id if target_node not in (pnode, snode): raise errors.ConfigurationError("DRBD device not knowing node %s" % target_node) @@ -421,12 +421,12 @@ class Disk(ConfigObject): if pnode_ip is None or snode_ip is None: raise errors.ConfigurationError("Can't find primary or secondary node" " for %s" % str(self)) + p_data = (pnode_ip, port) + s_data = (snode_ip, port) if pnode == target_node: - self.physical_id = (pnode_ip, port, - snode_ip, port) + self.physical_id = p_data + s_data + (pminor,) else: # it must be secondary, we tested above - self.physical_id = (snode_ip, port, - pnode_ip, port) + self.physical_id = s_data + p_data + (sminor,) else: self.physical_id = self.logical_id return @@ -458,6 +458,9 @@ class Disk(ConfigObject): obj.logical_id = tuple(obj.logical_id) if obj.physical_id and isinstance(obj.physical_id, list): obj.physical_id = tuple(obj.physical_id) + if obj.dev_type in constants.LDS_DRBD and len(obj.logical_id) == 3: + # old non-minor based disk type + obj.logical_id += (None, None) return obj def __str__(self): @@ -529,7 +532,7 @@ class Instance(TaggableObject): def _Helper(primary, sec_nodes, device): """Recursively computes secondary nodes given a top device.""" if device.dev_type in constants.LDS_DRBD: - nodea, nodeb, dummy = device.logical_id + nodea, nodeb, dummy = device.logical_id[:3] if nodea == primary: candidate = nodeb else: -- GitLab