|
41 | 41 | import javax.inject.Inject; |
42 | 42 | import javax.naming.ConfigurationException; |
43 | 43 |
|
| 44 | +import com.google.common.base.Strings; |
44 | 45 | import com.googlecode.ipv6.IPv6Address; |
45 | 46 | import org.apache.cloudstack.acl.SecurityChecker; |
46 | 47 | import org.apache.cloudstack.affinity.AffinityGroup; |
|
90 | 91 | import org.apache.cloudstack.framework.config.dao.ConfigurationDao; |
91 | 92 | import org.apache.cloudstack.framework.config.impl.ConfigurationVO; |
92 | 93 | import org.apache.cloudstack.framework.messagebus.MessageBus; |
93 | | -import org.apache.cloudstack.framework.messagebus.MessageSubscriber; |
94 | 94 | import org.apache.cloudstack.framework.messagebus.PublishScope; |
95 | 95 | import org.apache.cloudstack.query.QueryService; |
96 | 96 | import org.apache.cloudstack.region.PortableIp; |
@@ -425,6 +425,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati |
425 | 425 | private Set<String> overprovisioningFactorsForValidation; |
426 | 426 | public static final String VM_USERDATA_MAX_LENGTH_STRING = "vm.userdata.max.length"; |
427 | 427 |
|
| 428 | + public static final String KVM_HEARTBEAT_UPDATE_MAX_RETRIES = "kvm.heartbeat.update.max.retries"; |
| 429 | + public static final String KVM_HEARTBEAT_UPDATE_RETRY_SLEEP = "kvm.heartbeat.update.retry.sleep"; |
| 430 | + public static final String KVM_HEARTBEAT_UPDATE_TIMEOUT = "kvm.heartbeat.update.timeout"; |
| 431 | + public static final String KVM_HEARTBEAT_FAILURE_ACTION = "kvm.heartbeat.failure.action"; |
| 432 | + |
428 | 433 | public static final ConfigKey<Boolean> SystemVMUseLocalStorage = new ConfigKey<Boolean>(Boolean.class, "system.vm.use.local.storage", "Advanced", "false", |
429 | 434 | "Indicates whether to use local storage pools or shared storage pools for system VMs.", false, ConfigKey.Scope.Zone, null); |
430 | 435 |
|
@@ -459,6 +464,20 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati |
459 | 464 | public static final ConfigKey<Boolean> MIGRATE_VM_ACROSS_CLUSTERS = new ConfigKey<Boolean>(Boolean.class, "migrate.vm.across.clusters", "Advanced", "false", |
460 | 465 | "Indicates whether the VM can be migrated to different cluster if no host is found in same cluster",true, ConfigKey.Scope.Zone, null); |
461 | 466 |
|
| 467 | + public static final ConfigKey<Long> KVM_HEARTBEAT_UPDATE_MAX_RETRIES_CK = new ConfigKey<>("Advanced", Long.class, KVM_HEARTBEAT_UPDATE_MAX_RETRIES, "5", |
| 468 | + "The maximum retries of kvm heartbeat to write to storage", |
| 469 | + true, ConfigKey.Scope.Global); |
| 470 | + |
| 471 | + public static final ConfigKey<Long> KVM_HEARTBEAT_UPDATE_RETRY_SLEEP_CK = new ConfigKey<>("Advanced", Long.class, KVM_HEARTBEAT_UPDATE_RETRY_SLEEP, "10000", |
| 472 | + "The sleep time, in milliseconds, between two kvm heartbeats to write to storage", |
| 473 | + true, ConfigKey.Scope.Global); |
| 474 | + public static final ConfigKey<Long> KVM_HEARTBEAT_UPDATE_TIMEOUT_CK = new ConfigKey<>("Advanced", Long.class, KVM_HEARTBEAT_UPDATE_TIMEOUT, "60000", |
| 475 | + "Timeout(in milliseconds) that kvm heartbeat to write to storage", |
| 476 | + true, ConfigKey.Scope.Global); |
| 477 | + public static final ConfigKey<String> KVM_HEARTBEAT_FAILURE_ACTION_CK = new ConfigKey<>("Advanced", String.class, KVM_HEARTBEAT_FAILURE_ACTION, "hardreset", |
| 478 | + "The action for heartbeat write failures on KVM host. The valid value are 'hardreset' (default), 'stopagent', 'destroyvms'", |
| 479 | + true, ConfigKey.Scope.Global); |
| 480 | + |
462 | 481 | private static final String IOPS_READ_RATE = "IOPS Read"; |
463 | 482 | private static final String IOPS_WRITE_RATE = "IOPS Write"; |
464 | 483 | private static final String BYTES_READ_RATE = "Bytes Read"; |
@@ -514,6 +533,9 @@ private void populateConfigValuesForValidationSet() { |
514 | 533 | configValuesForValidation.add(StorageManager.STORAGE_POOL_CLIENT_TIMEOUT.key()); |
515 | 534 | configValuesForValidation.add(StorageManager.STORAGE_POOL_CLIENT_MAX_CONNECTIONS.key()); |
516 | 535 | configValuesForValidation.add(VM_USERDATA_MAX_LENGTH_STRING); |
| 536 | + configValuesForValidation.add(KVM_HEARTBEAT_UPDATE_MAX_RETRIES); |
| 537 | + configValuesForValidation.add(KVM_HEARTBEAT_UPDATE_RETRY_SLEEP); |
| 538 | + configValuesForValidation.add(KVM_HEARTBEAT_UPDATE_TIMEOUT); |
517 | 539 | } |
518 | 540 |
|
519 | 541 | private void weightBasedParametersForValidation() { |
@@ -546,23 +568,30 @@ private void overProvisioningFactorsForValidation() { |
546 | 568 | } |
547 | 569 |
|
548 | 570 | private void initMessageBusListener() { |
549 | | - messageBus.subscribe(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, new MessageSubscriber() { |
550 | | - @Override |
551 | | - public void onPublishMessage(String serderAddress, String subject, Object args) { |
552 | | - String globalSettingUpdated = (String) args; |
553 | | - if (StringUtils.isEmpty(globalSettingUpdated)) { |
554 | | - return; |
555 | | - } |
556 | | - if (globalSettingUpdated.equals(ApiServiceConfiguration.ManagementServerAddresses.key()) || |
557 | | - globalSettingUpdated.equals(IndirectAgentLBServiceImpl.IndirectAgentLBAlgorithm.key())) { |
558 | | - _indirectAgentLB.propagateMSListToAgents(); |
559 | | - } else if (globalSettingUpdated.equals(Config.RouterAggregationCommandEachTimeout.toString()) |
560 | | - || globalSettingUpdated.equals(Config.MigrateWait.toString())) { |
561 | | - Map<String, String> params = new HashMap<String, String>(); |
562 | | - params.put(Config.RouterAggregationCommandEachTimeout.toString(), _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString())); |
563 | | - params.put(Config.MigrateWait.toString(), _configDao.getValue(Config.MigrateWait.toString())); |
564 | | - _agentManager.propagateChangeToAgents(params); |
565 | | - } |
| 571 | + Map<String, ConfigKey> configKeyMap = new HashMap<>(); |
| 572 | + configKeyMap.put(KVM_HEARTBEAT_UPDATE_MAX_RETRIES, KVM_HEARTBEAT_UPDATE_MAX_RETRIES_CK); |
| 573 | + configKeyMap.put(KVM_HEARTBEAT_UPDATE_RETRY_SLEEP, KVM_HEARTBEAT_UPDATE_RETRY_SLEEP_CK); |
| 574 | + configKeyMap.put(KVM_HEARTBEAT_UPDATE_TIMEOUT, KVM_HEARTBEAT_UPDATE_TIMEOUT_CK); |
| 575 | + configKeyMap.put(KVM_HEARTBEAT_FAILURE_ACTION, KVM_HEARTBEAT_FAILURE_ACTION_CK); |
| 576 | + messageBus.subscribe(EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, (serverAddress, subject, args) -> { |
| 577 | + String globalSettingUpdated = (String) args; |
| 578 | + if (Strings.isNullOrEmpty(globalSettingUpdated)) { |
| 579 | + return; |
| 580 | + } |
| 581 | + if (globalSettingUpdated.equals(ApiServiceConfiguration.ManagementServerAddresses.key()) || |
| 582 | + globalSettingUpdated.equals(IndirectAgentLBServiceImpl.IndirectAgentLBAlgorithm.key())) { |
| 583 | + _indirectAgentLB.propagateMSListToAgents(); |
| 584 | + } else if (globalSettingUpdated.equals(Config.RouterAggregationCommandEachTimeout.toString()) |
| 585 | + || globalSettingUpdated.equals(Config.MigrateWait.toString())) { |
| 586 | + Map<String, String> params = new HashMap<String, String>(); |
| 587 | + params.put(Config.RouterAggregationCommandEachTimeout.toString(), _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString())); |
| 588 | + params.put(Config.MigrateWait.toString(), _configDao.getValue(Config.MigrateWait.toString())); |
| 589 | + _agentManager.propagateChangeToAgents(params); |
| 590 | + } else if (configKeyMap.keySet().contains(globalSettingUpdated)) { |
| 591 | + ConfigKey configKey = configKeyMap.get(globalSettingUpdated); |
| 592 | + Map<String, String> params = new HashMap<String, String>(); |
| 593 | + params.put(configKey.key(), configKey.value().toString()); |
| 594 | + _agentManager.propagateChangeToAgents(params); |
566 | 595 | } |
567 | 596 | }); |
568 | 597 | } |
@@ -928,6 +957,15 @@ private String validateConfigurationValue(final String name, String value, final |
928 | 957 | return errMsg; |
929 | 958 | } |
930 | 959 |
|
| 960 | + if (KVM_HEARTBEAT_FAILURE_ACTION.equalsIgnoreCase(name)) { |
| 961 | + List<String> kvmHeartBeatFailureActions = Arrays.asList("hardreset", "destroyvms", "stopagent"); |
| 962 | + if (value == null || ! kvmHeartBeatFailureActions.contains(value.toLowerCase())) { |
| 963 | + final String msg = "Possible values for " + name + " are - " + Arrays.toString(kvmHeartBeatFailureActions.toArray()); |
| 964 | + s_logger.error(msg); |
| 965 | + throw new InvalidParameterValueException(msg); |
| 966 | + } |
| 967 | + } |
| 968 | + |
931 | 969 | if (value == null) { |
932 | 970 | if (type.equals(Boolean.class)) { |
933 | 971 | return "Please enter either 'true' or 'false'."; |
@@ -7047,7 +7085,8 @@ public ConfigKey<?>[] getConfigKeys() { |
7047 | 7085 | return new ConfigKey<?>[] {SystemVMUseLocalStorage, IOPS_MAX_READ_LENGTH, IOPS_MAX_WRITE_LENGTH, |
7048 | 7086 | BYTES_MAX_READ_LENGTH, BYTES_MAX_WRITE_LENGTH, ADD_HOST_ON_SERVICE_RESTART_KVM, SET_HOST_DOWN_TO_MAINTENANCE, VM_SERVICE_OFFERING_MAX_CPU_CORES, |
7049 | 7087 | VM_SERVICE_OFFERING_MAX_RAM_SIZE, VM_USERDATA_MAX_LENGTH, MIGRATE_VM_ACROSS_CLUSTERS, |
7050 | | - ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN, ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN |
| 7088 | + ENABLE_ACCOUNT_SETTINGS_FOR_DOMAIN, ENABLE_DOMAIN_SETTINGS_FOR_CHILD_DOMAIN, |
| 7089 | + KVM_HEARTBEAT_UPDATE_MAX_RETRIES_CK, KVM_HEARTBEAT_UPDATE_RETRY_SLEEP_CK, KVM_HEARTBEAT_UPDATE_TIMEOUT_CK, KVM_HEARTBEAT_FAILURE_ACTION_CK |
7051 | 7090 | }; |
7052 | 7091 | } |
7053 | 7092 | } |
0 commit comments