From 437de8bcb1fb997d354596d4d60160b3232d8394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Wei=C3=9Fe?= Date: Wed, 11 May 2022 11:08:23 +0200 Subject: [PATCH] Add function to retrieve real device path of mapped device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Weiße --- go.mod | 2 +- go.sum | 4 +-- mount/cryptmapper/cryptmapper.go | 23 +++++++++++++ mount/cryptmapper/cryptmapper_test.go | 47 +++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 57e108e47..18575033c 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 9171ce9fc..175015c7d 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/mount/cryptmapper/cryptmapper.go b/mount/cryptmapper/cryptmapper.go index 14c24df5f..d05f4a4cd 100644 --- a/mount/cryptmapper/cryptmapper.go +++ b/mount/cryptmapper/cryptmapper.go @@ -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) { diff --git a/mount/cryptmapper/cryptmapper_test.go b/mount/cryptmapper/cryptmapper_test.go index 1aad773d4..be491e208 100644 --- a/mount/cryptmapper/cryptmapper_test.go +++ b/mount/cryptmapper/cryptmapper_test.go @@ -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