@@ -361,6 +361,77 @@ func (l VirtualDeviceList) newNVMEBusNumber() int32 {
361361 return - 1
362362}
363363
364+ // FindSATAController will find the named SATA or AHCI controller if given, otherwise will pick an available controller.
365+ // An error is returned if the named controller is not found or not a SATA or AHCI controller. Or, if name is not
366+ // given and no available controller can be found.
367+ func (l VirtualDeviceList ) FindSATAController (name string ) (types.BaseVirtualController , error ) {
368+ if name != "" {
369+ d := l .Find (name )
370+ if d == nil {
371+ return nil , fmt .Errorf ("device '%s' not found" , name )
372+ }
373+ switch c := d .(type ) {
374+ case * types.VirtualSATAController :
375+ return c , nil
376+ case * types.VirtualAHCIController :
377+ return c , nil
378+ default :
379+ return nil , fmt .Errorf ("%s is not a SATA or AHCI controller" , name )
380+ }
381+ }
382+
383+ c := l .PickController ((* types .VirtualSATAController )(nil ))
384+ if c == nil {
385+ c = l .PickController ((* types .VirtualAHCIController )(nil ))
386+ }
387+ if c == nil {
388+ return nil , errors .New ("no available SATA or AHCI controller" )
389+ }
390+
391+ switch c := c .(type ) {
392+ case * types.VirtualSATAController :
393+ return c , nil
394+ case * types.VirtualAHCIController :
395+ return c , nil
396+ }
397+
398+ return nil , errors .New ("unexpected controller type" )
399+ }
400+
401+ // CreateSATAController creates a new SATA controller.
402+ func (l VirtualDeviceList ) CreateSATAController () (types.BaseVirtualDevice , error ) {
403+ sata := & types.VirtualAHCIController {}
404+ sata .BusNumber = l .newSATABusNumber ()
405+ sata .Key = l .NewKey ()
406+
407+ return sata , nil
408+ }
409+
410+ var sataBusNumbers = []int {0 , 1 , 2 , 3 }
411+
412+ // newSATABusNumber returns the bus number to use for adding a new SATA bus device.
413+ // -1 is returned if there are no bus numbers available.
414+ func (l VirtualDeviceList ) newSATABusNumber () int32 {
415+ var used []int
416+
417+ for _ , d := range l .SelectByType ((* types .VirtualSATAController )(nil )) {
418+ num := d .(types.BaseVirtualController ).GetVirtualController ().BusNumber
419+ if num >= 0 {
420+ used = append (used , int (num ))
421+ } // else caller is creating a new vm using SATAControllerTypes
422+ }
423+
424+ sort .Ints (used )
425+
426+ for i , n := range sataBusNumbers {
427+ if i == len (used ) || n != used [i ] {
428+ return int32 (n )
429+ }
430+ }
431+
432+ return - 1
433+ }
434+
364435// FindDiskController will find an existing ide or scsi disk controller.
365436func (l VirtualDeviceList ) FindDiskController (name string ) (types.BaseVirtualController , error ) {
366437 switch {
@@ -370,6 +441,8 @@ func (l VirtualDeviceList) FindDiskController(name string) (types.BaseVirtualCon
370441 return l .FindSCSIController ("" )
371442 case name == "nvme" :
372443 return l .FindNVMEController ("" )
444+ case name == "sata" :
445+ return l .FindSATAController ("" )
373446 default :
374447 if c , ok := l .Find (name ).(types.BaseVirtualController ); ok {
375448 return c , nil
@@ -389,6 +462,8 @@ func (l VirtualDeviceList) PickController(kind types.BaseVirtualController) type
389462 return num < 15
390463 case * types.VirtualIDEController :
391464 return num < 2
465+ case types.BaseVirtualSATAController :
466+ return num < 30
392467 case * types.VirtualNVMEController :
393468 return num < 8
394469 default :
@@ -909,8 +984,6 @@ func (l VirtualDeviceList) Type(device types.BaseVirtualDevice) string {
909984 return "pvscsi"
910985 case * types.VirtualLsiLogicSASController :
911986 return "lsilogic-sas"
912- case * types.VirtualNVMEController :
913- return "nvme"
914987 case * types.VirtualPrecisionClock :
915988 return "clock"
916989 default :
0 commit comments