Revision ffa1c0dc
b/lib/bdev.py | ||
---|---|---|
804 | 804 |
|
805 | 805 |
if len(children) not in (0, 2): |
806 | 806 |
raise ValueError("Invalid configuration data %s" % str(children)) |
807 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 4:
|
|
807 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 5:
|
|
808 | 808 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
809 |
self._lhost, self._lport, self._rhost, self._rport = unique_id |
|
809 |
(self._lhost, self._lport, |
|
810 |
self._rhost, self._rport, |
|
811 |
self._aminor) = unique_id |
|
812 |
if (self._lhost is not None and self._lhost == self._rhost and |
|
813 |
self._lport == self._rport): |
|
814 |
raise ValueError("Invalid configuration data, same local/remote %s" % |
|
815 |
(unique_id,)) |
|
810 | 816 |
self.Attach() |
811 | 817 |
|
812 | 818 |
@classmethod |
b/lib/cmdlib.py | ||
---|---|---|
30 | 30 |
import tempfile |
31 | 31 |
import re |
32 | 32 |
import platform |
33 |
import logging |
|
33 | 34 |
|
34 | 35 |
from ganeti import rpc |
35 | 36 |
from ganeti import ssh |
... | ... | |
2909 | 2910 |
return results |
2910 | 2911 |
|
2911 | 2912 |
|
2912 |
def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name): |
|
2913 |
def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name, |
|
2914 |
p_minor, s_minor): |
|
2913 | 2915 |
"""Generate a drbd8 device complete with its children. |
2914 | 2916 |
|
2915 | 2917 |
""" |
... | ... | |
2920 | 2922 |
dev_meta = objects.Disk(dev_type=constants.LD_LV, size=128, |
2921 | 2923 |
logical_id=(vgname, names[1])) |
2922 | 2924 |
drbd_dev = objects.Disk(dev_type=constants.LD_DRBD8, size=size, |
2923 |
logical_id = (primary, secondary, port), |
|
2924 |
children = [dev_data, dev_meta], |
|
2925 |
logical_id=(primary, secondary, port, |
|
2926 |
p_minor, s_minor), |
|
2927 |
children=[dev_data, dev_meta], |
|
2925 | 2928 |
iv_name=iv_name) |
2926 | 2929 |
return drbd_dev |
2927 | 2930 |
|
... | ... | |
2954 | 2957 |
if len(secondary_nodes) != 1: |
2955 | 2958 |
raise errors.ProgrammerError("Wrong template configuration") |
2956 | 2959 |
remote_node = secondary_nodes[0] |
2960 |
(minor_pa, minor_pb, |
|
2961 |
minor_sa, minor_sb) = [None, None, None, None] |
|
2962 |
|
|
2957 | 2963 |
names = _GenerateUniqueNames(cfg, [".sda_data", ".sda_meta", |
2958 | 2964 |
".sdb_data", ".sdb_meta"]) |
2959 | 2965 |
drbd_sda_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node, |
2960 |
disk_sz, names[0:2], "sda") |
|
2966 |
disk_sz, names[0:2], "sda", |
|
2967 |
minor_pa, minor_sa) |
|
2961 | 2968 |
drbd_sdb_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node, |
2962 |
swap_sz, names[2:4], "sdb") |
|
2969 |
swap_sz, names[2:4], "sdb", |
|
2970 |
minor_pb, minor_sb) |
|
2963 | 2971 |
disks = [drbd_sda_dev, drbd_sdb_dev] |
2964 | 2972 |
elif template_name == constants.DT_FILE: |
2965 | 2973 |
if len(secondary_nodes) != 0: |
... | ... | |
4003 | 4011 |
pri_node) |
4004 | 4012 |
|
4005 | 4013 |
# Step: create new storage |
4014 |
|
|
4015 |
minors = [None for dev in instance.disks] |
|
4016 |
logging.debug("Allocated minors %s" % (minors,)) |
|
4006 | 4017 |
self.proc.LogStep(3, steps_total, "allocate new storage") |
4007 |
for dev in instance.disks:
|
|
4018 |
for idx, dev in enumerate(instance.disks):
|
|
4008 | 4019 |
size = dev.size |
4009 | 4020 |
info("adding new local storage on %s for %s" % (new_node, dev.iv_name)) |
4010 | 4021 |
# since we *always* want to create this LV, we use the |
... | ... | |
4017 | 4028 |
" node '%s'" % |
4018 | 4029 |
(new_lv.logical_id[1], new_node)) |
4019 | 4030 |
|
4020 |
iv_names[dev.iv_name] = (dev, dev.children) |
|
4031 |
iv_names[dev.iv_name] = (dev, dev.children, minors[idx])
|
|
4021 | 4032 |
|
4022 | 4033 |
self.proc.LogStep(4, steps_total, "changing drbd configuration") |
4023 | 4034 |
for dev in instance.disks: |
4024 | 4035 |
size = dev.size |
4025 | 4036 |
info("activating a new drbd on %s for %s" % (new_node, dev.iv_name)) |
4026 | 4037 |
# create new devices on new_node |
4038 |
new_minor = iv_names[dev.iv_name][2] |
|
4039 |
if pri_node == dev.logical_id[0]: |
|
4040 |
new_logical_id = (pri_node, new_node, |
|
4041 |
dev.logical_id[2], dev.logical_id[3], new_minor) |
|
4042 |
else: |
|
4043 |
new_logical_id = (new_node, pri_node, |
|
4044 |
dev.logical_id[2], new_minor, dev.logical_id[4]) |
|
4027 | 4045 |
new_drbd = objects.Disk(dev_type=constants.LD_DRBD8, |
4028 |
logical_id=(pri_node, new_node, |
|
4029 |
dev.logical_id[2]), |
|
4046 |
logical_id=new_logical_id, |
|
4030 | 4047 |
children=dev.children) |
4031 | 4048 |
if not _CreateBlockDevOnSecondary(cfg, new_node, instance, |
4032 | 4049 |
new_drbd, False, |
... | ... | |
4048 | 4065 |
cfg.SetDiskID(dev, pri_node) |
4049 | 4066 |
# set the physical (unique in bdev terms) id to None, meaning |
4050 | 4067 |
# detach from network |
4051 |
dev.physical_id = (None,) * len(dev.physical_id)
|
|
4068 |
dev.physical_id = (None, None, None, None, dev.physical_id[4])
|
|
4052 | 4069 |
# and 'find' the device, which will 'fix' it to match the |
4053 | 4070 |
# standalone state |
4054 | 4071 |
if rpc.call_blockdev_find(pri_node, dev): |
... | ... | |
4078 | 4095 |
# it will automatically activate the network, if the physical_id |
4079 | 4096 |
# is correct |
4080 | 4097 |
cfg.SetDiskID(dev, pri_node) |
4098 |
logging.debug("Disk to attach: %s", dev) |
|
4081 | 4099 |
if not rpc.call_blockdev_find(pri_node, dev): |
4082 | 4100 |
warning("can't attach drbd %s to new secondary!" % dev.iv_name, |
4083 | 4101 |
"please do a gnt-instance info to see the status of disks") |
... | ... | |
4089 | 4107 |
_WaitForSync(cfg, instance, self.proc, unlock=True) |
4090 | 4108 |
|
4091 | 4109 |
# so check manually all the devices |
4092 |
for name, (dev, old_lvs) in iv_names.iteritems(): |
|
4110 |
for name, (dev, old_lvs, _) in iv_names.iteritems():
|
|
4093 | 4111 |
cfg.SetDiskID(dev, pri_node) |
4094 | 4112 |
is_degr = rpc.call_blockdev_find(pri_node, dev)[5] |
4095 | 4113 |
if is_degr: |
4096 | 4114 |
raise errors.OpExecError("DRBD device %s is degraded!" % name) |
4097 | 4115 |
|
4098 | 4116 |
self.proc.LogStep(6, steps_total, "removing old storage") |
4099 |
for name, (dev, old_lvs) in iv_names.iteritems(): |
|
4117 |
for name, (dev, old_lvs, _) in iv_names.iteritems():
|
|
4100 | 4118 |
info("remove logical volumes for %s" % name) |
4101 | 4119 |
for lv in old_lvs: |
4102 | 4120 |
cfg.SetDiskID(lv, old_node) |
b/lib/config.py | ||
---|---|---|
229 | 229 |
|
230 | 230 |
if disk.logical_id is None and disk.physical_id is not None: |
231 | 231 |
return |
232 |
if disk.dev_type in constants.LDS_DRBD:
|
|
233 |
pnode, snode, port = disk.logical_id |
|
232 |
if disk.dev_type == constants.LD_DRBD8:
|
|
233 |
pnode, snode, port, pminor, sminor = disk.logical_id
|
|
234 | 234 |
if node_name not in (pnode, snode): |
235 | 235 |
raise errors.ConfigurationError("DRBD device not knowing node %s" % |
236 | 236 |
node_name) |
... | ... | |
239 | 239 |
if pnode_info is None or snode_info is None: |
240 | 240 |
raise errors.ConfigurationError("Can't find primary or secondary node" |
241 | 241 |
" for %s" % str(disk)) |
242 |
p_data = (pnode_info.secondary_ip, port) |
|
243 |
s_data = (snode_info.secondary_ip, port) |
|
242 | 244 |
if pnode == node_name: |
243 |
disk.physical_id = (pnode_info.secondary_ip, port, |
|
244 |
snode_info.secondary_ip, port) |
|
245 |
disk.physical_id = p_data + s_data + (pminor,) |
|
245 | 246 |
else: # it must be secondary, we tested above |
246 |
disk.physical_id = (snode_info.secondary_ip, port, |
|
247 |
pnode_info.secondary_ip, port) |
|
247 |
disk.physical_id = s_data + p_data + (sminor,) |
|
248 | 248 |
else: |
249 | 249 |
disk.physical_id = disk.logical_id |
250 | 250 |
return |
b/lib/objects.py | ||
---|---|---|
412 | 412 |
if self.logical_id is None and self.physical_id is not None: |
413 | 413 |
return |
414 | 414 |
if self.dev_type in constants.LDS_DRBD: |
415 |
pnode, snode, port = self.logical_id |
|
415 |
pnode, snode, port, pminor, sminor = self.logical_id
|
|
416 | 416 |
if target_node not in (pnode, snode): |
417 | 417 |
raise errors.ConfigurationError("DRBD device not knowing node %s" % |
418 | 418 |
target_node) |
... | ... | |
421 | 421 |
if pnode_ip is None or snode_ip is None: |
422 | 422 |
raise errors.ConfigurationError("Can't find primary or secondary node" |
423 | 423 |
" for %s" % str(self)) |
424 |
p_data = (pnode_ip, port) |
|
425 |
s_data = (snode_ip, port) |
|
424 | 426 |
if pnode == target_node: |
425 |
self.physical_id = (pnode_ip, port, |
|
426 |
snode_ip, port) |
|
427 |
self.physical_id = p_data + s_data + (pminor,) |
|
427 | 428 |
else: # it must be secondary, we tested above |
428 |
self.physical_id = (snode_ip, port, |
|
429 |
pnode_ip, port) |
|
429 |
self.physical_id = s_data + p_data + (sminor,) |
|
430 | 430 |
else: |
431 | 431 |
self.physical_id = self.logical_id |
432 | 432 |
return |
... | ... | |
458 | 458 |
obj.logical_id = tuple(obj.logical_id) |
459 | 459 |
if obj.physical_id and isinstance(obj.physical_id, list): |
460 | 460 |
obj.physical_id = tuple(obj.physical_id) |
461 |
if obj.dev_type in constants.LDS_DRBD and len(obj.logical_id) == 3: |
|
462 |
# old non-minor based disk type |
|
463 |
obj.logical_id += (None, None) |
|
461 | 464 |
return obj |
462 | 465 |
|
463 | 466 |
def __str__(self): |
... | ... | |
529 | 532 |
def _Helper(primary, sec_nodes, device): |
530 | 533 |
"""Recursively computes secondary nodes given a top device.""" |
531 | 534 |
if device.dev_type in constants.LDS_DRBD: |
532 |
nodea, nodeb, dummy = device.logical_id |
|
535 |
nodea, nodeb, dummy = device.logical_id[:3]
|
|
533 | 536 |
if nodea == primary: |
534 | 537 |
candidate = nodeb |
535 | 538 |
else: |
Also available in: Unified diff