Skip to content

Commit

Permalink
feat: mkfs block/inode size options
Browse files Browse the repository at this point in the history
Add CSI blockSize/inodeSize format options.

Signed-off-by: Serge Logvinov <[email protected]>
  • Loading branch information
sergelogvinov committed Oct 15, 2023
1 parent c464dab commit 603bcf3
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 19 deletions.
2 changes: 1 addition & 1 deletion charts/proxmox-csi-plugin/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ maintainers:
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.7
version: 0.1.8

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
Expand Down
2 changes: 1 addition & 1 deletion charts/proxmox-csi-plugin/templates/csidriver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ spec:
storageCapacity: true
volumeLifecycleModes:
- Persistent
- Ephemeral
# - Ephemeral
2 changes: 1 addition & 1 deletion docs/deploy/test-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ spec:
resources:
requests:
storage: 50Gi
storageClassName: proxmox-rbd
storageClassName: proxmox-lvm
7 changes: 7 additions & 0 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ parameters:
csi.storage.k8s.io/node-expand-secret-name: "proxmox-csi-secret"
csi.storage.k8s.io/node-expand-secret-namespace: "kube-system"

## Optional: File system format options
blockSize: "4096"
inodeSize: "256"

# Proxmox csi options
## Proxmox storage ID
storage: data
Expand Down Expand Up @@ -70,6 +74,9 @@ metadata:
namespace: kube-system
```

* `blockSize` - specify the size of blocks in bytes.
* `inodeSize` - Specify the size of each inode in bytes.

* `storage` - proxmox storage ID
* `cache` - qemu cache param: `directsync`, `none`, `writeback`, `writethrough` [Official documentation](https://pve.proxmox.com/wiki/Performance_Tweaks)
* `ssd` - set true if SSD/NVME disk
Expand Down
14 changes: 14 additions & 0 deletions docs/proxmox-lvm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,21 @@ metadata:
name: proxmox-lvm
parameters:
csi.storage.k8s.io/fstype: xfs
# blockSize: "1024"
# inodeSize: "512"
#
storage: lvm
# diskIOPS: "400"
# diskMBps: "120"
provisioner: csi.proxmox.sinextra.dev
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
# allowedTopologies:
# - matchLabelExpressions:
# - key: topology.kubernetes.io/region
# values:
# - fsn1
# - key: topology.kubernetes.io/zone
# values:
# - hvm-4
# - hvm-3
30 changes: 21 additions & 9 deletions pkg/csi/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func NewControllerService(cloudConfig string) (*ControllerService, error) {

// CreateVolume creates a volume
//
//lint:gocyclo
//nolint:gocyclo
func (d *ControllerService) CreateVolume(_ context.Context, request *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
klog.V(4).Infof("CreateVolume: called with args %+v", protosanitizer.StripSecrets(*request))

Expand All @@ -99,6 +99,18 @@ func (d *ControllerService) CreateVolume(_ context.Context, request *csi.CreateV
return nil, status.Errorf(codes.InvalidArgument, "Parameters %s must be provided", StorageIDKey)
}

if params[StorageBlockSizeKey] != "" {
if _, err := strconv.Atoi(params[StorageBlockSizeKey]); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Parameters %s must be a number", StorageBlockSizeKey)
}
}

if params[StorageInodeSizeKey] != "" {
if _, err := strconv.Atoi(params[StorageInodeSizeKey]); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Parameters %s must be a number", StorageInodeSizeKey)
}
}

// Volume Size - Default is 10 GiB
volSizeBytes := int64(DefaultVolumeSize * 1024 * 1024 * 1024)
if request.GetCapacityRange() != nil {
Expand Down Expand Up @@ -309,23 +321,23 @@ func (d *ControllerService) ControllerPublishVolume(_ context.Context, request *
options["cache"] = volCtx[StorageCacheKey]
}

if volCtx[StorageDiskIOPS] != "" {
iops, err := strconv.Atoi(volCtx[StorageDiskIOPS]) //nolint:govet
if volCtx[StorageDiskIOPSKey] != "" {
iops, err := strconv.Atoi(volCtx[StorageDiskIOPSKey]) //nolint:govet
if err != nil {
klog.Errorf("failed %s must be a number: %v", StorageDiskIOPS, err)
klog.Errorf("failed %s must be a number: %v", StorageDiskIOPSKey, err)

return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed %s must be a number: %v", StorageDiskIOPS, err))
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed %s must be a number: %v", StorageDiskIOPSKey, err))
}

options["iops"] = strconv.Itoa(iops)
}

if volCtx[StorageDiskMBps] != "" {
mbps, err := strconv.Atoi(volCtx[StorageDiskMBps]) //nolint:govet
if volCtx[StorageDiskMBpsKey] != "" {
mbps, err := strconv.Atoi(volCtx[StorageDiskMBpsKey]) //nolint:govet
if err != nil {
klog.Errorf("failed %s must be a number: %v", StorageDiskMBps, err)
klog.Errorf("failed %s must be a number: %v", StorageDiskMBpsKey, err)

return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed %s must be a number: %v", StorageDiskMBps, err))
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed %s must be a number: %v", StorageDiskMBpsKey, err))
}

options["mbps"] = strconv.Itoa(mbps)
Expand Down
28 changes: 28 additions & 0 deletions pkg/csi/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,34 @@ func (ts *csiTestSuite) TestCreateVolume() {
},
expectedError: status.Error(codes.InvalidArgument, "Parameters storage must be provided"),
},
{
msg: "VolumeParametersBlockSize",
request: &proto.CreateVolumeRequest{
Name: "volume-id",
Parameters: map[string]string{
"storage": "local-lvm",
"blockSize": "abc",
},
VolumeCapabilities: []*proto.VolumeCapability{volcap},
CapacityRange: volsize,
AccessibilityRequirements: topology,
},
expectedError: status.Error(codes.InvalidArgument, "Parameters blockSize must be a number"),
},
{
msg: "VolumeParametersInodeSize",
request: &proto.CreateVolumeRequest{
Name: "volume-id",
Parameters: map[string]string{
"storage": "local-lvm",
"inodeSize": "abc",
},
VolumeCapabilities: []*proto.VolumeCapability{volcap},
CapacityRange: volsize,
AccessibilityRequirements: topology,
},
expectedError: status.Error(codes.InvalidArgument, "Parameters inodeSize must be a number"),
},
{
msg: "RegionZone",
request: &proto.CreateVolumeRequest{
Expand Down
22 changes: 18 additions & 4 deletions pkg/csi/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,16 @@ const (
// StorageSSDKey is it ssd disk
StorageSSDKey = "ssd"

// StorageDiskIOPS is maximum r/w I/O in operations per second
StorageDiskIOPS = "diskIOPS"
// StorageDiskMBps is maximum r/w throughput in MB/s
StorageDiskMBps = "diskMBps"
// StorageDiskIOPSKey is maximum r/w I/O in operations per second
StorageDiskIOPSKey = "diskIOPS"
// StorageDiskMBpsKey is maximum r/w throughput in MB/s
StorageDiskMBpsKey = "diskMBps"

// StorageBlockSizeKey the block size when formatting a volume
StorageBlockSizeKey = "blockSize"

// StorageInodeSizeKey the inode size when formatting a volume
StorageInodeSizeKey = "inodeSize"

// MaxVolumesPerNode is the maximum number of volumes that can be attached to a node
MaxVolumesPerNode = 16
Expand All @@ -45,3 +51,11 @@ const (
// EncryptionPassphraseKey is the encryption passphrase secret key
EncryptionPassphraseKey = "encryption-passphrase"
)

// constants for fstypes
const (
// FSTypeExt4 represents the ext4 filesystem type
FSTypeExt4 = "ext4"
// FSTypeXfs represents the xfs filesystem type
FSTypeXfs = "xfs"
)
30 changes: 27 additions & 3 deletions pkg/csi/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ func NewNodeService(nodeID string, clientSet kubernetes.Interface) *NodeService
}

// NodeStageVolume is called by the CO when a workload that wants to use the specified volume is placed (scheduled) on a node.
//
//nolint:cyclop,gocyclo
func (n *NodeService) NodeStageVolume(_ context.Context, request *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) {
klog.V(4).Infof("NodeStageVolume: called with args %s", stripSecrets(*request))

Expand Down Expand Up @@ -120,7 +122,10 @@ func (n *NodeService) NodeStageVolume(_ context.Context, request *csi.NodeStageV
}

if notMnt {
var options []string
var (
options []string
formatOptions []string
)

fsType := "ext4"

Expand All @@ -137,6 +142,25 @@ func (n *NodeService) NodeStageVolume(_ context.Context, request *csi.NodeStageV
options = append(options, collectMountOptions(fsType, mountFlags)...)
}

blockSize := volumeContext[StorageBlockSizeKey]
if blockSize != "" {
if fsType == FSTypeXfs {
blockSize = "size=" + blockSize
}

formatOptions = append(formatOptions, "-b", blockSize)
}

inodeSize := volumeContext[StorageInodeSizeKey]
if inodeSize != "" {
option := "-I"
if fsType == FSTypeXfs {
option, inodeSize = "-i", "size="+inodeSize
}

formatOptions = append(formatOptions, option, inodeSize)
}

passphraseKey, ok := request.GetSecrets()[EncryptionPassphraseKey]
if ok {
klog.V(4).Infof("NodeStageVolume: volume encrypted")
Expand Down Expand Up @@ -167,7 +191,7 @@ func (n *NodeService) NodeStageVolume(_ context.Context, request *csi.NodeStageV
devicePath = lukskDevicePath
}

err = m.Mounter().FormatAndMount(devicePath, stagingTarget, fsType, options)
err = m.Mounter().FormatAndMountSensitiveWithFormatOptions(devicePath, stagingTarget, fsType, options, nil, formatOptions)
if err != nil {
klog.Errorf("NodeStageVolume: failed to mount device %s at %s (fstype: %s), error: %v", devicePath, stagingTarget, fsType, err)

Expand Down Expand Up @@ -503,7 +527,7 @@ func collectMountOptions(fsType string, mntFlags []string) []string {

// By default, xfs does not allow mounting of two volumes with the same filesystem uuid.
// Force ignore this uuid to be able to mount volume + its clone / restored snapshot on the same node.
if fsType == "xfs" {
if fsType == FSTypeXfs {
options = append(options, "nouuid")
}

Expand Down

0 comments on commit 603bcf3

Please sign in to comment.