Skip to content

Commit 903daef

Browse files
committed
cephfs: address review feedback on MDS pinning
Handle several review comments on the VolumeAttributesClass MDS pinning support: - Purge the freshly created subvolume when applying the mutable parameters fails in CreateVolume, so a failed pin does not leave an orphaned subvolume behind. The already-existing subvolume path is left untouched on failure. - Reject unknown mutable parameters in validateMDSPinParameters and return InvalidArgument, as recommended by the CSI spec for unsupported parameters. - Return NotFound (instead of InvalidArgument) from ControllerModifyVolume when the volume backing the given ID cannot be found, and Internal for other resolution errors. - Log the manager command status and output returned when pinning a subvolume. - Clarify the PinVolume documentation to describe the valid pin setting value for each pin type. Assisted-by: goose <noreply@block.xyz> Signed-off-by: Ismael Puerto Freire <ismaelpf@inditex.com>
1 parent b8b5c07 commit 903daef

3 files changed

Lines changed: 48 additions & 14 deletions

File tree

internal/cephfs/controllerserver.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@ func (cs *cephfsControllerServer) CreateVolume(
413413
}
414414

415415
// apply MutableParameters (e.g. MDS pinning) from a
416-
// VolumeAttributesClass, if any were requested.
416+
// VolumeAttributesClass, if any were requested. The subvolume already
417+
// existed before this request, so it must not be purged on failure.
417418
if len(req.GetMutableParameters()) != 0 {
418419
if err = applyMutableParameters(ctx, volClient, vID.FsSubvolName,
419420
req.GetMutableParameters()); err != nil {
@@ -496,10 +497,17 @@ func (cs *cephfsControllerServer) CreateVolume(
496497
vID.FsSubvolName, requestName)
497498

498499
// apply MutableParameters (e.g. MDS pinning) from a VolumeAttributesClass,
499-
// if any were requested.
500+
// if any were requested. On failure the freshly created subvolume must be
501+
// purged to avoid leaving an orphaned subvolume behind (the deferred
502+
// UndoVolReservation only cleans up the reservation/OMAP entry).
500503
if len(req.GetMutableParameters()) != 0 {
501504
if err = applyMutableParameters(ctx, volClient, vID.FsSubvolName,
502505
req.GetMutableParameters()); err != nil {
506+
if purgeErr := volClient.PurgeVolume(ctx, true); purgeErr != nil {
507+
log.ErrorLog(ctx, "failed to purge subvolume %s after applying mutable "+
508+
"parameters failed: %v", vID.FsSubvolName, purgeErr)
509+
}
510+
503511
return nil, err
504512
}
505513
}
@@ -1514,17 +1522,25 @@ var mdsPinParams = []string{paramMDSPinExport, paramMDSPinDistributed, paramMDSP
15141522
// returns the CephFS pin type and setting to apply.
15151523
//
15161524
// The three pin parameters (mds-pin-export, mds-pin-distributed,
1517-
// mds-pin-random) are mutually exclusive: at most one may be set. It returns:
1525+
// mds-pin-random) are mutually exclusive: at most one may be set. Any parameter
1526+
// key that is not a recognized MDS pin parameter is rejected, as recommended by
1527+
// the CSI spec for unsupported mutable parameters. It returns:
15181528
// - ("", "", nil) when no MDS pin parameter is present
15191529
// - (pinType, pinSetting, nil) when exactly one is present with a valid value
1520-
// - ("", "", err) when more than one is present, or the value
1521-
// is invalid for the given pin type
1530+
// - ("", "", err) when an unknown parameter is present, more
1531+
// than one is present, or the value is invalid for the given pin type
15221532
func validateMDSPinParameters(params map[string]string) (string, string, error) {
15231533
var (
15241534
selected string
15251535
setting string
15261536
)
15271537

1538+
for key := range params {
1539+
if _, ok := mdsPinParamToType[key]; !ok {
1540+
return "", "", fmt.Errorf("unsupported mutable parameter %q", key)
1541+
}
1542+
}
1543+
15281544
for _, key := range mdsPinParams {
15291545
value, ok := params[key]
15301546
if !ok {
@@ -1663,7 +1679,13 @@ func (cs *cephfsControllerServer) ControllerModifyVolume(
16631679
if err != nil {
16641680
log.ErrorLog(ctx, "validation and extraction of volume options failed: %v", err)
16651681

1666-
return nil, status.Error(codes.InvalidArgument, err.Error())
1682+
// the volume backing the given ID could not be found.
1683+
if errors.Is(err, cerrors.ErrVolumeNotFound) || errors.Is(err, util.ErrKeyNotFound) ||
1684+
errors.Is(err, util.ErrPoolNotFound) {
1685+
return nil, status.Error(codes.NotFound, err.Error())
1686+
}
1687+
1688+
return nil, status.Error(codes.Internal, err.Error())
16671689
}
16681690
defer volOptions.Destroy()
16691691

internal/cephfs/controllerserver_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,17 @@ func TestValidateMDSPinParameters(t *testing.T) {
4040
wantErr: false,
4141
},
4242
{
43-
name: "unrelated parameters only",
44-
params: map[string]string{"foo": "bar"},
45-
wantType: "",
46-
wantSetting: "",
47-
wantErr: false,
43+
name: "unrelated parameters only",
44+
params: map[string]string{"foo": "bar"},
45+
wantErr: true,
46+
},
47+
{
48+
name: "unknown parameter mixed with a valid pin",
49+
params: map[string]string{
50+
paramMDSPinExport: "1",
51+
"foo": "bar",
52+
},
53+
wantErr: true,
4854
},
4955
{
5056
name: "export pin with valid rank",

internal/cephfs/core/volume.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,11 @@ type SubVolumeClient interface {
9191
ListMetadata() (map[string]string, error)
9292

9393
// PinVolume sets an MDS pinning policy on the subvolume.
94-
// pinType can be "export", "distributed" or "random".
95-
// pinSetting is the value for the pin (e.g. MDS rank "2", "true", etc.).
94+
// pinType is one of "export", "distributed" or "random".
95+
// pinSetting is the value for the pin, its meaning depends on pinType:
96+
// - export: MDS rank as an integer (e.g. "2"), or "-1" to unpin
97+
// - distributed: "1" to enable or "0" to disable
98+
// - random: a float in the range 0.0-1.0
9699
PinVolume(ctx context.Context, pinType, pinSetting string) error
97100
}
98101

@@ -359,11 +362,14 @@ func (s *subVolumeClient) PinVolume(ctx context.Context, pinType, pinSetting str
359362
return fmt.Errorf("failed to marshal pin command for subvolume %s: %w", s.VolID, err)
360363
}
361364

362-
_, _, err = s.conn.MgrCommand([][]byte{buf})
365+
out, status, err := s.conn.MgrCommand([][]byte{buf})
363366
if err != nil {
364367
return fmt.Errorf("failed to pin subvolume %s in fs %s (group %s): %w",
365368
s.VolID, s.FsName, s.SubvolumeGroup, err)
366369
}
367370

371+
log.DebugLog(ctx, "cephfs: pinned subvolume %s in fs %s (group %s), type=%s setting=%s: status=%q output=%q",
372+
s.VolID, s.FsName, s.SubvolumeGroup, pinType, pinSetting, status, string(out))
373+
368374
return nil
369375
}

0 commit comments

Comments
 (0)