Skip to content

Commit 22bcbbb

Browse files
authored
Blkid fix master
Adds a fix for a LUKS issue using blkid. Retain information about the device being blank before cryptsetup format, use this information instead of blkid to decide if we should file format.
1 parent a21d755 commit 22bcbbb

File tree

20 files changed

+314
-191
lines changed

20 files changed

+314
-191
lines changed

core/orchestrator_core.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4086,7 +4086,8 @@ func (o *TridentOrchestrator) AttachVolume(
40864086

40874087
// Cryptsetup format if necessary and map to host
40884088
var luksFormatted bool
4089-
luksFormatted, err = nvmeHandler.EnsureCryptsetupFormattedAndMappedOnHost(
4089+
var safeToFsFormat bool
4090+
luksFormatted, safeToFsFormat, err = nvmeHandler.EnsureCryptsetupFormattedAndMappedOnHost(
40904091
ctx, volumeName, publishInfo, map[string]string{},
40914092
)
40924093
if err != nil {
@@ -4095,7 +4096,7 @@ func (o *TridentOrchestrator) AttachVolume(
40954096

40964097
// Format and mount if necessary
40974098
if err = nvmeHandler.EnsureVolumeFormattedAndMounted(
4098-
ctx, volumeName, mountpoint, publishInfo, luksFormatted,
4099+
ctx, volumeName, mountpoint, publishInfo, luksFormatted, safeToFsFormat,
40994100
); err != nil {
41004101
return err
41014102
}
@@ -4110,7 +4111,8 @@ func (o *TridentOrchestrator) AttachVolume(
41104111
// Cryptsetup format if necessary and map to host
41114112
command := exec.NewCommand()
41124113
var luksFormatted bool
4113-
luksFormatted, err = luks.EnsureCryptsetupFormattedAndMappedOnHost(
4114+
var safeToFsFormat bool
4115+
luksFormatted, safeToFsFormat, err = luks.EnsureCryptsetupFormattedAndMappedOnHost(
41144116
ctx, volumeName, publishInfo, map[string]string{}, command, devices.New(),
41154117
)
41164118
if err != nil {
@@ -4119,7 +4121,7 @@ func (o *TridentOrchestrator) AttachVolume(
41194121

41204122
// Format and mount if necessary
41214123
if err = o.iscsi.EnsureVolumeFormattedAndMounted(
4122-
ctx, volumeName, mountpoint, publishInfo, luksFormatted,
4124+
ctx, volumeName, mountpoint, publishInfo, luksFormatted, safeToFsFormat,
41234125
); err != nil {
41244126
return err
41254127
}

frontend/csi/node_server.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ func (p *Plugin) nodeStageFCPVolume(
14071407
}
14081408

14091409
// Cryptsetup format if necessary and map to host
1410-
luksFormatted, err := luks.EnsureCryptsetupFormattedAndMappedOnHost(
1410+
luksFormatted, safeToFsFormat, err := luks.EnsureCryptsetupFormattedAndMappedOnHost(
14111411
ctx, req.VolumeContext["internalName"], publishInfo, req.GetSecrets(), p.command, p.devices,
14121412
)
14131413
if err != nil {
@@ -1416,7 +1416,7 @@ func (p *Plugin) nodeStageFCPVolume(
14161416

14171417
// Format and mount if necessary
14181418
if err = p.fcp.EnsureVolumeFormattedAndMounted(
1419-
ctx, req.VolumeContext["internalName"], "", publishInfo, luksFormatted,
1419+
ctx, req.VolumeContext["internalName"], "", publishInfo, luksFormatted, safeToFsFormat,
14201420
); err != nil {
14211421
return err
14221422
}
@@ -1885,7 +1885,7 @@ func (p *Plugin) nodeStageISCSIVolume(
18851885
}
18861886

18871887
// Cryptsetup format if necessary and map to host
1888-
luksFormatted, err := luks.EnsureCryptsetupFormattedAndMappedOnHost(
1888+
luksFormatted, safeToFsFormat, err := luks.EnsureCryptsetupFormattedAndMappedOnHost(
18891889
ctx, req.VolumeContext["internalName"], publishInfo, req.GetSecrets(), p.command, p.devices,
18901890
)
18911891
if err != nil {
@@ -1894,7 +1894,7 @@ func (p *Plugin) nodeStageISCSIVolume(
18941894

18951895
// Format and mount if necessary
18961896
if err = p.iscsi.EnsureVolumeFormattedAndMounted(
1897-
ctx, req.VolumeContext["internalName"], "", publishInfo, luksFormatted,
1897+
ctx, req.VolumeContext["internalName"], "", publishInfo, luksFormatted, safeToFsFormat,
18981898
); err != nil {
18991899
return err
19001900
}
@@ -3047,7 +3047,7 @@ func (p *Plugin) nodeStageNVMeVolume(
30473047
}
30483048

30493049
// Cryptsetup format if necessary and map to host
3050-
luksFormatted, err := p.nvmeHandler.EnsureCryptsetupFormattedAndMappedOnHost(
3050+
luksFormatted, safeToFormat, err := p.nvmeHandler.EnsureCryptsetupFormattedAndMappedOnHost(
30513051
ctx, req.VolumeContext["internalName"], publishInfo, req.GetSecrets(),
30523052
)
30533053
if err != nil {
@@ -3056,7 +3056,7 @@ func (p *Plugin) nodeStageNVMeVolume(
30563056

30573057
// Format and mount if necessary
30583058
if err = p.nvmeHandler.EnsureVolumeFormattedAndMounted(
3059-
ctx, req.VolumeContext["internalName"], "", publishInfo, luksFormatted,
3059+
ctx, req.VolumeContext["internalName"], "", publishInfo, luksFormatted, safeToFormat,
30603060
); err != nil {
30613061
return err
30623062
}

frontend/csi/node_server_test.go

Lines changed: 92 additions & 44 deletions
Large diffs are not rendered by default.

mocks/mock_utils/mock_devices/mock_luks/mock_luks.go

Lines changed: 8 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/mock_utils/mock_fcp/mock_fcp_client.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/mock_utils/mock_iscsi/mock_iscsi_client.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/mock_utils/nvme/mock_nvme_utils.go

Lines changed: 8 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utils/devices/luks/luks.go

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ func (o *osFs) ReadlinkIfPossible(name string) (string, error) {
7777
}
7878

7979
type Device interface {
80-
EnsureDeviceMappedOnHost(ctx context.Context, name string, secrets map[string]string) (bool, error)
80+
EnsureDeviceMappedOnHost(ctx context.Context, name string, secrets map[string]string) (bool, bool, error)
8181
MappedDevicePath() string
8282
MappedDeviceName() string
8383
RawDevicePath() string
84-
EnsureFormattedAndOpen(ctx context.Context, luksPassphrase string) (bool, error)
84+
EnsureFormattedAndOpen(ctx context.Context, luksPassphrase string) (bool, bool, error)
8585
CheckPassphrase(ctx context.Context, luksPassphrase string) (bool, error)
8686
RotatePassphrase(ctx context.Context, volumeId, previousLUKSPassphrase, luksPassphrase string) error
8787
IsMappingStale(ctx context.Context) bool
@@ -123,48 +123,48 @@ func NewDeviceFromMappingPath(
123123
}
124124

125125
// EnsureDeviceMappedOnHost ensures the specified device is LUKS formatted, opened, and has the current passphrase.
126-
func (d *LUKSDevice) EnsureDeviceMappedOnHost(ctx context.Context, name string, secrets map[string]string) (bool, error) {
126+
func (d *LUKSDevice) EnsureDeviceMappedOnHost(ctx context.Context, name string, secrets map[string]string) (bool, bool, error) {
127127
// Try to Open with current luks passphrase
128128
luksPassphraseName, luksPassphrase, previousLUKSPassphraseName, previousLUKSPassphrase := GetLUKSPassphrasesFromSecretMap(secrets)
129129
if luksPassphrase == "" {
130-
return false, errors.New("LUKS passphrase cannot be empty")
130+
return false, false, errors.New("LUKS passphrase cannot be empty")
131131
}
132132
if luksPassphraseName == "" {
133-
return false, errors.New("LUKS passphrase name cannot be empty")
133+
return false, false, errors.New("LUKS passphrase name cannot be empty")
134134
}
135135

136136
Logc(ctx).WithFields(LogFields{
137137
"volume": name,
138138
"luks-passphrase-name": luksPassphraseName,
139139
}).Info("Opening encrypted volume.")
140-
luksFormatted, err := d.EnsureFormattedAndOpen(ctx, luksPassphrase)
140+
luksFormatted, safeToFormat, err := d.EnsureFormattedAndOpen(ctx, luksPassphrase)
141141

142142
// If we fail due to a format issue there is no need to try to open the device.
143143
if err == nil || errors.IsFormatError(err) {
144-
return luksFormatted, err
144+
return luksFormatted, safeToFormat, err
145145
}
146146

147147
// If we failed to open, try previous passphrase
148148
if previousLUKSPassphrase == "" {
149149
// Return original error if there is no previous passphrase to use
150-
return luksFormatted, fmt.Errorf("could not open LUKS device; %v", err)
150+
return luksFormatted, safeToFormat, fmt.Errorf("could not open LUKS device; %v", err)
151151
}
152152
if luksPassphrase == previousLUKSPassphrase {
153-
return luksFormatted, errors.New("could not open LUKS device, previous passphrase matches current")
153+
return luksFormatted, safeToFormat, errors.New("could not open LUKS device, previous passphrase matches current")
154154
}
155155
if previousLUKSPassphraseName == "" {
156-
return luksFormatted, errors.New("could not open LUKS device, no previous passphrase name provided")
156+
return luksFormatted, safeToFormat, errors.New("could not open LUKS device, no previous passphrase name provided")
157157
}
158158
Logc(ctx).WithFields(LogFields{
159159
"volume": name,
160160
"luks-passphrase-name": previousLUKSPassphraseName,
161161
}).Info("Opening encrypted volume.")
162-
luksFormatted, err = d.EnsureFormattedAndOpen(ctx, previousLUKSPassphrase)
162+
luksFormatted, safeToFormat, err = d.EnsureFormattedAndOpen(ctx, previousLUKSPassphrase)
163163
if err != nil {
164-
return luksFormatted, fmt.Errorf("could not open LUKS device; %v", err)
164+
return luksFormatted, safeToFormat, fmt.Errorf("could not open LUKS device; %v", err)
165165
}
166166

167-
return luksFormatted, nil
167+
return luksFormatted, safeToFormat, nil
168168
}
169169

170170
// MappedDevicePath returns the location of the LUKS device when opened.
@@ -183,7 +183,11 @@ func (d *LUKSDevice) RawDevicePath() string {
183183
}
184184

185185
// EnsureFormattedAndOpen ensures the specified device is LUKS formatted and opened.
186-
func (d *LUKSDevice) EnsureFormattedAndOpen(ctx context.Context, luksPassphrase string) (formatted bool, err error) {
186+
// Returns two booleans: the first indicates if the device is crypt formatted,
187+
// the second indicates if the device is safe to file format, meaning the device was empty before being crypt formatted.
188+
func (d *LUKSDevice) EnsureFormattedAndOpen(ctx context.Context, luksPassphrase string) (
189+
formatted, safeToFileFormat bool, err error,
190+
) {
187191
return d.ensureLUKSDevice(ctx, luksPassphrase)
188192
}
189193

@@ -199,36 +203,41 @@ func (d *LUKSDevice) IsMappingStale(ctx context.Context) bool {
199203
return d.isMappingStale(ctx)
200204
}
201205

202-
func (d *LUKSDevice) ensureLUKSDevice(ctx context.Context, luksPassphrase string) (bool, error) {
206+
// ensureLUKSDevice ensures the device is LUKS formatted and opened.
207+
// Returns two booleans: the first indicates if the device is formatted,
208+
// the second indicates if the device is safe to file format, meaning the device was empty before being crypt formatted.
209+
func (d *LUKSDevice) ensureLUKSDevice(ctx context.Context, luksPassphrase string) (bool, bool, error) {
203210
// First check if LUKS device is already opened. This is OK to check even if the device isn't LUKS formatted.
204211
if isOpen, err := d.IsOpen(ctx); err != nil {
205212
// If the LUKS device isn't found, it means that we need to check if the device is LUKS formatted.
206213
// If it isn't, then we should format it and attempt to open it.
207214
// If any other error occurs, bail out.
208215
if !errors.IsNotFoundError(err) {
209216
Logc(ctx).WithError(err).Error("Could not check if device is an open LUKS device.")
210-
return false, err
217+
return false, false, err
211218
}
212219
} else if isOpen {
213220
Logc(ctx).Debug("Device is LUKS formatted and open.")
214-
return true, nil
221+
return true, false, nil
215222
}
216223

217-
if err := d.formatUnformattedDevice(ctx, luksPassphrase); err != nil {
224+
var safeToFileFormat bool
225+
var err error
226+
if safeToFileFormat, err = d.formatUnformattedDevice(ctx, luksPassphrase); err != nil {
218227
Logc(ctx).WithError(err).Error("Could not LUKS format device.")
219-
return false, fmt.Errorf("could not LUKS format device; %w", err)
228+
return false, safeToFileFormat, fmt.Errorf("could not LUKS format device; %w", err)
220229
}
221230

222231
// At this point, we should be able to open the device.
223232
if err := d.Open(ctx, luksPassphrase); err != nil {
224233
// At this point, we couldn't open the LUKS device, but we do know
225234
// the device is LUKS formatted because LUKSFormat didn't fail.
226235
Logc(ctx).WithError(err).Error("Could not open LUKS formatted device.")
227-
return true, fmt.Errorf("could not open LUKS device; %v", err)
236+
return true, safeToFileFormat, fmt.Errorf("could not open LUKS device; %v", err)
228237
}
229238

230239
Logc(ctx).Debug("Device is LUKS formatted and open.")
231-
return true, nil
240+
return true, safeToFileFormat, nil
232241
}
233242

234243
func GetLUKSPassphrasesFromSecretMap(secrets map[string]string) (string, string, string, string) {
@@ -283,22 +292,23 @@ func IsLuksDevice(publishInfo *models.VolumePublishInfo) (bool, error) {
283292
func EnsureCryptsetupFormattedAndMappedOnHost(
284293
ctx context.Context, name string, publishInfo *models.VolumePublishInfo, secrets map[string]string, command execCmd.Command,
285294
devices devices.Devices,
286-
) (bool, error) {
295+
) (bool, bool, error) {
287296
Logc(ctx).Debug(">>>> EnsureCryptsetupFormattedAndMappedOnHost")
288297
defer Logc(ctx).Debug("<<<< EnsureCryptsetupFormattedAndMappedOnHost")
289298

290299
isLUKSDevice, err := IsLuksDevice(publishInfo)
291300
if err != nil {
292-
return isLUKSDevice, err
301+
return isLUKSDevice, false, err
293302
}
294303

295304
var luksFormatted bool
305+
var safeToFsFormat bool
296306
if isLUKSDevice {
297307
luksDevice := NewDevice(publishInfo.DevicePath, name, command, devices)
298-
luksFormatted, err = luksDevice.EnsureDeviceMappedOnHost(ctx, name, secrets)
308+
luksFormatted, safeToFsFormat, err = luksDevice.EnsureDeviceMappedOnHost(ctx, name, secrets)
299309
if err != nil {
300-
return luksFormatted, err
310+
return luksFormatted, safeToFsFormat, err
301311
}
302312
}
303-
return luksFormatted, nil
313+
return luksFormatted, safeToFsFormat, nil
304314
}

utils/devices/luks/luks_darwin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ func (d *LUKSDevice) IsOpen(ctx context.Context) (bool, error) {
3838

3939
// formatUnformattedDevice attempts to set up LUKS headers on a device with the specified passphrase, but bails if the
4040
// underlying device already has a format present that is not LUKS.
41-
func (d *LUKSDevice) formatUnformattedDevice(ctx context.Context, _ string) error {
41+
func (d *LUKSDevice) formatUnformattedDevice(ctx context.Context, _ string) (bool, error) {
4242
Logc(ctx).Debug(">>>> devices_darwin.formatUnformattedDevice")
4343
defer Logc(ctx).Debug("<<<< devices_darwin.formatUnformattedDevice")
44-
return errors.UnsupportedError("formatUnformattedDevice is not supported for darwin")
44+
return false, errors.UnsupportedError("formatUnformattedDevice is not supported for darwin")
4545
}
4646

4747
// Open makes the device accessible on the host

0 commit comments

Comments
 (0)