-
Notifications
You must be signed in to change notification settings - Fork 551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rbd: prevent calling rbdVolume.Destroy() after an error #4564
base: devel
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1070,6 +1070,8 @@ func updateSnapshotDetails(rbdSnap *rbdSnapshot) error { | |
} | ||
|
||
// generateVolumeFromVolumeID generates a rbdVolume structure from the provided identifier. | ||
// The returned rbdVolume is connected in case no error occurred, and should be | ||
// cleaned up with rbdVolume.Destroy(). | ||
func generateVolumeFromVolumeID( | ||
ctx context.Context, | ||
volumeID string, | ||
|
@@ -1116,6 +1118,13 @@ func generateVolumeFromVolumeID( | |
if err != nil { | ||
return rbdVol, err | ||
} | ||
// in case of any error call Destroy for cleanup. | ||
defer func() { | ||
if err != nil { | ||
rbdVol.Destroy() | ||
} | ||
}() | ||
|
||
rbdVol.JournalPool = rbdVol.Pool | ||
|
||
imageAttributes, err := j.GetImageAttributes( | ||
|
@@ -1163,6 +1172,8 @@ func generateVolumeFromVolumeID( | |
|
||
// GenVolFromVolID generates a rbdVolume structure from the provided identifier, updating | ||
// the structure with elements from on-disk image metadata as well. | ||
// The returned rbdVolume is connected in case no error occurred, and should be | ||
// cleaned up with rbdVolume.Destroy(). | ||
func GenVolFromVolID( | ||
ctx context.Context, | ||
volumeID string, | ||
|
@@ -1185,17 +1196,27 @@ func GenVolFromVolID( | |
!errors.Is(err, ErrImageNotFound) { | ||
return vol, err | ||
} | ||
defer func() { | ||
if err != nil { | ||
vol.Destroy() | ||
} | ||
}() | ||
|
||
// Check clusterID mapping exists | ||
mapping, mErr := util.GetClusterMappingInfo(vi.ClusterID) | ||
if mErr != nil { | ||
return vol, mErr | ||
mapping, err := util.GetClusterMappingInfo(vi.ClusterID) | ||
if err != nil { | ||
return vol, err | ||
} | ||
if mapping != nil { | ||
rbdVol, vErr := generateVolumeFromMapping(ctx, mapping, volumeID, vi, cr, secrets) | ||
if !errors.Is(vErr, util.ErrKeyNotFound) && !errors.Is(vErr, util.ErrPoolNotFound) && | ||
!errors.Is(vErr, ErrImageNotFound) { | ||
return rbdVol, vErr | ||
// create a new volume based on the mapping, cleanup the old volume | ||
if vol != nil { | ||
vol.Destroy() | ||
} | ||
Comment on lines
+1212
to
+1214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when will we hit this one? In case of error we are already doing the Destory and in case of non-nil error case the vol is returned at line 1197 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not clear to me if this can be hit, better destroy something that could have been at line 1194. If the |
||
|
||
vol, err = generateVolumeFromMapping(ctx, mapping, volumeID, vi, cr, secrets) | ||
if !errors.Is(err, util.ErrKeyNotFound) && !errors.Is(err, util.ErrPoolNotFound) && | ||
!errors.Is(err, ErrImageNotFound) { | ||
return vol, err | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case of err the volume is already destroyed above, do we need to destroy it again? if yes , can you please add check check for
vol !=nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generateVolumeFromVolumeID()
should now only return a connected volume if no error occurred. But it is possible that this function itself detects an error below. In that case, the.Destroy()
function should be called too.Destroying a volume that is already destroyed is fine, extra checks for that just make the code more complex.