rbd: fix topology snapshot pool

Restoring a snapshot with a new PVC results with a wrong
dataPoolName in case of initial volume linked
to a storageClass with topology constraints and erasure coding.

Signed-off-by: Thibaut Blanchard <thibaut.blanchard@gmail.com>
This commit is contained in:
Thibaut Blanchard 2022-03-08 13:45:01 +01:00 committed by mergify[bot]
parent 134603540b
commit e874c9c11b
3 changed files with 17 additions and 15 deletions

View File

@ -267,7 +267,7 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
rv.RbdImageName = imageData.ImageAttributes.ImageName rv.RbdImageName = imageData.ImageAttributes.ImageName
rv.ImageID = imageData.ImageAttributes.ImageID rv.ImageID = imageData.ImageAttributes.ImageID
// check if topology constraints match what is found // check if topology constraints match what is found
rv.Topology, err = util.MatchTopologyForPool(rv.TopologyPools, rv.TopologyRequirement, _, _, rv.Topology, err = util.MatchPoolAndTopology(rv.TopologyPools, rv.TopologyRequirement,
imageData.ImagePool) imageData.ImagePool)
if err != nil { if err != nil {
// TODO check if need any undo operation here, or ErrVolNameConflict // TODO check if need any undo operation here, or ErrVolNameConflict
@ -412,7 +412,10 @@ func updateTopologyConstraints(rbdVol *rbdVolume, rbdSnap *rbdSnapshot) error {
var err error var err error
if rbdSnap != nil { if rbdSnap != nil {
// check if topology constraints matches snapshot pool // check if topology constraints matches snapshot pool
rbdVol.Topology, err = util.MatchTopologyForPool(rbdVol.TopologyPools, var poolName string
var dataPoolName string
poolName, dataPoolName, rbdVol.Topology, err = util.MatchPoolAndTopology(rbdVol.TopologyPools,
rbdVol.TopologyRequirement, rbdSnap.Pool) rbdVol.TopologyRequirement, rbdSnap.Pool)
if err != nil { if err != nil {
return err return err
@ -420,7 +423,8 @@ func updateTopologyConstraints(rbdVol *rbdVolume, rbdSnap *rbdSnapshot) error {
// update Pool, if it was topology constrained // update Pool, if it was topology constrained
if rbdVol.Topology != nil { if rbdVol.Topology != nil {
rbdVol.Pool = rbdSnap.Pool rbdVol.Pool = poolName
rbdVol.DataPool = dataPoolName
} }
return nil return nil

View File

@ -168,14 +168,14 @@ func GetTopologyFromRequest(
return &topologyPools, accessibilityRequirements, nil return &topologyPools, accessibilityRequirements, nil
} }
// MatchTopologyForPool returns the topology map, if the passed in pool matches any // MatchPoolAndTopology returns the topology map, if the passed in pool matches any
// passed in accessibility constraints. // passed in accessibility constraints.
func MatchTopologyForPool(topologyPools *[]TopologyConstrainedPool, func MatchPoolAndTopology(topologyPools *[]TopologyConstrainedPool,
accessibilityRequirements *csi.TopologyRequirement, poolName string) (map[string]string, error) { accessibilityRequirements *csi.TopologyRequirement, poolName string) (string, string, map[string]string, error) {
var topologyPool []TopologyConstrainedPool var topologyPool []TopologyConstrainedPool
if topologyPools == nil || accessibilityRequirements == nil { if topologyPools == nil || accessibilityRequirements == nil {
return nil, nil return "", "", nil, nil
} }
// find the pool in the list of topology based pools // find the pool in the list of topology based pools
@ -187,13 +187,11 @@ func MatchTopologyForPool(topologyPools *[]TopologyConstrainedPool,
} }
} }
if len(topologyPool) == 0 { if len(topologyPool) == 0 {
return nil, fmt.Errorf("none of the configured topology pools (%+v) matched passed in pool name (%s)", return "", "", nil, fmt.Errorf("none of the configured topology pools (%+v) matched passed in pool name (%s)",
topologyPools, poolName) topologyPools, poolName)
} }
_, _, topology, err := FindPoolAndTopology(&topologyPool, accessibilityRequirements) return FindPoolAndTopology(&topologyPool, accessibilityRequirements)
return topology, err
} }
// FindPoolAndTopology loops through passed in "topologyPools" and also related // FindPoolAndTopology loops through passed in "topologyPools" and also related

View File

@ -37,7 +37,7 @@ func checkAndReportError(t *testing.T, msg string, err error) {
} }
} }
// TestFindPoolAndTopology also tests MatchTopologyForPool. // TestFindPoolAndTopology also tests MatchPoolAndTopology.
func TestFindPoolAndTopology(t *testing.T) { func TestFindPoolAndTopology(t *testing.T) {
t.Parallel() t.Parallel()
var err error var err error
@ -319,15 +319,15 @@ func TestFindPoolAndTopology(t *testing.T) {
t.Errorf("expected data pool to be named ec-%s, got %s", poolName, dataPoolName) t.Errorf("expected data pool to be named ec-%s, got %s", poolName, dataPoolName)
} }
// TEST: MatchTopologyForPool // TEST: MatchPoolAndTopology
// check for non-existent pool // check for non-existent pool
_, err = MatchTopologyForPool(&validMultipleTopoPools, &validAccReq, pool1+"fuzz") _, _, _, err = MatchPoolAndTopology(&validMultipleTopoPools, &validAccReq, pool1+"fuzz")
if err == nil { if err == nil {
t.Errorf("expected failure due to non-existent pool name (%s) got success", pool1+"fuzz") t.Errorf("expected failure due to non-existent pool name (%s) got success", pool1+"fuzz")
} }
// check for existing pool // check for existing pool
topoSegment, err = MatchTopologyForPool(&validMultipleTopoPools, &validAccReq, pool1) _, _, topoSegment, err = MatchPoolAndTopology(&validMultipleTopoPools, &validAccReq, pool1)
err = checkOutput(err, pool1, topoSegment) err = checkOutput(err, pool1, topoSegment)
checkAndReportError(t, "expected success got:", err) checkAndReportError(t, "expected success got:", err)
} }