[lxc-devel] [lxd/master] Storage: Cache supported drivers

tomponline on Github lxc-bot at linuxcontainers.org
Thu Aug 27 15:25:15 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 960 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200827/8ac2f6b7/attachment.bin>
-------------- next part --------------
From 57bd5b22ad8102ff21125000a75e262ff6e6ce28 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Aug 2020 16:17:38 +0100
Subject: [PATCH 1/4] lxd/daemon: db.StorageRemoteDriverNames usage

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/daemon.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/daemon.go b/lxd/daemon.go
index 15d43ceaa1..cafe77ef02 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -828,7 +828,7 @@ func (d *Daemon) init() error {
 	}
 
 	// Have the db package determine remote storage drivers
-	db.GetRemoteDrivers = storageDrivers.RemoteDriverNames(d.State())
+	db.StorageRemoteDriverNames = storageDrivers.RemoteDriverNames(d.State())
 
 	/* Open the cluster database */
 	for {

From c64e135e44d0e92e595539591b81ac2ffb82b096 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Aug 2020 16:18:29 +0100
Subject: [PATCH 2/4] lxd/db: StorageRemoteDriverNames usage

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/db/instances.go       |  2 +-
 lxd/db/instances_test.go  |  2 +-
 lxd/db/storage_pools.go   |  4 ++--
 lxd/db/storage_volumes.go | 12 ++++++------
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/lxd/db/instances.go b/lxd/db/instances.go
index 51cc7a0f36..d05267cb40 100644
--- a/lxd/db/instances.go
+++ b/lxd/db/instances.go
@@ -657,7 +657,7 @@ func (c *ClusterTx) GetInstancePool(projectName string, instanceName string) (st
 	// as that must always be the same as the snapshot's storage pool.
 	instanceName, _, _ = shared.InstanceGetParentAndSnapshotName(instanceName)
 
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	// Get container storage volume. Since container names are globally
 	// unique, and their storage volumes carry the same name, their storage
diff --git a/lxd/db/instances_test.go b/lxd/db/instances_test.go
index 6dcc92fc1a..a2239ae94f 100644
--- a/lxd/db/instances_test.go
+++ b/lxd/db/instances_test.go
@@ -200,7 +200,7 @@ func TestInstanceListExpanded(t *testing.T) {
 }
 
 func TestCreateInstance(t *testing.T) {
-	db.GetRemoteDrivers = func() []string {
+	db.StorageRemoteDriverNames = func() []string {
 		return []string{"ceph", "cephfs"}
 	}
 
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 013547658b..78e351444f 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -80,7 +80,7 @@ func (c *ClusterTx) GetStoragePoolUsedBy(name string) ([]string, error) {
 		return []interface{}{&vols[i].volName, &vols[i].volType, &vols[i].projectName, &vols[i].nodeID}
 	}
 
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	s := fmt.Sprintf(`
 SELECT storage_volumes.name, storage_volumes.type, projects.name, storage_volumes.node_id
@@ -898,7 +898,7 @@ func (c *Cluster) isRemoteStorage(poolID int64) (bool, error) {
 			return err
 		}
 
-		isRemoteStorage = shared.StringInSlice(driver, GetRemoteDrivers())
+		isRemoteStorage = shared.StringInSlice(driver, StorageRemoteDriverNames())
 
 		return nil
 	})
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 0517e289e2..f89d6ab1db 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -89,7 +89,7 @@ WHERE storage_volumes.type = ?
 func (c *Cluster) GetStoragePoolVolumes(project string, poolID int64, volumeTypes []int) ([]*api.StorageVolume, error) {
 	var nodeIDs []int
 
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	err := c.Transaction(func(tx *ClusterTx) error {
 		var err error
@@ -187,7 +187,7 @@ func (c *Cluster) storagePoolVolumesGet(project string, poolID, nodeID int64, vo
 func (c *Cluster) storagePoolVolumesGetType(project string, volumeType int, poolID, nodeID int64) ([]string, error) {
 	var poolName string
 
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	query := fmt.Sprintf(`
 SELECT storage_volumes_all.name
@@ -223,7 +223,7 @@ SELECT storage_volumes_all.name
 // Returns snapshots slice ordered by when they were created, oldest first.
 func (c *Cluster) GetLocalStoragePoolVolumeSnapshotsWithType(projectName string, volumeName string, volumeType int, poolID int64) ([]StorageVolumeArgs, error) {
 	result := []StorageVolumeArgs{}
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	// ORDER BY id is important here as the users of this function can expect that the results
 	// will be returned in the order that the snapshots were created. This is specifically used
@@ -433,7 +433,7 @@ func storagePoolVolumeReplicateIfCeph(tx *sql.Tx, volumeID int64, project, volum
 	}
 	volumeIDs := []int64{volumeID}
 
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	// If this is a ceph volume, we want to duplicate the change across the
 	// the rows for all other nodes.
@@ -463,7 +463,7 @@ func (c *Cluster) CreateStoragePoolVolume(project, volumeName, volumeDescription
 		return -1, fmt.Errorf("Volume name may not be a snapshot")
 	}
 
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	err := c.Transaction(func(tx *ClusterTx) error {
 		driver, err := tx.GetStoragePoolDriver(poolID)
@@ -525,7 +525,7 @@ func (c *Cluster) storagePoolVolumeGetTypeID(project string, volumeName string,
 }
 
 func (c *ClusterTx) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
-	remoteDrivers := GetRemoteDrivers()
+	remoteDrivers := StorageRemoteDriverNames()
 
 	s := fmt.Sprintf(`
 SELECT storage_volumes_all.id

From 677f5a20f7f001a13e756e3d7bd241fd2fd9a73d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Aug 2020 16:18:40 +0100
Subject: [PATCH 3/4] lxd/db/storage/pools: Renames GetRemoteDrivers to
 StorageRemoteDriverNames for clarity

Easier to relate to linked function.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/db/storage_pools.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 78e351444f..e27a3d1e12 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -15,8 +15,8 @@ import (
 	"github.com/lxc/lxd/shared/api"
 )
 
-// GetRemoteDrivers returns a list of remote storage driver names.
-var GetRemoteDrivers func() []string
+// StorageRemoteDriverNames returns a list of remote storage driver names.
+var StorageRemoteDriverNames func() []string
 
 // GetStoragePoolsLocalConfig returns a map associating each storage pool name to
 // its node-specific config values (i.e. the ones where node_id is not NULL).

From 19693c8154170beb80d5b8cd20436f2e4496b93a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Aug 2020 16:19:41 +0100
Subject: [PATCH 4/4] lxd/storage/drivers/load: Cache supported drivers

So that repeated calls to SupportedDrivers() don't cause driver introspection every time which can cause slow downs if a storage driver isn't available and takes time to discover this.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/load.go | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/lxd/storage/drivers/load.go b/lxd/storage/drivers/load.go
index 5e7889fbe0..432048724d 100644
--- a/lxd/storage/drivers/load.go
+++ b/lxd/storage/drivers/load.go
@@ -46,9 +46,18 @@ func Load(state *state.State, driverName string, name string, config map[string]
 	return d, nil
 }
 
+// supportedDrivers cache of supported drivers to avoid inspecting the storage layer every time.
+var supportedDrivers []Info
+
 // SupportedDrivers returns a list of supported storage drivers.
 func SupportedDrivers(s *state.State) []Info {
-	supportedDrivers := make([]Info, 0, len(drivers))
+	// Return cached list if available.
+	if supportedDrivers != nil {
+		return supportedDrivers
+	}
+
+	// Initialise fresh cache and populate.
+	supportedDrivers = make([]Info, 0, len(drivers))
 
 	for driverName := range drivers {
 		driver, err := Load(s, driverName, "", nil, nil, nil, nil)


More information about the lxc-devel mailing list