@@ -3,22 +3,29 @@ package main
3
3
import (
4
4
"errors"
5
5
"fmt"
6
- "os"
7
- "path "
6
+ "os"
7
+ "strings "
8
8
"path/filepath"
9
9
"sync"
10
- "syscall"
11
10
12
- log "github.com/Sirupsen /logrus"
11
+ log "github.com/sirupsen /logrus"
13
12
14
13
"github.com/davecgh/go-spew/spew"
15
14
"github.com/docker/go-plugins-helpers/volume"
16
15
)
17
16
17
+ // Configuration structure
18
+ type MoosefsConfig struct {
19
+ MasterHost string
20
+ MasterPort string
21
+ RootDir string
22
+ MountOptions []string
23
+ }
24
+
18
25
// A single volume instance
19
26
type moosefsMount struct {
20
27
name string
21
- path string
28
+ path string
22
29
root string
23
30
}
24
31
@@ -27,16 +34,21 @@ type moosefsDriver struct {
27
34
m * sync.Mutex
28
35
}
29
36
30
- func newMooseFSDriver (root string ) moosefsDriver {
31
- d := moosefsDriver {
37
+ func newMooseFSDriver (root string ) ( * moosefsDriver , error ) {
38
+ d := & moosefsDriver {
32
39
mounts : make (map [string ]* moosefsMount ),
33
40
m : & sync.Mutex {},
34
41
}
35
- return d
42
+
43
+ if err := d .loadState (); err != nil {
44
+ return nil , err
45
+ }
46
+
47
+ return d , nil
36
48
}
37
49
38
50
func (d moosefsDriver ) Create (r * volume.CreateRequest ) error {
39
- var volumeRoot string
51
+ var volumeRoot string
40
52
41
53
d .m .Lock ()
42
54
defer d .m .Unlock ()
@@ -45,15 +57,15 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
45
57
volumeRoot = optsRoot
46
58
} else {
47
59
// Assume the default root
48
- volumeRoot = * root
60
+ volumeRoot = * root
49
61
}
50
62
51
- volumePath := filepath .Join (volumeRoot , r .Name )
63
+ volumePath := filepath .Join (volumeRoot , r .Name )
52
64
53
- if err := mkdir (volumePath ); err != nil {
65
+ if err := mkdir (volumePath ); err != nil {
54
66
return err
55
67
}
56
-
68
+
57
69
if ! ismoosefs (volumePath ) {
58
70
emsg := fmt .Sprintf ("Cannot create volume %s as it's not a valid MooseFS mount" , volumePath )
59
71
log .Error (emsg )
@@ -66,19 +78,22 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
66
78
return errors .New (emsg )
67
79
}
68
80
69
- if err := mkdir (volumePath ); err != nil {
70
- return err
71
- }
72
81
d .mounts [r .Name ] = & moosefsMount {
73
82
name : r .Name ,
74
- path : volumePath ,
83
+ path : volumePath ,
75
84
root : volumeRoot ,
76
85
}
77
86
78
87
if * verbose {
79
88
spew .Dump (d .mounts )
80
89
}
81
90
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
+
82
97
return nil
83
98
}
84
99
@@ -87,6 +102,9 @@ func (d moosefsDriver) Remove(r *volume.RemoveRequest) error {
87
102
defer d .m .Unlock ()
88
103
if _ , ok := d .mounts [r .Name ]; ok {
89
104
delete (d .mounts , r .Name )
105
+ if err := d .saveState (); err != nil {
106
+ return err
107
+ }
90
108
}
91
109
return nil
92
110
}
@@ -99,16 +117,16 @@ func (d moosefsDriver) Path(r *volume.PathRequest) (*volume.PathResponse, error)
99
117
}
100
118
101
119
func (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
112
130
}
113
131
114
132
func (d moosefsDriver ) Unmount (r * volume.UnmountRequest ) error {
@@ -137,15 +155,41 @@ func (d moosefsDriver) Capabilities() *volume.CapabilitiesResponse {
137
155
return & res
138
156
}
139
157
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
149
193
}
150
194
151
195
func mkdir (path string ) error {
0 commit comments