Add function to retrieve real device path of mapped device

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2022-05-11 11:08:23 +02:00 committed by Daniel Weiße
parent f8c9c0f17f
commit 437de8bcb1
4 changed files with 73 additions and 3 deletions

2
go.mod
View File

@ -221,4 +221,4 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
)
replace github.com/martinjungblut/go-cryptsetup => github.com/daniel-weisse/go-cryptsetup v0.0.0-20220510090142-d35a60c619db
replace github.com/martinjungblut/go-cryptsetup => github.com/daniel-weisse/go-cryptsetup v0.0.0-20220511084044-b537356aa24b

4
go.sum
View File

@ -512,8 +512,8 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/daniel-weisse/go-cryptsetup v0.0.0-20220510090142-d35a60c619db h1:MgKZLtrp/goZpLnshCnx7j5YwjfibjCt60Sl/pPJHtg=
github.com/daniel-weisse/go-cryptsetup v0.0.0-20220510090142-d35a60c619db/go.mod h1:gZoZ0+POlM1ge/VUxWpMmZVNPzzMJ7l436CgkQ5+qzU=
github.com/daniel-weisse/go-cryptsetup v0.0.0-20220511084044-b537356aa24b h1:YGmoG92uSwGnXqoYYIAAXZSJ33Ogc13GXgnBbDr8p5o=
github.com/daniel-weisse/go-cryptsetup v0.0.0-20220511084044-b537356aa24b/go.mod h1:gZoZ0+POlM1ge/VUxWpMmZVNPzzMJ7l436CgkQ5+qzU=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

View File

@ -63,6 +63,8 @@ type DeviceMapper interface {
Format(deviceType cryptsetup.DeviceType, genericParams cryptsetup.GenericParams) error
// Free releases crypt device context and used memory.
Free() bool
// GetDeviceName gets the path to the underlying device.
GetDeviceName() string
// Load loads crypt device parameters from the on-disk header.
// Returns nil on success, or an error otherwise.
Load(cryptsetup.DeviceType) error
@ -195,6 +197,11 @@ func (c *CryptMapper) ResizeCryptDevice(ctx context.Context, volumeID string) (s
return cryptPrefix + volumeID, nil
}
// GetDeviceName returns the real device name of a mapped crypt device.
func (c *CryptMapper) GetDevicePath(volumeID string) (string, error) {
return getDevicePath(c.mapper, strings.TrimPrefix(volumeID, cryptPrefix))
}
// closeCryptDevice closes the crypt device mapped for volumeID.
func closeCryptDevice(device DeviceMapper, source, volumeID, deviceType string) error {
packageLock.Lock()
@ -389,6 +396,22 @@ func resizeCryptDevice(device DeviceMapper, name, passphrase string) error {
return nil
}
func getDevicePath(device DeviceMapper, name string) (string, error) {
packageLock.Lock()
defer packageLock.Unlock()
if err := device.InitByName(name); err != nil {
return "", fmt.Errorf("initializing device: %w", err)
}
defer device.Free()
deviceName := device.GetDeviceName()
if deviceName == "" {
return "", errors.New("unable to determine device name")
}
return deviceName, nil
}
// IsIntegrityFS checks if the fstype string contains an integrity suffix.
// If yes, returns the trimmed fstype and true, fstype and false otherwise.
func IsIntegrityFS(fstype string) (string, bool) {

View File

@ -64,6 +64,10 @@ func (c *stubCryptDevice) Free() bool {
return true
}
func (c *stubCryptDevice) GetDeviceName() string {
return c.deviceName
}
func (c *stubCryptDevice) Load(cryptsetup.DeviceType) error {
return c.loadErr
}
@ -314,6 +318,49 @@ func TestResizeCryptDevice(t *testing.T) {
}
}
func TestGetDevicePath(t *testing.T) {
volumeID := "pvc-123"
someErr := errors.New("error")
testCases := map[string]struct {
volumeID string
device *stubCryptDevice
wantErr bool
}{
"success": {
volumeID: volumeID,
device: &stubCryptDevice{deviceName: volumeID},
},
"InitByName fails": {
volumeID: volumeID,
device: &stubCryptDevice{initByNameErr: someErr},
wantErr: true,
},
"GetDeviceName returns nothing": {
volumeID: volumeID,
device: &stubCryptDevice{},
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
mapper := &CryptMapper{
mapper: tc.device,
}
res, err := mapper.GetDevicePath(tc.volumeID)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
assert.Equal(tc.device.deviceName, res)
}
})
}
}
func TestIsIntegrityFS(t *testing.T) {
testCases := map[string]struct {
wantIntegrity bool