Explorar o código

zfs: update filesystem cache on filesystem creation/deletion

Previously the cache was only updated once on startup, because the graph
code only check for filesystems on startup. However this breaks the API as it
was supposed and so unit tests.

Fixes #13142

Signed-off-by: Jörg Thalheim <joerg@higgsboson.tk>
Jörg Thalheim %!s(int64=10) %!d(string=hai) anos
pai
achega
2cb23527e4
Modificáronse 1 ficheiros con 25 adicións e 5 borrados
  1. 25 5
      daemon/graphdriver/zfs/zfs.go

+ 25 - 5
daemon/graphdriver/zfs/zfs.go

@@ -7,6 +7,7 @@ import (
 	"path"
 	"path"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"sync"
 	"syscall"
 	"syscall"
 	"time"
 	"time"
 
 
@@ -154,6 +155,7 @@ func lookupZfsDataset(rootdir string) (string, error) {
 type Driver struct {
 type Driver struct {
 	dataset          *zfs.Dataset
 	dataset          *zfs.Dataset
 	options          ZfsOptions
 	options          ZfsOptions
+	sync.Mutex       // protects filesystem cache against concurrent access
 	filesystemsCache map[string]bool
 	filesystemsCache map[string]bool
 }
 }
 
 
@@ -194,7 +196,7 @@ func (d *Driver) Status() [][2]string {
 	}
 	}
 }
 }
 
 
-func cloneFilesystem(name, parentName string) error {
+func (d *Driver) cloneFilesystem(name, parentName string) error {
 	snapshotName := fmt.Sprintf("%d", time.Now().Nanosecond())
 	snapshotName := fmt.Sprintf("%d", time.Now().Nanosecond())
 	parentDataset := zfs.Dataset{Name: parentName}
 	parentDataset := zfs.Dataset{Name: parentName}
 	snapshot, err := parentDataset.Snapshot(snapshotName /*recursive */, false)
 	snapshot, err := parentDataset.Snapshot(snapshotName /*recursive */, false)
@@ -203,6 +205,12 @@ func cloneFilesystem(name, parentName string) error {
 	}
 	}
 
 
 	_, err = snapshot.Clone(name, map[string]string{"mountpoint": "legacy"})
 	_, err = snapshot.Clone(name, map[string]string{"mountpoint": "legacy"})
+	if err == nil {
+		d.Lock()
+		d.filesystemsCache[name] = true
+		d.Unlock()
+	}
+
 	if err != nil {
 	if err != nil {
 		snapshot.Destroy(zfs.DestroyDeferDeletion)
 		snapshot.Destroy(zfs.DestroyDeferDeletion)
 		return err
 		return err
@@ -245,15 +253,27 @@ func (d *Driver) create(id, parent string) error {
 	name := d.ZfsPath(id)
 	name := d.ZfsPath(id)
 	if parent == "" {
 	if parent == "" {
 		mountoptions := map[string]string{"mountpoint": "legacy"}
 		mountoptions := map[string]string{"mountpoint": "legacy"}
-		_, err := zfs.CreateFilesystem(name, mountoptions)
+		fs, err := zfs.CreateFilesystem(name, mountoptions)
+		if err == nil {
+			d.Lock()
+			d.filesystemsCache[fs.Name] = true
+			d.Unlock()
+		}
 		return err
 		return err
 	}
 	}
-	return cloneFilesystem(name, d.ZfsPath(parent))
+	return d.cloneFilesystem(name, d.ZfsPath(parent))
 }
 }
 
 
 func (d *Driver) Remove(id string) error {
 func (d *Driver) Remove(id string) error {
-	dataset := zfs.Dataset{Name: d.ZfsPath(id)}
-	return dataset.Destroy(zfs.DestroyRecursive)
+	name := d.ZfsPath(id)
+	dataset := zfs.Dataset{Name: name}
+	err := dataset.Destroy(zfs.DestroyRecursive)
+	if err == nil {
+		d.Lock()
+		delete(d.filesystemsCache, name)
+		d.Unlock()
+	}
+	return err
 }
 }
 
 
 func (d *Driver) Get(id, mountLabel string) (string, error) {
 func (d *Driver) Get(id, mountLabel string) (string, error) {