Skip to content

Device Mapper

This section documents the Device Mapper functionality, which provides interfaces for working with Linux's device-mapper framework.

Device Mapper Core

sts.dm

Device Mapper device management.

This module provides functionality for managing Device Mapper devices: - Device discovery - Device information - Device operations - Device Mapper targets

Device Mapper is a Linux kernel framework for mapping physical block devices onto higher-level virtual block devices. It forms the foundation for (example): - LVM (Logical Volume Management) - Software RAID (dm-raid) - Disk encryption (dm-crypt) - Thin provisioning (dm-thin)

DelayTarget dataclass

Bases: DmTarget

Delay target.

Delays I/O operations by a specified amount. Useful for testing how applications handle slow devices.

Args format:

Example
target = DelayTarget(0, 1000000, '253:0 0 100')  # 100ms delay
str(target)
'0 1000000 delay 253:0 0 100'
Source code in sts_libs/src/sts/dm.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
@dataclass
class DelayTarget(DmTarget):
    """Delay target.

    Delays I/O operations by a specified amount. Useful for testing
    how applications handle slow devices.

    Args format: <device> <offset> <delay in milliseconds>

    Example:
        ```python
        target = DelayTarget(0, 1000000, '253:0 0 100')  # 100ms delay
        str(target)
        '0 1000000 delay 253:0 0 100'
        ```
    """

DmDevice dataclass

Bases: StorageDevice

Device Mapper device representation.

A Device Mapper device is a virtual block device that maps to one or more physical devices through a table of targets.

Parameters:

Name Type Description Default
name str | None

Device name (optional, e.g. 'dm-0')

None
path Path | str | None

Device path (optional, defaults to /dev/)

None
size int | None

Device size in bytes (optional, discovered from device)

None
dm_name str | None

Device Mapper name (optional, discovered from device)

None
model str | None

Device model (optional)

None
uuid str | None

Device UUID (optional)

None
Example
device = DmDevice('dm-0')  # Create from kernel name
device = DmDevice(dm_name='vg-lv')  # Create from mapper name
Source code in sts_libs/src/sts/dm.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
@dataclass
class DmDevice(StorageDevice):
    """Device Mapper device representation.

    A Device Mapper device is a virtual block device that maps to one or
    more physical devices through a table of targets.

    Args:
        name: Device name (optional, e.g. 'dm-0')
        path: Device path (optional, defaults to /dev/<name>)
        size: Device size in bytes (optional, discovered from device)
        dm_name: Device Mapper name (optional, discovered from device)
        model: Device model (optional)
        uuid: Device UUID (optional)

    Example:
        ```python
        device = DmDevice('dm-0')  # Create from kernel name
        device = DmDevice(dm_name='vg-lv')  # Create from mapper name
        ```
    """

    # Optional parameters from parent classes
    name: str | None = None
    path: Path | str | None = None
    size: int | None = None
    model: str | None = None

    # Optional parameters for this class
    dm_name: str | None = None  # Mapper name (e.g. 'vg-lv')
    uuid: str | None = None  # Unique identifier

    # Internal fields
    _table: str | None = field(init=False, default=None)

    # Class-level paths
    DM_PATH: ClassVar[Path] = Path('/sys/class/block')  # Sysfs block devices
    DM_DEV_PATH: ClassVar[Path] = Path('/dev/mapper')  # Device nodes

    def __post_init__(self) -> None:
        """Initialize Device Mapper device.

        - Sets device path if not provided
        - Discovers mapper name if not provided
        - Loads device table

        Raises:
            DeviceNotFoundError: If device does not exist
            DeviceError: If device cannot be accessed
        """
        # Set path based on name if not provided
        if not self.path and self.name:
            self.path = f'/dev/{self.name}'

        # Initialize parent class
        super().__post_init__()

        # Get device mapper name if not provided
        if not self.dm_name and self.name:
            result = run(f'dmsetup info -c --noheadings -o name {self.name}')
            if result.succeeded:
                self.dm_name = result.stdout.strip()

        # Get device table (defines how I/O is mapped)
        if self.dm_name:
            result = run(f'dmsetup table {self.dm_name}')
            if result.succeeded:
                self._table = result.stdout.strip()

    @property
    def device_path(self) -> Path:
        """Get path to device in sysfs.

        The sysfs path provides access to device attributes and statistics.

        Returns:
            Path to device directory

        Raises:
            DeviceNotFoundError: If device does not exist

        Example:
            ```python
            device.device_path
            PosixPath('/sys/class/block/dm-0')
            ```
        """
        if not self.name:
            msg = 'Device name not available'
            raise DeviceNotFoundError(msg)

        path = self.DM_PATH / self.name
        if not path.exists():
            msg = f'Device {self.name} not found'
            raise DeviceNotFoundError(msg)
        return path

    @property
    def table(self) -> str | None:
        """Get device table.

        The table defines how I/O requests are mapped to underlying devices.
        Format: <start sector> <length> <target type> <target args>

        Returns:
            Device table string or None if not available

        Example:
            ```python
            device.table
            '0 209715200 linear 253:0 0'
            ```
        """
        return self._table

    def suspend(self) -> bool:
        """Suspend device.

        Suspends I/O to the device. Required before changing the device table.
        Outstanding I/O will be queued until the device is resumed.

        Returns:
            True if successful, False otherwise

        Example:
            ```python
            device.suspend()
            True
            ```
        """
        if not self.dm_name:
            logging.error('Device mapper name not available')
            return False

        result = run(f'dmsetup suspend {self.dm_name}')
        if result.failed:
            logging.error('Failed to suspend device')
            return False
        return True

    def resume(self) -> bool:
        """Resume device.

        Resumes I/O to the device after suspension.
        Queued I/O will be processed.

        Returns:
            True if successful, False otherwise

        Example:
            ```python
            device.resume()
            True
            ```
        """
        if not self.dm_name:
            logging.error('Device mapper name not available')
            return False

        result = run(f'dmsetup resume {self.dm_name}')
        if result.failed:
            logging.error('Failed to resume device')
            return False
        return True

    def remove(self) -> bool:
        """Remove device.

        Removes the device mapping. The underlying devices are unaffected.
        Device must not be in use (mounted, etc).

        Returns:
            True if successful, False otherwise

        Example:
            ```python
            device.remove()
            True
            ```
        """
        if not self.dm_name:
            logging.error('Device mapper name not available')
            return False

        result = run(f'dmsetup remove {self.dm_name}')
        if result.failed:
            logging.error('Failed to remove device')
            return False
        return True

    @classmethod
    def get_all(cls) -> Sequence[DmDevice]:
        """Get list of all Device Mapper devices.

        Lists all active device-mapper devices on the system.
        Currently only lists linear targets.

        Returns:
            List of DmDevice instances

        Example:
            ```python
            DmDevice.get_all()
            [DmDevice(name='dm-0', ...), DmDevice(name='dm-1', ...)]
            ```
        """
        devices = []
        # List only linear targets for now
        result = run('dmsetup ls --target linear')
        if result.failed:
            logging.warning('No Device Mapper devices found')
            return []

        for line in result.stdout.splitlines():
            try:
                # Parse line like: vg-lv (253:0)
                dm_name, dev_id = line.split()
                dev_id = dev_id.strip('()')
                major, minor = dev_id.split(':')

                # Get kernel device name (dm-N)
                result = run(f'ls -l /dev/dm-* | grep "{major}, *{minor}"')
                if result.failed:
                    continue
                name = result.stdout.split('/')[-1].strip()

                # Get device UUID for identification
                result = run(f'dmsetup info -c --noheadings -o uuid {dm_name}')
                uuid = result.stdout.strip() if result.succeeded else None

                devices.append(cls(name=name, dm_name=dm_name, uuid=uuid))
            except (ValueError, DeviceError):
                logging.exception('Failed to parse device info')
                continue

        return devices

    @classmethod
    def get_by_name(cls, dm_name: str) -> DmDevice | None:
        """Get Device Mapper device by name.

        Finds a device by its mapper name (e.g. 'vg-lv').
        More user-friendly than using kernel names (dm-N).

        Args:
            dm_name: Device Mapper name (e.g. 'vg-lv')

        Returns:
            DmDevice instance or None if not found

        Example:
            ```python
            DmDevice.get_by_name('vg-lv')
            DmDevice(name='dm-0', ...)
            ```
        """
        if not dm_name:
            msg = 'Device Mapper name required'
            raise ValueError(msg)

        for device in cls.get_all():
            if device.dm_name == dm_name:
                return device

        return None

device_path: Path property

Get path to device in sysfs.

The sysfs path provides access to device attributes and statistics.

Returns:

Type Description
Path

Path to device directory

Raises:

Type Description
DeviceNotFoundError

If device does not exist

Example
device.device_path
PosixPath('/sys/class/block/dm-0')

table: str | None property

Get device table.

The table defines how I/O requests are mapped to underlying devices. Format:

Returns:

Type Description
str | None

Device table string or None if not available

Example
device.table
'0 209715200 linear 253:0 0'

__post_init__()

Initialize Device Mapper device.

  • Sets device path if not provided
  • Discovers mapper name if not provided
  • Loads device table

Raises:

Type Description
DeviceNotFoundError

If device does not exist

DeviceError

If device cannot be accessed

Source code in sts_libs/src/sts/dm.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
def __post_init__(self) -> None:
    """Initialize Device Mapper device.

    - Sets device path if not provided
    - Discovers mapper name if not provided
    - Loads device table

    Raises:
        DeviceNotFoundError: If device does not exist
        DeviceError: If device cannot be accessed
    """
    # Set path based on name if not provided
    if not self.path and self.name:
        self.path = f'/dev/{self.name}'

    # Initialize parent class
    super().__post_init__()

    # Get device mapper name if not provided
    if not self.dm_name and self.name:
        result = run(f'dmsetup info -c --noheadings -o name {self.name}')
        if result.succeeded:
            self.dm_name = result.stdout.strip()

    # Get device table (defines how I/O is mapped)
    if self.dm_name:
        result = run(f'dmsetup table {self.dm_name}')
        if result.succeeded:
            self._table = result.stdout.strip()

get_all() classmethod

Get list of all Device Mapper devices.

Lists all active device-mapper devices on the system. Currently only lists linear targets.

Returns:

Type Description
Sequence[DmDevice]

List of DmDevice instances

Example
DmDevice.get_all()
[DmDevice(name='dm-0', ...), DmDevice(name='dm-1', ...)]
Source code in sts_libs/src/sts/dm.py
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
@classmethod
def get_all(cls) -> Sequence[DmDevice]:
    """Get list of all Device Mapper devices.

    Lists all active device-mapper devices on the system.
    Currently only lists linear targets.

    Returns:
        List of DmDevice instances

    Example:
        ```python
        DmDevice.get_all()
        [DmDevice(name='dm-0', ...), DmDevice(name='dm-1', ...)]
        ```
    """
    devices = []
    # List only linear targets for now
    result = run('dmsetup ls --target linear')
    if result.failed:
        logging.warning('No Device Mapper devices found')
        return []

    for line in result.stdout.splitlines():
        try:
            # Parse line like: vg-lv (253:0)
            dm_name, dev_id = line.split()
            dev_id = dev_id.strip('()')
            major, minor = dev_id.split(':')

            # Get kernel device name (dm-N)
            result = run(f'ls -l /dev/dm-* | grep "{major}, *{minor}"')
            if result.failed:
                continue
            name = result.stdout.split('/')[-1].strip()

            # Get device UUID for identification
            result = run(f'dmsetup info -c --noheadings -o uuid {dm_name}')
            uuid = result.stdout.strip() if result.succeeded else None

            devices.append(cls(name=name, dm_name=dm_name, uuid=uuid))
        except (ValueError, DeviceError):
            logging.exception('Failed to parse device info')
            continue

    return devices

get_by_name(dm_name) classmethod

Get Device Mapper device by name.

Finds a device by its mapper name (e.g. 'vg-lv'). More user-friendly than using kernel names (dm-N).

Parameters:

Name Type Description Default
dm_name str

Device Mapper name (e.g. 'vg-lv')

required

Returns:

Type Description
DmDevice | None

DmDevice instance or None if not found

Example
DmDevice.get_by_name('vg-lv')
DmDevice(name='dm-0', ...)
Source code in sts_libs/src/sts/dm.py
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
@classmethod
def get_by_name(cls, dm_name: str) -> DmDevice | None:
    """Get Device Mapper device by name.

    Finds a device by its mapper name (e.g. 'vg-lv').
    More user-friendly than using kernel names (dm-N).

    Args:
        dm_name: Device Mapper name (e.g. 'vg-lv')

    Returns:
        DmDevice instance or None if not found

    Example:
        ```python
        DmDevice.get_by_name('vg-lv')
        DmDevice(name='dm-0', ...)
        ```
    """
    if not dm_name:
        msg = 'Device Mapper name required'
        raise ValueError(msg)

    for device in cls.get_all():
        if device.dm_name == dm_name:
            return device

    return None

remove()

Remove device.

Removes the device mapping. The underlying devices are unaffected. Device must not be in use (mounted, etc).

Returns:

Type Description
bool

True if successful, False otherwise

Example
device.remove()
True
Source code in sts_libs/src/sts/dm.py
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
def remove(self) -> bool:
    """Remove device.

    Removes the device mapping. The underlying devices are unaffected.
    Device must not be in use (mounted, etc).

    Returns:
        True if successful, False otherwise

    Example:
        ```python
        device.remove()
        True
        ```
    """
    if not self.dm_name:
        logging.error('Device mapper name not available')
        return False

    result = run(f'dmsetup remove {self.dm_name}')
    if result.failed:
        logging.error('Failed to remove device')
        return False
    return True

resume()

Resume device.

Resumes I/O to the device after suspension. Queued I/O will be processed.

Returns:

Type Description
bool

True if successful, False otherwise

Example
device.resume()
True
Source code in sts_libs/src/sts/dm.py
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
def resume(self) -> bool:
    """Resume device.

    Resumes I/O to the device after suspension.
    Queued I/O will be processed.

    Returns:
        True if successful, False otherwise

    Example:
        ```python
        device.resume()
        True
        ```
    """
    if not self.dm_name:
        logging.error('Device mapper name not available')
        return False

    result = run(f'dmsetup resume {self.dm_name}')
    if result.failed:
        logging.error('Failed to resume device')
        return False
    return True

suspend()

Suspend device.

Suspends I/O to the device. Required before changing the device table. Outstanding I/O will be queued until the device is resumed.

Returns:

Type Description
bool

True if successful, False otherwise

Example
device.suspend()
True
Source code in sts_libs/src/sts/dm.py
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
def suspend(self) -> bool:
    """Suspend device.

    Suspends I/O to the device. Required before changing the device table.
    Outstanding I/O will be queued until the device is resumed.

    Returns:
        True if successful, False otherwise

    Example:
        ```python
        device.suspend()
        True
        ```
    """
    if not self.dm_name:
        logging.error('Device mapper name not available')
        return False

    result = run(f'dmsetup suspend {self.dm_name}')
    if result.failed:
        logging.error('Failed to suspend device')
        return False
    return True

DmTarget dataclass

Base class for Device Mapper targets.

Device Mapper targets define how I/O operations are processed. Each target maps a range of the virtual device to one or more physical devices, optionally transforming the I/O in some way.

Parameters:

Name Type Description Default
start int

Start sector (where this target begins)

required
size int

Size in sectors (length of this target)

required
args str

Target-specific arguments (e.g. device paths, options)

required
Source code in sts_libs/src/sts/dm.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@dataclass
class DmTarget:
    """Base class for Device Mapper targets.

    Device Mapper targets define how I/O operations are processed.
    Each target maps a range of the virtual device to one or more
    physical devices, optionally transforming the I/O in some way.

    Args:
        start: Start sector (where this target begins)
        size: Size in sectors (length of this target)
        args: Target-specific arguments (e.g. device paths, options)
    """

    start: int
    size: int
    args: str

    @property
    def type(self) -> str:
        """Get target type.

        Returns:
            Target type string (e.g. 'linear', 'thin-pool')
        """
        # Remove 'target' suffix from class name and convert to lowercase
        return self.__class__.__name__.lower().removesuffix('target')

    def __str__(self) -> str:
        """Return target table entry.

        Format: <start> <size> <type> <args>
        Used in dmsetup table commands.
        """
        return f'{self.start} {self.size} {self.type} {self.args}'

type: str property

Get target type.

Returns:

Type Description
str

Target type string (e.g. 'linear', 'thin-pool')

__str__()

Return target table entry.

Format: Used in dmsetup table commands.

Source code in sts_libs/src/sts/dm.py
63
64
65
66
67
68
69
def __str__(self) -> str:
    """Return target table entry.

    Format: <start> <size> <type> <args>
    Used in dmsetup table commands.
    """
    return f'{self.start} {self.size} {self.type} {self.args}'

LinearTarget dataclass

Bases: DmTarget

Linear target.

The simplest target type - maps a linear range of the virtual device directly onto a linear range of another device.

Args format:

Example
target = LinearTarget(0, 1000000, '253:0 0')  # Map to device 253:0 starting at sector 0
str(target)
'0 1000000 linear 253:0 0'
Source code in sts_libs/src/sts/dm.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@dataclass
class LinearTarget(DmTarget):
    """Linear target.

    The simplest target type - maps a linear range of the virtual device
    directly onto a linear range of another device.

    Args format: <destination device> <sector offset>

    Example:
        ```python
        target = LinearTarget(0, 1000000, '253:0 0')  # Map to device 253:0 starting at sector 0
        str(target)
        '0 1000000 linear 253:0 0'
        ```
    """

MultipathTarget dataclass

Bases: DmTarget

Multipath target.

Provides I/O failover across multiple paths to the same device. Used for high availability storage configurations.

Args format: <# of feature args> <# of paths>

Example
# Round-robin across two paths with queue_if_no_path
target = MultipathTarget(0, 1000000, '2 1 round-robin 0 2 1 8:32 1000 8:48 1000')
str(target)
'0 1000000 multipath 2 1 round-robin 0 2 1 8:32 1000 8:48 1000'
Source code in sts_libs/src/sts/dm.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
@dataclass
class MultipathTarget(DmTarget):
    """Multipath target.

    Provides I/O failover across multiple paths to the same device.
    Used for high availability storage configurations.

    Args format: <# of feature args> <# of paths> <features...> <path specs...>

    Example:
        ```python
        # Round-robin across two paths with queue_if_no_path
        target = MultipathTarget(0, 1000000, '2 1 round-robin 0 2 1 8:32 1000 8:48 1000')
        str(target)
        '0 1000000 multipath 2 1 round-robin 0 2 1 8:32 1000 8:48 1000'
        ```
    """

ThinPoolTarget dataclass

Bases: DmTarget

Thin pool target.

Manages a pool of storage space from which thin volumes can be allocated. Enables thin provisioning - allocating more virtual space than physical.

Args format:

Example
# Pool with 128 sector blocks and 32768 low water mark
target = ThinPoolTarget(0, 1000000, '253:0 253:1 128 32768 1 skip_block_zeroing')
str(target)
'0 1000000 thin-pool 253:0 253:1 128 32768 1 skip_block_zeroing'
Source code in sts_libs/src/sts/dm.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
@dataclass
class ThinPoolTarget(DmTarget):
    """Thin pool target.

    Manages a pool of storage space from which thin volumes can be allocated.
    Enables thin provisioning - allocating more virtual space than physical.

    Args format: <metadata dev> <data dev> <block size> <low water mark> <flags> <args>

    Example:
        ```python
        # Pool with 128 sector blocks and 32768 low water mark
        target = ThinPoolTarget(0, 1000000, '253:0 253:1 128 32768 1 skip_block_zeroing')
        str(target)
        '0 1000000 thin-pool 253:0 253:1 128 32768 1 skip_block_zeroing'
        ```
    """

ThinTarget dataclass

Bases: DmTarget

Thin target.

A virtual device that allocates space from a thin pool on demand. Enables over-provisioning of storage.

Args format:

Example
target = ThinTarget(0, 1000000, '253:0 1')  # Device 1 from pool 253:0
str(target)
'0 1000000 thin 253:0 1'
Source code in sts_libs/src/sts/dm.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@dataclass
class ThinTarget(DmTarget):
    """Thin target.

    A virtual device that allocates space from a thin pool on demand.
    Enables over-provisioning of storage.

    Args format: <pool dev> <dev id>

    Example:
        ```python
        target = ThinTarget(0, 1000000, '253:0 1')  # Device 1 from pool 253:0
        str(target)
        '0 1000000 thin 253:0 1'
        ```
    """

Device Mapper Persistent Data

sts.dmpd

Device Mapper Persistent Data (DMPD) tools management.

This module provides functionality for managing Device Mapper Persistent Data tools. Each tool is a separate command-line utility for managing metadata of device-mapper targets:

Cache Tools: - cache_check: Check cache metadata integrity - cache_dump: Dump cache metadata to file or stdout - cache_repair: Repair corrupted cache metadata - cache_restore: Restore cache metadata from backup - cache_metadata_size: Calculate cache metadata size requirements

Thin Tools: - thin_check: Check thin provisioning metadata integrity - thin_dump: Dump thin metadata to file or stdout - thin_repair: Repair corrupted thin metadata - thin_restore: Restore thin metadata from backup - thin_metadata_size: Calculate thin metadata size requirements - thin_trim: Trim thin metadata

Era Tools: - era_check: Check era metadata integrity - era_dump: Dump era metadata to file or stdout - era_repair: Repair corrupted era metadata - era_restore: Restore era metadata from backup

Each tool operates independently and can work with various device sources: - Block devices (/dev/sdX, /dev/mapper/*, /dev/vg/lv) - Regular files (metadata dumps) - Device mapper devices

CacheCheck

Bases: DmpdTool

Check cache metadata integrity.

Usage: cache_check [options] {device|file}

For available options, see: cache_check --help

Source code in sts_libs/src/sts/dmpd.py
119
120
121
122
123
124
125
126
127
class CacheCheck(DmpdTool):
    """Check cache metadata integrity.

    Usage: cache_check [options] {device|file}

    For available options, see: cache_check --help
    """

    TOOL_NAME = 'cache_check'

CacheDump

Bases: DmpdTool

Dump cache metadata to stdout or file.

Usage: cache_dump [options] {device|file}

For available options, see: cache_dump --help

Source code in sts_libs/src/sts/dmpd.py
130
131
132
133
134
135
136
137
138
class CacheDump(DmpdTool):
    """Dump cache metadata to stdout or file.

    Usage: cache_dump [options] {device|file}

    For available options, see: cache_dump --help
    """

    TOOL_NAME = 'cache_dump'

CacheMetadataSize

Bases: DmpdTool

Calculate cache metadata size requirements.

Usage: cache_metadata_size [options]

For available options, see: cache_metadata_size --help

Source code in sts_libs/src/sts/dmpd.py
163
164
165
166
167
168
169
170
171
class CacheMetadataSize(DmpdTool):
    """Calculate cache metadata size requirements.

    Usage: cache_metadata_size [options]

    For available options, see: cache_metadata_size --help
    """

    TOOL_NAME = 'cache_metadata_size'

CacheRepair

Bases: DmpdTool

Repair corrupted cache metadata.

Usage: cache_repair [options] --input {device|file} --output {device|file}

For available options, see: cache_repair --help

Source code in sts_libs/src/sts/dmpd.py
141
142
143
144
145
146
147
148
149
class CacheRepair(DmpdTool):
    """Repair corrupted cache metadata.

    Usage: cache_repair [options] --input {device|file} --output {device|file}

    For available options, see: cache_repair --help
    """

    TOOL_NAME = 'cache_repair'

CacheRestore

Bases: DmpdTool

Restore cache metadata from backup.

Usage: cache_restore [options] --input --output {device|file}

For available options, see: cache_restore --help

Source code in sts_libs/src/sts/dmpd.py
152
153
154
155
156
157
158
159
160
class CacheRestore(DmpdTool):
    """Restore cache metadata from backup.

    Usage: cache_restore [options] --input <file> --output {device|file}

    For available options, see: cache_restore --help
    """

    TOOL_NAME = 'cache_restore'

DmpdTool

Bases: ABC

Base class for DMPD command-line tools.

Each DMPD tool is a separate command-line utility that can operate on: - Block devices (LVM logical volumes, raw devices) - Regular files (metadata dump files) - Device mapper devices

Source code in sts_libs/src/sts/dmpd.py
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class DmpdTool(ABC):
    """Base class for DMPD command-line tools.

    Each DMPD tool is a separate command-line utility that can operate on:
    - Block devices (LVM logical volumes, raw devices)
    - Regular files (metadata dump files)
    - Device mapper devices
    """

    # Tool name (must be set by subclasses)
    TOOL_NAME: ClassVar[str]

    @staticmethod
    def _build_command(cmd: str, device_or_file: str | Path | None = None, **options: CommandOption) -> str:
        """Build DMPD command string with options.

        Args:
            cmd: Command name (e.g., 'cache_check')
            device_or_file: Device path or file path
            **options: Command options

        Returns:
            Complete command string
        """
        command_parts = [cmd]

        # Add device/file path if provided
        if device_or_file:
            command_parts.append(str(device_or_file))

        # Add options
        for option_key, value in options.items():
            if value is not None:
                key = option_key.replace('_', '-')
                if isinstance(value, bool) and value:
                    command_parts.append(f'--{key}')
                else:
                    command_parts.append(f'--{key}={value!s}')

        return ' '.join(command_parts)

    @classmethod
    def run(cls, device_or_file: str | Path | None = None, **options: CommandOption) -> CommandResult:
        """Run the DMPD tool with specified options.

        Args:
            device_or_file: Device path or file path to operate on
            **options: Tool-specific options

        Returns:
            Command result
        """
        cmd = cls._build_command(cls.TOOL_NAME, device_or_file, **options)
        return run(cmd)

    @classmethod
    def help(cls) -> CommandResult:
        """Get help information for the tool."""
        return run(f'{cls.TOOL_NAME} --help')

    @classmethod
    def version(cls) -> CommandResult:
        """Get version information for the tool."""
        return run(f'{cls.TOOL_NAME} --version')

help() classmethod

Get help information for the tool.

Source code in sts_libs/src/sts/dmpd.py
105
106
107
108
@classmethod
def help(cls) -> CommandResult:
    """Get help information for the tool."""
    return run(f'{cls.TOOL_NAME} --help')

run(device_or_file=None, **options) classmethod

Run the DMPD tool with specified options.

Parameters:

Name Type Description Default
device_or_file str | Path | None

Device path or file path to operate on

None
**options CommandOption

Tool-specific options

{}

Returns:

Type Description
CommandResult

Command result

Source code in sts_libs/src/sts/dmpd.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
@classmethod
def run(cls, device_or_file: str | Path | None = None, **options: CommandOption) -> CommandResult:
    """Run the DMPD tool with specified options.

    Args:
        device_or_file: Device path or file path to operate on
        **options: Tool-specific options

    Returns:
        Command result
    """
    cmd = cls._build_command(cls.TOOL_NAME, device_or_file, **options)
    return run(cmd)

version() classmethod

Get version information for the tool.

Source code in sts_libs/src/sts/dmpd.py
110
111
112
113
@classmethod
def version(cls) -> CommandResult:
    """Get version information for the tool."""
    return run(f'{cls.TOOL_NAME} --version')

EraCheck

Bases: DmpdTool

Check era metadata integrity.

Usage: era_check [options] {device|file}

For available options, see: era_check --help

Source code in sts_libs/src/sts/dmpd.py
268
269
270
271
272
273
274
275
276
class EraCheck(DmpdTool):
    """Check era metadata integrity.

    Usage: era_check [options] {device|file}

    For available options, see: era_check --help
    """

    TOOL_NAME = 'era_check'

EraDump

Bases: DmpdTool

Dump era metadata to stdout or file.

Usage: era_dump [options] {device|file}

For available options, see: era_dump --help

Source code in sts_libs/src/sts/dmpd.py
279
280
281
282
283
284
285
286
287
class EraDump(DmpdTool):
    """Dump era metadata to stdout or file.

    Usage: era_dump [options] {device|file}

    For available options, see: era_dump --help
    """

    TOOL_NAME = 'era_dump'

EraRepair

Bases: DmpdTool

Repair corrupted era metadata.

Usage: era_repair [options] --input {device|file} --output {device|file}

For available options, see: era_repair --help

Source code in sts_libs/src/sts/dmpd.py
290
291
292
293
294
295
296
297
298
class EraRepair(DmpdTool):
    """Repair corrupted era metadata.

    Usage: era_repair [options] --input {device|file} --output {device|file}

    For available options, see: era_repair --help
    """

    TOOL_NAME = 'era_repair'

EraRestore

Bases: DmpdTool

Restore era metadata from backup.

Usage: era_restore [options] --input --output {device|file}

For available options, see: era_restore --help

Source code in sts_libs/src/sts/dmpd.py
301
302
303
304
305
306
307
308
309
class EraRestore(DmpdTool):
    """Restore era metadata from backup.

    Usage: era_restore [options] --input <file> --output {device|file}

    For available options, see: era_restore --help
    """

    TOOL_NAME = 'era_restore'

ThinCheck

Bases: DmpdTool

Check thin provisioning metadata integrity.

Usage: thin_check [options] {device|file}

For available options, see: thin_check --help

Source code in sts_libs/src/sts/dmpd.py
177
178
179
180
181
182
183
184
185
class ThinCheck(DmpdTool):
    """Check thin provisioning metadata integrity.

    Usage: thin_check [options] {device|file}

    For available options, see: thin_check --help
    """

    TOOL_NAME = 'thin_check'

ThinDelta

Bases: DmpdTool

Print differences between thin devices.

Usage: thin_delta [options]

For available options, see: thin_delta --help

Source code in sts_libs/src/sts/dmpd.py
254
255
256
257
258
259
260
261
262
class ThinDelta(DmpdTool):
    """Print differences between thin devices.

    Usage: thin_delta [options] <input>

    For available options, see: thin_delta --help
    """

    TOOL_NAME = 'thin_delta'

ThinDump

Bases: DmpdTool

Dump thin metadata to stdout or file.

Usage: thin_dump [options] {device|file}

For available options, see: thin_dump --help

Source code in sts_libs/src/sts/dmpd.py
188
189
190
191
192
193
194
195
196
class ThinDump(DmpdTool):
    """Dump thin metadata to stdout or file.

    Usage: thin_dump [options] {device|file}

    For available options, see: thin_dump --help
    """

    TOOL_NAME = 'thin_dump'

ThinLs

Bases: DmpdTool

List thin devices.

Usage: thin_ls [options] {device|file}

For available options, see: thin_ls --help

Source code in sts_libs/src/sts/dmpd.py
243
244
245
246
247
248
249
250
251
class ThinLs(DmpdTool):
    """List thin devices.

    Usage: thin_ls [options] {device|file}

    For available options, see: thin_ls --help
    """

    TOOL_NAME = 'thin_ls'

ThinMetadataSize

Bases: DmpdTool

Calculate thin metadata size requirements.

Usage: thin_metadata_size [options]

For available options, see: thin_metadata_size --help

Source code in sts_libs/src/sts/dmpd.py
221
222
223
224
225
226
227
228
229
class ThinMetadataSize(DmpdTool):
    """Calculate thin metadata size requirements.

    Usage: thin_metadata_size [options]

    For available options, see: thin_metadata_size --help
    """

    TOOL_NAME = 'thin_metadata_size'

ThinRepair

Bases: DmpdTool

Repair corrupted thin metadata.

Usage: thin_repair [options] --input {device|file} --output {device|file}

For available options, see: thin_repair --help

Source code in sts_libs/src/sts/dmpd.py
199
200
201
202
203
204
205
206
207
class ThinRepair(DmpdTool):
    """Repair corrupted thin metadata.

    Usage: thin_repair [options] --input {device|file} --output {device|file}

    For available options, see: thin_repair --help
    """

    TOOL_NAME = 'thin_repair'

ThinRestore

Bases: DmpdTool

Restore thin metadata from backup.

Usage: thin_restore [options] --input --output {device|file}

For available options, see: thin_restore --help

Source code in sts_libs/src/sts/dmpd.py
210
211
212
213
214
215
216
217
218
class ThinRestore(DmpdTool):
    """Restore thin metadata from backup.

    Usage: thin_restore [options] --input <file> --output {device|file}

    For available options, see: thin_restore --help
    """

    TOOL_NAME = 'thin_restore'

ThinTrim

Bases: DmpdTool

Trim thin metadata.

Usage: thin_trim [options] --data-dev {device} --metadata-dev {device}

For available options, see: thin_trim --help

Source code in sts_libs/src/sts/dmpd.py
232
233
234
235
236
237
238
239
240
class ThinTrim(DmpdTool):
    """Trim thin metadata.

    Usage: thin_trim [options] --data-dev {device} --metadata-dev {device}

    For available options, see: thin_trim --help
    """

    TOOL_NAME = 'thin_trim'

cache_check(device_or_file, **options)

Check cache metadata integrity.

Source code in sts_libs/src/sts/dmpd.py
315
316
317
def cache_check(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Check cache metadata integrity."""
    return CacheCheck.run(device_or_file, **options)

cache_dump(device_or_file, **options)

Dump cache metadata.

Source code in sts_libs/src/sts/dmpd.py
320
321
322
def cache_dump(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Dump cache metadata."""
    return CacheDump.run(device_or_file, **options)

cache_metadata_size(**options)

Calculate cache metadata size.

Source code in sts_libs/src/sts/dmpd.py
335
336
337
def cache_metadata_size(**options: CommandOption) -> CommandResult:
    """Calculate cache metadata size."""
    return CacheMetadataSize.run(None, **options)

cache_repair(**options)

Repair cache metadata.

Source code in sts_libs/src/sts/dmpd.py
325
326
327
def cache_repair(**options: CommandOption) -> CommandResult:
    """Repair cache metadata."""
    return CacheRepair.run(None, **options)

cache_restore(**options)

Restore cache metadata.

Source code in sts_libs/src/sts/dmpd.py
330
331
332
def cache_restore(**options: CommandOption) -> CommandResult:
    """Restore cache metadata."""
    return CacheRestore.run(None, **options)

era_check(device_or_file, **options)

Check era metadata integrity.

Source code in sts_libs/src/sts/dmpd.py
380
381
382
def era_check(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Check era metadata integrity."""
    return EraCheck.run(device_or_file, **options)

era_dump(device_or_file, **options)

Dump era metadata.

Source code in sts_libs/src/sts/dmpd.py
385
386
387
def era_dump(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Dump era metadata."""
    return EraDump.run(device_or_file, **options)

era_repair(**options)

Repair era metadata.

Source code in sts_libs/src/sts/dmpd.py
390
391
392
def era_repair(**options: CommandOption) -> CommandResult:
    """Repair era metadata."""
    return EraRepair.run(None, **options)

era_restore(**options)

Restore era metadata.

Source code in sts_libs/src/sts/dmpd.py
395
396
397
def era_restore(**options: CommandOption) -> CommandResult:
    """Restore era metadata."""
    return EraRestore.run(None, **options)

get_help(tool_name)

Get help for any DMPD tool.

Source code in sts_libs/src/sts/dmpd.py
400
401
402
def get_help(tool_name: str) -> CommandResult:
    """Get help for any DMPD tool."""
    return run(f'{tool_name} --help')

get_version(tool_name)

Get version for any DMPD tool.

Source code in sts_libs/src/sts/dmpd.py
405
406
407
def get_version(tool_name: str) -> CommandResult:
    """Get version for any DMPD tool."""
    return run(f'{tool_name} --version')

thin_check(device_or_file, **options)

Check thin metadata integrity.

Source code in sts_libs/src/sts/dmpd.py
340
341
342
def thin_check(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Check thin metadata integrity."""
    return ThinCheck.run(device_or_file, **options)

thin_delta(device_or_file, **options)

Print differences between thin devices.

Source code in sts_libs/src/sts/dmpd.py
375
376
377
def thin_delta(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Print differences between thin devices."""
    return ThinDelta.run(device_or_file, **options)

thin_dump(device_or_file, **options)

Dump thin metadata.

Source code in sts_libs/src/sts/dmpd.py
345
346
347
def thin_dump(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """Dump thin metadata."""
    return ThinDump.run(device_or_file, **options)

thin_ls(device_or_file, **options)

List thin devices.

Source code in sts_libs/src/sts/dmpd.py
370
371
372
def thin_ls(device_or_file: str | Path, **options: CommandOption) -> CommandResult:
    """List thin devices."""
    return ThinLs.run(device_or_file, **options)

thin_metadata_size(**options)

Calculate thin metadata size.

Source code in sts_libs/src/sts/dmpd.py
360
361
362
def thin_metadata_size(**options: CommandOption) -> CommandResult:
    """Calculate thin metadata size."""
    return ThinMetadataSize.run(None, **options)

thin_repair(**options)

Repair thin metadata.

Source code in sts_libs/src/sts/dmpd.py
350
351
352
def thin_repair(**options: CommandOption) -> CommandResult:
    """Repair thin metadata."""
    return ThinRepair.run(None, **options)

thin_restore(**options)

Restore thin metadata.

Source code in sts_libs/src/sts/dmpd.py
355
356
357
def thin_restore(**options: CommandOption) -> CommandResult:
    """Restore thin metadata."""
    return ThinRestore.run(None, **options)

thin_trim(**options)

Trim thin metadata.

Source code in sts_libs/src/sts/dmpd.py
365
366
367
def thin_trim(**options: CommandOption) -> CommandResult:
    """Trim thin metadata."""
    return ThinTrim.run(None, **options)