Merge pull request #9258 from rhvgoyal/transaction-id-improvements

devmapper fix usage of pool transaction id
This commit is contained in:
Vincent Batts 2014-12-11 12:58:18 -05:00
commit ab77e1f2dd

View file

@ -67,6 +67,7 @@ var (
ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file") ErrGetLoopbackBackingFile = errors.New("Unable to get loopback backing file")
ErrLoopbackSetCapacity = errors.New("Unable set loopback capacity") ErrLoopbackSetCapacity = errors.New("Unable set loopback capacity")
ErrBusy = errors.New("Device is Busy") ErrBusy = errors.New("Device is Busy")
ErrDeviceIdExists = errors.New("Device Id Exists")
dmSawBusy bool dmSawBusy bool
dmSawExist bool dmSawExist bool
@ -97,6 +98,16 @@ type (
AddNodeType int AddNodeType int
) )
// 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 (t *Task) destroy() { func (t *Task) destroy() {
if t != nil { if t != nil {
DmTaskDestroy(t.unmanaged) DmTaskDestroy(t.unmanaged)
@ -528,33 +539,29 @@ func ResumeDevice(name string) error {
return nil return nil
} }
func CreateDevice(poolName string, deviceId *int) error { func CreateDevice(poolName string, deviceId int) error {
log.Debugf("[devmapper] CreateDevice(poolName=%v, deviceId=%v)", poolName, *deviceId) log.Debugf("[devmapper] CreateDevice(poolName=%v, deviceId=%v)", poolName, deviceId)
task, err := TaskCreateNamed(DeviceTargetMsg, poolName)
if task == nil {
return err
}
for { if err := task.SetSector(0); err != nil {
task, err := TaskCreateNamed(DeviceTargetMsg, poolName) return fmt.Errorf("Can't set sector %s", err)
if task == nil { }
return err
}
if err := task.SetSector(0); err != nil { if err := task.SetMessage(fmt.Sprintf("create_thin %d", deviceId)); err != nil {
return fmt.Errorf("Can't set sector %s", err) return fmt.Errorf("Can't set message %s", err)
} }
if err := task.SetMessage(fmt.Sprintf("create_thin %d", *deviceId)); err != nil { dmSawExist = false // reset before the task is run
return fmt.Errorf("Can't set message %s", err) if err := task.Run(); err != nil {
} // Caller wants to know about ErrDeviceIdExists so that it can try with a different device id.
if dmSawExist {
dmSawExist = false // reset before the task is run return ErrDeviceIdExists
if err := task.Run(); err != nil { } else {
if dmSawExist {
// Already exists, try next id
*deviceId++
continue
}
return fmt.Errorf("Error running CreateDevice %s", err) return fmt.Errorf("Error running CreateDevice %s", err)
} }
break
} }
return nil return nil
} }
@ -607,7 +614,7 @@ func ActivateDevice(poolName string, name string, deviceId int, size uint64) err
return nil return nil
} }
func CreateSnapDevice(poolName string, deviceId *int, baseName string, baseDeviceId int) error { func CreateSnapDevice(poolName string, deviceId int, baseName string, baseDeviceId int) error {
devinfo, _ := GetInfo(baseName) devinfo, _ := GetInfo(baseName)
doSuspend := devinfo != nil && devinfo.Exists != 0 doSuspend := devinfo != nil && devinfo.Exists != 0
@ -617,44 +624,39 @@ func CreateSnapDevice(poolName string, deviceId *int, baseName string, baseDevic
} }
} }
for { task, err := TaskCreateNamed(DeviceTargetMsg, poolName)
task, err := TaskCreateNamed(DeviceTargetMsg, poolName) if task == nil {
if task == nil { if doSuspend {
if doSuspend { ResumeDevice(baseName)
ResumeDevice(baseName)
}
return err
} }
return err
}
if err := task.SetSector(0); err != nil { if err := task.SetSector(0); err != nil {
if doSuspend { if doSuspend {
ResumeDevice(baseName) ResumeDevice(baseName)
}
return fmt.Errorf("Can't set sector %s", err)
} }
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 { if doSuspend {
ResumeDevice(baseName) ResumeDevice(baseName)
}
return fmt.Errorf("Can't set message %s", err)
} }
return fmt.Errorf("Can't set message %s", err)
}
dmSawExist = false // reset before the task is run dmSawExist = false // reset before the task is run
if err := task.Run(); err != nil { if err := task.Run(); err != nil {
if dmSawExist { if doSuspend {
// Already exists, try next id ResumeDevice(baseName)
*deviceId++ }
continue // Caller wants to know about ErrDeviceIdExists so that it can try with a different device id.
} if dmSawExist {
return ErrDeviceIdExists
if doSuspend { } else {
ResumeDevice(baseName)
}
return fmt.Errorf("Error running DeviceCreate (createSnapDevice) %s", err) return fmt.Errorf("Error running DeviceCreate (createSnapDevice) %s", err)
} }
break
} }
if doSuspend { if doSuspend {