From f9957d24824812a7b4704f8f31ebef58cef322ee Mon Sep 17 00:00:00 2001 From: Vicente Cheng Date: Mon, 28 Oct 2024 10:28:48 +0800 Subject: [PATCH] provisioner/lvm: ensure only one lvmvg for the vgName - Because the lvmvg name is generated with the prefix, we need to ensure we only have one lvmvg CR for the specific vgName in the same node. Signed-off-by: Vicente Cheng (cherry picked from commit ca6454146df39707fffae95e71d414d20954f94a) --- pkg/controller/blockdevice/controller.go | 7 +++++-- pkg/provisioner/lvm.go | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkg/controller/blockdevice/controller.go b/pkg/controller/blockdevice/controller.go index 2eeb6f54..c4a4c89d 100644 --- a/pkg/controller/blockdevice/controller.go +++ b/pkg/controller/blockdevice/controller.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "reflect" + "sync" "time" gocommon "github.com/harvester/go-common" @@ -38,7 +39,8 @@ type Controller struct { BlockdeviceCache ctldiskv1.BlockDeviceCache BlockInfo block.Info - LVMVgClient ctldiskv1.LVMVolumeGroupController + LVMVgClient ctldiskv1.LVMVolumeGroupController + provisionerLock *sync.Mutex // Lock for some specific provisioner operations, e.g. LVM scanner *Scanner semaphore *provisioner.Semaphore @@ -81,6 +83,7 @@ func Register( BlockInfo: block, scanner: scanner, semaphore: semaphoreObj, + provisionerLock: &sync.Mutex{}, } if err := scanner.Start(); err != nil { @@ -269,7 +272,7 @@ func (c *Controller) generateLHv1Provisioner(device *diskv1.BlockDevice) (provis func (c *Controller) generateLVMProvisioner(device *diskv1.BlockDevice) (provisioner.Provisioner, error) { vgName := device.Spec.Provisioner.LVM.VgName - return provisioner.NewLVMProvisioner(vgName, c.NodeName, c.LVMVgClient, device, c.BlockInfo) + return provisioner.NewLVMProvisioner(vgName, c.NodeName, c.LVMVgClient, device, c.BlockInfo, c.provisionerLock) } func (c *Controller) generateLHv2Provisioner(device *diskv1.BlockDevice) (provisioner.Provisioner, error) { diff --git a/pkg/provisioner/lvm.go b/pkg/provisioner/lvm.go index 92682791..17bf0d51 100644 --- a/pkg/provisioner/lvm.go +++ b/pkg/provisioner/lvm.go @@ -3,6 +3,7 @@ package provisioner import ( "fmt" "reflect" + "sync" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/errors" @@ -20,9 +21,10 @@ type LVMProvisioner struct { vgName string nodeName string vgClient ctldiskv1.LVMVolumeGroupController + lock *sync.Mutex } -func NewLVMProvisioner(vgName, nodeName string, lvmVGs ctldiskv1.LVMVolumeGroupController, device *diskv1.BlockDevice, blockInfo block.Info) (Provisioner, error) { +func NewLVMProvisioner(vgName, nodeName string, lvmVGs ctldiskv1.LVMVolumeGroupController, device *diskv1.BlockDevice, blockInfo block.Info, lock *sync.Mutex) (Provisioner, error) { baseProvisioner := &provisioner{ name: TypeLVM, blockInfo: blockInfo, @@ -33,6 +35,7 @@ func NewLVMProvisioner(vgName, nodeName string, lvmVGs ctldiskv1.LVMVolumeGroupC vgName: vgName, vgClient: lvmVGs, nodeName: nodeName, + lock: lock, }, nil } @@ -67,6 +70,9 @@ func (l *LVMProvisioner) UnFormat() (bool, error) { func (l *LVMProvisioner) Provision() (bool, error) { logrus.Infof("Provisioning block device %s to vg: %s", l.device.Name, l.vgName) found := true + // because the LVMVG name is a generated name, we need to lock here to ensure we only have one LVMVG CRD for specific vgName. + l.lock.Lock() + defer l.lock.Unlock() lvmvg, err := l.getTargetLVMVG() if err != nil { if !errors.IsNotFound(err) {