diff --git a/core/src/main/java/org/apache/cloudstack/diagnostics/CopyToSecondaryStorageCommand.java b/core/src/main/java/org/apache/cloudstack/diagnostics/CopyToSecondaryStorageCommand.java index 8e76aad580f..5cd4991c287 100644 --- a/core/src/main/java/org/apache/cloudstack/diagnostics/CopyToSecondaryStorageCommand.java +++ b/core/src/main/java/org/apache/cloudstack/diagnostics/CopyToSecondaryStorageCommand.java @@ -22,11 +22,13 @@ public class CopyToSecondaryStorageCommand extends StorageSubSystemCommand { private String secondaryStorageUrl; private String systemVmIp; private String fileName; + private String nfsVersion; - public CopyToSecondaryStorageCommand(String secondaryStorageUrl, String systemVmIp, String fileName) { + public CopyToSecondaryStorageCommand(String secondaryStorageUrl, String systemVmIp, String fileName, String nfsVersion) { this.secondaryStorageUrl = secondaryStorageUrl; this.systemVmIp = systemVmIp; this.fileName = fileName; + this.nfsVersion = nfsVersion; } public String getSecondaryStorageUrl() { @@ -41,6 +43,10 @@ public class CopyToSecondaryStorageCommand extends StorageSubSystemCommand { return fileName; } + public String getNfsVersion() { + return nfsVersion; + } + @Override public boolean executeInSequence() { return false; diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java index aea792211dd..6e5c979f111 100755 --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java @@ -18,31 +18,15 @@ */ package org.apache.cloudstack.storage.image; -import java.util.Map; - -import javax.inject.Inject; - -import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; - import com.cloud.capacity.CapacityManager; public abstract class NfsImageStoreDriverImpl extends BaseImageStoreDriverImpl { - @Inject - ImageStoreDetailsDao _imageStoreDetailsDao; - /** - * Retrieve NFS version to be used for imgStoreId store, if provided in image_store_details table - * @param imgStoreId store id - * @return "secstorage.nfs.version" associated value for imgStoreId in image_store_details table if exists, null if not + * Retrieve the NFS version to be used for the imgStoreId store */ - protected String getNfsVersion(long imgStoreId){ - Map imgStoreDetails = _imageStoreDetailsDao.getDetails(imgStoreId); - String nfsVersionKey = CapacityManager.ImageStoreNFSVersion.key(); - if (imgStoreDetails != null && imgStoreDetails.containsKey(nfsVersionKey)){ - return imgStoreDetails.get(nfsVersionKey); - } - return null; + protected String getNfsVersion(long imgStoreId) { + return CapacityManager.ImageStoreNFSVersion.valueIn(imgStoreId); } } diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index a9715765bf7..9348bcaab9f 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1110,8 +1110,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return cdromVBD; } - protected boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String newFolder) { - final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder); + protected boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String newFolder, final String nfsVersion) { + final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder, "nfsVersion", nfsVersion); return result != null; } @@ -1482,8 +1482,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return vm; } - protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String folder) { - final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder); + protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String folder, final String nfsVersion) { + final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder, "nfsVersion", nfsVersion); return details != null && details.equals("1"); } @@ -4102,7 +4102,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected boolean postCreatePrivateTemplate(final Connection conn, final String templatePath, final String tmpltFilename, final String templateName, String templateDescription, String checksum, - final long size, final long virtualSize, final long templateId) { + final long size, final long virtualSize, final long templateId, final String nfsVersion) { if (templateDescription == null) { templateDescription = ""; @@ -4113,7 +4113,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } final String result = callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", templateName, - "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), "templateId", String.valueOf(templateId)); + "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), "templateId", String.valueOf(templateId), "nfsVersion", nfsVersion); boolean success = false; if (result != null && !result.isEmpty()) { @@ -5661,6 +5661,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); String vmIP = cmd.getSystemVmIp(); String diagnosticsZipFile = cmd.getFileName(); + String nfsVersion = cmd.getNfsVersion(); String localDir = null; boolean success; @@ -5671,7 +5672,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe URI uri = new URI(secondaryStorageUrl); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()); - String mountPoint = mountNfs(conn, secondaryStorageMountPath, localDir); + String mountPoint = mountNfs(conn, secondaryStorageMountPath, localDir, nfsVersion); if (org.apache.commons.lang.StringUtils.isBlank(mountPoint)) { return new CopyToSecondaryStorageAnswer(cmd, false, "Could not mount secondary storage " + secondaryStorageMountPath + " on host " + localDir); } @@ -5698,11 +5699,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - private String mountNfs(Connection conn, String remoteDir, String localDir) { + private String mountNfs(Connection conn, String remoteDir, String localDir, String nfsVersion) { if (localDir == null) { localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(remoteDir.getBytes()); } - return callHostPlugin(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", "localDir", localDir, "remoteDir", remoteDir); + return callHostPlugin(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", "localDir", localDir, "remoteDir", remoteDir, "nfsVersion", nfsVersion); } // Unmount secondary storage from host diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java index a035eac30fb..69f60c5f543 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java @@ -916,8 +916,9 @@ public class XenServerStorageProcessor implements StorageProcessor { try { final NfsTO nfsStore = (NfsTO) destStore; final URI uri = new URI(nfsStore.getUrl()); + final String nfsVersion = nfsStore.getNfsVersion(); // Create the volume folder - if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) { + if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath(), nfsVersion)) { throw new InternalErrorException("Failed to create the volume folder."); } @@ -1179,6 +1180,7 @@ public class XenServerStorageProcessor implements StorageProcessor { secondaryStorageUrl = cacheStore.getUrl(); destPath = destData.getPath(); } + String nfsVersion = cacheStore.getNfsVersion(); final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData; final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData; @@ -1235,7 +1237,7 @@ public class XenServerStorageProcessor implements StorageProcessor { if (fullbackup) { // the first snapshot is always a full snapshot - if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder)) { + if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder, nfsVersion)) { details = " Filed to create folder " + folder + " in secondary storage"; s_logger.warn(details); return new CopyCmdAnswer(details); @@ -1349,6 +1351,7 @@ public class XenServerStorageProcessor implements StorageProcessor { final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO(); final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore(); final int wait = cmd.getWait(); + final String nfsVersion = destStore.getNfsVersion(); final String secondaryStoragePoolURL = destStore.getUrl(); final String volumeUUID = volume.getPath(); @@ -1364,7 +1367,7 @@ public class XenServerStorageProcessor implements StorageProcessor { final URI uri = new URI(secondaryStoragePoolURL); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); installPath = template.getPath(); - if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) { + if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath, nfsVersion)) { details = " Filed to create folder " + installPath + " in secondary storage"; s_logger.warn(details); return new CopyCmdAnswer(details); @@ -1391,7 +1394,7 @@ public class XenServerStorageProcessor implements StorageProcessor { final String templatePath = secondaryStorageMountPath + "/" + installPath; result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, - template.getId()); + template.getId(), nfsVersion); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI); } @@ -1411,7 +1414,7 @@ public class XenServerStorageProcessor implements StorageProcessor { hypervisorResource.removeSR(conn, tmpltSR); } if (secondaryStorageMountPath != null) { - hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath); + hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath, nfsVersion); } details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString(); s_logger.error(details, e); @@ -1465,7 +1468,8 @@ public class XenServerStorageProcessor implements StorageProcessor { final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); - if (!hypervisorResource.createSecondaryStorageFolder(conn, destNfsPath, destDir)) { + String destNfsVersion = destStore.getNfsVersion(); + if (!hypervisorResource.createSecondaryStorageFolder(conn, destNfsPath, destDir, destNfsVersion)) { final String details = " Failed to create folder " + destDir + " in secondary storage"; s_logger.warn(details); @@ -1500,7 +1504,7 @@ public class XenServerStorageProcessor implements StorageProcessor { templatePath = templatePath.replaceAll("//", "/"); result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, userSpecifiedTemplateName, null, - physicalSize, virtualSize, templateObjTO.getId()); + physicalSize, virtualSize, templateObjTO.getId(), destNfsVersion); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templateUri); diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java index 7e2c701e51a..a31b597f89b 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java @@ -73,11 +73,11 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { super(resource); } - private void mountNfs(Connection conn, String remoteDir, String localDir) { + private void mountNfs(Connection conn, String remoteDir, String localDir, String nfsVersion) { if (localDir == null) { localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(remoteDir.getBytes()); } - String result = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, "localDir", localDir, "remoteDir", remoteDir); + String result = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, "localDir", localDir, "remoteDir", remoteDir, "nfsVersion", nfsVersion); if (StringUtils.isBlank(result)) { String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir; s_logger.warn(errMsg); @@ -244,9 +244,9 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } } - protected SR createFileSr(Connection conn, String remotePath, String dir) { + protected SR createFileSr(Connection conn, String remotePath, String dir, String nfsVersion) { String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(remotePath.getBytes()); - mountNfs(conn, remotePath, localDir); + mountNfs(conn, remotePath, localDir, nfsVersion); return createFileSR(conn, localDir + "/" + dir); } @@ -269,6 +269,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final String storeUrl = srcImageStore.getUrl(); final URI uri = new URI(storeUrl); String volumePath = srcData.getPath(); + String nfsVersion = srcImageStore.getNfsVersion(); volumePath = StringUtils.stripEnd(volumePath, "/"); @@ -282,7 +283,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { volumeDirectory = volumePath.substring(0, index); } - srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory); + srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory, nfsVersion); final Set setVdis = srcSr.getVDIs(conn); @@ -416,7 +417,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } protected String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path, final String secondaryStorageMountPath, - final String snapshotUuid, String prevBackupUuid, final String prevSnapshotUuid, final Boolean isISCSI, int wait) { + final String snapshotUuid, String prevBackupUuid, final String prevSnapshotUuid, final Boolean isISCSI, int wait, String nfsVersion) { boolean filesrcreated = false; // boolean copied = false; @@ -427,7 +428,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final String remoteDir = secondaryStorageMountPath; try { - ssSR = createFileSr(conn, remoteDir, path); + ssSR = createFileSr(conn, remoteDir, path, nfsVersion); filesrcreated = true; final VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid); @@ -509,6 +510,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { secondaryStorageUrl = cacheStore.getUrl(); destPath = destData.getPath(); } + String nfsVersion = cacheStore != null ? cacheStore.getNfsVersion() : null; final SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData; final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData; @@ -569,7 +571,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { Task task = null; try { final String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()); - mountNfs(conn, secondaryStorageMountPath, localDir); + mountNfs(conn, secondaryStorageMountPath, localDir, nfsVersion); final boolean result = makeDirectory(conn, localDir + "/" + folder); if (!result) { details = " Failed to create folder " + folder + " in secondary storage"; @@ -577,7 +579,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { return new CopyCmdAnswer(details); } - snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder); + snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder, nfsVersion); task = snapshotVdi.copyAsync(conn, snapshotSr, null, null); // poll every 1 seconds , @@ -649,7 +651,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed"); } } else { - final String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, prevSnapshotUuid, isISCSI, wait); + final String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, prevSnapshotUuid, isISCSI, wait, nfsVersion); final String[] tmp = result.split("#"); snapshotBackupUuid = tmp[0]; physicalSize = Long.parseLong(tmp[1]); @@ -695,6 +697,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final String secondaryStoragePoolURL = destStore.getUrl(); final String volumeUUID = volume.getPath(); + final String nfsVersion = destStore.getNfsVersion(); final String userSpecifiedName = template.getName(); @@ -708,7 +711,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final URI uri = new URI(secondaryStoragePoolURL); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); installPath = template.getPath(); - if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) { + if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath, nfsVersion)) { details = " Filed to create folder " + installPath + " in secondary storage"; s_logger.warn(details); return new CopyCmdAnswer(details); @@ -716,7 +719,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final VDI vol = getVDIbyUuid(conn, volumeUUID); // create template SR - tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), installPath); + tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), installPath, nfsVersion); // copy volume to template SR task = vol.copyAsync(conn, tmpltSR, null, null); @@ -736,7 +739,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); // create the template.properties file final String templatePath = secondaryStorageMountPath + "/" + installPath; - result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId()); + result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId(), nfsVersion); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); } @@ -756,7 +759,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { hypervisorResource.removeSR(conn, tmpltSR); } if (secondaryStorageMountPath != null) { - hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath); + hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath, nfsVersion); } details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString(); s_logger.error(details, e); @@ -805,6 +808,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } final NfsTO nfsImageStore = (NfsTO)imageStore; + final String nfsVersion = nfsImageStore.getNfsVersion(); final String primaryStorageNameLabel = pool.getUuid(); final String secondaryStorageUrl = nfsImageStore.getUrl(); final int wait = cmd.getWait(); @@ -851,7 +855,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final String snapshotUuid = getSnapshotUuid(snapshotInstallPath); final URI uri = new URI(secondaryStorageUrl); - srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory); + srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory, nfsVersion); final String[] parents = snapshot.getParents(); final List snapshotChains = new ArrayList(); @@ -940,14 +944,15 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { Task task = null; try { final NfsTO nfsStore = (NfsTO)destStore; + final String nfsVersion = nfsStore.getNfsVersion(); final URI uri = new URI(nfsStore.getUrl()); // Create the volume folder - if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) { + if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath(), nfsVersion)) { throw new InternalErrorException("Failed to create the volume folder."); } // Create a SR for the volume UUID folder - secondaryStorage = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath()); + secondaryStorage = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath(), nfsVersion); // Look up the volume on the source primary storage pool final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); // Copy the volume to secondary storage @@ -992,6 +997,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (srcStore instanceof NfsTO) { final NfsTO nfsStore = (NfsTO)srcStore; + final String nfsVersion = nfsStore.getNfsVersion(); final String volumePath = srcVolume.getPath(); int index = volumePath.lastIndexOf("/"); final String volumeDirectory = volumePath.substring(0, index); @@ -1006,7 +1012,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } catch (final Exception e) { return new CopyCmdAnswer(e.toString()); } - final SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory); + final SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory, nfsVersion); Task task = null; try { final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, @@ -1089,12 +1095,14 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { boolean result = false; try { - srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir); + String srcNfsVersion = srcStore.getNfsVersion(); + srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir, srcNfsVersion); final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); final String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); - mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir); + String destNfsVersion = destStore.getNfsVersion(); + mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir, destNfsVersion); makeDirectory(conn, localDir + "/" + destDir); destSr = createFileSR(conn, localDir + "/" + destDir); @@ -1148,7 +1156,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { templatePath = templatePath.replaceAll("//", "/"); - result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, destObj.getId()); + result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, destObj.getId(), destNfsVersion); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); @@ -1236,7 +1244,8 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); final String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); - mountNfs(conn, destNfsPath, localDir); + String nfsVersion = destStore.getNfsVersion(); + mountNfs(conn, destNfsPath, localDir, nfsVersion); makeDirectory(conn, localDir + "/" + destDir); destSr = createFileSR(conn, localDir + "/" + destDir); @@ -1263,7 +1272,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { templatePath = templatePath.replaceAll("//", "/"); - result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, templateObjTO.getId()); + result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, templateObjTO.getId(), nfsVersion); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); diff --git a/scripts/vm/hypervisor/xenserver/cloud-plugin-storage b/scripts/vm/hypervisor/xenserver/cloud-plugin-storage index 207d4f4800b..bc909474dcb 100644 --- a/scripts/vm/hypervisor/xenserver/cloud-plugin-storage +++ b/scripts/vm/hypervisor/xenserver/cloud-plugin-storage @@ -238,6 +238,8 @@ def umount(localDir): def mountNfsSecondaryStorage(session, args): remoteDir = args['remoteDir'] localDir = args['localDir'] + nfsVersion = args['nfsVersion'] + logging.debug("mountNfsSecondaryStorage with params: " + str(args)) mounted = False f = open("/proc/mounts", 'r') for line in f: @@ -250,6 +252,8 @@ def mountNfsSecondaryStorage(session, args): makedirs(localDir) options = "soft,tcp,timeo=133,retrans=1" + if nfsVersion: + options += ",vers=" + nfsVersion try: cmd = ['mount', '-o', options, remoteDir, localDir] txt = util.pread2(cmd) diff --git a/scripts/vm/hypervisor/xenserver/vmopsSnapshot b/scripts/vm/hypervisor/xenserver/vmopsSnapshot index 6b4693ca62e..b74a8550e05 100755 --- a/scripts/vm/hypervisor/xenserver/vmopsSnapshot +++ b/scripts/vm/hypervisor/xenserver/vmopsSnapshot @@ -68,7 +68,8 @@ def create_secondary_storage_folder(session, args): # Mount the remote resource folder locally remote_mount_path = args["remoteMountPath"] local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) - mount(remote_mount_path, local_mount_path) + nfsVersion = args["nfsVersion"] + mount(remote_mount_path, local_mount_path, nfsVersion) # Create the new folder new_folder = local_mount_path + "/" + args["newFolder"] @@ -104,7 +105,8 @@ def delete_secondary_storage_folder(session, args): # Mount the remote resource folder locally remote_mount_path = args["remoteMountPath"] local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) - mount(remote_mount_path, local_mount_path) + nfsVersion = args["nfsVersion"] + mount(remote_mount_path, local_mount_path, nfsVersion) # Delete the specified folder folder = local_mount_path + "/" + args["folder"] @@ -136,7 +138,8 @@ def post_create_private_template(session, args): # get local template folder templatePath = args["templatePath"] local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) - mount(templatePath, local_mount_path) + nfsVersion = args["nfsVersion"] + mount(templatePath, local_mount_path, nfsVersion) # Retrieve args filename = args["templateFilename"] name = args["templateName"] @@ -307,9 +310,11 @@ def makedirs(path): raise xs_errors.XenError(errMsg) return -def mount(remoteDir, localDir): +def mount(remoteDir, localDir, nfsVersion=None): makedirs(localDir) options = "soft,tcp,timeo=133,retrans=1" + if nfsVersion: + options += ",vers=" + nfsVersion try: cmd = ['mount', '-o', options, remoteDir, localDir] txt = util.pread2(cmd) diff --git a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java index de370b3ae2b..e00d898c1aa 100644 --- a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java @@ -30,6 +30,7 @@ import java.util.regex.Pattern; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.capacity.CapacityManager; import org.apache.cloudstack.api.command.admin.diagnostics.GetDiagnosticsDataCmd; import org.apache.cloudstack.api.command.admin.diagnostics.RunDiagnosticsCmd; import org.apache.cloudstack.diagnostics.fileprocessor.DiagnosticsFilesList; @@ -313,7 +314,8 @@ public class DiagnosticsServiceImpl extends ManagerBase implements PluggableServ } private Pair copyToSecondaryStorageNonVMware(final DataStore store, final String vmControlIp, String fileToCopy, Long vmHostId) { - CopyToSecondaryStorageCommand toSecondaryStorageCommand = new CopyToSecondaryStorageCommand(store.getUri(), vmControlIp, fileToCopy); + String nfsVersion = CapacityManager.ImageStoreNFSVersion.valueIn(store.getId()); + CopyToSecondaryStorageCommand toSecondaryStorageCommand = new CopyToSecondaryStorageCommand(store.getUri(), vmControlIp, fileToCopy, nfsVersion); Answer copyToSecondaryAnswer = agentManager.easySend(vmHostId, toSecondaryStorageCommand); Pair copyAnswer; if (copyToSecondaryAnswer != null) {