diff --git a/core/src/com/cloud/host/dao/DetailsDao.java b/core/src/com/cloud/host/dao/DetailsDao.java index 26e17d50902..e398f353887 100644 --- a/core/src/com/cloud/host/dao/DetailsDao.java +++ b/core/src/com/cloud/host/dao/DetailsDao.java @@ -28,4 +28,6 @@ public interface DetailsDao extends GenericDao { void persist(long hostId, Map details); DetailVO findDetail(long hostId, String name); + + void deleteDetails(long hostId); } diff --git a/core/src/com/cloud/host/dao/DetailsDaoImpl.java b/core/src/com/cloud/host/dao/DetailsDaoImpl.java index f4c95e82d11..d1cfe247d66 100644 --- a/core/src/com/cloud/host/dao/DetailsDaoImpl.java +++ b/core/src/com/cloud/host/dao/DetailsDaoImpl.java @@ -66,6 +66,17 @@ public class DetailsDaoImpl extends GenericDaoBase implements De } return details; } + + @Override + public void deleteDetails(long hostId) { + SearchCriteria sc = HostSearch.create(); + sc.setParameters("hostId", hostId); + + List results = search(sc, null); + for (DetailVO result : results) { + remove(result.getId()); + } + } @Override public void persist(long hostId, Map details) { diff --git a/core/src/com/cloud/host/dao/HostDao.java b/core/src/com/cloud/host/dao/HostDao.java index 6bccaa4a4ea..78eeea89bfb 100644 --- a/core/src/com/cloud/host/dao/HostDao.java +++ b/core/src/com/cloud/host/dao/HostDao.java @@ -35,7 +35,7 @@ import com.cloud.utils.db.GenericDao; public interface HostDao extends GenericDao { List listBy(Host.Type type, Long clusterId, Long podId, long dcId); - long countBy(long podId, Status... statuses); + long countBy(long clusterId, Status... statuses); List listByDataCenter(long dcId); List listByHostPod(long podId); diff --git a/core/src/com/cloud/host/dao/HostDaoImpl.java b/core/src/com/cloud/host/dao/HostDaoImpl.java index 01e5c1e173d..47d3134e0b6 100644 --- a/core/src/com/cloud/host/dao/HostDaoImpl.java +++ b/core/src/com/cloud/host/dao/HostDaoImpl.java @@ -77,7 +77,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao protected final SearchBuilder SequenceSearch; protected final SearchBuilder DirectlyConnectedSearch; protected final SearchBuilder UnmanagedDirectConnectSearch; - protected final GenericSearchBuilder MaintenanceCountSearch; + protected final SearchBuilder MaintenanceCountSearch; protected final SearchBuilder ClusterSearch; protected final Attribute _statusAttr; @@ -88,9 +88,8 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao public HostDaoImpl() { - MaintenanceCountSearch = createSearchBuilder(Long.class); - MaintenanceCountSearch.and("pod", MaintenanceCountSearch.entity().getPodId(), SearchCriteria.Op.EQ); - MaintenanceCountSearch.select(null, Func.COUNT, null); + MaintenanceCountSearch = createSearchBuilder(); + MaintenanceCountSearch.and("cluster", MaintenanceCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ); MaintenanceCountSearch.and("status", MaintenanceCountSearch.entity().getStatus(), SearchCriteria.Op.IN); MaintenanceCountSearch.done(); @@ -200,18 +199,14 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao } @Override - public long countBy(long podId, Status... statuses) { - SearchCriteria sc = MaintenanceCountSearch.create(); + public long countBy(long clusterId, Status... statuses) { + SearchCriteria sc = MaintenanceCountSearch.create(); sc.setParameters("status", (Object[])statuses); - sc.setParameters("pod", podId); - - List rs = searchIncludingRemoved(sc, null); - if (rs.size() == 0) { - return 0; - } - - return rs.get(0); + sc.setParameters("cluster", clusterId); + + List hosts = listBy(sc); + return hosts.size(); } @Override diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index a821b386c14..aa25a7b364c 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -2541,15 +2541,19 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR public boolean joinPool(String masterIp, String username, String password) { - Connection slaveConn = null; + Connection hostConn = null; Connection poolConn = null; - Session slaveSession = null; - URL slaveUrl = null; + Session hostSession = null; + URL hostUrl = null; try { // Connect and find out about the new connection to the new pool. poolConn = _connPool.masterConnect(masterIp, username, password); + Set pools = Pool.getAll(poolConn); + Pool pool = pools.iterator().next(); + String poolUUID = pool.getUuid(poolConn); + //check if this host is already in pool Set hosts = Host.getAll(poolConn); for( Host host : hosts ) { @@ -2558,13 +2562,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } - slaveUrl = new URL("http://" + _host.ip); - slaveConn = new Connection(slaveUrl, 100); - slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password); + hostUrl = new URL("http://" + _host.ip); + hostConn = new Connection(hostUrl, 100); + hostSession = Session.loginWithPassword(hostConn, _username, _password, APIVersion.latest().toString()); // Now join it. - Pool.join(slaveConn, masterIp, username, password); + Pool.join(hostConn, masterIp, username, password); if (s_logger.isDebugEnabled()) { s_logger.debug("Joined the pool at " + masterIp); } @@ -2576,12 +2580,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } // check if the master of this host is set correctly. - Connection c = new Connection(slaveUrl, 100); - for (int i = 0; i < 15; i++) { + Connection c = new Connection(hostUrl, 100); + int i; + for (i = 0 ; i < 15; i++) { try { Session.loginWithPassword(c, _username, _password, APIVersion.latest().toString()); - s_logger.debug("Still waiting for the conversion to the master"); + s_logger.debug(_host.ip + " is still master, waiting for the conversion to the slave"); Session.logout(c); c.dispose(); } catch (Types.HostIsSlave e) { @@ -2604,7 +2609,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } catch (InterruptedException e) { } } - + if( i >= 15 ) { + throw new CloudRuntimeException(_host.ip + " didn't change to slave after waiting 30 secondary"); + } + _host.pool = poolUUID; return true; } catch (MalformedURLException e) { throw new CloudRuntimeException("Problem with url " + _host.ip); @@ -2626,9 +2634,9 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } poolConn.dispose(); } - if(slaveSession != null) { + if(hostSession != null) { try { - Session.localLogout(slaveConn); + Session.logout(hostConn); } catch (Exception e) { } } @@ -6166,7 +6174,19 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected Answer execute(PoolEjectCommand cmd) { Connection conn = getConnection(); String hostuuid = cmd.getHostuuid(); + try { + Map hostrs = Host.getAllRecords(conn); + boolean found = false; + for( Host.Record hr : hostrs.values() ) { + if( hr.uuid.equals(hostuuid)) { + found = true; + } + } + if( ! found) { + s_logger.debug("host " + hostuuid + " has already been ejected from pool " + _host.pool); + return new Answer(cmd); + } Host host = Host.getByUuid(conn, hostuuid); // remove all tags cloud stack add before eject Host.Record hr = host.getRecord(conn); diff --git a/core/src/com/cloud/storage/StoragePoolVO.java b/core/src/com/cloud/storage/StoragePoolVO.java index 7d3a8b90724..f15be056f97 100644 --- a/core/src/com/cloud/storage/StoragePoolVO.java +++ b/core/src/com/cloud/storage/StoragePoolVO.java @@ -49,7 +49,7 @@ public class StoragePoolVO implements StoragePool { @Column(name="name", updatable=false, nullable=false, length=255) private String name = null; - @Column(name="uuid", updatable=false, nullable=false, length=255) + @Column(name="uuid", length=255) private String uuid = null; @Column(name="pool_type", updatable=false, nullable=false, length=32) diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 51758b0c32e..f33ba2ee421 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -529,18 +529,24 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { if (host.getType() == Type.Routing && host.getHypervisorType() == HypervisorType.XenServer ) { if (host.getClusterId() != null) { List hosts = _hostDao.listBy(Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId()); + boolean success = false; for( HostVO thost: hosts ) { long thostId = thost.getId(); if( thostId == hostId ) continue; PoolEjectCommand eject = new PoolEjectCommand(host.getGuid()); Answer answer = easySend(thostId, eject); - if( answer == null || !answer.getResult()) { + if( answer != null && answer.getResult()) { + s_logger.debug("Eject Host: " + hostId + " from " + thostId + " Succeed"); + success = true; + break; + } else { s_logger.debug("Eject Host: " + hostId + " from " + thostId + " failed due to " + answer.getDetails()); - continue; } - break; } + if( !success ){ + throw new CloudRuntimeException("Unable to delete host " + hostId + " due to unable to eject it from pool"); + } } } txn.start(); @@ -548,6 +554,10 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null); AgentAttache attache = _agents.get(hostId); handleDisconnect(attache, Status.Event.Remove, false); + + //delete host details + _hostDetailsDao.deleteDetails(hostId); + host.setGuid(null); host.setClusterId(null); _hostDao.update(host.getId(), host); @@ -567,8 +577,14 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { _storagePoolHostDao.deletePrimaryRecordsForHost(hostId); //3.For pool ids you got, delete entries in pool table where type='FileSystem' || 'LVM' - if(!pool_ids.isEmpty()) { - _storagePoolDao.deleteStoragePoolRecords(pool_ids); + for( Long poolId : pool_ids) { + StoragePoolVO storagePool = _storagePoolDao.findById(poolId); + if( storagePool.isLocal()) { + storagePool.setUuid(null); + storagePool.setClusterId(null); + _storagePoolDao.update(poolId, storagePool); + _storagePoolDao.remove(poolId); + } } txn.commit(); return true; diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index e36909bc83d..ab3e7166627 100644 --- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -104,14 +104,38 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password) throws DiscoveryException { Map> resources = new HashMap>(); Connection conn = null; - Connection slaveConn = null; if (!url.getScheme().equals("http")) { String msg = "urlString is not http so we're not taking care of the discovery for this: " + url; s_logger.debug(msg); return null; } - try { + String cluster = null; + if (clusterId == null) { + String msg = "must specify cluster Id when add host"; + s_logger.debug(msg); + throw new RuntimeException(msg); + } else { + cluster = Long.toString(clusterId); + } + + String pod; + if (podId == null) { + String msg = "must specify pod Id when add host"; + s_logger.debug(msg); + throw new RuntimeException(msg); + } else { + pod = Long.toString(podId); + } + try { + String poolUuid = null; + List eHosts = _hostDao.listByCluster(clusterId); + if( eHosts.size() > 0 ) { + HostVO eHost = eHosts.get(0); + _hostDao.loadDetails(eHost); + poolUuid = eHost.getDetail("pool"); + } + String hostname = url.getHost(); InetAddress ia = InetAddress.getByName(hostname); String addr = ia.getHostAddress(); @@ -123,26 +147,14 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L s_logger.debug(msg); return null; } - - String pod; - if (podId == null) { - Map pools = Pool.getAllRecords(conn); - assert pools.size() == 1 : "Pools are not one....where on earth have i been? " + pools.size(); - - pod = pools.values().iterator().next().uuid; - } else { - pod = Long.toString(podId); + if( poolUuid == null ) { + Set pools = Pool.getAll(conn); + Pool pool = pools.iterator().next(); + Pool.Record pr = pool.getRecord(conn); + poolUuid = pr.uuid; } - String cluster = null; - if (clusterId != null) { - cluster = Long.toString(clusterId); - } - Set pools = Pool.getAll(conn); - Pool pool = pools.iterator().next(); - Pool.Record pr = pool.getRecord(conn); - String poolUuid = pr.uuid; + Map hosts = Host.getAllRecords(conn); - Host master = pr.master; if (_checkHvm) { for (Map.Entry entry : hosts.entrySet()) { @@ -195,6 +207,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L params.put("zone", Long.toString(dcId)); params.put("guid", record.uuid); params.put("pod", pod); + params.put("cluster", cluster); if (_increase != null) { params.put(Config.XenPreallocatedLunSizeRange.name(), _increase); @@ -402,6 +415,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L throw new DiscoveryException("Unable to join the pool"); } + return true; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index bf9875cd605..c47f53355ae 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -684,7 +684,7 @@ public class ManagementServerImpl implements ManagementServer { throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID."); } - if (_hostDao.countBy(host.getPodId(), Status.PrepareForMaintenance, Status.ErrorInMaintenance, Status.Maintenance) > 0) { + if (_hostDao.countBy(host.getClusterId(), Status.PrepareForMaintenance, Status.ErrorInMaintenance, Status.Maintenance) > 0) { throw new InvalidParameterValueException("There are other servers in maintenance mode."); }