@@ -3,22 +3,29 @@ package main
33import (
44 "errors"
55 "fmt"
6- "os"
7- "path "
6+ "os"
7+ "strings "
88 "path/filepath"
99 "sync"
10- "syscall"
1110
12- log "github.com/Sirupsen /logrus"
11+ log "github.com/sirupsen /logrus"
1312
1413 "github.com/davecgh/go-spew/spew"
1514 "github.com/docker/go-plugins-helpers/volume"
1615)
1716
17+ // Configuration structure
18+ type MoosefsConfig struct {
19+ MasterHost string
20+ MasterPort string
21+ RootDir string
22+ MountOptions []string
23+ }
24+
1825// A single volume instance
1926type moosefsMount struct {
2027 name string
21- path string
28+ path string
2229 root string
2330}
2431
@@ -27,16 +34,21 @@ type moosefsDriver struct {
2734 m * sync.Mutex
2835}
2936
30- func newMooseFSDriver (root string ) moosefsDriver {
31- d := moosefsDriver {
37+ func newMooseFSDriver (root string ) ( * moosefsDriver , error ) {
38+ d := & moosefsDriver {
3239 mounts : make (map [string ]* moosefsMount ),
3340 m : & sync.Mutex {},
3441 }
35- return d
42+
43+ if err := d .loadState (); err != nil {
44+ return nil , err
45+ }
46+
47+ return d , nil
3648}
3749
3850func (d moosefsDriver ) Create (r * volume.CreateRequest ) error {
39- var volumeRoot string
51+ var volumeRoot string
4052
4153 d .m .Lock ()
4254 defer d .m .Unlock ()
@@ -45,15 +57,15 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
4557 volumeRoot = optsRoot
4658 } else {
4759 // Assume the default root
48- volumeRoot = * root
60+ volumeRoot = * root
4961 }
5062
51- volumePath := filepath .Join (volumeRoot , r .Name )
63+ volumePath := filepath .Join (volumeRoot , r .Name )
5264
53- if err := mkdir (volumePath ); err != nil {
65+ if err := mkdir (volumePath ); err != nil {
5466 return err
5567 }
56-
68+
5769 if ! ismoosefs (volumePath ) {
5870 emsg := fmt .Sprintf ("Cannot create volume %s as it's not a valid MooseFS mount" , volumePath )
5971 log .Error (emsg )
@@ -66,19 +78,22 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
6678 return errors .New (emsg )
6779 }
6880
69- if err := mkdir (volumePath ); err != nil {
70- return err
71- }
7281 d .mounts [r .Name ] = & moosefsMount {
7382 name : r .Name ,
74- path : volumePath ,
83+ path : volumePath ,
7584 root : volumeRoot ,
7685 }
7786
7887 if * verbose {
7988 spew .Dump (d .mounts )
8089 }
8190
91+ if err := d .saveState (); err != nil {
92+ // If we can't save state, remove the volume from memory
93+ delete (d .mounts , r .Name )
94+ return err
95+ }
96+
8297 return nil
8398}
8499
@@ -87,6 +102,9 @@ func (d moosefsDriver) Remove(r *volume.RemoveRequest) error {
87102 defer d .m .Unlock ()
88103 if _ , ok := d .mounts [r .Name ]; ok {
89104 delete (d .mounts , r .Name )
105+ if err := d .saveState (); err != nil {
106+ return err
107+ }
90108 }
91109 return nil
92110}
@@ -99,16 +117,16 @@ func (d moosefsDriver) Path(r *volume.PathRequest) (*volume.PathResponse, error)
99117}
100118
101119func (d moosefsDriver ) Mount (r * volume.MountRequest ) (* volume.MountResponse , error ) {
102- volumePath := filepath .Join (d .mounts [r .Name ].root , r .Name )
103- if ! ismoosefs (volumePath ) {
104- emsg := fmt .Sprintf ("Cannot mount volume %s as it's not a valid MooseFS mount" , volumePath )
105- log .Error (emsg )
106- return & volume.MountResponse {}, errors .New (emsg )
107- }
108- if _ , ok := d .mounts [r .Name ]; ok {
109- return & volume.MountResponse {Mountpoint : d .mounts [r .Name ].path }, nil
110- }
111- return & volume.MountResponse {}, nil
120+ volumePath := filepath .Join (d .mounts [r .Name ].root , r .Name )
121+ if ! ismoosefs (volumePath ) {
122+ emsg := fmt .Sprintf ("Cannot mount volume %s as it's not a valid MooseFS mount" , volumePath )
123+ log .Error (emsg )
124+ return & volume.MountResponse {}, errors .New (emsg )
125+ }
126+ if _ , ok := d .mounts [r .Name ]; ok {
127+ return & volume.MountResponse {Mountpoint : d .mounts [r .Name ].path }, nil
128+ }
129+ return & volume.MountResponse {}, nil
112130}
113131
114132func (d moosefsDriver ) Unmount (r * volume.UnmountRequest ) error {
@@ -137,15 +155,41 @@ func (d moosefsDriver) Capabilities() *volume.CapabilitiesResponse {
137155 return & res
138156}
139157
140- // Check if MooseFS is mounted in mountpoint using the .masterinfo file
141- func ismoosefs (mountpoint string ) bool {
142- stat := syscall.Statfs_t {}
143- err := syscall .Statfs (path .Join (mountpoint , ".masterinfo" ), & stat )
144- if err != nil {
145- log .Errorf ("Could not determine filesystem type for %s: %s" , mountpoint , err )
146- return false
147- }
148- return true
158+ // Check if path is under a MooseFS mount
159+ func ismoosefs (checkPath string ) bool {
160+ absPath , err := filepath .Abs (checkPath )
161+ if err != nil {
162+ log .Errorf ("Cannot get absolute path for %s: %s" , checkPath , err )
163+ return false
164+ }
165+
166+ data , err := os .ReadFile ("/proc/mounts" )
167+ if err != nil {
168+ log .Errorf ("Cannot read /proc/mounts: %s" , err )
169+ return false
170+ }
171+
172+ mounts := strings .Split (string (data ), "\n " )
173+ for _ , mount := range mounts {
174+ fields := strings .Fields (mount )
175+ if len (fields ) < 3 {
176+ continue
177+ }
178+
179+ mountPoint := fields [1 ]
180+ fsType := fields [2 ]
181+
182+ if fsType == "fuse.mfs" {
183+ log .Infof ("Found MooseFS mount at %s" , mountPoint )
184+ if strings .HasPrefix (absPath , mountPoint ) {
185+ log .Infof ("Path %s is under MooseFS mount %s" , absPath , mountPoint )
186+ return true
187+ }
188+ }
189+ }
190+
191+ log .Infof ("Path %s is not under any MooseFS mount" , absPath )
192+ return false
149193}
150194
151195func mkdir (path string ) error {
0 commit comments