Skip to content

Commit aa1cf88

Browse files
committed
Add NodeStageVolume disk size validation before mounting
1 parent 0898415 commit aa1cf88

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

pkg/common/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const (
4848

4949
ContextDataCacheSize = "data-cache-size"
5050
ContextDataCacheMode = "data-cache-mode"
51+
ContextDiskSizeGB = "disk-size"
5152

5253
// Keys in the publish context
5354
ContexLocalSsdCacheSize = "local-ssd-cache-size"

pkg/gce-pd-csi-driver/controller.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"math/rand"
2222
neturl "net/url"
2323
"sort"
24+
"strconv"
2425
"strings"
2526
"time"
2627

@@ -1113,7 +1114,7 @@ func (gceCS *GCEControllerServer) executeControllerPublishVolume(ctx context.Con
11131114
volumeCapability := req.GetVolumeCapability()
11141115

11151116
pubVolResp := &csi.ControllerPublishVolumeResponse{
1116-
PublishContext: nil,
1117+
PublishContext: map[string]string{},
11171118
}
11181119

11191120
// Set data cache publish context
@@ -1162,6 +1163,7 @@ func (gceCS *GCEControllerServer) executeControllerPublishVolume(ctx context.Con
11621163
}
11631164
return nil, common.LoggedError("Failed to getDisk: ", err), disk
11641165
}
1166+
pubVolResp.PublishContext[common.ContextDiskSizeGB] = strconv.FormatInt(disk.GetSizeGb(), 10)
11651167
instance, err := gceCS.CloudProvider.GetInstanceOrError(ctx, project, instanceZone, instanceName)
11661168
if err != nil {
11671169
if gce.IsGCENotFoundError(err) {

pkg/gce-pd-csi-driver/node.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,17 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
446446
klog.V(4).Infof("CSI volume is read-only, mounting with extra option ro")
447447
}
448448

449+
// If a disk size is provided in the publish context, ensure it matches the actual device size.
450+
if expectedSize := req.GetPublishContext()[common.ContextDiskSizeGB]; expectedSize != "" {
451+
actualSize, err := getBlockSizeBytes(devicePath, ns.Mounter)
452+
if err != nil {
453+
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to get block size for '%s': %v", devicePath, err.Error()))
454+
}
455+
if expectedSize != strconv.FormatInt(actualSize, 10) {
456+
return nil, status.Error(codes.Internal, fmt.Sprintf("expected block size %q, got %q", expectedSize, strconv.FormatInt(actualSize, 10)))
457+
}
458+
}
459+
449460
err = ns.formatAndMount(devicePath, stagingTargetPath, fstype, options, ns.Mounter)
450461
if err != nil {
451462
// If a volume is created from a content source like snapshot or cloning, the filesystem might get marked

pkg/gce-pd-csi-driver/node_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"google.golang.org/grpc/codes"
3434
"google.golang.org/grpc/status"
3535
"k8s.io/mount-utils"
36+
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/common"
3637
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/deviceutils"
3738
metadataservice "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-cloud-provider/metadata"
3839
mountmanager "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/mount-manager"
@@ -1118,6 +1119,41 @@ func TestNodeStageVolume(t *testing.T) {
11181119
},
11191120
},
11201121
},
1122+
{
1123+
name: "Valid request with disk size check",
1124+
req: &csi.NodeStageVolumeRequest{
1125+
VolumeId: volumeID,
1126+
StagingTargetPath: stagingPath,
1127+
VolumeCapability: stdVolCap,
1128+
PublishContext: map[string]string{common.ContextDiskSizeGB: "1"},
1129+
},
1130+
deviceSize: 1,
1131+
blockExtSize: 1,
1132+
readonlyBit: "1",
1133+
expResize: false,
1134+
expCommandList: []fakeCmd{
1135+
{
1136+
cmd: "blockdev",
1137+
args: "--getsize64 /dev/disk/fake-path",
1138+
stdout: "%v",
1139+
},
1140+
{
1141+
cmd: "blkid",
1142+
args: "-p -s TYPE -s PTTYPE -o export /dev/disk/fake-path",
1143+
stdout: "DEVNAME=/dev/sdb\nTYPE=%v",
1144+
},
1145+
{
1146+
cmd: "fsck",
1147+
args: "-a /dev/disk/fake-path",
1148+
stdout: "",
1149+
},
1150+
{
1151+
cmd: "blockdev",
1152+
args: "--getro /dev/disk/fake-path",
1153+
stdout: "%v",
1154+
},
1155+
},
1156+
},
11211157
{
11221158
name: "Invalid request (Bad Access Mode)",
11231159
req: &csi.NodeStageVolumeRequest{
@@ -1197,6 +1233,24 @@ func TestNodeStageVolume(t *testing.T) {
11971233
},
11981234
expErrCode: codes.InvalidArgument,
11991235
},
1236+
{
1237+
name: "Invalid request, block size mismatch",
1238+
req: &csi.NodeStageVolumeRequest{
1239+
VolumeId: volumeID,
1240+
StagingTargetPath: stagingPath,
1241+
VolumeCapability: stdVolCap,
1242+
PublishContext: map[string]string{common.ContextDiskSizeGB: "10"},
1243+
},
1244+
deviceSize: 5,
1245+
expErrCode: codes.Internal,
1246+
expCommandList: []fakeCmd{
1247+
{
1248+
cmd: "blockdev",
1249+
args: "--getsize64 /dev/disk/fake-path",
1250+
stdout: "%v",
1251+
},
1252+
},
1253+
},
12001254
}
12011255
for _, tc := range testCases {
12021256
t.Run(tc.name, func(t *testing.T) {

0 commit comments

Comments
 (0)