feat(block): adding block volume support for ZFSPV (#102)

This commit adds the support for creating a Raw Block Volume request using volumemode as block in PVC :-

```
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: block-claim
spec:
  volumeMode: Block
  storageClassName: zfspv-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
```

The driver will create a zvol for this volume and bind mount the block device at the given path.

Signed-off-by: Pawan <pawan@mayadata.io>
This commit is contained in:
Pawan Prakash Sharma 2020-05-05 12:28:46 +05:30 committed by GitHub
parent 49dc99726b
commit dd059a2f43
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 274 additions and 10 deletions

View file

@ -110,14 +110,18 @@ func (ns *node) NodePublishVolume(
vol, mountInfo, err := GetVolAndMountInfo(req)
if err != nil {
goto PublishVolumeResponse
return nil, status.Error(codes.Internal, err.Error())
}
// attempt mount operation on the requested path
if err = zfs.MountVolume(vol, mountInfo); err != nil {
goto PublishVolumeResponse
// If the access type is block, do nothing for stage
switch req.GetVolumeCapability().GetAccessType().(type) {
case *csi.VolumeCapability_Block:
// attempt block mount operation on the requested path
err = zfs.MountBlock(vol, mountInfo)
case *csi.VolumeCapability_Mount:
// attempt filesystem mount operation on the requested path
err = zfs.MountFilesystem(vol, mountInfo)
}
PublishVolumeResponse:
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

View file

@ -208,7 +208,7 @@ func MountDataset(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
}
// MountVolume mounts the disk to the specified path
func MountVolume(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
func MountFilesystem(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
switch vol.Spec.VolumeType {
case VOLTYPE_DATASET:
return MountDataset(vol, mount)
@ -216,3 +216,29 @@ func MountVolume(vol *apis.ZFSVolume, mount *apis.MountInfo) error {
return MountZvol(vol, mount)
}
}
func MountBlock(vol *apis.ZFSVolume, mountinfo *apis.MountInfo) error {
target := mountinfo.MountPath
devicePath := ZFS_DEVPATH + vol.Spec.PoolName + "/" + vol.Name
mountopt := []string{"bind"}
mounter := &mount.SafeFormatAndMount{Interface: mount.New(""), Exec: mount.NewOsExec()}
// Create the mount point as a file since bind mount device node requires it to be a file
err := mounter.MakeFile(target)
if err != nil {
return status.Errorf(codes.Internal, "Could not create target file %q: %v", target, err)
}
// do the bind mount of the zvol device at the target path
if err := mounter.Mount(devicePath, target, "", mountopt); err != nil {
if removeErr := os.Remove(target); removeErr != nil {
return status.Errorf(codes.Internal, "Could not remove mount target %q: %v", target, removeErr)
}
return status.Errorf(codes.Internal, "mount failed at %v err : %v", target, err)
}
logrus.Infof("NodePublishVolume mounted block device %s at %s", devicePath, target)
return nil
}