You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by vi...@apache.org on 2024/06/25 13:24:17 UTC

(cloudstack) branch main updated (f6ceeab3b3a -> 3923f80c225)

This is an automated email from the ASF dual-hosted git repository.

vishesh pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


    from f6ceeab3b3a server: Enforce strict host tag check (#9017)
     add ae3fa5d0de3 Add configuration to limit the number of rows deleted from vm_stats (#8740)
     add 097359bef9e plugins/shutdown: fix triggerShutdown scheduling and response (#9276)
     add 5ab23cd9c97 Timeout config to copy the disks of remote KVM instance while importing the instance from an external host (#9213)
     add ded7b4dbe5a test: fix test failure on ubuntu 24.04: "top: unknown option 'n'" (#9262)
     add 083ac069ca4 fix assignvm template permission check (#8886)
     add 60f234c682d remove Project Template Permissions inhibition (#9196)
     add 0c422aca767 server: fix additional zones cannot be removed (#9261)
     add 674495b162b Fixup startVM on simulator (#9199)
     add 313a165e62b server: add global setting consoleproxy.sslEnabled (#8809)
     add 9055610034b Remove duplicate network state checks before shutdown network (#8462)
     add 59e9ab9efee Fix volume response for service offering with disk offering (#9273)
     add 7e00678691e set isSystem for SVM IPs (#9281)
     add f4612c51ec4 libvirtstorage: Make sure netfs storage was really mounted (#8887)
     add 6a518e29b74 Allow deletion of external managed cks nodes (#9183)
     add c17aa0d9ada Import Remote KVM VM logging improvements (#9284)
     add f792684b9c4 Support migration of VM imported from a remote host (#9259)
     add f944d4c61d1 debian: add cpu-checker to debian/control (#9263)
     add 3e30283500f Fix migration from local storage to NFS in KVM (#8909)
     add 8b07b66f145 Fix volume snapshot of encrypted NFS/StorPool volume (#8873)
     add de266a4cb85 api,server: allow updating hypervisor capabilities with hypervisor and  version (#8475)
     add 4d6df586da2 engine-schema: fix options for host.allocators.order config (#8733)
     add fcfa3713373 kvm: support Rocky/RHEL/OL/Alma in the same cluster (#8641)
     add 42e71175d77 Merge remote-tracking branch 'origin/4.18' into 4.19
     add 6ee66033596 Updates to HPE-Primera and Pure FlashArray Drivers to use Host-based VLUN Assignments (#8889)
     add 620ed164d8b VMware: Improve error messaging / logs when starting non-user VMs, and secondary storage not available or doesn't have enough capacity (#9207)
     new 3923f80c225 Merge branch '4.19'

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../config/UpdateHypervisorCapabilitiesCmd.java    |  14 +
 .../admin/vm/ImportUnmanagedInstanceCmd.java       |   8 +-
 .../apache/cloudstack/vm/UnmanagedVMsManager.java  |   9 +
 .../com/cloud/agent/api/CheckVolumeAnswer.java     |   1 -
 .../com/cloud/agent/api/CheckVolumeCommand.java    |   1 -
 .../cloud/agent/api/CopyRemoteVolumeAnswer.java    |   1 -
 .../cloud/agent/api/CopyRemoteVolumeCommand.java   |   5 +-
 .../com/cloud/agent/api/GetRemoteVmsAnswer.java    |   2 +-
 .../com/cloud/agent/api/GetRemoteVmsCommand.java   |   2 +-
 .../agent/api/GetUnmanagedInstancesAnswer.java     |   2 +-
 .../agent/api/GetUnmanagedInstancesCommand.java    |   2 +-
 debian/control                                     |   2 +-
 .../engine/orchestration/NetworkOrchestrator.java  |  12 +-
 .../engine/orchestration/VolumeOrchestrator.java   |   9 +-
 .../orchestration/NetworkOrchestratorTest.java     | 272 ++++++++-------
 .../cloud/hypervisor/HypervisorCapabilitiesVO.java |  12 +
 .../src/main/java/com/cloud/vm/dao/VmStatsDao.java |   6 +-
 .../main/java/com/cloud/vm/dao/VmStatsDaoImpl.java |  22 +-
 .../storage/datastore/db/ImageStoreDaoImpl.java    |   2 +-
 .../resources/META-INF/db/schema-41900to41910.sql  |   5 +
 .../motion/StorageSystemDataMotionStrategy.java    | 370 ++++++++++++---------
 .../KvmNonManagedStorageSystemDataMotionTest.java  |   8 +-
 .../StorageSystemDataMotionStrategyTest.java       |  71 ----
 .../manager/ImageStoreProviderManagerImpl.java     |   2 +-
 .../main/java/com/cloud/utils/db/GenericDao.java   |   8 +
 .../java/com/cloud/utils/db/GenericDaoBase.java    |   6 +
 .../model/impl/DefaultModuleDefinitionSet.java     |   4 +-
 .../acl/DynamicRoleBasedAPIAccessChecker.java      |   4 +-
 .../acl/ProjectRoleBasedApiAccessChecker.java      |   8 +-
 .../kvm/resource/LibvirtComputingResource.java     |  41 ++-
 .../LibvirtCopyRemoteVolumeCommandWrapper.java     |  17 +-
 .../wrapper/LibvirtGetRemoteVmsCommandWrapper.java |  21 +-
 .../LibvirtMigrateVolumeCommandWrapper.java        |  18 +-
 .../kvm/storage/FiberChannelAdapter.java           |  28 ++
 .../kvm/storage/KVMStorageProcessor.java           |  72 ++--
 .../kvm/storage/LibvirtStorageAdaptor.java         |  20 +-
 .../kvm/storage/MultipathSCSIAdapterBase.java      | 262 +++++----------
 .../kvm/storage/KVMStorageProcessorTest.java       |  66 ++--
 .../com/cloud/agent/manager/MockVmManagerImpl.java |  79 ++---
 .../vmware/manager/VmwareManagerImpl.java          |  13 +-
 .../hypervisor/vmware/resource/VmwareResource.java |  19 +-
 .../cluster/KubernetesServiceHelperImpl.java       |   3 +
 .../cluster/KubernetesServiceHelperImplTest.java   |  20 +-
 .../cloudstack/shutdown/ShutdownManagerImpl.java   |   5 +-
 plugins/storage/volume/adaptive/README.md          |  41 +++
 .../storage/datastore/adapter/ProviderAdapter.java |  22 +-
 .../datastore/adapter/ProviderAdapterFactory.java  |   4 +
 .../datastore/adapter/ProviderVolumeNamer.java     |   1 -
 .../driver/AdaptiveDataStoreDriverImpl.java        | 222 +++++++++----
 .../lifecycle/AdaptiveDataStoreLifeCycleImpl.java  |  11 +-
 .../AdaptivePrimaryDatastoreAdapterFactoryMap.java |   4 +
 .../provider/AdaptivePrimaryHostListener.java      |   2 +
 .../adapter/flasharray/FlashArrayAdapter.java      | 274 ++++++++-------
 .../flasharray/FlashArrayAdapterFactory.java       |   5 +
 ...lashArrayVolumePod.java => FlashArrayHost.java} |  29 +-
 .../adapter/flasharray/FlashArrayVolume.java       |   4 +-
 .../adapter/flasharray/FlashArrayVolumePod.java    |  17 +-
 .../datastore/adapter/primera/PrimeraAdapter.java  | 201 +++++------
 .../adapter/primera/PrimeraAdapterFactory.java     |   5 +
 .../datastore/adapter/primera/PrimeraHost.java}    |  35 +-
 ...aVolumeLink.java => PrimeraHostDescriptor.java} |  24 +-
 .../datastore/adapter/primera/PrimeraHostset.java  |  44 ++-
 .../{PrimeraVolumeLink.java => PrimeraPort.java}   |  24 +-
 ...PrimeraCpgSAGrowth.java => PrimeraPortPos.java} |  31 +-
 .../PrimeraVolumeCopyRequestParameters.java        |   2 +-
 .../primera/PrimeraVolumePromoteRequest.java       |   5 +-
 .../StorPoolBackupSnapshotCommandWrapper.java      |  63 +++-
 .../cloudstack/oauth2/OAuth2UserAuthenticator.java |   5 +
 scripts/storage/multipath/copyVolume.sh            |   2 +-
 .../com/cloud/api/query/dao/VolumeJoinDaoImpl.java |   7 +-
 .../configuration/ConfigurationManagerImpl.java    |   2 +
 .../AgentBasedConsoleProxyManager.java             |   2 +-
 .../java/com/cloud/consoleproxy/AgentHookBase.java |   2 +-
 .../cloud/consoleproxy/ConsoleProxyManager.java    |   3 +
 .../consoleproxy/ConsoleProxyManagerImpl.java      |   4 +-
 .../consoleproxy/StaticConsoleProxyManager.java    |   2 +-
 .../kvm/discoverer/LibvirtServerDiscoverer.java    |  18 +-
 .../com/cloud/network/guru/PublicNetworkGuru.java  |   2 +-
 .../com/cloud/server/ManagementServerImpl.java     |  52 ++-
 .../main/java/com/cloud/server/StatsCollector.java |  12 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java    |  43 +--
 .../com/cloud/template/TemplateManagerImpl.java    |   7 +-
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  |  11 +-
 .../apache/cloudstack/snapshot/SnapshotHelper.java |   4 +-
 .../cloudstack/vm/UnmanagedVMsManagerImpl.java     |  27 +-
 .../discoverer/LibvirtServerDiscovererTest.java    |  54 +++
 .../java/com/cloud/server/StatsCollectorTest.java  |   8 +-
 .../java/com/cloud/user/MockUsageEventDao.java     |   5 +
 test/integration/smoke/test_service_offerings.py   |   2 +-
 ui/src/views/compute/DeployVM.vue                  |   2 +
 .../main/java/com/cloud/utils/ssh/SshHelper.java   |   8 +-
 91 files changed, 1711 insertions(+), 1197 deletions(-)
 copy plugins/storage/volume/flasharray/src/main/java/org/apache/cloudstack/storage/datastore/adapter/flasharray/{FlashArrayVolumePod.java => FlashArrayHost.java} (84%)
 copy plugins/storage/volume/{flasharray/src/main/java/org/apache/cloudstack/storage/datastore/adapter/flasharray/FlashArrayVolumeSource.java => primera/src/main/java/org/apache/cloudstack/storage/datastore/adapter/primera/PrimeraHost.java} (65%)
 copy plugins/storage/volume/primera/src/main/java/org/apache/cloudstack/storage/datastore/adapter/primera/{PrimeraVolumeLink.java => PrimeraHostDescriptor.java} (76%)
 copy plugins/storage/volume/primera/src/main/java/org/apache/cloudstack/storage/datastore/adapter/primera/{PrimeraVolumeLink.java => PrimeraPort.java} (75%)
 copy plugins/storage/volume/primera/src/main/java/org/apache/cloudstack/storage/datastore/adapter/primera/{PrimeraCpgSAGrowth.java => PrimeraPortPos.java} (68%)
 create mode 100644 server/src/test/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscovererTest.java


(cloudstack) 01/01: Merge branch '4.19'

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vishesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 3923f80c225c593a79e32cc7d9d5567fb63ecca2
Merge: f6ceeab3b3a 620ed164d8b
Author: Vishesh <vi...@gmail.com>
AuthorDate: Tue Jun 25 18:53:57 2024 +0530

    Merge branch '4.19'

 .../config/UpdateHypervisorCapabilitiesCmd.java    |  14 +
 .../admin/vm/ImportUnmanagedInstanceCmd.java       |   8 +-
 .../apache/cloudstack/vm/UnmanagedVMsManager.java  |   9 +
 .../com/cloud/agent/api/CheckVolumeAnswer.java     |   1 -
 .../com/cloud/agent/api/CheckVolumeCommand.java    |   1 -
 .../cloud/agent/api/CopyRemoteVolumeAnswer.java    |   1 -
 .../cloud/agent/api/CopyRemoteVolumeCommand.java   |   5 +-
 .../com/cloud/agent/api/GetRemoteVmsAnswer.java    |   2 +-
 .../com/cloud/agent/api/GetRemoteVmsCommand.java   |   2 +-
 .../agent/api/GetUnmanagedInstancesAnswer.java     |   2 +-
 .../agent/api/GetUnmanagedInstancesCommand.java    |   2 +-
 debian/control                                     |   2 +-
 .../engine/orchestration/NetworkOrchestrator.java  |  12 +-
 .../engine/orchestration/VolumeOrchestrator.java   |   9 +-
 .../orchestration/NetworkOrchestratorTest.java     | 272 ++++++++-------
 .../cloud/hypervisor/HypervisorCapabilitiesVO.java |  12 +
 .../src/main/java/com/cloud/vm/dao/VmStatsDao.java |   6 +-
 .../main/java/com/cloud/vm/dao/VmStatsDaoImpl.java |  22 +-
 .../storage/datastore/db/ImageStoreDaoImpl.java    |   2 +-
 .../resources/META-INF/db/schema-41900to41910.sql  |   5 +
 .../motion/StorageSystemDataMotionStrategy.java    | 370 ++++++++++++---------
 .../KvmNonManagedStorageSystemDataMotionTest.java  |   8 +-
 .../StorageSystemDataMotionStrategyTest.java       |  71 ----
 .../manager/ImageStoreProviderManagerImpl.java     |   2 +-
 .../main/java/com/cloud/utils/db/GenericDao.java   |   8 +
 .../java/com/cloud/utils/db/GenericDaoBase.java    |   6 +
 .../model/impl/DefaultModuleDefinitionSet.java     |   4 +-
 .../acl/DynamicRoleBasedAPIAccessChecker.java      |   4 +-
 .../acl/ProjectRoleBasedApiAccessChecker.java      |   8 +-
 .../kvm/resource/LibvirtComputingResource.java     |  41 ++-
 .../LibvirtCopyRemoteVolumeCommandWrapper.java     |  17 +-
 .../wrapper/LibvirtGetRemoteVmsCommandWrapper.java |  21 +-
 .../LibvirtMigrateVolumeCommandWrapper.java        |  18 +-
 .../kvm/storage/FiberChannelAdapter.java           |  28 ++
 .../kvm/storage/KVMStorageProcessor.java           |  72 ++--
 .../kvm/storage/LibvirtStorageAdaptor.java         |  20 +-
 .../kvm/storage/MultipathSCSIAdapterBase.java      | 262 +++++----------
 .../kvm/storage/KVMStorageProcessorTest.java       |  66 ++--
 .../com/cloud/agent/manager/MockVmManagerImpl.java |  79 ++---
 .../vmware/manager/VmwareManagerImpl.java          |  13 +-
 .../hypervisor/vmware/resource/VmwareResource.java |  19 +-
 .../cluster/KubernetesServiceHelperImpl.java       |   3 +
 .../cluster/KubernetesServiceHelperImplTest.java   |  20 +-
 .../cloudstack/shutdown/ShutdownManagerImpl.java   |   5 +-
 plugins/storage/volume/adaptive/README.md          |  41 +++
 .../storage/datastore/adapter/ProviderAdapter.java |  22 +-
 .../datastore/adapter/ProviderAdapterFactory.java  |   4 +
 .../datastore/adapter/ProviderVolumeNamer.java     |   1 -
 .../driver/AdaptiveDataStoreDriverImpl.java        | 222 +++++++++----
 .../lifecycle/AdaptiveDataStoreLifeCycleImpl.java  |  11 +-
 .../AdaptivePrimaryDatastoreAdapterFactoryMap.java |   4 +
 .../provider/AdaptivePrimaryHostListener.java      |   2 +
 .../adapter/flasharray/FlashArrayAdapter.java      | 274 ++++++++-------
 .../flasharray/FlashArrayAdapterFactory.java       |   5 +
 ...lashArrayVolumePod.java => FlashArrayHost.java} |  29 +-
 .../adapter/flasharray/FlashArrayVolume.java       |   4 +-
 .../adapter/flasharray/FlashArrayVolumePod.java    |  17 +-
 .../datastore/adapter/primera/PrimeraAdapter.java  | 201 +++++------
 .../adapter/primera/PrimeraAdapterFactory.java     |   5 +
 .../datastore/adapter/primera/PrimeraHost.java}    |  33 +-
 .../adapter/primera/PrimeraHostDescriptor.java}    |  31 +-
 .../datastore/adapter/primera/PrimeraHostset.java  |  44 ++-
 .../datastore/adapter/primera/PrimeraPort.java}    |  31 +-
 .../datastore/adapter/primera/PrimeraPortPos.java} |  38 ++-
 .../PrimeraVolumeCopyRequestParameters.java        |   2 +-
 .../primera/PrimeraVolumePromoteRequest.java       |   5 +-
 .../StorPoolBackupSnapshotCommandWrapper.java      |  63 +++-
 .../cloudstack/oauth2/OAuth2UserAuthenticator.java |   5 +
 scripts/storage/multipath/copyVolume.sh            |   2 +-
 .../com/cloud/api/query/dao/VolumeJoinDaoImpl.java |   7 +-
 .../configuration/ConfigurationManagerImpl.java    |   2 +
 .../AgentBasedConsoleProxyManager.java             |   2 +-
 .../java/com/cloud/consoleproxy/AgentHookBase.java |   2 +-
 .../cloud/consoleproxy/ConsoleProxyManager.java    |   3 +
 .../consoleproxy/ConsoleProxyManagerImpl.java      |   4 +-
 .../consoleproxy/StaticConsoleProxyManager.java    |   2 +-
 .../kvm/discoverer/LibvirtServerDiscoverer.java    |  18 +-
 .../com/cloud/network/guru/PublicNetworkGuru.java  |   2 +-
 .../com/cloud/server/ManagementServerImpl.java     |  52 ++-
 .../main/java/com/cloud/server/StatsCollector.java |  12 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java    |  43 +--
 .../com/cloud/template/TemplateManagerImpl.java    |   7 +-
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  |  11 +-
 .../apache/cloudstack/snapshot/SnapshotHelper.java |   4 +-
 .../cloudstack/vm/UnmanagedVMsManagerImpl.java     |  27 +-
 .../discoverer/LibvirtServerDiscovererTest.java    |  54 +++
 .../java/com/cloud/server/StatsCollectorTest.java  |   8 +-
 .../java/com/cloud/user/MockUsageEventDao.java     |   5 +
 test/integration/smoke/test_service_offerings.py   |   2 +-
 ui/src/views/compute/DeployVM.vue                  |   2 +
 .../main/java/com/cloud/utils/ssh/SshHelper.java   |   8 +-
 91 files changed, 1718 insertions(+), 1209 deletions(-)

diff --cc api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
index dd897218a4d,3d8b23318dd..ae6ceff26c7
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
@@@ -201,8 -203,8 +201,8 @@@ public class ImportUnmanagedInstanceCm
              for (Map<String, String> entry : (Collection<Map<String, String>>)nicNetworkList.values()) {
                  String nic = entry.get(VmDetailConstants.NIC);
                  String networkUuid = entry.get(VmDetailConstants.NETWORK);
-                 if (logger.isTraceEnabled()) {
-                     logger.trace(String.format("nic, '%s', goes on net, '%s'", nic, networkUuid));
 -                if (LOGGER.isDebugEnabled()) {
 -                    LOGGER.debug(String.format("nic, '%s', goes on net, '%s'", nic, networkUuid));
++                if (logger.isDebugEnabled()) {
++                    logger.debug(String.format("nic, '%s', goes on net, '%s'", nic, networkUuid));
                  }
                  if (StringUtils.isAnyEmpty(nic, networkUuid) || _entityMgr.findByUuid(Network.class, networkUuid) == null) {
                      throw new InvalidParameterValueException(String.format("Network ID: %s for NIC ID: %s is invalid", networkUuid, nic));
@@@ -219,8 -221,8 +219,8 @@@
              for (Map<String, String> entry : (Collection<Map<String, String>>)nicIpAddressList.values()) {
                  String nic = entry.get(VmDetailConstants.NIC);
                  String ipAddress = StringUtils.defaultIfEmpty(entry.get(VmDetailConstants.IP4_ADDRESS), null);
-                 if (logger.isTraceEnabled()) {
-                     logger.trace(String.format("nic, '%s', gets ip, '%s'", nic, ipAddress));
 -                if (LOGGER.isDebugEnabled()) {
 -                    LOGGER.debug(String.format("nic, '%s', gets ip, '%s'", nic, ipAddress));
++                if (logger.isDebugEnabled()) {
++                    logger.debug(String.format("nic, '%s', gets ip, '%s'", nic, ipAddress));
                  }
                  if (StringUtils.isEmpty(nic)) {
                      throw new InvalidParameterValueException(String.format("NIC ID: '%s' is invalid for IP address mapping", nic));
diff --cc debian/control
index 3508c7b5f75,c968f337bd5..dab7b254b88
--- a/debian/control
+++ b/debian/control
@@@ -24,7 -24,7 +24,7 @@@ Description: CloudStack server librar
  
  Package: cloudstack-agent
  Architecture: all
- Depends: ${python:Depends}, ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, lsb-release, ufw, apparmor
 -Depends: ${python:Depends}, ${python3:Depends}, openjdk-11-jre-headless | java11-runtime-headless | java11-runtime | openjdk-11-jre-headless | zulu-11, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, lsb-release, ufw, apparmor, cpu-checker
++Depends: ${python:Depends}, ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, lsb-release, ufw, apparmor, cpu-checker
  Recommends: init-system-helpers
  Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts
  Description: CloudStack agent
diff --cc engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
index d1532cdbef1,45ed646240f..a4700f6cdc0
--- a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
+++ b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
@@@ -92,8 -95,9 +94,8 @@@ import junit.framework.TestCase
   */
  @RunWith(JUnit4.class)
  public class NetworkOrchestratorTest extends TestCase {
 -    static final Logger s_logger = Logger.getLogger(NetworkOrchestratorTest.class);
  
-     NetworkOrchestrator testOrchastrator = Mockito.spy(new NetworkOrchestrator());
+     NetworkOrchestrator testOrchestrator = Mockito.spy(new NetworkOrchestrator());
  
      private String guruName = "GuestNetworkGuru";
      private String dhcpProvider = "VirtualRouter";
@@@ -135,8 -140,8 +138,8 @@@
          when(provider.getCapabilities()).thenReturn(services);
          capabilities.put(Network.Capability.DhcpAccrossMultipleSubnets, "true");
  
-         when(testOrchastrator._ntwkSrvcDao.getProviderForServiceInNetwork(ArgumentMatchers.anyLong(), ArgumentMatchers.eq(Service.Dhcp))).thenReturn(dhcpProvider);
-         when(testOrchastrator._networkModel.getElementImplementingProvider(dhcpProvider)).thenReturn(provider);
 -        when(testOrchestrator._ntwkSrvcDao.getProviderForServiceInNetwork(Matchers.anyLong(), Matchers.eq(Service.Dhcp))).thenReturn(dhcpProvider);
++        when(testOrchestrator._ntwkSrvcDao.getProviderForServiceInNetwork(ArgumentMatchers.anyLong(), ArgumentMatchers.eq(Service.Dhcp))).thenReturn(dhcpProvider);
+         when(testOrchestrator._networkModel.getElementImplementingProvider(dhcpProvider)).thenReturn(provider);
  
          when(guru.getName()).thenReturn(guruName);
          List<NetworkGuru> networkGurus = new ArrayList<NetworkGuru>();
diff --cc engine/schema/src/main/java/com/cloud/vm/dao/VmStatsDaoImpl.java
index 1bef8f0626c,a98302e2136..aa58e489364
--- a/engine/schema/src/main/java/com/cloud/vm/dao/VmStatsDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/VmStatsDaoImpl.java
@@@ -21,6 -21,7 +21,8 @@@ import java.util.List
  
  import javax.annotation.PostConstruct;
  
 -import org.apache.log4j.Logger;
++import org.apache.logging.log4j.LogManager;
++import org.apache.logging.log4j.Logger;
  import org.springframework.stereotype.Component;
  
  import com.cloud.utils.db.Filter;
@@@ -33,6 -34,8 +35,8 @@@ import com.cloud.vm.VmStatsVO
  @Component
  public class VmStatsDaoImpl extends GenericDaoBase<VmStatsVO, Long> implements VmStatsDao {
  
 -    protected Logger logger = Logger.getLogger(getClass());
++    protected Logger logger = LogManager.getLogger(getClass());
+ 
      protected SearchBuilder<VmStatsVO> vmIdSearch;
      protected SearchBuilder<VmStatsVO> vmIdTimestampGreaterThanEqualSearch;
      protected SearchBuilder<VmStatsVO> vmIdTimestampLessThanEqualSearch;
diff --cc engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
index 03aa5b50988,f3e6049c792..70e79e3252b
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
@@@ -69,10 -71,8 +71,9 @@@ import org.apache.cloudstack.storage.da
  import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
  import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
  import org.apache.cloudstack.storage.to.VolumeObjectTO;
- import org.apache.commons.collections.MapUtils;
  import org.apache.commons.lang3.StringUtils;
 -import org.apache.log4j.Logger;
 +import org.apache.logging.log4j.Logger;
 +import org.apache.logging.log4j.LogManager;
  
  import com.cloud.agent.AgentManager;
  import com.cloud.agent.api.Answer;
@@@ -141,8 -140,11 +141,11 @@@ import java.util.HashSet
  import java.util.stream.Collectors;
  import org.apache.commons.collections.CollectionUtils;
  
+ import static org.apache.cloudstack.vm.UnmanagedVMsManagerImpl.KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME;
+ import static org.apache.cloudstack.vm.UnmanagedVMsManagerImpl.VM_IMPORT_DEFAULT_TEMPLATE_NAME;
+ 
  public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
 -    private static final Logger LOGGER = Logger.getLogger(StorageSystemDataMotionStrategy.class);
 +    protected Logger logger = LogManager.getLogger(getClass());
      private static final Random RANDOM = new Random(System.nanoTime());
      private static final int LOCK_TIME_IN_SECONDS = 300;
      private static final String OPERATION_NOT_SUPPORTED = "This operation is not supported.";
@@@ -871,6 -869,18 +870,18 @@@
                  throw new CloudRuntimeException(errMsg, ex);
              }
          } finally {
+             // revoke access (for managed volumes)
+             if (hostVO != null) {
+                 try {
+                     _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+                 } catch (Exception e) {
 -                    LOGGER.warn(String.format("Failed to revoke access for volume 'name=%s,uuid=%s' after a migration attempt", destVolumeInfo.getVolume(), destVolumeInfo.getUuid()), e);
++                    logger.warn(String.format("Failed to revoke access for volume 'name=%s,uuid=%s' after a migration attempt", destVolumeInfo.getVolume(), destVolumeInfo.getUuid()), e);
+                 }
+             }
+ 
+             // re-retrieve volume to get any updated information from grant
+             destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
+ 
              CopyCmdAnswer copyCmdAnswer;
              if (errMsg != null) {
                  copyCmdAnswer = new CopyCmdAnswer(errMsg);
@@@ -921,6 -931,125 +932,125 @@@
          return hostVO;
      }
  
+     private VolumeInfo createTemporaryVolumeCopyOfSnapshotAdaptive(SnapshotInfo snapshotInfo) {
+         VolumeInfo tempVolumeInfo = null;
+         VolumeVO tempVolumeVO = null;
+         try {
+             tempVolumeVO = new VolumeVO(Volume.Type.DATADISK, snapshotInfo.getName() + "_" + System.currentTimeMillis() + ".TMP",
+                 snapshotInfo.getDataCenterId(), snapshotInfo.getDomainId(), snapshotInfo.getAccountId(), 0, ProvisioningType.THIN, snapshotInfo.getSize(), 0L, 0L, "");
+             tempVolumeVO.setPoolId(snapshotInfo.getDataStore().getId());
+             _volumeDao.persist(tempVolumeVO);
+             tempVolumeInfo = this._volFactory.getVolume(tempVolumeVO.getId());
+ 
+             if (snapshotInfo.getDataStore().getDriver().canCopy(snapshotInfo, tempVolumeInfo)) {
+                 snapshotInfo.getDataStore().getDriver().copyAsync(snapshotInfo, tempVolumeInfo, null, null);
+                 // refresh volume info as data could have changed
+                 tempVolumeInfo = this._volFactory.getVolume(tempVolumeVO.getId());
+             } else {
+                 throw new CloudRuntimeException("Storage driver indicated it could create a volume from the snapshot but rejected the subsequent request to do so");
+             }
+             return tempVolumeInfo;
+         } catch (Throwable e) {
+             try {
+                 if (tempVolumeInfo != null) {
+                     tempVolumeInfo.getDataStore().getDriver().deleteAsync(tempVolumeInfo.getDataStore(), tempVolumeInfo, null);
+                 }
+ 
+                 // cleanup temporary volume
+                 if (tempVolumeVO != null) {
+                     _volumeDao.remove(tempVolumeVO.getId());
+                 }
+             } catch (Throwable e2) {
 -                LOGGER.warn("Failed to delete temporary volume created for copy", e2);
++                logger.warn("Failed to delete temporary volume created for copy", e2);
+             }
+ 
+             throw e;
+         }
+     }
+ 
+     /**
+      * Simplier logic for copy from snapshot for adaptive driver only.
+      * @param snapshotInfo
+      * @param destData
+      * @param callback
+      */
+     private void handleCopyAsyncToSecondaryStorageAdaptive(SnapshotInfo snapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+         CopyCmdAnswer copyCmdAnswer = null;
+         DataObject srcFinal = null;
+         HostVO hostVO = null;
+         DataStore srcDataStore = null;
+         boolean tempRequired = false;
+ 
+         try {
+             snapshotInfo.processEvent(Event.CopyingRequested);
+             hostVO = getHost(snapshotInfo);
+             DataObject destOnStore = destData;
+             srcDataStore = snapshotInfo.getDataStore();
+             int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+             CopyCommand copyCommand = null;
+             if (!Boolean.parseBoolean(srcDataStore.getDriver().getCapabilities().get("CAN_DIRECT_ATTACH_SNAPSHOT"))) {
+                 srcFinal = createTemporaryVolumeCopyOfSnapshotAdaptive(snapshotInfo);
+                 tempRequired = true;
+             } else {
+                 srcFinal = snapshotInfo;
+             }
+ 
+             _volumeService.grantAccess(srcFinal, hostVO, srcDataStore);
+ 
+             DataTO srcTo = srcFinal.getTO();
+ 
+             // have to set PATH as extraOptions due to logic in KVM hypervisor processor
+             HashMap<String,String> extraDetails = new HashMap<>();
+             extraDetails.put(DiskTO.PATH, srcTo.getPath());
+ 
+             copyCommand = new CopyCommand(srcFinal.getTO(), destOnStore.getTO(), primaryStorageDownloadWait,
+                 VirtualMachineManager.ExecuteInSequence.value());
+             copyCommand.setOptions(extraDetails);
+             copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
+         } catch (Exception ex) {
+             String msg = "Failed to create template from snapshot (Snapshot ID = " + snapshotInfo.getId() + ") : ";
 -            LOGGER.warn(msg, ex);
++            logger.warn(msg, ex);
+             throw new CloudRuntimeException(msg + ex.getMessage(), ex);
+         }
+         finally {
+             // remove access tot he volume that was used
+             if (srcFinal != null && hostVO != null && srcDataStore != null) {
+                 _volumeService.revokeAccess(srcFinal, hostVO, srcDataStore);
+             }
+ 
+             // delete the temporary volume if it was needed
+             if (srcFinal != null && tempRequired) {
+                 try {
+                     srcFinal.getDataStore().getDriver().deleteAsync(srcFinal.getDataStore(), srcFinal, null);
+                 } catch (Throwable e) {
 -                    LOGGER.warn("Failed to delete temporary volume created for copy", e);
++                    logger.warn("Failed to delete temporary volume created for copy", e);
+                 }
+             }
+ 
+             // check we have a reasonable result
+             String errMsg = null;
+             if (copyCmdAnswer == null || (!copyCmdAnswer.getResult() && copyCmdAnswer.getDetails() == null)) {
+                 errMsg = "Unable to create template from snapshot";
+                 copyCmdAnswer = new CopyCmdAnswer(errMsg);
+             } else if (!copyCmdAnswer.getResult() && StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
+                 errMsg = "Unable to create template from snapshot";
+             } else if (!copyCmdAnswer.getResult()) {
+                 errMsg = copyCmdAnswer.getDetails();
+             }
+ 
+             //submit processEvent
+             if (StringUtils.isEmpty(errMsg)) {
+                 snapshotInfo.processEvent(Event.OperationSuccessed);
+             } else {
+                 snapshotInfo.processEvent(Event.OperationFailed);
+             }
+ 
+             CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+             result.setResult(copyCmdAnswer.getDetails());
+             callback.complete(result);
+         }
+     }
+ 
      /**
       * This function is responsible for copying a snapshot from managed storage to secondary storage. This is used in the following two cases:
       * 1) When creating a template from a snapshot
@@@ -1797,31 -1891,20 +1892,20 @@@
       * invocation of createVolumeFromSnapshot(SnapshotInfo).
       */
      private void deleteVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
-         VolumeVO volumeVO = null;
-         // cleanup any temporary volume previously created for copy from a snapshot
-         if ("true".equalsIgnoreCase(snapshotInfo.getDataStore().getDriver().getCapabilities().get("CAN_CREATE_TEMP_VOLUME_FROM_SNAPSHOT"))) {
-             SnapshotDetailsVO tempUuid = null;
-             tempUuid = _snapshotDetailsDao.findDetail(snapshotInfo.getId(), "TemporaryVolumeCopyUUID");
-             if (tempUuid == null || tempUuid.getValue() == null) {
-                 return;
-             }
+         try {
 -            LOGGER.debug("Cleaning up temporary volume created for copy from a snapshot");
++            logger.debug("Cleaning up temporary volume created for copy from a snapshot");
  
-             volumeVO = _volumeDao.findByUuid(tempUuid.getValue());
-             if (volumeVO != null) {
-                 _volumeDao.remove(volumeVO.getId());
-             }
-             _snapshotDetailsDao.remove(tempUuid.getId());
-             _snapshotDetailsDao.removeDetail(snapshotInfo.getId(), "TemporaryVolumeCopyUUID");
-             return;
-         }
+             SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "delete");
  
-         SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "delete");
+             try {
+                 snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null);
+             }
+             finally {
+                 _snapshotDetailsDao.remove(snapshotDetails.getId());
+             }
  
-         try {
-             snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null);
-         }
-         finally {
-             _snapshotDetailsDao.remove(snapshotDetails.getId());
+         } catch (Throwable e) {
 -            LOGGER.warn("Failed to clean up temporary volume created for copy from a snapshot, transction will not be failed but an adminstrator should clean this up: " + snapshotInfo.getUuid() + " - " + snapshotInfo.getPath(), e);
++            logger.warn("Failed to clean up temporary volume created for copy from a snapshot, transction will not be failed but an adminstrator should clean this up: " + snapshotInfo.getUuid() + " - " + snapshotInfo.getPath(), e);
          }
      }
  
@@@ -1933,11 -2016,14 +2017,14 @@@
                      continue;
                  }
  
-                 if (srcVolumeInfo.getTemplateId() != null) {
+                 VMTemplateVO vmTemplate = _vmTemplateDao.findById(vmInstance.getTemplateId());
+                 if (srcVolumeInfo.getTemplateId() != null &&
+                         Objects.nonNull(vmTemplate) &&
+                         !Arrays.asList(KVM_VM_IMPORT_DEFAULT_TEMPLATE_NAME, VM_IMPORT_DEFAULT_TEMPLATE_NAME).contains(vmTemplate.getName())) {
 -                    LOGGER.debug(String.format("Copying template [%s] of volume [%s] from source storage pool [%s] to target storage pool [%s].", srcVolumeInfo.getTemplateId(), srcVolumeInfo.getId(), sourceStoragePool.getId(), destStoragePool.getId()));
 +                    logger.debug(String.format("Copying template [%s] of volume [%s] from source storage pool [%s] to target storage pool [%s].", srcVolumeInfo.getTemplateId(), srcVolumeInfo.getId(), sourceStoragePool.getId(), destStoragePool.getId()));
                      copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost);
                  } else {
 -                    LOGGER.debug(String.format("Skipping copy template from source storage pool [%s] to target storage pool [%s] before migration due to volume [%s] does not have a template.", sourceStoragePool.getId(), destStoragePool.getId(), srcVolumeInfo.getId()));
 +                    logger.debug(String.format("Skipping copy template from source storage pool [%s] to target storage pool [%s] before migration due to volume [%s] does not have a template.", sourceStoragePool.getId(), destStoragePool.getId(), srcVolumeInfo.getId()));
                  }
  
                  VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool);
diff --cc engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
index cea9de3f1b4,e619b40fae0..45357fa64b2
--- a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
+++ b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
@@@ -47,8 -46,7 +46,7 @@@ import org.mockito.InjectMocks
  import org.mockito.Mock;
  import org.mockito.Mockito;
  import org.mockito.Spy;
 -import org.mockito.runners.MockitoJUnitRunner;
 +import org.mockito.junit.MockitoJUnitRunner;
- import org.mockito.verification.VerificationMode;
  
  import com.cloud.agent.api.MigrateCommand;
  import com.cloud.host.HostVO;
diff --cc engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
index 11a13e7ccb4,27fb77660ac..d2f08260aa3
--- a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
+++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
@@@ -201,8 -200,8 +201,8 @@@ public class ImageStoreProviderManagerI
          }
  
          // No store with space found
 -        s_logger.error(String.format("Can't find an image storage in zone with less than %d usage",
 +        logger.error(String.format("Can't find an image storage in zone with less than %d usage",
-                 Math.round(_statsCollector.getImageStoreCapacityThreshold()*100)));
+                 Math.round(_statsCollector.getImageStoreCapacityThreshold() * 100)));
          return null;
      }
  
diff --cc framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
index de8838b0999,b9199468bd1..84750c2068c
--- a/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
@@@ -229,24 -229,14 +229,32 @@@ public interface GenericDao<T, ID exten
       */
      int expunge(final SearchCriteria<T> sc);
  
 +    /**
 +     * remove the entity bean specified by the search criteria and filter
 +     * @param sc
 +     * @param filter
 +     * @return number of rows deleted
 +     */
 +    int expunge(final SearchCriteria<T> sc, final Filter filter);
 +
 +    /**
 +     * remove the entity bean specified by the search criteria and batchSize
 +     * @param sc
 +     * @param batchSize
 +     * @return number of rows deleted
 +     */
 +    int batchExpunge(final SearchCriteria<T> sc, final Long batchSize);
 +
 +    int expungeList(List<ID> ids);
 +
+     /**
+      * Delete the entity beans specified by the search criteria with a given limit
+      * @param sc Search criteria
+      * @param limit Maximum number of rows that will be affected
+      * @return Number of rows deleted
+      */
+     int expunge(SearchCriteria<T> sc, long limit);
+ 
      /**
       * expunge the removed rows.
       */
diff --cc framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
index 4202f6996c1,3b950e1983d..b7e4f44cf8c
--- a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
@@@ -1235,9 -1226,14 +1235,15 @@@ public abstract class GenericDaoBase<T
          }
      }
  
 +    // FIXME: Does not work for joins.
+     @Override
 -    public int expunge(final SearchCriteria<T> sc) {
 -        return expunge(sc, -1);
++    public int expunge(final SearchCriteria<T> sc, long limit) {
++        Filter filter = new Filter(limit);
++        return expunge(sc, filter);
+     }
+ 
 -    // FIXME: Does not work for joins.
      @Override
 -    public int expunge(final SearchCriteria<T> sc, long limit) {
 +    public int expunge(final SearchCriteria<T> sc, final Filter filter) {
          if (sc == null) {
              throw new CloudRuntimeException("Call to throw new expunge with null search Criteria");
          }
diff --cc framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java
index d61e26fc3a8,cda07c9dee6..2a6d0b63e5c
--- a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java
+++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java
@@@ -99,20 -98,22 +99,22 @@@ public class DefaultModuleDefinitionSe
              public void with(ModuleDefinition def, Stack<ModuleDefinition> parents) {
                  try {
                      String moduleDefinitionName = def.getName();
 -                    log.debug(String.format("Trying to obtain module [%s] context.", moduleDefinitionName));
 +                    logger.debug(String.format("Trying to obtain module [%s] context.", moduleDefinitionName));
                      ApplicationContext context = getApplicationContext(moduleDefinitionName);
                      try {
-                         if (context.containsBean("moduleStartup")) {
+                         if (context == null) {
 -                            log.warn(String.format("Application context not found for module definition [%s]", moduleDefinitionName));
++                            logger.warn(String.format("Application context not found for module definition [%s]", moduleDefinitionName));
+                         } else if (context.containsBean("moduleStartup")) {
                              Runnable runnable = context.getBean("moduleStartup", Runnable.class);
 -                            log.info(String.format("Starting module [%s].", moduleDefinitionName));
 +                            logger.info(String.format("Starting module [%s].", moduleDefinitionName));
                              runnable.run();
                          } else {
 -                            log.debug(String.format("Could not get module [%s] context bean.", moduleDefinitionName));
 +                            logger.debug(String.format("Could not get module [%s] context bean.", moduleDefinitionName));
                          }
                      } catch (BeansException e) {
 -                        log.warn(String.format("Failed to start module [%s] due to: [%s].", moduleDefinitionName, e.getMessage()));
 -                        if (log.isDebugEnabled()) {
 -                            log.debug(String.format("module start failure of module [%s] was due to: ", moduleDefinitionName), e);
 +                        logger.warn(String.format("Failed to start module [%s] due to: [%s].", moduleDefinitionName, e.getMessage()));
 +                        if (logger.isDebugEnabled()) {
 +                            logger.debug(String.format("module start failure of module [%s] was due to: ", moduleDefinitionName), e);
                          }
                      }
                  } catch (EmptyStackException e) {
diff --cc plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
index 94b763d013f,1dfe20a10be..db40b6e68dd
--- a/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
+++ b/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
@@@ -120,7 -122,9 +120,9 @@@ public class DynamicRoleBasedAPIAccessC
          }
  
          if (accountRole.getRoleType() == RoleType.Admin && accountRole.getId() == RoleType.Admin.getId()) {
-             logger.info(String.format("Account [%s] is Root Admin or Domain Admin, all APIs are allowed.", account));
 -            if (LOGGER.isTraceEnabled()) {
 -                LOGGER.trace(String.format("Account [%s] is Root Admin or Domain Admin, all APIs are allowed.", account));
++            if (logger.isTraceEnabled()) {
++                logger.trace(String.format("Account [%s] is Root Admin or Domain Admin, all APIs are allowed.", account));
+             }
              return true;
          }
  
diff --cc plugins/acl/project-role-based/src/main/java/org/apache/cloudstack/acl/ProjectRoleBasedApiAccessChecker.java
index 1e766468ba8,cffda4681c6..2e7ae23d6f1
--- a/plugins/acl/project-role-based/src/main/java/org/apache/cloudstack/acl/ProjectRoleBasedApiAccessChecker.java
+++ b/plugins/acl/project-role-based/src/main/java/org/apache/cloudstack/acl/ProjectRoleBasedApiAccessChecker.java
@@@ -72,7 -76,9 +72,9 @@@ public class ProjectRoleBasedApiAccessC
  
          Project project = CallContext.current().getProject();
          if (project == null) {
-             logger.warn(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning APIs [%s] for user [%s] as allowed.", apiNames, user));
 -            if (LOGGER.isTraceEnabled()) {
 -                LOGGER.trace(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning APIs [%s] for user [%s] as allowed.", apiNames, user));
++            if (logger.isTraceEnabled()) {
++                logger.trace(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning APIs [%s] for user [%s] as allowed.", apiNames, user));
+             }
              return apiNames;
          }
  
@@@ -110,8 -116,10 +112,10 @@@
  
          Project project = CallContext.current().getProject();
          if (project == null) {
-             logger.warn(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning API [%s] for user [%s] as allowed.", apiCommandName,
 -            if (LOGGER.isTraceEnabled()) {
 -                LOGGER.trace(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning API [%s] for user [%s] as allowed.", apiCommandName,
++            if (logger.isTraceEnabled()) {
++                logger.trace(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning API [%s] for user [%s] as allowed.", apiCommandName,
                  user));
+             }
              return true;
          }
  
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index b5ec716e805,86ece3c8c66..5cffa77c297
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@@ -3801,27 -3775,27 +3801,27 @@@ public class LibvirtComputingResource e
          try {
              final String names[] = conn.listDefinedDomains();
              for (int i = 0; i < names.length; i++) {
-                 la.add(names[i]);
+                 domainNames.add(names[i]);
              }
          } catch (final LibvirtException e) {
-             LOGGER.warn("Failed to list Defined domains", e);
 -            s_logger.warn("Failed to list defined domains", e);
++            logger.warn("Failed to list defined domains", e);
          }
  
          int[] ids = null;
          try {
              ids = conn.listDomains();
          } catch (final LibvirtException e) {
-             LOGGER.warn("Failed to list domains", e);
-             return la;
 -            s_logger.warn("Failed to list domains", e);
++            logger.warn("Failed to list domains", e);
+             return domainNames;
          }
  
          Domain dm = null;
          for (int i = 0; i < ids.length; i++) {
              try {
                  dm = conn.domainLookupByID(ids[i]);
-                 la.add(dm.getName());
+                 domainNames.add(dm.getName());
              } catch (final LibvirtException e) {
 -                s_logger.warn("Unable to get vms", e);
 +                LOGGER.warn("Unable to get vms", e);
              } finally {
                  try {
                      if (dm != null) {
@@@ -5379,20 -5336,31 +5379,31 @@@
      /*
      Scp volume from remote host to local directory
       */
-     public String copyVolume(String srcIp, String username, String password, String localDir, String remoteFile, String tmpPath) {
+     public String copyVolume(String srcIp, String username, String password, String localDir, String remoteFile, String tmpPath, int timeoutInSecs) {
+         String outputFile = UUID.randomUUID().toString();
          try {
-             String outputFile = UUID.randomUUID().toString();
              StringBuilder command = new StringBuilder("qemu-img convert -O qcow2 ");
              command.append(remoteFile);
-             command.append(" "+tmpPath);
+             command.append(" " + tmpPath);
              command.append(outputFile);
-             logger.debug("Converting remoteFile: "+remoteFile);
-             SshHelper.sshExecute(srcIp, 22, username, null, password, command.toString());
-             logger.debug("Copying remoteFile to: "+localDir);
-             SshHelper.scpFrom(srcIp, 22, username, null, password, localDir, tmpPath+outputFile);
-             logger.debug("Successfully copyied remoteFile to: "+localDir+"/"+outputFile);
 -            s_logger.debug(String.format("Converting remote disk file: %s, output file: %s%s (timeout: %d secs)", remoteFile, tmpPath, outputFile, timeoutInSecs));
++            logger.debug(String.format("Converting remote disk file: %s, output file: %s%s (timeout: %d secs)", remoteFile, tmpPath, outputFile, timeoutInSecs));
+             SshHelper.sshExecute(srcIp, 22, username, null, password, command.toString(), timeoutInSecs * 1000);
 -            s_logger.debug("Copying converted remote disk file " + outputFile + " to: " + localDir);
++            logger.debug("Copying converted remote disk file " + outputFile + " to: " + localDir);
+             SshHelper.scpFrom(srcIp, 22, username, null, password, localDir, tmpPath + outputFile);
 -            s_logger.debug("Successfully copied converted remote disk file to: " + localDir + "/" + outputFile);
++            logger.debug("Successfully copied converted remote disk file to: " + localDir + "/" + outputFile);
              return outputFile;
          } catch (Exception e) {
+             try {
+                 String deleteRemoteConvertedFileCmd = String.format("rm -f %s%s", tmpPath, outputFile);
+                 SshHelper.sshExecute(srcIp, 22, username, null, password, deleteRemoteConvertedFileCmd);
+             } catch (Exception ignored) {
+             }
+ 
+             try {
+                 FileUtils.deleteQuietly(new File(localDir + "/" + outputFile));
+             } catch (Exception ignored) {
+             }
+ 
              throw new RuntimeException(e);
          }
      }
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyRemoteVolumeCommandWrapper.java
index 025a5ed192c,a5e1716da2e..e6ec05fec23
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyRemoteVolumeCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyRemoteVolumeCommandWrapper.java
@@@ -41,9 -42,10 +41,8 @@@ import java.util.Map
  @ResourceWrapper(handles = CopyRemoteVolumeCommand.class)
  public final class LibvirtCopyRemoteVolumeCommandWrapper extends CommandWrapper<CopyRemoteVolumeCommand, Answer, LibvirtComputingResource> {
  
 -    private static final Logger s_logger = Logger.getLogger(LibvirtCopyRemoteVolumeCommandWrapper.class);
 -
      @Override
      public Answer execute(final CopyRemoteVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
-         String result = null;
          String srcIp = command.getRemoteIp();
          String username = command.getUsername();
          String password = command.getPassword();
@@@ -57,19 -60,20 +57,20 @@@
          try {
              if (storageFilerTO.getType() == Storage.StoragePoolType.Filesystem ||
                      storageFilerTO.getType() == Storage.StoragePoolType.NetworkFilesystem) {
-                 String filename = libvirtComputingResource.copyVolume(srcIp, username, password, dstPath, srcFile, tmpPath);
-                 logger.debug("Volume Copy Successful");
+                 String filename = libvirtComputingResource.copyVolume(srcIp, username, password, dstPath, srcFile, tmpPath, timeoutInSecs);
 -                s_logger.debug("Volume " + srcFile + " copy successful, copied to file: " + filename);
++                logger.debug("Volume " + srcFile + " copy successful, copied to file: " + filename);
                  final KVMPhysicalDisk vol = pool.getPhysicalDisk(filename);
                  final String path = vol.getPath();
                  long size = getVirtualSizeFromFile(path);
-                 return  new CopyRemoteVolumeAnswer(command, "", filename, size);
+                 return new CopyRemoteVolumeAnswer(command, "", filename, size);
              } else {
-                 return new Answer(command, false, "Unsupported Storage Pool");
+                 String msg = "Unsupported storage pool type: " + storageFilerTO.getType().toString() + ", only local and NFS pools are supported";
+                 return new Answer(command, false, msg);
              }
- 
          } catch (final Exception e) {
-             logger.error("Error while copying file from remote host: "+ e.getMessage());
-             return new Answer(command, false, result);
 -            s_logger.error("Error while copying volume file from remote host: " + e.getMessage(), e);
++            logger.error("Error while copying volume file from remote host: " + e.getMessage(), e);
+             String msg = "Failed to copy volume due to: " + e.getMessage();
+             return new Answer(command, false, msg);
          }
      }
  
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
index a9da4a50452,942a68b8074..114b27d3a5b
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetRemoteVmsCommandWrapper.java
@@@ -45,39 -46,41 +45,40 @@@ import java.util.List
  @ResourceWrapper(handles = GetRemoteVmsCommand.class)
  public final class LibvirtGetRemoteVmsCommandWrapper extends CommandWrapper<GetRemoteVmsCommand, Answer, LibvirtComputingResource> {
  
 -    private static final Logger s_logger = Logger.getLogger(LibvirtGetRemoteVmsCommandWrapper.class);
 -
      @Override
      public Answer execute(final GetRemoteVmsCommand command, final LibvirtComputingResource libvirtComputingResource) {
-         String hypervisorURI = "qemu+tcp://" + command.getRemoteIp() + "/system";
+         String remoteIp = command.getRemoteIp();
+         String hypervisorURI = "qemu+tcp://" + remoteIp + "/system";
          HashMap<String, UnmanagedInstanceTO> unmanagedInstances = new HashMap<>();
          try {
              Connect conn = LibvirtConnection.getConnection(hypervisorURI);
              final List<String> allVmNames = libvirtComputingResource.getAllVmNames(conn);
 -            s_logger.info(String.format("Found %d VMs on the remote host %s", allVmNames.size(), remoteIp));
++            logger.info(String.format("Found %d VMs on the remote host %s", allVmNames.size(), remoteIp));
              for (String name : allVmNames) {
                  final Domain domain = libvirtComputingResource.getDomain(conn, name);
- 
                  final DomainInfo.DomainState ps = domain.getInfo().state;
                  final VirtualMachine.PowerState state = libvirtComputingResource.convertToPowerState(ps);
 -                s_logger.debug(String.format("Remote VM %s - powerstate: %s, state: %s", domain.getName(), ps.toString(), state.toString()));
 +
-                 logger.debug("VM " + domain.getName() + " - powerstate: " + ps + ", state: " + state.toString());
++                logger.debug(String.format("Remote VM %s - powerstate: %s, state: %s", domain.getName(), ps.toString(), state.toString()));
  
                  if (state == VirtualMachine.PowerState.PowerOff) {
                      try {
                          UnmanagedInstanceTO instance = getUnmanagedInstance(libvirtComputingResource, domain, conn);
                          unmanagedInstances.put(instance.getName(), instance);
                      } catch (Exception e) {
-                         logger.error("Couldn't fetch VM " + domain.getName() + " details, due to: " + e.getMessage(), e);
 -                        s_logger.error("Couldn't fetch remote VM " + domain.getName() + " details, due to: " + e.getMessage(), e);
++                        logger.error("Couldn't fetch remote VM " + domain.getName() + " details, due to: " + e.getMessage(), e);
                      }
                  }
                  domain.free();
              }
-             logger.debug("Found " + unmanagedInstances.size() + " stopped VMs on host " + command.getRemoteIp());
 -            s_logger.debug("Found " + unmanagedInstances.size() + " stopped VMs on remote host " + remoteIp);
++            logger.debug("Found " + unmanagedInstances.size() + " stopped VMs on remote host " + remoteIp);
              return new GetRemoteVmsAnswer(command, "", unmanagedInstances);
          } catch (final LibvirtException e) {
-             logger.error("Failed to list stopped VMs on remote host " + command.getRemoteIp() + ", due to: " + e.getMessage(), e);
 -            s_logger.error("Failed to list stopped VMs on remote host " + remoteIp + ", due to: " + e.getMessage(), e);
++            logger.error("Failed to list stopped VMs on remote host " + remoteIp + ", due to: " + e.getMessage(), e);
              if (e.getMessage().toLowerCase().contains("connection refused")) {
-                 return new Answer(command, false, "Unable to connect to remote host " + command.getRemoteIp() + ", please check the libvirtd tcp connectivity and retry");
+                 return new Answer(command, false, "Unable to connect to remote host " + remoteIp + ", please check the libvirtd tcp connectivity and retry");
              }
-             return new Answer(command, false, "Unable to list stopped VMs on remote host " + command.getRemoteIp() + ", due to: " + e.getMessage());
+             return new Answer(command, false, "Unable to list stopped VMs on remote host " + remoteIp + ", due to: " + e.getMessage());
          }
      }
  
@@@ -103,8 -106,8 +104,8 @@@
  
              return instance;
          } catch (Exception e) {
-             logger.debug("Unable to retrieve unmanaged instance info,  due to: " + e.getMessage(), e);
-             throw new CloudRuntimeException("Unable to retrieve unmanaged instance info, due to: " + e.getMessage());
 -            s_logger.debug("Unable to retrieve remote unmanaged instance info,  due to: " + e.getMessage(), e);
++            logger.debug("Unable to retrieve remote unmanaged instance info,  due to: " + e.getMessage(), e);
+             throw new CloudRuntimeException("Unable to retrieve remote unmanaged instance info, due to: " + e.getMessage());
          }
      }
  
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/FiberChannelAdapter.java
index 83636b9a9c3,d5192bfdb71..917435479f2
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/FiberChannelAdapter.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/FiberChannelAdapter.java
@@@ -19,16 -24,30 +24,34 @@@ import org.apache.log4j.Logger
  import com.cloud.storage.Storage;
  import com.cloud.utils.exception.CloudRuntimeException;
  
 -@StorageAdaptorInfo(storagePoolType=Storage.StoragePoolType.FiberChannel)
  public class FiberChannelAdapter extends MultipathSCSIAdapterBase {
+ 
+     private Logger LOGGER = Logger.getLogger(getClass());
+ 
+     private String hostname = null;
+     private String hostnameFq = null;
+ 
      public FiberChannelAdapter() {
          LOGGER.info("Loaded FiberChannelAdapter for StorageLayer");
+         // get the hostname - we need this to compare to connid values
+         try {
+             InetAddress inetAddress = InetAddress.getLocalHost();
+             hostname = inetAddress.getHostName(); // basic hostname
+             if (hostname.indexOf(".") > 0) {
+                 hostname = hostname.substring(0, hostname.indexOf(".")); // strip off domain
+             }
+             hostnameFq = inetAddress.getCanonicalHostName(); // fully qualified hostname
+             LOGGER.info("Loaded FiberChannelAdapter for StorageLayer on host [" + hostname + "]");
+         } catch (UnknownHostException e) {
+             LOGGER.error("Error getting hostname", e);
+         }
      }
  
 +    @Override
 +    public Storage.StoragePoolType getStoragePoolType() {
 +        return Storage.StoragePoolType.FiberChannel;
 +    }
 +
      @Override
      public KVMStoragePool getStoragePool(String uuid) {
          KVMStoragePool pool = MapStorageUuidToStoragePool.get(uuid);
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index b9671c872d1,a3a79de6bf5..f6242444d91
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@@ -134,9 -66,78 +134,13 @@@ import com.cloud.utils.exception.CloudR
  import com.cloud.utils.script.Script;
  import com.cloud.utils.storage.S3.S3Utils;
  import com.cloud.vm.VmDetailConstants;
 -import org.apache.cloudstack.agent.directdownload.DirectDownloadAnswer;
 -import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
 -import org.apache.cloudstack.direct.download.DirectDownloadHelper;
 -import org.apache.cloudstack.direct.download.DirectTemplateDownloader;
 -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 -import org.apache.cloudstack.storage.command.AttachAnswer;
 -import org.apache.cloudstack.storage.command.AttachCommand;
 -import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 -import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 -import org.apache.cloudstack.storage.command.CopyCommand;
 -import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 -import org.apache.cloudstack.storage.command.CreateObjectCommand;
 -import org.apache.cloudstack.storage.command.DeleteCommand;
 -import org.apache.cloudstack.storage.command.DettachAnswer;
 -import org.apache.cloudstack.storage.command.DettachCommand;
 -import org.apache.cloudstack.storage.command.ForgetObjectCmd;
 -import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
 -import org.apache.cloudstack.storage.command.ResignatureAnswer;
 -import org.apache.cloudstack.storage.command.ResignatureCommand;
 -import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
 -import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
 -import org.apache.cloudstack.storage.command.SyncVolumePathCommand;
 -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 -import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 -import org.apache.cloudstack.storage.to.TemplateObjectTO;
 -import org.apache.cloudstack.storage.to.VolumeObjectTO;
+ import org.apache.cloudstack.utils.cryptsetup.KeyFile;
+ import org.apache.cloudstack.utils.qemu.QemuImageOptions;
 -import org.apache.cloudstack.utils.qemu.QemuImg;
 -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
 -import org.apache.cloudstack.utils.qemu.QemuImgException;
 -import org.apache.cloudstack.utils.qemu.QemuImgFile;
 -import org.apache.cloudstack.utils.qemu.QemuObject;
+ import org.apache.cloudstack.utils.qemu.QemuObject.EncryptFormat;
 -import org.apache.commons.collections.MapUtils;
 -import org.apache.commons.io.FileUtils;
 -import org.apache.commons.lang3.BooleanUtils;
 -import org.apache.commons.lang3.StringUtils;
 -import org.apache.commons.lang3.builder.ToStringBuilder;
 -import org.apache.commons.lang3.builder.ToStringStyle;
 -import org.apache.log4j.Logger;
 -import org.libvirt.Connect;
 -import org.libvirt.Domain;
 -import org.libvirt.DomainInfo;
 -import org.libvirt.DomainSnapshot;
 -import org.libvirt.LibvirtException;
 -
 -import javax.naming.ConfigurationException;
 -import java.io.File;
 -import java.io.FileNotFoundException;
 -import java.io.FileOutputStream;
 -import java.io.IOException;
 -import java.nio.file.Files;
 -import java.nio.file.Paths;
 -import java.text.DateFormat;
 -import java.text.SimpleDateFormat;
+ import java.util.ArrayList;
 -import java.util.Arrays;
 -import java.util.Date;
 -import java.util.HashMap;
 -import java.util.HashSet;
 -import java.util.List;
 -import java.util.Map;
 -import java.util.Set;
 -import java.util.UUID;
 -import java.util.stream.Collectors;
 -
 -import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
 -import static com.cloud.utils.storage.S3.S3Utils.putFile;
  
  public class KVMStorageProcessor implements StorageProcessor {
 -    private static final Logger s_logger = Logger.getLogger(KVMStorageProcessor.class);
 +    protected Logger logger = LogManager.getLogger(getClass());
      private final KVMStoragePoolManager storagePoolMgr;
      private final LibvirtComputingResource resource;
      private StorageLayer storageLayer;
@@@ -267,10 -268,10 +271,10 @@@
  
                  Map<String, String> details = primaryStore.getDetails();
  
-                 String path = details != null ? details.get("managedStoreTarget") : null;
+                 String path = derivePath(primaryStore, destData, details);
  
                  if (!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details)) {
 -                    s_logger.warn("Failed to connect physical disk at path: " + path + ", in storage pool id: " + primaryStore.getUuid());
 +                    logger.warn("Failed to connect physical disk at path: " + path + ", in storage pool id: " + primaryStore.getUuid());
                  }
  
                  primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, path != null ? path : destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
@@@ -404,12 -415,12 +418,12 @@@
              if (primaryPool.getType() == StoragePoolType.CLVM) {
                  templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
                  vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
 -            } if (primaryPool.getType() == StoragePoolType.PowerFlex) {
 +            } if (storagePoolMgr.supportsPhysicalDiskCopy(primaryPool.getType())) {
                  Map<String, String> details = primaryStore.getDetails();
-                 String path = details != null ? details.get("managedStoreTarget") : null;
+                 String path = derivePath(primaryStore, destData, details);
  
                  if (!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath, details)) {
 -                    s_logger.warn("Failed to connect base template volume at path: " + templatePath + ", in storage pool id: " + primaryStore.getUuid());
 +                    logger.warn("Failed to connect base template volume at path: " + templatePath + ", in storage pool id: " + primaryStore.getUuid());
                  }
  
                  BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
@@@ -1046,8 -1057,8 +1060,8 @@@
          } finally {
              srcVolume.clearPassphrase();
              if (isCreatedFromVmSnapshot) {
 -                s_logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
 +                logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
-             } else if (primaryPool.getType() != StoragePoolType.RBD) {
+             } else if (primaryPool != null && primaryPool.getType() != StoragePoolType.RBD) {
                  deleteSnapshotOnPrimary(cmd, snapshot, primaryPool);
              }
  
@@@ -1940,26 -1948,43 +1954,43 @@@
       * @param snapshotPath Path to convert the base file;
       * @return null if the conversion occurs successfully or an error message that must be handled.
       */
-     protected String convertBaseFileToSnapshotFileInPrimaryStorageDir(KVMStoragePool primaryPool, String baseFile, String snapshotPath, VolumeObjectTO volume, int wait) {
-         try {
-             logger.debug(String.format("Trying to convert volume [%s] (%s) to snapshot [%s].", volume, baseFile, snapshotPath));
+     protected String convertBaseFileToSnapshotFileInPrimaryStorageDir(KVMStoragePool primaryPool,
+             KVMPhysicalDisk baseFile, String snapshotPath, VolumeObjectTO volume, int wait) {
+         try (KeyFile srcKey = new KeyFile(volume.getPassphrase())) {
 -            s_logger.debug(
++            logger.debug(
+                     String.format("Trying to convert volume [%s] (%s) to snapshot [%s].", volume, baseFile, snapshotPath));
  
              primaryPool.createFolder(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR);
+             convertTheBaseFileToSnapshot(baseFile, snapshotPath, wait, srcKey);
+         } catch (QemuImgException | LibvirtException | IOException ex) {
+             return String.format("Failed to convert %s snapshot of volume [%s] to [%s] due to [%s].", volume, baseFile,
+                     snapshotPath, ex.getMessage());
+         }
  
-             QemuImgFile srcFile = new QemuImgFile(baseFile);
-             srcFile.setFormat(PhysicalDiskFormat.QCOW2);
 -        s_logger.debug(String.format("Converted volume [%s] (from path \"%s\") to snapshot [%s].", volume, baseFile,
++        logger.debug(String.format("Converted volume [%s] (from path \"%s\") to snapshot [%s].", volume, baseFile,
+                 snapshotPath));
+         return null;
+     }
  
-             QemuImgFile destFile = new QemuImgFile(snapshotPath);
-             destFile.setFormat(PhysicalDiskFormat.QCOW2);
+     private void convertTheBaseFileToSnapshot(KVMPhysicalDisk baseFile, String snapshotPath, int wait, KeyFile srcKey)
+             throws LibvirtException, QemuImgException {
+         List<QemuObject> qemuObjects = new ArrayList<>();
+         Map<String, String> options = new HashMap<>();
+         QemuImageOptions qemuImageOpts = new QemuImageOptions(baseFile.getPath());
+         if (srcKey.isSet()) {
+             String srcKeyName = "sec0";
+             qemuObjects.add(QemuObject.prepareSecretForQemuImg(baseFile.getFormat(), EncryptFormat.LUKS,
+                     srcKey.toString(), srcKeyName, options));
+             qemuImageOpts = new QemuImageOptions(baseFile.getFormat(), baseFile.getPath(), srcKeyName);
+         }
+         QemuImgFile srcFile = new QemuImgFile(baseFile.getPath());
+         srcFile.setFormat(PhysicalDiskFormat.QCOW2);
  
-             QemuImg q = new QemuImg(wait);
-             q.convert(srcFile, destFile);
+         QemuImgFile destFile = new QemuImgFile(snapshotPath);
+         destFile.setFormat(PhysicalDiskFormat.QCOW2);
  
-             logger.debug(String.format("Converted volume [%s] (from path \"%s\") to snapshot [%s].", volume, baseFile, snapshotPath));
-             return null;
-         } catch (QemuImgException | LibvirtException ex) {
-             return String.format("Failed to convert %s snapshot of volume [%s] to [%s] due to [%s].", volume, baseFile, snapshotPath, ex.getMessage());
-         }
+         QemuImg q = new QemuImg(wait);
+         q.convert(srcFile, destFile, options, qemuObjects, qemuImageOpts, null, true);
      }
  
      /**
@@@ -2465,10 -2490,9 +2496,9 @@@
              String destVolumeName = null;
              if (destPrimaryStore.isManaged()) {
                  if (!storagePoolMgr.connectPhysicalDisk(destPrimaryStore.getPoolType(), destPrimaryStore.getUuid(), destVolumePath, destPrimaryStore.getDetails())) {
 -                    s_logger.warn("Failed to connect dest volume at path: " + destVolumePath + ", in storage pool id: " + destPrimaryStore.getUuid());
 +                    logger.warn("Failed to connect dest volume at path: " + destVolumePath + ", in storage pool id: " + destPrimaryStore.getUuid());
                  }
-                 String managedStoreTarget = destPrimaryStore.getDetails() != null ? destPrimaryStore.getDetails().get("managedStoreTarget") : null;
-                 destVolumeName = managedStoreTarget != null ? managedStoreTarget : destVolumePath;
+                 destVolumeName = derivePath(destPrimaryStore, destData, destPrimaryStore.getDetails());
              } else {
                  final String volumeName = UUID.randomUUID().toString();
                  destVolumeName = volumeName + "." + destFormat.getFileExtension();
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index b80accd6018,31281615bce..97a4c4dc044
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@@ -273,6 -272,16 +273,16 @@@ public class LibvirtStorageAdaptor impl
          }
      }
  
+     private void checkNetfsStoragePoolMounted(String uuid) {
+         String targetPath = _mountPoint + File.separator + uuid;
+         int mountpointResult = Script.runSimpleBashScriptForExitValue("mountpoint -q " + targetPath);
+         if (mountpointResult != 0) {
+             String errMsg = String.format("libvirt failed to mount storage pool %s at %s", uuid, targetPath);
 -            s_logger.error(errMsg);
++            logger.error(errMsg);
+             throw new CloudRuntimeException(errMsg);
+         }
+     }
+ 
      private StoragePool createNetfsStoragePool(PoolType fsType, Connect conn, String uuid, String host, String path) throws LibvirtException {
          String targetPath = _mountPoint + File.separator + uuid;
          LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(fsType, uuid, uuid, host, path, targetPath);
@@@ -762,14 -769,14 +776,14 @@@
              // handle ebusy error when pool is quickly destroyed
              if (e.toString().contains("exit status 16")) {
                  String targetPath = _mountPoint + File.separator + uuid;
-                 logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble unmounting the pool. Trying umount location " + targetPath +
-                         "again in a few seconds");
 -                s_logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble unmounting the pool. Trying umount location " + targetPath +
++                    logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble unmounting the pool. Trying umount location " + targetPath +
+                         " again in a few seconds");
                  String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath);
                  if (result == null) {
-                     logger.error("Succeeded in unmounting " + targetPath);
 -                    s_logger.info("Succeeded in unmounting " + targetPath);
++                    logger.info("Succeeded in unmounting " + targetPath);
                      return true;
                  }
 -                s_logger.error("Failed to unmount " + targetPath);
 +                logger.error("Failed to unmount " + targetPath);
              }
              throw new CloudRuntimeException(e.toString(), e);
          }
diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/MultipathSCSIAdapterBase.java
index 1625ecc171a,5bcb6e48d97..03acfcc89ad
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/MultipathSCSIAdapterBase.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/MultipathSCSIAdapterBase.java
@@@ -32,8 -30,8 +30,7 @@@ import java.util.concurrent.TimeUnit
  
  import org.apache.cloudstack.utils.qemu.QemuImg;
  import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
- import org.apache.cloudstack.utils.qemu.QemuImgException;
  import org.apache.cloudstack.utils.qemu.QemuImgFile;
 -import org.joda.time.Duration;
  
  import com.cloud.storage.Storage;
  import com.cloud.storage.StorageManager;
@@@ -42,13 -40,10 +39,12 @@@ import com.cloud.utils.exception.CloudR
  import com.cloud.utils.script.OutputInterpreter;
  import com.cloud.utils.script.Script;
  import org.apache.commons.lang3.StringUtils;
 -import org.apache.log4j.Logger;
 +import org.apache.logging.log4j.LogManager;
 +import org.apache.logging.log4j.Logger;
- import org.libvirt.LibvirtException;
 +import org.joda.time.Duration;
  
  public abstract class MultipathSCSIAdapterBase implements StorageAdaptor {
 -    static final Logger LOGGER = Logger.getLogger(MultipathSCSIAdapterBase.class);
 +    protected static Logger LOGGER = LogManager.getLogger(MultipathSCSIAdapterBase.class);
      static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool = new HashMap<>();
  
      /**
diff --cc plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 826c613798a,61a949f42d3..561034155c2
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@@ -570,14 -571,13 +569,13 @@@ public class VmwareManagerImpl extends 
          }
  
          if (secUrl == null) {
-             // we are using non-NFS image store, then use cache storage instead
-             logger.info("Secondary storage is not NFS, we need to use staging storage");
 -            s_logger.info("Secondary storage is either not having free capacity or not NFS, then use cache/staging storage instead");
++            logger.info("Secondary storage is either not having free capacity or not NFS, then use cache/staging storage instead");
              DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId);
              if (cacheStore != null) {
                  secUrl = cacheStore.getUri();
                  secId = cacheStore.getId();
              } else {
-                 logger.warn("No staging storage is found when non-NFS secondary storage is used");
 -                s_logger.warn("No cache/staging storage found when NFS secondary storage with free capacity not available or non-NFS secondary storage is used");
++                logger.warn("No cache/staging storage found when NFS secondary storage with free capacity not available or non-NFS secondary storage is used");
              }
          }
  
@@@ -597,13 -597,12 +595,12 @@@
          }
  
          if (urlIdList.isEmpty()) {
-             // we are using non-NFS image store, then use cache storage instead
-             logger.info("Secondary storage is not NFS, we need to use staging storage");
 -            s_logger.info("Secondary storage is either not having free capacity or not NFS, then use cache/staging storage instead");
++            logger.info("Secondary storage is either not having free capacity or not NFS, then use cache/staging storage instead");
              DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId);
              if (cacheStore != null) {
                  urlIdList.add(new Pair<>(cacheStore.getUri(), cacheStore.getId()));
              } else {
-                 logger.warn("No staging storage is found when non-NFS secondary storage is used");
 -                s_logger.warn("No cache/staging storage found when NFS secondary storage with free capacity not available or non-NFS secondary storage is used");
++                logger.warn("No cache/staging storage found when NFS secondary storage with free capacity not available or non-NFS secondary storage is used");
              }
          }
  
diff --cc plugins/storage/volume/adaptive/src/main/java/org/apache/cloudstack/storage/datastore/driver/AdaptiveDataStoreDriverImpl.java
index 87dd67f72af,549604b3577..329de5a398a
--- a/plugins/storage/volume/adaptive/src/main/java/org/apache/cloudstack/storage/datastore/driver/AdaptiveDataStoreDriverImpl.java
+++ b/plugins/storage/volume/adaptive/src/main/java/org/apache/cloudstack/storage/datastore/driver/AdaptiveDataStoreDriverImpl.java
@@@ -303,18 -350,10 +351,10 @@@ public class AdaptiveDataStoreDriverImp
                      api.resize(context, destIn, destdata.getSize());
                  }
  
-                 String connectionId = api.attach(context, destIn);
- 
-                 String finalPath;
-                 // format: type=fiberwwn; address=<address>; connid=<connid>
-                 if (connectionId != null) {
-                     finalPath = String.format("type=%s; address=%s; connid=%s", outVolume.getAddressType().toString(), outVolume.getAddress().toLowerCase(), connectionId);
-                 } else {
-                     finalPath = String.format("type=%s; address=%s;", outVolume.getAddressType().toString(), outVolume.getAddress().toLowerCase());
-                 }
- 
-                 persistVolumeData(storagePool, details, destdata, outVolume, connectionId);
+                 // initial volume info does not have connection map yet.  That is added when grantAccess is called later.
+                 String finalPath = generatePathInfo(outVolume, null);
+                 persistVolumeData(storagePool, details, destdata, outVolume, null);
 -                s_logger.info("Copy completed from [" + srcdata.getUuid() + "] to [" + destdata.getUuid() + "]");
 +                logger.info("Copy completed from [" + srcdata.getUuid() + "] to [" + destdata.getUuid() + "]");
  
                  VolumeObjectTO voto = new VolumeObjectTO();
                  voto.setPath(finalPath);
@@@ -443,6 -482,66 +483,66 @@@
  
      }
  
+     public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
 -        s_logger.debug("Granting host " + host.getName() + " access to volume " + dataObject.getUuid());
++        logger.debug("Granting host " + host.getName() + " access to volume " + dataObject.getUuid());
+ 
+         try {
+             StoragePoolVO storagePool = _storagePoolDao.findById(dataObject.getDataStore().getId());
+             Map<String, String> details = _storagePoolDao.getDetails(storagePool.getId());
+             ProviderAdapter api = getAPI(storagePool, details);
+ 
+             ProviderAdapterContext context = newManagedVolumeContext(dataObject);
+             ProviderAdapterDataObject sourceIn = newManagedDataObject(dataObject, storagePool);
+             api.attach(context, sourceIn, host.getName());
+ 
+             // rewrite the volume data, especially the connection string for informational purposes - unless it was turned off above
+             ProviderVolume vol = api.getVolume(context, sourceIn);
+             ProviderAdapterDataObject dataIn = newManagedDataObject(dataObject, storagePool);
+             Map<String,String> connIdMap = api.getConnectionIdMap(dataIn);
+             persistVolumeOrTemplateData(storagePool, details, dataObject, vol, connIdMap);
+ 
+ 
 -            s_logger.info("Granted host " + host.getName() + " access to volume " + dataObject.getUuid());
++            logger.info("Granted host " + host.getName() + " access to volume " + dataObject.getUuid());
+             return true;
+         } catch (Throwable e) {
+             String msg = "Error granting host " + host.getName() + " access to volume " + dataObject.getUuid() + ":" + e.getMessage();
 -            s_logger.error(msg);
++            logger.error(msg);
+             throw new CloudRuntimeException(msg, e);
+         }
+     }
+ 
+     public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
+         // nothing to do if the host is null
+         if (dataObject == null || host == null || dataStore == null) {
+             return;
+         }
+ 
 -        s_logger.debug("Revoking access for host " + host.getName() + " to volume " + dataObject.getUuid());
++        logger.debug("Revoking access for host " + host.getName() + " to volume " + dataObject.getUuid());
+ 
+         try {
+             StoragePoolVO storagePool = _storagePoolDao.findById(dataObject.getDataStore().getId());
+             Map<String, String> details = _storagePoolDao.getDetails(storagePool.getId());
+             ProviderAdapter api = getAPI(storagePool, details);
+ 
+             ProviderAdapterContext context = newManagedVolumeContext(dataObject);
+             ProviderAdapterDataObject sourceIn = newManagedDataObject(dataObject, storagePool);
+ 
+             api.detach(context, sourceIn, host.getName());
+ 
+             // rewrite the volume data, especially the connection string for informational purposes
+             ProviderVolume vol = api.getVolume(context, sourceIn);
+             ProviderAdapterDataObject dataIn = newManagedDataObject(dataObject, storagePool);
+             Map<String,String> connIdMap = api.getConnectionIdMap(dataIn);
+             persistVolumeOrTemplateData(storagePool, details, dataObject, vol, connIdMap);
+ 
 -            s_logger.info("Revoked access for host " + host.getName() + " to volume " + dataObject.getUuid());
++            logger.info("Revoked access for host " + host.getName() + " to volume " + dataObject.getUuid());
+         } catch (Throwable e) {
+             String msg = "Error revoking access for host " + host.getName() + " to volume " + dataObject.getUuid() + ":" + e.getMessage();
 -            s_logger.error(msg);
++            logger.error(msg);
+             throw new CloudRuntimeException(msg, e);
+         }
+     }
+ 
      @Override
      public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo,
              QualityOfServiceState qualityOfServiceState) {
diff --cc plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolBackupSnapshotCommandWrapper.java
index ade9e8370a8,58264161bd6..b3f49b015d1
--- a/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolBackupSnapshotCommandWrapper.java
+++ b/plugins/storage/volume/storpool/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/StorPoolBackupSnapshotCommandWrapper.java
@@@ -25,10 -30,16 +30,15 @@@ import java.util.Map
  
  import org.apache.cloudstack.storage.command.CopyCmdAnswer;
  import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+ import org.apache.cloudstack.utils.cryptsetup.KeyFile;
+ import org.apache.cloudstack.utils.qemu.QemuImageOptions;
  import org.apache.cloudstack.utils.qemu.QemuImg;
  import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+ import org.apache.cloudstack.utils.qemu.QemuImgException;
  import org.apache.cloudstack.utils.qemu.QemuImgFile;
+ import org.apache.cloudstack.utils.qemu.QemuObject;
+ import org.apache.cloudstack.utils.qemu.QemuObject.EncryptFormat;
  import org.apache.commons.io.FileUtils;
 -import org.apache.log4j.Logger;
  
  import com.cloud.agent.api.storage.StorPoolBackupSnapshotCommand;
  import com.cloud.agent.api.to.DataStoreTO;
diff --cc server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index 4f70149ad11,eb72a626036..d9277377cbf
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@@ -139,11 -135,12 +139,12 @@@ import org.apache.cloudstack.storage.da
  import org.apache.cloudstack.userdata.UserDataManager;
  import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
  import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
+ import org.apache.cloudstack.vm.UnmanagedVMsManager;
  import org.apache.commons.collections.CollectionUtils;
  import org.apache.commons.collections.MapUtils;
 +import org.apache.commons.lang3.EnumUtils;
  import org.apache.commons.lang3.ObjectUtils;
  import org.apache.commons.lang3.StringUtils;
 -import org.apache.log4j.Logger;
  
  import com.cloud.agent.AgentManager;
  import com.cloud.alert.AlertManager;
diff --cc server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
index 390ea155b3c,927637ab918..ffd482b711d
--- a/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
+++ b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
@@@ -69,7 -71,12 +70,11 @@@ import java.util.UUID
  import static com.cloud.configuration.ConfigurationManagerImpl.ADD_HOST_ON_SERVICE_RESTART_KVM;
  
  public abstract class LibvirtServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter {
 -    private static final Logger s_logger = Logger.getLogger(LibvirtServerDiscoverer.class);
      private final int _waitTime = 5; /* wait for 5 minutes */
+ 
+     private final static HashSet<String> COMPATIBLE_HOST_OSES = new HashSet<>(Arrays.asList("Rocky", "Rocky Linux",
+             "Red", "Red Hat Enterprise Linux", "Oracle", "Oracle Linux Server", "AlmaLinux"));
+ 
      private String _kvmPrivateNic;
      private String _kvmPublicNic;
      private String _kvmGuestNic;
@@@ -468,10 -475,10 +473,10 @@@
              _hostDao.loadDetails(oneHost);
              String hostOsInCluster = oneHost.getDetail("Host.OS");
              String hostOs = ssCmd.getHostDetails().get("Host.OS");
-             if (!hostOsInCluster.equalsIgnoreCase(hostOs)) {
+             if (!isHostOsCompatibleWithOtherHost(hostOsInCluster, hostOs)) {
                  String msg = String.format("host: %s with hostOS, \"%s\"into a cluster, in which there are \"%s\" hosts added", firstCmd.getPrivateIpAddress(), hostOs, hostOsInCluster);
                  if (hostOs != null && hostOs.startsWith(hostOsInCluster)) {
 -                    s_logger.warn(String.format("Adding %s. This may or may not be ok!", msg));
 +                    logger.warn(String.format("Adding %s. This may or may not be ok!", msg));
                  } else {
                      throw new IllegalArgumentException(String.format("Can't add %s.", msg));
                  }
@@@ -483,6 -490,17 +488,17 @@@
          return _resourceMgr.fillRoutingHostVO(host, ssCmd, getHypervisorType(), host.getDetails(), null);
      }
  
+     protected boolean isHostOsCompatibleWithOtherHost(String hostOsInCluster, String hostOs) {
+         if (hostOsInCluster.equalsIgnoreCase(hostOs)) {
+             return true;
+         }
+         if (COMPATIBLE_HOST_OSES.contains(hostOsInCluster) && COMPATIBLE_HOST_OSES.contains(hostOs)) {
 -            s_logger.info(String.format("The host OS (%s) is compatible with the existing host OS (%s) in the cluster.", hostOs, hostOsInCluster));
++            logger.info(String.format("The host OS (%s) is compatible with the existing host OS (%s) in the cluster.", hostOs, hostOsInCluster));
+             return true;
+         }
+         return false;
+     }
+ 
      @Override
      public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
          // TODO Auto-generated method stub
diff --cc server/src/main/java/com/cloud/server/ManagementServerImpl.java
index 81ab2524bd6,14afcc71245..0adcd8310da
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@@ -5148,12 -5062,47 +5148,47 @@@ public class ManagementServerImpl exten
          }
  
          final Pair<List<HypervisorCapabilitiesVO>, Integer> result = _hypervisorCapabilitiesDao.searchAndCount(sc, searchFilter);
 -        return new Pair<List<? extends HypervisorCapabilities>, Integer>(result.first(), result.second());
 +        return new Pair<>(result.first(), result.second());
      }
  
+     protected HypervisorCapabilitiesVO getHypervisorCapabilitiesForUpdate(final Long id, final String hypervisorStr, final String hypervisorVersion) {
+         if (id == null && StringUtils.isAllEmpty(hypervisorStr, hypervisorVersion)) {
+             throw new InvalidParameterValueException("Either ID or hypervisor and hypervisor version must be specified");
+         }
+         if (id != null) {
+             if (!StringUtils.isAllBlank(hypervisorStr, hypervisorVersion)) {
+                 throw new InvalidParameterValueException("ID can not be specified together with hypervisor and hypervisor version");
+             }
+             HypervisorCapabilitiesVO hpvCapabilities = _hypervisorCapabilitiesDao.findById(id, true);
+             if (hpvCapabilities == null) {
+                 final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find the hypervisor capabilities for specified id");
+                 ex.addProxyObject(id.toString(), "Id");
+                 throw ex;
+             }
+             return hpvCapabilities;
+         }
+         if (StringUtils.isAnyBlank(hypervisorStr, hypervisorVersion)) {
+             throw new InvalidParameterValueException("Hypervisor and hypervisor version must be specified together");
+         }
+         HypervisorType hypervisorType = HypervisorType.getType(hypervisorStr);
+         if (hypervisorType == HypervisorType.None) {
+             throw new InvalidParameterValueException("Invalid hypervisor specified");
+         }
+         HypervisorCapabilitiesVO hpvCapabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
+         if (hpvCapabilities == null) {
+             final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the hypervisor capabilities for specified hypervisor and hypervisor version");
+             ex.addProxyObject(hypervisorStr, "hypervisor");
+             ex.addProxyObject(hypervisorVersion, "hypervisorVersion");
+             throw ex;
+         }
+         return hpvCapabilities;
+     }
+ 
      @Override
      public HypervisorCapabilities updateHypervisorCapabilities(UpdateHypervisorCapabilitiesCmd cmd) {
-         final Long id = cmd.getId();
+         Long id = cmd.getId();
+         final String hypervisorStr = cmd.getHypervisor();
+         final String hypervisorVersion = cmd.getHypervisorVersion();
          final Boolean securityGroupEnabled = cmd.getSecurityGroupEnabled();
          final Long maxGuestsLimit = cmd.getMaxGuestsLimit();
          final Integer maxDataVolumesLimit = cmd.getMaxDataVolumesLimit();
@@@ -5174,7 -5117,14 +5203,14 @@@
          if (!updateNeeded) {
              return hpvCapabilities;
          }
+         if (StringUtils.isNotBlank(hypervisorVersion) && !hpvCapabilities.getHypervisorVersion().equals(hypervisorVersion)) {
 -            s_logger.debug(String.format("Hypervisor capabilities for hypervisor: %s and version: %s does not exist, creating a copy from the parent version: %s for update.", hypervisorStr, hypervisorVersion, hpvCapabilities.getHypervisorVersion()));
++            logger.debug(String.format("Hypervisor capabilities for hypervisor: %s and version: %s does not exist, creating a copy from the parent version: %s for update.", hypervisorStr, hypervisorVersion, hpvCapabilities.getHypervisorVersion()));
+             HypervisorCapabilitiesVO copy = new HypervisorCapabilitiesVO(hpvCapabilities);
+             copy.setHypervisorVersion(hypervisorVersion);
+             hpvCapabilities = _hypervisorCapabilitiesDao.persist(copy);
+         }
  
+         id = hpvCapabilities.getId();
          hpvCapabilities = _hypervisorCapabilitiesDao.createForUpdate(id);
  
          if (securityGroupEnabled != null) {
diff --cc server/src/main/java/com/cloud/server/StatsCollector.java
index 86b8b0c682c,070508f2502..9d0d95c8b39
--- a/server/src/main/java/com/cloud/server/StatsCollector.java
+++ b/server/src/main/java/com/cloud/server/StatsCollector.java
@@@ -1960,10 -1964,10 +1962,10 @@@ public class StatsCollector extends Man
                      vmStatsMaxRetentionTime.scope(), vmStatsMaxRetentionTime.toString()));
              return;
          }
 -        LOGGER.trace("Removing older VM stats records.");
 +        logger.trace("Removing older VM stats records.");
          Date now = new Date();
          Date limit = DateUtils.addMinutes(now, -maxRetentionTime);
-         vmStatsDao.removeAllByTimestampLessThan(limit);
+         vmStatsDao.removeAllByTimestampLessThan(limit, vmStatsRemoveBatchSize.value());
      }
  
      /**
diff --cc server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index c950322452b,553f72b719b..73a7f7ab546
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@@ -1055,12 -1057,12 +1055,12 @@@ public class VolumeApiServiceImpl exten
              created = false;
              VolumeInfo vol = volFactory.getVolume(cmd.getEntityId());
              vol.stateTransit(Volume.Event.DestroyRequested);
-             throw new CloudRuntimeException("Failed to create volume: " + volume.getId(), e);
+             throw new CloudRuntimeException("Failed to create volume: " + volume.getUuid(), e);
          } finally {
              if (!created) {
 -                s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
 -                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume());
 -                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, cmd.getDisplayVolume(), new Long(volume.getSize()));
 +                logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
 +                _resourceLimitMgr.decrementVolumeResourceCount(volume.getAccountId(), cmd.getDisplayVolume(),
 +                        volume.getSize(), _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId()));
              }
          }
      }
diff --cc server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
index b1c653d3f92,2ff3bf2ca21..c593b23d7cc
--- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
@@@ -796,9 -794,16 +796,16 @@@ public class UnmanagedVMsManagerImpl im
              }
          }
          copyRemoteVolumeCommand.setTempPath(tmpPath);
+         int copyTimeout = UnmanagedVMsManager.RemoteKvmInstanceDisksCopyTimeout.value();
+         if (copyTimeout <= 0) {
+             copyTimeout = Integer.valueOf(UnmanagedVMsManager.RemoteKvmInstanceDisksCopyTimeout.defaultValue());
+         }
+         int copyTimeoutInSecs = copyTimeout * 60;
+         copyRemoteVolumeCommand.setWait(copyTimeoutInSecs);
 -        LOGGER.error(String.format("Initiating copy remote volume %s from %s, timeout %d secs", path, remoteUrl, copyTimeoutInSecs));
++        logger.error(String.format("Initiating copy remote volume %s from %s, timeout %d secs", path, remoteUrl, copyTimeoutInSecs));
          Answer answer = agentManager.easySend(dest.getHost().getId(), copyRemoteVolumeCommand);
          if (!(answer instanceof CopyRemoteVolumeAnswer)) {
-             throw new CloudRuntimeException("Error while copying volume");
+             throw new CloudRuntimeException("Error while copying volume of remote instance: " + answer.getDetails());
          }
          CopyRemoteVolumeAnswer copyRemoteVolumeAnswer = (CopyRemoteVolumeAnswer) answer;
          if(!copyRemoteVolumeAnswer.getResult()) {
diff --cc ui/src/views/compute/DeployVM.vue
index 865ee79d76c,0bd68e5e204..6792314e74b
--- a/ui/src/views/compute/DeployVM.vue
+++ b/ui/src/views/compute/DeployVM.vue
@@@ -2343,10 -2275,8 +2343,11 @@@ export default 
          args.pageSize = args.pageSize || 10
        }
        args.zoneid = _.get(this.zone, 'id')
 +      args.account = store.getters.project?.id ? null : this.owner.account
 +      args.domainid = store.getters.project?.id ? null : this.owner.domainid
 +      args.projectid = store.getters.project?.id || this.owner.projectid
        args.templatefilter = templateFilter
+       args.projectid = -1
        args.details = 'all'
        args.showicon = 'true'
        args.id = this.templateId
diff --cc utils/src/main/java/com/cloud/utils/ssh/SshHelper.java
index fc229bd7464,1856c0b3838..87221ab5ac8
--- a/utils/src/main/java/com/cloud/utils/ssh/SshHelper.java
+++ b/utils/src/main/java/com/cloud/utils/ssh/SshHelper.java
@@@ -39,8 -38,9 +39,9 @@@ import com.cloud.utils.Pair
  public class SshHelper {
      private static final int DEFAULT_CONNECT_TIMEOUT = 180000;
      private static final int DEFAULT_KEX_TIMEOUT = 60000;
+     private static final int DEFAULT_WAIT_RESULT_TIMEOUT = 120000;
  
 -    private static final Logger s_logger = Logger.getLogger(SshHelper.class);
 +    protected static Logger LOGGER = LogManager.getLogger(SshHelper.class);
  
      public static Pair<Boolean, String> sshExecute(String host, int port, String user, File pemKeyFile, String password, String command) throws Exception {