@@ -361,6 +361,77 @@ func (l VirtualDeviceList) newNVMEBusNumber() int32 {
361
361
return - 1
362
362
}
363
363
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
+
364
435
// FindDiskController will find an existing ide or scsi disk controller.
365
436
func (l VirtualDeviceList ) FindDiskController (name string ) (types.BaseVirtualController , error ) {
366
437
switch {
@@ -370,6 +441,8 @@ func (l VirtualDeviceList) FindDiskController(name string) (types.BaseVirtualCon
370
441
return l .FindSCSIController ("" )
371
442
case name == "nvme" :
372
443
return l .FindNVMEController ("" )
444
+ case name == "sata" :
445
+ return l .FindSATAController ("" )
373
446
default :
374
447
if c , ok := l .Find (name ).(types.BaseVirtualController ); ok {
375
448
return c , nil
@@ -389,6 +462,8 @@ func (l VirtualDeviceList) PickController(kind types.BaseVirtualController) type
389
462
return num < 15
390
463
case * types.VirtualIDEController :
391
464
return num < 2
465
+ case types.BaseVirtualSATAController :
466
+ return num < 30
392
467
case * types.VirtualNVMEController :
393
468
return num < 8
394
469
default :
@@ -909,8 +984,6 @@ func (l VirtualDeviceList) Type(device types.BaseVirtualDevice) string {
909
984
return "pvscsi"
910
985
case * types.VirtualLsiLogicSASController :
911
986
return "lsilogic-sas"
912
- case * types.VirtualNVMEController :
913
- return "nvme"
914
987
case * types.VirtualPrecisionClock :
915
988
return "clock"
916
989
default :
0 commit comments