File: //lib64/python2.7/site-packages/block/maps.py
#!/usr/bin/python
#
# Copyright 2005-2007 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
class DeviceMapperLogSync:
"""Policy for synchronization of a DM Log"""
def set_policy(self, policy=""):
if policy in ("", "sync", "nosync"):
self.__policy = policy
return
raise ValueError,\
'policy must be "sync", "nosync", or unspecified, not %s' % \
(policy,)
def get_policy(self):
return self.__policy
def del_policy(self):
self.__policy = ""
policy = property(get_policy, set_policy, del_policy,\
"policy for synchronization")
def __init__(self, policy=""):
self.policy = policy
pass
def __str__(self):
return self.policy
class DeviceMapperLog:
"""Base class for device-mapper's "logger" functionality"""
def set_type(self, type):
if not type in ("core", "disk"):
raise ValueError, 'log type must be "core" or "disk", not %s' % \
(type,)
self.__type = type
def get_type(self):
return self.__type
type = property(get_type, set_type, None, "type of dm logger")
def set_sync(self, policy):
if isinstance(policy, "".__class__):
policy = DeviceMapperLogpolicy(policy)
if not isinstance(policy, DeviceMapperLogSync):
raise TypeError, "synchronization policy must be a DeviceMapperLogSync instance, got %s" % (policy.__class__,)
self.__sync = sync
def get_sync(self):
return self.__sync
sync = property(get_sync, set_sync, None, "dm synchronization policy")
def __init__(self, type="core", sync=DeviceMapperLogSync(), *params):
self.type = type
self.sync == sync
self.__params = params
pass
def __str__(self):
import string as _string
r = "%s %s %s" % (self.__type, len(self.__params), \
_string.join(map(str, self.__params)))
del _string
class CoreLog(DeviceMapperLog):
"""A device-mapper "core" logger"""
def __init__(self, size, sync=""):
self.sync = sync
return apply(DeviceMapperLog.__init__, (self, "core", size, sync), {})
class DiskLog(DeviceMapperLog):
"""A device-mapper "disk" logger"""
def __init__(self, device, size, sync=True):
return apply(DeviceMapperLog.__init__, \
(self, "disk", device, size, sync), {})
class DeviceMap:
"""Base class for a device map"""
def get_start(self):
return self.__start
def set_start(self, value):
if value > 0 and value > self.size:
raise ValueError, "%d is above maximum address (%d)" % \
(value, self.size)
self.__start = value
start = property(get_start, set_start, None, "start address of map")
def get_size(self):
return self.__size
def set_size(self, value):
if value < self.start:
raise ValueError, "%d is below the minimum address (%d)" % \
(value, self.start)
size = property(get_size, set_size, None, "number of mapped blocks")
def get_type(self):
return self.__type
def set_type(self, value):
if not hasattr(self, "_format_%s" % (value,)):
raise RuntimeError, "incorrect table type for class"
self.__type = value
type = property(get_type, set_type, None, "type of map")
def get_parents(self):
return self.parents
def set_parents(self, *parents):
from device import Device as _Device
for x in parents:
if not isinstance(x, _Device):
raise TypeError, "%s is not a Device" % (repr(x),)
self.__parents = list(parents)
del _Device
parents = property(get_parents, set_parents, None, \
"devices this map requires")
def get_required_modules(self):
return self.__modules
required_modules = property(get_required_modules, None, None, \
"the kernel modules this map requires")
def get_table(self):
ff = "_format_%s" % (self.type,)
if not hasattr(self, ff):
raise RuntimeError, "type cannot be created"
f = getattr(self, ff)
import dm as _dm
ret = [ _dm.table(self.start, self.size, self.type, f()) ]
del _dm
return ret
table = property(get_table, None, None, "the table for this DeviceMap")
def get_name(self):
return self.__name
def set_name(self, name):
if not self.map is None:
self.map.name = name
self.__name = name
name = property(get_name, set_name, None, "the name of the device map")
def get_uuid(self):
return self.__uuid
def set_uuid(self, uuid):
if not self.map is None:
if self.map.uuid:
raise ValueError("UUID already set for %s" % self.name)
self.map.uuid = uuid
self.__uuid = uuid
uuid = property(get_uuid, set_uuid, None, "the uuid of the device map")
def get_map(self):
return self.__map
def set_map(self, map):
self.__map = map
map = property(get_map, set_map, None, "the map itself")
def __init__(self, start, size, type=None, modules=[]):
self.__start = 0
self.__size = 0
self.__type = None
self.__modules = ["dm-mod"] + modules
self.__parents = []
self.__map = None
self.__name = None
self.__uuid = None
self.start = start
self.size = size
self.type = type
self.parents = []
def create(self, name=None):
import dm as _dm
import device as _device
for map in _dm.maps():
if _device.compare_tables(map.table, self.table):
self.map = map
self.name = map.name
break
else:
if name is None:
name = self.name
if self.name is None:
raise ValueError, "DeviceMap name is not set"
self.map = _dm.map(name = self.name, uuid=self.uuid,
table = self.table)
del _dm
del _device
class LinearDeviceMap(DeviceMap):
"""map for dm-linear"""
def __init__(self, start, size, bdev, offset):
DeviceMap.__init__(self, start, size, "linear")
self.start = start
self.size = size
self.devices = (bdev,)
self.offset = offset
def _format_linear(self):
return "%s %s" % (self.devices[0].dmdev, self.offset)
class PartitionDeviceMap(LinearDeviceMap):
"""map for a partition on a dm device"""
def __init__(self, start, size, bdev, offset, id):
LinearDeviceMap.__init__(self, start, size, bdev, offset)
self.id = id
class MirrorDeviceMap(DeviceMap):
"""map for a dm based raid1"""
def __init__(self, start, size, *devices):
DeviceMap.__init__(self, start, size, "mirror", ["dm-mirror"])
self.start = start
self.size = size
self.log = CoreLog(512, True)
self.parents = devices
def _format_mirror(self):
import string as _string
rc = "%s %s %s" % (self.log, len(self.parents), \
_string.join(map(lambda x: x.dmdev, self.parents)))
del _string
class StripeDeviceMap(DeviceMap):
"""map for a dm based raid0"""
def __init__(self, start, size, stripes, chunksize, *devices):
"""\
start = start address for resulting device
size = size of the map
stripes = number of stripes
chunksize = stripe width
devices = devices to use
"""
DeviceMap.__init__(self, start, size, "striped")
self.start = start
self.size = size
self.stripes = stripes
self.chunksize = chunksize
self.parents = devices
# sample: "0 625163520 striped 2 128 8:16 0 8:32 0"
def _format_stripe(self):
import string as _string
rc = "%s %s %s" % (self.stripes, self.chunksize,
_string.join(map(lambda x: x.dmdev, self.parents)))
del _string
# from dm-multipath.c:
#-----------------------------------------------------------------
# Constructor/argument parsing:
# <#multipath feature args> [<arg>]*
# <#hw_handler args> [hw_handler [<arg>]*]
# <#priority groups>
# <initial priority group>
# [<selector> <#selector args> [<arg>]*
# <#paths> <#per-path selector args>
# [<path> [<arg>]* ]+ ]+
#-----------------------------------------------------------------
# from pj's create-testbed.sh:
# dd if=/dev/zero of=device_data bs=$((1024**2)) count=513
# losetup /dev/loop0 device_data
# losetup /dev/loop1 device_data
#
# parted /dev/loop0 -s mklabel msdos
# parted /dev/loop0 -s mkpart primary ext3 1 257
# parted /dev/loop0 -s mkpart primary ext3 257 513
#
# dmsetup create mp00 << EOF
# 0 1050623 multipath 0 0 1 1 round-robin 0 2 0 /dev/loop0 /dev/loop1
# EOF
# some annotation:
#
# 0 1050623 multipath 0 0 1 1 round-robin 0 2 0 /dev/loop0 /dev/loop1
# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
# | | | | | | | | | | | | path1
# | | | | | | | | | | | path 0
# | | | | | | | | | | # path selector args
# | | | | | | | | | # paths
# | | | | | | | | # selector args
# | | | | | | | path selector
# | | | | | | initial priority group
# | | | | | number of priority groups
# | | | | # hw handler args
# | | | # multipath feature args
# | | dm type
# | size
# start
#
# path selector args:
# round-robin:
# 0 2 0 /dev/loop0 /dev/loop1
# all as above
#
# 0 2 1 /dev/loop0 1000 /dev/loop1 1000
# ^ ^ ^ ^ ^
# | | | | |
# | | | | # IOs before switching
# | | | path name
# | | # IOs before switching
# | path name
# one arg per path
# right now this doesn't support very broad configuration options
class MultipathDeviceMap(DeviceMap):
"""map for a multipath device"""
def __init__(self, start, size, paths, uuid=None):
DeviceMap.__init__(self, start, size, "multipath", \
["dm-mirror", "dm-round-robin"])
self.start = start
self.size = size
self.parents = paths
self.uuid = uuid
def _format_multipath(self):
import string as _string
rc = "0 0 1 1 round-robin 0 %s 1 %s" % (len(self.parents),
_string.join(map(lambda x: "%s 1000" % (x.dmdev,),
self.parents)))
del _string
class LVMDeviceMap(DeviceMap):
"""map for lvm device"""
pass
class MDDevice(DeviceMap):
"""map for lvm device"""
pass
class DMTable:
def __init__(self):
pass
#
# vim:ts=8:sts=4:sw=8:et
#