Skip to content

Commit 6eecb0b

Browse files
committed
CLOUDSTACK-5017: If SSVM is unavailable DownloadCommands will be routed
to mgmt server.
1 parent c2e2f6c commit 6eecb0b

16 files changed

Lines changed: 369 additions & 198 deletions

File tree

engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.apache.log4j.Logger;
2626
import org.springframework.stereotype.Component;
2727

28-
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
2928
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
3029
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
3130
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
@@ -46,10 +45,6 @@
4645
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
4746
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
4847
import org.apache.cloudstack.storage.command.CopyCommand;
49-
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
50-
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
51-
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
52-
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
5348
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
5449

5550
import com.cloud.agent.api.Answer;
@@ -62,19 +57,11 @@
6257
import com.cloud.agent.api.to.VirtualMachineTO;
6358
import com.cloud.configuration.Config;
6459
import com.cloud.host.Host;
65-
import com.cloud.host.dao.HostDao;
6660
import com.cloud.server.ManagementService;
6761
import com.cloud.storage.DataStoreRole;
68-
import com.cloud.storage.StorageManager;
6962
import com.cloud.storage.StoragePool;
7063
import com.cloud.storage.VolumeVO;
71-
import com.cloud.storage.dao.DiskOfferingDao;
72-
import com.cloud.storage.dao.SnapshotDao;
73-
import com.cloud.storage.dao.VMTemplateDao;
74-
import com.cloud.storage.dao.VMTemplatePoolDao;
7564
import com.cloud.storage.dao.VolumeDao;
76-
import com.cloud.storage.snapshot.SnapshotManager;
77-
import com.cloud.template.TemplateManager;
7865
import com.cloud.utils.NumbersUtil;
7966
import com.cloud.utils.db.DB;
8067
import com.cloud.utils.exception.CloudRuntimeException;
@@ -177,7 +164,13 @@ protected Answer copyObject(DataObject srcData, DataObject destData) {
177164

178165
CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), destData.getTO(), _primaryStorageDownloadWait, _mgmtServer.getExecuteInSequence());
179166
EndPoint ep = selector.select(srcForCopy, destData);
180-
answer = ep.sendMessage(cmd);
167+
if (ep == null) {
168+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
169+
s_logger.error(errMsg);
170+
answer = new Answer(cmd, false, errMsg);
171+
} else {
172+
answer = ep.sendMessage(cmd);
173+
}
181174

182175
if (cacheData != null) {
183176
if (srcData.getType() == DataObjectType.VOLUME && destData.getType() == DataObjectType.VOLUME) {
@@ -255,7 +248,14 @@ protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) {
255248
}
256249

257250
CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait, _mgmtServer.getExecuteInSequence());
258-
Answer answer = ep.sendMessage(cmd);
251+
Answer answer = null;
252+
if (ep == null) {
253+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
254+
s_logger.error(errMsg);
255+
answer = new Answer(cmd, false, errMsg);
256+
} else {
257+
answer = ep.sendMessage(cmd);
258+
}
259259

260260
return answer;
261261
} catch (Exception e) {
@@ -273,7 +273,14 @@ protected Answer cloneVolume(DataObject template, DataObject volume) {
273273
CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0, _mgmtServer.getExecuteInSequence());
274274
try {
275275
EndPoint ep = selector.select(volume.getDataStore());
276-
Answer answer = ep.sendMessage(cmd);
276+
Answer answer = null;
277+
if (ep == null) {
278+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
279+
s_logger.error(errMsg);
280+
answer = new Answer(cmd, false, errMsg);
281+
} else {
282+
answer = ep.sendMessage(cmd);
283+
}
277284
return answer;
278285
} catch (Exception e) {
279286
s_logger.debug("Failed to send to storage pool", e);
@@ -315,7 +322,13 @@ protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData)
315322

316323
CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), destData.getTO(), _copyvolumewait, _mgmtServer.getExecuteInSequence());
317324
EndPoint ep = selector.select(objOnImageStore, destData);
318-
answer = ep.sendMessage(cmd);
325+
if (ep == null) {
326+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
327+
s_logger.error(errMsg);
328+
answer = new Answer(cmd, false, errMsg);
329+
} else {
330+
answer = ep.sendMessage(cmd);
331+
}
319332

320333
if (answer == null || !answer.getResult()) {
321334
if (answer != null) {
@@ -333,7 +346,14 @@ protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData)
333346
DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope);
334347
CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait, _mgmtServer.getExecuteInSequence());
335348
EndPoint ep = selector.select(cacheData, destData);
336-
Answer answer = ep.sendMessage(cmd);
349+
Answer answer = null;
350+
if (ep == null) {
351+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
352+
s_logger.error(errMsg);
353+
answer = new Answer(cmd, false, errMsg);
354+
} else {
355+
answer = ep.sendMessage(cmd);
356+
}
337357
// delete volume on cache store
338358
if (cacheData != null) {
339359
cacheMgr.deleteCacheObject(cacheData);
@@ -348,15 +368,22 @@ protected Answer migrateVolumeToPool(DataObject srcData, DataObject destData) {
348368
StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
349369
MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool);
350370
EndPoint ep = selector.select(volume.getDataStore());
351-
MigrateVolumeAnswer answer = (MigrateVolumeAnswer) ep.sendMessage(command);
371+
Answer answer = null;
372+
if (ep == null) {
373+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
374+
s_logger.error(errMsg);
375+
answer = new Answer(command, false, errMsg);
376+
} else {
377+
answer = ep.sendMessage(command);
378+
}
352379

353380
if (answer == null || !answer.getResult()) {
354381
throw new CloudRuntimeException("Failed to migrate volume " + volume + " to storage pool " + destPool);
355382
} else {
356383
// Update the volume details after migration.
357384
VolumeVO volumeVo = volDao.findById(volume.getId());
358385
Long oldPoolId = volume.getPoolId();
359-
volumeVo.setPath(answer.getVolumePath());
386+
volumeVo.setPath(((MigrateVolumeAnswer)answer).getVolumePath());
360387
volumeVo.setFolder(destPool.getPath());
361388
volumeVo.setPodId(destPool.getPodId());
362389
volumeVo.setPoolId(destPool.getId());
@@ -431,7 +458,14 @@ protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destD
431458
}
432459

433460
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromsnapshotwait, _mgmtServer.getExecuteInSequence());
434-
Answer answer = ep.sendMessage(cmd);
461+
Answer answer = null;
462+
if (ep == null) {
463+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
464+
s_logger.error(errMsg);
465+
answer = new Answer(cmd, false, errMsg);
466+
} else {
467+
answer = ep.sendMessage(cmd);
468+
}
435469

436470
// clean up snapshot copied to staging
437471
if (needCache && srcData != null) {
@@ -455,11 +489,23 @@ protected Answer copySnapshot(DataObject srcData, DataObject destData) {
455489
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, _mgmtServer.getExecuteInSequence());
456490
cmd.setCacheTO(cacheData.getTO());
457491
EndPoint ep = selector.select(srcData, destData);
458-
answer = ep.sendMessage(cmd);
492+
if (ep == null) {
493+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
494+
s_logger.error(errMsg);
495+
answer = new Answer(cmd, false, errMsg);
496+
} else {
497+
answer = ep.sendMessage(cmd);
498+
}
459499
} else {
460500
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, _mgmtServer.getExecuteInSequence());
461501
EndPoint ep = selector.select(srcData, destData);
462-
answer = ep.sendMessage(cmd);
502+
if (ep == null) {
503+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
504+
s_logger.error(errMsg);
505+
answer = new Answer(cmd, false, errMsg);
506+
} else {
507+
answer = ep.sendMessage(cmd);
508+
}
463509
}
464510
// clean up cache entry in case of failure
465511
if (answer == null || !answer.getResult()) {

engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,14 @@ public void handleTemplateSync(DataStore store) {
441441
tmplTO.setId(tInfo.getId());
442442
DeleteCommand dtCommand = new DeleteCommand(tmplTO);
443443
EndPoint ep = _epSelector.select(store);
444-
Answer answer = ep.sendMessage(dtCommand);
444+
Answer answer = null;
445+
if (ep == null) {
446+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
447+
s_logger.error(errMsg);
448+
answer = new Answer(dtCommand, false, errMsg);
449+
} else {
450+
answer = ep.sendMessage(dtCommand);
451+
}
445452
if (answer == null || !answer.getResult()) {
446453
s_logger.info("Failed to deleted template at store: " + store.getName());
447454

@@ -513,7 +520,14 @@ public void associateCrosszoneTemplatesToZone(long dcId){
513520
private Map<String, TemplateProp> listTemplate(DataStore ssStore) {
514521
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
515522
EndPoint ep = _epSelector.select(ssStore);
516-
Answer answer = ep.sendMessage(cmd);
523+
Answer answer = null;
524+
if (ep == null) {
525+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
526+
s_logger.error(errMsg);
527+
answer = new Answer(cmd, false, errMsg);
528+
} else {
529+
answer = ep.sendMessage(cmd);
530+
}
517531
if (answer != null && answer.getResult()) {
518532
ListTemplateAnswer tanswer = (ListTemplateAnswer) answer;
519533
return tanswer.getTemplateInfo();

engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,28 @@
2727

2828
import javax.inject.Inject;
2929

30+
import org.apache.log4j.Logger;
31+
import org.springframework.stereotype.Component;
32+
3033
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
3134
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
3235
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
3336
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
3437
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
38+
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
3539
import org.apache.cloudstack.storage.LocalHostEndpoint;
3640
import org.apache.cloudstack.storage.RemoteHostEndPoint;
37-
import org.apache.log4j.Logger;
38-
import org.springframework.stereotype.Component;
3941

4042
import com.cloud.host.Host;
4143
import com.cloud.host.HostVO;
4244
import com.cloud.host.Status;
4345
import com.cloud.host.dao.HostDao;
4446
import com.cloud.storage.DataStoreRole;
4547
import com.cloud.storage.ScopeType;
48+
import com.cloud.storage.Storage.TemplateType;
4649
import com.cloud.utils.db.DB;
4750
import com.cloud.utils.db.QueryBuilder;
4851
import com.cloud.utils.db.SearchCriteria.Op;
49-
import com.cloud.utils.db.Transaction;
5052
import com.cloud.utils.db.TransactionLegacy;
5153
import com.cloud.utils.exception.CloudRuntimeException;
5254

@@ -209,9 +211,7 @@ protected EndPoint findEndpointForImageStorage(DataStore store) {
209211
// we can arbitrarily pick one ssvm to do that task
210212
List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
211213
if (ssAHosts == null || ssAHosts.isEmpty()) {
212-
s_logger.info("No running ssvm is found, so command will be sent to LocalHostEndPoint");
213-
return LocalHostEndpoint.getEndpoint(); // use local host as endpoint in
214-
// case of no ssvm existing
214+
return null;
215215
}
216216
Collections.shuffle(ssAHosts);
217217
HostVO host = ssAHosts.get(0);
@@ -232,7 +232,16 @@ private List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
232232
@Override
233233
public EndPoint select(DataObject object) {
234234
DataStore store = object.getDataStore();
235-
return select(store);
235+
EndPoint ep = select(store);
236+
if (ep != null)
237+
return ep;
238+
if (object instanceof TemplateInfo) {
239+
TemplateInfo tmplInfo = (TemplateInfo)object;
240+
if (store.getScope().getScopeType() == ScopeType.ZONE && store.getScope().getScopeId() == null && tmplInfo.getTemplateType() == TemplateType.SYSTEM) {
241+
return LocalHostEndpoint.getEndpoint(); // for bootstrap system vm template downloading to region image store
242+
}
243+
}
244+
return null;
236245
}
237246

238247
@Override

engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
import javax.inject.Inject;
2525

26+
import org.apache.log4j.Logger;
27+
2628
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
2729
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
2830
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
@@ -32,7 +34,6 @@
3234
import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
3335
import org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelper;
3436
import org.apache.cloudstack.storage.to.VolumeObjectTO;
35-
import org.apache.log4j.Logger;
3637

3738
import com.cloud.agent.AgentManager;
3839
import com.cloud.agent.api.Answer;
@@ -66,7 +67,14 @@ public class HypervisorHelperImpl implements HypervisorHelper {
6667
public DataTO introduceObject(DataTO object, Scope scope, Long storeId) {
6768
EndPoint ep = selector.select(scope, storeId);
6869
IntroduceObjectCmd cmd = new IntroduceObjectCmd(object);
69-
Answer answer = ep.sendMessage(cmd);
70+
Answer answer = null;
71+
if (ep == null) {
72+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
73+
s_logger.error(errMsg);
74+
answer = new Answer(cmd, false, errMsg);
75+
} else {
76+
answer = ep.sendMessage(cmd);
77+
}
7078
if (answer == null || !answer.getResult()) {
7179
String errMsg = answer == null ? null : answer.getDetails();
7280
throw new CloudRuntimeException("Failed to introduce object, due to " + errMsg);
@@ -79,7 +87,14 @@ public DataTO introduceObject(DataTO object, Scope scope, Long storeId) {
7987
public boolean forgetObject(DataTO object, Scope scope, Long storeId) {
8088
EndPoint ep = selector.select(scope, storeId);
8189
ForgetObjectCmd cmd = new ForgetObjectCmd(object);
82-
Answer answer = ep.sendMessage(cmd);
90+
Answer answer = null;
91+
if (ep == null) {
92+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
93+
s_logger.error(errMsg);
94+
answer = new Answer(cmd, false, errMsg);
95+
} else {
96+
answer = ep.sendMessage(cmd);
97+
}
8398
if (answer == null || !answer.getResult()) {
8499
String errMsg = answer == null ? null : answer.getDetails();
85100
if (errMsg != null) {

engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@
1818
*/
1919
package org.apache.cloudstack.storage.image;
2020

21-
import com.cloud.agent.api.Answer;
22-
import com.cloud.agent.api.storage.DownloadAnswer;
23-
import com.cloud.agent.api.storage.Proxy;
24-
import com.cloud.agent.api.to.DataObjectType;
25-
import com.cloud.agent.api.to.DataTO;
26-
import com.cloud.storage.VMTemplateStorageResourceAssoc;
27-
import com.cloud.storage.VMTemplateVO;
28-
import com.cloud.storage.VolumeVO;
29-
import com.cloud.storage.dao.VMTemplateDao;
30-
import com.cloud.storage.dao.VolumeDao;
31-
import com.cloud.storage.download.DownloadMonitor;
21+
import java.net.URI;
22+
import java.net.URISyntaxException;
23+
import java.util.Date;
24+
25+
import javax.inject.Inject;
26+
27+
import org.apache.log4j.Logger;
3228

3329
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
3430
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
@@ -47,13 +43,17 @@
4743
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
4844
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
4945

50-
import org.apache.log4j.Logger;
51-
52-
import javax.inject.Inject;
53-
54-
import java.net.URI;
55-
import java.net.URISyntaxException;
56-
import java.util.Date;
46+
import com.cloud.agent.api.Answer;
47+
import com.cloud.agent.api.storage.DownloadAnswer;
48+
import com.cloud.agent.api.storage.Proxy;
49+
import com.cloud.agent.api.to.DataObjectType;
50+
import com.cloud.agent.api.to.DataTO;
51+
import com.cloud.storage.VMTemplateStorageResourceAssoc;
52+
import com.cloud.storage.VMTemplateVO;
53+
import com.cloud.storage.VolumeVO;
54+
import com.cloud.storage.dao.VMTemplateDao;
55+
import com.cloud.storage.dao.VolumeDao;
56+
import com.cloud.storage.download.DownloadMonitor;
5757

5858
public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
5959
private static final Logger s_logger = Logger.getLogger(BaseImageStoreDriverImpl.class);
@@ -239,7 +239,14 @@ public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCal
239239
try {
240240
DeleteCommand cmd = new DeleteCommand(data.getTO());
241241
EndPoint ep = _epSelector.select(data);
242-
Answer answer = ep.sendMessage(cmd);
242+
Answer answer = null;
243+
if (ep == null) {
244+
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
245+
s_logger.error(errMsg);
246+
answer = new Answer(cmd, false, errMsg);
247+
} else {
248+
answer = ep.sendMessage(cmd);
249+
}
243250
if (answer != null && !answer.getResult()) {
244251
result.setResult(answer.getDetails());
245252
}

0 commit comments

Comments
 (0)