From b6c1dd079a7e558d01f6e19bea2d61134acbeed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Fri, 6 Sep 2024 01:08:55 -0400 Subject: [PATCH] incusd/storage/drivers/lvm: Cache VG extent size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Querying this value can get extremely expensive on busy systems. Signed-off-by: Stéphane Graber --- internal/server/storage/drivers/driver_lvm.go | 4 ++++ .../storage/drivers/driver_lvm_utils.go | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/internal/server/storage/drivers/driver_lvm.go b/internal/server/storage/drivers/driver_lvm.go index 9f620be85ab..6c9acc364e7 100644 --- a/internal/server/storage/drivers/driver_lvm.go +++ b/internal/server/storage/drivers/driver_lvm.go @@ -9,6 +9,7 @@ import ( "slices" "strconv" "strings" + "sync" "time" "github.com/lxc/incus/v6/internal/linux" @@ -26,6 +27,9 @@ import ( const lvmVgPoolMarker = "incus_pool" // Indicator tag used to mark volume groups as in use. +var lvmExtentSize map[string]int64 +var lvmExtentSizeMu sync.Mutex + var lvmLoaded bool var lvmVersion string diff --git a/internal/server/storage/drivers/driver_lvm_utils.go b/internal/server/storage/drivers/driver_lvm_utils.go index c17d3abc92c..e3d626caf3e 100644 --- a/internal/server/storage/drivers/driver_lvm_utils.go +++ b/internal/server/storage/drivers/driver_lvm_utils.go @@ -132,6 +132,16 @@ func (d *lvm) volumeGroupExists(vgName string) (bool, []string, error) { // volumeGroupExtentSize gets the volume group's physical extent size in bytes. func (d *lvm) volumeGroupExtentSize(vgName string) (int64, error) { + // Look for cached value. + lvmExtentSizeMu.Lock() + defer lvmExtentSizeMu.Unlock() + + if lvmExtentSize == nil { + lvmExtentSize = map[string]int64{} + } else if lvmExtentSize[d.name] > 0 { + return lvmExtentSize[d.name], nil + } + output, err := subprocess.TryRunCommand("vgs", "--noheadings", "--nosuffix", "--units", "b", "-o", "vg_extent_size", vgName) if err != nil { if d.isLVMNotFoundExitError(err) { @@ -142,7 +152,14 @@ func (d *lvm) volumeGroupExtentSize(vgName string) (int64, error) { } output = strings.TrimSpace(output) - return strconv.ParseInt(output, 10, 64) + val, err := strconv.ParseInt(output, 10, 64) + if err != nil { + return -1, err + } + + lvmExtentSize[d.name] = val + + return val, nil } // countLogicalVolumes gets the count of volumes (both normal and thin) in a volume group.