From d835067f40a13aee24862a3d3dc04a710df66bce Mon Sep 17 00:00:00 2001 From: anthony Date: Mon, 16 May 2011 15:44:49 -0700 Subject: [PATCH] multiple secondary storage support template download works creating snapshot works creating volume/template from snapshot works --- core/src/com/cloud/storage/SnapshotVO.java | 4 +-- .../storage/template/DownloadManagerImpl.java | 4 +-- server/src/com/cloud/agent/AgentManager.java | 4 +++ .../cloud/agent/manager/AgentManagerImpl.java | 27 ++++++++++++++++++- .../com/cloud/agent/manager/AgentMonitor.java | 3 ++- .../src/com/cloud/host/dao/HostDaoImpl.java | 14 ++-------- .../src/com/cloud/server/StatsCollector.java | 1 + .../com/cloud/storage/StorageManagerImpl.java | 10 ++++--- .../storage/download/DownloadMonitorImpl.java | 10 +++++-- .../secondary/SecondaryStorageListener.java | 8 ++++-- .../SecondaryStorageManagerImpl.java | 4 ++- .../storage/snapshot/SnapshotManagerImpl.java | 6 ++++- 12 files changed, 67 insertions(+), 28 deletions(-) diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index 287c554d1ef..856fb892e91 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -110,7 +110,7 @@ public class SnapshotVO implements Snapshot { public SnapshotVO() { } - public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType) { + public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType, Long secHostId) { this.dataCenterId = dcId; this.accountId = accountId; this.domainId = domainId; @@ -125,7 +125,7 @@ public class SnapshotVO implements Snapshot { this.prevSnapshotId = 0; this.hypervisorType = hypervisorType; this.version = "2.2"; - this.secHostId = null; + this.secHostId = secHostId; } diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 4a37f6e5100..35021faefec 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -623,13 +623,13 @@ public class DownloadManagerImpl implements DownloadManager { try { if (!loc.load()) { s_logger.warn("Post download installation was not completed for " + path); - loc.purge(); + //loc.purge(); _storage.cleanup(path, templateDir); continue; } } catch (IOException e) { s_logger.warn("Unable to load template location " + path, e); - loc.purge(); + //loc.purge(); try { _storage.cleanup(path, templateDir); } catch (IOException e1) { diff --git a/server/src/com/cloud/agent/AgentManager.java b/server/src/com/cloud/agent/AgentManager.java index ac85a36f189..b0308d0ad00 100755 --- a/server/src/com/cloud/agent/AgentManager.java +++ b/server/src/com/cloud/agent/AgentManager.java @@ -267,4 +267,8 @@ public interface AgentManager extends Manager { long sendToSecStorage(HostVO ssHost, Command cmd, Listener listener); Answer sendToSecStorage(HostVO ssHost, Command cmd); + + HostVO getSSAgent(HostVO ssHost); + + void updateStatus(HostVO host, Event event); } diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 1e06f546353..0fa6aa771b9 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -1007,6 +1007,24 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { } } + + @Override + public HostVO getSSAgent(HostVO ssHost) { + if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) { + return ssHost; + } else if ( ssHost.getType() == Host.Type.SecondaryStorage) { + Long dcId = ssHost.getDataCenterId(); + List ssAHosts = _hostDao.listBy(Host.Type.SecondaryStorageVM, dcId); + if (ssAHosts == null || ssAHosts.isEmpty() ) { + return null; + } + int size = ssAHosts.size(); + Random rn = new Random(System.currentTimeMillis()); + return ssAHosts.get(rn.nextInt(size)); + } + return null; + } + @Override public long sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) { if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) { @@ -1021,7 +1039,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { private long sendToSSVM(final long dcId, final Command cmd, final Listener listener) { - List ssAHosts = _hostDao.listByTypeDataCenter(Host.Type.SecondaryStorageVM, dcId); + List ssAHosts = _hostDao.listBy(Host.Type.SecondaryStorageVM, dcId); if (ssAHosts == null || ssAHosts.isEmpty() ) { return -1; } @@ -1496,6 +1514,10 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { } } + @Override + public void updateStatus(HostVO host, Status.Event event) { + _hostDao.updateStatus(host, event, _nodeId); + } public void disconnect(AgentAttache attache, final Status.Event event, final boolean investigate) { _executor.submit(new DisconnectTask(attache, event, investigate)); } @@ -2810,6 +2832,9 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager { } else if (cmd instanceof StartupProxyCommand) { final StartupProxyCommand startup = (StartupProxyCommand) cmd; answer = new StartupAnswer(startup, attache.getId(), getPingInterval()); + } else if (cmd instanceof StartupSecondaryStorageCommand) { + final StartupSecondaryStorageCommand startup = (StartupSecondaryStorageCommand) cmd; + answer = new StartupAnswer(startup, attache.getId(), getPingInterval()); } else if (cmd instanceof StartupStorageCommand) { final StartupStorageCommand startup = (StartupStorageCommand) cmd; answer = new StartupAnswer(startup, attache.getId(), getPingInterval()); diff --git a/server/src/com/cloud/agent/manager/AgentMonitor.java b/server/src/com/cloud/agent/manager/AgentMonitor.java index cafd8d685c3..04c4a45de21 100755 --- a/server/src/com/cloud/agent/manager/AgentMonitor.java +++ b/server/src/com/cloud/agent/manager/AgentMonitor.java @@ -107,7 +107,8 @@ public class AgentMonitor extends Thread implements Listener { for (HostVO host : hosts) { if (host.getType().equals(Host.Type.ExternalFirewall) || host.getType().equals(Host.Type.ExternalLoadBalancer) || - host.getType().equals(Host.Type.TrafficMonitor)) { + host.getType().equals(Host.Type.TrafficMonitor) || + host.getType().equals(Host.Type.SecondaryStorage)) { continue; } diff --git a/server/src/com/cloud/host/dao/HostDaoImpl.java b/server/src/com/cloud/host/dao/HostDaoImpl.java index 75f11285b12..0be14a7cdea 100644 --- a/server/src/com/cloud/host/dao/HostDaoImpl.java +++ b/server/src/com/cloud/host/dao/HostDaoImpl.java @@ -21,9 +21,11 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.TimeZone; import javax.ejb.Local; @@ -55,8 +57,6 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; -import edu.emory.mathcs.backport.java.util.Collections; - @Local(value = { HostDao.class }) @DB(txn=false) @TableGenerator(name="host_req_sq", table="op_host", pkColumnName="id", valueColumnName="sequence", allocationSize=1) public class HostDaoImpl extends GenericDaoBase implements HostDao { @@ -814,16 +814,6 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao return customSearch(sc, null).get(0); } - @Override - public List listSecondaryStorageHosts(long dataCenterId) { - SearchCriteria sc = TypeDcSearch.create(); - sc.setParameters("type", Host.Type.SecondaryStorage); - sc.setParameters("dc", dataCenterId); - List secondaryStorageHosts = listIncludingRemovedBy(sc); - - return secondaryStorageHosts; - } - @Override public HostVO findTrafficMonitorHost() { SearchCriteria sc = TypeSearch.create(); diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 2059b81aff0..773e71450d8 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -153,6 +153,7 @@ public class StatsCollector { sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ConsoleProxy.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorage.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.TrafficMonitor.toString()); + sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorageVM.toString()); ConcurrentHashMap hostStats = new ConcurrentHashMap(); List hosts = _hostDao.search(sc, null); for (HostVO host : hosts) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 41a7be9338c..923eb94aa61 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -2922,13 +2922,15 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } if (podId != null) { List templHosts = _templateHostDao.listByTemplateStatus(templateId, dcId, podId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - for (VMTemplateHostVO templHost: templHosts) { - return templHost; + if( templHosts != null && ! templHosts.isEmpty()) { + Collections.shuffle(templHosts); + return templHosts.get(0); } } List templHosts = _templateHostDao.listByTemplateStatus(templateId, dcId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - for (VMTemplateHostVO templHost: templHosts) { - return templHost; + if( templHosts != null && ! templHosts.isEmpty()) { + Collections.shuffle(templHosts); + return templHosts.get(0); } return null; } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 56751b7cc66..c9157801111 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -42,6 +42,7 @@ import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenterVO; @@ -304,7 +305,12 @@ public class DownloadMonitorImpl implements DownloadMonitor { if (vmTemplateHost.isCopy()) { dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); } - DownloadListener dl = new DownloadListener(sserver, template, _timer, _vmTemplateHostDao, vmTemplateHost.getId(), this, dcmd); + HostVO ssAhost = _agentMgr.getSSAgent(sserver); + if( ssAhost == null ) { + s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName()); + return; + } + DownloadListener dl = new DownloadListener(ssAhost, template, _timer, _vmTemplateHostDao, vmTemplateHost.getId(), this, dcmd); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, vmTemplateHost.getJobId(), RequestType.GET_OR_RESTART); dl.setCurrState(vmTemplateHost.getDownloadState()); @@ -312,7 +318,7 @@ public class DownloadMonitorImpl implements DownloadMonitor { _listenerMap.put(vmTemplateHost, dl); - long result = _agentMgr.sendToSecStorage(sserver, dcmd, dl); + long result = send(ssAhost.getId(), dcmd, dl); if (result == -1) { s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + sserver.getName()); dl.setDisconnected(); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java index bcc3e9259cf..a2c0b4e5a97 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java @@ -19,6 +19,7 @@ package com.cloud.storage.secondary; import org.apache.log4j.Logger; +import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; import com.cloud.agent.api.AgentControlCommand; @@ -29,15 +30,17 @@ import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.StartupStorageCommand; import com.cloud.host.HostVO; import com.cloud.host.Status; +import com.cloud.host.Status.Event; import com.cloud.storage.Storage; public class SecondaryStorageListener implements Listener { private final static Logger s_logger = Logger.getLogger(SecondaryStorageListener.class); SecondaryStorageVmManager _ssVmMgr = null; - - public SecondaryStorageListener(SecondaryStorageVmManager ssVmMgr) { + AgentManager _agentMgr = null; + public SecondaryStorageListener(SecondaryStorageVmManager ssVmMgr, AgentManager agentMgr) { _ssVmMgr = ssVmMgr; + _agentMgr = agentMgr; } @Override @@ -79,6 +82,7 @@ public class SecondaryStorageListener implements Listener { if(s_logger.isInfoEnabled()) { s_logger.info("Received a host startup notification " + cmd); } + _agentMgr.updateStatus(agent, Event.Ready); _ssVmMgr.onAgentConnect(agent.getDataCenterId(), cmd); _ssVmMgr.generateSetupCommand(agent.getId()); _ssVmMgr.generateFirewallConfiguration(agent.getId()); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 4700af2dfc7..c337eddfac3 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -751,7 +751,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V value = agentMgrConfigs.get("port"); _mgmt_port = NumbersUtil.parseInt(value, 8250); - _listener = new SecondaryStorageListener(this); + _listener = new SecondaryStorageListener(this, _agentMgr); _agentMgr.registerForHostEvents(_listener, true, false, true); _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this); @@ -931,6 +931,8 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } buf.append(" instance=SecStorage"); buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy)); + buf.append(" role=").append(profile.getVirtualMachine().getRole().toString()); + boolean externalDhcp = false; String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled"); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 61bd6e2ae89..5c3876190c9 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -1274,8 +1274,12 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma // user Type snapshotType = getSnapshotType(policyId); HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId); + HostVO ssHost = _hostDao.findSecondaryStorageHost(volume.getDataCenterId()); + if( ssHost == null ) { + throw new CloudRuntimeException("There is no secondary storage in this zone :" + volume.getDataCenterId()); + } SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), null, snapshotName, - (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType); + (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType, ssHost.getId()); SnapshotVO snapshot = _snapshotDao.persist(snapshotVO); if (snapshot != null) {