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

Initial implementation of drbd8 template type

This is a partially working drbd8 template type. It does:
  - add/remove
  - startup/failover/shutdown

Not working is replace disks, which needs custom code for this template.

Reviewed-by: imsnah
parent f38478b2
......@@ -2086,6 +2086,7 @@ DEV_MAP = {
constants.LD_LV: LogicalVolume,
constants.LD_MD_R1: MDRaid1,
constants.LD_DRBD7: DRBDev,
constants.LD_DRBD8: DRBD8,
}
......
......@@ -2460,9 +2460,9 @@ class LUFailoverInstance(LogicalUnit):
raise errors.OpPrereqError("Instance '%s' not known" %
self.op.instance_name)
if instance.disk_template != constants.DT_REMOTE_RAID1:
if instance.disk_template not in constants.DTS_NET_MIRROR:
raise errors.OpPrereqError("Instance's disk layout is not"
" remote_raid1.")
" network mirrored, cannot failover.")
secondary_nodes = instance.secondary_nodes
if not secondary_nodes:
......@@ -2636,6 +2636,22 @@ def _GenerateMDDRBDBranch(cfg, primary, secondary, size, names):
return drbd_dev
def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name):
"""Generate a drbd8 device complete with its children.
"""
port = cfg.AllocatePort()
vgname = cfg.GetVGName()
dev_data = objects.Disk(dev_type=constants.LD_LV, size=size,
logical_id=(vgname, names[0]))
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],
iv_name=iv_name)
return drbd_dev
def _GenerateDiskTemplate(cfg, template_name,
instance_name, primary_node,
secondary_nodes, disk_sz, swap_sz):
......@@ -2696,6 +2712,17 @@ def _GenerateDiskTemplate(cfg, template_name,
md_sdb_dev = objects.Disk(dev_type=constants.LD_MD_R1, iv_name="sdb",
children = [drbd_sdb_dev], size=swap_sz)
disks = [md_sda_dev, md_sdb_dev]
elif template_name == constants.DT_DRBD8:
if len(secondary_nodes) != 1:
raise errors.ProgrammerError("Wrong template configuration")
remote_node = secondary_nodes[0]
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")
drbd_sdb_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node,
swap_sz, names[2:4], "sdb")
disks = [drbd_sda_dev, drbd_sdb_dev]
else:
raise errors.ProgrammerError("Invalid disk template '%s'" % template_name)
return disks
......@@ -2872,9 +2899,9 @@ class LUCreateInstance(LogicalUnit):
if self.op.disk_template not in constants.DISK_TEMPLATES:
raise errors.OpPrereqError("Invalid disk template name")
if self.op.disk_template == constants.DT_REMOTE_RAID1:
if self.op.disk_template in constants.DTS_NET_MIRROR:
if getattr(self.op, "snode", None) is None:
raise errors.OpPrereqError("The 'remote_raid1' disk template needs"
raise errors.OpPrereqError("The networked disk templates need"
" a mirror node")
snode_name = self.cfg.ExpandNodeName(self.op.snode)
......@@ -2897,6 +2924,7 @@ class LUCreateInstance(LogicalUnit):
constants.DT_LOCAL_RAID1: (self.op.disk_size + self.op.swap_size) * 2,
# 256 MB are added for drbd metadata, 128MB for each drbd device
constants.DT_REMOTE_RAID1: self.op.disk_size + self.op.swap_size + 256,
constants.DT_DRBD8: self.op.disk_size + self.op.swap_size + 256,
}
if self.op.disk_template not in req_size_dict:
......@@ -3006,7 +3034,7 @@ class LUCreateInstance(LogicalUnit):
if self.op.wait_for_sync:
disk_abort = not _WaitForSync(self.cfg, iobj)
elif iobj.disk_template == constants.DT_REMOTE_RAID1:
elif iobj.disk_template in constants.DTS_NET_MIRROR:
# make sure the disks are not degraded (still sync-ing is ok)
time.sleep(15)
feedback_fn("* checking mirrors status")
......@@ -3486,7 +3514,7 @@ class LUQueryInstanceData(NoHooksLU):
"""
self.cfg.SetDiskID(dev, instance.primary_node)
dev_pstatus = rpc.call_blockdev_find(instance.primary_node, dev)
if dev.dev_type == constants.LD_DRBD7:
if dev.dev_type in constants.LDS_DRBD:
# we change the snode then (otherwise we use the one passed in)
if dev.logical_id[0] == instance.primary_node:
snode = dev.logical_id[1]
......
......@@ -198,7 +198,7 @@ class ConfigWriter:
if disk.logical_id is None and disk.physical_id is not None:
return
if disk.dev_type == constants.LD_DRBD7:
if disk.dev_type in constants.LDS_DRBD:
pnode, snode, port = disk.logical_id
if node_name not in (pnode, snode):
raise errors.ConfigurationError("DRBD device not knowing node %s" %
......
......@@ -78,18 +78,27 @@ DT_DISKLESS = "diskless"
DT_PLAIN = "plain"
DT_LOCAL_RAID1 = "local_raid1"
DT_REMOTE_RAID1 = "remote_raid1"
DT_DRBD8 = "drbd"
# the set of network-mirrored disk templates
DTS_NET_MIRROR = frozenset([DT_REMOTE_RAID1, DT_DRBD8])
# logical disk types
LD_LV = "lvm"
LD_MD_R1 = "md_raid1"
LD_DRBD7 = "drbd"
LD_DRBD8 = "drbd8"
# the set of drbd-like disk types
LDS_DRBD = frozenset([LD_DRBD7, LD_DRBD8])
# instance creation modem
INSTANCE_CREATE = "create"
INSTANCE_IMPORT = "import"
DISK_TEMPLATES = frozenset([DT_DISKLESS, DT_PLAIN,
DT_LOCAL_RAID1, DT_REMOTE_RAID1])
DT_LOCAL_RAID1, DT_REMOTE_RAID1,
DT_DRBD8])
# import/export config options
INISECT_EXP = "export"
......
......@@ -314,11 +314,13 @@ class Disk(ConfigObject):
def CreateOnSecondary(self):
"""Test if this device needs to be created on a secondary node."""
return self.dev_type in (constants.LD_DRBD7, constants.LD_LV)
return self.dev_type in (constants.LD_DRBD7, constants.LD_DRBD8,
constants.LD_LV)
def AssembleOnSecondary(self):
"""Test if this device needs to be assembled on a secondary node."""
return self.dev_type in (constants.LD_DRBD7, constants.LD_LV)
return self.dev_type in (constants.LD_DRBD7, constants.LD_DRBD8,
constants.LD_LV)
def OpenOnSecondary(self):
"""Test if this device needs to be opened on a secondary node."""
......@@ -335,7 +337,7 @@ class Disk(ConfigObject):
"""
if self.dev_type == constants.LD_LV or self.dev_type == constants.LD_MD_R1:
result = [node]
elif self.dev_type == constants.LD_DRBD7:
elif self.dev_type in constants.LDS_DRBD:
result = [self.logical_id[0], self.logical_id[1]]
if node not in result:
raise errors.ConfigurationError("DRBD device passed unknown node")
......@@ -436,7 +438,7 @@ class Instance(TaggableObject):
"""
def _Helper(primary, sec_nodes, device):
"""Recursively computes secondary nodes given a top device."""
if device.dev_type == constants.LD_DRBD7:
if device.dev_type in constants.LDS_DRBD:
nodea, nodeb, dummy = device.logical_id
if nodea == primary:
candidate = nodeb
......@@ -488,7 +490,7 @@ class Instance(TaggableObject):
if dev.dev_type == constants.LD_LV:
lvmap[node].append(dev.logical_id[1])
elif dev.dev_type == constants.LD_DRBD7:
elif dev.dev_type in constants.LDS_DRBD:
if dev.logical_id[0] not in lvmap:
lvmap[dev.logical_id[0]] = []
......
......@@ -503,7 +503,7 @@ def _FormatBlockDevInfo(buf, dev, indent_level):
else:
(path, major, minor, syncp, estt, degr) = status
buf.write("%s (%d:%d)" % (path, major, minor))
if dtype in (constants.LD_MD_R1, constants.LD_DRBD7):
if dtype in (constants.LD_MD_R1, constants.LD_DRBD7, constants.LD_DRBD8):
if syncp is not None:
sync_text = "*RECOVERING* %5.2f%%," % syncp
if estt:
......@@ -661,8 +661,8 @@ add_opts = [
make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs",
default=1, type="int", metavar="<PROC>"),
make_option("-t", "--disk-template", dest="disk_template",
help="Custom disk setup (diskless, plain, local_raid1 or"
" remote_raid1)", default=None, metavar="TEMPL"),
help="Custom disk setup (diskless, plain, local_raid1,"
" remote_raid1 or drbd)", default=None, metavar="TEMPL"),
make_option("-i", "--ip", dest="ip",
help="IP address ('none' [default], 'auto', or specify address)",
default='none', type="string", metavar="<ADDRESS>"),
......
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