Skip to content

Commit e297644

Browse files
KVM: Enable HA heartbeat on ShareMountPoint (#12773)
1 parent 2a60305 commit e297644

File tree

9 files changed

+253
-22
lines changed

9 files changed

+253
-22
lines changed

engine/components-api/src/main/java/com/cloud/ha/HighAvailabilityManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.cloud.deploy.DeploymentPlanner;
2222
import com.cloud.host.HostVO;
2323
import com.cloud.host.Status;
24+
import com.cloud.storage.Storage.StoragePoolType;
2425
import com.cloud.utils.component.Manager;
2526
import com.cloud.vm.VMInstanceVO;
2627
import org.apache.cloudstack.framework.config.ConfigKey;
@@ -32,6 +33,8 @@
3233
*/
3334
public interface HighAvailabilityManager extends Manager {
3435

36+
List<StoragePoolType> LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT = List.of(StoragePoolType.NetworkFilesystem, StoragePoolType.SharedMountPoint);
37+
3538
ConfigKey<Boolean> ForceHA = new ConfigKey<>("Advanced", Boolean.class, "force.ha", "false",
3639
"Force High-Availability to happen even if the VM says no.", true, Cluster);
3740

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
public class KVMHABase {
3636
protected Logger logger = LogManager.getLogger(getClass());
3737
private long _timeout = 60000; /* 1 minutes */
38-
protected static String s_heartBeatPath;
3938
protected long _heartBeatUpdateTimeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HEARTBEAT_UPDATE_TIMEOUT);
4039
protected long _heartBeatUpdateFreq = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.KVM_HEARTBEAT_UPDATE_FREQUENCY);
4140
protected long _heartBeatUpdateMaxTries = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.KVM_HEARTBEAT_UPDATE_MAX_TRIES);

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import com.cloud.agent.properties.AgentProperties;
2020
import com.cloud.agent.properties.AgentPropertiesFileHandler;
21-
import com.cloud.storage.Storage.StoragePoolType;
21+
import com.cloud.ha.HighAvailabilityManager;
2222
import com.cloud.utils.script.Script;
2323
import org.libvirt.Connect;
2424
import org.libvirt.LibvirtException;
@@ -39,20 +39,15 @@ public class KVMHAMonitor extends KVMHABase implements Runnable {
3939

4040
private final String hostPrivateIp;
4141

42-
public KVMHAMonitor(HAStoragePool pool, String host, String scriptPath) {
42+
public KVMHAMonitor(HAStoragePool pool, String host) {
4343
if (pool != null) {
4444
storagePool.put(pool.getPoolUUID(), pool);
4545
}
4646
hostPrivateIp = host;
47-
configureHeartBeatPath(scriptPath);
4847

4948
rebootHostAndAlertManagementOnHeartbeatTimeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.REBOOT_HOST_AND_ALERT_MANAGEMENT_ON_HEARTBEAT_TIMEOUT);
5049
}
5150

52-
private static synchronized void configureHeartBeatPath(String scriptPath) {
53-
KVMHABase.s_heartBeatPath = scriptPath;
54-
}
55-
5651
public void addStoragePool(HAStoragePool pool) {
5752
synchronized (storagePool) {
5853
storagePool.put(pool.getPoolUUID(), pool);
@@ -86,8 +81,8 @@ protected void runHeartBeat() {
8681
Set<String> removedPools = new HashSet<>();
8782
for (String uuid : storagePool.keySet()) {
8883
HAStoragePool primaryStoragePool = storagePool.get(uuid);
89-
if (primaryStoragePool.getPool().getType() == StoragePoolType.NetworkFilesystem) {
90-
checkForNotExistingPools(removedPools, uuid);
84+
if (HighAvailabilityManager.LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT.contains(primaryStoragePool.getPool().getType())) {
85+
checkForNotExistingLibvirtStoragePools(removedPools, uuid);
9186
if (removedPools.contains(uuid)) {
9287
continue;
9388
}
@@ -127,7 +122,7 @@ private String executePoolHeartBeatCommand(String uuid, HAStoragePool primarySto
127122
return result;
128123
}
129124

130-
private void checkForNotExistingPools(Set<String> removedPools, String uuid) {
125+
private void checkForNotExistingLibvirtStoragePools(Set<String> removedPools, String uuid) {
131126
try {
132127
Connect conn = LibvirtConnection.getConnection();
133128
StoragePool storage = conn.storagePoolLookupByUUIDString(uuid);

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,11 +1063,6 @@ public boolean configure(final String name, final Map<String, Object> params) th
10631063
throw new ConfigurationException("Unable to find patch.sh");
10641064
}
10651065

1066-
heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
1067-
if (heartBeatPath == null) {
1068-
throw new ConfigurationException("Unable to find kvmheartbeat.sh");
1069-
}
1070-
10711066
createVmPath = Script.findScript(storageScriptsDir, "createvm.sh");
10721067
if (createVmPath == null) {
10731068
throw new ConfigurationException("Unable to find the createvm.sh");
@@ -1330,7 +1325,7 @@ public boolean configure(final String name, final Map<String, Object> params) th
13301325

13311326
final String[] info = NetUtils.getNetworkParams(privateNic);
13321327

1333-
kvmhaMonitor = new KVMHAMonitor(null, info[0], heartBeatPath);
1328+
kvmhaMonitor = new KVMHAMonitor(null, info[0]);
13341329
final Thread ha = new Thread(kvmhaMonitor);
13351330
ha.start();
13361331

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public Answer execute(final CheckVMActivityOnStoragePoolCommand command, final L
4848

4949
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
5050

51-
if (primaryPool.isPoolSupportHA()){
51+
if (primaryPool.isPoolSupportHA()) {
5252
final HAStoragePool nfspool = monitor.getStoragePool(pool.getUuid());
5353
final KVMHAVMActivityChecker ha = new KVMHAVMActivityChecker(nfspool, command.getHost(), command.getVolumeList(), libvirtComputingResource.getVmActivityCheckPath(), command.getSuspectTimeInSeconds());
5454
final Future<Boolean> future = executors.submit(ha);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ public KVMStoragePool getStoragePool(StoragePoolType type, String uuid, boolean
289289

290290
if (pool instanceof LibvirtStoragePool) {
291291
addPoolDetails(uuid, (LibvirtStoragePool) pool);
292+
((LibvirtStoragePool) pool).setType(type);
292293
}
293294

294295
return pool;
@@ -390,6 +391,9 @@ public KVMStoragePool createStoragePool(String name, String host, int port, Stri
390391
private synchronized KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean primaryStorage) {
391392
StorageAdaptor adaptor = getStorageAdaptor(type);
392393
KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type, details, primaryStorage);
394+
if (pool instanceof LibvirtStoragePool) {
395+
((LibvirtStoragePool) pool).setType(type);
396+
}
393397

394398
// LibvirtStorageAdaptor-specific statement
395399
if (pool.isPoolSupportHA() && primaryStorage) {

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.cloud.agent.api.to.HostTO;
3232
import com.cloud.agent.properties.AgentProperties;
3333
import com.cloud.agent.properties.AgentPropertiesFileHandler;
34+
import com.cloud.ha.HighAvailabilityManager;
3435
import com.cloud.hypervisor.kvm.resource.KVMHABase.HAStoragePool;
3536
import com.cloud.storage.Storage;
3637
import com.cloud.storage.Storage.StoragePoolType;
@@ -320,13 +321,24 @@ public void setDetails(Map<String, String> details) {
320321

321322
@Override
322323
public boolean isPoolSupportHA() {
323-
return type == StoragePoolType.NetworkFilesystem;
324+
return HighAvailabilityManager.LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT.contains(type);
324325
}
325326

326327
public String getHearthBeatPath() {
327-
if (type == StoragePoolType.NetworkFilesystem) {
328+
if (StoragePoolType.NetworkFilesystem.equals(type)) {
328329
String kvmScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.KVM_SCRIPTS_DIR);
329-
return Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
330+
String scriptPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
331+
if (scriptPath == null) {
332+
throw new CloudRuntimeException("Unable to find heartbeat script 'kvmheartbeat.sh' in directory: " + kvmScriptsDir);
333+
}
334+
return scriptPath;
335+
} else if (StoragePoolType.SharedMountPoint.equals(type)) {
336+
String kvmScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.KVM_SCRIPTS_DIR);
337+
String scriptPath = Script.findScript(kvmScriptsDir, "kvmsmpheartbeat.sh");
338+
if (scriptPath == null) {
339+
throw new CloudRuntimeException("Unable to find heartbeat script 'kvmsmpheartbeat.sh' in directory: " + kvmScriptsDir);
340+
}
341+
return scriptPath;
330342
}
331343
return null;
332344
}
@@ -410,4 +422,8 @@ public Boolean vmActivityCheck(HAStoragePool pool, HostTO host, Duration activit
410422
return true;
411423
}
412424
}
425+
426+
public void setType(StoragePoolType type) {
427+
this.type = type;
428+
}
413429
}

plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.inject.Inject;
2828

2929
import com.cloud.agent.api.to.DiskTO;
30+
import com.cloud.ha.HighAvailabilityManager;
3031
import com.cloud.storage.VolumeVO;
3132
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
3233
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
@@ -587,7 +588,7 @@ private boolean anyVolumeRequiresEncryption(DataObject ... objects) {
587588

588589
@Override
589590
public boolean isStorageSupportHA(StoragePoolType type) {
590-
return StoragePoolType.NetworkFilesystem == type;
591+
return type != null && HighAvailabilityManager.LIBVIRT_STORAGE_POOL_TYPES_WITH_HA_SUPPORT.contains(type);
591592
}
592593

593594
@Override

0 commit comments

Comments
 (0)