Skip to content

Commit 5adce2f

Browse files
handerajatl-technicore
authored andcommitted
Add Raw Block Volume support
1 parent 2e2a189 commit 5adce2f

File tree

14 files changed

+1662
-297
lines changed

14 files changed

+1662
-297
lines changed

pkg/csi-util/utils.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"net"
2121
"os"
2222
"os/exec"
23+
"path/filepath"
2324
"regexp"
2425
"strconv"
2526
"strings"
@@ -69,7 +70,6 @@ const (
6970

7071
InTransitEncryptionPackageName = "oci-fss-utils"
7172
FIPS_ENABLED_FILE_PATH = "/host/proc/sys/crypto/fips_enabled"
72-
FINDMNT_COMMAND = "findmnt"
7373
CAT_COMMAND = "cat"
7474
RPM_COMMAND = "rpm-host"
7575
LabelIpFamilyPreferred = "oci.oraclecloud.com/ip-family-preferred"
@@ -79,6 +79,9 @@ const (
7979

8080
Ipv6Stack = "IPv6"
8181
Ipv4Stack = "IPv4"
82+
83+
// For Raw Block Volumes, the name of the bind-mounted file inside StagingTargetPath
84+
RawBlockStagingFile = "mountfile"
8285
)
8386

8487
// Util interface
@@ -255,6 +258,37 @@ func GetKubeClient(logger *zap.SugaredLogger, master, kubeconfig string) *kubern
255258
return kubeClientSet
256259
}
257260

261+
// Get the staging target filepath inside the given stagingTargetPath, to be used for raw block volume support
262+
func GetPathForBlock(volumePath string) string {
263+
pathForBlock := filepath.Join(volumePath, RawBlockStagingFile)
264+
return pathForBlock
265+
}
266+
267+
// Creates a file on the specified path after creating the containing directory
268+
func CreateFilePath(logger *zap.SugaredLogger, path string) error {
269+
pathDir := filepath.Dir(path)
270+
271+
err := os.MkdirAll(pathDir, 0750)
272+
if err != nil {
273+
logger.With(zap.Error(err)).Fatal("failed to create surrounding directory")
274+
return err
275+
}
276+
277+
file, fileErr := os.OpenFile(path, os.O_CREATE, 0640)
278+
if fileErr != nil && !os.IsExist(fileErr) {
279+
logger.With(zap.Error(err)).Fatal("failed to create/open the target file")
280+
return fileErr
281+
}
282+
283+
fileErr = file.Close()
284+
if fileErr != nil {
285+
logger.With(zap.Error(err)).Fatal("failed to close the target file")
286+
return fileErr
287+
}
288+
289+
return nil
290+
}
291+
258292
func MaxOfInt(a, b int64) int64 {
259293
if a > b {
260294
return a
@@ -417,18 +451,6 @@ func IsInTransitEncryptionPackageInstalled() (bool, error) {
417451
return false, nil
418452
}
419453

420-
func FindMount(target string) ([]string, error) {
421-
mountArgs := []string{"-n", "-o", "SOURCE", "-T", target}
422-
command := exec.Command(FINDMNT_COMMAND, mountArgs...)
423-
output, err := command.CombinedOutput()
424-
if err != nil {
425-
return nil, fmt.Errorf("findmnt failed: %v\narguments: %s\nOutput: %v\n", err, mountArgs, string(output))
426-
}
427-
428-
sources := strings.Fields(string(output))
429-
return sources, nil
430-
}
431-
432454
func GetBlockSizeBytes(logger *zap.SugaredLogger, devicePath string) (int64, error) {
433455
args := []string{"--getsize64", devicePath}
434456
cmd := exec.Command("blockdev", args...)

pkg/csi/driver/bv_controller.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ func (d *BlockVolumeControllerDriver) CreateVolume(ctx context.Context, req *csi
244244

245245
availableDomainShortName := ""
246246
volumeName := req.Name
247-
248247
dimensionsMap := make(map[string]string)
249248

250249
volumeParams, err := extractVolumeParameters(log, req.GetParameters())
@@ -256,6 +255,14 @@ func (d *BlockVolumeControllerDriver) CreateVolume(ctx context.Context, req *csi
256255
return nil, status.Errorf(codes.InvalidArgument, "failed to parse storageclass parameters %v", err)
257256
}
258257

258+
// Return error for the case of Raw Block Volume with Ultra High Performance Volumes
259+
for _, cap := range req.VolumeCapabilities {
260+
if blk := cap.GetBlock(); blk != nil && volumeParams.vpusPerGB >= 30 {
261+
log.Error("volumeMode is set to Block for an Ultra High Performance Volume, which is not supported")
262+
return nil, status.Errorf(codes.InvalidArgument, "failed to support Block volumeMode for Ultra High Performance Volumes (vpusPerGB >= 30)")
263+
}
264+
}
265+
259266
dimensionsMap[metrics.ResourceOCIDDimension] = volumeName
260267
dimensionsMap[metrics.VolumeVpusPerGBDimension] = strconv.Itoa(int(volumeParams.vpusPerGB))
261268

@@ -972,8 +979,7 @@ func (d *BlockVolumeControllerDriver) validateCapabilities(caps []*csi.VolumeCap
972979

973980
for _, cap := range caps {
974981
if blk := cap.GetBlock(); blk != nil {
975-
d.logger.Error("volumeMode is set to Block which is not supported.")
976-
return fmt.Errorf("driver does not support Block volumeMode. Please use Filesystem mode")
982+
d.logger.Info("The requested volume mode is set to Block")
977983
}
978984
if hasSupport(cap.AccessMode.Mode) {
979985
continue

pkg/csi/driver/bv_controller_test.go

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -954,21 +954,94 @@ func TestControllerDriver_CreateVolume(t *testing.T) {
954954
wantErr: errors.New("required in PreferredTopologies or allowedTopologies"),
955955
},
956956
{
957-
name: "Error for unsupported volumeMode Block",
957+
name: "No error when a volume is created in block mode",
958+
args: args{
959+
ctx: context.TODO(),
960+
req: &csi.CreateVolumeRequest{
961+
Name: "volume-in-available-state",
962+
VolumeCapabilities: []*csi.VolumeCapability{
963+
{
964+
AccessMode: &csi.VolumeCapability_AccessMode{
965+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
966+
},
967+
AccessType: &csi.VolumeCapability_Block{
968+
Block: &csi.VolumeCapability_BlockVolume{},
969+
},
970+
},
971+
},
972+
Parameters: map[string]string{
973+
"vpusPerGB": "10",
974+
},
975+
CapacityRange: &csi.CapacityRange{
976+
RequiredBytes: int64(50000),
977+
},
978+
AccessibilityRequirements: &csi.TopologyRequirement{
979+
Requisite: []*csi.Topology{
980+
{
981+
Segments: map[string]string{
982+
kubeAPI.LabelZoneFailureDomain: "PHX-AD-2",
983+
},
984+
}, {
985+
Segments: map[string]string{
986+
kubeAPI.LabelZoneFailureDomain: "PHX-AD-2",
987+
},
988+
},
989+
},
990+
},
991+
},
992+
},
993+
want: &csi.CreateVolumeResponse{
994+
Volume: &csi.Volume{
995+
VolumeId: "volume-in-available-state",
996+
CapacityBytes: int64(52428800000),
997+
AccessibleTopology: []*csi.Topology{
998+
{
999+
Segments: map[string]string{
1000+
kubeAPI.LabelTopologyZone: "PHX-AD-2",
1001+
},
1002+
},
1003+
{
1004+
Segments: map[string]string{
1005+
kubeAPI.LabelZoneFailureDomain: "PHX-AD-2",
1006+
},
1007+
},
1008+
},
1009+
VolumeContext: map[string]string{
1010+
"needResize": "false",
1011+
"newSize": "",
1012+
"vpusPerGB": "10",
1013+
"attachment-type": "",
1014+
},
1015+
},
1016+
},
1017+
wantErr: nil,
1018+
},
1019+
{
1020+
name: "Error for support of Block volumeMode in Ultra High Performance Volumes (vpusPerGB >= 30)",
9581021
fields: fields{},
9591022
args: args{
9601023
ctx: nil,
9611024
req: &csi.CreateVolumeRequest{
9621025
Name: "ut-volume",
963-
VolumeCapabilities: []*csi.VolumeCapability{{
964-
AccessType: &csi.VolumeCapability_Block{
965-
Block: &csi.VolumeCapability_BlockVolume{},
966-
},
967-
}},
1026+
VolumeCapabilities: []*csi.VolumeCapability{
1027+
{
1028+
AccessMode: &csi.VolumeCapability_AccessMode{
1029+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
1030+
},
1031+
AccessType: &csi.VolumeCapability_Block{
1032+
Block: &csi.VolumeCapability_BlockVolume{},
1033+
},
1034+
}},
1035+
Parameters: map[string]string{
1036+
"vpusPerGB": "40",
1037+
},
1038+
CapacityRange: &csi.CapacityRange{
1039+
RequiredBytes: int64(csi_util.MaximumVolumeSizeInBytes),
1040+
},
9681041
},
9691042
},
9701043
want: nil,
971-
wantErr: errors.New("driver does not support Block volumeMode. Please use Filesystem mode"),
1044+
wantErr: errors.New("failed to support Block volumeMode for Ultra High Performance Volumes (vpusPerGB >= 30)"),
9721045
},
9731046
{
9741047
name: "Create Volume times out waiting for volume to become available",

0 commit comments

Comments
 (0)