Commit 0402302c authored by Iustin Pop's avatar Iustin Pop
Browse files

Allow disk object to set their own physical ID

Currently, the way to customize a DRBD disk from (node name 1, node name
2, port) to (ip1, port, ip2, port) is to use the ConfigWriter method
SetDiskID. However, since this needs a ConfigWriter object, it can be
run only on the master, and therefore disk object can't be passed to
more than one node unchanged. This, coupled with the rpc layer
limitation that all nodes in a multi-node call receive the same
arguments, prevent any kind of multi-node operation that has disks as an
argument.

This patch takes the SetDiskID method from ConfigWriter and ports it to
the disk object itself, and instead of the full node configuration it
uses a simple {node_name: replication_ip} mapping for all the nodes
involved in the disk tree (currently we only pass primary and secondary
node since we don't support nested drbd devices).

This allows us to send disks to both the primary and secondary nodes at
once and perform synchronized drbd activation on primary/secondary
nodes.

Note that while for the 1.2 branch this will not change old methods, it
is worth to investigate and possible replace all such calls on the
master to the nodes themselves for the 2.0 branch.

Reviewed-by: ultrotter
parent c7cdfc90
......@@ -390,6 +390,50 @@ class Disk(ConfigObject):
raise errors.ProgrammerError("Disk.RecordGrow called for unsupported"
" disk type %s" % self.dev_type)
def SetPhysicalID(self, target_node, nodes_ip):
"""Convert the logical ID to the physical ID.
This is used only for drbd, which needs ip/port configuration.
The routine descends down and updates its children also, because
this helps when the only the top device is passed to the remote
node.
Arguments:
- target_node: the node we wish to configure for
- nodes_ip: a mapping of node name to ip
The target_node must exist in in nodes_ip, and must be one of the
nodes in the logical ID for each of the DRBD devices encountered
in the disk tree.
"""
if self.children:
for child in self.children:
child.SetPhysicalID(target_node, nodes_ip)
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
if target_node not in (pnode, snode):
raise errors.ConfigurationError("DRBD device not knowing node %s" %
target_node)
pnode_ip = nodes_ip.get(pnode, None)
snode_ip = nodes_ip.get(snode, None)
if pnode_ip is None or snode_ip is None:
raise errors.ConfigurationError("Can't find primary or secondary node"
" for %s" % str(self))
if pnode == target_node:
self.physical_id = (pnode_ip, port,
snode_ip, port)
else: # it must be secondary, we tested above
self.physical_id = (snode_ip, port,
pnode_ip, port)
else:
self.physical_id = self.logical_id
return
def ToDict(self):
"""Disk-specific conversion to standard python types.
......
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