mirror of
https://github.com/clearlinux/docker.git
synced 2026-09-07 14:32:09 +00:00
devicemapper tool: Add support for pool resizing
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type DevmapperLogger interface {
|
||||
@@ -40,25 +41,27 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrTaskRun = errors.New("dm_task_run failed")
|
||||
ErrTaskSetName = errors.New("dm_task_set_name failed")
|
||||
ErrTaskSetMessage = errors.New("dm_task_set_message failed")
|
||||
ErrTaskSetAddNode = errors.New("dm_task_set_add_node failed")
|
||||
ErrTaskSetRo = errors.New("dm_task_set_ro failed")
|
||||
ErrTaskAddTarget = errors.New("dm_task_add_target failed")
|
||||
ErrTaskSetSector = errors.New("dm_task_set_sector failed")
|
||||
ErrTaskGetInfo = errors.New("dm_task_get_info failed")
|
||||
ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version failed")
|
||||
ErrTaskSetCookie = errors.New("dm_task_set_cookie failed")
|
||||
ErrNilCookie = errors.New("cookie ptr can't be nil")
|
||||
ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
|
||||
ErrGetBlockSize = errors.New("Can't get block size")
|
||||
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")
|
||||
ErrRunRemoveDevice = errors.New("running removeDevice failed")
|
||||
ErrInvalidAddNode = errors.New("Invalide AddNoce type")
|
||||
ErrTaskRun = errors.New("dm_task_run failed")
|
||||
ErrTaskSetName = errors.New("dm_task_set_name failed")
|
||||
ErrTaskSetMessage = errors.New("dm_task_set_message failed")
|
||||
ErrTaskSetAddNode = errors.New("dm_task_set_add_node failed")
|
||||
ErrTaskSetRo = errors.New("dm_task_set_ro failed")
|
||||
ErrTaskAddTarget = errors.New("dm_task_add_target failed")
|
||||
ErrTaskSetSector = errors.New("dm_task_set_sector failed")
|
||||
ErrTaskGetInfo = errors.New("dm_task_get_info failed")
|
||||
ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version failed")
|
||||
ErrTaskSetCookie = errors.New("dm_task_set_cookie failed")
|
||||
ErrNilCookie = errors.New("cookie ptr can't be nil")
|
||||
ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
|
||||
ErrGetBlockSize = errors.New("Can't get block size")
|
||||
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")
|
||||
ErrRunRemoveDevice = errors.New("running removeDevice failed")
|
||||
ErrInvalidAddNode = errors.New("Invalide AddNoce type")
|
||||
ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file")
|
||||
ErrLoopbackSetCapacity = errors.New("Unable set loopback capacity")
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -186,6 +189,55 @@ func AttachLoopDevice(filename string) (*os.File, error) {
|
||||
return os.NewFile(uintptr(fd), res), nil
|
||||
}
|
||||
|
||||
func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
|
||||
dev, inode, err := dmGetLoopbackBackingFile(file.Fd())
|
||||
if err != 0 {
|
||||
return 0, 0, ErrGetLoopbackBackingFile
|
||||
}
|
||||
return dev, inode, nil
|
||||
}
|
||||
|
||||
func LoopbackSetCapacity(file *os.File) error {
|
||||
err := dmLoopbackSetCapacity(file.Fd())
|
||||
if err != 0 {
|
||||
return ErrLoopbackSetCapacity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindLoopDeviceFor(file *os.File) *os.File {
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
targetInode := stat.Sys().(*syscall.Stat_t).Ino
|
||||
targetDevice := stat.Sys().(*syscall.Stat_t).Dev
|
||||
|
||||
for i := 0; true; i++ {
|
||||
path := fmt.Sprintf("/dev/loop%d", i)
|
||||
|
||||
file, err := os.OpenFile(path, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ignore all errors until the first not-exist
|
||||
// we want to continue looking for the file
|
||||
continue
|
||||
}
|
||||
|
||||
dev, inode, err := getLoopbackBackingFile(file)
|
||||
if err == nil && dev == targetDevice && inode == targetInode {
|
||||
return file
|
||||
}
|
||||
|
||||
file.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UdevWait(cookie uint) error {
|
||||
if res := DmUdevWait(cookie); res != 1 {
|
||||
utils.Debugf("Failed to wait on udev cookie %d", cookie)
|
||||
@@ -276,6 +328,29 @@ func createPool(poolName string, dataFile *os.File, metadataFile *os.File) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func reloadPool(poolName string, dataFile *os.File, metadataFile *os.File) error {
|
||||
task, err := createTask(DeviceReload, poolName)
|
||||
if task == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
size, err := GetBlockDeviceSize(dataFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can't get data size")
|
||||
}
|
||||
|
||||
params := metadataFile.Name() + " " + dataFile.Name() + " 128 32768"
|
||||
if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
|
||||
return fmt.Errorf("Can't add target")
|
||||
}
|
||||
|
||||
if err := task.Run(); err != nil {
|
||||
return fmt.Errorf("Error running DeviceCreate")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createTask(t TaskType, name string) (*Task, error) {
|
||||
task := TaskCreate(t)
|
||||
if task == nil {
|
||||
|
||||
Reference in New Issue
Block a user