Skip to content

Commit 158c97b

Browse files
Fix a problem when reverting a snapshot from a storage pool already deleted.
The fix here is the same one as introduced in master by apache#2402
1 parent 3cddf56 commit 158c97b

5 files changed

Lines changed: 33 additions & 47 deletions

File tree

engine/schema/src/com/cloud/host/dao/HostDao.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@
1919
import java.util.Date;
2020
import java.util.List;
2121

22-
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
23-
2422
import com.cloud.host.Host;
2523
import com.cloud.host.Host.Type;
2624
import com.cloud.host.HostVO;
2725
import com.cloud.host.Status;
2826
import com.cloud.hypervisor.Hypervisor;
27+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
2928
import com.cloud.info.RunningHostCountInfo;
3029
import com.cloud.resource.ResourceState;
3130
import com.cloud.utils.db.GenericDao;
@@ -102,5 +101,14 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
102101

103102
List<HostVO> listByType(Type type);
104103

105-
HostVO findHostToOperateOnSnapshotBasedOnStoragePool(StoragePoolVO storagePoolVO);
104+
/**
105+
* This method will look for a host that is of the same hypervisor and zone as indicated in its parameters.
106+
* <ul>
107+
* <li>We give priority to 'Enabled' hosts, but if no 'Enabled' hosts are found, we use 'Disabled' hosts
108+
* <li>If no host is found, we throw a runtime exception
109+
* </ul>
110+
*
111+
* Side note: this method is currently only used in XenServerGuru; therefore, it was designed to meet XenServer deployment scenarios requirements.
112+
*/
113+
HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervisorType);
106114
}

engine/schema/src/com/cloud/host/dao/HostDaoImpl.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@
2424
import java.util.HashMap;
2525
import java.util.List;
2626
import java.util.Map;
27+
import java.util.Objects;
2728
import java.util.TimeZone;
2829

2930
import javax.annotation.PostConstruct;
3031
import javax.ejb.Local;
3132
import javax.inject.Inject;
3233
import javax.persistence.TableGenerator;
3334

34-
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
35-
import org.apache.commons.lang.StringUtils;
3635
import org.apache.log4j.Logger;
3736
import org.springframework.stereotype.Component;
3837

@@ -50,6 +49,7 @@
5049
import com.cloud.host.Status;
5150
import com.cloud.host.Status.Event;
5251
import com.cloud.hypervisor.Hypervisor;
52+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
5353
import com.cloud.info.RunningHostCountInfo;
5454
import com.cloud.org.Grouping;
5555
import com.cloud.org.Managed;
@@ -1127,44 +1127,43 @@ public List<HostVO> listByType(Host.Type type) {
11271127
return listBy(sc);
11281128
}
11291129

1130-
String sqlFindHostConnectedToStoragePoolToExecuteCommand = "select h.id from storage_pool pool " + " join cluster c on pool.cluster_id = c.id " + " %s "
1131-
+ " join host h on h.data_center_id = c.data_center_id and h.hypervisor_type = c.hypervisor_type"
1132-
+ " where pool.id = ? and h.status = 'Up' and h.type = 'Routing' and resource_state = '%s' " + " ORDER by rand() limit 1 ";
1130+
1131+
String sqlFindHostInZoneToExecuteCommand = "Select id from host "
1132+
+ " where type = 'Routing' and hypervisor_type = ? and data_center_id = ? and status = 'Up' "
1133+
+ " and resource_state = '%s' "
1134+
+ " ORDER by rand() limit 1";
11331135

11341136
@Override
1135-
public HostVO findHostToOperateOnSnapshotBasedOnStoragePool(StoragePoolVO storagePoolVO) {
1137+
public HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervisorType) {
11361138
try (TransactionLegacy tx = TransactionLegacy.currentTxn()) {
1137-
String sql = createSqlFindHostConnectedToStoragePoolToExecuteCommand(storagePoolVO, false);
1138-
ResultSet rs = executeSqlGetResultSetForMethodFindHostToOperateBasedOnStoragePool(storagePoolVO, tx, sql);
1139+
String sql = createSqlFindHostToExecuteCommand(false);
1140+
ResultSet rs = executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(hypervisorType, zoneId, tx, sql);
11391141
if (rs.next()) {
11401142
return findById(rs.getLong("id"));
11411143
}
1142-
sql = createSqlFindHostConnectedToStoragePoolToExecuteCommand(storagePoolVO, true);
1143-
rs = executeSqlGetResultSetForMethodFindHostToOperateBasedOnStoragePool(storagePoolVO, tx, sql);
1144+
sql = createSqlFindHostToExecuteCommand(true);
1145+
rs = executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(hypervisorType, zoneId, tx, sql);
11441146
if (!rs.next()) {
1145-
throw new CloudRuntimeException(String.format("Could not find a host connected to the storage pool [storagepool=%d]. ", storagePoolVO.getId()));
1147+
throw new CloudRuntimeException(String.format("Could not find a host in zone [zoneId=%d] to operate on. ", zoneId));
11461148
}
11471149
return findById(rs.getLong("id"));
11481150
} catch (SQLException e) {
11491151
throw new CloudRuntimeException(e);
11501152
}
11511153
}
11521154

1153-
private ResultSet executeSqlGetResultSetForMethodFindHostToOperateBasedOnStoragePool(StoragePoolVO storagePoolVO, TransactionLegacy tx, String sql) throws SQLException {
1155+
private ResultSet executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(HypervisorType hypervisorType, long zoneId, TransactionLegacy tx, String sql) throws SQLException {
11541156
PreparedStatement pstmt = tx.prepareAutoCloseStatement(sql);
1155-
pstmt.setLong(1, storagePoolVO.getId());
1157+
pstmt.setString(1, Objects.toString(hypervisorType));
1158+
pstmt.setLong(2, zoneId);
11561159
return pstmt.executeQuery();
11571160
}
11581161

1159-
private String createSqlFindHostConnectedToStoragePoolToExecuteCommand(StoragePoolVO storagePoolVO, boolean useDisabledHosts) {
1162+
private String createSqlFindHostToExecuteCommand(boolean useDisabledHosts) {
11601163
String hostResourceStatus = "Enabled";
11611164
if (useDisabledHosts) {
11621165
hostResourceStatus = "Disabled";
11631166
}
1164-
String joinForManagedStorage = StringUtils.EMPTY;
1165-
if (storagePoolVO.isManaged()) {
1166-
joinForManagedStorage = "join cluster_details cd on cd.cluster_id = c.id and cd.name = 'supportsResign' and cd.value = 'true'";
1167-
}
1168-
return String.format(sqlFindHostConnectedToStoragePoolToExecuteCommand, joinForManagedStorage, hostResourceStatus);
1167+
return String.format(sqlFindHostInZoneToExecuteCommand, hostResourceStatus);
11691168
}
11701169
}

engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,4 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
121121
List<StoragePoolVO> findLocalStoragePoolsByHostAndTags(long hostId, String[] tags);
122122

123123
List<StoragePoolVO> listLocalStoragePoolByPath(long datacenterId, String path);
124-
125-
StoragePoolVO findStoragePoolForSnapshot(long snapshotId);
126124
}

engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -525,24 +525,4 @@ public List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterI
525525
sc.and(sc.entity().getHypervisor(), Op.EQ, hypervisorType);
526526
return sc.list();
527527
}
528-
529-
private String sqlIsSnapshotStoragePoolManaged = "select pool.id from snapshots s " + " join volumes v on v.id = s.volume_id " + " join storage_pool pool on pool.id = v.pool_id "
530-
+ " where s.id = ?";
531-
532-
@Override
533-
public StoragePoolVO findStoragePoolForSnapshot(long snapshotId) {
534-
try (TransactionLegacy tx = TransactionLegacy.currentTxn();
535-
PreparedStatement pstmt = tx.prepareAutoCloseStatement(sqlIsSnapshotStoragePoolManaged);) {
536-
pstmt.setLong(1, snapshotId);
537-
ResultSet rs = pstmt.executeQuery();
538-
if (!rs.next()) {
539-
throw new CloudRuntimeException(String.format("Could not find a storage pool for snapshot [snapshotId=%d]. ", snapshotId));
540-
}
541-
long storagePoolId = rs.getLong("id");
542-
return findById(storagePoolId);
543-
} catch (SQLException e) {
544-
throw new CloudRuntimeException(e);
545-
}
546-
}
547-
548528
}

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,11 @@ public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
191191
logger.debug("We are returning the default host to execute commands because the source and destination objects are not snapshot and template respectively.");
192192
return defaultHostToExecuteCommands;
193193
}
194-
long snapshotId = srcData.getId();
195-
StoragePoolVO storagePoolVO = storagePoolDao.findStoragePoolForSnapshot(snapshotId);
196-
HostVO hostCandidateToExecutedCommand = hostDao.findHostToOperateOnSnapshotBasedOnStoragePool(storagePoolVO);
194+
HostVO defaultHostToExecuteCommand = hostDao.findById(hostId);
195+
196+
HostVO hostCandidateToExecutedCommand = hostDao.findHostInZoneToExecuteCommand(defaultHostToExecuteCommand.getDataCenterId(), srcData.getHypervisorType());
197197
hostDao.loadDetails(hostCandidateToExecutedCommand);
198+
198199
String hypervisorVersion = hostCandidateToExecutedCommand.getHypervisorVersion();
199200
if (StringUtils.isBlank(hypervisorVersion)) {
200201
logger.debug("We are returning the default host to execute commands because the hypervisor version is blank.");

0 commit comments

Comments
 (0)