Bläddra i källkod

Filesystem: Re-implemented Umount() and IsMounted() to work around AUFS
issues.

Umount() will now attempt to remove the mntpoint after umounting.
It will keep retrying for some time until the mntpoint is deleted.

Andrea Luzzardi 12 år sedan
förälder
incheckning
174f25909c
1 ändrade filer med 35 tillägg och 10 borttagningar
  1. 35 10
      filesystem.go

+ 35 - 10
filesystem.go

@@ -7,6 +7,7 @@ import (
 	"path/filepath"
 	"path/filepath"
 	"strings"
 	"strings"
 	"syscall"
 	"syscall"
+	"time"
 )
 )
 
 
 type Filesystem struct {
 type Filesystem struct {
@@ -38,33 +39,57 @@ func (fs *Filesystem) Mount() error {
 		roBranches += fmt.Sprintf("%v=ro:", layer)
 		roBranches += fmt.Sprintf("%v=ro:", layer)
 	}
 	}
 	branches := fmt.Sprintf("br:%v:%v", rwBranch, roBranches)
 	branches := fmt.Sprintf("br:%v:%v", rwBranch, roBranches)
-	return syscall.Mount("none", fs.RootFS, "aufs", 0, branches)
+	if err := syscall.Mount("none", fs.RootFS, "aufs", 0, branches); err != nil {
+		return err
+	}
+	if !fs.IsMounted() {
+		return errors.New("Mount failed")
+	}
+	return nil
 }
 }
 
 
 func (fs *Filesystem) Umount() error {
 func (fs *Filesystem) Umount() error {
 	if !fs.IsMounted() {
 	if !fs.IsMounted() {
 		return errors.New("Umount: Filesystem not mounted")
 		return errors.New("Umount: Filesystem not mounted")
 	}
 	}
-	return syscall.Unmount(fs.RootFS, 0)
+	if err := syscall.Unmount(fs.RootFS, 0); err != nil {
+		return err
+	}
+	if fs.IsMounted() {
+		return fmt.Errorf("Umount: Filesystem still mounted after calling umount(%v)", fs.RootFS)
+	}
+	for retries := 0; retries < 1000; retries++ {
+		err := os.Remove(fs.RootFS)
+		if err == nil {
+			// rm mntpoint succeeded
+			return nil
+		}
+		if os.IsNotExist(err) {
+			// mntpoint doesn't exist anymore. Success.
+			return nil
+		}
+		// fmt.Printf("(%v) Remove %v returned: %v\n", retries, fs.RootFS, err)
+		time.Sleep(10 * time.Millisecond)
+	}
+	return fmt.Errorf("Umount: Failed to umount %v", fs.RootFS)
 }
 }
 
 
 func (fs *Filesystem) IsMounted() bool {
 func (fs *Filesystem) IsMounted() bool {
-	f, err := os.Open(fs.RootFS)
+	mntpoint, err := os.Stat(fs.RootFS)
 	if err != nil {
 	if err != nil {
 		if os.IsNotExist(err) {
 		if os.IsNotExist(err) {
 			return false
 			return false
 		}
 		}
 		panic(err)
 		panic(err)
 	}
 	}
-	list, err := f.Readdirnames(1)
-	f.Close()
+	parent, err := os.Stat(filepath.Join(fs.RootFS, ".."))
 	if err != nil {
 	if err != nil {
-		return false
-	}
-	if len(list) > 0 {
-		return true
+		panic(err)
 	}
 	}
-	return false
+
+	mntpointSt := mntpoint.Sys().(*syscall.Stat_t)
+	parentSt := parent.Sys().(*syscall.Stat_t)
+	return mntpointSt.Dev != parentSt.Dev
 }
 }
 
 
 type ChangeType int
 type ChangeType int