mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Lint package pkg/devicemapper
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
		
							parent
							
								
									915d6ec76d
								
							
						
					
					
						commit
						6990b76a69
					
				
					 7 changed files with 236 additions and 180 deletions
				
			
		| 
						 | 
				
			
			@ -266,7 +266,7 @@ func (devices *DeviceSet) allocateTransactionID() uint64 {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (devices *DeviceSet) updatePoolTransactionID() error {
 | 
			
		||||
	if err := devicemapper.SetTransactionId(devices.getPoolDevName(), devices.TransactionID, devices.OpenTransactionID); err != nil {
 | 
			
		||||
	if err := devicemapper.SetTransactionID(devices.getPoolDevName(), devices.TransactionID, devices.OpenTransactionID); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error setting devmapper transaction ID: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	devices.TransactionID = devices.OpenTransactionID
 | 
			
		||||
| 
						 | 
				
			
			@ -596,7 +596,7 @@ func (devices *DeviceSet) createRegisterDevice(hash string) (*devInfo, error) {
 | 
			
		|||
 | 
			
		||||
	for {
 | 
			
		||||
		if err := devicemapper.CreateDevice(devices.getPoolDevName(), deviceID); err != nil {
 | 
			
		||||
			if devicemapper.DeviceIdExists(err) {
 | 
			
		||||
			if devicemapper.DeviceIDExists(err) {
 | 
			
		||||
				// Device ID already exists. This should not
 | 
			
		||||
				// happen. Now we have a mechianism to find
 | 
			
		||||
				// a free device ID. So something is not right.
 | 
			
		||||
| 
						 | 
				
			
			@ -648,7 +648,7 @@ func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInf
 | 
			
		|||
 | 
			
		||||
	for {
 | 
			
		||||
		if err := devicemapper.CreateSnapDevice(devices.getPoolDevName(), deviceID, baseInfo.Name(), baseInfo.DeviceID); err != nil {
 | 
			
		||||
			if devicemapper.DeviceIdExists(err) {
 | 
			
		||||
			if devicemapper.DeviceIDExists(err) {
 | 
			
		||||
				// Device ID already exists. This should not
 | 
			
		||||
				// happen. Now we have a mechianism to find
 | 
			
		||||
				// a free device ID. So something is not right.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ func openNextAvailableLoopback(index int, sparseFile *os.File) (loopFile *os.Fil
 | 
			
		|||
	return loopFile, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// attachLoopDevice attaches the given sparse file to the next
 | 
			
		||||
// AttachLoopDevice attaches the given sparse file to the next
 | 
			
		||||
// available loopback device. It returns an opened *os.File.
 | 
			
		||||
func AttachLoopDevice(sparseName string) (loop *os.File, err error) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ func AttachLoopDevice(sparseName string) (loop *os.File, err error) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Set the status of the loopback device
 | 
			
		||||
	loopInfo := &LoopInfo64{
 | 
			
		||||
	loopInfo := &loopInfo64{
 | 
			
		||||
		loFileName: stringToLoopName(loopFile.Name()),
 | 
			
		||||
		loOffset:   0,
 | 
			
		||||
		loFlags:    LoFlagsAutoClear,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,37 +13,39 @@ import (
 | 
			
		|||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DevmapperLogger defines methods for logging with devicemapper.
 | 
			
		||||
type DevmapperLogger interface {
 | 
			
		||||
	DMLog(level int, file string, line int, dmError int, message string)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	DeviceCreate TaskType = iota
 | 
			
		||||
	DeviceReload
 | 
			
		||||
	DeviceRemove
 | 
			
		||||
	DeviceRemoveAll
 | 
			
		||||
	DeviceSuspend
 | 
			
		||||
	DeviceResume
 | 
			
		||||
	DeviceInfo
 | 
			
		||||
	DeviceDeps
 | 
			
		||||
	DeviceRename
 | 
			
		||||
	DeviceVersion
 | 
			
		||||
	DeviceStatus
 | 
			
		||||
	DeviceTable
 | 
			
		||||
	DeviceWaitevent
 | 
			
		||||
	DeviceList
 | 
			
		||||
	DeviceClear
 | 
			
		||||
	DeviceMknodes
 | 
			
		||||
	DeviceListVersions
 | 
			
		||||
	DeviceTargetMsg
 | 
			
		||||
	DeviceSetGeometry
 | 
			
		||||
	deviceCreate TaskType = iota
 | 
			
		||||
	deviceReload
 | 
			
		||||
	deviceRemove
 | 
			
		||||
	deviceRemoveAll
 | 
			
		||||
	deviceSuspend
 | 
			
		||||
	deviceResume
 | 
			
		||||
	deviceInfo
 | 
			
		||||
	deviceDeps
 | 
			
		||||
	deviceRename
 | 
			
		||||
	deviceVersion
 | 
			
		||||
	deviceStatus
 | 
			
		||||
	deviceTable
 | 
			
		||||
	deviceWaitevent
 | 
			
		||||
	deviceList
 | 
			
		||||
	deviceClear
 | 
			
		||||
	deviceMknodes
 | 
			
		||||
	deviceListVersions
 | 
			
		||||
	deviceTargetMsg
 | 
			
		||||
	deviceSetGeometry
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	AddNodeOnResume AddNodeType = iota
 | 
			
		||||
	AddNodeOnCreate
 | 
			
		||||
	addNodeOnResume AddNodeType = iota
 | 
			
		||||
	addNodeOnCreate
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// List of errors returned when using devicemapper.
 | 
			
		||||
var (
 | 
			
		||||
	ErrTaskRun                = errors.New("dm_task_run failed")
 | 
			
		||||
	ErrTaskSetName            = errors.New("dm_task_set_name failed")
 | 
			
		||||
| 
						 | 
				
			
			@ -63,29 +65,35 @@ var (
 | 
			
		|||
	ErrUdevWait               = errors.New("wait on udev cookie failed")
 | 
			
		||||
	ErrSetDevDir              = errors.New("dm_set_dev_dir failed")
 | 
			
		||||
	ErrGetLibraryVersion      = errors.New("dm_get_library_version failed")
 | 
			
		||||
	ErrCreateRemoveTask       = errors.New("Can't create task of type DeviceRemove")
 | 
			
		||||
	ErrCreateRemoveTask       = errors.New("Can't create task of type deviceRemove")
 | 
			
		||||
	ErrRunRemoveDevice        = errors.New("running RemoveDevice failed")
 | 
			
		||||
	ErrInvalidAddNode         = errors.New("Invalid AddNode type")
 | 
			
		||||
	ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file")
 | 
			
		||||
	ErrLoopbackSetCapacity    = errors.New("Unable set loopback capacity")
 | 
			
		||||
	ErrBusy                   = errors.New("Device is Busy")
 | 
			
		||||
	ErrDeviceIdExists         = errors.New("Device Id Exists")
 | 
			
		||||
	ErrDeviceIDExists         = errors.New("Device Id Exists")
 | 
			
		||||
	ErrEnxio                  = errors.New("No such device or address")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	dmSawBusy  bool
 | 
			
		||||
	dmSawExist bool
 | 
			
		||||
	dmSawEnxio bool // No Such Device or Address
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	// Task represents a devicemapper task (like lvcreate, etc.) ; a task is needed for each ioctl
 | 
			
		||||
	// command to execute.
 | 
			
		||||
	Task struct {
 | 
			
		||||
		unmanaged *CDmTask
 | 
			
		||||
		unmanaged *cdmTask
 | 
			
		||||
	}
 | 
			
		||||
	// Deps represents dependents (layer) of a device.
 | 
			
		||||
	Deps struct {
 | 
			
		||||
		Count  uint32
 | 
			
		||||
		Filler uint32
 | 
			
		||||
		Device []uint64
 | 
			
		||||
	}
 | 
			
		||||
	// Info represents information about a device.
 | 
			
		||||
	Info struct {
 | 
			
		||||
		Exists         int
 | 
			
		||||
		Suspended      int
 | 
			
		||||
| 
						 | 
				
			
			@ -99,18 +107,20 @@ type (
 | 
			
		|||
		TargetCount    int32
 | 
			
		||||
		DeferredRemove int
 | 
			
		||||
	}
 | 
			
		||||
	TaskType    int
 | 
			
		||||
	// TaskType represents a type of task
 | 
			
		||||
	TaskType int
 | 
			
		||||
	// AddNodeType represents a type of node to be added (?)
 | 
			
		||||
	AddNodeType int
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Returns whether error conveys the information about device Id already
 | 
			
		||||
// DeviceIDExists returns whether error conveys the information about device Id already
 | 
			
		||||
// exist or not. This will be true if device creation or snap creation
 | 
			
		||||
// operation fails if device or snap device already exists in pool.
 | 
			
		||||
// Current implementation is little crude as it scans the error string
 | 
			
		||||
// for exact pattern match. Replacing it with more robust implementation
 | 
			
		||||
// is desirable.
 | 
			
		||||
func DeviceIdExists(err error) bool {
 | 
			
		||||
	return fmt.Sprint(err) == fmt.Sprint(ErrDeviceIdExists)
 | 
			
		||||
func DeviceIDExists(err error) bool {
 | 
			
		||||
	return fmt.Sprint(err) == fmt.Sprint(ErrDeviceIDExists)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) destroy() {
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +137,7 @@ func TaskCreateNamed(t TaskType, name string) (*Task, error) {
 | 
			
		|||
	if task == nil {
 | 
			
		||||
		return nil, fmt.Errorf("Can't create task of type %d", int(t))
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.SetName(name); err != nil {
 | 
			
		||||
	if err := task.setName(name); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("Can't set task name %s", name)
 | 
			
		||||
	}
 | 
			
		||||
	return task, nil
 | 
			
		||||
| 
						 | 
				
			
			@ -144,35 +154,35 @@ func TaskCreate(tasktype TaskType) *Task {
 | 
			
		|||
	return task
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) Run() error {
 | 
			
		||||
func (t *Task) run() error {
 | 
			
		||||
	if res := DmTaskRun(t.unmanaged); res != 1 {
 | 
			
		||||
		return ErrTaskRun
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) SetName(name string) error {
 | 
			
		||||
func (t *Task) setName(name string) error {
 | 
			
		||||
	if res := DmTaskSetName(t.unmanaged, name); res != 1 {
 | 
			
		||||
		return ErrTaskSetName
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) SetMessage(message string) error {
 | 
			
		||||
func (t *Task) setMessage(message string) error {
 | 
			
		||||
	if res := DmTaskSetMessage(t.unmanaged, message); res != 1 {
 | 
			
		||||
		return ErrTaskSetMessage
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) SetSector(sector uint64) error {
 | 
			
		||||
func (t *Task) setSector(sector uint64) error {
 | 
			
		||||
	if res := DmTaskSetSector(t.unmanaged, sector); res != 1 {
 | 
			
		||||
		return ErrTaskSetSector
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) SetCookie(cookie *uint, flags uint16) error {
 | 
			
		||||
func (t *Task) setCookie(cookie *uint, flags uint16) error {
 | 
			
		||||
	if cookie == nil {
 | 
			
		||||
		return ErrNilCookie
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -182,8 +192,8 @@ func (t *Task) SetCookie(cookie *uint, flags uint16) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) SetAddNode(addNode AddNodeType) error {
 | 
			
		||||
	if addNode != AddNodeOnResume && addNode != AddNodeOnCreate {
 | 
			
		||||
func (t *Task) setAddNode(addNode AddNodeType) error {
 | 
			
		||||
	if addNode != addNodeOnResume && addNode != addNodeOnCreate {
 | 
			
		||||
		return ErrInvalidAddNode
 | 
			
		||||
	}
 | 
			
		||||
	if res := DmTaskSetAddNode(t.unmanaged, addNode); res != 1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -192,14 +202,14 @@ func (t *Task) SetAddNode(addNode AddNodeType) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) SetRo() error {
 | 
			
		||||
func (t *Task) setRo() error {
 | 
			
		||||
	if res := DmTaskSetRo(t.unmanaged); res != 1 {
 | 
			
		||||
		return ErrTaskSetRo
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) AddTarget(start, size uint64, ttype, params string) error {
 | 
			
		||||
func (t *Task) addTarget(start, size uint64, ttype, params string) error {
 | 
			
		||||
	if res := DmTaskAddTarget(t.unmanaged, start, size,
 | 
			
		||||
		ttype, params); res != 1 {
 | 
			
		||||
		return ErrTaskAddTarget
 | 
			
		||||
| 
						 | 
				
			
			@ -207,7 +217,7 @@ func (t *Task) AddTarget(start, size uint64, ttype, params string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) GetDeps() (*Deps, error) {
 | 
			
		||||
func (t *Task) getDeps() (*Deps, error) {
 | 
			
		||||
	var deps *Deps
 | 
			
		||||
	if deps = DmTaskGetDeps(t.unmanaged); deps == nil {
 | 
			
		||||
		return nil, ErrTaskGetDeps
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +225,7 @@ func (t *Task) GetDeps() (*Deps, error) {
 | 
			
		|||
	return deps, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) GetInfo() (*Info, error) {
 | 
			
		||||
func (t *Task) getInfo() (*Info, error) {
 | 
			
		||||
	info := &Info{}
 | 
			
		||||
	if res := DmTaskGetInfo(t.unmanaged, info); res != 1 {
 | 
			
		||||
		return nil, ErrTaskGetInfo
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +233,7 @@ func (t *Task) GetInfo() (*Info, error) {
 | 
			
		|||
	return info, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) GetInfoWithDeferred() (*Info, error) {
 | 
			
		||||
func (t *Task) getInfoWithDeferred() (*Info, error) {
 | 
			
		||||
	info := &Info{}
 | 
			
		||||
	if res := DmTaskGetInfoWithDeferred(t.unmanaged, info); res != 1 {
 | 
			
		||||
		return nil, ErrTaskGetInfo
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +241,7 @@ func (t *Task) GetInfoWithDeferred() (*Info, error) {
 | 
			
		|||
	return info, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) GetDriverVersion() (string, error) {
 | 
			
		||||
func (t *Task) getDriverVersion() (string, error) {
 | 
			
		||||
	res := DmTaskGetDriverVersion(t.unmanaged)
 | 
			
		||||
	if res == "" {
 | 
			
		||||
		return "", ErrTaskGetDriverVersion
 | 
			
		||||
| 
						 | 
				
			
			@ -239,7 +249,7 @@ func (t *Task) GetDriverVersion() (string, error) {
 | 
			
		|||
	return res, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *Task) GetNextTarget(next unsafe.Pointer) (nextPtr unsafe.Pointer, start uint64,
 | 
			
		||||
func (t *Task) getNextTarget(next unsafe.Pointer) (nextPtr unsafe.Pointer, start uint64,
 | 
			
		||||
	length uint64, targetType string, params string) {
 | 
			
		||||
 | 
			
		||||
	return DmGetNextTarget(t.unmanaged, next, &start, &length,
 | 
			
		||||
| 
						 | 
				
			
			@ -256,6 +266,7 @@ func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
 | 
			
		|||
	return loopInfo.loDevice, loopInfo.loInode, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LoopbackSetCapacity reloads the size for the loopback device.
 | 
			
		||||
func LoopbackSetCapacity(file *os.File) error {
 | 
			
		||||
	if err := ioctlLoopSetCapacity(file.Fd(), 0); err != nil {
 | 
			
		||||
		logrus.Errorf("Error loopbackSetCapacity: %s", err)
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +275,8 @@ func LoopbackSetCapacity(file *os.File) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindLoopDeviceFor returns a loopback device file for the specified file which
 | 
			
		||||
// is backing file of a loop back device.
 | 
			
		||||
func FindLoopDeviceFor(file *os.File) *os.File {
 | 
			
		||||
	stat, err := file.Stat()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -296,6 +309,7 @@ func FindLoopDeviceFor(file *os.File) *os.File {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UdevWait wakes any processes that are waiting for udev to complete the specified cookie. (?)
 | 
			
		||||
func UdevWait(cookie *uint) error {
 | 
			
		||||
	if res := DmUdevWait(*cookie); res != 1 {
 | 
			
		||||
		logrus.Debugf("Failed to wait on udev cookie %d", *cookie)
 | 
			
		||||
| 
						 | 
				
			
			@ -304,18 +318,20 @@ func UdevWait(cookie *uint) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogInitVerbose is an interface to initialize the verbose logger for the device mapper library. (?)
 | 
			
		||||
func LogInitVerbose(level int) {
 | 
			
		||||
	DmLogInitVerbose(level)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var dmLogger DevmapperLogger = nil
 | 
			
		||||
var dmLogger DevmapperLogger
 | 
			
		||||
 | 
			
		||||
// initialize the logger for the device mapper library
 | 
			
		||||
// LogInit initializes the logger for the device mapper library.
 | 
			
		||||
func LogInit(logger DevmapperLogger) {
 | 
			
		||||
	dmLogger = logger
 | 
			
		||||
	LogWithErrnoInit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDevDir sets the dev folder for the device mapper library (usually /dev).
 | 
			
		||||
func SetDevDir(dir string) error {
 | 
			
		||||
	if res := DmSetDevDir(dir); res != 1 {
 | 
			
		||||
		logrus.Debugf("Error dm_set_dev_dir")
 | 
			
		||||
| 
						 | 
				
			
			@ -324,6 +340,7 @@ func SetDevDir(dir string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetLibraryVersion returns the device mapper library version.
 | 
			
		||||
func GetLibraryVersion() (string, error) {
 | 
			
		||||
	var version string
 | 
			
		||||
	if res := DmGetLibraryVersion(&version); res != 1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -359,21 +376,21 @@ func CookieSupported() bool {
 | 
			
		|||
	return DmCookieSupported() != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Useful helper for cleanup
 | 
			
		||||
// RemoveDevice is a useful helper for cleaning up a device.
 | 
			
		||||
func RemoveDevice(name string) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceRemove, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceRemove, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var cookie uint = 0
 | 
			
		||||
	if err := task.SetCookie(&cookie, 0); err != nil {
 | 
			
		||||
	var cookie uint
 | 
			
		||||
	if err := task.setCookie(&cookie, 0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can not set cookie: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer UdevWait(&cookie)
 | 
			
		||||
 | 
			
		||||
	dmSawBusy = false // reset before the task is run
 | 
			
		||||
	if err = task.Run(); err != nil {
 | 
			
		||||
	if err = task.run(); err != nil {
 | 
			
		||||
		if dmSawBusy {
 | 
			
		||||
			return ErrBusy
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -383,10 +400,11 @@ func RemoveDevice(name string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoveDeviceDeferred is a useful helper for cleaning up a device, but deferred.
 | 
			
		||||
func RemoveDeviceDeferred(name string) error {
 | 
			
		||||
	logrus.Debugf("[devmapper] RemoveDeviceDeferred START(%s)", name)
 | 
			
		||||
	defer logrus.Debugf("[devmapper] RemoveDeviceDeferred END(%s)", name)
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceRemove, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceRemove, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -395,31 +413,31 @@ func RemoveDeviceDeferred(name string) error {
 | 
			
		|||
		return ErrTaskDeferredRemove
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = task.Run(); err != nil {
 | 
			
		||||
	if err = task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running RemoveDeviceDeferred %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Useful helper for cleanup
 | 
			
		||||
// CancelDeferredRemove cancels a deferred remove for a device.
 | 
			
		||||
func CancelDeferredRemove(deviceName string) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceTargetMsg, deviceName)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceTargetMsg, deviceName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetSector(0); err != nil {
 | 
			
		||||
	if err := task.setSector(0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set sector %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetMessage(fmt.Sprintf("@cancel_deferred_remove")); err != nil {
 | 
			
		||||
	if err := task.setMessage(fmt.Sprintf("@cancel_deferred_remove")); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set message %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dmSawBusy = false
 | 
			
		||||
	dmSawEnxio = false
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		// A device might be being deleted already
 | 
			
		||||
		if dmSawBusy {
 | 
			
		||||
			return ErrBusy
 | 
			
		||||
| 
						 | 
				
			
			@ -432,6 +450,7 @@ func CancelDeferredRemove(deviceName string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBlockDeviceSize returns the size of a block device identified by the specified file.
 | 
			
		||||
func GetBlockDeviceSize(file *os.File) (uint64, error) {
 | 
			
		||||
	size, err := ioctlBlkGetSize64(file.Fd())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -441,6 +460,10 @@ func GetBlockDeviceSize(file *os.File) (uint64, error) {
 | 
			
		|||
	return uint64(size), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BlockDeviceDiscard runs discard for the given path.
 | 
			
		||||
// This is used as a workaround for the kernel not discarding block so
 | 
			
		||||
// on the thin pool when we remove a thinp device, so we do it
 | 
			
		||||
// manually
 | 
			
		||||
func BlockDeviceDiscard(path string) error {
 | 
			
		||||
	file, err := os.OpenFile(path, os.O_RDWR, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -464,9 +487,10 @@ func BlockDeviceDiscard(path string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This is the programmatic example of "dmsetup create"
 | 
			
		||||
// CreatePool is the programmatic example of "dmsetup create".
 | 
			
		||||
// It creates a device with the specified poolName, data and metadata file and block size.
 | 
			
		||||
func CreatePool(poolName string, dataFile, metadataFile *os.File, poolBlockSize uint32) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceCreate, poolName)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceCreate, poolName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -477,26 +501,29 @@ func CreatePool(poolName string, dataFile, metadataFile *os.File, poolBlockSize
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	params := fmt.Sprintf("%s %s %d 32768 1 skip_block_zeroing", metadataFile.Name(), dataFile.Name(), poolBlockSize)
 | 
			
		||||
	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
 | 
			
		||||
	if err := task.addTarget(0, size/512, "thin-pool", params); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't add target %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var cookie uint = 0
 | 
			
		||||
	var flags uint16 = DmUdevDisableSubsystemRulesFlag | DmUdevDisableDiskRulesFlag | DmUdevDisableOtherRulesFlag
 | 
			
		||||
	if err := task.SetCookie(&cookie, flags); err != nil {
 | 
			
		||||
	var cookie uint
 | 
			
		||||
	var flags uint16
 | 
			
		||||
	flags = DmUdevDisableSubsystemRulesFlag | DmUdevDisableDiskRulesFlag | DmUdevDisableOtherRulesFlag
 | 
			
		||||
	if err := task.setCookie(&cookie, flags); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set cookie %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer UdevWait(&cookie)
 | 
			
		||||
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running DeviceCreate (CreatePool) %s", err)
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running deviceCreate (CreatePool) %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReloadPool is the programmatic example of "dmsetup reload".
 | 
			
		||||
// It reloads the table with the specified poolName, data and metadata file and block size.
 | 
			
		||||
func ReloadPool(poolName string, dataFile, metadataFile *os.File, poolBlockSize uint32) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceReload, poolName)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceReload, poolName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -507,73 +534,83 @@ func ReloadPool(poolName string, dataFile, metadataFile *os.File, poolBlockSize
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	params := fmt.Sprintf("%s %s %d 32768 1 skip_block_zeroing", metadataFile.Name(), dataFile.Name(), poolBlockSize)
 | 
			
		||||
	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
 | 
			
		||||
	if err := task.addTarget(0, size/512, "thin-pool", params); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't add target %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running DeviceCreate %s", err)
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running deviceCreate %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetDeps is the programmatic example of "dmsetup deps".
 | 
			
		||||
// It outputs a list of devices referenced by the live table for the specified device.
 | 
			
		||||
func GetDeps(name string) (*Deps, error) {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceDeps, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceDeps, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return task.GetDeps()
 | 
			
		||||
	return task.getDeps()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetInfo is the programmatic example of "dmsetup info".
 | 
			
		||||
// It outputs some brief information about the device.
 | 
			
		||||
func GetInfo(name string) (*Info, error) {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceInfo, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceInfo, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return task.GetInfo()
 | 
			
		||||
	return task.getInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetInfoWithDeferred is the programmatic example of "dmsetup info", but deferred.
 | 
			
		||||
// It outputs some brief information about the device.
 | 
			
		||||
func GetInfoWithDeferred(name string) (*Info, error) {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceInfo, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceInfo, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return task.GetInfoWithDeferred()
 | 
			
		||||
	return task.getInfoWithDeferred()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetDriverVersion is the programmatic example of "dmsetup version".
 | 
			
		||||
// It outputs version information of the driver.
 | 
			
		||||
func GetDriverVersion() (string, error) {
 | 
			
		||||
	task := TaskCreate(DeviceVersion)
 | 
			
		||||
	task := TaskCreate(deviceVersion)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return "", fmt.Errorf("Can't create DeviceVersion task")
 | 
			
		||||
		return "", fmt.Errorf("Can't create deviceVersion task")
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return task.GetDriverVersion()
 | 
			
		||||
	return task.getDriverVersion()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetStatus is the programmatic example of "dmsetup status".
 | 
			
		||||
// It outputs status information for the specified device name.
 | 
			
		||||
func GetStatus(name string) (uint64, uint64, string, string, error) {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceStatus, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceStatus, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		logrus.Debugf("GetStatus: Error TaskCreateNamed: %s", err)
 | 
			
		||||
		return 0, 0, "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		logrus.Debugf("GetStatus: Error Run: %s", err)
 | 
			
		||||
		return 0, 0, "", "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	devinfo, err := task.GetInfo()
 | 
			
		||||
	devinfo, err := task.getInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Debugf("GetStatus: Error GetInfo: %s", err)
 | 
			
		||||
		return 0, 0, "", "", err
 | 
			
		||||
| 
						 | 
				
			
			@ -583,22 +620,24 @@ func GetStatus(name string) (uint64, uint64, string, string, error) {
 | 
			
		|||
		return 0, 0, "", "", fmt.Errorf("Non existing device %s", name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, start, length, targetType, params := task.GetNextTarget(unsafe.Pointer(nil))
 | 
			
		||||
	_, start, length, targetType, params := task.getNextTarget(unsafe.Pointer(nil))
 | 
			
		||||
	return start, length, targetType, params, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetTable is the programmatic example for "dmsetup table".
 | 
			
		||||
// It outputs the current table for the specified device name.
 | 
			
		||||
func GetTable(name string) (uint64, uint64, string, string, error) {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceTable, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceTable, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		logrus.Debugf("GetTable: Error TaskCreateNamed: %s", err)
 | 
			
		||||
		return 0, 0, "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		logrus.Debugf("GetTable: Error Run: %s", err)
 | 
			
		||||
		return 0, 0, "", "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	devinfo, err := task.GetInfo()
 | 
			
		||||
	devinfo, err := task.getInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Debugf("GetTable: Error GetInfo: %s", err)
 | 
			
		||||
		return 0, 0, "", "", err
 | 
			
		||||
| 
						 | 
				
			
			@ -608,80 +647,86 @@ func GetTable(name string) (uint64, uint64, string, string, error) {
 | 
			
		|||
		return 0, 0, "", "", fmt.Errorf("Non existing device %s", name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, start, length, targetType, params := task.GetNextTarget(unsafe.Pointer(nil))
 | 
			
		||||
	_, start, length, targetType, params := task.getNextTarget(unsafe.Pointer(nil))
 | 
			
		||||
	return start, length, targetType, params, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetTransactionId(poolName string, oldId uint64, newId uint64) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceTargetMsg, poolName)
 | 
			
		||||
// SetTransactionID sets a transaction id for the specified device name.
 | 
			
		||||
func SetTransactionID(poolName string, oldID uint64, newID uint64) error {
 | 
			
		||||
	task, err := TaskCreateNamed(deviceTargetMsg, poolName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetSector(0); err != nil {
 | 
			
		||||
	if err := task.setSector(0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set sector %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetMessage(fmt.Sprintf("set_transaction_id %d %d", oldId, newId)); err != nil {
 | 
			
		||||
	if err := task.setMessage(fmt.Sprintf("set_transaction_id %d %d", oldID, newID)); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set message %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running SetTransactionId %s", err)
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running SetTransactionID %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SuspendDevice is the programmatic example of "dmsetup suspend".
 | 
			
		||||
// It suspends the specified device.
 | 
			
		||||
func SuspendDevice(name string) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceSuspend, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceSuspend, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running DeviceSuspend %s", err)
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running deviceSuspend %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResumeDevice is the programmatic example of "dmsetup resume".
 | 
			
		||||
// It un-suspends the specified device.
 | 
			
		||||
func ResumeDevice(name string) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceResume, name)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceResume, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var cookie uint = 0
 | 
			
		||||
	if err := task.SetCookie(&cookie, 0); err != nil {
 | 
			
		||||
	var cookie uint
 | 
			
		||||
	if err := task.setCookie(&cookie, 0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set cookie %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer UdevWait(&cookie)
 | 
			
		||||
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running DeviceResume %s", err)
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running deviceResume %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CreateDevice(poolName string, deviceId int) error {
 | 
			
		||||
	logrus.Debugf("[devmapper] CreateDevice(poolName=%v, deviceId=%v)", poolName, deviceId)
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceTargetMsg, poolName)
 | 
			
		||||
// CreateDevice creates a device with the specified poolName with the specified device id. (?)
 | 
			
		||||
func CreateDevice(poolName string, deviceID int) error {
 | 
			
		||||
	logrus.Debugf("[devmapper] CreateDevice(poolName=%v, deviceID=%v)", poolName, deviceID)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceTargetMsg, poolName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetSector(0); err != nil {
 | 
			
		||||
	if err := task.setSector(0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set sector %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetMessage(fmt.Sprintf("create_thin %d", deviceId)); err != nil {
 | 
			
		||||
	if err := task.setMessage(fmt.Sprintf("create_thin %d", deviceID)); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set message %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dmSawExist = false // reset before the task is run
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		// Caller wants to know about ErrDeviceIdExists so that it can try with a different device id.
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		// Caller wants to know about ErrDeviceIDExists so that it can try with a different device id.
 | 
			
		||||
		if dmSawExist {
 | 
			
		||||
			return ErrDeviceIdExists
 | 
			
		||||
			return ErrDeviceIDExists
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return fmt.Errorf("Error running CreateDevice %s", err)
 | 
			
		||||
| 
						 | 
				
			
			@ -690,68 +735,74 @@ func CreateDevice(poolName string, deviceId int) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DeleteDevice(poolName string, deviceId int) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceTargetMsg, poolName)
 | 
			
		||||
// DeleteDevice deletes a device with the specified poolName with the specified device id. (?)
 | 
			
		||||
func DeleteDevice(poolName string, deviceID int) error {
 | 
			
		||||
	task, err := TaskCreateNamed(deviceTargetMsg, poolName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetSector(0); err != nil {
 | 
			
		||||
	if err := task.setSector(0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set sector %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetMessage(fmt.Sprintf("delete %d", deviceId)); err != nil {
 | 
			
		||||
	if err := task.setMessage(fmt.Sprintf("delete %d", deviceID)); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set message %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running DeleteDevice %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ActivateDevice(poolName string, name string, deviceId int, size uint64) error {
 | 
			
		||||
	return activateDevice(poolName, name, deviceId, size, "")
 | 
			
		||||
// ActivateDevice activates the device identified by the specified
 | 
			
		||||
// poolName, name and deviceID with the specified size.
 | 
			
		||||
func ActivateDevice(poolName string, name string, deviceID int, size uint64) error {
 | 
			
		||||
	return activateDevice(poolName, name, deviceID, size, "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ActivateDeviceWithExternal(poolName string, name string, deviceId int, size uint64, external string) error {
 | 
			
		||||
	return activateDevice(poolName, name, deviceId, size, external)
 | 
			
		||||
// ActivateDeviceWithExternal activates the device identified by the specified
 | 
			
		||||
// poolName, name and deviceID with the specified size. (?)
 | 
			
		||||
func ActivateDeviceWithExternal(poolName string, name string, deviceID int, size uint64, external string) error {
 | 
			
		||||
	return activateDevice(poolName, name, deviceID, size, external)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func activateDevice(poolName string, name string, deviceId int, size uint64, external string) error {
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceCreate, name)
 | 
			
		||||
func activateDevice(poolName string, name string, deviceID int, size uint64, external string) error {
 | 
			
		||||
	task, err := TaskCreateNamed(deviceCreate, name)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var params string
 | 
			
		||||
	if len(external) > 0 {
 | 
			
		||||
		params = fmt.Sprintf("%s %d %s", poolName, deviceId, external)
 | 
			
		||||
		params = fmt.Sprintf("%s %d %s", poolName, deviceID, external)
 | 
			
		||||
	} else {
 | 
			
		||||
		params = fmt.Sprintf("%s %d", poolName, deviceId)
 | 
			
		||||
		params = fmt.Sprintf("%s %d", poolName, deviceID)
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.AddTarget(0, size/512, "thin", params); err != nil {
 | 
			
		||||
	if err := task.addTarget(0, size/512, "thin", params); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't add target %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := task.SetAddNode(AddNodeOnCreate); err != nil {
 | 
			
		||||
	if err := task.setAddNode(addNodeOnCreate); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't add node %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var cookie uint = 0
 | 
			
		||||
	if err := task.SetCookie(&cookie, 0); err != nil {
 | 
			
		||||
	var cookie uint
 | 
			
		||||
	if err := task.setCookie(&cookie, 0); err != nil {
 | 
			
		||||
		return fmt.Errorf("Can't set cookie %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer UdevWait(&cookie)
 | 
			
		||||
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running DeviceCreate (ActivateDevice) %s", err)
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		return fmt.Errorf("Error running deviceCreate (ActivateDevice) %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CreateSnapDevice(poolName string, deviceId int, baseName string, baseDeviceId int) error {
 | 
			
		||||
// CreateSnapDevice creates a snapshot based on the device identified by the baseName and baseDeviceId,
 | 
			
		||||
func CreateSnapDevice(poolName string, deviceID int, baseName string, baseDeviceID int) error {
 | 
			
		||||
	devinfo, _ := GetInfo(baseName)
 | 
			
		||||
	doSuspend := devinfo != nil && devinfo.Exists != 0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -761,7 +812,7 @@ func CreateSnapDevice(poolName string, deviceId int, baseName string, baseDevice
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	task, err := TaskCreateNamed(DeviceTargetMsg, poolName)
 | 
			
		||||
	task, err := TaskCreateNamed(deviceTargetMsg, poolName)
 | 
			
		||||
	if task == nil {
 | 
			
		||||
		if doSuspend {
 | 
			
		||||
			ResumeDevice(baseName)
 | 
			
		||||
| 
						 | 
				
			
			@ -769,14 +820,14 @@ func CreateSnapDevice(poolName string, deviceId int, baseName string, baseDevice
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetSector(0); err != nil {
 | 
			
		||||
	if err := task.setSector(0); err != nil {
 | 
			
		||||
		if doSuspend {
 | 
			
		||||
			ResumeDevice(baseName)
 | 
			
		||||
		}
 | 
			
		||||
		return fmt.Errorf("Can't set sector %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := task.SetMessage(fmt.Sprintf("create_snap %d %d", deviceId, baseDeviceId)); err != nil {
 | 
			
		||||
	if err := task.setMessage(fmt.Sprintf("create_snap %d %d", deviceID, baseDeviceID)); err != nil {
 | 
			
		||||
		if doSuspend {
 | 
			
		||||
			ResumeDevice(baseName)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -784,16 +835,16 @@ func CreateSnapDevice(poolName string, deviceId int, baseName string, baseDevice
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	dmSawExist = false // reset before the task is run
 | 
			
		||||
	if err := task.Run(); err != nil {
 | 
			
		||||
	if err := task.run(); err != nil {
 | 
			
		||||
		if doSuspend {
 | 
			
		||||
			ResumeDevice(baseName)
 | 
			
		||||
		}
 | 
			
		||||
		// Caller wants to know about ErrDeviceIdExists so that it can try with a different device id.
 | 
			
		||||
		// Caller wants to know about ErrDeviceIDExists so that it can try with a different device id.
 | 
			
		||||
		if dmSawExist {
 | 
			
		||||
			return ErrDeviceIdExists
 | 
			
		||||
			return ErrDeviceIDExists
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return fmt.Errorf("Error running DeviceCreate (createSnapDevice) %s", err)
 | 
			
		||||
		return fmt.Errorf("Error running deviceCreate (createSnapDevice) %s", err)
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,23 +44,23 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
	CDmTask C.struct_dm_task
 | 
			
		||||
	cdmTask C.struct_dm_task
 | 
			
		||||
 | 
			
		||||
	CLoopInfo64 C.struct_loop_info64
 | 
			
		||||
	LoopInfo64  struct {
 | 
			
		||||
		loDevice           uint64 /* ioctl r/o */
 | 
			
		||||
		loInode            uint64 /* ioctl r/o */
 | 
			
		||||
		loRdevice          uint64 /* ioctl r/o */
 | 
			
		||||
		loOffset           uint64
 | 
			
		||||
		loSizelimit        uint64 /* bytes, 0 == max available */
 | 
			
		||||
		loNumber           uint32 /* ioctl r/o */
 | 
			
		||||
		loEncrypt_type     uint32
 | 
			
		||||
		loEncrypt_key_size uint32 /* ioctl w/o */
 | 
			
		||||
		loFlags            uint32 /* ioctl r/o */
 | 
			
		||||
		loFileName         [LoNameSize]uint8
 | 
			
		||||
		loCryptName        [LoNameSize]uint8
 | 
			
		||||
		loEncryptKey       [LoKeySize]uint8 /* ioctl w/o */
 | 
			
		||||
		loInit             [2]uint64
 | 
			
		||||
	cLoopInfo64 C.struct_loop_info64
 | 
			
		||||
	loopInfo64  struct {
 | 
			
		||||
		loDevice         uint64 /* ioctl r/o */
 | 
			
		||||
		loInode          uint64 /* ioctl r/o */
 | 
			
		||||
		loRdevice        uint64 /* ioctl r/o */
 | 
			
		||||
		loOffset         uint64
 | 
			
		||||
		loSizelimit      uint64 /* bytes, 0 == max available */
 | 
			
		||||
		loNumber         uint32 /* ioctl r/o */
 | 
			
		||||
		loEncryptType    uint32
 | 
			
		||||
		loEncryptKeySize uint32 /* ioctl w/o */
 | 
			
		||||
		loFlags          uint32 /* ioctl r/o */
 | 
			
		||||
		loFileName       [LoNameSize]uint8
 | 
			
		||||
		loCryptName      [LoNameSize]uint8
 | 
			
		||||
		loEncryptKey     [LoKeySize]uint8 /* ioctl w/o */
 | 
			
		||||
		loInit           [2]uint64
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +77,7 @@ const (
 | 
			
		|||
	LoopSetCapacity = C.LOOP_SET_CAPACITY
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LOOP consts. (?)
 | 
			
		||||
const (
 | 
			
		||||
	LoFlagsAutoClear = C.LO_FLAGS_AUTOCLEAR
 | 
			
		||||
	LoFlagsReadOnly  = C.LO_FLAGS_READ_ONLY
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +86,7 @@ const (
 | 
			
		|||
	LoNameSize       = C.LO_NAME_SIZE
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DeviceMapper Udev consts. (?)
 | 
			
		||||
const (
 | 
			
		||||
	DmUdevDisableSubsystemRulesFlag = C.DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG
 | 
			
		||||
	DmUdevDisableDiskRulesFlag      = C.DM_UDEV_DISABLE_DISK_RULES_FLAG
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +94,7 @@ const (
 | 
			
		|||
	DmUdevDisableLibraryFallback    = C.DM_UDEV_DISABLE_LIBRARY_FALLBACK
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DeviceMapper mapped functions.
 | 
			
		||||
var (
 | 
			
		||||
	DmGetLibraryVersion       = dmGetLibraryVersionFct
 | 
			
		||||
	DmGetNextTarget           = dmGetNextTargetFct
 | 
			
		||||
| 
						 | 
				
			
			@ -123,38 +126,38 @@ func free(p *C.char) {
 | 
			
		|||
	C.free(unsafe.Pointer(p))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskDestroyFct(task *CDmTask) {
 | 
			
		||||
func dmTaskDestroyFct(task *cdmTask) {
 | 
			
		||||
	C.dm_task_destroy((*C.struct_dm_task)(task))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskCreateFct(taskType int) *CDmTask {
 | 
			
		||||
	return (*CDmTask)(C.dm_task_create(C.int(taskType)))
 | 
			
		||||
func dmTaskCreateFct(taskType int) *cdmTask {
 | 
			
		||||
	return (*cdmTask)(C.dm_task_create(C.int(taskType)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskRunFct(task *CDmTask) int {
 | 
			
		||||
func dmTaskRunFct(task *cdmTask) int {
 | 
			
		||||
	ret, _ := C.dm_task_run((*C.struct_dm_task)(task))
 | 
			
		||||
	return int(ret)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskSetNameFct(task *CDmTask, name string) int {
 | 
			
		||||
func dmTaskSetNameFct(task *cdmTask, name string) int {
 | 
			
		||||
	Cname := C.CString(name)
 | 
			
		||||
	defer free(Cname)
 | 
			
		||||
 | 
			
		||||
	return int(C.dm_task_set_name((*C.struct_dm_task)(task), Cname))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskSetMessageFct(task *CDmTask, message string) int {
 | 
			
		||||
func dmTaskSetMessageFct(task *cdmTask, message string) int {
 | 
			
		||||
	Cmessage := C.CString(message)
 | 
			
		||||
	defer free(Cmessage)
 | 
			
		||||
 | 
			
		||||
	return int(C.dm_task_set_message((*C.struct_dm_task)(task), Cmessage))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskSetSectorFct(task *CDmTask, sector uint64) int {
 | 
			
		||||
func dmTaskSetSectorFct(task *cdmTask, sector uint64) int {
 | 
			
		||||
	return int(C.dm_task_set_sector((*C.struct_dm_task)(task), C.uint64_t(sector)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskSetCookieFct(task *CDmTask, cookie *uint, flags uint16) int {
 | 
			
		||||
func dmTaskSetCookieFct(task *cdmTask, cookie *uint, flags uint16) int {
 | 
			
		||||
	cCookie := C.uint32_t(*cookie)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		*cookie = uint(cCookie)
 | 
			
		||||
| 
						 | 
				
			
			@ -162,15 +165,15 @@ func dmTaskSetCookieFct(task *CDmTask, cookie *uint, flags uint16) int {
 | 
			
		|||
	return int(C.dm_task_set_cookie((*C.struct_dm_task)(task), &cCookie, C.uint16_t(flags)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskSetAddNodeFct(task *CDmTask, addNode AddNodeType) int {
 | 
			
		||||
func dmTaskSetAddNodeFct(task *cdmTask, addNode AddNodeType) int {
 | 
			
		||||
	return int(C.dm_task_set_add_node((*C.struct_dm_task)(task), C.dm_add_node_t(addNode)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskSetRoFct(task *CDmTask) int {
 | 
			
		||||
func dmTaskSetRoFct(task *cdmTask) int {
 | 
			
		||||
	return int(C.dm_task_set_ro((*C.struct_dm_task)(task)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskAddTargetFct(task *CDmTask,
 | 
			
		||||
func dmTaskAddTargetFct(task *cdmTask,
 | 
			
		||||
	start, size uint64, ttype, params string) int {
 | 
			
		||||
 | 
			
		||||
	Cttype := C.CString(ttype)
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +185,7 @@ func dmTaskAddTargetFct(task *CDmTask,
 | 
			
		|||
	return int(C.dm_task_add_target((*C.struct_dm_task)(task), C.uint64_t(start), C.uint64_t(size), Cttype, Cparams))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskGetDepsFct(task *CDmTask) *Deps {
 | 
			
		||||
func dmTaskGetDepsFct(task *cdmTask) *Deps {
 | 
			
		||||
	Cdeps := C.dm_task_get_deps((*C.struct_dm_task)(task))
 | 
			
		||||
	if Cdeps == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +209,7 @@ func dmTaskGetDepsFct(task *CDmTask) *Deps {
 | 
			
		|||
	return deps
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskGetInfoFct(task *CDmTask, info *Info) int {
 | 
			
		||||
func dmTaskGetInfoFct(task *cdmTask, info *Info) int {
 | 
			
		||||
	Cinfo := C.struct_dm_info{}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		info.Exists = int(Cinfo.exists)
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +226,7 @@ func dmTaskGetInfoFct(task *CDmTask, info *Info) int {
 | 
			
		|||
	return int(C.dm_task_get_info((*C.struct_dm_task)(task), &Cinfo))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskGetDriverVersionFct(task *CDmTask) string {
 | 
			
		||||
func dmTaskGetDriverVersionFct(task *cdmTask) string {
 | 
			
		||||
	buffer := C.malloc(128)
 | 
			
		||||
	defer C.free(buffer)
 | 
			
		||||
	res := C.dm_task_get_driver_version((*C.struct_dm_task)(task), (*C.char)(buffer), 128)
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +236,7 @@ func dmTaskGetDriverVersionFct(task *CDmTask) string {
 | 
			
		|||
	return C.GoString((*C.char)(buffer))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmGetNextTargetFct(task *CDmTask, next unsafe.Pointer, start, length *uint64, target, params *string) unsafe.Pointer {
 | 
			
		||||
func dmGetNextTargetFct(task *cdmTask, next unsafe.Pointer, start, length *uint64, target, params *string) unsafe.Pointer {
 | 
			
		||||
	var (
 | 
			
		||||
		Cstart, Clength      C.uint64_t
 | 
			
		||||
		CtargetType, Cparams *C.char
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ package devicemapper
 | 
			
		|||
*/
 | 
			
		||||
import "C"
 | 
			
		||||
 | 
			
		||||
// LibraryDeferredRemovalsupport is supported when statically linked.
 | 
			
		||||
const LibraryDeferredRemovalSupport = true
 | 
			
		||||
 | 
			
		||||
func dmTaskDeferredRemoveFct(task *CDmTask) int {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,13 +2,14 @@
 | 
			
		|||
 | 
			
		||||
package devicemapper
 | 
			
		||||
 | 
			
		||||
// LibraryDeferredRemovalsupport is not supported when statically linked.
 | 
			
		||||
const LibraryDeferredRemovalSupport = false
 | 
			
		||||
 | 
			
		||||
func dmTaskDeferredRemoveFct(task *CDmTask) int {
 | 
			
		||||
func dmTaskDeferredRemoveFct(task *cdmTask) int {
 | 
			
		||||
	// Error. Nobody should be calling it.
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dmTaskGetInfoWithDeferredFct(task *CDmTask, info *Info) int {
 | 
			
		||||
func dmTaskGetInfoWithDeferredFct(task *cdmTask, info *Info) int {
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ func ioctlLoopSetFd(loopFd, sparseFd uintptr) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlLoopSetStatus64(loopFd uintptr, loopInfo *LoopInfo64) error {
 | 
			
		||||
func ioctlLoopSetStatus64(loopFd uintptr, loopInfo *loopInfo64) error {
 | 
			
		||||
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, loopFd, LoopSetStatus64, uintptr(unsafe.Pointer(loopInfo))); err != 0 {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,8 +36,8 @@ func ioctlLoopClrFd(loopFd uintptr) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlLoopGetStatus64(loopFd uintptr) (*LoopInfo64, error) {
 | 
			
		||||
	loopInfo := &LoopInfo64{}
 | 
			
		||||
func ioctlLoopGetStatus64(loopFd uintptr) (*loopInfo64, error) {
 | 
			
		||||
	loopInfo := &loopInfo64{}
 | 
			
		||||
 | 
			
		||||
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, loopFd, LoopGetStatus64, uintptr(unsafe.Pointer(loopInfo))); err != 0 {
 | 
			
		||||
		return nil, err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue