Skip to content

Commit 3337f42

Browse files
Rene GloverGLOVER RENEsureshanaparti
authored
Primera pure patches & various small fixes (#10132)
Co-authored-by: GLOVER RENE <[email protected]> Co-authored-by: Suresh Kumar Anaparti <[email protected]>
1 parent c09720a commit 3337f42

File tree

18 files changed

+163
-40
lines changed

18 files changed

+163
-40
lines changed

api/src/main/java/com/cloud/exception/StorageAccessException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
public class StorageAccessException extends RuntimeException {
2727
private static final long serialVersionUID = SerialVersionUID.StorageAccessException;
2828

29-
public StorageAccessException(String message) {
30-
super(message);
29+
public StorageAccessException(String message, Exception causer) {
30+
super(message, causer);
3131
}
3232
}

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,7 +1827,7 @@ private Pair<VolumeVO, DataStore> recreateVolume(VolumeVO vol, VirtualMachinePro
18271827
try {
18281828
volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
18291829
} catch (Exception e) {
1830-
throw new StorageAccessException(String.format("Unable to grant access to the volume [%s] on host [%s].", newVolToString, host));
1830+
throw new StorageAccessException(String.format("Unable to grant access to the volume [%s] on host [%s].", newVolToString, host), e);
18311831
}
18321832
}
18331833

@@ -1867,7 +1867,7 @@ protected void grantVolumeAccessToHostIfNeeded(PrimaryDataStore volumeStore, lon
18671867
try {
18681868
volService.grantAccess(volFactory.getVolume(volumeId), host, volumeStore);
18691869
} catch (Exception e) {
1870-
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
1870+
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host), e);
18711871
}
18721872
}
18731873

@@ -1915,7 +1915,7 @@ public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws Sto
19151915
try {
19161916
volService.grantAccess(volFactory.getVolume(vol.getId()), host, store);
19171917
} catch (Exception e) {
1918-
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
1918+
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host), e);
19191919
}
19201920
} else {
19211921
grantVolumeAccessToHostIfNeeded(store, vol.getId(), host, volToString);

engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
4141
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
4242
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
43+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
4344
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
4445
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
4546
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
@@ -1533,6 +1534,16 @@ private void handleCreateVolumeFromTemplateBothOnStorageSystem(TemplateInfo temp
15331534
verifyFormat(templateInfo.getFormat());
15341535
}
15351536

1537+
// this blurb handles the case where the storage system can clone a volume from a template
1538+
String canCloneVolumeFromTemplate = templateInfo.getDataStore().getDriver().getCapabilities().get("CAN_CLONE_VOLUME_FROM_TEMPLATE");
1539+
if (canCloneVolumeFromTemplate != null && canCloneVolumeFromTemplate.toLowerCase().equals("true")) {
1540+
DataStoreDriver driver = templateInfo.getDataStore().getDriver();
1541+
driver.createAsync(volumeInfo.getDataStore(), volumeInfo, null);
1542+
volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
1543+
driver.copyAsync(templateInfo, volumeInfo, null);
1544+
return;
1545+
}
1546+
15361547
HostVO hostVO = null;
15371548

15381549
final boolean computeClusterSupportsVolumeClone;
@@ -1640,7 +1651,7 @@ else if (volumeInfo.getFormat() == ImageFormat.OVA) {
16401651
errMsg = "Create volume from template failed: " + ex.getMessage();
16411652
}
16421653

1643-
throw new CloudRuntimeException(errMsg);
1654+
throw new CloudRuntimeException(errMsg, ex);
16441655
}
16451656
finally {
16461657
if (copyCmdAnswer == null) {
@@ -2633,7 +2644,7 @@ private void handleCreateTemplateFromManagedVolume(VolumeInfo volumeInfo, Templa
26332644
catch (Exception ex) {
26342645
errMsg = ex.getMessage();
26352646

2636-
throw new CloudRuntimeException(errMsg);
2647+
throw new CloudRuntimeException(errMsg, ex);
26372648
}
26382649
finally {
26392650
if (copyCmdAnswer == null) {

engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, T
10351035
try {
10361036
grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
10371037
} catch (Exception e) {
1038-
throw new StorageAccessException("Unable to grant access to template: " + templateOnPrimary.getId() + " on host: " + destHost.getId());
1038+
throw new StorageAccessException("Unable to grant access to template: " + templateOnPrimary.getId() + " on host: " + destHost.getId(), e);
10391039
}
10401040

10411041
templateOnPrimary.processEvent(Event.CopyingRequested);
@@ -1161,7 +1161,7 @@ private void createManagedVolumeCopyManagedTemplateAsync(VolumeInfo volumeInfo,
11611161
try {
11621162
grantAccess(srcTemplateOnPrimary, destHost, destPrimaryDataStore);
11631163
} catch (Exception e) {
1164-
throw new StorageAccessException("Unable to grant access to src template: " + srcTemplateOnPrimary.getId() + " on host: " + destHost.getId());
1164+
throw new StorageAccessException("Unable to grant access to src template: " + srcTemplateOnPrimary.getId() + " on host: " + destHost.getId(), e);
11651165
}
11661166

11671167
_volumeDetailsDao.addDetail(volumeInfo.getId(), volumeDetailKey, String.valueOf(templatePoolRef.getId()), false);
@@ -1406,7 +1406,7 @@ public TemplateInfo createManagedStorageTemplate(long srcTemplateId, long destDa
14061406
try {
14071407
grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
14081408
} catch (Exception e) {
1409-
throw new StorageAccessException("Unable to grant access to template: " + templateOnPrimary.getId() + " on host: " + destHost.getId());
1409+
throw new StorageAccessException("Unable to grant access to template: " + templateOnPrimary.getId() + " on host: " + destHost.getId(), e);
14101410
}
14111411

14121412
templateOnPrimary.processEvent(Event.CopyingRequested);

framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ public void startBeans() {
7171
with(new WithComponentLifeCycle() {
7272
@Override
7373
public void with(ComponentLifecycle lifecycle) {
74-
lifecycle.start();
74+
try {
75+
lifecycle.start();
76+
} catch (Throwable e) {
77+
log.warn("Unable to start component: " + lifecycle.getName(), e);
78+
}
7579

7680
if (lifecycle instanceof ManagementBean) {
7781
ManagementBean mbean = (ManagementBean)lifecycle;
@@ -115,6 +119,9 @@ public void with(ComponentLifecycle lifecycle) {
115119
} catch (ConfigurationException e) {
116120
log.error("Failed to configure " + lifecycle.getName(), e);
117121
throw new CloudRuntimeException(e);
122+
} catch (Throwable e) {
123+
log.error("Failed to configure " + lifecycle.getName(), e);
124+
throw new CloudRuntimeException(e);
118125
}
119126
}
120127
});

framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/registry/RegistryLifecycle.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,15 @@ public void start() {
108108

109109
while (iter.hasNext()) {
110110
Object next = iter.next();
111-
if (registry.register(next)) {
112-
log.debug("Registered " + next);
113-
} else {
114-
iter.remove();
111+
try {
112+
if (registry.register(next)) {
113+
log.debug("Registered " + next);
114+
} else {
115+
log.warn("Bean registration failed for " + next.toString());
116+
iter.remove();
117+
}
118+
} catch (Throwable e) {
119+
log.warn("Bean registration attempt resulted in an exception for " + next.toString(), e);
115120
}
116121
}
117122
}

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ public String toString() {
184184
guestDef.append("<entry name='manufacturer'>Apache Software Foundation</entry>\n");
185185
guestDef.append("<entry name='product'>CloudStack " + _type.toString() + " Hypervisor</entry>\n");
186186
guestDef.append("<entry name='uuid'>" + _uuid + "</entry>\n");
187+
guestDef.append("<entry name='serial'>" + _uuid + "</entry>\n");
187188
guestDef.append("</system>\n");
188189
guestDef.append("</sysinfo>\n");
189190

@@ -222,7 +223,9 @@ public String toString() {
222223
guestDef.append("<boot dev='" + bo + "'/>\n");
223224
}
224225
}
225-
guestDef.append("<smbios mode='sysinfo'/>\n");
226+
if (_arch == null || !_arch.equals("aarch64")) {
227+
guestDef.append("<smbios mode='sysinfo'/>\n");
228+
}
226229
guestDef.append("</os>\n");
227230
if (iothreads) {
228231
guestDef.append(String.format("<iothreads>%s</iothreads>", NUMBER_OF_IOTHREADS));

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetUnmanagedInstancesCommandWrapper.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ private UnmanagedInstanceTO getUnmanagedInstance(LibvirtComputingResource libvir
124124
instance.setName(domain.getName());
125125

126126
instance.setCpuCores((int) LibvirtComputingResource.countDomainRunningVcpus(domain));
127-
instance.setCpuSpeed(parser.getCpuTuneDef().getShares()/instance.getCpuCores());
127+
128+
if (parser.getCpuTuneDef() != null && instance.getCpuCores() != null) {
129+
instance.setCpuSpeed(parser.getCpuTuneDef().getShares()/instance.getCpuCores());
130+
}
128131

129132
if (parser.getCpuModeDef() != null) {
130133
instance.setCpuCoresPerSocket(parser.getCpuModeDef().getCoresPerSocket());

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,13 @@ public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
273273

274274
String path = derivePath(primaryStore, destData, details);
275275

276-
if (!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details)) {
276+
if (path == null) {
277+
path = destTempl.getUuid();
278+
}
279+
280+
if (path != null && !storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details)) {
277281
s_logger.warn("Failed to connect physical disk at path: " + path + ", in storage pool id: " + primaryStore.getUuid());
282+
return new PrimaryStorageDownloadAnswer("Failed to spool template disk at path: " + path + ", in storage pool id: " + primaryStore.getUuid());
278283
}
279284

280285
primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, path != null ? path : destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
@@ -338,6 +343,7 @@ private String derivePath(PrimaryDataStoreTO primaryStore, DataTO destData, Map<
338343
} else {
339344
path = details != null ? details.get("managedStoreTarget") : null;
340345
}
346+
341347
return path;
342348
}
343349

@@ -418,7 +424,7 @@ public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) {
418424
if (primaryPool.getType() == StoragePoolType.CLVM) {
419425
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
420426
vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
421-
} if (primaryPool.getType() == StoragePoolType.PowerFlex) {
427+
} if (primaryPool.getType() == StoragePoolType.PowerFlex || primaryPool.getType() == StoragePoolType.FiberChannel) {
422428
Map<String, String> details = primaryStore.getDetails();
423429
String path = derivePath(primaryStore, destData, details);
424430

@@ -772,15 +778,19 @@ else if (srcData instanceof SnapshotObjectTO) {
772778

773779
KVMStoragePool secondaryStorage = null;
774780

781+
String path = null;
775782
try {
776783
// look for options indicating an overridden path or IQN. Used when snapshots have to be
777784
// temporarily copied on the manaaged storage device before the actual copy to target object
778785
Map<String, String> details = cmd.getOptions();
779-
String path = details != null ? details.get(DiskTO.PATH) : null;
786+
path = details != null ? details.get(DiskTO.PATH) : null;
780787
if (path == null) {
781788
path = details != null ? details.get(DiskTO.IQN) : null;
782789
if (path == null) {
783-
new CloudRuntimeException("The 'path' or 'iqn' field must be specified.");
790+
path = srcData.getPath();
791+
if (path == null) {
792+
new CloudRuntimeException("The 'path' or 'iqn' field must be specified.");
793+
}
784794
}
785795
}
786796

@@ -843,8 +853,6 @@ else if (srcData instanceof SnapshotObjectTO) {
843853
loc.addFormat(info);
844854
loc.save();
845855

846-
storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
847-
848856
TemplateObjectTO newTemplate = new TemplateObjectTO();
849857

850858
newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
@@ -864,6 +872,10 @@ else if (srcData instanceof SnapshotObjectTO) {
864872

865873
return new CopyCmdAnswer(ex.toString());
866874
} finally {
875+
if (path != null) {
876+
storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
877+
}
878+
867879
if (secondaryStorage != null) {
868880
secondaryStorage.delete();
869881
}
@@ -1039,7 +1051,9 @@ public Answer backupSnapshot(final CopyCommand cmd) {
10391051
command.add(NAME_OPTION, snapshotName);
10401052
command.add("-p", snapshotDestPath);
10411053

1042-
descName = UUID.randomUUID().toString();
1054+
if (isCreatedFromVmSnapshot) {
1055+
descName = UUID.randomUUID().toString();
1056+
}
10431057

10441058
command.add("-t", descName);
10451059
final String result = command.execute();

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/MultipathSCSIAdapterBase.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ private KVMPhysicalDisk getPhysicalDisk(AddressInfo address, KVMStoragePool pool
160160
KVMPhysicalDisk disk = new KVMPhysicalDisk(address.getPath(), address.toString(), pool);
161161
disk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
162162

163+
// validate we have a connection, if not we need to connect first.
164+
if (!isConnected(address.getPath())) {
165+
if (!connectPhysicalDisk(address, pool, null)) {
166+
throw new CloudRuntimeException("Unable to connect to volume " + address.getPath());
167+
}
168+
}
169+
163170
long diskSize = getPhysicalDiskSize(address.getPath());
164171
disk.setSize(diskSize);
165172
disk.setVirtualSize(diskSize);
@@ -197,6 +204,10 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S
197204
// we expect WWN values in the volumePath so need to convert it to an actual physical path
198205
AddressInfo address = this.parseAndValidatePath(volumePath);
199206

207+
return connectPhysicalDisk(address, pool, details);
208+
}
209+
210+
private boolean connectPhysicalDisk(AddressInfo address, KVMStoragePool pool, Map<String, String> details) {
200211
// validate we have a connection id - we can't proceed without that
201212
if (address.getConnectionId() == null) {
202213
LOGGER.error("Unable to connect volume with address [" + address.getPath() + "] of the storage pool: " + pool.getUuid() + " - connection id is not set in provided path");
@@ -508,6 +519,18 @@ boolean waitForDiskToBecomeAvailable(AddressInfo address, KVMStoragePool pool, l
508519
return false;
509520
}
510521

522+
boolean isConnected(String path) {
523+
// run a command to test if this is a binary device at this path
524+
Script blockTest = new Script("/bin/test", LOGGER);
525+
blockTest.add("-b", path);
526+
blockTest.execute();
527+
int rc = blockTest.getExitValue();
528+
if (rc == 0) {
529+
return true;
530+
}
531+
return false;
532+
}
533+
511534
long getPhysicalDiskSize(String diskPath) {
512535
if (StringUtils.isEmpty(diskPath)) {
513536
return 0;

0 commit comments

Comments
 (0)