diff --git a/core/src/com/cloud/agent/api/BackupSnapshotCommand.java b/core/src/com/cloud/agent/api/BackupSnapshotCommand.java
index 2a46610117f8..d93c32f99086 100644
--- a/core/src/com/cloud/agent/api/BackupSnapshotCommand.java
+++ b/core/src/com/cloud/agent/api/BackupSnapshotCommand.java
@@ -39,6 +39,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
private S3TO s3;
StorageFilerTO pool;
private Long secHostId;
+ private String nfsVersion;
protected BackupSnapshotCommand() {
@@ -107,4 +108,12 @@ public Long getSnapshotId() {
public Long getSecHostId() {
return secHostId;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
index 7ac2ddedd2e3..5a09994ab728 100644
--- a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
+++ b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
@@ -28,6 +28,7 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
private String origTemplateInstallPath;
private Long newTemplateId;
private String templateName;
+ private String nfsVersion;
protected CreatePrivateTemplateFromSnapshotCommand() {
@@ -72,4 +73,12 @@ public Long getNewTemplateId() {
public String getTemplateName() {
return templateName;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
index 3025147a3044..b6cc6ac4475a 100644
--- a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
+++ b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
@@ -32,6 +32,7 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
StorageFilerTO _primaryPool;
// For XenServer
private String _secondaryStorageUrl;
+ private String nfsVersion;
public CreatePrivateTemplateFromVolumeCommand() {
}
@@ -99,4 +100,12 @@ public Long getAccountId() {
public void setTemplateId(long templateId) {
_templateId = templateId;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
index fa9a4d584613..933be0360686 100644
--- a/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
+++ b/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
@@ -26,6 +26,8 @@
*/
public class CreateVolumeFromSnapshotCommand extends SnapshotCommand {
+ private String nfsVersion;
+
protected CreateVolumeFromSnapshotCommand() {
}
@@ -50,4 +52,12 @@ public CreateVolumeFromSnapshotCommand(StoragePool pool, String secondaryStorage
super(pool, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
setWait(wait);
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
index 23e8f9e3e55d..84b54264511c 100644
--- a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
+++ b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java
@@ -30,6 +30,7 @@ public class GetStorageStatsCommand extends Command {
private StoragePoolType pooltype;
private String secUrl;
private DataStoreTO store;
+ private String nfsVersion;
public String getSecUrl() {
return secUrl;
@@ -54,6 +55,11 @@ public GetStorageStatsCommand(DataStoreTO store) {
this.store = store;
}
+ public GetStorageStatsCommand(DataStoreTO store, String nfsVersion) {
+ this.store = store;
+ this.nfsVersion = nfsVersion;
+ }
+
public GetStorageStatsCommand(String secUrl) {
this.secUrl = secUrl;
}
@@ -81,6 +87,14 @@ public DataStoreTO getStore() {
return this.store;
}
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
+
@Override
public boolean executeInSequence() {
return false;
diff --git a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java b/core/src/com/cloud/agent/api/SecStorageSetupCommand.java
index 28e55c2f4efc..316e4698dc50 100644
--- a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java
+++ b/core/src/com/cloud/agent/api/SecStorageSetupCommand.java
@@ -28,6 +28,7 @@ public class SecStorageSetupCommand extends Command {
private String secUrl;
private KeystoreManager.Certificates certs;
private String postUploadKey;
+ private String nfsVersion;
public SecStorageSetupCommand() {
@@ -74,4 +75,12 @@ public String getPostUploadKey() {
public void setPostUploadKey(String postUploadKey) {
this.postUploadKey = postUploadKey;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
index 43c84ee2bc0b..7ab822c03bc3 100644
--- a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
+++ b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
@@ -32,6 +32,7 @@ public class CopyVolumeCommand extends Command {
boolean toSecondaryStorage;
String vmName;
boolean executeInSequence = false;
+ String nfsVersion;
public CopyVolumeCommand() {
}
@@ -75,4 +76,12 @@ public boolean toSecondaryStorage() {
public String getVmName() {
return vmName;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java
index 855095280d7d..bacc83aea50a 100644
--- a/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java
+++ b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java
@@ -23,6 +23,7 @@
public class ListTemplateCommand extends StorageCommand {
private DataStoreTO store;
+ private String nfsVersion;
//private String secUrl;
@@ -34,6 +35,11 @@ public ListTemplateCommand(DataStoreTO store) {
// this.secUrl = url;
}
+ public ListTemplateCommand(DataStoreTO store, String nfsVersion) {
+ this.store = store;
+ this.nfsVersion = nfsVersion;
+ }
+
@Override
public boolean executeInSequence() {
return true;
@@ -43,6 +49,10 @@ public DataStoreTO getDataStore() {
return store;
}
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
// public String getSecUrl() {
// return secUrl;
// }
diff --git a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
index ce8ed217a562..9dae513b989b 100644
--- a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
+++ b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
@@ -35,6 +35,7 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
String secondaryStorageUrl;
String primaryStorageUrl;
+ String nfsVersion;
protected PrimaryStorageDownloadCommand() {
}
@@ -87,4 +88,12 @@ public String getPrimaryStorageUrl() {
public boolean executeInSequence() {
return true;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index 5d1e56bd7733..bfcd9ae9b41d 100644
--- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -53,6 +53,8 @@ public class TemplateOrVolumePostUploadCommand {
private long accountId;
+ private String nfsVersion;
+
public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
String dataToRole) {
this.entityId = entityId;
@@ -196,4 +198,12 @@ public void setAccountId(long accountId) {
public long getAccountId() {
return accountId;
}
+
+ public String getNfsVersion() {
+ return nfsVersion;
+ }
+
+ public void setNfsVersion(String nfsVersion) {
+ this.nfsVersion = nfsVersion;
+ }
}
diff --git a/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml b/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml
index db517dbd863d..51be9d99faa8 100644
--- a/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml
+++ b/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml
@@ -29,7 +29,7 @@
+ depends-on="dataObjectManagerImpl, dataStoreManagerImpl, dataMotionServiceImpl, objectInDataStoreManagerImpl, defaultEndPointSelector, templateDataFactoryImpl, imageStoreDetailsUtil" />
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
index 9ab35953711d..a1d10e328077 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -73,6 +73,7 @@
import com.cloud.exception.ResourceAllocationException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ImageStoreDetailsUtil;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StoragePool;
@@ -135,6 +136,8 @@ public class TemplateServiceImpl implements TemplateService {
ConfigurationDao _configDao;
@Inject
StorageCacheManager _cacheMgr;
+ @Inject
+ ImageStoreDetailsUtil imageStoreDetailsUtil;
class TemplateOpContext extends AsyncRpcContext {
final TemplateObject template;
@@ -564,7 +567,7 @@ public void associateCrosszoneTemplatesToZone(long dcId) {
}
private Map listTemplate(DataStore ssStore) {
- ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
+ ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO(), imageStoreDetailsUtil.getNfsVersion(ssStore.getId()));
EndPoint ep = _epSelector.select(ssStore);
Answer answer = null;
if (ep == null) {
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java
index 896342890c82..5c41dcab0ee5 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java
@@ -51,7 +51,7 @@ public MockLocalNfsSecondaryStorageResource() {
}
@Override
- public String getRootDir(String secUrl) {
+ public String getRootDir(String secUrl, String nfsVersion) {
return "/mnt";
}
diff --git a/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml b/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
index 8040d801b3e5..a45e4ee3e40c 100644
--- a/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
+++ b/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
@@ -69,5 +69,7 @@
+
+
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
index 751da9e3d2a3..9b1f091db71b 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 boolean configure(String name, Map params) throws Configu
}
@Override
- public String getRootDir(String url) {
+ public String getRootDir(String url, String nfsVersion) {
// TODO Auto-generated method stub
return null;
}
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 72ee2184e399..65590500a07f 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 params);
@@ -48,7 +48,7 @@ public interface VmwareManager {
String getManagementPortGroupName();
- String getSecondaryStorageStoreUrl(long dcId);
+ Pair getSecondaryStorageStoreUrlAndId(long dcId);
File getSystemVMKeyFile();
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 575801fa6034..f27e938e7334 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
@@ -105,6 +105,7 @@
import com.cloud.org.Cluster.ClusterType;
import com.cloud.secstorage.CommandExecLogDao;
import com.cloud.server.ConfigurationServer;
+import com.cloud.storage.ImageStoreDetailsUtil;
import com.cloud.storage.JavaStorageLayer;
import com.cloud.storage.StorageLayer;
import com.cloud.utils.FileUtil;
@@ -167,6 +168,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
private ManagementServerHostPeerDao _mshostPeerDao;
@Inject
private ClusterManager _clusterMgr;
+ @Inject
+ private ImageStoreDetailsUtil imageStoreDetailsUtil;
private String _mountParent;
private StorageLayer _storage;
@@ -439,12 +442,14 @@ public List addHostToPodCluster(VmwareContext serviceCon
}
@Override
- public String getSecondaryStorageStoreUrl(long dcId) {
+ public Pair 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 String getSecondaryStorageStoreUrl(long dcId) {
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(secUrl, secId);
}
@Override
@@ -546,8 +552,8 @@ public boolean needRecycle(String workerTag) {
}
@Override
- public void prepareSecondaryStorageStore(String storageUrl) {
- String mountPoint = getMountPoint(storageUrl);
+ public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
+ String mountPoint = getMountPoint(storageUrl, imageStoreDetailsUtil.getNfsVersion(storeId));
GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
try {
@@ -655,7 +661,7 @@ public void run() {
}
@Override
- public String getMountPoint(String storageUrl) {
+ public String getMountPoint(String storageUrl, String nfsVersion) {
String mountPoint = null;
synchronized (_storageMounts) {
mountPoint = _storageMounts.get(storageUrl);
@@ -670,7 +676,8 @@ public String getMountPoint(String storageUrl) {
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 +752,7 @@ private void shutdownCleanup() {
}
}
- 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 +763,9 @@ protected String mount(String path, String parent) {
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 +1244,5 @@ public boolean hasNexusVSM(Long clusterId) {
return true;
}
}
+
}
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 4109ff2345b9..c7c53bacba99 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
@@ -92,6 +92,9 @@
import com.cloud.vm.snapshot.VMSnapshot;
public class VmwareStorageManagerImpl implements VmwareStorageManager {
+
+ private String _nfsVersion;
+
@Override
public boolean execute(VmwareHostService hostService, CreateEntityDownloadURLCommand cmd) {
DataTO data = cmd.getData();
@@ -138,6 +141,12 @@ public VmwareStorageManagerImpl(VmwareStorageMount mountService) {
_mountService = mountService;
}
+ public VmwareStorageManagerImpl(VmwareStorageMount mountService, String nfsVersion) {
+ assert (mountService != null);
+ _mountService = mountService;
+ _nfsVersion = nfsVersion;
+ }
+
public void configure(Map params) {
s_logger.info("Configure VmwareStorageManagerImpl");
@@ -156,7 +165,7 @@ public String createOvaForTemplate(TemplateObjectTO template) {
String secStorageUrl = nfsStore.getUrl();
assert (secStorageUrl != null);
String installPath = template.getPath();
- String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, _nfsVersion);
String installFullPath = secondaryMountPoint + "/" + installPath;
try {
if (installFullPath.endsWith(".ova")) {
@@ -194,7 +203,7 @@ public String createOvaForVolume(VolumeObjectTO volume) {
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, _nfsVersion);
//The real volume path
String volumePath = installPath + File.separator + volumeUuid + ".ova";
String installFullPath = secondaryMountPoint + "/" + installPath;
@@ -271,7 +280,8 @@ public Answer execute(VmwareHostService hostService, PrimaryStorageDownloadComma
assert (morDs != null);
DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs);
- copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, mountPoint, templateName, templateUuidName);
+ copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, mountPoint, templateName, templateUuidName,
+ cmd.getNfsVersion());
} else {
s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage");
}
@@ -345,7 +355,7 @@ public Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd)
snapshotBackupUuid =
backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid,
- hostService.getWorkerName(context, cmd, 1));
+ hostService.getWorkerName(context, cmd, 1), cmd.getNfsVersion());
success = (snapshotBackupUuid != null);
if (success) {
@@ -413,7 +423,7 @@ public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVo
Ternary result =
createTemplateFromVolume(vmMo, accountId, templateId, cmd.getUniqueName(), secondaryStoragePoolURL, volumePath,
- hostService.getWorkerName(context, cmd, 0));
+ hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion());
return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), cmd.getUniqueName(), ImageFormat.OVA);
@@ -441,7 +451,8 @@ public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSn
VmwareContext context = hostService.getServiceContext(cmd);
try {
- Ternary result = createTemplateFromSnapshot(accountId, newTemplateId, uniqeName, secondaryStorageUrl, volumeId, backedUpSnapshotUuid);
+ Ternary result = createTemplateFromSnapshot(accountId, newTemplateId, uniqeName, secondaryStorageUrl, volumeId, backedUpSnapshotUuid,
+ cmd.getNfsVersion());
return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), uniqeName, ImageFormat.OVA);
} catch (Throwable e) {
@@ -471,7 +482,7 @@ public Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd) {
if (cmd.toSecondaryStorage()) {
result =
copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, secondaryStorageURL,
- hostService.getWorkerName(context, cmd, 0));
+ hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion());
} else {
StorageFilerTO poolTO = cmd.getPool();
@@ -484,8 +495,9 @@ public Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd) {
}
}
- result = copyVolumeFromSecStorage(hyperHost, volumeId, new DatastoreMO(context, morDatastore), secondaryStorageURL, volumePath);
- deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL);
+ result = copyVolumeFromSecStorage(hyperHost, volumeId, new DatastoreMO(context, morDatastore), secondaryStorageURL, volumePath,
+ cmd.getNfsVersion());
+ deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL, cmd.getNfsVersion());
}
return new CopyVolumeAnswer(cmd, true, null, result.first(), result.second());
} catch (Throwable e) {
@@ -523,7 +535,8 @@ public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCom
}
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
- details = createVolumeFromSnapshot(hyperHost, primaryDsMo, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid);
+ details = createVolumeFromSnapshot(hyperHost, primaryDsMo, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid,
+ cmd.getNfsVersion());
if (details == null) {
success = true;
}
@@ -542,12 +555,12 @@ public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCom
// templateName: name in secondary storage
// templateUuid: will be used at hypervisor layer
private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
- String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception {
+ String templatePathAtSecondaryStorage, String templateName, String templateUuid, String nfsVersion) throws Exception {
s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
templatePathAtSecondaryStorage + ", templateName: " + templateName);
- String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl);
+ String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
String srcOVAFileName = secondaryMountPoint + "/" + templatePathAtSecondaryStorage + templateName + "." + ImageFormat.OVA.getFileExtension();
@@ -598,9 +611,9 @@ private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost,
}
private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, long accountId, long templateId, String templateUniqueName, String secStorageUrl,
- String volumePath, String workerVmName) throws Exception {
+ String volumePath, String workerVmName, String nfsVersion) throws Exception {
- String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
String installFullPath = secondaryMountPoint + "/" + installPath;
synchronized (installPath.intern()) {
@@ -663,9 +676,9 @@ private Ternary createTemplateFromVolume(VirtualMachineMO vm
}
private Ternary createTemplateFromSnapshot(long accountId, long templateId, String templateUniqueName, String secStorageUrl, long volumeId,
- String backedUpSnapshotUuid) throws Exception {
+ String backedUpSnapshotUuid, String nfsVersion) throws Exception {
- String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
String installFullPath = secondaryMountPoint + "/" + installPath;
String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl
@@ -847,16 +860,16 @@ private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename,
}
private String createVolumeFromSnapshot(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, long accountId, long volumeId,
- String secStorageUrl, String snapshotBackupUuid) throws Exception {
+ String secStorageUrl, String snapshotBackupUuid, String nfsVersion) throws Exception {
- restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid);
+ restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid, nfsVersion);
return null;
}
private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
- String backupName) throws Exception {
+ String backupName, String nfsVersion) throws Exception {
- String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension();
String snapshotDir = "";
if (backupName.contains("/")) {
@@ -914,17 +927,17 @@ private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, Datasto
}
private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, long accountId, long volumeId, String volumePath, String snapshotUuid, String secStorageUrl,
- String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception {
+ String prevSnapshotUuid, String prevBackupUuid, String workerVmName, String nfsVersion) throws Exception {
String backupUuid = UUID.randomUUID().toString();
- exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName);
+ exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName, nfsVersion);
return backupUuid + "/" + backupUuid;
}
private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName,
- String workerVmName) throws Exception {
+ String workerVmName, String nfsVersion) throws Exception {
- String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
synchronized (exportPath.intern()) {
@@ -967,7 +980,7 @@ private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volume
}
private Pair copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd, String vmName,
- long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName) throws Exception {
+ long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName, String nfsVersion) throws Exception {
String volumeFolder = String.valueOf(volumeId) + "/";
VirtualMachineMO workerVm = null;
@@ -1004,7 +1017,7 @@ private Pair copyVolumeToSecStorage(VmwareHostService hostServic
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName,
- hostService.getWorkerName(hyperHost.getContext(), cmd, 1));
+ hostService.getWorkerName(hyperHost.getContext(), cmd, 1), nfsVersion);
return new Pair(volumeFolder, exportName);
} finally {
@@ -1025,12 +1038,12 @@ private String getVolumePathInDatastore(DatastoreMO dsMo, String volumeFileName)
return datastoreVolumePath;
}
- private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName)
+ private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName, String nfsVersion)
throws Exception {
String volumeFolder = String.valueOf(volumeId) + "/";
String newVolume = UUID.randomUUID().toString().replaceAll("-", "");
- restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, "volumes/" + volumeFolder, exportName);
+ restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, "volumes/" + volumeFolder, exportName, nfsVersion);
return new Pair(volumeFolder, newVolume);
}
@@ -1445,8 +1458,8 @@ public RevertToVMSnapshotAnswer execute(VmwareHostService hostService, RevertToV
}
}
- private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl) throws Exception {
- String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
+ private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl, String nfsVersion) throws Exception {
+ String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
String volumeMountRoot = secondaryMountPoint + "/" + getVolumeRelativeDirInSecStroage(volumeId);
return deleteDir(volumeMountRoot);
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 dd07029766c4..54b52f6dff4c 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);
}
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 fdbc244997d0..e71425b9488f 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 @@ protected StartAnswer execute(StartCommand cmd) {
// 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 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 @@ protected Answer execute(PrepareForMigrationCommand cmd) {
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
}
- String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
+ Pair 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 @@ protected Answer execute(MigrateWithStorageCommand cmd) {
}
// Ensure secondary storage mounted on target host
- String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId));
+ Pair 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;
@@ -5191,8 +5197,8 @@ else if (value != null && value.equalsIgnoreCase("ide"))
value = (String)params.get("scripts.timeout");
int timeout = NumbersUtil.parseInt(value, 1440) * 1000;
- _storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null);
- storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor);
+ _storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null, (String)params.get("nfsVersion"));
+ storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor, (String)params.get("nfsVersion"));
_vrResource = new VirtualRoutingResource(this);
if (!_vrResource.configure(name, params)) {
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
index 8e4a0d2a83db..1ec4958509bc 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
@@ -102,7 +102,7 @@ public boolean configure(String name, Map params) throws Configu
VmwareSecondaryStorageContextFactory.initFactoryEnvironment();
}
- registerHandler(Hypervisor.HypervisorType.VMware, new VmwareSecondaryStorageResourceHandler(this));
+ registerHandler(Hypervisor.HypervisorType.VMware, new VmwareSecondaryStorageResourceHandler(this, (String)params.get("nfsVersion")));
return true;
}
}
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 8a277991aac6..3c4e6340d31f 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -66,13 +66,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
* private Map _activeHosts = new HashMap();
*/
- public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource) {
+ public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource, String nfsVersion) {
_resource = resource;
- _storageMgr = new VmwareStorageManagerImpl(this);
+ _storageMgr = new VmwareStorageManagerImpl(this, nfsVersion);
_gson = GsonHelper.getGsonLogger();
- VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), null, null, _resource);
- VmwareStorageSubsystemCommandHandler vmwareStorageSubsystemCommandHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor);
+ VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), null, null, _resource, nfsVersion);
+ VmwareStorageSubsystemCommandHandler vmwareStorageSubsystemCommandHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor, nfsVersion);
vmwareStorageSubsystemCommandHandler.setStorageResource(_resource);
vmwareStorageSubsystemCommandHandler.setStorageManager(_storageMgr);
storageSubsystemHandler = vmwareStorageSubsystemCommandHandler;
@@ -304,7 +304,7 @@ public String getWorkerName(VmwareContext context, Command cmd, int workerSequen
}
@Override
- public String getMountPoint(String storageUrl) {
- return _resource.getRootDir(storageUrl);
+ public String getMountPoint(String storageUrl, String nfsVersion) {
+ return _resource.getRootDir(storageUrl, nfsVersion);
}
}
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 fa2f369afaf6..ffa839d4598a 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -109,6 +109,7 @@
import com.cloud.vm.VmDetailConstants;
public class VmwareStorageProcessor implements StorageProcessor {
+
private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
private static final int DEFAULT_NFS_PORT = 2049;
@@ -120,9 +121,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
protected Integer _shutdownWaitMs;
private final Gson _gson;
private final StorageLayer _storage = new JavaStorageLayer();
+ private String _nfsVersion;
public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, Integer timeout, VmwareResource resource,
- Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource) {
+ Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource, String nfsVersion) {
this.hostService = hostService;
_fullCloneFlag = fullCloneFlag;
this.mountService = mountService;
@@ -130,6 +132,7 @@ public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFl
this.resource = resource;
_shutdownWaitMs = shutdownWaitMs;
_gson = GsonHelper.getGsonLogger();
+ _nfsVersion = nfsVersion;
}
@Override
@@ -155,12 +158,12 @@ private String getOVFFilePath(String srcOVAFileName) {
}
private VirtualMachineMO copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
- String templatePathAtSecondaryStorage, String templateName, String templateUuid, boolean createSnapshot) throws Exception {
+ String templatePathAtSecondaryStorage, String templateName, String templateUuid, boolean createSnapshot, String nfsVersion) throws Exception {
s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
templatePathAtSecondaryStorage + ", templateName: " + templateName);
- String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl);
+ String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
String srcOVAFileName =
@@ -316,7 +319,7 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
if (managed) {
VirtualMachineMO vmMo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
- managedStoragePoolRootVolumeName, false);
+ managedStoragePoolRootVolumeName, false, _nfsVersion);
vmMo.unregisterVm();
@@ -333,7 +336,7 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
}
else {
copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
- templateUuidName, true);
+ templateUuidName, true, _nfsVersion);
}
} else {
s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
@@ -518,7 +521,7 @@ public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
}
}
- private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl, long wait) throws Exception {
+ private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl, long wait, String nfsVersion) throws Exception {
String volumeFolder = null;
String volumeName = null;
@@ -533,13 +536,13 @@ private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyper
}
String newVolume = VmwareHelper.getVCenterSafeUuid();
- restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait);
+ restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait, nfsVersion);
return new Pair(volumeFolder, newVolume);
}
- private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl) throws Exception {
- String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+ private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl, String nfsVersion) throws Exception {
+ String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir;
return deleteDir(volumeMountRoot);
@@ -578,8 +581,8 @@ public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
}
}
- Pair result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000);
- deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl());
+ Pair result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000, _nfsVersion);
+ deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl(), _nfsVersion);
VolumeObjectTO newVolume = new VolumeObjectTO();
newVolume.setPath(result.second());
return new CopyCmdAnswer(newVolume);
@@ -636,7 +639,7 @@ private Pair copyVolumeToSecStorage(VmwareHostService hostServic
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
- exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1));
+ exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion);
return new Pair(destVolumePath, exportName);
} finally {
@@ -720,9 +723,9 @@ private void postCreatePrivateTemplate(String installFullPath, long templateId,
}
private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName,
- String secStorageUrl, String volumePath, String workerVmName) throws Exception {
+ String secStorageUrl, String volumePath, String workerVmName, String nfsVersion) throws Exception {
- String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
String installFullPath = secondaryMountPoint + "/" + installPath;
synchronized (installPath.intern()) {
Script command = new Script(false, "mkdir", _timeout, s_logger);
@@ -838,7 +841,7 @@ public Answer createTemplateFromVolume(CopyCommand cmd) {
Ternary result =
createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath,
- hostService.getWorkerName(context, cmd, 0));
+ hostService.getWorkerName(context, cmd, 0), _nfsVersion);
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(result.first());
@@ -885,7 +888,7 @@ private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename,
}
private Ternary createTemplateFromSnapshot(String installPath, String templateUniqueName, String secStorageUrl, String snapshotPath,
- Long templateId, long wait) throws Exception {
+ Long templateId, long wait, String nfsVersion) throws Exception {
//Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid
String backupSSUuid;
String snapshotFolder;
@@ -899,7 +902,7 @@ private Ternary createTemplateFromSnapshot(String installPat
snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length - 1);
}
- String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
String installFullPath = secondaryMountPoint + "/" + installPath;
String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl
String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder;
@@ -1029,7 +1032,7 @@ public Answer createTemplateFromSnapshot(CopyCommand cmd) {
}
NfsTO nfsSvr = (NfsTO)imageStore;
- Ternary result = createTemplateFromSnapshot(template.getPath(), uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(), (long)cmd.getWait() * 1000);
+ Ternary result = createTemplateFromSnapshot(template.getPath(), uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(), (long)cmd.getWait() * 1000, _nfsVersion);
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(result.first());
@@ -1052,9 +1055,9 @@ public Answer createTemplateFromSnapshot(CopyCommand cmd) {
// return Pair
private Pair exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
- String exportName, String workerVmName) throws Exception {
+ String exportName, String workerVmName, String nfsVersion) throws Exception {
- String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
synchronized (exportPath.intern()) {
@@ -1096,10 +1099,10 @@ private Pair exportVolumeToSecondaryStroage(VirtualMachineMO v
// Ternary
private Ternary backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, String volumePath, String snapshotUuid,
- String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception {
+ String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName, String nfsVersion) throws Exception {
String backupUuid = UUID.randomUUID().toString();
- Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName);
+ Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion);
return new Ternary(backupUuid, snapshotInfo.first(), snapshotInfo.second());
}
@@ -1174,7 +1177,7 @@ public Answer backupSnapshot(CopyCommand cmd) {
backupResult =
backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl,
- prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1));
+ prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion);
snapshotBackupUuid = backupResult.first();
success = (snapshotBackupUuid != null);
@@ -1186,7 +1189,7 @@ public Answer backupSnapshot(CopyCommand cmd) {
// Get snapshot physical size
long physicalSize = 0l;
- String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl);
+ String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid;
File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
if(files != null) {
@@ -2144,9 +2147,9 @@ private List getManagedIqnsFromVirtualDisks(List virtualDis
}
private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
- String backupName, long wait) throws Exception {
+ String backupName, long wait, String nfsVersion) throws Exception {
- String secondaryMountPoint = mountService.getMountPoint(secStorageUrl);
+ String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
String srcOVAFileName = null;
String srcOVFFileName = null;
@@ -2248,7 +2251,7 @@ public Answer createVolumeFromSnapshot(CopyCommand cmd) {
backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", "");
}
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
- restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000);
+ restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000, _nfsVersion);
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(newVolumeName);
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 431286248b2d..40fa47b03bb3 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
@@ -21,7 +21,6 @@
import java.io.File;
import org.apache.log4j.Logger;
-
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.DeleteCommand;
@@ -40,9 +39,11 @@
import com.cloud.storage.DataStoreRole;
public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemCommandHandlerBase {
+
private static final Logger s_logger = Logger.getLogger(VmwareStorageSubsystemCommandHandler.class);
private VmwareStorageManager storageManager;
private PremiumSecondaryStorageResource storageResource;
+ private String _nfsVersion;
public PremiumSecondaryStorageResource getStorageResource() {
return storageResource;
@@ -60,8 +61,9 @@ public void setStorageManager(VmwareStorageManager storageManager) {
this.storageManager = storageManager;
}
- public VmwareStorageSubsystemCommandHandler(StorageProcessor processor) {
+ public VmwareStorageSubsystemCommandHandler(StorageProcessor processor, String nfsVersion) {
super(processor);
+ this._nfsVersion = nfsVersion;
}
@Override
@@ -82,7 +84,7 @@ protected Answer execute(CopyCommand cmd) {
//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(), _nfsVersion);
VolumeObjectTO vol = (VolumeObjectTO)srcData;
String path = vol.getPath();
int index = path.lastIndexOf(File.separator);
@@ -95,7 +97,7 @@ protected Answer execute(CopyCommand cmd) {
} 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(), _nfsVersion);
SnapshotObjectTO snap = (SnapshotObjectTO)srcData;
String path = snap.getPath();
int index = path.lastIndexOf(File.separator);
@@ -138,7 +140,7 @@ protected Answer execute(CopyCommand cmd) {
return answer;
}
NfsTO cacheStore = (NfsTO)cmd.getCacheTO().getDataStore();
- String parentPath = storageResource.getRootDir(cacheStore.getUrl());
+ String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion);
SnapshotObjectTO newSnapshot = (SnapshotObjectTO)answer.getNewData();
String path = newSnapshot.getPath();
int index = path.lastIndexOf(File.separator);
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 3b3dd4794991..fec2aba40f64 100644
--- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
@@ -25,18 +25,19 @@
import java.util.UUID;
import javax.inject.Inject;
-import javax.naming.ConfigurationException;
import com.cloud.user.User;
+
import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
@@ -48,12 +49,13 @@
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
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.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
import org.apache.cloudstack.test.utils.SpringUtils;
import com.cloud.agent.AgentManager;
@@ -86,6 +88,7 @@
import com.cloud.org.Managed.ManagedState;
import com.cloud.secstorage.CommandExecLogDao;
import com.cloud.server.ConfigurationServer;
+import com.cloud.storage.ImageStoreDetailsUtil;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountService;
@@ -98,6 +101,7 @@
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+@PrepareForTest({ComponentContext.class, ApplicationContext.class})
public class VmwareDatacenterApiUnitTest {
@Inject
@@ -155,10 +159,6 @@ public class VmwareDatacenterApiUnitTest {
@Mock
private static RemoveVmwareDcCmd removeCmd;
- @BeforeClass
- public static void setUp() throws ConfigurationException {
- }
-
@Before
public void testSetUp() {
Mockito.when(_configDao.isPremium()).thenReturn(true);
@@ -431,6 +431,22 @@ public DataStoreManager dataStoreManager() {
return Mockito.mock(DataStoreManager.class);
}
+ @Bean
+ public ImageStoreDetailsUtil imageStoreDetailsUtil() {
+ return Mockito.mock(ImageStoreDetailsUtil.class);
+ }
+
+ //Mocks for ImageStoreDetailsUtil
+ @Bean
+ public ImageStoreDao imageStoreDao() {
+ return Mockito.mock(ImageStoreDao.class);
+ }
+
+ @Bean
+ public ImageStoreDetailsDao imageStoreDetailsDao() {
+ return Mockito.mock(ImageStoreDetailsDao.class);
+ }
+
public static class Library implements TypeFilter {
@Override
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
index ca86cfd08049..0702335308da 100644
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@ -36,7 +36,6 @@
import org.apache.cloudstack.utils.usage.UsageUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
-
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -90,6 +89,7 @@
import com.cloud.resource.ResourceState;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.ImageStoreDetailsUtil;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StorageStats;
import com.cloud.storage.VolumeStats;
@@ -198,6 +198,8 @@ public String toString() {
private ServiceOfferingDao _serviceOfferingDao;
@Inject
private HostGpuGroupsDao _hostGpuGroupsDao;
+ @Inject
+ private ImageStoreDetailsUtil imageStoreDetailsUtil;
private ConcurrentHashMap _hostStats = new ConcurrentHashMap();
private final ConcurrentHashMap _VmStats = new ConcurrentHashMap();
@@ -715,7 +717,7 @@ protected void runInContext() {
continue;
}
- GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO());
+ GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO(), imageStoreDetailsUtil.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 +764,7 @@ protected void runInContext() {
s_logger.error("Error trying to retrieve storage stats", t);
}
}
+
}
class AutoScaleMonitor extends ManagedContextRunnable {
diff --git a/server/src/com/cloud/storage/ImageStoreDetailsUtil.java b/server/src/com/cloud/storage/ImageStoreDetailsUtil.java
new file mode 100755
index 000000000000..63bd5c54d67d
--- /dev/null
+++ b/server/src/com/cloud/storage/ImageStoreDetailsUtil.java
@@ -0,0 +1,67 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+
+public class ImageStoreDetailsUtil {
+
+ @Inject
+ protected ImageStoreDao imageStoreDao;
+ @Inject
+ protected ImageStoreDetailsDao imageStoreDetailsDao;
+
+ /**
+ * Obtain NFS protocol version (if provided) for a store id.
+ * It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3)
+ * @param storeId image store id
+ * @return {@code null} if {@code nfs.version} is not found for storeId
+ * {@code X} if {@code nfs.version} is found found for storeId
+ */
+ public String getNfsVersion(long storeId) {
+ String nfsVersion = null;
+ if (imageStoreDetailsDao.getDetails(storeId) != null){
+ Map storeDetails = imageStoreDetailsDao.getDetails(storeId);
+ if (storeDetails != null && storeDetails.containsKey("nfs.version")){
+ nfsVersion = storeDetails.get("nfs.version");
+ }
+ }
+ return nfsVersion;
+ }
+
+ /**
+ * Obtain NFS protocol version (if provided) for a store uuid.
+ * It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3)
+ * @param storeId image store id
+ * @return {@code null} if {@code nfs.version} is not found for storeUuid
+ * {@code X} if {@code nfs.version} is found found for storeUuid
+ */
+ public String getNfsVersionByUuid(String storeUuid){
+ ImageStoreVO imageStore = imageStoreDao.findByUuid(storeUuid);
+ if (imageStore != null){
+ return getNfsVersion(imageStore.getId());
+ }
+ return null;
+ }
+
+}
diff --git a/server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java b/server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java
new file mode 100755
index 000000000000..026a7d346d2e
--- /dev/null
+++ b/server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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.junit.Before;
+import org.junit.Test;
+
+public class ImageStoreDetailsUtilTest {
+
+ private final static long STORE_ID = 1l;
+ private final static String STORE_UUID = "aaaa-aaaa-aaaa-aaaa";
+ private final static String NFS_VERSION = "3";
+
+ ImageStoreDetailsUtil imageStoreDetailsUtil = new ImageStoreDetailsUtil();
+
+ ImageStoreDao imgStoreDao = mock(ImageStoreDao.class);
+ ImageStoreDetailsDao imgStoreDetailsDao = mock(ImageStoreDetailsDao.class);
+
+ @Before
+ public void setup() throws Exception {
+ Map imgStoreDetails = new HashMap();
+ imgStoreDetails.put("nfs.version", NFS_VERSION);
+ when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
+
+ ImageStoreVO imgStoreVO = mock(ImageStoreVO.class);
+ when(imgStoreVO.getId()).thenReturn(Long.valueOf(STORE_ID));
+ when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(imgStoreVO);
+
+ imageStoreDetailsUtil.imageStoreDao = imgStoreDao;
+ imageStoreDetailsUtil.imageStoreDetailsDao = imgStoreDetailsDao;
+ }
+
+ @Test
+ public void testGetNfsVersion(){
+ String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
+ assertEquals(NFS_VERSION, nfsVersion);
+ }
+
+ @Test
+ public void testGetNfsVersionNotFound(){
+ Map imgStoreDetails = new HashMap();
+ imgStoreDetails.put("other.prop", "propValue");
+ when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
+
+ String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
+ assertNull(nfsVersion);
+ }
+
+ @Test
+ public void testGetNfsVersionNoDetails(){
+ Map imgStoreDetails = new HashMap();
+ when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
+
+ String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
+ assertNull(nfsVersion);
+ }
+
+ @Test
+ public void testGetNfsVersionByUuid(){
+ String nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID);
+ assertEquals(NFS_VERSION, nfsVersion);
+ }
+
+ @Test
+ public void testGetNfsVersionByUuidNoImgStore(){
+ when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(null);
+ String nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID);
+ assertNull(nfsVersion);
+ }
+}
\ No newline at end of file
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
index 4891b71967ac..2ff54c8dc9a7 100644
--- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
@@ -101,6 +101,7 @@
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.ImageStoreDetailsUtil;
import com.cloud.storage.Storage;
import com.cloud.storage.UploadVO;
import com.cloud.storage.VMTemplateVO;
@@ -239,6 +240,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
TemplateDataStoreDao _tmplStoreDao;
@Inject
VolumeDataStoreDao _volumeStoreDao;
+ @Inject
+ private ImageStoreDetailsUtil imageStoreDetailsUtil;
private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
private int _secStorageVmMtuSize;
@@ -310,6 +313,8 @@ public boolean generateSetupCommand(Long ssHostId) {
setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
}
+ setupCmd.setNfsVersion(imageStoreDetailsUtil.getNfsVersion(ssStore.getId()));
+
//template/volume file upload key
String postUploadKey = _configDao.getValue(Config.SSVMPSK.key());
setupCmd.setPostUploadKey(postUploadKey);
@@ -1046,7 +1051,6 @@ private String getSecStorageVmLockName(long id) {
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
Map details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
vm.setDetails(details);
@@ -1131,6 +1135,8 @@ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, Depl
if (dc.getDns2() != null) {
buf.append(" dns2=").append(dc.getDns2());
}
+ String nfsVersion = imageStoreDetailsUtil != null ? imageStoreDetailsUtil.getNfsVersion(secStore.getId()) : null;
+ buf.append(" nfsVersion=").append(nfsVersion);
String bootArgs = buf.toString();
if (s_logger.isDebugEnabled()) {
@@ -1430,4 +1436,5 @@ public List getSecondaryStorageVmAllocators() {
public void setSecondaryStorageVmAllocators(List ssVmAllocators) {
_ssVmAllocators = ssVmAllocators;
}
+
}
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 9393ee217a10..6f189ef5f3c6 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 Answer executeRequest(Command cmd) {
}
@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 @@ synchronized public String getRootDir(String secUrl) {
}
@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);
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 bdfe7e837f26..d953338c911d 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 void disconnected() {
}
@Override
- public String getRootDir(String url) {
+ public String getRootDir(String url, String nfsVersion) {
return getRootDir();
}
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 768a177cdc52..663699aad2e8 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
@@ -52,6 +52,7 @@
import com.cloud.utils.EncryptionUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
@@ -65,6 +66,7 @@
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
+
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.cloudstack.storage.template.UploadEntity;
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
@@ -161,6 +163,7 @@
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
import com.cloud.vm.SecondaryStorageVm;
+
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
@@ -205,6 +208,7 @@ public void setTimeout(int timeout) {
private String _storageIp;
private String _storageNetmask;
private String _storageGateway;
+ private String _nfsVersion;
private final List nfsIps = new ArrayList();
protected String _parent = "/mnt/SecStorage";
final private String _tmpltpp = "template.properties";
@@ -352,7 +356,7 @@ protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swi
final String storagePath = destImageStore.getUrl();
final String destPath = destData.getPath();
try {
- String downloadPath = determineStorageTemplatePath(storagePath, destPath);
+ String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
final File downloadDirectory = _storage.getFile(downloadPath);
if (downloadDirectory.exists()) {
@@ -379,7 +383,7 @@ protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataT
try {
- String downloadPath = determineStorageTemplatePath(storagePath, destPath);
+ String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
final File downloadDirectory = _storage.getFile(downloadPath);
if (downloadDirectory.exists()) {
@@ -412,7 +416,7 @@ protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataT
protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
NfsTO destDataStore) {
- String srcMountPoint = getRootDir(srcDataStore.getUrl());
+ String srcMountPoint = getRootDir(srcDataStore.getUrl(), _nfsVersion);
String snapshotPath = srcData.getPath();
int index = snapshotPath.lastIndexOf("/");
String snapshotName = snapshotPath.substring(index + 1);
@@ -422,7 +426,7 @@ protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, Sn
snapshotPath = snapshotPath.substring(0, index);
snapshotPath = srcMountPoint + File.separator + snapshotPath;
- String destMountPoint = getRootDir(destDataStore.getUrl());
+ String destMountPoint = getRootDir(destDataStore.getUrl(), _nfsVersion);
String destPath = destMountPoint + File.separator + destData.getPath();
String errMsg = null;
@@ -480,8 +484,8 @@ protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObj
if (srcData.getHypervisorType() == HypervisorType.XenServer) {
return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
} else if (srcData.getHypervisorType() == HypervisorType.KVM) {
- File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
- File destFile = getFile(destData.getPath(), destDataStore.getUrl());
+ File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl(), _nfsVersion);
+ File destFile = getFile(destData.getPath(), destDataStore.getUrl(), _nfsVersion);
VolumeObjectTO volumeObjectTO = srcData.getVolume();
ImageFormat srcFormat = null;
@@ -565,8 +569,8 @@ protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObj
return new CopyCmdAnswer("");
}
- protected File getFile(String path, String nfsPath) {
- String filePath = getRootDir(nfsPath) + File.separator + path;
+ protected File getFile(String path, String nfsPath, String nfsVersion) {
+ String filePath = getRootDir(nfsPath, nfsVersion) + File.separator + path;
File f = new File(filePath);
if (!f.exists()) {
_storage.mkdirs(filePath);
@@ -598,7 +602,7 @@ protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
}
s_logger.debug("starting copy template to swift");
DataTO newTemplate = answer.getNewData();
- File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl());
+ File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl(), _nfsVersion);
SwiftTO swift = (SwiftTO)destDataStore;
String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
@@ -705,8 +709,8 @@ protected Long determineS3VolumeIdFromKey(String key) {
return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
}
- private String determineStorageTemplatePath(final String storagePath, String dataPath) {
- return join(asList(getRootDir(storagePath), dataPath), File.separator);
+ private String determineStorageTemplatePath(final String storagePath, String dataPath, String nfsVersion) {
+ return join(asList(getRootDir(storagePath, nfsVersion), dataPath), File.separator);
}
protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
@@ -720,7 +724,7 @@ protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String n
throw new CloudRuntimeException("Failed to get url: " + url);
}
- String nfsMountPath = getRootDir(nfs.getUrl());
+ String nfsMountPath = getRootDir(nfs.getUrl(), _nfsVersion);
String filePath = nfsMountPath + File.separator + path;
File directory = new File(filePath);
@@ -885,7 +889,7 @@ protected Answer copyFromNfsToS3(CopyCommand cmd) {
final S3TO s3 = (S3TO)destDataStore;
try {
- final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath());
+ final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath(), _nfsVersion);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
@@ -1098,7 +1102,7 @@ public Answer execute(DeleteSnapshotsDirCommand cmd) {
if (dstore instanceof NfsTO) {
NfsTO nfs = (NfsTO)dstore;
String relativeSnapshotPath = cmd.getDirectory();
- String parent = getRootDir(nfs.getUrl());
+ String parent = getRootDir(nfs.getUrl(), _nfsVersion);
if (relativeSnapshotPath.startsWith(File.separator)) {
relativeSnapshotPath = relativeSnapshotPath.substring(1);
@@ -1176,7 +1180,7 @@ private Answer execute(ComputeChecksumCommand cmd) {
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(), _nfsVersion);
if (relativeTemplatePath.startsWith(File.separator)) {
relativeTemplatePath = relativeTemplatePath.substring(1);
@@ -1310,7 +1314,8 @@ private Answer execute(SecStorageSetupCommand cmd) {
String nfsHostIp = getUriHostIp(uri);
addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
- String dir = mountUri(uri);
+
+ String dir = mountUri(uri, cmd.getNfsVersion());
configCerts(cmd.getCerts());
@@ -1386,7 +1391,7 @@ protected Answer deleteSnapshot(final DeleteCommand cmd) {
DataStoreTO dstore = obj.getDataStore();
if (dstore instanceof NfsTO) {
NfsTO nfs = (NfsTO)dstore;
- String parent = getRootDir(nfs.getUrl());
+ String parent = getRootDir(nfs.getUrl(), _nfsVersion);
if (!parent.endsWith(File.separator)) {
parent += File.separator;
}
@@ -1557,7 +1562,7 @@ private Answer execute(ListTemplateCommand cmd) {
if (store instanceof NfsTO) {
NfsTO nfs = (NfsTO)store;
String secUrl = nfs.getUrl();
- String root = getRootDir(secUrl);
+ String root = getRootDir(secUrl, cmd.getNfsVersion());
Map templateInfos = _dlMgr.gatherTemplateInfo(root);
return new ListTemplateAnswer(secUrl, templateInfos);
} else if (store instanceof SwiftTO) {
@@ -1579,7 +1584,7 @@ private Answer execute(ListVolumeCommand cmd) {
}
DataStoreTO store = cmd.getDataStore();
if (store instanceof NfsTO) {
- String root = getRootDir(cmd.getSecUrl());
+ String root = getRootDir(cmd.getSecUrl(), _nfsVersion);
Map templateInfos = _dlMgr.gatherVolumeInfo(root);
return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
} else if (store instanceof S3TO) {
@@ -1714,7 +1719,7 @@ protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
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 +1753,7 @@ protected Answer deleteTemplate(DeleteCommand cmd) {
if (dstore instanceof NfsTO) {
NfsTO nfs = (NfsTO)dstore;
String relativeTemplatePath = obj.getPath();
- String parent = getRootDir(nfs.getUrl());
+ String parent = getRootDir(nfs.getUrl(), _nfsVersion);
if (relativeTemplatePath.startsWith(File.separator)) {
relativeTemplatePath = relativeTemplatePath.substring(1);
@@ -1852,7 +1857,7 @@ protected Answer deleteVolume(final DeleteCommand cmd) {
if (dstore instanceof NfsTO) {
NfsTO nfs = (NfsTO)dstore;
String relativeVolumePath = obj.getPath();
- String parent = getRootDir(nfs.getUrl());
+ String parent = getRootDir(nfs.getUrl(), _nfsVersion);
if (relativeVolumePath.startsWith(File.separator)) {
relativeVolumePath = relativeVolumePath.substring(1);
@@ -1954,13 +1959,13 @@ protected Answer deleteVolume(final DeleteCommand cmd) {
}
@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();
@@ -2117,6 +2122,7 @@ public boolean configure(String name, Map params) throws Configu
startAdditionalServices();
_params.put("install.numthreads", "50");
_params.put("secondary.storage.vm", "true");
+ _nfsVersion = (String)params.get("nfsVersion");
}
try {
@@ -2291,10 +2297,11 @@ private String configureIpFirewall(List ipList, boolean isAppend) {
* @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 +2319,7 @@ protected String mountUri(URI uri) throws UnknownHostException {
s_logger.debug("Mounting device with nfs-style path of " + remoteDevice);
}
- mount(localRootPath, remoteDevice, uri);
+ mount(localRootPath, remoteDevice, uri, nfsVersion);
return dir;
}
@@ -2340,15 +2347,15 @@ protected void umount(String localRootPath, URI uri) {
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 +2363,10 @@ protected void mount(String localRootPath, String remoteDevice, URI uri) {
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 +2378,7 @@ protected void attemptMount(String localRootPath, String remoteDevice, URI uri)
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 +2655,7 @@ public UploadEntity createUploadEntity(String uuid, String metadata, long conten
//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, cmd.getNfsVersion()) + File.separator + absolutePath;
uploadEntity.setInstallPathPrefix(installPathPrefix);
uploadEntity.setHvm(cmd.getRequiresHvm());
uploadEntity.setChksum(cmd.getChecksum());
@@ -2669,7 +2677,7 @@ public UploadEntity createUploadEntity(String uuid, String metadata, long conten
}
private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
- String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator;
+ String rootDir = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator;
long accountId = cmd.getAccountId();
long accountTemplateDirSize = 0;
@@ -2716,7 +2724,7 @@ private String getSnapshotPathForAccount(long accountId) {
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(), cmd.getNfsVersion()) + File.separator + cmd.getAbsolutePath();
return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists();
}
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 4d3f04819e84..3c24b6c6de3e 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 @@
*/
public interface SecondaryStorageResource extends ServerResource {
- String getRootDir(String cmd);
+ String getRootDir(String cmd, String nfsVersion);
}
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 9cf37e56596c..affe8a716a72 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
@@ -89,6 +89,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
StorageLayer _storage;
public Map _processors;
+ private String _nfsVersion;
+
public class Completion implements DownloadCompleteCallback {
private final String jobId;
@@ -708,7 +710,7 @@ public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, D
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(), _nfsVersion) + File.separator + installPathPrefix;
}
String user = null;
String password = null;
@@ -982,6 +984,7 @@ public boolean configure(String name, Map params) throws Configu
String inSystemVM = (String)params.get("secondary.storage.vm");
if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
s_logger.info("DownloadManager: starting additional services since we are inside system vm");
+ _nfsVersion = (String)params.get("nfsVersion");
startAdditionalServices();
blockOutgoingOnPrivate();
}
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 13ddb3531a82..9da5c53a9034 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 void testMount() throws Exception {
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 {