@@ -3,13 +3,13 @@ package main
3
3
import (
4
4
"errors"
5
5
"fmt"
6
- "os"
6
+ "os"
7
7
"path"
8
8
"path/filepath"
9
9
"sync"
10
10
"syscall"
11
11
12
- log "github.com/Sirupsen /logrus"
12
+ log "github.com/sirupsen /logrus"
13
13
14
14
"github.com/davecgh/go-spew/spew"
15
15
"github.com/docker/go-plugins-helpers/volume"
@@ -18,7 +18,7 @@ import (
18
18
// A single volume instance
19
19
type moosefsMount struct {
20
20
name string
21
- path string
21
+ path string
22
22
root string
23
23
}
24
24
@@ -27,16 +27,21 @@ type moosefsDriver struct {
27
27
m * sync.Mutex
28
28
}
29
29
30
- func newMooseFSDriver (root string ) moosefsDriver {
31
- d := moosefsDriver {
30
+ func newMooseFSDriver (root string ) ( * moosefsDriver , error ) {
31
+ d := & moosefsDriver {
32
32
mounts : make (map [string ]* moosefsMount ),
33
33
m : & sync.Mutex {},
34
34
}
35
- return d
35
+
36
+ if err := d .loadState (); err != nil {
37
+ return nil , err
38
+ }
39
+
40
+ return d , nil
36
41
}
37
42
38
43
func (d moosefsDriver ) Create (r * volume.CreateRequest ) error {
39
- var volumeRoot string
44
+ var volumeRoot string
40
45
41
46
d .m .Lock ()
42
47
defer d .m .Unlock ()
@@ -45,15 +50,15 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
45
50
volumeRoot = optsRoot
46
51
} else {
47
52
// Assume the default root
48
- volumeRoot = * root
53
+ volumeRoot = * root
49
54
}
50
55
51
- volumePath := filepath .Join (volumeRoot , r .Name )
56
+ volumePath := filepath .Join (volumeRoot , r .Name )
52
57
53
- if err := mkdir (volumePath ); err != nil {
58
+ if err := mkdir (volumePath ); err != nil {
54
59
return err
55
60
}
56
-
61
+
57
62
if ! ismoosefs (volumePath ) {
58
63
emsg := fmt .Sprintf ("Cannot create volume %s as it's not a valid MooseFS mount" , volumePath )
59
64
log .Error (emsg )
@@ -66,19 +71,22 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
66
71
return errors .New (emsg )
67
72
}
68
73
69
- if err := mkdir (volumePath ); err != nil {
70
- return err
71
- }
72
74
d .mounts [r .Name ] = & moosefsMount {
73
75
name : r .Name ,
74
- path : volumePath ,
76
+ path : volumePath ,
75
77
root : volumeRoot ,
76
78
}
77
79
78
80
if * verbose {
79
81
spew .Dump (d .mounts )
80
82
}
81
83
84
+ if err := d .saveState (); err != nil {
85
+ // If we can't save state, remove the volume from memory
86
+ delete (d .mounts , r .Name )
87
+ return err
88
+ }
89
+
82
90
return nil
83
91
}
84
92
@@ -87,6 +95,9 @@ func (d moosefsDriver) Remove(r *volume.RemoveRequest) error {
87
95
defer d .m .Unlock ()
88
96
if _ , ok := d .mounts [r .Name ]; ok {
89
97
delete (d .mounts , r .Name )
98
+ if err := d .saveState (); err != nil {
99
+ return err
100
+ }
90
101
}
91
102
return nil
92
103
}
@@ -137,15 +148,26 @@ func (d moosefsDriver) Capabilities() *volume.CapabilitiesResponse {
137
148
return & res
138
149
}
139
150
140
- // Check if MooseFS is mounted in mountpoint using the .masterinfo file
151
+ // Check if path is under a MooseFS mount
141
152
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
153
+ // Get the parent directory until we find the mount point
154
+ currentPath := mountpoint
155
+ for currentPath != "/" {
156
+ stat := syscall.Statfs_t {}
157
+ err := syscall .Statfs (currentPath , & stat )
158
+ if err != nil {
159
+ log .Errorf ("Could not determine filesystem type for %s: %s" , currentPath , err )
160
+ return false
161
+ }
162
+
163
+ // Check if this is a FUSE filesystem (MooseFS uses FUSE)
164
+ if stat .Type == 0x65735546 { // FUSE_SUPER_MAGIC
165
+ return true
166
+ }
167
+
168
+ currentPath = filepath .Dir (currentPath )
169
+ }
170
+ return false
149
171
}
150
172
151
173
func mkdir (path string ) error {
0 commit comments