@@ -62,6 +62,8 @@ const (
6262 newBackupAvailableTimeout = 45 * time .Second
6363 needResize = "needResize"
6464 newSize = "newSize"
65+ multipathEnabled = "multipathEnabled"
66+ multipathDevices = "multipathDevices"
6567 //device is the consistent device path that would be used for paravirtualized attachment
6668 device = "device"
6769)
@@ -239,7 +241,18 @@ func (d *BlockVolumeControllerDriver) CreateVolume(ctx context.Context, req *csi
239241 volumeName := req .Name
240242
241243 dimensionsMap := make (map [string ]string )
244+
245+ volumeParams , err := extractVolumeParameters (log , req .GetParameters ())
246+ if err != nil {
247+ log .With (zap .Error (err )).Error ("Failed to parse storageclass parameters." )
248+ metricDimension = util .GetMetricDimensionForComponent (util .ErrValidation , util .CSIStorageType )
249+ dimensionsMap [metrics .ComponentDimension ] = metricDimension
250+ metrics .SendMetricData (d .metricPusher , metrics .PVProvision , time .Since (startTime ).Seconds (), dimensionsMap )
251+ return nil , status .Errorf (codes .InvalidArgument , "failed to parse storageclass parameters %v" , err )
252+ }
253+
242254 dimensionsMap [metrics .ResourceOCIDDimension ] = volumeName
255+ dimensionsMap [metrics .VolumeVpusPerGBDimension ] = strconv .Itoa (int (volumeParams .vpusPerGB ))
243256
244257 srcSnapshotId := ""
245258 srcVolumeId := ""
@@ -370,15 +383,6 @@ func (d *BlockVolumeControllerDriver) CreateVolume(ctx context.Context, req *csi
370383 return nil , fmt .Errorf ("duplicate volume %q exists" , volumeName )
371384 }
372385
373- volumeParams , err := extractVolumeParameters (log , req .GetParameters ())
374- if err != nil {
375- log .With (zap .Error (err )).Error ("Failed to parse storageclass parameters." )
376- metricDimension = util .GetMetricDimensionForComponent (util .ErrValidation , metricType )
377- dimensionsMap [metrics .ComponentDimension ] = metricDimension
378- metrics .SendMetricData (d .metricPusher , metric , time .Since (startTime ).Seconds (), dimensionsMap )
379- return nil , status .Errorf (codes .InvalidArgument , "failed to parse storageclass parameters %v" , err )
380- }
381-
382386 provisionedVolume := core.Volume {}
383387
384388 if len (volumes ) > 0 {
@@ -641,7 +645,16 @@ func (d *BlockVolumeControllerDriver) ControllerPublishVolume(ctx context.Contex
641645 //Checking if Volume state is already Attached or Attachment (from above condition) is completed
642646 if volumeAttached .GetLifecycleState () == core .VolumeAttachmentLifecycleStateAttached {
643647 log .With ("instanceID" , id ).Info ("Volume is already ATTACHED to the Node." )
644- return generatePublishContext (volumeAttachmentOptions , log , volumeAttached , vpusPerGB , req .VolumeContext [needResize ], req .VolumeContext [newSize ]), nil
648+ resp , err := generatePublishContext (volumeAttachmentOptions , log , volumeAttached , vpusPerGB , req .VolumeContext [needResize ], req .VolumeContext [newSize ])
649+ if err != nil {
650+ log .With (zap .Error (err )).Error ("Failed to generate publish context" )
651+ errorType = util .GetError (err )
652+ csiMetricDimension = util .GetMetricDimensionForComponent (errorType , util .CSIStorageType )
653+ dimensionsMap [metrics .ComponentDimension ] = csiMetricDimension
654+ metrics .SendMetricData (d .metricPusher , metrics .PVAttach , time .Since (startTime ).Seconds (), dimensionsMap )
655+ return nil , status .Errorf (codes .Internal , "Failed to generate publish context: %s" , err )
656+ }
657+ return resp , nil
645658 }
646659 }
647660 }
@@ -686,11 +699,25 @@ func (d *BlockVolumeControllerDriver) ControllerPublishVolume(ctx context.Contex
686699 csiMetricDimension = util .GetMetricDimensionForComponent (util .Success , util .CSIStorageType )
687700 dimensionsMap [metrics .ComponentDimension ] = csiMetricDimension
688701 metrics .SendMetricData (d .metricPusher , metrics .PVAttach , time .Since (startTime ).Seconds (), dimensionsMap )
689- return generatePublishContext (volumeAttachmentOptions , log , volumeAttached , vpusPerGB , req .VolumeContext [needResize ], req .VolumeContext [newSize ]), nil
690-
702+ resp , err := generatePublishContext (volumeAttachmentOptions , log , volumeAttached , vpusPerGB , req .VolumeContext [needResize ], req .VolumeContext [newSize ])
703+ if err != nil {
704+ log .With (zap .Error (err )).Error ("Failed to generate publish context" )
705+ errorType = util .GetError (err )
706+ csiMetricDimension = util .GetMetricDimensionForComponent (errorType , util .CSIStorageType )
707+ dimensionsMap [metrics .ComponentDimension ] = csiMetricDimension
708+ metrics .SendMetricData (d .metricPusher , metrics .PVAttach , time .Since (startTime ).Seconds (), dimensionsMap )
709+ return nil , status .Errorf (codes .Internal , "Failed to generate publish context: %s" , err )
710+ }
711+ return resp , nil
691712}
692713
693- func generatePublishContext (volumeAttachmentOptions VolumeAttachmentOption , log * zap.SugaredLogger , volumeAttached core.VolumeAttachment , vpusPerGB string , needsResize string , expectedSize string ) * csi.ControllerPublishVolumeResponse {
714+ func generatePublishContext (volumeAttachmentOptions VolumeAttachmentOption , log * zap.SugaredLogger , volumeAttached core.VolumeAttachment , vpusPerGB string , needsResize string , expectedSize string ) (* csi.ControllerPublishVolumeResponse , error ) {
715+ multipath := "false"
716+
717+ if volumeAttached .GetIsMultipath () != nil {
718+ multipath = strconv .FormatBool (* volumeAttached .GetIsMultipath ())
719+ }
720+
694721 if volumeAttachmentOptions .useParavirtualizedAttachment {
695722 log .With ("volumeAttachedId" , * volumeAttached .GetId ()).Info ("Publishing paravirtualized Volume Completed." )
696723 return & csi.ControllerPublishVolumeResponse {
@@ -700,24 +727,36 @@ func generatePublishContext(volumeAttachmentOptions VolumeAttachmentOption, log
700727 csi_util .VpusPerGB : vpusPerGB ,
701728 needResize : needsResize ,
702729 newSize : expectedSize ,
730+ multipathEnabled : multipath ,
703731 },
704- }
732+ }, nil
705733 }
706734 iSCSIVolumeAttached := volumeAttached .(core.IScsiVolumeAttachment )
735+ multiPathDevicesJson := []byte {}
736+ if len (iSCSIVolumeAttached .MultipathDevices ) > 0 {
737+ var err error
738+ multiPathDevicesJson , err = json .Marshal (iSCSIVolumeAttached .MultipathDevices )
739+ if err != nil {
740+ return nil , err
741+ }
742+ }
707743
708744 log .With ("volumeAttachedId" , * volumeAttached .GetId ()).Info ("Publishing iSCSI Volume Completed." )
709745
710746 return & csi.ControllerPublishVolumeResponse {
711747 PublishContext : map [string ]string {
712748 attachmentType : attachmentTypeISCSI ,
749+ device : * volumeAttached .GetDevice (),
713750 disk .ISCSIIQN : * iSCSIVolumeAttached .Iqn ,
714751 disk .ISCSIIP : * iSCSIVolumeAttached .Ipv4 ,
715752 disk .ISCSIPORT : strconv .Itoa (* iSCSIVolumeAttached .Port ),
716753 csi_util .VpusPerGB : vpusPerGB ,
717754 needResize : needsResize ,
718755 newSize : expectedSize ,
756+ multipathEnabled : multipath ,
757+ multipathDevices : string (multiPathDevicesJson ),
719758 },
720- }
759+ }, nil
721760}
722761
723762// ControllerUnpublishVolume detaches the given volume from the node
@@ -797,6 +836,18 @@ func (d *BlockVolumeControllerDriver) ControllerUnpublishVolume(ctx context.Cont
797836 return nil , status .Errorf (codes .Unknown , "timed out waiting for volume to be detached %s" , err )
798837 }
799838
839+ multipath := false
840+
841+ if attachedVolume .GetIsMultipath () != nil {
842+ multipath = * attachedVolume .GetIsMultipath ()
843+ }
844+
845+ // sleeping to ensure block volume plugin logs out of iscsi connections on nodes before delete
846+ if multipath {
847+ log .Info ("Waiting for 90 seconds to ensure block volume plugin logs out of iscsi connections on nodes" )
848+ time .Sleep (90 * time .Second )
849+ }
850+
800851 log .Info ("Un-publishing Volume Completed" )
801852 csiMetricDimension = util .GetMetricDimensionForComponent (util .Success , util .CSIStorageType )
802853 dimensionsMap [metrics .ComponentDimension ] = csiMetricDimension
0 commit comments