// 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.
extern crate bitflags;
extern crate nix;
extern crate lazy_static;
/// Range macros
/// ID macros
/// shared constants
/// core functionality
/// Macros shared by device mapper devices.
/// cachedev
/// functions to create continuous linear space given device segments
/// return results container
/// functionality shared between devices
/// allocate a device from a pool
/// the id the pool uses to track its devices
/// thinpooldev is shared space for other thin provisioned devices to use
/// representation of units used by the outer layers
/// More useful test output for match cases
extern crate assert_matches;
pub use crate::;