DaanHoogland commented on code in PR #6508:
URL: https://github.com/apache/cloudstack/pull/6508#discussion_r992000677


##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1207,14 +1222,38 @@ protected synchronized String 
attachOrDetachDevice(final Connect conn, final boo
             }
         }
 
-        return null;
+        return;

Review Comment:
   ```suggestion
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1068,10 +1072,9 @@ public Answer backupSnapshot(final CopyCommand cmd) {
             }
         }
     }
-
-    protected synchronized String attachOrDetachISO(final Connect conn, final 
String vmName, String isoPath, final boolean isAttach, Map<String, String> 
params) throws LibvirtException, URISyntaxException,
+    protected synchronized void attachOrDetachISO(final Connect conn, final 
String vmName, String isoPath, final boolean isAttach, Map<String, String> 
params) throws LibvirtException, URISyntaxException,

Review Comment:
   sonarcode sugesstion(s):
   ```suggestion
       protected synchronized void attachOrDetachISO(final Connect conn, final 
String vmName, String isoPath, final boolean isAttach, Map<String, String> 
params) throws LibvirtException,
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1207,14 +1222,38 @@ protected synchronized String 
attachOrDetachDevice(final Connect conn, final boo
             }
         }
 
-        return null;
+        return;
     }
-
-    protected synchronized String attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId, final String serial,
-            final Long bytesReadRate, final Long bytesReadRateMax, final Long 
bytesReadRateMaxLength,
-            final Long bytesWriteRate, final Long bytesWriteRateMax, final 
Long bytesWriteRateMaxLength,
-            final Long iopsReadRate, final Long iopsReadRateMax, final Long 
iopsReadRateMaxLength,
-            final Long iopsWriteRate, final Long iopsWriteRateMax, final Long 
iopsWriteRateMaxLength, final String cacheMode, final 
DiskDef.LibvirtDiskEncryptDetails encryptDetails) throws LibvirtException, 
InternalErrorException {
+    protected boolean checkDetachSucess(String diskPath, Domain dm) throws 
LibvirtException {
+        LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+        parser.parseDomainXML(dm.getXMLDesc(0));
+        List<DiskDef> disks = parser.getDisks();
+        for (DiskDef diskDef : disks) {
+            if (StringUtils.equals(diskPath, diskDef.getDiskPath())) {
+                s_logger.debug(String.format("The hypervisor sent the detach 
command, but it is still possible to identify the device [%s] in the instance 
with UUID [%s].",
+                        diskPath, dm.getUUIDString()));
+                return false;
+            }
+        }
+        return true;
+    }
+    protected synchronized void attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId,

Review Comment:
   ```suggestion
   
       /**
        *
        */
       protected synchronized void attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId,
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1169,27 +1168,43 @@ private String getDataStoreUrlFromStore(DataStoreTO 
store) {
         }
         return store.getUrl();
     }
-
-    protected synchronized String attachOrDetachDevice(final Connect conn, 
final boolean attach, final String vmName, final String xml) throws 
LibvirtException, InternalErrorException {
+    protected synchronized void attachOrDetachDevice(final Connect conn, final 
boolean attach, final String vmName, final DiskDef xml)
+            throws LibvirtException, InternalErrorException {
+        attachOrDetachDevice(conn, attach, vmName, xml, 0l);
+    }
+    protected synchronized void attachOrDetachDevice(final Connect conn, final 
boolean attach, final String vmName, final DiskDef diskDef, long 
waitDetachDevice)

Review Comment:
   ```suggestion
   
       /**
        *
        */
       protected synchronized void attachOrDetachDevice(final Connect conn, 
final boolean attach, final String vmName, final DiskDef diskDef, long 
waitDetachDevice)
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1081,26 +1084,22 @@ protected synchronized String attachOrDetachISO(final 
Connect conn, final String
             final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
             isoPath = isoVol.getPath();
 
-            final DiskDef iso = new DiskDef();
             iso.defISODisk(isoPath, isUefiEnabled);
-            isoXml = iso.toString();
         } else {
-            final DiskDef iso = new DiskDef();
             iso.defISODisk(null, isUefiEnabled);
-            isoXml = iso.toString();
         }
 
         final List<DiskDef> disks = resource.getDisks(conn, vmName);
-        final String result = attachOrDetachDevice(conn, true, vmName, isoXml);
-        if (result == null && !isAttach) {
+        attachOrDetachDevice(conn, true, vmName, iso);
+        if (!isAttach) {
             for (final DiskDef disk : disks) {
                 if (disk.getDeviceType() == DiskDef.DeviceType.CDROM) {
                     resource.cleanupDisk(disk);
                 }
             }
 
         }
-        return result;
+        return;

Review Comment:
   ```suggestion
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1207,14 +1222,38 @@ protected synchronized String 
attachOrDetachDevice(final Connect conn, final boo
             }
         }
 
-        return null;
+        return;
     }
-
-    protected synchronized String attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId, final String serial,
-            final Long bytesReadRate, final Long bytesReadRateMax, final Long 
bytesReadRateMaxLength,
-            final Long bytesWriteRate, final Long bytesWriteRateMax, final 
Long bytesWriteRateMaxLength,
-            final Long iopsReadRate, final Long iopsReadRateMax, final Long 
iopsReadRateMaxLength,
-            final Long iopsWriteRate, final Long iopsWriteRateMax, final Long 
iopsWriteRateMaxLength, final String cacheMode, final 
DiskDef.LibvirtDiskEncryptDetails encryptDetails) throws LibvirtException, 
InternalErrorException {
+    protected boolean checkDetachSucess(String diskPath, Domain dm) throws 
LibvirtException {
+        LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+        parser.parseDomainXML(dm.getXMLDesc(0));
+        List<DiskDef> disks = parser.getDisks();
+        for (DiskDef diskDef : disks) {
+            if (StringUtils.equals(diskPath, diskDef.getDiskPath())) {
+                s_logger.debug(String.format("The hypervisor sent the detach 
command, but it is still possible to identify the device [%s] in the instance 
with UUID [%s].",
+                        diskPath, dm.getUUIDString()));
+                return false;
+            }
+        }
+        return true;
+    }
+    protected synchronized void attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId,
+                                                   final String serial, final 
Long bytesReadRate, final Long bytesReadRateMax, final Long 
bytesReadRateMaxLength,
+                                                   final Long bytesWriteRate, 
final Long bytesWriteRateMax, final Long bytesWriteRateMaxLength, final Long 
iopsReadRate,
+                                                   final Long iopsReadRateMax, 
final Long iopsReadRateMaxLength, final Long iopsWriteRate, final Long 
iopsWriteRateMax,
+                                                   final Long 
iopsWriteRateMaxLength, final String cacheMode, final 
DiskDef.LibvirtDiskEncryptDetails encryptDetails)
+            throws LibvirtException, InternalErrorException {
+        attachOrDetachDisk(conn, attach, vmName, attachingDisk, devId, serial, 
bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength,
+                bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength, 
iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate,
+                iopsWriteRateMax, iopsWriteRateMaxLength, cacheMode, 
encryptDetails, 0l);
+    }
+    protected synchronized void attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId,
+                                                   final String serial, final 
Long bytesReadRate, final Long bytesReadRateMax, final Long 
bytesReadRateMaxLength,
+                                                   final Long bytesWriteRate, 
final Long bytesWriteRateMax, final Long bytesWriteRateMaxLength, final Long 
iopsReadRate,
+                                                   final Long iopsReadRateMax, 
final Long iopsReadRateMaxLength, final Long iopsWriteRate, final Long 
iopsWriteRateMax,
+                                                   final Long 
iopsWriteRateMaxLength, final String cacheMode, final 
DiskDef.LibvirtDiskEncryptDetails encryptDetails,
+                                                   long waitDetachDevice)

Review Comment:
   ```suggestion
   
       /**
        *
        */
       protected synchronized void attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId,
                                                      final String serial, 
final Long bytesReadRate, final Long bytesReadRateMax, final Long 
bytesReadRateMaxLength,
                                                      final Long 
bytesWriteRate, final Long bytesWriteRateMax, final Long 
bytesWriteRateMaxLength, final Long iopsReadRate,
                                                      final Long 
iopsReadRateMax, final Long iopsReadRateMaxLength, final Long iopsWriteRate, 
final Long iopsWriteRateMax,
                                                      final Long 
iopsWriteRateMaxLength, final String cacheMode, final 
DiskDef.LibvirtDiskEncryptDetails encryptDetails)
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1169,27 +1168,43 @@ private String getDataStoreUrlFromStore(DataStoreTO 
store) {
         }
         return store.getUrl();
     }
-
-    protected synchronized String attachOrDetachDevice(final Connect conn, 
final boolean attach, final String vmName, final String xml) throws 
LibvirtException, InternalErrorException {
+    protected synchronized void attachOrDetachDevice(final Connect conn, final 
boolean attach, final String vmName, final DiskDef xml)
+            throws LibvirtException, InternalErrorException {
+        attachOrDetachDevice(conn, attach, vmName, xml, 0l);
+    }
+    protected synchronized void attachOrDetachDevice(final Connect conn, final 
boolean attach, final String vmName, final DiskDef diskDef, long 
waitDetachDevice)
+            throws LibvirtException, InternalErrorException {
         Domain dm = null;
+        String diskXml = diskDef.toString();
+        String diskPath = diskDef.getDiskPath();
         try {
             dm = conn.domainLookupByName(vmName);
 
             if (attach) {
-                s_logger.debug("Attaching device: " + xml);
-                dm.attachDevice(xml);
-            } else {
-                s_logger.debug("Detaching device: " + xml);
-                dm.detachDevice(xml);
-                LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-                parser.parseDomainXML(dm.getXMLDesc(0));
-                List<DiskDef> disks = parser.getDisks();
-                for (DiskDef diskDef : disks) {
-                    if (StringUtils.contains(xml, diskDef.getDiskPath())) {
-                        throw new InternalErrorException("Could not detach 
volume. Probably the VM is in boot state at the moment");
-                    }
+                s_logger.debug("Attaching device: " + diskXml);
+                dm.attachDevice(diskXml);
+                return;
+            }
+            s_logger.debug(String.format("Detaching device: [%s].", diskXml));
+            dm.detachDevice(diskXml);
+            long wait = waitDetachDevice;
+            while (!checkDetachSucess(diskPath, dm) && wait > 0) {
+                try {
+                    wait -= waitDelayForVirshCommands;
+                    Thread.sleep(waitDelayForVirshCommands);
+                    s_logger.trace(String.format("Trying to detach device [%s] 
from VM instance with UUID [%s]. " +
+                            "Waiting [%s] milliseconds before assuming the VM 
was unable to detach the volume.", diskPath, dm.getUUIDString(), wait));
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
                 }

Review Comment:
   extract this block into a method. Also a sonar suggestion but this one I 
very much agree on. It makes code both more readable and more debug-able. The 
exception can be cloudstack specific.
   
   ```suggestion
                   try {
                       wait -= waitDelayForVirshCommands;
                       Thread.sleep(waitDelayForVirshCommands);
                       s_logger.trace(String.format("Trying to detach device 
[%s] from VM instance with UUID [%s]. " +
                               "Waiting [%s] milliseconds before assuming the 
VM was unable to detach the volume.", diskPath, dm.getUUIDString(), wait));
                   } catch (InterruptedException e) {
                       throw new CloudRuntimeException(e);
                   }
   ```



##########
server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java:
##########
@@ -336,6 +336,14 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
     public static final ConfigKey<Boolean> 
MatchStoragePoolTagsWithDiskOffering = new ConfigKey<Boolean>("Advanced", 
Boolean.class, "match.storage.pool.tags.with.disk.offering", "true",
             "If true, volume's disk offering can be changed only with the 
matched storage tags", true, ConfigKey.Scope.Zone);
 
+    public static ConfigKey<Long> WaitDetachDevice = new ConfigKey<>(

Review Comment:
   ```suggestion
       public static final ConfigKey<Long> WaitDetachDevice = new ConfigKey<>(
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1207,14 +1222,38 @@ protected synchronized String 
attachOrDetachDevice(final Connect conn, final boo
             }
         }
 
-        return null;
+        return;
     }
-
-    protected synchronized String attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId, final String serial,
-            final Long bytesReadRate, final Long bytesReadRateMax, final Long 
bytesReadRateMaxLength,
-            final Long bytesWriteRate, final Long bytesWriteRateMax, final 
Long bytesWriteRateMaxLength,
-            final Long iopsReadRate, final Long iopsReadRateMax, final Long 
iopsReadRateMaxLength,
-            final Long iopsWriteRate, final Long iopsWriteRateMax, final Long 
iopsWriteRateMaxLength, final String cacheMode, final 
DiskDef.LibvirtDiskEncryptDetails encryptDetails) throws LibvirtException, 
InternalErrorException {
+    protected boolean checkDetachSucess(String diskPath, Domain dm) throws 
LibvirtException {

Review Comment:
   ```suggestion
   
       /**
        *
        */
       protected boolean checkDetachSucess(String diskPath, Domain dm) throws 
LibvirtException {
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to