Revision 0c3d9c7c
b/lib/backend.py | ||
---|---|---|
3634 | 3634 |
|
3635 | 3635 |
assert isinstance(disk_index, (int, long)) |
3636 | 3636 |
|
3637 |
real_disk = _OpenRealBD(disk) |
|
3638 |
|
|
3639 | 3637 |
inst_os = OSFromDisk(instance.os) |
3640 | 3638 |
env = OSEnvironment(instance, inst_os) |
3641 | 3639 |
|
... | ... | |
3645 | 3643 |
script = inst_os.import_script |
3646 | 3644 |
|
3647 | 3645 |
elif mode == constants.IEM_EXPORT: |
3646 |
real_disk = _OpenRealBD(disk) |
|
3648 | 3647 |
env["EXPORT_DEVICE"] = real_disk.dev_path |
3649 | 3648 |
env["EXPORT_INDEX"] = str(disk_index) |
3650 | 3649 |
script = inst_os.export_script |
... | ... | |
3872 | 3871 |
shutil.rmtree(status_dir, ignore_errors=True) |
3873 | 3872 |
|
3874 | 3873 |
|
3875 |
def _SetPhysicalId(target_node_uuid, nodes_ip, disks): |
|
3876 |
"""Sets the correct physical ID on all passed disks. |
|
3877 |
|
|
3878 |
""" |
|
3879 |
for cf in disks: |
|
3880 |
cf.SetPhysicalID(target_node_uuid, nodes_ip) |
|
3874 |
def _FindDisks(disks): |
|
3875 |
"""Finds attached L{BlockDev}s for the given disks. |
|
3881 | 3876 |
|
3877 |
@type disks: list of L{objects.Disk} |
|
3878 |
@param disks: the disk objects we need to find |
|
3882 | 3879 |
|
3883 |
def _FindDisks(target_node_uuid, nodes_ip, disks):
|
|
3884 |
"""Sets the physical ID on disks and returns the block devices.
|
|
3880 |
@return: list of L{BlockDev} objects or C{None} if a given disk
|
|
3881 |
was not found or was no attached.
|
|
3885 | 3882 |
|
3886 | 3883 |
""" |
3887 |
_SetPhysicalId(target_node_uuid, nodes_ip, disks) |
|
3888 |
|
|
3889 | 3884 |
bdevs = [] |
3890 | 3885 |
|
3891 |
for cf in disks:
|
|
3892 |
rd = _RecursiveFindBD(cf)
|
|
3886 |
for disk in disks:
|
|
3887 |
rd = _RecursiveFindBD(disk)
|
|
3893 | 3888 |
if rd is None: |
3894 |
_Fail("Can't find device %s", cf)
|
|
3889 |
_Fail("Can't find device %s", disk)
|
|
3895 | 3890 |
bdevs.append(rd) |
3896 | 3891 |
return bdevs |
3897 | 3892 |
|
3898 | 3893 |
|
3899 |
def DrbdDisconnectNet(target_node_uuid, nodes_ip, disks):
|
|
3894 |
def DrbdDisconnectNet(disks): |
|
3900 | 3895 |
"""Disconnects the network on a list of drbd devices. |
3901 | 3896 |
|
3902 | 3897 |
""" |
3903 |
bdevs = _FindDisks(target_node_uuid, nodes_ip, disks)
|
|
3898 |
bdevs = _FindDisks(disks) |
|
3904 | 3899 |
|
3905 | 3900 |
# disconnect disks |
3906 | 3901 |
for rd in bdevs: |
... | ... | |
3911 | 3906 |
err, exc=True) |
3912 | 3907 |
|
3913 | 3908 |
|
3914 |
def DrbdAttachNet(target_node_uuid, nodes_ip, disks, instance_name, |
|
3915 |
multimaster): |
|
3909 |
def DrbdAttachNet(disks, instance_name, multimaster): |
|
3916 | 3910 |
"""Attaches the network on a list of drbd devices. |
3917 | 3911 |
|
3918 | 3912 |
""" |
3919 |
bdevs = _FindDisks(target_node_uuid, nodes_ip, disks)
|
|
3913 |
bdevs = _FindDisks(disks) |
|
3920 | 3914 |
|
3921 | 3915 |
if multimaster: |
3922 | 3916 |
for idx, rd in enumerate(bdevs): |
... | ... | |
3974 | 3968 |
_Fail("Can't change to primary mode: %s", err) |
3975 | 3969 |
|
3976 | 3970 |
|
3977 |
def DrbdWaitSync(target_node_uuid, nodes_ip, disks):
|
|
3971 |
def DrbdWaitSync(disks): |
|
3978 | 3972 |
"""Wait until DRBDs have synchronized. |
3979 | 3973 |
|
3980 | 3974 |
""" |
... | ... | |
3984 | 3978 |
raise utils.RetryAgain() |
3985 | 3979 |
return stats |
3986 | 3980 |
|
3987 |
bdevs = _FindDisks(target_node_uuid, nodes_ip, disks)
|
|
3981 |
bdevs = _FindDisks(disks) |
|
3988 | 3982 |
|
3989 | 3983 |
min_resync = 100 |
3990 | 3984 |
alldone = True |
... | ... | |
4004 | 3998 |
return (alldone, min_resync) |
4005 | 3999 |
|
4006 | 4000 |
|
4007 |
def DrbdNeedsActivation(target_node_uuid, nodes_ip, disks):
|
|
4001 |
def DrbdNeedsActivation(disks): |
|
4008 | 4002 |
"""Checks which of the passed disks needs activation and returns their UUIDs. |
4009 | 4003 |
|
4010 | 4004 |
""" |
4011 |
_SetPhysicalId(target_node_uuid, nodes_ip, disks) |
|
4012 | 4005 |
faulty_disks = [] |
4013 | 4006 |
|
4014 | 4007 |
for disk in disks: |
b/lib/cmdlib/cluster.py | ||
---|---|---|
533 | 533 |
|
534 | 534 |
changed = [] |
535 | 535 |
for node_uuid, dskl in per_node_disks.items(): |
536 |
newl = [v[2].Copy() for v in dskl] |
|
537 |
for dsk in newl: |
|
536 |
if not dskl: |
|
537 |
# no disks on the node |
|
538 |
continue |
|
539 |
|
|
540 |
newl = [(v[2].Copy(), v[0]) for v in dskl] |
|
541 |
for (dsk, _) in newl: |
|
538 | 542 |
self.cfg.SetDiskID(dsk, node_uuid) |
539 | 543 |
node_name = self.cfg.GetNodeName(node_uuid) |
540 | 544 |
result = self.rpc.call_blockdev_getdimensions(node_uuid, newl) |
... | ... | |
2667 | 2671 |
|
2668 | 2672 |
""" |
2669 | 2673 |
node_disks = {} |
2670 |
node_disks_devonly = {} |
|
2674 |
node_disks_dev_inst_only = {}
|
|
2671 | 2675 |
diskless_instances = set() |
2672 | 2676 |
diskless = constants.DT_DISKLESS |
2673 | 2677 |
|
... | ... | |
2687 | 2691 |
node_disks[nuuid] = disks |
2688 | 2692 |
|
2689 | 2693 |
# _AnnotateDiskParams makes already copies of the disks |
2690 |
devonly = [] |
|
2694 |
dev_inst_only = []
|
|
2691 | 2695 |
for (inst_uuid, dev) in disks: |
2692 | 2696 |
(anno_disk,) = AnnotateDiskParams(instanceinfo[inst_uuid], [dev], |
2693 | 2697 |
self.cfg) |
2694 | 2698 |
self.cfg.SetDiskID(anno_disk, nuuid) |
2695 |
devonly.append(anno_disk)
|
|
2699 |
dev_inst_only.append((anno_disk, instanceinfo[inst_uuid]))
|
|
2696 | 2700 |
|
2697 |
node_disks_devonly[nuuid] = devonly
|
|
2701 |
node_disks_dev_inst_only[nuuid] = dev_inst_only
|
|
2698 | 2702 |
|
2699 |
assert len(node_disks) == len(node_disks_devonly) |
|
2703 |
assert len(node_disks) == len(node_disks_dev_inst_only)
|
|
2700 | 2704 |
|
2701 | 2705 |
# Collect data from all nodes with disks |
2702 |
result = self.rpc.call_blockdev_getmirrorstatus_multi(node_disks.keys(),
|
|
2703 |
node_disks_devonly)
|
|
2706 |
result = self.rpc.call_blockdev_getmirrorstatus_multi( |
|
2707 |
node_disks.keys(), node_disks_dev_inst_only)
|
|
2704 | 2708 |
|
2705 | 2709 |
assert len(result) == len(node_disks) |
2706 | 2710 |
|
b/lib/cmdlib/common.py | ||
---|---|---|
720 | 720 |
@see L{rpc.AnnotateDiskParams} |
721 | 721 |
|
722 | 722 |
""" |
723 |
return rpc.AnnotateDiskParams(instance.disk_template, devs, |
|
724 |
cfg.GetInstanceDiskParams(instance)) |
|
723 |
return rpc.AnnotateDiskParams(devs, cfg.GetInstanceDiskParams(instance)) |
|
725 | 724 |
|
726 | 725 |
|
727 | 726 |
def SupportsOob(cfg, node): |
b/lib/cmdlib/group.py | ||
---|---|---|
968 | 968 |
inst.secondary_nodes): |
969 | 969 |
node_to_inst.setdefault(node_uuid, []).append(inst) |
970 | 970 |
|
971 |
nodes_ip = dict((uuid, node.secondary_ip) for (uuid, node) |
|
972 |
in self.cfg.GetMultiNodeInfo(node_to_inst.keys())) |
|
973 | 971 |
for (node_uuid, insts) in node_to_inst.items(): |
974 | 972 |
node_disks = [(inst.disks, inst) for inst in insts] |
975 |
node_res = self.rpc.call_drbd_needs_activation(node_uuid, nodes_ip, |
|
976 |
node_disks) |
|
973 |
node_res = self.rpc.call_drbd_needs_activation(node_uuid, node_disks) |
|
977 | 974 |
msg = node_res.fail_msg |
978 | 975 |
if msg: |
979 | 976 |
logging.warning("Error getting DRBD status on node %s: %s", |
b/lib/cmdlib/instance.py | ||
---|---|---|
1389 | 1389 |
dt = masterd.instance.DiskTransfer("disk/%s" % idx, |
1390 | 1390 |
constants.IEIO_FILE, (image, ), |
1391 | 1391 |
constants.IEIO_SCRIPT, |
1392 |
(iobj.disks[idx], idx),
|
|
1392 |
((iobj.disks[idx], iobj), idx),
|
|
1393 | 1393 |
None) |
1394 | 1394 |
transfers.append(dt) |
1395 | 1395 |
|
... | ... | |
1574 | 1574 |
for (idx, disk) in enumerate(renamed_inst.disks): |
1575 | 1575 |
for node_uuid in renamed_inst.all_nodes: |
1576 | 1576 |
self.cfg.SetDiskID(disk, node_uuid) |
1577 |
result = self.rpc.call_blockdev_setinfo(node_uuid, disk, info) |
|
1577 |
result = self.rpc.call_blockdev_setinfo(node_uuid, |
|
1578 |
(disk, renamed_inst), info) |
|
1578 | 1579 |
result.Warn("Error setting info on node %s for disk %s" % |
1579 | 1580 |
(self.cfg.GetNodeName(node_uuid), idx), self.LogWarning) |
1580 | 1581 |
try: |
... | ... | |
3098 | 3099 |
self.instance.uuid, pnode_uuid, |
3099 | 3100 |
[snode_uuid], disk_info, None, None, 0, |
3100 | 3101 |
feedback_fn, self.diskparams) |
3101 |
anno_disks = rpc.AnnotateDiskParams(constants.DT_DRBD8, new_disks, |
|
3102 |
self.diskparams) |
|
3102 |
anno_disks = rpc.AnnotateDiskParams(new_disks, self.diskparams) |
|
3103 | 3103 |
p_excl_stor = IsExclusiveStorageEnabledNodeUuid(self.cfg, pnode_uuid) |
3104 | 3104 |
s_excl_stor = IsExclusiveStorageEnabledNodeUuid(self.cfg, snode_uuid) |
3105 | 3105 |
info = GetInstanceInfoText(self.instance) |
... | ... | |
3195 | 3195 |
feedback_fn("Removing volumes on the secondary node...") |
3196 | 3196 |
for disk in old_disks: |
3197 | 3197 |
self.cfg.SetDiskID(disk, snode_uuid) |
3198 |
result = self.rpc.call_blockdev_remove(snode_uuid, disk)
|
|
3198 |
result = self.rpc.call_blockdev_remove(snode_uuid, (disk, self.instance))
|
|
3199 | 3199 |
result.Warn("Could not remove block device %s on node %s," |
3200 | 3200 |
" continuing anyway" % |
3201 | 3201 |
(disk.iv_name, self.cfg.GetNodeName(snode_uuid)), |
... | ... | |
3205 | 3205 |
for idx, disk in enumerate(old_disks): |
3206 | 3206 |
meta = disk.children[1] |
3207 | 3207 |
self.cfg.SetDiskID(meta, pnode_uuid) |
3208 |
result = self.rpc.call_blockdev_remove(pnode_uuid, meta)
|
|
3208 |
result = self.rpc.call_blockdev_remove(pnode_uuid, (meta, self.instance))
|
|
3209 | 3209 |
result.Warn("Could not remove metadata for disk %d on node %s," |
3210 | 3210 |
" continuing anyway" % |
3211 | 3211 |
(idx, self.cfg.GetNodeName(pnode_uuid)), |
... | ... | |
3265 | 3265 |
for node_uuid, disk in anno_disk.ComputeNodeTree( |
3266 | 3266 |
self.instance.primary_node): |
3267 | 3267 |
self.cfg.SetDiskID(disk, node_uuid) |
3268 |
msg = self.rpc.call_blockdev_remove(node_uuid, disk).fail_msg |
|
3268 |
msg = self.rpc.call_blockdev_remove(node_uuid, (disk, self.instance)) \ |
|
3269 |
.fail_msg |
|
3269 | 3270 |
if msg: |
3270 | 3271 |
self.LogWarning("Could not remove disk/%d on node '%s': %s," |
3271 | 3272 |
" continuing anyway", idx, |
b/lib/cmdlib/instance_migration.py | ||
---|---|---|
480 | 480 |
while not all_done: |
481 | 481 |
all_done = True |
482 | 482 |
result = self.rpc.call_drbd_wait_sync(self.all_node_uuids, |
483 |
self.nodes_ip, |
|
484 | 483 |
(self.instance.disks, |
485 | 484 |
self.instance)) |
486 | 485 |
min_percent = 100 |
... | ... | |
507 | 506 |
self.cfg.SetDiskID(dev, node_uuid) |
508 | 507 |
|
509 | 508 |
result = self.rpc.call_blockdev_close(node_uuid, self.instance.name, |
510 |
self.instance.disks)
|
|
509 |
(self.instance.disks, self.instance))
|
|
511 | 510 |
result.Raise("Cannot change disk to secondary on node %s" % |
512 | 511 |
self.cfg.GetNodeName(node_uuid)) |
513 | 512 |
|
... | ... | |
516 | 515 |
|
517 | 516 |
""" |
518 | 517 |
self.feedback_fn("* changing into standalone mode") |
519 |
result = self.rpc.call_drbd_disconnect_net(self.all_node_uuids, |
|
520 |
self.nodes_ip, |
|
521 |
self.instance.disks) |
|
518 |
result = self.rpc.call_drbd_disconnect_net( |
|
519 |
self.all_node_uuids, (self.instance.disks, self.instance)) |
|
522 | 520 |
for node_uuid, nres in result.items(): |
523 | 521 |
nres.Raise("Cannot disconnect disks node %s" % |
524 | 522 |
self.cfg.GetNodeName(node_uuid)) |
... | ... | |
532 | 530 |
else: |
533 | 531 |
msg = "single-master" |
534 | 532 |
self.feedback_fn("* changing disks into %s mode" % msg) |
535 |
result = self.rpc.call_drbd_attach_net(self.all_node_uuids, self.nodes_ip,
|
|
533 |
result = self.rpc.call_drbd_attach_net(self.all_node_uuids, |
|
536 | 534 |
(self.instance.disks, self.instance), |
537 | 535 |
self.instance.name, multimaster) |
538 | 536 |
for node_uuid, nres in result.items(): |
b/lib/cmdlib/instance_query.py | ||
---|---|---|
309 | 309 |
return None |
310 | 310 |
|
311 | 311 |
self.cfg.SetDiskID(dev, node_uuid) |
312 |
|
|
313 |
result = self.rpc.call_blockdev_find(node_uuid, dev) |
|
312 |
result = self.rpc.call_blockdev_find(node_uuid, (dev, instance)) |
|
314 | 313 |
if result.offline: |
315 | 314 |
return None |
316 | 315 |
|
b/lib/cmdlib/instance_storage.py | ||
---|---|---|
80 | 80 |
|
81 | 81 |
""" |
82 | 82 |
lu.cfg.SetDiskID(device, node_uuid) |
83 |
result = lu.rpc.call_blockdev_create(node_uuid, device, device.size,
|
|
84 |
instance.name, force_open, info,
|
|
85 |
excl_stor) |
|
83 |
result = lu.rpc.call_blockdev_create(node_uuid, (device, instance),
|
|
84 |
device.size, instance.name, force_open,
|
|
85 |
info, excl_stor)
|
|
86 | 86 |
result.Raise("Can't create block device %s on" |
87 | 87 |
" node %s for instance %s" % (device, |
88 | 88 |
lu.cfg.GetNodeName(node_uuid), |
... | ... | |
184 | 184 |
force_open, excl_stor) |
185 | 185 |
|
186 | 186 |
|
187 |
def _UndoCreateDisks(lu, disks_created): |
|
187 |
def _UndoCreateDisks(lu, disks_created, instance):
|
|
188 | 188 |
"""Undo the work performed by L{CreateDisks}. |
189 | 189 |
|
190 | 190 |
This function is called in case of an error to undo the work of |
... | ... | |
193 | 193 |
@type lu: L{LogicalUnit} |
194 | 194 |
@param lu: the logical unit on whose behalf we execute |
195 | 195 |
@param disks_created: the result returned by L{CreateDisks} |
196 |
@type instance: L{objects.Instance} |
|
197 |
@param instance: the instance for which disks were created |
|
196 | 198 |
|
197 | 199 |
""" |
198 | 200 |
for (node_uuid, disk) in disks_created: |
199 | 201 |
lu.cfg.SetDiskID(disk, node_uuid) |
200 |
result = lu.rpc.call_blockdev_remove(node_uuid, disk)
|
|
202 |
result = lu.rpc.call_blockdev_remove(node_uuid, (disk, instance))
|
|
201 | 203 |
result.Warn("Failed to remove newly-created disk %s on node %s" % |
202 | 204 |
(disk, lu.cfg.GetNodeName(node_uuid)), logging.warning) |
203 | 205 |
|
... | ... | |
259 | 261 |
logging.warning("Creating disk %s for instance '%s' failed", |
260 | 262 |
idx, instance.name) |
261 | 263 |
disks_created.extend(e.created_devices) |
262 |
_UndoCreateDisks(lu, disks_created) |
|
264 |
_UndoCreateDisks(lu, disks_created, instance)
|
|
263 | 265 |
raise errors.OpExecError(e.message) |
264 | 266 |
return disks_created |
265 | 267 |
|
... | ... | |
1110 | 1112 |
except errors.OpExecError: |
1111 | 1113 |
logging.warning("Wiping disks for instance '%s' failed", |
1112 | 1114 |
instance.name) |
1113 |
_UndoCreateDisks(lu, cleanup) |
|
1115 |
_UndoCreateDisks(lu, cleanup, instance)
|
|
1114 | 1116 |
raise |
1115 | 1117 |
|
1116 | 1118 |
|
... | ... | |
1490 | 1492 |
if wipe_disks: |
1491 | 1493 |
# Get disk size from primary node for wiping |
1492 | 1494 |
self.cfg.SetDiskID(self.disk, self.instance.primary_node) |
1493 |
result = self.rpc.call_blockdev_getdimensions(self.instance.primary_node,
|
|
1494 |
[self.disk])
|
|
1495 |
result = self.rpc.call_blockdev_getdimensions( |
|
1496 |
self.instance.primary_node, ([self.disk], self.instance))
|
|
1495 | 1497 |
result.Raise("Failed to retrieve disk size from node '%s'" % |
1496 | 1498 |
self.instance.primary_node) |
1497 | 1499 |
|
... | ... | |
1801 | 1803 |
result = True |
1802 | 1804 |
|
1803 | 1805 |
if on_primary or dev.AssembleOnSecondary(): |
1804 |
rstats = lu.rpc.call_blockdev_find(node_uuid, dev)
|
|
1806 |
rstats = lu.rpc.call_blockdev_find(node_uuid, (dev, instance))
|
|
1805 | 1807 |
msg = rstats.fail_msg |
1806 | 1808 |
if msg: |
1807 | 1809 |
lu.LogWarning("Can't find disk on node %s: %s", |
... | ... | |
1844 | 1846 |
|
1845 | 1847 |
""" |
1846 | 1848 |
(disk,) = AnnotateDiskParams(instance, [dev], lu.cfg) |
1847 |
return lu.rpc.call_blockdev_find(node_uuid, disk)
|
|
1849 |
return lu.rpc.call_blockdev_find(node_uuid, (disk, instance))
|
|
1848 | 1850 |
|
1849 | 1851 |
|
1850 | 1852 |
def _GenerateUniqueNames(lu, exts): |
... | ... | |
2298 | 2300 |
|
2299 | 2301 |
for lv in old_lvs: |
2300 | 2302 |
self.cfg.SetDiskID(lv, node_uuid) |
2301 |
|
|
2302 |
msg = self.rpc.call_blockdev_remove(node_uuid, lv).fail_msg
|
|
2303 |
msg = self.rpc.call_blockdev_remove(node_uuid, (lv, self.instance)) \ |
|
2304 |
.fail_msg
|
|
2303 | 2305 |
if msg: |
2304 | 2306 |
self.lu.LogWarning("Can't remove old LV: %s", msg, |
2305 | 2307 |
hint="remove unused LVs manually") |
... | ... | |
2348 | 2350 |
for dev, old_lvs, new_lvs in iv_names.itervalues(): |
2349 | 2351 |
self.lu.LogInfo("Detaching %s drbd from local storage", dev.iv_name) |
2350 | 2352 |
|
2351 |
result = self.rpc.call_blockdev_removechildren(self.target_node_uuid, dev, |
|
2352 |
old_lvs) |
|
2353 |
result = self.rpc.call_blockdev_removechildren(self.target_node_uuid, |
|
2354 |
(dev, self.instance), |
|
2355 |
(old_lvs, self.instance)) |
|
2353 | 2356 |
result.Raise("Can't detach drbd from local storage on node" |
2354 | 2357 |
" %s for device %s" % |
2355 | 2358 |
(self.cfg.GetNodeName(self.target_node_uuid), dev.iv_name)) |
... | ... | |
2370 | 2373 |
# Build the rename list based on what LVs exist on the node |
2371 | 2374 |
rename_old_to_new = [] |
2372 | 2375 |
for to_ren in old_lvs: |
2373 |
result = self.rpc.call_blockdev_find(self.target_node_uuid, to_ren) |
|
2376 |
result = self.rpc.call_blockdev_find(self.target_node_uuid, |
|
2377 |
(to_ren, self.instance)) |
|
2374 | 2378 |
if not result.fail_msg and result.payload: |
2375 | 2379 |
# device exists |
2376 | 2380 |
rename_old_to_new.append((to_ren, ren_fn(to_ren, temp_suffix))) |
... | ... | |
2393 | 2397 |
# Intermediate steps of in memory modifications |
2394 | 2398 |
for old, new in zip(old_lvs, new_lvs): |
2395 | 2399 |
new.logical_id = old.logical_id |
2396 |
self.cfg.SetDiskID(new, self.target_node_uuid) |
|
2397 | 2400 |
|
2398 | 2401 |
# We need to modify old_lvs so that removal later removes the |
2399 | 2402 |
# right LVs, not the newly added ones; note that old_lvs is a |
2400 | 2403 |
# copy here |
2401 | 2404 |
for disk in old_lvs: |
2402 | 2405 |
disk.logical_id = ren_fn(disk, temp_suffix) |
2403 |
self.cfg.SetDiskID(disk, self.target_node_uuid) |
|
2404 | 2406 |
|
2405 | 2407 |
# Now that the new lvs have the old name, we can add them to the device |
2406 | 2408 |
self.lu.LogInfo("Adding new mirror component on %s", |
2407 | 2409 |
self.cfg.GetNodeName(self.target_node_uuid)) |
2408 | 2410 |
result = self.rpc.call_blockdev_addchildren(self.target_node_uuid, |
2409 |
(dev, self.instance), new_lvs) |
|
2411 |
(dev, self.instance), |
|
2412 |
(new_lvs, self.instance)) |
|
2410 | 2413 |
msg = result.fail_msg |
2411 | 2414 |
if msg: |
2412 | 2415 |
for new_lv in new_lvs: |
2413 | 2416 |
msg2 = self.rpc.call_blockdev_remove(self.target_node_uuid, |
2414 |
new_lv).fail_msg
|
|
2417 |
(new_lv, self.instance)).fail_msg
|
|
2415 | 2418 |
if msg2: |
2416 | 2419 |
self.lu.LogWarning("Can't rollback device %s: %s", dev, msg2, |
2417 | 2420 |
hint=("cleanup manually the unused logical" |
... | ... | |
2560 | 2563 |
" soon as possible")) |
2561 | 2564 |
|
2562 | 2565 |
self.lu.LogInfo("Detaching primary drbds from the network (=> standalone)") |
2563 |
result = self.rpc.call_drbd_disconnect_net([pnode], self.node_secondary_ip,
|
|
2564 |
self.instance.disks)[pnode]
|
|
2566 |
result = self.rpc.call_drbd_disconnect_net( |
|
2567 |
[pnode], (self.instance.disks, self.instance))[pnode]
|
|
2565 | 2568 |
|
2566 | 2569 |
msg = result.fail_msg |
2567 | 2570 |
if msg: |
... | ... | |
2587 | 2590 |
" (standalone => connected)") |
2588 | 2591 |
result = self.rpc.call_drbd_attach_net([self.instance.primary_node, |
2589 | 2592 |
self.new_node_uuid], |
2590 |
self.node_secondary_ip, |
|
2591 | 2593 |
(self.instance.disks, self.instance), |
2592 | 2594 |
self.instance.name, |
2593 | 2595 |
False) |
b/lib/cmdlib/instance_utils.py | ||
---|---|---|
275 | 275 |
edata = device.ComputeNodeTree(instance.primary_node) |
276 | 276 |
for node_uuid, disk in edata: |
277 | 277 |
lu.cfg.SetDiskID(disk, node_uuid) |
278 |
result = lu.rpc.call_blockdev_remove(node_uuid, disk)
|
|
278 |
result = lu.rpc.call_blockdev_remove(node_uuid, (disk, instance))
|
|
279 | 279 |
if result.fail_msg: |
280 | 280 |
lu.LogWarning("Could not remove disk %s on node %s," |
281 | 281 |
" continuing anyway: %s", idx, |
b/lib/constants.py | ||
---|---|---|
1207 | 1207 |
|
1208 | 1208 |
DISK_DT_PARAMETERS = frozenset(DISK_DT_TYPES.keys()) |
1209 | 1209 |
|
1210 |
# dynamic disk parameters |
|
1211 |
DDP_LOCAL_IP = "local-ip" |
|
1212 |
DDP_REMOTE_IP = "remote-ip" |
|
1213 |
DDP_PORT = "port" |
|
1214 |
DDP_LOCAL_MINOR = "local-minor" |
|
1215 |
DDP_REMOTE_MINOR = "remote-minor" |
|
1216 |
|
|
1210 | 1217 |
# OOB supported commands |
1211 | 1218 |
OOB_POWER_ON = _constants.OOB_POWER_ON |
1212 | 1219 |
OOB_POWER_OFF = _constants.OOB_POWER_OFF |
b/lib/masterd/instance.py | ||
---|---|---|
1209 | 1209 |
self._feedback_fn("Removing snapshot of disk/%s on node %s" % |
1210 | 1210 |
(disk_index, src_node)) |
1211 | 1211 |
|
1212 |
result = self._lu.rpc.call_blockdev_remove(src_node, disk) |
|
1212 |
result = self._lu.rpc.call_blockdev_remove(src_node, |
|
1213 |
(disk, self._instance)) |
|
1213 | 1214 |
if result.fail_msg: |
1214 | 1215 |
self._lu.LogWarning("Could not remove snapshot for disk/%d from node" |
1215 | 1216 |
" %s: %s", disk_index, src_node, result.fail_msg) |
... | ... | |
1242 | 1243 |
|
1243 | 1244 |
# FIXME: pass debug option from opcode to backend |
1244 | 1245 |
dt = DiskTransfer("snapshot/%s" % idx, |
1245 |
constants.IEIO_SCRIPT, (dev, idx),
|
|
1246 |
constants.IEIO_SCRIPT, ((dev, instance), idx),
|
|
1246 | 1247 |
constants.IEIO_FILE, (path, ), |
1247 | 1248 |
finished_fn) |
1248 | 1249 |
transfers.append(dt) |
... | ... | |
1300 | 1301 |
finished_fn = compat.partial(self._TransferFinished, idx) |
1301 | 1302 |
ieloop.Add(DiskExport(self._lu, instance.primary_node, |
1302 | 1303 |
opts, host, port, instance, "disk%d" % idx, |
1303 |
constants.IEIO_SCRIPT, (dev, idx),
|
|
1304 |
constants.IEIO_SCRIPT, ((dev, instance), idx),
|
|
1304 | 1305 |
timeouts, cbs, private=(idx, finished_fn))) |
1305 | 1306 |
|
1306 | 1307 |
ieloop.Run() |
... | ... | |
1482 | 1483 |
|
1483 | 1484 |
ieloop.Add(DiskImport(lu, instance.primary_node, opts, instance, |
1484 | 1485 |
"disk%d" % idx, |
1485 |
constants.IEIO_SCRIPT, (dev, idx),
|
|
1486 |
constants.IEIO_SCRIPT, ((dev, instance), idx),
|
|
1486 | 1487 |
timeouts, cbs, private=(idx, ))) |
1487 | 1488 |
|
1488 | 1489 |
ieloop.Run() |
b/lib/objects.py | ||
---|---|---|
506 | 506 |
|
507 | 507 |
class Disk(ConfigObject): |
508 | 508 |
"""Config object representing a block device.""" |
509 |
__slots__ = (["name", "dev_type", "logical_id", "physical_id", |
|
510 |
"children", "iv_name", "size", "mode", "params", "spindles"] + |
|
511 |
_UUID) |
|
509 |
__slots__ = (["name", "dev_type", "logical_id", "physical_id", "children", "iv_name", |
|
510 |
"size", "mode", "params", "spindles"] + _UUID + |
|
511 |
# dynamic_params is special. It depends on the node this instance |
|
512 |
# is sent to, and should not be persisted. |
|
513 |
["dynamic_params"]) |
|
512 | 514 |
|
513 | 515 |
def CreateOnSecondary(self): |
514 | 516 |
"""Test if this device needs to be created on a secondary node.""" |
... | ... | |
696 | 698 |
child.UnsetSize() |
697 | 699 |
self.size = 0 |
698 | 700 |
|
699 |
def SetPhysicalID(self, target_node_uuid, nodes_ip):
|
|
700 |
"""Convert the logical ID to the physical ID.
|
|
701 |
def UpdateDynamicDiskParams(self, target_node_uuid, nodes_ip):
|
|
702 |
"""Updates the dynamic disk params for the given node.
|
|
701 | 703 |
|
702 |
This is used only for drbd, which needs ip/port configuration. |
|
703 |
|
|
704 |
The routine descends down and updates its children also, because |
|
705 |
this helps when the only the top device is passed to the remote |
|
706 |
node. |
|
704 |
This is mainly used for drbd, which needs ip/port configuration. |
|
707 | 705 |
|
708 | 706 |
Arguments: |
709 | 707 |
- target_node_uuid: the node UUID we wish to configure for |
710 | 708 |
- nodes_ip: a mapping of node name to ip |
711 | 709 |
|
712 |
The target_node must exist in in nodes_ip, and must be one of the |
|
713 |
nodes in the logical ID for each of the DRBD devices encountered |
|
714 |
in the disk tree. |
|
710 |
The target_node must exist in nodes_ip, and should be one of the |
|
711 |
nodes in the logical ID if this device is a DRBD device. |
|
715 | 712 |
|
716 | 713 |
""" |
717 | 714 |
if self.children: |
718 | 715 |
for child in self.children: |
719 |
child.SetPhysicalID(target_node_uuid, nodes_ip)
|
|
716 |
child.UpdateDynamicDiskParams(target_node_uuid, nodes_ip)
|
|
720 | 717 |
|
721 |
if self.logical_id is None and self.physical_id is not None: |
|
722 |
return |
|
723 |
if self.dev_type in constants.LDS_DRBD: |
|
724 |
pnode_uuid, snode_uuid, port, pminor, sminor, secret = self.logical_id |
|
718 |
dyn_disk_params = {} |
|
719 |
if self.logical_id is not None and self.dev_type in constants.LDS_DRBD: |
|
720 |
pnode_uuid, snode_uuid, _, pminor, sminor, _ = self.logical_id |
|
725 | 721 |
if target_node_uuid not in (pnode_uuid, snode_uuid): |
726 |
raise errors.ConfigurationError("DRBD device not knowing node %s" % |
|
727 |
target_node_uuid) |
|
722 |
# disk object is being sent to neither the primary nor the secondary |
|
723 |
# node. reset the dynamic parameters, the target node is not |
|
724 |
# supposed to use them. |
|
725 |
self.dynamic_params = dyn_disk_params |
|
726 |
return |
|
727 |
|
|
728 | 728 |
pnode_ip = nodes_ip.get(pnode_uuid, None) |
729 | 729 |
snode_ip = nodes_ip.get(snode_uuid, None) |
730 | 730 |
if pnode_ip is None or snode_ip is None: |
731 | 731 |
raise errors.ConfigurationError("Can't find primary or secondary node" |
732 | 732 |
" for %s" % str(self)) |
733 |
p_data = (pnode_ip, port) |
|
734 |
s_data = (snode_ip, port) |
|
735 | 733 |
if pnode_uuid == target_node_uuid: |
736 |
self.physical_id = p_data + s_data + (pminor, secret) |
|
734 |
dyn_disk_params[constants.DDP_LOCAL_IP] = pnode_ip |
|
735 |
dyn_disk_params[constants.DDP_REMOTE_IP] = snode_ip |
|
736 |
dyn_disk_params[constants.DDP_LOCAL_MINOR] = pminor |
|
737 |
dyn_disk_params[constants.DDP_REMOTE_MINOR] = sminor |
|
737 | 738 |
else: # it must be secondary, we tested above |
738 |
self.physical_id = s_data + p_data + (sminor, secret) |
|
739 |
else: |
|
740 |
self.physical_id = self.logical_id |
|
741 |
return |
|
739 |
dyn_disk_params[constants.DDP_LOCAL_IP] = snode_ip |
|
740 |
dyn_disk_params[constants.DDP_REMOTE_IP] = pnode_ip |
|
741 |
dyn_disk_params[constants.DDP_LOCAL_MINOR] = sminor |
|
742 |
dyn_disk_params[constants.DDP_REMOTE_MINOR] = pminor |
|
743 |
|
|
744 |
self.dynamic_params = dyn_disk_params |
|
742 | 745 |
|
743 | 746 |
def ToDict(self): |
744 | 747 |
"""Disk-specific conversion to standard python types. |
b/lib/rpc.py | ||
---|---|---|
126 | 126 |
return wrapper |
127 | 127 |
|
128 | 128 |
|
129 |
def _Compress(data): |
|
129 |
def _Compress(_, data):
|
|
130 | 130 |
"""Compresses a string for transport over RPC. |
131 | 131 |
|
132 | 132 |
Small amounts of data are not compressed. |
... | ... | |
460 | 460 |
self._encoder = compat.partial(self._EncodeArg, encoder_fn) |
461 | 461 |
|
462 | 462 |
@staticmethod |
463 |
def _EncodeArg(encoder_fn, (argkind, value)): |
|
463 |
def _EncodeArg(encoder_fn, node, (argkind, value)):
|
|
464 | 464 |
"""Encode argument. |
465 | 465 |
|
466 | 466 |
""" |
467 | 467 |
if argkind is None: |
468 | 468 |
return value |
469 | 469 |
else: |
470 |
return encoder_fn(argkind)(value) |
|
470 |
return encoder_fn(argkind)(node, value)
|
|
471 | 471 |
|
472 | 472 |
def _Call(self, cdef, node_list, args): |
473 | 473 |
"""Entry point for automatically generated RPC wrappers. |
... | ... | |
489 | 489 |
if len(args) != len(argdefs): |
490 | 490 |
raise errors.ProgrammerError("Number of passed arguments doesn't match") |
491 | 491 |
|
492 |
enc_args = map(self._encoder, zip(map(compat.snd, argdefs), args)) |
|
493 | 492 |
if prep_fn is None: |
494 |
# for a no-op prep_fn, we serialise the body once, and then we |
|
495 |
# reuse it in the dictionary values |
|
496 |
body = serializer.DumpJson(enc_args) |
|
497 |
pnbody = dict((n, body) for n in node_list) |
|
498 |
else: |
|
499 |
# for a custom prep_fn, we pass the encoded arguments and the |
|
500 |
# node name to the prep_fn, and we serialise its return value |
|
501 |
assert callable(prep_fn) |
|
502 |
pnbody = dict((n, serializer.DumpJson(prep_fn(n, enc_args))) |
|
503 |
for n in node_list) |
|
493 |
prep_fn = lambda _, args: args |
|
494 |
assert callable(prep_fn) |
|
495 |
|
|
496 |
# encode the arguments for each node individually, pass them and the node |
|
497 |
# name to the prep_fn, and serialise its return value |
|
498 |
encode_args_fn = lambda node: map(compat.partial(self._encoder, node), |
|
499 |
zip(map(compat.snd, argdefs), args)) |
|
500 |
pnbody = dict((n, serializer.DumpJson(prep_fn(n, encode_args_fn(n)))) |
|
501 |
for n in node_list) |
|
504 | 502 |
|
505 | 503 |
result = self._proc(node_list, procedure, pnbody, read_timeout, |
506 | 504 |
req_resolver_opts) |
... | ... | |
512 | 510 |
return result |
513 | 511 |
|
514 | 512 |
|
515 |
def _ObjectToDict(value): |
|
513 |
def _ObjectToDict(_, value):
|
|
516 | 514 |
"""Converts an object to a dictionary. |
517 | 515 |
|
518 | 516 |
@note: See L{objects}. |
... | ... | |
521 | 519 |
return value.ToDict() |
522 | 520 |
|
523 | 521 |
|
524 |
def _ObjectListToDict(value): |
|
522 |
def _ObjectListToDict(node, value):
|
|
525 | 523 |
"""Converts a list of L{objects} to dictionaries. |
526 | 524 |
|
527 | 525 |
""" |
528 |
return map(_ObjectToDict, value)
|
|
526 |
return map(compat.partial(_ObjectToDict, node), value)
|
|
529 | 527 |
|
530 | 528 |
|
531 |
def _EncodeNodeToDiskDict(value): |
|
532 |
"""Encodes a dictionary with node name as key and disk objects as values. |
|
533 |
|
|
534 |
""" |
|
535 |
return dict((name, _ObjectListToDict(disks)) |
|
536 |
for name, disks in value.items()) |
|
537 |
|
|
538 |
|
|
539 |
def _PrepareFileUpload(getents_fn, filename): |
|
529 |
def _PrepareFileUpload(getents_fn, node, filename): |
|
540 | 530 |
"""Loads a file and prepares it for an upload to nodes. |
541 | 531 |
|
542 | 532 |
""" |
543 | 533 |
statcb = utils.FileStatHelper() |
544 |
data = _Compress(utils.ReadFile(filename, preread=statcb)) |
|
534 |
data = _Compress(node, utils.ReadFile(filename, preread=statcb))
|
|
545 | 535 |
st = statcb.st |
546 | 536 |
|
547 | 537 |
if getents_fn is None: |
... | ... | |
555 | 545 |
getents.LookupGid(st.st_gid), st.st_atime, st.st_mtime] |
556 | 546 |
|
557 | 547 |
|
558 |
def _PrepareFinalizeExportDisks(snap_disks): |
|
548 |
def _PrepareFinalizeExportDisks(_, snap_disks):
|
|
559 | 549 |
"""Encodes disks for finalizing export. |
560 | 550 |
|
561 | 551 |
""" |
... | ... | |
570 | 560 |
return flat_disks |
571 | 561 |
|
572 | 562 |
|
573 |
def _EncodeImportExportIO((ieio, ieioargs)): |
|
574 |
"""Encodes import/export I/O information. |
|
575 |
|
|
576 |
""" |
|
577 |
if ieio == constants.IEIO_RAW_DISK: |
|
578 |
assert len(ieioargs) == 1 |
|
579 |
return (ieio, (ieioargs[0].ToDict(), )) |
|
580 |
|
|
581 |
if ieio == constants.IEIO_SCRIPT: |
|
582 |
assert len(ieioargs) == 2 |
|
583 |
return (ieio, (ieioargs[0].ToDict(), ieioargs[1])) |
|
584 |
|
|
585 |
return (ieio, ieioargs) |
|
586 |
|
|
587 |
|
|
588 |
def _EncodeBlockdevRename(value): |
|
563 |
def _EncodeBlockdevRename(_, value): |
|
589 | 564 |
"""Encodes information for renaming block devices. |
590 | 565 |
|
591 | 566 |
""" |
... | ... | |
683 | 658 |
return disk |
684 | 659 |
|
685 | 660 |
|
686 |
def AnnotateDiskParams(template, disks, disk_params):
|
|
661 |
def AnnotateDiskParams(disks, disk_params): |
|
687 | 662 |
"""Annotates the disk objects with the disk parameters. |
688 | 663 |
|
689 |
@param template: The disk template used |
|
690 | 664 |
@param disks: The list of disks objects to annotate |
691 |
@param disk_params: The disk paramaters for annotation
|
|
665 |
@param disk_params: The disk parameters for annotation
|
|
692 | 666 |
@returns: A list of disk objects annotated |
693 | 667 |
|
694 | 668 |
""" |
695 |
ld_params = objects.Disk.ComputeLDParams(template, disk_params) |
|
669 |
def AnnotateDisk(disk): |
|
670 |
if disk.dev_type == constants.DT_DISKLESS: |
|
671 |
return disk |
|
696 | 672 |
|
697 |
if template == constants.DT_DRBD8: |
|
698 |
annotation_fn = _AnnotateDParamsDRBD |
|
699 |
elif template == constants.DT_DISKLESS: |
|
700 |
annotation_fn = lambda disk, _: disk |
|
701 |
else: |
|
702 |
annotation_fn = _AnnotateDParamsGeneric |
|
673 |
ld_params = objects.Disk.ComputeLDParams(disk.dev_type, disk_params) |
|
703 | 674 |
|
704 |
return [annotation_fn(disk.Copy(), ld_params) for disk in disks] |
|
675 |
if disk.dev_type == constants.DT_DRBD8: |
|
676 |
return _AnnotateDParamsDRBD(disk, ld_params) |
|
677 |
else: |
|
678 |
return _AnnotateDParamsGeneric(disk, ld_params) |
|
679 |
|
|
680 |
return [AnnotateDisk(disk.Copy()) for disk in disks] |
|
705 | 681 |
|
706 | 682 |
|
707 | 683 |
def _GetExclusiveStorageFlag(cfg, node_uuid): |
... | ... | |
785 | 761 |
_ENCODERS = { |
786 | 762 |
rpc_defs.ED_OBJECT_DICT: _ObjectToDict, |
787 | 763 |
rpc_defs.ED_OBJECT_DICT_LIST: _ObjectListToDict, |
788 |
rpc_defs.ED_NODE_TO_DISK_DICT: _EncodeNodeToDiskDict, |
|
789 | 764 |
rpc_defs.ED_COMPRESS: _Compress, |
790 | 765 |
rpc_defs.ED_FINALIZE_EXPORT_DISKS: _PrepareFinalizeExportDisks, |
791 |
rpc_defs.ED_IMPEXP_IO: _EncodeImportExportIO, |
|
792 | 766 |
rpc_defs.ED_BLOCKDEV_RENAME: _EncodeBlockdevRename, |
793 | 767 |
} |
794 | 768 |
|
... | ... | |
825 | 799 |
rpc_defs.ED_DISKS_DICT_DP: self._DisksDictDP, |
826 | 800 |
rpc_defs.ED_MULTI_DISKS_DICT_DP: self._MultiDiskDictDP, |
827 | 801 |
rpc_defs.ED_SINGLE_DISK_DICT_DP: self._SingleDiskDictDP, |
802 |
rpc_defs.ED_NODE_TO_DISK_DICT_DP: self._EncodeNodeToDiskDictDP, |
|
828 | 803 |
|
829 | 804 |
# Encoders with special requirements |
830 | 805 |
rpc_defs.ED_FILE_DETAILS: compat.partial(_PrepareFileUpload, _getents), |
806 |
|
|
807 |
rpc_defs.ED_IMPEXP_IO: self._EncodeImportExportIO, |
|
831 | 808 |
}) |
832 | 809 |
|
833 | 810 |
# Resolver using configuration |
... | ... | |
846 | 823 |
_generated_rpc.RpcClientDnsOnly.__init__(self) |
847 | 824 |
_generated_rpc.RpcClientDefault.__init__(self) |
848 | 825 |
|
849 |
def _NicDict(self, nic): |
|
826 |
def _NicDict(self, _, nic):
|
|
850 | 827 |
"""Convert the given nic to a dict and encapsulate netinfo |
851 | 828 |
|
852 | 829 |
""" |
... | ... | |
858 | 835 |
n.netinfo = objects.Network.ToDict(nobj) |
859 | 836 |
return n.ToDict() |
860 | 837 |
|
861 |
def _InstDict(self, instance, hvp=None, bep=None, osp=None): |
|
838 |
def _InstDict(self, node, instance, hvp=None, bep=None, osp=None):
|
|
862 | 839 |
"""Convert the given instance to a dict. |
863 | 840 |
|
864 | 841 |
This is done via the instance's ToDict() method and additionally |
... | ... | |
888 | 865 |
idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams) |
889 | 866 |
if osp is not None: |
890 | 867 |
idict["osparams"].update(osp) |
891 |
idict["disks"] = self._DisksDictDP((instance.disks, instance)) |
|
868 |
idict["disks"] = self._DisksDictDP(node, (instance.disks, instance))
|
|
892 | 869 |
for nic in idict["nics"]: |
893 | 870 |
nic["nicparams"] = objects.FillDict( |
894 | 871 |
cluster.nicparams[constants.PP_DEFAULT], |
... | ... | |
901 | 878 |
nic["netinfo"] = objects.Network.ToDict(nobj) |
902 | 879 |
return idict |
903 | 880 |
|
904 |
def _InstDictHvpBepDp(self, (instance, hvp, bep)): |
|
881 |
def _InstDictHvpBepDp(self, node, (instance, hvp, bep)):
|
|
905 | 882 |
"""Wrapper for L{_InstDict}. |
906 | 883 |
|
907 | 884 |
""" |
908 |
return self._InstDict(instance, hvp=hvp, bep=bep) |
|
885 |
return self._InstDict(node, instance, hvp=hvp, bep=bep)
|
|
909 | 886 |
|
910 |
def _InstDictOspDp(self, (instance, osparams)): |
|
887 |
def _InstDictOspDp(self, node, (instance, osparams)):
|
|
911 | 888 |
"""Wrapper for L{_InstDict}. |
912 | 889 |
|
913 | 890 |
""" |
914 |
return self._InstDict(instance, osp=osparams) |
|
891 |
return self._InstDict(node, instance, osp=osparams)
|
|
915 | 892 |
|
916 |
def _DisksDictDP(self, (disks, instance)): |
|
893 |
def _DisksDictDP(self, node, (disks, instance)):
|
|
917 | 894 |
"""Wrapper for L{AnnotateDiskParams}. |
918 | 895 |
|
919 | 896 |
""" |
920 | 897 |
diskparams = self._cfg.GetInstanceDiskParams(instance) |
921 |
return [disk.ToDict() |
|
922 |
for disk in AnnotateDiskParams(instance.disk_template, |
|
923 |
disks, diskparams)] |
|
898 |
ret = [] |
|
899 |
for disk in AnnotateDiskParams(disks, diskparams): |
|
900 |
disk_node_uuids = disk.GetNodes(instance.primary_node) |
|
901 |
node_ips = dict((uuid, node.secondary_ip) for (uuid, node) |
|
902 |
in self._cfg.GetMultiNodeInfo(disk_node_uuids)) |
|
903 |
|
|
904 |
disk.UpdateDynamicDiskParams(node, node_ips) |
|
905 |
|
|
906 |
ret.append(disk.ToDict()) |
|
924 | 907 |
|
925 |
def _MultiDiskDictDP(self, disks_insts): |
|
908 |
return ret |
|
909 |
|
|
910 |
def _MultiDiskDictDP(self, node, disks_insts): |
|
926 | 911 |
"""Wrapper for L{AnnotateDiskParams}. |
927 | 912 |
|
928 | 913 |
Supports a list of (disk, instance) tuples. |
929 | 914 |
""" |
930 | 915 |
return [disk for disk_inst in disks_insts |
931 |
for disk in self._DisksDictDP(disk_inst)] |
|
916 |
for disk in self._DisksDictDP(node, disk_inst)]
|
|
932 | 917 |
|
933 |
def _SingleDiskDictDP(self, (disk, instance)): |
|
918 |
def _SingleDiskDictDP(self, node, (disk, instance)):
|
|
934 | 919 |
"""Wrapper for L{AnnotateDiskParams}. |
935 | 920 |
|
936 | 921 |
""" |
937 |
(anno_disk,) = self._DisksDictDP(([disk], instance)) |
|
922 |
(anno_disk,) = self._DisksDictDP(node, ([disk], instance))
|
|
938 | 923 |
return anno_disk |
939 | 924 |
|
925 |
def _EncodeNodeToDiskDictDP(self, node, value): |
|
926 |
"""Encode dict of node name -> list of (disk, instance) tuples as values. |
|
927 |
|
|
928 |
""" |
|
929 |
return dict((name, [self._SingleDiskDictDP(node, disk) for disk in disks]) |
|
930 |
for name, disks in value.items()) |
|
931 |
|
|
932 |
def _EncodeImportExportIO(self, node, (ieio, ieioargs)): |
|
933 |
"""Encodes import/export I/O information. |
|
934 |
|
|
935 |
""" |
|
936 |
if ieio == constants.IEIO_RAW_DISK: |
|
937 |
assert len(ieioargs) == 1 |
|
938 |
return (ieio, (self._SingleDiskDictDP(node, ieioargs[0]), )) |
|
939 |
|
|
940 |
if ieio == constants.IEIO_SCRIPT: |
|
941 |
assert len(ieioargs) == 2 |
|
942 |
return (ieio, (self._SingleDiskDictDP(node, ieioargs[0]), ieioargs[1])) |
|
943 |
|
|
944 |
return (ieio, ieioargs) |
|
945 |
|
|
940 | 946 |
|
941 | 947 |
class JobQueueRunner(_RpcClientBase, _generated_rpc.RpcClientJobQueue): |
942 | 948 |
"""RPC wrappers for job queue. |
b/lib/rpc_defs.py | ||
---|---|---|
62 | 62 |
ED_OBJECT_DICT_LIST, |
63 | 63 |
ED_INST_DICT, |
64 | 64 |
ED_INST_DICT_HVP_BEP_DP, |
65 |
ED_NODE_TO_DISK_DICT, |
|
65 |
ED_NODE_TO_DISK_DICT_DP,
|
|
66 | 66 |
ED_INST_DICT_OSP_DP, |
67 | 67 |
ED_IMPEXP_IO, |
68 | 68 |
ED_FILE_DETAILS, |
... | ... | |
143 | 143 |
return args |
144 | 144 |
|
145 | 145 |
|
146 |
def _DrbdCallsPreProc(node, args): |
|
147 |
"""Add the target node UUID as additional field for DRBD related calls.""" |
|
148 |
return args + [node] |
|
149 |
|
|
150 |
|
|
151 | 146 |
def _OsGetPostProc(result): |
152 | 147 |
"""Post-processor for L{rpc.RpcRunner.call_os_get}. |
153 | 148 |
|
... | ... | |
351 | 346 |
], None, None, |
352 | 347 |
"Gets the sizes of requested block devices present on a node"), |
353 | 348 |
("blockdev_create", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
354 |
("bdev", ED_OBJECT_DICT, None),
|
|
349 |
("bdev", ED_SINGLE_DISK_DICT_DP, None),
|
|
355 | 350 |
("size", None, None), |
356 | 351 |
("owner", None, None), |
357 | 352 |
("on_primary", None, None), |
... | ... | |
365 | 360 |
], None, None, |
366 | 361 |
"Request wipe at given offset with given size of a block device"), |
367 | 362 |
("blockdev_remove", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
368 |
("bdev", ED_OBJECT_DICT, None),
|
|
363 |
("bdev", ED_SINGLE_DISK_DICT_DP, None),
|
|
369 | 364 |
], None, None, "Request removal of a given block device"), |
370 | 365 |
("blockdev_pause_resume_sync", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
371 | 366 |
("disks", ED_DISKS_DICT_DP, None), |
... | ... | |
382 | 377 |
], None, None, "Request shutdown of a given block device"), |
383 | 378 |
("blockdev_addchildren", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
384 | 379 |
("bdev", ED_SINGLE_DISK_DICT_DP, None), |
385 |
("ndevs", ED_OBJECT_DICT_LIST, None),
|
|
380 |
("ndevs", ED_DISKS_DICT_DP, None),
|
|
386 | 381 |
], None, None, |
387 | 382 |
"Request adding a list of children to a (mirroring) device"), |
388 | 383 |
("blockdev_removechildren", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
389 |
("bdev", ED_OBJECT_DICT, None),
|
|
390 |
("ndevs", ED_OBJECT_DICT_LIST, None),
|
|
384 |
("bdev", ED_SINGLE_DISK_DICT_DP, None),
|
|
385 |
("ndevs", ED_DISKS_DICT_DP, None),
|
|
391 | 386 |
], None, None, |
392 | 387 |
"Request removing a list of children from a (mirroring) device"), |
393 | 388 |
("blockdev_close", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
394 | 389 |
("instance_name", None, None), |
395 |
("disks", ED_OBJECT_DICT_LIST, None),
|
|
390 |
("disks", ED_DISKS_DICT_DP, None),
|
|
396 | 391 |
], None, None, "Closes the given block devices"), |
397 | 392 |
("blockdev_getdimensions", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
398 |
("disks", ED_OBJECT_DICT_LIST, None),
|
|
393 |
("disks", ED_MULTI_DISKS_DICT_DP, None),
|
|
399 | 394 |
], None, None, "Returns size and spindles of the given disks"), |
400 | 395 |
("drbd_disconnect_net", MULTI, None, constants.RPC_TMO_NORMAL, [ |
401 |
("nodes_ip", None, None), |
|
402 |
("disks", ED_OBJECT_DICT_LIST, None), |
|
403 |
], _DrbdCallsPreProc, None, |
|
396 |
("disks", ED_DISKS_DICT_DP, None), |
|
397 |
], None, None, |
|
404 | 398 |
"Disconnects the network of the given drbd devices"), |
405 | 399 |
("drbd_attach_net", MULTI, None, constants.RPC_TMO_NORMAL, [ |
406 |
("nodes_ip", None, None), |
|
407 | 400 |
("disks", ED_DISKS_DICT_DP, None), |
408 | 401 |
("instance_name", None, None), |
409 | 402 |
("multimaster", None, None), |
410 |
], _DrbdCallsPreProc, None, "Connects the given DRBD devices"),
|
|
403 |
], None, None, "Connects the given DRBD devices"),
|
|
411 | 404 |
("drbd_wait_sync", MULTI, None, constants.RPC_TMO_SLOW, [ |
412 |
("nodes_ip", None, None), |
|
413 | 405 |
("disks", ED_DISKS_DICT_DP, None), |
414 |
], _DrbdCallsPreProc, None,
|
|
406 |
], None, None,
|
|
415 | 407 |
"Waits for the synchronization of drbd devices is complete"), |
416 | 408 |
("drbd_needs_activation", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
417 |
("nodes_ip", None, None), |
|
418 | 409 |
("disks", ED_MULTI_DISKS_DICT_DP, None), |
419 |
], _DrbdCallsPreProc, None,
|
|
410 |
], None, None,
|
|
420 | 411 |
"Returns the drbd disks which need activation"), |
421 | 412 |
("blockdev_grow", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
422 | 413 |
("cf_bdev", ED_SINGLE_DISK_DICT_DP, None), |
... | ... | |
439 | 430 |
("devlist", ED_BLOCKDEV_RENAME, None), |
440 | 431 |
], None, None, "Request rename of the given block devices"), |
441 | 432 |
("blockdev_find", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
442 |
("disk", ED_OBJECT_DICT, None),
|
|
433 |
("disk", ED_SINGLE_DISK_DICT_DP, None),
|
|
443 | 434 |
], None, _BlockdevFindPostProc, |
444 | 435 |
"Request identification of a given block device"), |
445 | 436 |
("blockdev_getmirrorstatus", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
... | ... | |
447 | 438 |
], None, _BlockdevGetMirrorStatusPostProc, |
448 | 439 |
"Request status of a (mirroring) device"), |
449 | 440 |
("blockdev_getmirrorstatus_multi", MULTI, None, constants.RPC_TMO_NORMAL, [ |
450 |
("node_disks", ED_NODE_TO_DISK_DICT, None), |
|
441 |
("node_disks", ED_NODE_TO_DISK_DICT_DP, None),
|
|
451 | 442 |
], _BlockdevGetMirrorStatusMultiPreProc, |
452 | 443 |
_BlockdevGetMirrorStatusMultiPostProc, |
453 | 444 |
"Request status of (mirroring) devices from multiple nodes"), |
454 | 445 |
("blockdev_setinfo", SINGLE, None, constants.RPC_TMO_NORMAL, [ |
455 |
("disk", ED_OBJECT_DICT, None),
|
|
446 |
("disk", ED_SINGLE_DISK_DICT_DP, None),
|
|
456 | 447 |
("info", None, None), |
457 | 448 |
], None, None, "Sets metadata information on a given block device"), |
458 | 449 |
] |
b/lib/server/noded.py | ||
---|---|---|
415 | 415 |
disk list must all be drbd devices. |
416 | 416 |
|
417 | 417 |
""" |
418 |
nodes_ip, disks, target_node_uuid = params
|
|
419 |
disks = [objects.Disk.FromDict(cf) for cf in disks]
|
|
420 |
return backend.DrbdDisconnectNet(target_node_uuid, nodes_ip, disks)
|
|
418 |
(disks,) = params
|
|
419 |
disks = [objects.Disk.FromDict(disk) for disk in disks]
|
|
420 |
return backend.DrbdDisconnectNet(disks) |
|
421 | 421 |
|
422 | 422 |
@staticmethod |
423 | 423 |
def perspective_drbd_attach_net(params): |
... | ... | |
427 | 427 |
disk list must all be drbd devices. |
428 | 428 |
|
429 | 429 |
""" |
430 |
nodes_ip, disks, instance_name, multimaster, target_node_uuid = params |
|
431 |
disks = [objects.Disk.FromDict(cf) for cf in disks] |
|
432 |
return backend.DrbdAttachNet(target_node_uuid, nodes_ip, disks, |
|
433 |
instance_name, multimaster) |
|
430 |
disks, instance_name, multimaster = params |
|
431 |
disks = [objects.Disk.FromDict(disk) for disk in disks] |
|
432 |
return backend.DrbdAttachNet(disks, instance_name, multimaster) |
|
434 | 433 |
|
435 | 434 |
@staticmethod |
436 | 435 |
def perspective_drbd_wait_sync(params): |
... | ... | |
440 | 439 |
disk list must all be drbd devices. |
441 | 440 |
|
442 | 441 |
""" |
443 |
nodes_ip, disks, target_node_uuid = params
|
|
444 |
disks = [objects.Disk.FromDict(cf) for cf in disks]
|
|
445 |
return backend.DrbdWaitSync(target_node_uuid, nodes_ip, disks)
|
|
442 |
(disks,) = params
|
|
443 |
disks = [objects.Disk.FromDict(disk) for disk in disks]
|
|
444 |
return backend.DrbdWaitSync(disks) |
|
446 | 445 |
|
447 | 446 |
@staticmethod |
448 | 447 |
def perspective_drbd_needs_activation(params): |
... | ... | |
452 | 451 |
disk list must all be drbd devices. |
453 | 452 |
|
454 | 453 |
""" |
455 |
nodes_ip, disks, target_node_uuid = params
|
|
456 |
disks = [objects.Disk.FromDict(cf) for cf in disks]
|
|
457 |
return backend.DrbdNeedsActivation(target_node_uuid, nodes_ip, disks)
|
|
454 |
(disks,) = params
|
|
455 |
disks = [objects.Disk.FromDict(disk) for disk in disks]
|
|
456 |
return backend.DrbdNeedsActivation(disks) |
|
458 | 457 |
|
459 | 458 |
@staticmethod |
460 |
def perspective_drbd_helper(params):
|
|
459 |
def perspective_drbd_helper(_):
|
|
461 | 460 |
"""Query drbd helper. |
462 | 461 |
|
463 | 462 |
""" |
b/lib/storage/base.py | ||
---|---|---|
72 | 72 |
after assembly we'll have our correct major/minor. |
73 | 73 |
|
74 | 74 |
""" |
75 |
def __init__(self, unique_id, children, size, params): |
|
75 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
76 | 76 |
self._children = children |
77 | 77 |
self.dev_path = None |
78 | 78 |
self.unique_id = unique_id |
... | ... | |
81 | 81 |
self.attached = False |
82 | 82 |
self.size = size |
83 | 83 |
self.params = params |
84 |
self.dyn_params = dyn_params |
|
84 | 85 |
|
85 | 86 |
def Assemble(self): |
86 | 87 |
"""Assemble the device from its components. |
... | ... | |
109 | 110 |
raise NotImplementedError |
110 | 111 |
|
111 | 112 |
@classmethod |
112 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
113 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
114 |
dyn_params): |
|
113 | 115 |
"""Create the device. |
114 | 116 |
|
115 | 117 |
If the device cannot be created, it will return None |
... | ... | |
132 | 134 |
@param params: device-specific options/parameters |
133 | 135 |
@type excl_stor: bool |
134 | 136 |
@param excl_stor: whether exclusive_storage is active |
137 |
@type dyn_params: dict |
|
138 |
@param dyn_params: dynamic parameters of the disk only valid for this node. |
|
139 |
As set by L{objects.Disk.UpdateDynamicDiskParams}. |
|
135 | 140 |
@rtype: L{BlockDev} |
136 | 141 |
@return: the created device, or C{None} in case of an error |
137 | 142 |
|
b/lib/storage/bdev.py | ||
---|---|---|
67 | 67 |
_INVALID_NAMES = compat.UniqueFrozenset([".", "..", "snapshot", "pvmove"]) |
68 | 68 |
_INVALID_SUBSTRINGS = compat.UniqueFrozenset(["_mlog", "_mimage"]) |
69 | 69 |
|
70 |
def __init__(self, unique_id, children, size, params): |
|
70 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
71 | 71 |
"""Attaches to a LV device. |
72 | 72 |
|
73 | 73 |
The unique_id is a tuple (vg_name, lv_name) |
74 | 74 |
|
75 | 75 |
""" |
76 |
super(LogicalVolume, self).__init__(unique_id, children, size, params) |
|
76 |
super(LogicalVolume, self).__init__(unique_id, children, size, params, |
|
77 |
dyn_params) |
|
77 | 78 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: |
78 | 79 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
79 | 80 |
self._vg_name, self._lv_name = unique_id |
... | ... | |
123 | 124 |
return map((lambda pv: pv.name), empty_pvs) |
124 | 125 |
|
125 | 126 |
@classmethod |
126 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
127 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
128 |
dyn_params): |
|
127 | 129 |
"""Create a new logical volume. |
128 | 130 |
|
129 | 131 |
""" |
... | ... | |
205 | 207 |
if result.failed: |
206 | 208 |
base.ThrowError("LV create failed (%s): %s", |
207 | 209 |
result.fail_reason, result.output) |
208 |
return LogicalVolume(unique_id, children, size, params) |
|
210 |
return LogicalVolume(unique_id, children, size, params, dyn_params)
|
|
209 | 211 |
|
210 | 212 |
@staticmethod |
211 | 213 |
def _GetVolumeInfo(lvm_cmd, fields): |
... | ... | |
597 | 599 |
snap_name = self._lv_name + ".snap" |
598 | 600 |
|
599 | 601 |
# remove existing snapshot if found |
600 |
snap = LogicalVolume((self._vg_name, snap_name), None, size, self.params) |
|
602 |
snap = LogicalVolume((self._vg_name, snap_name), None, size, self.params, |
|
603 |
self.dyn_params) |
|
601 | 604 |
base.IgnoreError(snap.Remove) |
602 | 605 |
|
603 | 606 |
vg_info = self.GetVGInfo([self._vg_name], False) |
... | ... | |
717 | 720 |
The unique_id for the file device is a (file_driver, file_path) tuple. |
718 | 721 |
|
719 | 722 |
""" |
720 |
def __init__(self, unique_id, children, size, params): |
|
723 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
721 | 724 |
"""Initalizes a file device backend. |
722 | 725 |
|
723 | 726 |
""" |
724 | 727 |
if children: |
725 | 728 |
raise errors.BlockDeviceError("Invalid setup for file device") |
726 |
super(FileStorage, self).__init__(unique_id, children, size, params) |
|
729 |
super(FileStorage, self).__init__(unique_id, children, size, params, |
|
730 |
dyn_params) |
|
727 | 731 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: |
728 | 732 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
729 | 733 |
self.driver = unique_id[0] |
... | ... | |
836 | 840 |
base.ThrowError("Can't stat %s: %s", self.dev_path, err) |
837 | 841 |
|
838 | 842 |
@classmethod |
839 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
843 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
844 |
dyn_params): |
|
840 | 845 |
"""Create a new file. |
841 | 846 |
|
842 | 847 |
@param size: the size of file in MiB |
... | ... | |
865 | 870 |
base.ThrowError("File already existing: %s", dev_path) |
866 | 871 |
base.ThrowError("Error in file creation: %", str(err)) |
867 | 872 |
|
868 |
return FileStorage(unique_id, children, size, params) |
|
873 |
return FileStorage(unique_id, children, size, params, dyn_params)
|
|
869 | 874 |
|
870 | 875 |
|
871 | 876 |
class PersistentBlockDevice(base.BlockDev): |
... | ... | |
878 | 883 |
For the time being, pathnames are required to lie under /dev. |
879 | 884 |
|
880 | 885 |
""" |
881 |
def __init__(self, unique_id, children, size, params): |
|
886 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
882 | 887 |
"""Attaches to a static block device. |
883 | 888 |
|
884 | 889 |
The unique_id is a path under /dev. |
885 | 890 |
|
886 | 891 |
""" |
887 | 892 |
super(PersistentBlockDevice, self).__init__(unique_id, children, size, |
888 |
params) |
|
893 |
params, dyn_params)
|
|
889 | 894 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: |
890 | 895 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
891 | 896 |
self.dev_path = unique_id[1] |
... | ... | |
904 | 909 |
self.Attach() |
905 | 910 |
|
906 | 911 |
@classmethod |
907 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
912 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
913 |
dyn_params): |
|
908 | 914 |
"""Create a new device |
909 | 915 |
|
910 | 916 |
This is a noop, we only return a PersistentBlockDevice instance |
... | ... | |
913 | 919 |
if excl_stor: |
914 | 920 |
raise errors.ProgrammerError("Persistent block device requested with" |
915 | 921 |
" exclusive_storage") |
916 |
return PersistentBlockDevice(unique_id, children, 0, params) |
|
922 |
return PersistentBlockDevice(unique_id, children, 0, params, dyn_params)
|
|
917 | 923 |
|
918 | 924 |
def Remove(self): |
919 | 925 |
"""Remove a device |
... | ... | |
990 | 996 |
this to be functional. |
991 | 997 |
|
992 | 998 |
""" |
993 |
def __init__(self, unique_id, children, size, params): |
|
999 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
994 | 1000 |
"""Attaches to an rbd device. |
995 | 1001 |
|
996 | 1002 |
""" |
997 |
super(RADOSBlockDevice, self).__init__(unique_id, children, size, params) |
|
1003 |
super(RADOSBlockDevice, self).__init__(unique_id, children, size, params, |
|
1004 |
dyn_params) |
|
998 | 1005 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: |
999 | 1006 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
1000 | 1007 |
|
... | ... | |
1004 | 1011 |
self.Attach() |
1005 | 1012 |
|
1006 | 1013 |
@classmethod |
1007 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
1014 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
1015 |
dyn_params): |
|
1008 | 1016 |
"""Create a new rbd device. |
1009 | 1017 |
|
1010 | 1018 |
Provision a new rbd volume inside a RADOS pool. |
... | ... | |
1027 | 1035 |
base.ThrowError("rbd creation failed (%s): %s", |
1028 | 1036 |
result.fail_reason, result.output) |
1029 | 1037 |
|
1030 |
return RADOSBlockDevice(unique_id, children, size, params) |
|
1038 |
return RADOSBlockDevice(unique_id, children, size, params, dyn_params)
|
|
1031 | 1039 |
|
1032 | 1040 |
def Remove(self): |
1033 | 1041 |
"""Remove the rbd device. |
... | ... | |
1343 | 1351 |
handling of the externally provided block devices. |
1344 | 1352 |
|
1345 | 1353 |
""" |
1346 |
def __init__(self, unique_id, children, size, params): |
|
1354 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
1347 | 1355 |
"""Attaches to an extstorage block device. |
1348 | 1356 |
|
1349 | 1357 |
""" |
1350 |
super(ExtStorageDevice, self).__init__(unique_id, children, size, params) |
|
1358 |
super(ExtStorageDevice, self).__init__(unique_id, children, size, params, |
|
1359 |
dyn_params) |
|
1351 | 1360 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: |
1352 | 1361 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
1353 | 1362 |
|
... | ... | |
1358 | 1367 |
self.Attach() |
1359 | 1368 |
|
1360 | 1369 |
@classmethod |
1361 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
1370 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
1371 |
dyn_params): |
|
1362 | 1372 |
"""Create a new extstorage device. |
1363 | 1373 |
|
1364 | 1374 |
Provision a new volume using an extstorage provider, which will |
... | ... | |
1377 | 1387 |
_ExtStorageAction(constants.ES_ACTION_CREATE, unique_id, |
1378 | 1388 |
params, str(size)) |
1379 | 1389 |
|
1380 |
return ExtStorageDevice(unique_id, children, size, params) |
|
1390 |
return ExtStorageDevice(unique_id, children, size, params, dyn_params)
|
|
1381 | 1391 |
|
1382 | 1392 |
def Remove(self): |
1383 | 1393 |
"""Remove the extstorage device. |
... | ... | |
1757 | 1767 |
|
1758 | 1768 |
""" |
1759 | 1769 |
_VerifyDiskType(disk.dev_type) |
1760 |
device = DEV_MAP[disk.dev_type](disk.physical_id, children, disk.size,
|
|
1761 |
disk.params) |
|
1770 |
device = DEV_MAP[disk.dev_type](disk.logical_id, children, disk.size,
|
|
1771 |
disk.params, disk.dynamic_params)
|
|
1762 | 1772 |
if not device.attached: |
1763 | 1773 |
return None |
1764 | 1774 |
return device |
... | ... | |
1779 | 1789 |
""" |
1780 | 1790 |
_VerifyDiskType(disk.dev_type) |
1781 | 1791 |
_VerifyDiskParams(disk) |
1782 |
device = DEV_MAP[disk.dev_type](disk.physical_id, children, disk.size,
|
|
1783 |
disk.params) |
|
1792 |
device = DEV_MAP[disk.dev_type](disk.logical_id, children, disk.size,
|
|
1793 |
disk.params, disk.dynamic_params)
|
|
1784 | 1794 |
device.Assemble() |
1785 | 1795 |
return device |
1786 | 1796 |
|
... | ... | |
1801 | 1811 |
""" |
1802 | 1812 |
_VerifyDiskType(disk.dev_type) |
1803 | 1813 |
_VerifyDiskParams(disk) |
1804 |
device = DEV_MAP[disk.dev_type].Create(disk.physical_id, children, disk.size, |
|
1805 |
disk.spindles, disk.params, excl_stor) |
|
1814 |
device = DEV_MAP[disk.dev_type].Create(disk.logical_id, children, disk.size, |
|
1815 |
disk.spindles, disk.params, excl_stor, |
|
1816 |
disk.dynamic_params) |
|
1806 | 1817 |
return device |
b/lib/storage/drbd.py | ||
---|---|---|
163 | 163 |
doesn't do anything to the supposed peer. If you need a fully |
164 | 164 |
connected DRBD pair, you need to use this class on both hosts. |
165 | 165 |
|
166 |
The unique_id for the drbd device is a (local_ip, local_port,
|
|
167 |
remote_ip, remote_port, local_minor, secret) tuple, and it must have
|
|
168 |
two children: the data device and the meta_device. The meta device
|
|
169 |
is checked for valid size and is zeroed on create. |
|
166 |
The unique_id for the drbd device is a (pnode_uuid, snode_uuid,
|
|
167 |
port, pnode_minor, lnode_minor, secret) tuple, and it must have
|
|
168 |
two children: the data device and the meta_device. The meta |
|
169 |
device is checked for valid size and is zeroed on create.
|
|
170 | 170 |
|
171 | 171 |
""" |
172 | 172 |
_DRBD_MAJOR = 147 |
... | ... | |
174 | 174 |
# timeout constants |
175 | 175 |
_NET_RECONFIG_TIMEOUT = 60 |
176 | 176 |
|
177 |
def __init__(self, unique_id, children, size, params): |
|
177 |
def __init__(self, unique_id, children, size, params, dyn_params):
|
|
178 | 178 |
if children and children.count(None) > 0: |
179 | 179 |
children = [] |
180 | 180 |
if len(children) not in (0, 2): |
181 | 181 |
raise ValueError("Invalid configuration data %s" % str(children)) |
182 | 182 |
if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 6: |
183 | 183 |
raise ValueError("Invalid configuration data %s" % str(unique_id)) |
184 |
(self._lhost, self._lport, |
|
185 |
self._rhost, self._rport, |
|
186 |
self._aminor, self._secret) = unique_id |
|
184 |
if constants.DDP_LOCAL_IP not in dyn_params or \ |
|
185 |
constants.DDP_REMOTE_IP not in dyn_params or \ |
|
186 |
constants.DDP_LOCAL_MINOR not in dyn_params or \ |
|
187 |
constants.DDP_REMOTE_MINOR not in dyn_params: |
|
188 |
raise ValueError("Invalid dynamic parameters %s" % str(dyn_params)) |
|
189 |
|
|
190 |
self._lhost = dyn_params[constants.DDP_LOCAL_IP] |
|
191 |
self._lport = unique_id[2] |
|
192 |
self._rhost = dyn_params[constants.DDP_REMOTE_IP] |
|
193 |
self._rport = unique_id[2] |
|
194 |
self._aminor = dyn_params[constants.DDP_LOCAL_MINOR] |
|
195 |
self._secret = unique_id[5] |
|
196 |
|
|
187 | 197 |
if children: |
188 | 198 |
if not _CanReadDevice(children[1].dev_path): |
189 | 199 |
logging.info("drbd%s: Ignoring unreadable meta device", self._aminor) |
190 | 200 |
children = [] |
191 |
super(DRBD8Dev, self).__init__(unique_id, children, size, params) |
|
201 |
super(DRBD8Dev, self).__init__(unique_id, children, size, params, |
|
202 |
dyn_params) |
|
192 | 203 |
self.major = self._DRBD_MAJOR |
193 | 204 |
|
194 | 205 |
info = DRBD8.GetProcInfo() |
... | ... | |
207 | 218 |
|
208 | 219 |
if (self._lhost is not None and self._lhost == self._rhost and |
209 | 220 |
self._lport == self._rport): |
210 |
raise ValueError("Invalid configuration data, same local/remote %s" % |
|
211 |
(unique_id,)) |
|
221 |
raise ValueError("Invalid configuration data, same local/remote %s, %s" %
|
|
222 |
(unique_id, dyn_params))
|
|
212 | 223 |
self.Attach() |
213 | 224 |
|
214 | 225 |
@staticmethod |
... | ... | |
1005 | 1016 |
base.ThrowError("Can't initialize meta device: %s", result.output) |
1006 | 1017 |
|
1007 | 1018 |
@classmethod |
1008 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor): |
|
1019 |
def Create(cls, unique_id, children, size, spindles, params, excl_stor, |
|
1020 |
dyn_params): |
|
1009 | 1021 |
"""Create a new DRBD8 device. |
1010 | 1022 |
|
1011 | 1023 |
Since DRBD devices are not created per se, just assembled, this |
Also available in: Unified diff