You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2016/02/24 21:24:33 UTC

[02/11] git commit: updated refs/heads/master to d705d85

CLOUDSTACK-9252: Support configurable nfs version


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e524f655
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e524f655
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e524f655

Branch: refs/heads/master
Commit: e524f6557033f92da7cf9c099662630580b6a9e5
Parents: 0bc1b27
Author: nvazquez <ni...@gmail.com>
Authored: Fri Jan 22 16:41:23 2016 -0200
Committer: nvazquez <ni...@gmail.com>
Committed: Mon Feb 1 12:50:58 2016 -0800

----------------------------------------------------------------------
 .../cloud/resource/AgentStorageResource.java    |  2 +-
 .../vmware/manager/VmwareManager.java           |  4 +-
 .../vmware/manager/VmwareManagerImpl.java       | 34 +++++++--
 .../manager/VmwareStorageManagerImpl.java       | 16 ++--
 .../vmware/manager/VmwareStorageMount.java      |  2 +-
 .../vmware/resource/VmwareResource.java         | 18 +++--
 .../VmwareSecondaryStorageResourceHandler.java  |  4 +-
 .../resource/VmwareStorageProcessor.java        | 14 ++--
 .../VmwareStorageSubsystemCommandHandler.java   |  6 +-
 .../vmware/VmwareDatacenterApiUnitTest.java     |  6 ++
 server/src/com/cloud/server/StatsCollector.java | 16 +++-
 .../LocalNfsSecondaryStorageResource.java       |  8 +-
 .../resource/LocalSecondaryStorageResource.java |  2 +-
 .../resource/NfsSecondaryStorageResource.java   | 79 +++++++++++++-------
 .../resource/SecondaryStorageResource.java      |  2 +-
 .../storage/template/DownloadManagerImpl.java   |  2 +-
 .../NfsSecondaryStorageResourceTest.java        |  2 +-
 17 files changed, 144 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
index 751da9e..9b1f091 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
@@ -109,7 +109,7 @@ public class AgentStorageResource extends AgentResourceBase implements Secondary
     }
 
     @Override
-    public String getRootDir(String url) {
+    public String getRootDir(String url, String nfsVersion) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
index 72ee218..6559050 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
@@ -36,7 +36,7 @@ public interface VmwareManager {
 
     String getSystemVMDefaultNicAdapterType();
 
-    void prepareSecondaryStorageStore(String strStorageUrl);
+    void prepareSecondaryStorageStore(String strStorageUrl, Long storeId);
 
     void setupResourceStartupParams(Map<String, Object> params);
 
@@ -48,7 +48,7 @@ public interface VmwareManager {
 
     String getManagementPortGroupName();
 
-    String getSecondaryStorageStoreUrl(long dcId);
+    Pair<String, Long> getSecondaryStorageStoreUrlAndId(long dcId);
 
     File getSystemVMKeyFile();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 575801f..602a544 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -46,6 +46,7 @@ import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
 
 import com.cloud.agent.AgentManager;
@@ -167,6 +168,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     private ManagementServerHostPeerDao _mshostPeerDao;
     @Inject
     private ClusterManager _clusterMgr;
+    @Inject
+    private ImageStoreDetailsDao _imageDetailsStoreDao;
 
     private String _mountParent;
     private StorageLayer _storage;
@@ -439,12 +442,14 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     }
 
     @Override
-    public String getSecondaryStorageStoreUrl(long dcId) {
+    public Pair<String, Long> getSecondaryStorageStoreUrlAndId(long dcId) {
 
         String secUrl = null;
+        Long secId = null;
         DataStore secStore = _dataStoreMgr.getImageStore(dcId);
         if (secStore != null) {
             secUrl = secStore.getUri();
+            secId = secStore.getId();
         }
 
         if (secUrl == null) {
@@ -453,12 +458,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
             DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId);
             if (cacheStore != null) {
                 secUrl = cacheStore.getUri();
+                secId = cacheStore.getId();
             } else {
                 s_logger.warn("No staging storage is found when non-NFS secondary storage is used");
             }
         }
 
-        return secUrl;
+        return new Pair<String, Long>(secUrl, secId);
     }
 
     @Override
@@ -546,8 +552,17 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     }
 
     @Override
-    public void prepareSecondaryStorageStore(String storageUrl) {
-        String mountPoint = getMountPoint(storageUrl);
+    public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
+        String nfsVersion = null;
+        if (storeId != null){
+            Map<String, String> details = _imageDetailsStoreDao.getDetails(storeId);
+            for (String detailKey : details.keySet()) {
+                if (detailKey.equals("nfs.version")){
+                    nfsVersion = details.get(detailKey);
+                }
+            }
+        }
+        String mountPoint = getMountPoint(storageUrl, nfsVersion);
 
         GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
         try {
@@ -655,7 +670,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     }
 
     @Override
-    public String getMountPoint(String storageUrl) {
+    public String getMountPoint(String storageUrl, String nfsVersion) {
         String mountPoint = null;
         synchronized (_storageMounts) {
             mountPoint = _storageMounts.get(storageUrl);
@@ -670,7 +685,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
                 s_logger.error("Invalid storage URL format ", e);
                 throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl);
             }
-            mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent);
+
+            mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent, nfsVersion);
             if (mountPoint == null) {
                 s_logger.error("Unable to create mount point for " + storageUrl);
                 return "/mnt/sec"; // throw new CloudRuntimeException("Unable to create mount point for " + storageUrl);
@@ -745,7 +761,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
         }
     }
 
-    protected String mount(String path, String parent) {
+    protected String mount(String path, String parent, String nfsVersion) {
         String mountPoint = setupMountPoint(parent);
         if (mountPoint == null) {
             s_logger.warn("Unable to create a mount point");
@@ -756,6 +772,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
         String result = null;
         Script command = new Script(true, "mount", _timeout, s_logger);
         command.add("-t", "nfs");
+        if (nfsVersion != null){
+            command.add("-o", "vers=" + nfsVersion);
+        }
         // command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
         if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) {
             command.add("-o", "resvport");
@@ -1234,4 +1253,5 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
             return true;
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index 4109ff2..f87fe6c 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -156,7 +156,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
         String secStorageUrl = nfsStore.getUrl();
         assert (secStorageUrl != null);
         String installPath = template.getPath();
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         String installFullPath = secondaryMountPoint + "/" + installPath;
         try {
             if (installFullPath.endsWith(".ova")) {
@@ -194,7 +194,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
         String installPath = volume.getPath();
         int index = installPath.lastIndexOf(File.separator);
         String volumeUuid = installPath.substring(index + 1);
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         //The real volume path
         String volumePath = installPath + File.separator + volumeUuid + ".ova";
         String installFullPath = secondaryMountPoint + "/" + installPath;
@@ -547,7 +547,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
         s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
                 templatePathAtSecondaryStorage + ", templateName: " + templateName);
 
-        String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl, null);
         s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
 
         String srcOVAFileName = secondaryMountPoint + "/" + templatePathAtSecondaryStorage + templateName + "." + ImageFormat.OVA.getFileExtension();
@@ -600,7 +600,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
     private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, long accountId, long templateId, String templateUniqueName, String secStorageUrl,
             String volumePath, String workerVmName) throws Exception {
 
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
         String installFullPath = secondaryMountPoint + "/" + installPath;
         synchronized (installPath.intern()) {
@@ -665,7 +665,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
     private Ternary<String, Long, Long> createTemplateFromSnapshot(long accountId, long templateId, String templateUniqueName, String secStorageUrl, long volumeId,
             String backedUpSnapshotUuid) throws Exception {
 
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
         String installFullPath = secondaryMountPoint + "/" + installPath;
         String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova";  //Note: volss for tmpl
@@ -856,7 +856,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
     private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
             String backupName) throws Exception {
 
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension();
         String snapshotDir = "";
         if (backupName.contains("/")) {
@@ -924,7 +924,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
     private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName,
             String workerVmName) throws Exception {
 
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
 
         synchronized (exportPath.intern()) {
@@ -1446,7 +1446,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
     }
 
     private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl) throws Exception {
-        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, null);
         String volumeMountRoot = secondaryMountPoint + "/" + getVolumeRelativeDirInSecStroage(volumeId);
 
         return deleteDir(volumeMountRoot);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
index dd07029..54b52f6 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
@@ -17,5 +17,5 @@
 package com.cloud.hypervisor.vmware.manager;
 
 public interface VmwareStorageMount {
-    String getMountPoint(String storageUrl);
+    String getMountPoint(String storageUrl, String nfsVersion);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index fdbc244..56f9298 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -1636,12 +1636,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
             // prepare systemvm patch ISO
             if (vmSpec.getType() != VirtualMachine.Type.User) {
                 // attach ISO (for patching of system VM)
-                String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
+                Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
+                String secStoreUrl = secStoreUrlAndId.first();
+                Long secStoreId = secStoreUrlAndId.second();
                 if (secStoreUrl == null) {
                     String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
                     throw new Exception(msg);
                 }
-                mgr.prepareSecondaryStorageStore(secStoreUrl);
+                mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
 
                 ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
                 if (morSecDs == null) {
@@ -3134,12 +3136,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
                 prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
             }
 
-            String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
+            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
+            String secStoreUrl = secStoreUrlAndId.first();
+            Long secStoreId = secStoreUrlAndId.second();
             if (secStoreUrl == null) {
                 String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
                 throw new Exception(msg);
             }
-            mgr.prepareSecondaryStorageStore(secStoreUrl);
+            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
 
             ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
             if (morSecDs == null) {
@@ -3350,12 +3354,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
             }
 
             // Ensure secondary storage mounted on target host
-            String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
+            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
+            String secStoreUrl = secStoreUrlAndId.first();
+            Long secStoreId = secStoreUrlAndId.second();
             if (secStoreUrl == null) {
                 String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
                 throw new Exception(msg);
             }
-            mgr.prepareSecondaryStorageStore(secStoreUrl);
+            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
             ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost);
             if (morSecDs == null) {
                 String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index 8a27799..c3f65cb 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -304,7 +304,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
     }
 
     @Override
-    public String getMountPoint(String storageUrl) {
-        return _resource.getRootDir(storageUrl);
+    public String getMountPoint(String storageUrl, String nfsVersion) {
+        return _resource.getRootDir(storageUrl, nfsVersion);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index fa2f369..35e775f 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -160,7 +160,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
         s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
                 templatePathAtSecondaryStorage + ", templateName: " + templateName);
 
-        String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl);
+        String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, null);
         s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
 
         String srcOVAFileName =
@@ -539,7 +539,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
     }
 
     private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl) throws Exception {
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
         String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir;
 
         return deleteDir(volumeMountRoot);
@@ -722,7 +722,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
     private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName,
             String secStorageUrl, String volumePath, String workerVmName) throws Exception {
 
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
         String installFullPath = secondaryMountPoint + "/" + installPath;
         synchronized (installPath.intern()) {
             Script command = new Script(false, "mkdir", _timeout, s_logger);
@@ -899,7 +899,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
             snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length - 1);
         }
 
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
         String installFullPath = secondaryMountPoint + "/" + installPath;
         String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova";  //Note: volss for tmpl
         String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder;
@@ -1054,7 +1054,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
     private Pair<String, String[]> exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
             String exportName, String workerVmName) throws Exception {
 
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
         String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
 
         synchronized (exportPath.intern()) {
@@ -1186,7 +1186,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
 
                     // Get snapshot physical size
                     long physicalSize = 0l;
-                    String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl);
+                    String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, null);
                     String snapshotDir =  destSnapshot.getPath() + "/" + snapshotBackupUuid;
                     File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
                     if(files != null) {
@@ -2146,7 +2146,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
     private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
             String backupName, long wait) throws Exception {
 
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
         String srcOVAFileName = null;
         String srcOVFFileName = null;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
index 4312862..5beab05 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
@@ -82,7 +82,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
             //need to take extra processing for vmware, such as packing to ova, before sending to S3
             if (srcData.getObjectType() == DataObjectType.VOLUME) {
                 NfsTO cacheStore = (NfsTO)srcDataStore;
-                String parentPath = storageResource.getRootDir(cacheStore.getUrl());
+                String parentPath = storageResource.getRootDir(cacheStore.getUrl(), null);
                 VolumeObjectTO vol = (VolumeObjectTO)srcData;
                 String path = vol.getPath();
                 int index = path.lastIndexOf(File.separator);
@@ -95,7 +95,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
             } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT) {
                 // pack ova first
                 // sync snapshot from NFS cache to S3 in NFS migration to S3 case
-                String parentPath = storageResource.getRootDir(srcDataStore.getUrl());
+                String parentPath = storageResource.getRootDir(srcDataStore.getUrl(), null);
                 SnapshotObjectTO snap = (SnapshotObjectTO)srcData;
                 String path = snap.getPath();
                 int index = path.lastIndexOf(File.separator);
@@ -138,7 +138,7 @@ public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemComman
                     return answer;
                 }
                 NfsTO cacheStore = (NfsTO)cmd.getCacheTO().getDataStore();
-                String parentPath = storageResource.getRootDir(cacheStore.getUrl());
+                String parentPath = storageResource.getRootDir(cacheStore.getUrl(), null);
                 SnapshotObjectTO newSnapshot = (SnapshotObjectTO)answer.getNewData();
                 String path = newSnapshot.getPath();
                 int index = path.lastIndexOf(File.separator);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
index 3b3dd47..6b89e7b 100644
--- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
@@ -54,6 +54,7 @@ import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
 import org.apache.cloudstack.test.utils.SpringUtils;
 
 import com.cloud.agent.AgentManager;
@@ -431,6 +432,11 @@ public class VmwareDatacenterApiUnitTest {
             return Mockito.mock(DataStoreManager.class);
         }
 
+        @Bean
+        public ImageStoreDetailsDao imageStoreDetailsDao(){
+            return Mockito.mock(ImageStoreDetailsDao.class);
+        }
+
         public static class Library implements TypeFilter {
 
             @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/server/src/com/cloud/server/StatsCollector.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
index ca86cfd..c66ada8 100644
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@ -44,6 +44,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.utils.graphite.GraphiteClient;
@@ -198,6 +199,8 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
     private ServiceOfferingDao _serviceOfferingDao;
     @Inject
     private HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
+    private ImageStoreDetailsDao _imageStoreDetailsDao;
 
     private ConcurrentHashMap<Long, HostStats> _hostStats = new ConcurrentHashMap<Long, HostStats>();
     private final ConcurrentHashMap<Long, VmStats> _VmStats = new ConcurrentHashMap<Long, VmStats>();
@@ -715,7 +718,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
                         continue;
                     }
 
-                    GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO());
+                    GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO(), getNfsVersion(store.getId()));
                     EndPoint ssAhost = _epSelector.select(store);
                     if (ssAhost == null) {
                         s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName());
@@ -762,6 +765,17 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
                 s_logger.error("Error trying to retrieve storage stats", t);
             }
         }
+
+        private String getNfsVersion(long storeId) {
+            String nfsVersion = null;
+            if (_imageStoreDetailsDao.getDetails(storeId) != null){
+                Map<String, String> storeDetails = _imageStoreDetailsDao.getDetails(storeId);
+                if (storeDetails != null && storeDetails.containsKey("nfs.version")){
+                    nfsVersion = storeDetails.get("nfs.version");
+                }
+            }
+            return nfsVersion;
+        }
     }
 
     class AutoScaleMonitor extends ManagedContextRunnable {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
index 9393ee2..6f189ef 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
@@ -53,10 +53,10 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
     }
 
     @Override
-    synchronized public String getRootDir(String secUrl) {
+    synchronized public String getRootDir(String secUrl, String nfsVersion) {
         try {
             URI uri = new URI(secUrl);
-            String dir = mountUri(uri);
+            String dir = mountUri(uri, nfsVersion);
             return _parent + "/" + dir;
         } catch (Exception e) {
             String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
@@ -66,14 +66,14 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
     }
 
     @Override
-    protected void mount(String localRootPath, String remoteDevice, URI uri) {
+    protected void mount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) {
         ensureLocalRootPathExists(localRootPath, uri);
 
         if (mountExists(localRootPath, uri)) {
             return;
         }
 
-        attemptMount(localRootPath, remoteDevice, uri);
+        attemptMount(localRootPath, remoteDevice, uri, nfsVersion);
 
         // Change permissions for the mountpoint - seems to bypass authentication
         Script script = new Script(true, "chmod", _timeout, s_logger);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
index bdfe7e8..d953338 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
@@ -72,7 +72,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
     }
 
     @Override
-    public String getRootDir(String url) {
+    public String getRootDir(String url, String nfsVersion) {
         return getRootDir();
 
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 768a177..b71c96f 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -44,6 +44,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import com.cloud.exception.InvalidParameterValueException;
@@ -91,6 +92,9 @@ import org.apache.cloudstack.storage.command.DownloadCommand;
 import org.apache.cloudstack.storage.command.DownloadProgressCommand;
 import org.apache.cloudstack.storage.command.UploadStatusAnswer;
 import org.apache.cloudstack.storage.command.UploadStatusAnswer.UploadStatus;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.command.UploadStatusCommand;
 import org.apache.cloudstack.storage.template.DownloadManager;
 import org.apache.cloudstack.storage.template.DownloadManagerImpl;
@@ -212,6 +216,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     private HashMap<String,UploadEntity> uploadEntityStateMap = new HashMap<String,UploadEntity>();
     private String _ssvmPSK = null;
 
+    @Inject
+    ImageStoreDao dataStoreDao;
+
+    @Inject
+    ImageStoreDetailsDao detailsStoreDao;
+
+    public static final String IMAGE_STORE_PARAMETER_ID = "imageStoreId";
+
     public void setParentPath(String path) {
         _parent = path;
     }
@@ -412,7 +424,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
 
     protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
             NfsTO destDataStore) {
-        String srcMountPoint = getRootDir(srcDataStore.getUrl());
+        String srcMountPoint = getRootDir(srcDataStore.getUrl(), null);
         String snapshotPath = srcData.getPath();
         int index = snapshotPath.lastIndexOf("/");
         String snapshotName = snapshotPath.substring(index + 1);
@@ -422,7 +434,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         snapshotPath = snapshotPath.substring(0, index);
 
         snapshotPath = srcMountPoint + File.separator + snapshotPath;
-        String destMountPoint = getRootDir(destDataStore.getUrl());
+        String destMountPoint = getRootDir(destDataStore.getUrl(), null);
         String destPath = destMountPoint + File.separator + destData.getPath();
 
         String errMsg = null;
@@ -566,7 +578,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     }
 
     protected File getFile(String path, String nfsPath) {
-        String filePath = getRootDir(nfsPath) + File.separator + path;
+        String filePath = getRootDir(nfsPath, null) + File.separator + path;
         File f = new File(filePath);
         if (!f.exists()) {
             _storage.mkdirs(filePath);
@@ -706,7 +718,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     }
 
     private String determineStorageTemplatePath(final String storagePath, String dataPath) {
-        return join(asList(getRootDir(storagePath), dataPath), File.separator);
+        return join(asList(getRootDir(storagePath, null), dataPath), File.separator);
     }
 
     protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
@@ -720,7 +732,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 throw new CloudRuntimeException("Failed to get url: " + url);
             }
 
-            String nfsMountPath = getRootDir(nfs.getUrl());
+            String nfsMountPath = getRootDir(nfs.getUrl(), null);
 
             String filePath = nfsMountPath + File.separator + path;
             File directory = new File(filePath);
@@ -1098,7 +1110,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         if (dstore instanceof NfsTO) {
             NfsTO nfs = (NfsTO)dstore;
             String relativeSnapshotPath = cmd.getDirectory();
-            String parent = getRootDir(nfs.getUrl());
+            String parent = getRootDir(nfs.getUrl(), null);
 
             if (relativeSnapshotPath.startsWith(File.separator)) {
                 relativeSnapshotPath = relativeSnapshotPath.substring(1);
@@ -1176,7 +1188,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             return new Answer(cmd, false, "can't handle non nfs data store");
         }
         NfsTO nfsStore = (NfsTO)store;
-        String parent = getRootDir(nfsStore.getUrl());
+        String parent = getRootDir(nfsStore.getUrl(), null);
 
         if (relativeTemplatePath.startsWith(File.separator)) {
             relativeTemplatePath = relativeTemplatePath.substring(1);
@@ -1297,6 +1309,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         }
     }
 
+    private Long getImageStoreId(DataStoreTO dataStore){
+        Long imgStoreId = null;
+        if (dataStore.getRole().equals(DataStoreRole.Image)){
+            String uuid = dataStore.getUuid();
+            ImageStoreVO imageStoreVO = dataStoreDao.findByUuid(uuid);
+            imgStoreId = imageStoreVO.getId();
+        }
+        return imgStoreId;
+    }
+
     private Answer execute(SecStorageSetupCommand cmd) {
         if (!_inSystemVM) {
             return new Answer(cmd, true, null);
@@ -1310,7 +1332,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 String nfsHostIp = getUriHostIp(uri);
 
                 addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
-                String dir = mountUri(uri);
+
+                String dir = mountUri(uri, cmd.getNfsVersion());
 
                 configCerts(cmd.getCerts());
 
@@ -1386,7 +1409,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         DataStoreTO dstore = obj.getDataStore();
         if (dstore instanceof NfsTO) {
             NfsTO nfs = (NfsTO)dstore;
-            String parent = getRootDir(nfs.getUrl());
+            String parent = getRootDir(nfs.getUrl(), null);
             if (!parent.endsWith(File.separator)) {
                 parent += File.separator;
             }
@@ -1557,7 +1580,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         if (store instanceof NfsTO) {
             NfsTO nfs = (NfsTO)store;
             String secUrl = nfs.getUrl();
-            String root = getRootDir(secUrl);
+            String root = getRootDir(secUrl, cmd.getNfsVersion());
             Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
             return new ListTemplateAnswer(secUrl, templateInfos);
         } else if (store instanceof SwiftTO) {
@@ -1579,7 +1602,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         }
         DataStoreTO store = cmd.getDataStore();
         if (store instanceof NfsTO) {
-            String root = getRootDir(cmd.getSecUrl());
+            String root = getRootDir(cmd.getSecUrl(), null);
             Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
             return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
         } else if (store instanceof S3TO) {
@@ -1714,7 +1737,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             return new GetStorageStatsAnswer(cmd, infinity, 0L);
         }
 
-        String rootDir = getRootDir(((NfsTO)store).getUrl());
+        String rootDir = getRootDir(((NfsTO)store).getUrl(), cmd.getNfsVersion());
         final long usedSize = getUsedSize(rootDir);
         final long totalSize = getTotalSize(rootDir);
         if (usedSize == -1 || totalSize == -1) {
@@ -1748,7 +1771,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         if (dstore instanceof NfsTO) {
             NfsTO nfs = (NfsTO)dstore;
             String relativeTemplatePath = obj.getPath();
-            String parent = getRootDir(nfs.getUrl());
+            String parent = getRootDir(nfs.getUrl(), null);
 
             if (relativeTemplatePath.startsWith(File.separator)) {
                 relativeTemplatePath = relativeTemplatePath.substring(1);
@@ -1852,7 +1875,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         if (dstore instanceof NfsTO) {
             NfsTO nfs = (NfsTO)dstore;
             String relativeVolumePath = obj.getPath();
-            String parent = getRootDir(nfs.getUrl());
+            String parent = getRootDir(nfs.getUrl(), null);
 
             if (relativeVolumePath.startsWith(File.separator)) {
                 relativeVolumePath = relativeVolumePath.substring(1);
@@ -1954,13 +1977,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     }
 
     @Override
-    synchronized public String getRootDir(String secUrl) {
+    synchronized public String getRootDir(String secUrl, String nfsVersion) {
         if (!_inSystemVM) {
             return _parent;
         }
         try {
             URI uri = new URI(secUrl);
-            String dir = mountUri(uri);
+            String dir = mountUri(uri, nfsVersion);
             return _parent + "/" + dir;
         } catch (Exception e) {
             String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
@@ -2291,10 +2314,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
      * @param uri
      *            crresponding to the remote device. Will throw for unsupported
      *            scheme.
+     * @param imgStoreId
      * @return name of folder in _parent that device was mounted.
      * @throws UnknownHostException
      */
-    protected String mountUri(URI uri) throws UnknownHostException {
+    protected String mountUri(URI uri, String nfsVersion) throws UnknownHostException {
         String uriHostIp = getUriHostIp(uri);
         String nfsPath = uriHostIp + ":" + uri.getPath();
 
@@ -2312,7 +2336,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
             s_logger.debug("Mounting device with nfs-style path of " + remoteDevice);
         }
 
-        mount(localRootPath, remoteDevice, uri);
+        mount(localRootPath, remoteDevice, uri, nfsVersion);
 
         return dir;
     }
@@ -2340,15 +2364,15 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         s_logger.debug("Successfully umounted " + localRootPath);
     }
 
-    protected void mount(String localRootPath, String remoteDevice, URI uri) {
-        s_logger.debug("mount " + uri.toString() + " on " + localRootPath);
+    protected void mount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) {
+        s_logger.debug("mount " + uri.toString() + " on " + localRootPath + ((nfsVersion != null) ? " nfsVersion="+nfsVersion : ""));
         ensureLocalRootPathExists(localRootPath, uri);
 
         if (mountExists(localRootPath, uri)) {
             return;
         }
 
-        attemptMount(localRootPath, remoteDevice, uri);
+        attemptMount(localRootPath, remoteDevice, uri, nfsVersion);
 
         // XXX: Adding the check for creation of snapshots dir here. Might have
         // to move it somewhere more logical later.
@@ -2356,9 +2380,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
         checkForVolumesDir(localRootPath);
     }
 
-    protected void attemptMount(String localRootPath, String remoteDevice, URI uri) {
+    protected void attemptMount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) {
         String result;
-        s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri);
+        s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri
+                + ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : ""));
         Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
 
         String scheme = uri.getScheme().toLowerCase();
@@ -2370,7 +2395,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 command.add("-o", "resvport");
             }
             if (_inSystemVM) {
-                command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
+                command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0" + ((nfsVersion != null) ? ",vers=" + nfsVersion : ""));
             }
         } else if (scheme.equals("cifs")) {
             String extraOpts = parseCifsMountOptions(uri);
@@ -2647,7 +2672,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
                 //relative path with out ssvm mount info.
                 uploadEntity.setTemplatePath(absolutePath);
                 String dataStoreUrl = cmd.getDataTo();
-                String installPathPrefix = this.getRootDir(dataStoreUrl) + File.separator + absolutePath;
+                String installPathPrefix = this.getRootDir(dataStoreUrl, null) + File.separator + absolutePath;
                 uploadEntity.setInstallPathPrefix(installPathPrefix);
                 uploadEntity.setHvm(cmd.getRequiresHvm());
                 uploadEntity.setChksum(cmd.getChecksum());
@@ -2669,7 +2694,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
     }
 
     private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
-        String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator;
+        String rootDir = this.getRootDir(cmd.getDataTo(), null) + File.separator;
         long accountId = cmd.getAccountId();
 
         long accountTemplateDirSize = 0;
@@ -2716,7 +2741,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
 
     private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
         String uuid = cmd.getEntityUUID();
-        String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath();
+        String uploadPath = this.getRootDir(cmd.getDataTo(), null) + File.separator + cmd.getAbsolutePath();
         return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists();
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
index 4d3f048..3c24b6c 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
@@ -23,6 +23,6 @@ import com.cloud.resource.ServerResource;
  */
 public interface SecondaryStorageResource extends ServerResource {
 
-    String getRootDir(String cmd);
+    String getRootDir(String cmd, String nfsVersion);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
index 9cf37e5..7829bf6 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -708,7 +708,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
         String installPathPrefix = cmd.getInstallPath();
         // for NFS, we need to get mounted path
         if (dstore instanceof NfsTO) {
-            installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix;
+            installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl(), null) + File.separator + installPathPrefix;
         }
         String user = null;
         String password = null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e524f655/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
index 13ddb35..9da5c53 100644
--- a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
+++ b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
@@ -80,7 +80,7 @@ public class NfsSecondaryStorageResourceTest extends TestCase {
         if (!sampleMount.isEmpty()) {
             s_logger.info("functional test, mount " + sampleMount);
             URI realMntUri = new URI(sampleMount);
-            String mntSubDir = resource.mountUri(realMntUri);
+            String mntSubDir = resource.mountUri(realMntUri, null);
             s_logger.info("functional test, umount " + mntSubDir);
             resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri);
         } else {