HEX
Server: Apache
System: Linux wp02.tdr-lab.com 3.10.0-1160.42.2.el7.x86_64 #1 SMP Tue Sep 7 14:49:57 UTC 2021 x86_64
User: kusanagi (1001)
PHP: 7.4.23
Disabled: NONE
Upload Files
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
#