From df3b77b7646b862f625406b0471691714ea4e54d Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 19 Feb 2020 15:20:56 +0800 Subject: [PATCH] fix(esxi): No distinction between ordinary scsi and pvscsi when creating disks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parascsi 是 vmware 中一种高性能的 scsi 控制器。 在此之前,scsi 只包括 "lsilogic", "lsilogicsas", "buslogic"; 而别名为 pvscsi 的 parascsi 没有被包含进来;并且,一个 pci controller只能挂一个 scsi controller, 这会导致如果在一个拥有 pvscsi 的机器上添加普通scsi驱动类型的磁盘,就会替换驱动; 反之亦然。这会导致驱动的 key 不是我们指定的key,并且在添加磁盘的时候替换驱动的 类型有些随意。再者,我们的驱动类型的选择其实并没有暴露给前端。 所以,在寻找相应的controller时,将 parascsi 也纳入 scsi 类型。 尽量避免在创建磁盘的时候做硬件的改动,所以在创建磁盘的时候不区分 scsi 还是 pvscsi,如果两种 controller 均没有,就按照请求的类型创建一个。 此外,在 CloneVM 的时候,如果支持,优先使用 parascsi。 --- pkg/multicloud/esxi/host.go | 8 ++++++-- pkg/multicloud/esxi/virtualmachine.go | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/pkg/multicloud/esxi/host.go b/pkg/multicloud/esxi/host.go index 1069a3a59e..c48f921649 100644 --- a/pkg/multicloud/esxi/host.go +++ b/pkg/multicloud/esxi/host.go @@ -879,7 +879,11 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData } if len(scsiDevs) == 0 { key := from.FindMinDiffKey(1000) - deviceChange = append(deviceChange, addDevSpec(NewSCSIDev(key, 100, "scsi"))) + driver := "pvscsi" + if host.isVersion50() { + driver = "scsi" + } + deviceChange = append(deviceChange, addDevSpec(NewSCSIDev(key, 100, driver))) ctlKey = key } else { ctlKey = minDevKey(scsiDevs) @@ -914,7 +918,7 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, ds *SData // find same disk var index int32 var key int32 = 2000 - sameDisk := from.FindDiskByDriver("scsi") + sameDisk := from.FindDiskByDriver("scsi", "pvscsi") index += int32(len(sameDisk)) if len(sameDisk) > 0 { key = minDiskKey(sameDisk) diff --git a/pkg/multicloud/esxi/virtualmachine.go b/pkg/multicloud/esxi/virtualmachine.go index 8834c9fe6e..16d7f13ff0 100644 --- a/pkg/multicloud/esxi/virtualmachine.go +++ b/pkg/multicloud/esxi/virtualmachine.go @@ -33,6 +33,7 @@ import ( "yunion.io/x/pkg/util/netutils" "yunion.io/x/pkg/util/reflectutils" "yunion.io/x/pkg/util/regutils" + "yunion.io/x/pkg/utils" billing_api "yunion.io/x/onecloud/pkg/apis/billing" api "yunion.io/x/onecloud/pkg/apis/compute" @@ -787,7 +788,7 @@ func (self *SVirtualMachine) GetVGADevice() string { var ( driverTable = map[string][]string{ "sata": {"ahci"}, - "scsi": {"lsilogic", "lsilogicsas", "buslogic"}, + "scsi": {"parascsi", "lsilogic", "lsilogicsas", "buslogic"}, "pvscsi": {"parascsi"}, "ide": {"ide"}, } @@ -838,10 +839,10 @@ func (self *SVirtualMachine) FindController(ctx context.Context, driver string) return devs, nil } -func (self *SVirtualMachine) FindDiskByDriver(driver string) []SVirtualDisk { +func (self *SVirtualMachine) FindDiskByDriver(drivers ...string) []SVirtualDisk { disks := make([]SVirtualDisk, 0) for i := range self.vdisks { - if self.vdisks[i].GetDriver() == driver { + if utils.IsInStringArray(self.vdisks[i].GetDriver(), drivers) { disks = append(disks, self.vdisks[i]) } } @@ -849,6 +850,9 @@ func (self *SVirtualMachine) FindDiskByDriver(driver string) []SVirtualDisk { } func (self *SVirtualMachine) CreateDisk(ctx context.Context, sizeMb int, uuid string, driver string) error { + if driver == "pvscsi" { + driver = "scsi" + } devs, err := self.FindController(ctx, driver) if err != nil { return err @@ -857,10 +861,14 @@ func (self *SVirtualMachine) CreateDisk(ctx context.Context, sizeMb int, uuid st return self.createDriverAndDisk(ctx, sizeMb, uuid, driver) } ctlKey := minDevKey(devs) - sameDisks := self.FindDiskByDriver(driver) + drivers := []string{driver} + if driver == "scsi" { + drivers = append(drivers, "pvscsi") + } + sameDisks := self.FindDiskByDriver(drivers...) - var diskKey int32 = 2000 - if len(sameDisks) == 0 { + diskKey := self.FindMinDiffKey(2000) + if len(sameDisks) != 0 { diskKey = minDiskKey(sameDisks) } index := len(sameDisks)