@@ -18,6 +18,7 @@ import (
1818
1919 "github.com/container-storage-interface/spec/lib/go/csi"
2020 "golang.org/x/net/context"
21+ "golang.org/x/sys/unix"
2122 "google.golang.org/grpc/codes"
2223 "google.golang.org/grpc/status"
2324 "k8s.io/apimachinery/pkg/api/resource"
@@ -1029,31 +1030,49 @@ func (driver *Driver) nodePublishVolume(
10291030
10301031 // If Block, then stage the volume for raw block device access
10311032 if volAccessType .String () == model .BlockType .String () {
1032- log .Tracef ("Publishing the volume for raw block access (create symlink ), devicePath: %s, targetPath: %v" ,
1033+ log .Tracef ("Publishing the volume for raw block access (create block device ), devicePath: %s, targetPath: %v" ,
10331034 stagingDev .Device .AltFullPathName , targetPath )
10341035
1035- // Check if target path symlink to the device already exists
1036- exists , symlink , _ := util .IsFileSymlink (targetPath )
1037- if symlink {
1038- errMsg := fmt .Sprintf ("Target path %s already published as symlink to the device %s" , targetPath , stagingDev .Device .AltFullPathName )
1036+ // Check if target path block device to the mpath device already exists
1037+ exists , blockDevice , _ := util .IsFileBlockDevice (targetPath )
1038+ if blockDevice {
1039+ errMsg := fmt .Sprintf ("Target path %s already published as block device to the mpath device %s" , targetPath , stagingDev .Device .AltFullPathName )
10391040 log .Error ("Error: " , errMsg )
10401041 return status .Error (codes .Internal , errMsg )
10411042 }
10421043 if exists {
10431044 // Remove the target path before creating the symlink
1044- log .Tracef ("Removing the target path %s before creating symlink to the device" , targetPath )
1045+ log .Tracef ("Removing the target block device %s before creating block device to the mpath device" , targetPath )
10451046 if err := util .FileDelete (targetPath ); err != nil {
10461047 return status .Error (codes .Internal ,
1047- fmt .Sprintf ("Error removing the target path %s before creating symlink to the device, err: %s" ,
1048+ fmt .Sprintf ("Error removing the target block device %s before creating block device to the mpath device, err: %s" ,
10481049 targetPath , err .Error ()))
10491050 }
10501051 }
10511052
10521053 // Note: Bind-mount is not allowed for raw block device as there is no filesystem on it.
1053- // So, we create softlink to the device file. TODO: mknode() instead ???
1054- // Ex: ln -s /dev/mpathbm <targetPath>
1055- if err := os .Symlink (stagingDev .Device .AltFullPathName , targetPath ); err != nil {
1056- errMsg := fmt .Sprintf ("Failed to create symlink %s to the device path %s, err: %v" ,
1054+ rawDeviceMinor , err := strconv .Atoi (stagingDev .Device .Minor )
1055+ if err != nil {
1056+ errMsg := fmt .Sprintf ("Failed to retrieve device minor to create %s from the mpath device path %s, err: %v" ,
1057+ targetPath , stagingDev .Device .AltFullPathName , err .Error ())
1058+ log .Error ("Error: " , errMsg )
1059+ return status .Error (codes .Internal , errMsg )
1060+ }
1061+
1062+ rawDeviceMajor , err := strconv .Atoi (stagingDev .Device .Major )
1063+ if err != nil {
1064+ errMsg := fmt .Sprintf ("Failed to retrieve device major to create %s from the mpath device path %s, err: %v" ,
1065+ targetPath , stagingDev .Device .AltFullPathName , err .Error ())
1066+ log .Error ("Error: " , errMsg )
1067+ return status .Error (codes .Internal , errMsg )
1068+ }
1069+
1070+ rawDeviceMode := uint32 (unix .S_IFBLK | 0660 )
1071+ rawDeviceMM := int (unix .Mkdev (uint32 (rawDeviceMajor ), uint32 (rawDeviceMinor )))
1072+
1073+ // Create block device
1074+ if err := unix .Mknod (targetPath , rawDeviceMode , rawDeviceMM ); err != nil {
1075+ errMsg := fmt .Sprintf ("Failed to create block device %s to the mpath device path %s, err: %v" ,
10571076 targetPath , stagingDev .Device .AltFullPathName , err .Error ())
10581077 log .Error ("Error: " , errMsg )
10591078 return status .Error (codes .Internal , errMsg )
@@ -1456,10 +1475,10 @@ func (driver *Driver) isVolumePublished(
14561475 return false , nil // Not published yet as targetPath does not exists
14571476 }
14581477
1459- // Check if target path is the symlink to the device
1460- _ , symlink , _ := util .IsFileSymlink (targetPath )
1461- if ! symlink {
1462- log .Tracef ("Target path %s is not symlink to the device %s" , targetPath , stagingDev .Device .AltFullPathName )
1478+ // Check if target path is a block device
1479+ _ , blockDevice , _ := util .IsFileBlockDevice (targetPath )
1480+ if ! blockDevice {
1481+ log .Tracef ("Target path %s is not a block device to the mpath device %s" , targetPath , stagingDev .Device .AltFullPathName )
14631482 return false , nil // Not published yet as symlink does not exists
14641483 }
14651484
@@ -1732,13 +1751,13 @@ func (driver *Driver) nodeUnpublishVolume(targetPath string) error {
17321751 defer log .Trace ("<<<<< nodeUnpublishVolume" )
17331752
17341753 // Block volume: Check for symlink and remove it
1735- _ , symlink , _ := util .IsFileSymlink (targetPath )
1736- if symlink {
1737- // Remove the symlink
1738- log .Tracef ("Removing the symlink from target path %s" , targetPath )
1754+ _ , blockDevice , _ := util .IsFileBlockDevice (targetPath )
1755+ if blockDevice {
1756+ // Remove the block device
1757+ log .Tracef ("Removing the block device from mpath device %s" , targetPath )
17391758 if err := util .FileDelete (targetPath ); err != nil {
17401759 return status .Error (codes .Internal ,
1741- fmt .Sprintf ("Error removing the symlink target path %s, err: %s" ,
1760+ fmt .Sprintf ("Error removing the block device target path%s, err: %s" ,
17421761 targetPath , err .Error ()))
17431762 }
17441763 return nil
0 commit comments