125125import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .InputDef ;
126126import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .InterfaceDef ;
127127import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .InterfaceDef .GuestNetType ;
128+ import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .SCSIDef ;
128129import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .SerialDef ;
129130import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .TermPolicy ;
130131import com .cloud .hypervisor .kvm .resource .LibvirtVMDef .VideoDef ;
@@ -2059,6 +2060,12 @@ So if getMinSpeed() returns null we fall back to getSpeed().
20592060 final InputDef input = new InputDef ("tablet" , "usb" );
20602061 devices .addDevice (input );
20612062
2063+ // If we're using virtio scsi, then we need to add a virtual scsi controller
2064+ if (getGuestDiskModel (vmTO .getPlatformEmulator ()) == DiskDef .DiskBus .SCSI ) {
2065+ final SCSIDef sd = new SCSIDef ((short )0 , 0 , 0 , 9 , 0 );
2066+ devices .addDevice (sd );
2067+ }
2068+
20622069 vm .addComp (devices );
20632070
20642071 return vm ;
@@ -2159,6 +2166,11 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
21592166 if (diskBusType == null ) {
21602167 diskBusType = getGuestDiskModel (vmSpec .getPlatformEmulator ());
21612168 }
2169+
2170+ // I'm not sure why previously certain DATADISKs were hard-coded VIRTIO and others not, however this
2171+ // maintains existing functionality with the exception that SCSI will override VIRTIO.
2172+ DiskDef .DiskBus diskBusTypeData = (diskBusType == DiskDef .DiskBus .SCSI ) ? diskBusType : DiskDef .DiskBus .VIRTIO ;
2173+
21622174 final DiskDef disk = new DiskDef ();
21632175 if (volume .getType () == Volume .Type .ISO ) {
21642176 if (volPath == null ) {
@@ -2188,7 +2200,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
21882200 disk .defBlockBasedDisk (physicalDisk .getPath (), devId , diskBusType );
21892201 } else {
21902202 if (volume .getType () == Volume .Type .DATADISK ) {
2191- disk .defFileBasedDisk (physicalDisk .getPath (), devId , DiskDef . DiskBus . VIRTIO , DiskDef .DiskFmtType .QCOW2 );
2203+ disk .defFileBasedDisk (physicalDisk .getPath (), devId , diskBusTypeData , DiskDef .DiskFmtType .QCOW2 );
21922204 } else {
21932205 disk .defFileBasedDisk (physicalDisk .getPath (), devId , diskBusType , DiskDef .DiskFmtType .QCOW2 );
21942206 }
@@ -2216,6 +2228,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
22162228 disk .setCacheMode (DiskDef .DiskCacheMode .valueOf (volumeObjectTO .getCacheMode ().toString ().toUpperCase ()));
22172229 }
22182230 }
2231+
22192232 vm .getDevices ().addDevice (disk );
22202233 }
22212234
@@ -2334,13 +2347,13 @@ public synchronized String attachOrDetachDisk(final Connect conn,
23342347 DiskDef diskdef = null ;
23352348 final KVMStoragePool attachingPool = attachingDisk .getPool ();
23362349 try {
2337- if (!attach ) {
2338- dm = conn .domainLookupByName (vmName );
2339- final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser ();
2340- final String xml = dm .getXMLDesc (0 );
2341- parser .parseDomainXML (xml );
2342- disks = parser .getDisks ();
2350+ dm = conn .domainLookupByName (vmName );
2351+ final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser ();
2352+ final String domXml = dm .getXMLDesc (0 );
2353+ parser .parseDomainXML (domXml );
2354+ disks = parser .getDisks ();
23432355
2356+ if (!attach ) {
23442357 for (final DiskDef disk : disks ) {
23452358 final String file = disk .getDiskPath ();
23462359 if (file != null && file .equalsIgnoreCase (attachingDisk .getPath ())) {
@@ -2352,17 +2365,29 @@ public synchronized String attachOrDetachDisk(final Connect conn,
23522365 throw new InternalErrorException ("disk: " + attachingDisk .getPath () + " is not attached before" );
23532366 }
23542367 } else {
2368+ DiskDef .DiskBus busT = DiskDef .DiskBus .VIRTIO ;
2369+ for (final DiskDef disk : disks ) {
2370+ s_logger .debug ("disk is type : " +disk .toString ());
2371+ if (disk .getDeviceType () == DeviceType .DISK ) {
2372+ if (disk .getBusType () == DiskDef .DiskBus .SCSI ) {
2373+ busT = DiskDef .DiskBus .SCSI ;
2374+ }
2375+ s_logger .debug ("Disk bus type: " + disk .getDeviceType ().toString () + ", busT: " +busT .toString ());
2376+ break ;
2377+ }
2378+ }
2379+
23552380 diskdef = new DiskDef ();
23562381 if (attachingPool .getType () == StoragePoolType .RBD ) {
23572382 diskdef .defNetworkBasedDisk (attachingDisk .getPath (), attachingPool .getSourceHost (), attachingPool .getSourcePort (), attachingPool .getAuthUserName (),
2358- attachingPool .getUuid (), devId , DiskDef . DiskBus . VIRTIO , DiskProtocol .RBD , DiskDef .DiskFmtType .RAW );
2383+ attachingPool .getUuid (), devId , busT , DiskProtocol .RBD , DiskDef .DiskFmtType .RAW );
23592384 } else if (attachingPool .getType () == StoragePoolType .Gluster ) {
23602385 diskdef .defNetworkBasedDisk (attachingDisk .getPath (), attachingPool .getSourceHost (), attachingPool .getSourcePort (), null ,
2361- null , devId , DiskDef . DiskBus . VIRTIO , DiskProtocol .GLUSTER , DiskDef .DiskFmtType .QCOW2 );
2386+ null , devId , busT , DiskProtocol .GLUSTER , DiskDef .DiskFmtType .QCOW2 );
23622387 } else if (attachingDisk .getFormat () == PhysicalDiskFormat .QCOW2 ) {
2363- diskdef .defFileBasedDisk (attachingDisk .getPath (), devId , DiskDef . DiskBus . VIRTIO , DiskDef .DiskFmtType .QCOW2 );
2388+ diskdef .defFileBasedDisk (attachingDisk .getPath (), devId , busT , DiskDef .DiskFmtType .QCOW2 );
23642389 } else if (attachingDisk .getFormat () == PhysicalDiskFormat .RAW ) {
2365- diskdef .defBlockBasedDisk (attachingDisk .getPath (), devId , DiskDef . DiskBus . VIRTIO );
2390+ diskdef .defBlockBasedDisk (attachingDisk .getPath (), devId , busT );
23662391 }
23672392 if (bytesReadRate != null && bytesReadRate > 0 ) {
23682393 diskdef .setBytesReadRate (bytesReadRate );
@@ -2961,19 +2986,8 @@ private String getHypervisorPath(final Connect conn) {
29612986 }
29622987
29632988 boolean isGuestPVEnabled (final String guestOSName ) {
2964- if (guestOSName == null ) {
2965- return false ;
2966- }
2967- if (guestOSName .startsWith ("Ubuntu" ) || guestOSName .startsWith ("Fedora 13" ) || guestOSName .startsWith ("Fedora 12" ) || guestOSName .startsWith ("Fedora 11" ) ||
2968- guestOSName .startsWith ("Fedora 10" ) || guestOSName .startsWith ("Fedora 9" ) || guestOSName .startsWith ("CentOS 5.3" ) || guestOSName .startsWith ("CentOS 5.4" ) ||
2969- guestOSName .startsWith ("CentOS 5.5" ) || guestOSName .startsWith ("CentOS" ) || guestOSName .startsWith ("Fedora" ) ||
2970- guestOSName .startsWith ("Red Hat Enterprise Linux 5.3" ) || guestOSName .startsWith ("Red Hat Enterprise Linux 5.4" ) ||
2971- guestOSName .startsWith ("Red Hat Enterprise Linux 5.5" ) || guestOSName .startsWith ("Red Hat Enterprise Linux 6" ) || guestOSName .startsWith ("Debian GNU/Linux" ) ||
2972- guestOSName .startsWith ("FreeBSD 10" ) || guestOSName .startsWith ("Oracle" ) || guestOSName .startsWith ("Other PV" )) {
2973- return true ;
2974- } else {
2975- return false ;
2976- }
2989+ DiskDef .DiskBus db = getGuestDiskModel (guestOSName );
2990+ return db != DiskDef .DiskBus .IDE ;
29772991 }
29782992
29792993 public boolean isCentosHost () {
@@ -2985,13 +2999,22 @@ public boolean isCentosHost() {
29852999 }
29863000
29873001 private DiskDef .DiskBus getGuestDiskModel (final String platformEmulator ) {
2988- if (isGuestPVEnabled (platformEmulator )) {
3002+ if (platformEmulator == null ) {
3003+ return DiskDef .DiskBus .IDE ;
3004+ } else if (platformEmulator .startsWith ("Other PV Virtio-SCSI" )) {
3005+ return DiskDef .DiskBus .SCSI ;
3006+ } else if (platformEmulator .startsWith ("Ubuntu" ) || platformEmulator .startsWith ("Fedora 13" ) || platformEmulator .startsWith ("Fedora 12" ) || platformEmulator .startsWith ("Fedora 11" ) ||
3007+ platformEmulator .startsWith ("Fedora 10" ) || platformEmulator .startsWith ("Fedora 9" ) || platformEmulator .startsWith ("CentOS 5.3" ) || platformEmulator .startsWith ("CentOS 5.4" ) ||
3008+ platformEmulator .startsWith ("CentOS 5.5" ) || platformEmulator .startsWith ("CentOS" ) || platformEmulator .startsWith ("Fedora" ) ||
3009+ platformEmulator .startsWith ("Red Hat Enterprise Linux 5.3" ) || platformEmulator .startsWith ("Red Hat Enterprise Linux 5.4" ) ||
3010+ platformEmulator .startsWith ("Red Hat Enterprise Linux 5.5" ) || platformEmulator .startsWith ("Red Hat Enterprise Linux 6" ) || platformEmulator .startsWith ("Debian GNU/Linux" ) ||
3011+ platformEmulator .startsWith ("FreeBSD 10" ) || platformEmulator .startsWith ("Oracle" ) || platformEmulator .startsWith ("Other PV" )) {
29893012 return DiskDef .DiskBus .VIRTIO ;
29903013 } else {
29913014 return DiskDef .DiskBus .IDE ;
29923015 }
2993- }
29943016
3017+ }
29953018 private void cleanupVMNetworks (final Connect conn , final List <InterfaceDef > nics ) {
29963019 if (nics != null ) {
29973020 for (final InterfaceDef nic : nics ) {
0 commit comments