1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! Low-level devicemapper configuration of the running kernel.
//!
//! # Overview
//!
//! Linux's devicemapper allows the creation of block devices whose
//! storage is mapped to other block devices in useful ways, either by
//! changing the location of its data blocks, or performing some
//! operation on the data itself. This is a low-level facility that is
//! used by higher-level volume managers such as LVM2. Uses may
//! include:
//!
//! * Dividing a large block device into smaller logical volumes (dm-linear)
//! * Combining several separate block devices into a single block
//!   device with better performance and/or redundancy (dm-raid)
//! * Encrypting a block device (dm-crypt)
//! * Performing Copy-on-Write (COW) allocation of a volume's blocks
//!   enabling fast volume cloning and snapshots (dm-thin)
//! * Configuring a smaller, faster block device to act as a cache for a
//!   larger, slower one (dm-cache)
//! * Verifying the contents of a read-only volume (dm-verity)
//!
//! # Usage
//!
//! Before they can be used, DM devices must be created using
//! `DM::device_create()`, have a mapping table loaded using
//! `DM::table_load()`, and then activated with
//! `DM::device_suspend()`. (This function is used for both suspending
//! and activating a device.) Once activated, they can be used as a
//! regular block device, including having other DM devices map to
//! them.
//!
//! Devices have "active" and "inactive" mapping tables. See function
//! descriptions for which table they affect.
//!
//! # Polling for Events
//!
//! Since DM minor version 37, first available in Linux kernel 4.14, the file
//! descriptor associated with a `DM` context may be polled for events generated by
//! DM devices.
//!
//! The fd will indicate POLLIN if any events have occurred on any DM devices
//! since the fd was opened, or since `DM::arm_poll()` was called. Therefore,
//! in order to determine which DM devices have generated an event, the
//! following usage is required:
//!
//! 1. Create a `DM`.
//! 2. Call `DM::list_devices()` and track the `event_nr`s for any DM devices
//! of interest.
//! 3. `poll()` on the `DM`'s file descriptor, obtained by calling
//! `DM::file().as_raw_fd()`.
//! 4. If the fd indicates activity, first clear the event by calling
//! `DM::arm_poll()`.  This must be done before event processing to ensure
//! events are not missed.
//! 5. Process events. Call `DM::list_devices()` again, and compare `event_nr`
//! returned by the more recent call with `event_nr` values from the earlier
//! call.  If `event_nr` differs, an event has occurred on that specific
//! device. Handle the event(s). Update the list of last-seen `event_nr`s.
//! 6. Optionally loop and re-invoke `poll()` on the fd to wait for more
//! events.

#![allow(clippy::doc_markdown)]
#![warn(missing_docs)]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate nix;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;

/// Range macros
#[macro_use]
mod range_macros;
/// ID macros
#[macro_use]
mod id_macros;
/// shared constants
mod consts;
/// core functionality
mod core;
/// Macros shared by device mapper devices.
#[macro_use]
mod shared_macros;
/// cachedev
mod cachedev;
/// functions to create continuous linear space given device segments
mod lineardev;
/// return results container
mod result;
/// functionality shared between devices
mod shared;
/// allocate a device from a pool
mod thindev;
/// the id the pool uses to track its devices
mod thindevid;
/// thinpooldev is shared space for  other thin provisioned devices to use
mod thinpooldev;
/// representation of units used by the outer layers
mod units;

#[cfg(test)]
mod testing;

/// More useful test output for match cases
#[cfg(test)]
#[macro_use]
extern crate assert_matches;

pub use crate::{
    cachedev::{
        CacheDev, CacheDevPerformance, CacheDevStatus, CacheDevTargetTable, CacheDevUsage,
        CacheDevWorkingStatus, CacheTargetParams, MAX_CACHE_BLOCK_SIZE, MIN_CACHE_BLOCK_SIZE,
    },
    consts::IEC,
    core::{
        devnode_to_devno, errors, DevId, Device, DeviceInfo, DmFlags, DmName, DmNameBuf, DmOptions,
        DmUdevFlags, DmUuid, DmUuidBuf, DM,
    },
    lineardev::{
        FlakeyTargetParams, LinearDev, LinearDevTargetParams, LinearDevTargetTable,
        LinearTargetParams,
    },
    result::{DmError, DmResult, ErrorEnum},
    shared::{
        device_exists, DmDevice, TargetLine, TargetParams, TargetTable, TargetType, TargetTypeBuf,
    },
    thindev::{ThinDev, ThinDevTargetTable, ThinDevWorkingStatus, ThinStatus, ThinTargetParams},
    thindevid::ThinDevId,
    thinpooldev::{
        ThinPoolDev, ThinPoolDevTargetTable, ThinPoolNoSpacePolicy, ThinPoolStatus,
        ThinPoolStatusSummary, ThinPoolTargetParams, ThinPoolUsage, ThinPoolWorkingStatus,
    },
    units::{Bytes, DataBlocks, MetaBlocks, Sectors, SECTOR_SIZE},
};