66 "reflect"
77 "strings"
88
9+ "github.com/alibaba/pouch/pkg/kmutex"
910 metastore "github.com/alibaba/pouch/pkg/meta"
1011 "github.com/alibaba/pouch/storage/volume/driver"
1112 volerr "github.com/alibaba/pouch/storage/volume/error"
@@ -19,11 +20,15 @@ import (
1920type Core struct {
2021 Config
2122 store * metastore.Store
23+ lock * kmutex.KMutex
2224}
2325
2426// NewCore returns Core struct instance with volume config.
2527func NewCore (cfg Config ) (* Core , error ) {
26- c := & Core {Config : cfg }
28+ c := & Core {
29+ Config : cfg ,
30+ lock : kmutex .New (),
31+ }
2732
2833 // initialize volume driver alias.
2934 if cfg .DriverAlias != "" {
@@ -75,8 +80,8 @@ func NewCore(cfg Config) (*Core, error) {
7580 return c , nil
7681}
7782
78- // GetVolume return a volume's info with specified name, If not errors.
79- func (c * Core ) GetVolume (id types.VolumeID ) (* types.Volume , error ) {
83+ // getVolume return a volume's info with specified name, If not errors.
84+ func (c * Core ) getVolume (id types.VolumeID ) (* types.Volume , error ) {
8085 ctx := driver .Contexts ()
8186
8287 // first, try to get volume from local store.
@@ -140,9 +145,22 @@ func (c *Core) GetVolume(id types.VolumeID) (*types.Volume, error) {
140145 return nil , volerr .ErrVolumeNotFound
141146}
142147
143- // ExistVolume return 'true' if volume be found and not errors.
144- func (c * Core ) ExistVolume (id types.VolumeID ) (bool , error ) {
145- _ , err := c .GetVolume (id )
148+ // getVolumeDriver return the backend driver and volume with specified volume's id.
149+ func (c * Core ) getVolumeDriver (id types.VolumeID ) (* types.Volume , driver.Driver , error ) {
150+ v , err := c .getVolume (id )
151+ if err != nil {
152+ return nil , nil , err
153+ }
154+ dv , err := driver .Get (v .Spec .Backend )
155+ if err != nil {
156+ return nil , nil , errors .Errorf ("failed to get backend driver %s: %v" , v .Spec .Backend , err )
157+ }
158+ return v , dv , nil
159+ }
160+
161+ // existVolume return 'true' if volume be found and not errors.
162+ func (c * Core ) existVolume (id types.VolumeID ) (bool , error ) {
163+ _ , err := c .getVolume (id )
146164 if err != nil {
147165 if ec , ok := err .(volerr.CoreError ); ok && ec .IsVolumeNotFound () {
148166 return false , nil
@@ -152,9 +170,20 @@ func (c *Core) ExistVolume(id types.VolumeID) (bool, error) {
152170 return true , nil
153171}
154172
173+ // GetVolume return a volume's info with specified name, If not errors.
174+ func (c * Core ) GetVolume (id types.VolumeID ) (* types.Volume , error ) {
175+ c .lock .Lock (id .Name )
176+ defer c .lock .Unlock (id .Name )
177+
178+ return c .getVolume (id )
179+ }
180+
155181// CreateVolume use to create a volume, if failed, will return error info.
156182func (c * Core ) CreateVolume (id types.VolumeID ) (* types.Volume , error ) {
157- exist , err := c .ExistVolume (id )
183+ c .lock .Lock (id .Name )
184+ defer c .lock .Unlock (id .Name )
185+
186+ exist , err := c .existVolume (id )
158187 if err != nil {
159188 return nil , err
160189 } else if exist {
@@ -282,7 +311,10 @@ func (c *Core) ListVolumeName(labels map[string]string) ([]string, error) {
282311
283312// RemoveVolume remove volume from storage and meta information, if not success return error.
284313func (c * Core ) RemoveVolume (id types.VolumeID ) error {
285- v , dv , err := c .GetVolumeDriver (id )
314+ c .lock .Lock (id .Name )
315+ defer c .lock .Unlock (id .Name )
316+
317+ v , dv , err := c .getVolumeDriver (id )
286318 if err != nil {
287319 return errors .Wrap (err , "Remove volume: " + id .String ())
288320 }
@@ -302,30 +334,23 @@ func (c *Core) RemoveVolume(id types.VolumeID) error {
302334
303335// VolumePath return the path of volume on node host.
304336func (c * Core ) VolumePath (id types.VolumeID ) (string , error ) {
305- v , dv , err := c .GetVolumeDriver (id )
337+ c .lock .Lock (id .Name )
338+ defer c .lock .Unlock (id .Name )
339+
340+ v , dv , err := c .getVolumeDriver (id )
306341 if err != nil {
307342 return "" , errors .Wrap (err , fmt .Sprintf ("Get volume: %s path" , id .String ()))
308343 }
309344
310345 return c .volumePath (v , dv )
311346}
312347
313- // GetVolumeDriver return the backend driver and volume with specified volume's id.
314- func (c * Core ) GetVolumeDriver (id types.VolumeID ) (* types.Volume , driver.Driver , error ) {
315- v , err := c .GetVolume (id )
316- if err != nil {
317- return nil , nil , err
318- }
319- dv , err := driver .Get (v .Spec .Backend )
320- if err != nil {
321- return nil , nil , errors .Errorf ("failed to get backend driver %s: %v" , v .Spec .Backend , err )
322- }
323- return v , dv , nil
324- }
325-
326348// AttachVolume to enable a volume on local host.
327349func (c * Core ) AttachVolume (id types.VolumeID , extra map [string ]string ) (* types.Volume , error ) {
328- v , dv , err := c .GetVolumeDriver (id )
350+ c .lock .Lock (id .Name )
351+ defer c .lock .Unlock (id .Name )
352+
353+ v , dv , err := c .getVolumeDriver (id )
329354 if err != nil {
330355 return nil , err
331356 }
@@ -353,7 +378,10 @@ func (c *Core) AttachVolume(id types.VolumeID, extra map[string]string) (*types.
353378
354379// DetachVolume to disable a volume on local host.
355380func (c * Core ) DetachVolume (id types.VolumeID , extra map [string ]string ) (* types.Volume , error ) {
356- v , dv , err := c .GetVolumeDriver (id )
381+ c .lock .Lock (id .Name )
382+ defer c .lock .Unlock (id .Name )
383+
384+ v , dv , err := c .getVolumeDriver (id )
357385 if err != nil {
358386 return nil , err
359387 }
0 commit comments