[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