Hyper.SuidHelper.Dmsetup (Hyper v0.1.0)

Copy Markdown View Source

device-mapper operations (snapshot / thin), via the setuid helper's dmsetup tool.

Summary

Functions

Create a read-only dm-snapshot device named name, layering cow_dev (exception store) over origin_dev. sectors is the logical size in 512-byte sectors. Returns the /dev/mapper/<name> path.

Create a writable dm-snapshot device named name over origin_dev, with cow_dev as its exception store. Writes to the device land in cow_dev, which is how a fork's delta layer file is populated. Same table as create_snapshot/4, minus --readonly.

Create a dm-thin volume name of sectors from thin device id dev_id in pool_dev, with origin_dev as its read-only external origin. Returns /dev/mapper/<name>.

Create a dm-thin pool name backed by meta_dev (metadata loop) and data_dev (data loop). sectors is the data device size; block_sectors the allocation block size; low_water the low-water mark in blocks. Returns the /dev/mapper/<name> path.

Names of every device-mapper device currently present on this host.

Send a thin-pool message to dm device name.

Remove the dm device name.

Resume the suspended dm device name.

Suspend dm device name, flushing queued I/O. Pair with resume/1.

Verify the kernel exposes the dm targets we use (snapshot, thin, thin-pool).

Types

err()

@type err() :: Hyper.SuidHelper.err()

Functions

create_snapshot(name, origin_dev, cow_dev, sectors)

@spec create_snapshot(String.t(), Path.t(), Path.t(), pos_integer()) ::
  {:ok, Path.t()} | {:error, err()}

Create a read-only dm-snapshot device named name, layering cow_dev (exception store) over origin_dev. sectors is the logical size in 512-byte sectors. Returns the /dev/mapper/<name> path.

create_snapshot_rw(name, origin_dev, cow_dev, sectors)

@spec create_snapshot_rw(String.t(), Path.t(), Path.t(), pos_integer()) ::
  {:ok, Path.t()} | {:error, err()}

Create a writable dm-snapshot device named name over origin_dev, with cow_dev as its exception store. Writes to the device land in cow_dev, which is how a fork's delta layer file is populated. Same table as create_snapshot/4, minus --readonly.

create_thin_external(name, pool_dev, dev_id, sectors, origin_dev)

@spec create_thin_external(
  String.t(),
  Path.t(),
  non_neg_integer(),
  pos_integer(),
  Path.t()
) ::
  {:ok, Path.t()} | {:error, err()}

Create a dm-thin volume name of sectors from thin device id dev_id in pool_dev, with origin_dev as its read-only external origin. Returns /dev/mapper/<name>.

create_thin_pool(name, meta_dev, data_dev, sectors, block_sectors, low_water)

@spec create_thin_pool(
  String.t(),
  Path.t(),
  Path.t(),
  pos_integer(),
  pos_integer(),
  non_neg_integer()
) :: {:ok, Path.t()} | {:error, err()}

Create a dm-thin pool name backed by meta_dev (metadata loop) and data_dev (data loop). sectors is the data device size; block_sectors the allocation block size; low_water the low-water mark in blocks. Returns the /dev/mapper/<name> path.

list()

@spec list() :: {:ok, [String.t()]} | {:error, err()}

Names of every device-mapper device currently present on this host.

message(name, message)

@spec message(String.t(), String.t()) :: :ok | {:error, err()}

Send a thin-pool message to dm device name.

remove(name)

@spec remove(String.t()) :: :ok | {:error, err()}

Remove the dm device name.

resume(name)

@spec resume(String.t()) :: :ok | {:error, err()}

Resume the suspended dm device name.

suspend(name)

@spec suspend(String.t()) :: :ok | {:error, err()}

Suspend dm device name, flushing queued I/O. Pair with resume/1.

test_system()

@spec test_system() :: :ok | {:error, term()}

Verify the kernel exposes the dm targets we use (snapshot, thin, thin-pool).

Routes through the setuid helper: dmsetup targets opens /dev/mapper/control, which needs root, and the BEAM runs unprivileged. The helper validates its configured dmsetup binary before running it, so a missing or unsafe binary surfaces here too.