Revision b6135bbc lib/bdev.py

b/lib/bdev.py
24 24
import re
25 25
import time
26 26
import errno
27
import stat
27 28
import pyparsing as pyp
28 29
import os
29 30
import logging
......
2069 2070
    return FileStorage(unique_id, children, size)
2070 2071

  
2071 2072

  
2073
class PersistentBlockDevice(BlockDev):
2074
  """A block device with persistent node
2075

  
2076
  May be either directly attached, or exposed through DM (e.g. dm-multipath).
2077
  udev helpers are probably required to give persistent, human-friendly
2078
  names.
2079

  
2080
  For the time being, pathnames are required to lie under /dev.
2081

  
2082
  """
2083
  def __init__(self, unique_id, children, size):
2084
    """Attaches to a static block device.
2085

  
2086
    The unique_id is a path under /dev.
2087

  
2088
    """
2089
    super(PersistentBlockDevice, self).__init__(unique_id, children, size)
2090
    if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2:
2091
      raise ValueError("Invalid configuration data %s" % str(unique_id))
2092
    self.dev_path = unique_id[1]
2093
    if not os.path.realpath(self.dev_path).startswith('/dev/'):
2094
      raise ValueError("Full path '%s' lies outside /dev" %
2095
                              os.path.realpath(self.dev_path))
2096
    # TODO: this is just a safety guard checking that we only deal with devices
2097
    # we know how to handle. In the future this will be integrated with
2098
    # external storage backends and possible values will probably be collected
2099
    # from the cluster configuration.
2100
    if unique_id[0] != constants.BLOCKDEV_DRIVER_MANUAL:
2101
      raise ValueError("Got persistent block device of invalid type: %s" %
2102
                       unique_id[0])
2103

  
2104
    self.major = self.minor = None
2105
    self.Attach()
2106

  
2107
  @classmethod
2108
  def Create(cls, unique_id, children, size):
2109
    """Create a new device
2110

  
2111
    This is a noop, we only return a PersistentBlockDevice instance
2112

  
2113
    """
2114
    return PersistentBlockDevice(unique_id, children, 0)
2115

  
2116
  def Remove(self):
2117
    """Remove a device
2118

  
2119
    This is a noop
2120

  
2121
    """
2122
    pass
2123

  
2124
  def Rename(self, new_id):
2125
    """Rename this device.
2126

  
2127
    """
2128
    _ThrowError("Rename is not supported for PersistentBlockDev storage")
2129

  
2130
  def Attach(self):
2131
    """Attach to an existing block device.
2132

  
2133

  
2134
    """
2135
    self.attached = False
2136
    try:
2137
      st = os.stat(self.dev_path)
2138
    except OSError, err:
2139
      logging.error("Error stat()'ing %s: %s", self.dev_path, str(err))
2140
      return False
2141

  
2142
    if not stat.S_ISBLK(st.st_mode):
2143
      logging.error("%s is not a block device", self.dev_path)
2144
      return False
2145

  
2146
    self.major = os.major(st.st_rdev)
2147
    self.minor = os.minor(st.st_rdev)
2148
    self.attached = True
2149

  
2150
    return True
2151

  
2152
  def Assemble(self):
2153
    """Assemble the device.
2154

  
2155
    """
2156
    pass
2157

  
2158
  def Shutdown(self):
2159
    """Shutdown the device.
2160

  
2161
    """
2162
    pass
2163

  
2164
  def Open(self, force=False):
2165
    """Make the device ready for I/O.
2166

  
2167
    """
2168
    pass
2169

  
2170
  def Close(self):
2171
    """Notifies that the device will no longer be used for I/O.
2172

  
2173
    """
2174
    pass
2175

  
2176
  def Grow(self, amount):
2177
    """Grow the logical volume.
2178

  
2179
    """
2180
    _ThrowError("Grow is not supported for PersistentBlockDev storage")
2181

  
2182

  
2072 2183
DEV_MAP = {
2073 2184
  constants.LD_LV: LogicalVolume,
2074 2185
  constants.LD_DRBD8: DRBD8,
2186
  constants.LD_BLOCKDEV: PersistentBlockDevice,
2075 2187
  }
2076 2188

  
2077 2189
if constants.ENABLE_FILE_STORAGE or constants.ENABLE_SHARED_FILE_STORAGE:

Also available in: Unified diff