Skip to content

Commit bad0711

Browse files
committed
feat: enforce SINGLE_NODE_SINGLE_WRITER access mode in node publish
Return FAILED_PRECONDITION if a volume in NodePublish uses the SINGLE_NODE_SINGLE_WRITER access mode and is already mounted elsewhere on the node. See the second table in this section for more details: https://github.com/container-storage-interface/spec/blob/v1.7.0/spec.md#nodepublishvolume
1 parent 047a69b commit bad0711

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

pkg/hostpath/nodeserver.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ import (
3131
"k8s.io/utils/mount"
3232
)
3333

34-
const TopologyKeyNode = "topology.hostpath.csi/node"
34+
const (
35+
TopologyKeyNode = "topology.hostpath.csi/node"
3536

36-
func (hp *hostPath) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) {
37+
failedPreconditionAccessModeConflict = "volume uses SINGLE_NODE_SINGLE_WRITER access mode and is already mounted at a different target path"
38+
)
3739

40+
func (hp *hostPath) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) {
3841
// Check arguments
3942
if req.GetVolumeCapability() == nil {
4043
return nil, status.Error(codes.InvalidArgument, "Volume capability missing in request")
@@ -82,6 +85,10 @@ func (hp *hostPath) NodePublishVolume(ctx context.Context, req *csi.NodePublishV
8285
return nil, status.Error(codes.NotFound, err.Error())
8386
}
8487

88+
if hasSingleNodeSingleWriterAccessMode(req) && isMountedElsewhere(req, vol) {
89+
return nil, status.Error(codes.FailedPrecondition, failedPreconditionAccessModeConflict)
90+
}
91+
8592
if !ephemeralVolume {
8693
if vol.Staged.Empty() {
8794
return nil, status.Errorf(codes.FailedPrecondition, "volume %q must be staged before publishing", vol.VolID)
@@ -521,3 +528,21 @@ func makeFile(pathname string) error {
521528
}
522529
return nil
523530
}
531+
532+
// hasSingleNodeSingleWriterAccessMode checks if the publish request uses the
533+
// SINGLE_NODE_SINGLE_WRITER access mode.
534+
func hasSingleNodeSingleWriterAccessMode(req *csi.NodePublishVolumeRequest) bool {
535+
accessMode := req.GetVolumeCapability().GetAccessMode()
536+
return accessMode != nil && accessMode.GetMode() == csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER
537+
}
538+
539+
// isMountedElsewhere checks if the volume to publish is mounted elsewhere on
540+
// the node.
541+
func isMountedElsewhere(req *csi.NodePublishVolumeRequest, vol state.Volume) bool {
542+
for _, targetPath := range vol.Published {
543+
if targetPath != req.GetTargetPath() {
544+
return true
545+
}
546+
}
547+
return false
548+
}

0 commit comments

Comments
 (0)