@@ -52,6 +52,8 @@ type nfsVolume struct {
5252 subDir string
5353 // size of volume
5454 size int64
55+ // pv name when subDir is not empty
56+ uuid string
5557}
5658
5759// Ordering of elements in the CSI volume id.
@@ -64,6 +66,7 @@ const (
6466 idServer = iota
6567 idBaseDir
6668 idSubDir
69+ idUUID
6770 totalIDElements // Always last
6871)
6972
@@ -93,6 +96,8 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
9396 // no op
9497 case paramShare :
9598 // no op
99+ case paramSubDir :
100+ // no op
96101 case mountPermissionsField :
97102 if v != "" {
98103 var err error
@@ -126,7 +131,7 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
126131
127132 fileMode := os .FileMode (mountPermissions )
128133 // Create subdirectory under base-dir
129- internalVolumePath := cs . getInternalVolumePath (nfsVol )
134+ internalVolumePath := getInternalVolumePath (cs . Driver . workingMountDir , nfsVol )
130135 if err = os .Mkdir (internalVolumePath , fileMode ); err != nil && ! os .IsExist (err ) {
131136 return nil , status .Errorf (codes .Internal , "failed to make subdirectory: %v" , err .Error ())
132137 }
@@ -135,8 +140,7 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
135140 klog .Warningf ("failed to chmod subdirectory: %v" , err .Error ())
136141 }
137142
138- parameters [paramServer ] = nfsVol .server
139- parameters [paramShare ] = cs .getVolumeSharePath (nfsVol )
143+ setKeyValueInMap (parameters , paramSubDir , nfsVol .subDir )
140144 return & csi.CreateVolumeResponse {
141145 Volume : & csi.Volume {
142146 VolumeId : nfsVol .id ,
@@ -183,7 +187,7 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
183187 }()
184188
185189 // delete subdirectory under base-dir
186- internalVolumePath := cs . getInternalVolumePath (nfsVol )
190+ internalVolumePath := getInternalVolumePath (cs . Driver . workingMountDir , nfsVol )
187191
188192 klog .V (2 ).Infof ("Removing subdirectory at %v" , internalVolumePath )
189193 if err = os .RemoveAll (internalVolumePath ); err != nil {
@@ -255,9 +259,6 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi
255259
256260// Mount nfs server at base-dir
257261func (cs * ControllerServer ) internalMount (ctx context.Context , vol * nfsVolume , volumeContext map [string ]string , volCap * csi.VolumeCapability ) error {
258- sharePath := filepath .Join (string (filepath .Separator ) + vol .baseDir )
259- targetPath := cs .getInternalMountPath (vol )
260-
261262 if volCap == nil {
262263 volCap = & csi.VolumeCapability {
263264 AccessType : & csi.VolumeCapability_Mount {
@@ -266,16 +267,24 @@ func (cs *ControllerServer) internalMount(ctx context.Context, vol *nfsVolume, v
266267 }
267268 }
268269
269- if volumeContext == nil {
270- volumeContext = make (map [string ]string )
270+ sharePath := filepath .Join (string (filepath .Separator ) + vol .baseDir )
271+ targetPath := getInternalMountPath (cs .Driver .workingMountDir , vol )
272+
273+ volContext := map [string ]string {
274+ paramServer : vol .server ,
275+ paramShare : sharePath ,
276+ }
277+ for k , v := range volumeContext {
278+ // don't set subDir field since only nfs-server:/share should be mounted in CreateVolume/DeleteVolume
279+ if strings .ToLower (k ) != paramSubDir {
280+ volContext [k ] = v
281+ }
271282 }
272- volumeContext [paramServer ] = vol .server
273- volumeContext [paramShare ] = sharePath
274283
275- klog .V (2 ).Infof ("internally mounting %v:%v at %v " , vol .server , sharePath , targetPath )
284+ klog .V (2 ).Infof ("internally mounting %s:%s at %s " , vol .server , sharePath , targetPath )
276285 _ , err := cs .Driver .ns .NodePublishVolume (ctx , & csi.NodePublishVolumeRequest {
277286 TargetPath : targetPath ,
278- VolumeContext : volumeContext ,
287+ VolumeContext : volContext ,
279288 VolumeCapability : volCap ,
280289 VolumeId : vol .id ,
281290 })
@@ -284,20 +293,20 @@ func (cs *ControllerServer) internalMount(ctx context.Context, vol *nfsVolume, v
284293
285294// Unmount nfs server at base-dir
286295func (cs * ControllerServer ) internalUnmount (ctx context.Context , vol * nfsVolume ) error {
287- targetPath := cs . getInternalMountPath (vol )
296+ targetPath := getInternalMountPath (cs . Driver . workingMountDir , vol )
288297
289298 // Unmount nfs server at base-dir
290299 klog .V (4 ).Infof ("internally unmounting %v" , targetPath )
291300 _ , err := cs .Driver .ns .NodeUnpublishVolume (ctx , & csi.NodeUnpublishVolumeRequest {
292301 VolumeId : vol .id ,
293- TargetPath : cs . getInternalMountPath ( vol ) ,
302+ TargetPath : targetPath ,
294303 })
295304 return err
296305}
297306
298307// Convert VolumeCreate parameters to an nfsVolume
299308func (cs * ControllerServer ) newNFSVolume (name string , size int64 , params map [string ]string ) (* nfsVolume , error ) {
300- var server , baseDir string
309+ var server , baseDir , subDir string
301310
302311 // validate parameters (case-insensitive)
303312 for k , v := range params {
@@ -306,6 +315,8 @@ func (cs *ControllerServer) newNFSVolume(name string, size int64, params map[str
306315 server = v
307316 case paramShare :
308317 baseDir = v
318+ case paramSubDir :
319+ subDir = v
309320 }
310321 }
311322
@@ -319,17 +330,30 @@ func (cs *ControllerServer) newNFSVolume(name string, size int64, params map[str
319330 vol := & nfsVolume {
320331 server : server ,
321332 baseDir : baseDir ,
322- subDir : name ,
323333 size : size ,
324334 }
335+ if subDir == "" {
336+ // use pv name by default if not specified
337+ vol .subDir = name
338+ } else {
339+ vol .subDir = subDir
340+ // make volume id unique if subDir is provided
341+ vol .uuid = name
342+ }
325343 vol .id = cs .getVolumeIDFromNfsVol (vol )
326-
327344 return vol , nil
328345}
329346
330- // Get working directory for CreateVolume and DeleteVolume
331- func (cs * ControllerServer ) getInternalMountPath (vol * nfsVolume ) string {
332- return filepath .Join (cs .Driver .workingMountDir , vol .subDir )
347+ // getInternalMountPath: get working directory for CreateVolume and DeleteVolume
348+ func getInternalMountPath (workingMountDir string , vol * nfsVolume ) string {
349+ if vol == nil {
350+ return ""
351+ }
352+ mountDir := vol .uuid
353+ if vol .uuid == "" {
354+ mountDir = vol .subDir
355+ }
356+ return filepath .Join (workingMountDir , mountDir )
333357}
334358
335359// Get internal path where the volume is created
@@ -339,13 +363,8 @@ func (cs *ControllerServer) getInternalMountPath(vol *nfsVolume) string {
339363// CreateVolume calls in parallel and they may use the same underlying share.
340364// Instead of refcounting how many CreateVolume calls are using the same
341365// share, it's simpler to just do a mount per request.
342- func (cs * ControllerServer ) getInternalVolumePath (vol * nfsVolume ) string {
343- return filepath .Join (cs .getInternalMountPath (vol ), vol .subDir )
344- }
345-
346- // Get user-visible share path for the volume
347- func (cs * ControllerServer ) getVolumeSharePath (vol * nfsVolume ) string {
348- return filepath .Join (string (filepath .Separator ), vol .baseDir , vol .subDir )
366+ func getInternalVolumePath (workingMountDir string , vol * nfsVolume ) string {
367+ return filepath .Join (getInternalMountPath (workingMountDir , vol ), vol .subDir )
349368}
350369
351370// Given a nfsVolume, return a CSI volume id
@@ -354,22 +373,25 @@ func (cs *ControllerServer) getVolumeIDFromNfsVol(vol *nfsVolume) string {
354373 idElements [idServer ] = strings .Trim (vol .server , "/" )
355374 idElements [idBaseDir ] = strings .Trim (vol .baseDir , "/" )
356375 idElements [idSubDir ] = strings .Trim (vol .subDir , "/" )
376+ idElements [idUUID ] = vol .uuid
357377 return strings .Join (idElements , separator )
358378}
359379
360380// Given a CSI volume id, return a nfsVolume
361381// sample volume Id:
362- // new volumeID: nfs-server.default.svc.cluster.local#share#pvc-4bcbf944-b6f7-4bd0-b50f-3c3dd00efc64
382+ // new volumeID:
383+ // nfs-server.default.svc.cluster.local#share#pvc-4bcbf944-b6f7-4bd0-b50f-3c3dd00efc64
384+ // nfs-server.default.svc.cluster.local#share#subdir#pvc-4bcbf944-b6f7-4bd0-b50f-3c3dd00efc64
363385// old volumeID: nfs-server.default.svc.cluster.local/share/pvc-4bcbf944-b6f7-4bd0-b50f-3c3dd00efc64
364386func getNfsVolFromID (id string ) (* nfsVolume , error ) {
365- var server , baseDir , subDir string
387+ var server , baseDir , subDir , uuid string
366388 segments := strings .Split (id , separator )
367389 if len (segments ) < 3 {
368390 klog .V (2 ).Infof ("could not split %s into server, baseDir and subDir with separator(%s)" , id , separator )
369- // try with separator "/""
391+ // try with separator "/"
370392 volRegex := regexp .MustCompile ("^([^/]+)/(.*)/([^/]+)$" )
371393 tokens := volRegex .FindStringSubmatch (id )
372- if tokens == nil {
394+ if tokens == nil || len ( tokens ) < 4 {
373395 return nil , fmt .Errorf ("could not split %s into server, baseDir and subDir with separator(%s)" , id , "/" )
374396 }
375397 server = tokens [1 ]
@@ -379,13 +401,17 @@ func getNfsVolFromID(id string) (*nfsVolume, error) {
379401 server = segments [0 ]
380402 baseDir = segments [1 ]
381403 subDir = segments [2 ]
404+ if len (segments ) >= 4 {
405+ uuid = segments [3 ]
406+ }
382407 }
383408
384409 return & nfsVolume {
385410 id : id ,
386411 server : server ,
387412 baseDir : baseDir ,
388413 subDir : subDir ,
414+ uuid : uuid ,
389415 }, nil
390416}
391417
0 commit comments