[XenServer/XCP-ng] Pass the image store NFS version on storage commands (#5886)

* Add NFS version to mount command

* Remove extra line

* Extend NFS version to mount secondary storage

* Unused import

* Refactor NFS version to be granular

* Make use of the ConfigKey on the NFS version setting value
This commit is contained in:
Nicolas Vazquez 2022-01-31 03:51:13 -03:00 committed by GitHub
parent 1fc7d70da2
commit 3e92a63155
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 79 additions and 64 deletions

View File

@ -22,11 +22,13 @@ public class CopyToSecondaryStorageCommand extends StorageSubSystemCommand {
private String secondaryStorageUrl; private String secondaryStorageUrl;
private String systemVmIp; private String systemVmIp;
private String fileName; 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.secondaryStorageUrl = secondaryStorageUrl;
this.systemVmIp = systemVmIp; this.systemVmIp = systemVmIp;
this.fileName = fileName; this.fileName = fileName;
this.nfsVersion = nfsVersion;
} }
public String getSecondaryStorageUrl() { public String getSecondaryStorageUrl() {
@ -41,6 +43,10 @@ public class CopyToSecondaryStorageCommand extends StorageSubSystemCommand {
return fileName; return fileName;
} }
public String getNfsVersion() {
return nfsVersion;
}
@Override @Override
public boolean executeInSequence() { public boolean executeInSequence() {
return false; return false;

View File

@ -18,31 +18,15 @@
*/ */
package org.apache.cloudstack.storage.image; 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; import com.cloud.capacity.CapacityManager;
public abstract class NfsImageStoreDriverImpl extends BaseImageStoreDriverImpl { 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 * Retrieve the NFS version to be used for the imgStoreId store
* @param imgStoreId store id
* @return "secstorage.nfs.version" associated value for imgStoreId in image_store_details table if exists, null if not
*/ */
protected String getNfsVersion(long imgStoreId){ protected String getNfsVersion(long imgStoreId) {
Map<String, String> imgStoreDetails = _imageStoreDetailsDao.getDetails(imgStoreId); return CapacityManager.ImageStoreNFSVersion.valueIn(imgStoreId);
String nfsVersionKey = CapacityManager.ImageStoreNFSVersion.key();
if (imgStoreDetails != null && imgStoreDetails.containsKey(nfsVersionKey)){
return imgStoreDetails.get(nfsVersionKey);
}
return null;
} }
} }

View File

@ -1110,8 +1110,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return cdromVBD; return cdromVBD;
} }
protected boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String 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); final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder, "nfsVersion", nfsVersion);
return result != null; return result != null;
} }
@ -1482,8 +1482,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return vm; return vm;
} }
protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String 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); final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder, "nfsVersion", nfsVersion);
return details != null && details.equals("1"); 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, 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) { if (templateDescription == null) {
templateDescription = ""; 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, 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; boolean success = false;
if (result != null && !result.isEmpty()) { if (result != null && !result.isEmpty()) {
@ -5661,6 +5661,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String vmIP = cmd.getSystemVmIp(); String vmIP = cmd.getSystemVmIp();
String diagnosticsZipFile = cmd.getFileName(); String diagnosticsZipFile = cmd.getFileName();
String nfsVersion = cmd.getNfsVersion();
String localDir = null; String localDir = null;
boolean success; boolean success;
@ -5671,7 +5672,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
URI uri = new URI(secondaryStorageUrl); URI uri = new URI(secondaryStorageUrl);
secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()); 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)) { if (org.apache.commons.lang.StringUtils.isBlank(mountPoint)) {
return new CopyToSecondaryStorageAnswer(cmd, false, "Could not mount secondary storage " + secondaryStorageMountPath + " on host " + localDir); 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) { if (localDir == null) {
localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(remoteDir.getBytes()); 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 // Unmount secondary storage from host

View File

@ -916,8 +916,9 @@ public class XenServerStorageProcessor implements StorageProcessor {
try { try {
final NfsTO nfsStore = (NfsTO) destStore; final NfsTO nfsStore = (NfsTO) destStore;
final URI uri = new URI(nfsStore.getUrl()); final URI uri = new URI(nfsStore.getUrl());
final String nfsVersion = nfsStore.getNfsVersion();
// Create the volume folder // 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."); throw new InternalErrorException("Failed to create the volume folder.");
} }
@ -1179,6 +1180,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
secondaryStorageUrl = cacheStore.getUrl(); secondaryStorageUrl = cacheStore.getUrl();
destPath = destData.getPath(); destPath = destData.getPath();
} }
String nfsVersion = cacheStore.getNfsVersion();
final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData; final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData;
final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData; final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData;
@ -1235,7 +1237,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
if (fullbackup) { if (fullbackup) {
// the first snapshot is always a full snapshot // 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"; details = " Filed to create folder " + folder + " in secondary storage";
s_logger.warn(details); s_logger.warn(details);
return new CopyCmdAnswer(details); return new CopyCmdAnswer(details);
@ -1349,6 +1351,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO(); final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO();
final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore(); final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore();
final int wait = cmd.getWait(); final int wait = cmd.getWait();
final String nfsVersion = destStore.getNfsVersion();
final String secondaryStoragePoolURL = destStore.getUrl(); final String secondaryStoragePoolURL = destStore.getUrl();
final String volumeUUID = volume.getPath(); final String volumeUUID = volume.getPath();
@ -1364,7 +1367,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
final URI uri = new URI(secondaryStoragePoolURL); final URI uri = new URI(secondaryStoragePoolURL);
secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
installPath = template.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"; details = " Filed to create folder " + installPath + " in secondary storage";
s_logger.warn(details); s_logger.warn(details);
return new CopyCmdAnswer(details); return new CopyCmdAnswer(details);
@ -1391,7 +1394,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
final String templatePath = secondaryStorageMountPath + "/" + installPath; final String templatePath = secondaryStorageMountPath + "/" + installPath;
result = result =
hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize,
template.getId()); template.getId(), nfsVersion);
if (!result) { if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI); 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); hypervisorResource.removeSR(conn, tmpltSR);
} }
if (secondaryStorageMountPath != null) { 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(); details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
s_logger.error(details, e); s_logger.error(details, e);
@ -1465,7 +1468,8 @@ public class XenServerStorageProcessor implements StorageProcessor {
final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); 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"; final String details = " Failed to create folder " + destDir + " in secondary storage";
s_logger.warn(details); s_logger.warn(details);
@ -1500,7 +1504,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
templatePath = templatePath.replaceAll("//", "/"); templatePath = templatePath.replaceAll("//", "/");
result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, userSpecifiedTemplateName, null, result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, userSpecifiedTemplateName, null,
physicalSize, virtualSize, templateObjTO.getId()); physicalSize, virtualSize, templateObjTO.getId(), destNfsVersion);
if (!result) { if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templateUri); throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templateUri);

View File

@ -73,11 +73,11 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
super(resource); 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) { if (localDir == null) {
localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(remoteDir.getBytes()); 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)) { if (StringUtils.isBlank(result)) {
String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir; String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir;
s_logger.warn(errMsg); 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()); 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); return createFileSR(conn, localDir + "/" + dir);
} }
@ -269,6 +269,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final String storeUrl = srcImageStore.getUrl(); final String storeUrl = srcImageStore.getUrl();
final URI uri = new URI(storeUrl); final URI uri = new URI(storeUrl);
String volumePath = srcData.getPath(); String volumePath = srcData.getPath();
String nfsVersion = srcImageStore.getNfsVersion();
volumePath = StringUtils.stripEnd(volumePath, "/"); volumePath = StringUtils.stripEnd(volumePath, "/");
@ -282,7 +283,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
volumeDirectory = volumePath.substring(0, index); volumeDirectory = volumePath.substring(0, index);
} }
srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory); srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory, nfsVersion);
final Set<VDI> setVdis = srcSr.getVDIs(conn); final Set<VDI> 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, 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 filesrcreated = false;
// boolean copied = false; // boolean copied = false;
@ -427,7 +428,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final String remoteDir = secondaryStorageMountPath; final String remoteDir = secondaryStorageMountPath;
try { try {
ssSR = createFileSr(conn, remoteDir, path); ssSR = createFileSr(conn, remoteDir, path, nfsVersion);
filesrcreated = true; filesrcreated = true;
final VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid); final VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid);
@ -509,6 +510,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
secondaryStorageUrl = cacheStore.getUrl(); secondaryStorageUrl = cacheStore.getUrl();
destPath = destData.getPath(); destPath = destData.getPath();
} }
String nfsVersion = cacheStore != null ? cacheStore.getNfsVersion() : null;
final SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData; final SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData;
final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData; final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData;
@ -569,7 +571,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
Task task = null; Task task = null;
try { try {
final String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()); 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); final boolean result = makeDirectory(conn, localDir + "/" + folder);
if (!result) { if (!result) {
details = " Failed to create folder " + folder + " in secondary storage"; details = " Failed to create folder " + folder + " in secondary storage";
@ -577,7 +579,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
return new CopyCmdAnswer(details); return new CopyCmdAnswer(details);
} }
snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder); snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder, nfsVersion);
task = snapshotVdi.copyAsync(conn, snapshotSr, null, null); task = snapshotVdi.copyAsync(conn, snapshotSr, null, null);
// poll every 1 seconds , // poll every 1 seconds ,
@ -649,7 +651,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed"); throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
} }
} else { } 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("#"); final String[] tmp = result.split("#");
snapshotBackupUuid = tmp[0]; snapshotBackupUuid = tmp[0];
physicalSize = Long.parseLong(tmp[1]); physicalSize = Long.parseLong(tmp[1]);
@ -695,6 +697,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final String secondaryStoragePoolURL = destStore.getUrl(); final String secondaryStoragePoolURL = destStore.getUrl();
final String volumeUUID = volume.getPath(); final String volumeUUID = volume.getPath();
final String nfsVersion = destStore.getNfsVersion();
final String userSpecifiedName = template.getName(); final String userSpecifiedName = template.getName();
@ -708,7 +711,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final URI uri = new URI(secondaryStoragePoolURL); final URI uri = new URI(secondaryStoragePoolURL);
secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
installPath = template.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"; details = " Filed to create folder " + installPath + " in secondary storage";
s_logger.warn(details); s_logger.warn(details);
return new CopyCmdAnswer(details); return new CopyCmdAnswer(details);
@ -716,7 +719,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final VDI vol = getVDIbyUuid(conn, volumeUUID); final VDI vol = getVDIbyUuid(conn, volumeUUID);
// create template SR // 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 // copy volume to template SR
task = vol.copyAsync(conn, tmpltSR, null, null); task = vol.copyAsync(conn, tmpltSR, null, null);
@ -736,7 +739,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
// create the template.properties file // create the template.properties file
final String templatePath = secondaryStorageMountPath + "/" + installPath; 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) { if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); 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); hypervisorResource.removeSR(conn, tmpltSR);
} }
if (secondaryStorageMountPath != null) { 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(); details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
s_logger.error(details, e); s_logger.error(details, e);
@ -805,6 +808,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
} }
final NfsTO nfsImageStore = (NfsTO)imageStore; final NfsTO nfsImageStore = (NfsTO)imageStore;
final String nfsVersion = nfsImageStore.getNfsVersion();
final String primaryStorageNameLabel = pool.getUuid(); final String primaryStorageNameLabel = pool.getUuid();
final String secondaryStorageUrl = nfsImageStore.getUrl(); final String secondaryStorageUrl = nfsImageStore.getUrl();
final int wait = cmd.getWait(); final int wait = cmd.getWait();
@ -851,7 +855,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
final String snapshotUuid = getSnapshotUuid(snapshotInstallPath); final String snapshotUuid = getSnapshotUuid(snapshotInstallPath);
final URI uri = new URI(secondaryStorageUrl); 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 String[] parents = snapshot.getParents();
final List<VDI> snapshotChains = new ArrayList<VDI>(); final List<VDI> snapshotChains = new ArrayList<VDI>();
@ -940,14 +944,15 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
Task task = null; Task task = null;
try { try {
final NfsTO nfsStore = (NfsTO)destStore; final NfsTO nfsStore = (NfsTO)destStore;
final String nfsVersion = nfsStore.getNfsVersion();
final URI uri = new URI(nfsStore.getUrl()); final URI uri = new URI(nfsStore.getUrl());
// Create the volume folder // 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."); throw new InternalErrorException("Failed to create the volume folder.");
} }
// Create a SR for the volume UUID 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 // Look up the volume on the source primary storage pool
final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
// Copy the volume to secondary storage // Copy the volume to secondary storage
@ -992,6 +997,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
if (srcStore instanceof NfsTO) { if (srcStore instanceof NfsTO) {
final NfsTO nfsStore = (NfsTO)srcStore; final NfsTO nfsStore = (NfsTO)srcStore;
final String nfsVersion = nfsStore.getNfsVersion();
final String volumePath = srcVolume.getPath(); final String volumePath = srcVolume.getPath();
int index = volumePath.lastIndexOf("/"); int index = volumePath.lastIndexOf("/");
final String volumeDirectory = volumePath.substring(0, index); final String volumeDirectory = volumePath.substring(0, index);
@ -1006,7 +1012,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
} catch (final Exception e) { } catch (final Exception e) {
return new CopyCmdAnswer(e.toString()); 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; Task task = null;
try { try {
final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn,
@ -1089,12 +1095,14 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
boolean result = false; boolean result = false;
try { 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 destNfsPath = destUri.getHost() + ":" + destUri.getPath();
final String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); 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); makeDirectory(conn, localDir + "/" + destDir);
destSr = createFileSR(conn, localDir + "/" + destDir); destSr = createFileSR(conn, localDir + "/" + destDir);
@ -1148,7 +1156,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
templatePath = templatePath.replaceAll("//", "/"); 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) { if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); 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 destNfsPath = destUri.getHost() + ":" + destUri.getPath();
final String localDir = BASE_MOUNT_POINT_ON_REMOTE + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); 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); makeDirectory(conn, localDir + "/" + destDir);
destSr = createFileSR(conn, localDir + "/" + destDir); destSr = createFileSR(conn, localDir + "/" + destDir);
@ -1263,7 +1272,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
templatePath = templatePath.replaceAll("//", "/"); 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) { if (!result) {
throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");

View File

@ -238,6 +238,8 @@ def umount(localDir):
def mountNfsSecondaryStorage(session, args): def mountNfsSecondaryStorage(session, args):
remoteDir = args['remoteDir'] remoteDir = args['remoteDir']
localDir = args['localDir'] localDir = args['localDir']
nfsVersion = args['nfsVersion']
logging.debug("mountNfsSecondaryStorage with params: " + str(args))
mounted = False mounted = False
f = open("/proc/mounts", 'r') f = open("/proc/mounts", 'r')
for line in f: for line in f:
@ -250,6 +252,8 @@ def mountNfsSecondaryStorage(session, args):
makedirs(localDir) makedirs(localDir)
options = "soft,tcp,timeo=133,retrans=1" options = "soft,tcp,timeo=133,retrans=1"
if nfsVersion:
options += ",vers=" + nfsVersion
try: try:
cmd = ['mount', '-o', options, remoteDir, localDir] cmd = ['mount', '-o', options, remoteDir, localDir]
txt = util.pread2(cmd) txt = util.pread2(cmd)

View File

@ -68,7 +68,8 @@ def create_secondary_storage_folder(session, args):
# Mount the remote resource folder locally # Mount the remote resource folder locally
remote_mount_path = args["remoteMountPath"] remote_mount_path = args["remoteMountPath"]
local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) 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 # Create the new folder
new_folder = local_mount_path + "/" + args["newFolder"] new_folder = local_mount_path + "/" + args["newFolder"]
@ -104,7 +105,8 @@ def delete_secondary_storage_folder(session, args):
# Mount the remote resource folder locally # Mount the remote resource folder locally
remote_mount_path = args["remoteMountPath"] remote_mount_path = args["remoteMountPath"]
local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) 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 # Delete the specified folder
folder = local_mount_path + "/" + args["folder"] folder = local_mount_path + "/" + args["folder"]
@ -136,7 +138,8 @@ def post_create_private_template(session, args):
# get local template folder # get local template folder
templatePath = args["templatePath"] templatePath = args["templatePath"]
local_mount_path = os.path.join(CLOUD_DIR, util.gen_uuid()) 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 # Retrieve args
filename = args["templateFilename"] filename = args["templateFilename"]
name = args["templateName"] name = args["templateName"]
@ -307,9 +310,11 @@ def makedirs(path):
raise xs_errors.XenError(errMsg) raise xs_errors.XenError(errMsg)
return return
def mount(remoteDir, localDir): def mount(remoteDir, localDir, nfsVersion=None):
makedirs(localDir) makedirs(localDir)
options = "soft,tcp,timeo=133,retrans=1" options = "soft,tcp,timeo=133,retrans=1"
if nfsVersion:
options += ",vers=" + nfsVersion
try: try:
cmd = ['mount', '-o', options, remoteDir, localDir] cmd = ['mount', '-o', options, remoteDir, localDir]
txt = util.pread2(cmd) txt = util.pread2(cmd)

View File

@ -30,6 +30,7 @@ import java.util.regex.Pattern;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; 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.GetDiagnosticsDataCmd;
import org.apache.cloudstack.api.command.admin.diagnostics.RunDiagnosticsCmd; import org.apache.cloudstack.api.command.admin.diagnostics.RunDiagnosticsCmd;
import org.apache.cloudstack.diagnostics.fileprocessor.DiagnosticsFilesList; import org.apache.cloudstack.diagnostics.fileprocessor.DiagnosticsFilesList;
@ -313,7 +314,8 @@ public class DiagnosticsServiceImpl extends ManagerBase implements PluggableServ
} }
private Pair<Boolean, String> copyToSecondaryStorageNonVMware(final DataStore store, final String vmControlIp, String fileToCopy, Long vmHostId) { private Pair<Boolean, String> 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); Answer copyToSecondaryAnswer = agentManager.easySend(vmHostId, toSecondaryStorageCommand);
Pair<Boolean, String> copyAnswer; Pair<Boolean, String> copyAnswer;
if (copyToSecondaryAnswer != null) { if (copyToSecondaryAnswer != null) {