devmapper

package module
v0.0.0-...-59ac2b9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2023 License: MIT Imports: 13 Imported by: 3

README

Pure Go library for device mapper targets management

devmapper.go is a pure-Go library that helps to deal with device mapper targets.

Here is an example that demonstrates the API usage:

func main() {
    name := "crypttarget"
    uuid := "2f144136-b0de-4b51-b2eb-bd869cc39a6e"
    key := make([]byte, 32)
    c := devmapper.CryptTable{
        Length:        60000 * 512, // size of the device in bytes
        Encryption:    "aes-xts-plain64",
        Key:           key,
        BackendDevice: "/dev/loop0",
        Flags:         []string{devmapper.CryptFlagAllowDiscards},
    }
    if err := devmapper.CreateAndLoad(name, uuid, c); err != nil {
        // handle error
    }
    defer devmapper.Remove(name)

    // at this point a devmapper target named 'crypttarget' should exist
    // you can check it with 'dmsetup info crypttarget'
    // and udev will create /dev/mapper/crypttarget device file
}

Or the same crypttarget initialization using Linux keychain

func main() {
    // load key into keyring
    keyname := fmt.Sprintf("cryptsetup:%s-d%d", uuid, luksDigestId) // an example of keyname used by LUKS framework
    kid, err := unix.AddKey("logon", keyname, key, unix.KEY_SPEC_THREAD_KEYRING)
    if err != nil {
        return err
    }
    defer unlinkKey(kid)
    keyid := fmt.Sprintf(":%v:logon:%v", len(key), keyname)

    name := "crypttarget"
    uuid := "2f144136-b0de-4b51-b2eb-bd869cc39a6e"
    c := devmapper.CryptTable{
        Length:        60000 * 512, // size of the device in bytes
        Encryption:    "aes-xts-plain64",
        KeyID:         keyid,
        BackendDevice: "/dev/loop0",
        Flags:         []string{devmapper.CryptFlagAllowDiscards},
    }
    if err := devmapper.CreateAndLoad(name, uuid, c); err != nil {
        // handle error
    }
    defer devmapper.Remove(name)
}

func unlinkKey(kid int) {
	if _, err := unix.KeyctlInt(unix.KEYCTL_REVOKE, kid, 0, 0, 0); err != nil {
		fmt.Printf("key revoke: %v\n", err)
	}

	if _, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, kid, unix.KEY_SPEC_THREAD_KEYRING, 0, 0); err != nil {
		fmt.Printf("key unlink, thread: %v\n", err)
	}

	// We added key to thread keyring only. But let's try to unlink the key from other keyrings as well just to be safe
	_, _ = unix.KeyctlInt(unix.KEYCTL_UNLINK, kid, unix.KEY_SPEC_PROCESS_KEYRING, 0, 0)
	_, _ = unix.KeyctlInt(unix.KEYCTL_UNLINK, kid, unix.KEY_SPEC_USER_KEYRING, 0, 0)
}

License

See LICENSE.

Documentation

Index

Constants

View Source
const (

	// CryptFlagAllowDiscards is an equivalent of 'allow_discards' crypt option
	CryptFlagAllowDiscards = "allow_discards"
	// CryptFlagSameCPUCrypt is an equivalent of 'same_cpu_crypt' crypt option
	CryptFlagSameCPUCrypt = "same_cpu_crypt"
	// CryptFlagSubmitFromCryptCPUs is an equivalent of 'submit_from_crypt_cpus' crypt option
	CryptFlagSubmitFromCryptCPUs = "submit_from_crypt_cpus"
	// CryptFlagNoReadWorkqueue is an equivalent of 'no_read_workqueue' crypt option
	CryptFlagNoReadWorkqueue = "no_read_workqueue"
	// CryptFlagNoWriteWorkqueue is an equivalent of 'no_write_workqueue' crypt option
	CryptFlagNoWriteWorkqueue = "no_write_workqueue"
)
View Source
const (
	// ReadOnlyFlag is a devmapper readonly flag value
	ReadOnlyFlag = unix.DM_READONLY_FLAG
)
View Source
const SectorSize = 512

SectorSize is a device size used for devmapper calculations. Currently this value hardcoded to 512.

Variables

This section is empty.

Functions

func Create

func Create(name string, uuid string) error

Create creates a new device. No table will be loaded. The device will be in suspended state. Any IO to this device will fail.

func CreateAndLoad

func CreateAndLoad(name string, uuid string, flags uint32, tables ...Table) error

CreateAndLoad creates, loads the provided tables and resumes the device.

func GetVersion

func GetVersion() (major, minor, patch uint32, err error)

GetVersion returns version for the dm-mapper kernel interface

func Load

func Load(name string, flags uint32, tables ...Table) error

Load loads given table into the device

func Message

func Message(name string, sector int, message string) error

Message passes a message string to the target at specific offset of a device.

func Remove

func Remove(name string) error

Remove removes the device and destroys its tables.

func Rename

func Rename(old, new string) error

Rename renames the device

func Resume

func Resume(name string) error

Resume resumes the given device.

func SetUUID

func SetUUID(name, uuid string) error

SetUUID sets uuid for a given device

func Suspend

func Suspend(name string) error

Suspend suspends the given device.

Types

type CryptTable

type CryptTable struct {
	Start         uint64
	Length        uint64
	BackendDevice string // device that stores the encrypted data
	BackendOffset uint64
	Encryption    string
	Key           []byte
	KeyID         string // key id in the keystore e.g. ":32:logon:foobarkey"
	IVTweak       uint64
	Flags         []string // TODO: maybe convert it to bitflag instead?
	SectorSize    uint64   // size of the sector the crypto device operates with
}

CryptTable represents information needed for 'crypt' target creation

type DeviceInfo

type DeviceInfo struct {
	Name       string
	UUID       string
	DevNo      uint64
	OpenCount  int32
	TargetsNum uint32
	Flags      uint32 // combination of unix.DM_*_FLAG
}

DeviceInfo is a type that holds devmapper device information

func InfoByDevno

func InfoByDevno(devno uint64) (*DeviceInfo, error)

InfoByDevno returns device mapper information by its block device number (major/minor)

func InfoByName

func InfoByName(name string) (*DeviceInfo, error)

InfoByName returns device information by its name

type LinearTable

type LinearTable struct {
	Start         uint64
	Length        uint64
	BackendDevice string
	BackendOffset uint64
}

LinearTable represents information needed for 'linear' target creation

type ListItem

type ListItem struct {
	DevNo uint64
	Name  string
}

ListItem represents information about a dmsetup device

func List

func List() ([]ListItem, error)

List provides a list of dmsetup devices

type Table

type Table interface {
	// contains filtered or unexported methods
}

Table is a type to represent different devmapper targets like 'zero', 'crypt', ...

type VerityTable

type VerityTable struct {
	Start                         uint64
	Length                        uint64
	HashType                      uint64
	DataDevice                    string // the device containing data, the integrity of which needs to be checked
	HashDevice                    string // device that supplies the hash tree data
	DataBlockSize, HashBlockSize  uint64
	NumDataBlocks, HashStartBlock uint64
	Algorithm, Digest, Salt       string
	Params                        []string
}

VerityTable represents information needed for 'verity' target creation

type Volume

type Volume interface {
	io.ReaderAt
	io.WriterAt
	io.Closer
}

Volume represents reader/writer for the data handled by the device mapper table. Due to constrains the reader and writer operate at SectorSize size. Some targets may put further restrictions on the buffer alignment, e.g. CryptTarget operates at CryptTarget.SectorSize instead

func OpenUserspaceVolume

func OpenUserspaceVolume(flag int, perm fs.FileMode, tables ...Table) (Volume, error)

OpenUserspaceVolume opens a volume that allows to read/write data. It performs the data processing at user-space level without using device-mapper kernel framework. flag and perm parameters are applied to os.OpenFile() when opening the underlying files

type ZeroTable

type ZeroTable struct {
	Start  uint64
	Length uint64
}

ZeroTable represents information needed for 'zero' target creation

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL