Skip to content

Commit

Permalink
feat: add support for checking if device is already open
Browse files Browse the repository at this point in the history
This allows to handle retries better on Talos volume management side.

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Oct 4, 2024
1 parent 33f603a commit f63c85d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
18 changes: 18 additions & 0 deletions encryption/luks/luks.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,22 @@ func (l *LUKS) Open(ctx context.Context, deviceName, mappedName string, key *enc
return filepath.Join("/dev/mapper", mappedName), nil
}

// IsOpen checks if the device is already opened.
func (l *LUKS) IsOpen(ctx context.Context, _, mappedName string) (bool, string, error) {
args := []string{"status", mappedName}

_, err := l.runCommand(ctx, args, nil)
if err != nil {
if errors.Is(err, encryption.ErrDeviceNotReady) {
return false, "", nil
}

return false, "", err
}

return true, filepath.Join("/dev/mapper", mappedName), nil
}

// Encrypt implements encryption.Provider.
func (l *LUKS) Encrypt(ctx context.Context, deviceName string, key *encryption.Key) error {
cipher, err := l.cipher.String()
Expand Down Expand Up @@ -358,6 +374,8 @@ func (l *LUKS) runCommand(ctx context.Context, args []string, stdin []byte) (str
}
case 2:
return "", encryption.ErrEncryptionKeyRejected
case 4:
return "", encryption.ErrDeviceNotReady
case 5:
return "", encryption.ErrDeviceBusy
}
Expand Down
18 changes: 18 additions & 0 deletions encryption/luks/luks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,24 @@ func testEncrypt(t *testing.T) {

t.Logf("unencrypted partition path %s", path)

isOpen, _, err := provider.IsOpen(ctx, path, mappedName)
require.NoError(t, err)
require.False(t, isOpen)

require.NoError(t, provider.Encrypt(ctx, path, key))

isOpen, _, err = provider.IsOpen(ctx, path, mappedName)
require.NoError(t, err)
require.False(t, isOpen)

encryptedPath, err := provider.Open(ctx, path, mappedName, key)
require.NoError(t, err)

isOpen, isOpenPath, err := provider.IsOpen(ctx, path, mappedName)
require.NoError(t, err)
require.True(t, isOpen)
require.Equal(t, encryptedPath, isOpenPath)

require.NoError(t, provider.Resize(ctx, encryptedPath, key))

require.NoError(t, provider.AddKey(ctx, path, key, keyExtra))
Expand Down Expand Up @@ -159,6 +172,11 @@ func testEncrypt(t *testing.T) {
require.NoError(t, unix.Unmount(mountPath, 0))

require.NoError(t, provider.Close(ctx, encryptedPath))

isOpen, _, err = provider.IsOpen(ctx, path, mappedName)
require.NoError(t, err)
require.False(t, isOpen)

require.Error(t, provider.Close(ctx, encryptedPath))

// second key slot
Expand Down
4 changes: 4 additions & 0 deletions encryption/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
type Provider interface {
TokenProvider
Encrypt(ctx context.Context, devname string, key *Key) error
IsOpen(ctx context.Context, devname, mappedName string) (bool, string, error)
Open(ctx context.Context, devname, mappedName string, key *Key) (string, error)
Close(ctx context.Context, devname string) error
AddKey(ctx context.Context, devname string, key, newKey *Key) error
Expand All @@ -47,6 +48,9 @@ var (

// ErrTokenNotFound returned when trying to get/delete not existing token.
ErrTokenNotFound = fmt.Errorf("no token with supplied id exists")

// ErrDeviceNotReady returned when device is not ready.
ErrDeviceNotReady = fmt.Errorf("device is not ready")
)

// Keyslots represents LUKS2 keyslots metadata.
Expand Down

0 comments on commit f63c85d

Please sign in to comment.