1- // +build linux
1+ // +build linux darwin
22
3- package linux
3+ /*
4+ Package unix is the OS driver for linux and darwin. In order to reduce external
5+ dependencies, this package borrows the following packages:
6+
7+ - github.com/docker/docker/pkg/mount
8+ - github.com/opencontainers/runc/libcontainer/label
9+ */
10+ package unix
411
512import (
613 "bytes"
@@ -9,19 +16,19 @@ import (
916 "os/exec"
1017 "runtime"
1118 "strings"
19+ "syscall"
20+ "time"
1221
13- log "github.com/Sirupsen/logrus"
1422 "github.com/akutz/gofig"
1523 "github.com/akutz/goof"
1624
1725 "github.com/emccode/libstorage/api/registry"
1826 "github.com/emccode/libstorage/api/types"
1927)
2028
21- const driverName = "linux"
29+ var driverName = runtime . GOOS
2230
2331var (
24- errUnknownOS = goof .New ("unknown OS" )
2532 errUnknownFileSystem = goof .New ("unknown file system" )
2633 errUnsupportedFileSystem = goof .New ("unsupported file system" )
2734)
@@ -40,9 +47,6 @@ func newDriver() types.OSDriver {
4047}
4148
4249func (d * driver ) Init (ctx types.Context , config gofig.Config ) error {
43- if runtime .GOOS != "linux" {
44- return errUnknownOS
45- }
4650 d .config = config
4751 return nil
4852}
@@ -56,7 +60,7 @@ func (d *driver) Mounts(
5660 deviceName , mountPoint string ,
5761 opts types.Store ) ([]* types.MountInfo , error ) {
5862
59- mounts , err := getMounts ( )
63+ mounts , err := mounts ( ctx , deviceName , mountPoint , opts )
6064 if err != nil {
6165 return nil , err
6266 }
@@ -122,66 +126,59 @@ func (d *driver) Unmount(
122126 mountPoint string ,
123127 opts types.Store ) error {
124128
125- return unmount (mountPoint )
129+ var (
130+ err error
131+ isMounted bool
132+ )
133+
134+ isMounted , err = d .IsMounted (ctx , mountPoint , opts )
135+ if err != nil || ! isMounted {
136+ return err
137+ }
138+
139+ for i := 0 ; i < 10 ; i ++ {
140+ if err = syscall .Unmount (mountPoint , 0 ); err == nil {
141+ return nil
142+ }
143+ time .Sleep (100 * time .Millisecond )
144+ }
145+
146+ return nil
126147}
127148
128149func (d * driver ) IsMounted (
129150 ctx types.Context ,
130151 mountPoint string ,
131152 opts types.Store ) (bool , error ) {
132153
133- return mounted (mountPoint )
154+ entries , err := mounts (ctx , "" , mountPoint , opts )
155+ if err != nil {
156+ return false , err
157+ }
158+
159+ // Search the table for the mountpoint
160+ for _ , e := range entries {
161+ if e .MountPoint == mountPoint {
162+ return true , nil
163+ }
164+ }
165+ return false , nil
134166}
135167
136168func (d * driver ) Format (
137169 ctx types.Context ,
138170 deviceName string ,
139171 opts * types.DeviceFormatOpts ) error {
140172
141- fsType , err := probeFsType (deviceName )
142- if err != nil && err != errUnknownFileSystem {
143- return err
144- }
145- fsDetected := fsType != ""
146-
147- ctx .WithFields (log.Fields {
148- "fsDetected" : fsDetected ,
149- "fsType" : fsType ,
150- "deviceName" : deviceName ,
151- "overwriteFs" : opts .OverwriteFS ,
152- "driverName" : driverName }).Info ("probe information" )
153-
154- if opts .OverwriteFS || ! fsDetected {
155- switch opts .NewFSType {
156- case "ext4" :
157- if err := exec .Command (
158- "mkfs.ext4" , "-F" , deviceName ).Run (); err != nil {
159- return goof .WithFieldE (
160- "deviceName" , deviceName ,
161- "error creating filesystem" ,
162- err )
163- }
164- case "xfs" :
165- if err := exec .Command (
166- "mkfs.xfs" , "-f" , deviceName ).Run (); err != nil {
167- return goof .WithFieldE (
168- "deviceName" , deviceName ,
169- "error creating filesystem" ,
170- err )
171- }
172- default :
173- return errUnsupportedFileSystem
174- }
175- }
176-
177- return nil
173+ return format (ctx , deviceName , opts )
178174}
179175
180176func (d * driver ) isNfsDevice (device string ) bool {
181177 return strings .Contains (device , ":" )
182178}
183179
184180func (d * driver ) nfsMount (device , target string ) error {
181+
185182 command := exec .Command ("mount" , device , target )
186183 output , err := command .CombinedOutput ()
187184 if err != nil {
@@ -246,6 +243,28 @@ func probeFsType(device string) (string, error) {
246243 return "" , errUnknownFileSystem
247244}
248245
246+ /*
247+ formatMountLabel returns a string to be used by the mount command.
248+ The format of this string will be used to alter the labeling of the mountpoint.
249+ The string returned is suitable to be used as the options field of the mount
250+ command.
251+
252+ If you need to have additional mount point options, you can pass them in as
253+ the first parameter. Second parameter is the label that you wish to apply
254+ to all content in the mount point.
255+ */
256+ func formatMountLabel (src , mountLabel string ) string {
257+ if mountLabel != "" {
258+ switch src {
259+ case "" :
260+ src = fmt .Sprintf ("context=%q" , mountLabel )
261+ default :
262+ src = fmt .Sprintf ("%s,context=%q" , src , mountLabel )
263+ }
264+ }
265+ return src
266+ }
267+
249268func (d * driver ) volumeMountPath (target string ) string {
250269 return fmt .Sprintf ("%s%s" , target , d .volumeRootPath ())
251270}
0 commit comments