Ramesh N has uploaded a new change for review. Change subject: engine: sync job for gluster disk provisioning ......................................................................
engine: sync job for gluster disk provisioning Adding a sync job for gluster Disk Provisioning. It will monitor all the storage devices in the host it will update the engine database accordingly. Change-Id: I651bb51873a96d491c5a5f51147cb72be958985a Signed-off-by: Ramesh Nachimuthu <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJob.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJobsManager.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StorageDeviceSyncJob.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/SyncStorageDevicesCommand.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/gluster/GlusterFeatureSupported.java M backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties M packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql 10 files changed, 233 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/29/36429/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJob.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJob.java index 57beb7b..3407d61 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJob.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJob.java @@ -33,6 +33,7 @@ import org.ovirt.engine.core.dao.gluster.GlusterServerServiceDao; import org.ovirt.engine.core.dao.gluster.GlusterServiceDao; import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao; +import org.ovirt.engine.core.dao.gluster.StorageDeviceDao; import org.ovirt.engine.core.dao.network.InterfaceDao; import org.ovirt.engine.core.utils.lock.EngineLock; import org.ovirt.engine.core.utils.lock.LockManager; @@ -134,6 +135,9 @@ return DbFacade.getInstance().getGlusterGeoRepDao(); } + protected StorageDeviceDao getStorageDeviceDao() { + return DbFacade.getInstance().getStorageDeviceDao(); + } /** * Acquires a lock on the cluster with given id and locking group {@link LockingGroup#GLUSTER} * diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJobsManager.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJobsManager.java index cd20f43..3529196 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJobsManager.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterJobsManager.java @@ -71,6 +71,13 @@ getRefreshRate(ConfigValues.GlusterRefreshRateGeoRepDiscovery), getRefreshRate(ConfigValues.GlusterRefreshRateGeoRepDiscovery), TimeUnit.SECONDS); + scheduler.scheduleAFixedDelayJob(StorageDeviceSyncJob.getInstance(), + "gluster_storage_device_pool_event", + new Class[0], + new Class[0], + getRefreshRate(ConfigValues.GlusterRefreshRateStorageDevices), + getRefreshRate(ConfigValues.GlusterRefreshRateStorageDevices), + TimeUnit.SECONDS); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StorageDeviceSyncJob.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StorageDeviceSyncJob.java new file mode 100644 index 0000000..7395216 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StorageDeviceSyncJob.java @@ -0,0 +1,145 @@ +package org.ovirt.engine.core.bll.gluster; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.ovirt.engine.core.common.AuditLogType; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.businessentities.gluster.StorageDevice; +import org.ovirt.engine.core.common.gluster.GlusterFeatureSupported; +import org.ovirt.engine.core.common.utils.ObjectUtils; +import org.ovirt.engine.core.common.vdscommands.VDSCommandType; +import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; +import org.ovirt.engine.core.common.vdscommands.VdsIdVDSCommandParametersBase; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StorageDeviceSyncJob extends GlusterJob { + private static final Logger log = LoggerFactory.getLogger(StorageDeviceSyncJob.class); + + private static final StorageDeviceSyncJob instance = new StorageDeviceSyncJob(); + + public void init() { + log.info("Gluster Storage Device monitoring has been initialized"); + } + + public static StorageDeviceSyncJob getInstance() { + return instance; + } + + @OnTimerMethodAnnotation("gluster_storage_device_pool_event") + public void refreshStorageDevices() { + // get all clusters + List<VDSGroup> clusters = getClusterDao().getAll(); + // for every cluster that supports disk provisioning + for (VDSGroup cluster : clusters) { + if (supportsGlusterDiskProvisioning(cluster)) { + refreshStorageDevicesInCluster(cluster); + } + } + } + + private void refreshStorageDevicesInCluster(VDSGroup cluster) { + List<VDS> allUpServers = getClusterUtils().getAllUpServers(cluster.getId()); + for (VDS vds : allUpServers) { + refreshStorageDevicesFromServer(vds); + } + + } + + public void refreshStorageDevicesFromServer(VDS vds) { + VDSReturnValue returnValue = + runVdsCommand(VDSCommandType.GetStorageDeviceList, new VdsIdVDSCommandParametersBase(vds.getId())); + if (returnValue.getSucceeded()) { + List<StorageDevice> storageDevices = (List<StorageDevice>) returnValue.getReturnValue(); + updateStorageDevices(vds, storageDevices); + } else { + log.error("VDS error {}", returnValue.getVdsError().getMessage()); + log.debug("VDS error", returnValue.getVdsError()); + } + } + + private void updateStorageDevices(VDS vds, List<StorageDevice> storageDevicesFromVdsm) { + Set<String> deviceUuidsFromVdsm = new HashSet<String>(); + Set<String> deviceNamesFromVdsm = new HashSet<String>(); + + List<StorageDevice> storageDevicesInDb = getStorageDeviceDao().getStorageDevicesInHost(vds.getId()); + Map<String, StorageDevice> nameToDeviceMap = new HashMap<String, StorageDevice>(); + Map<String, StorageDevice> deviceUuidToDeviceMap = new HashMap<String, StorageDevice>(); + + // Make deviceUuid to Device map and deviceName to device map so that we can find the + // newly added and updated devices without looping over the same list again and again. + for (StorageDevice storageDevice : storageDevicesInDb) { + nameToDeviceMap.put(storageDevice.getName(), storageDevice); + if (storageDevice.getDevUuid() != null && !storageDevice.getDevUuid().isEmpty()) { + deviceUuidToDeviceMap.put(storageDevice.getDevUuid(), storageDevice); + } + } + + for (StorageDevice storageDevice : storageDevicesFromVdsm) { + // Create deviceName and deviceUuid set to use it while finding the deleted services. + deviceNamesFromVdsm.add(storageDevice.getName()); + if (storageDevice.getDevUuid() != null) { + deviceUuidsFromVdsm.add(storageDevice.getDevUuid()); + } + if (deviceUuidToDeviceMap.get(storageDevice.getDevUuid()) != null + || (nameToDeviceMap.get(storageDevice.getName()) != null + && (nameToDeviceMap.get(storageDevice.getName()).getDevUuid() == null + || nameToDeviceMap.get(storageDevice.getName()).getDevUuid().isEmpty()))) { + // TODO Verify this logic. Get the deviceID by Name may not the right thing + storageDevice.setId(nameToDeviceMap.get(storageDevice.getName()).getId()); + if (!ObjectUtils.objectsEqual(nameToDeviceMap.get(storageDevice.getName()), storageDevice)) { + getStorageDeviceDao().updateStorageDevice(storageDevice); + } + + } else { + storageDevice.setId(Guid.newGuid()); + storageDevice.setVdsId(vds.getId()); + log.debug("detected new storage device '{}' for host '{}'", + storageDevice.getName(), + vds.getName()); + getStorageDeviceDao().save(storageDevice); + logStorageDeviceMessage(AuditLogType.NEW_STORAGE_DEVICE_DETECTED, + vds, + storageDevice); + } + } + + for (StorageDevice storageDevice : storageDevicesInDb) { + if (!deviceUuidsFromVdsm.contains(storageDevice.getDevUuid()) + && (!deviceNamesFromVdsm.contains(storageDevice.getName()) + && storageDevice.getDevUuid() == null)) { + log.debug("storage device '{}' detected removed for the host '{}'", + storageDevice.getName(), + vds.getName()); + getStorageDeviceDao().remove(storageDevice.getId()); + logStorageDeviceMessage(AuditLogType.STORAGE_DEVICE_REMOVED_FROM_THE_SYSTEM, + vds, + storageDevice); + } + } + + } + + private void logStorageDeviceMessage(AuditLogType logType, VDS vds, final StorageDevice device) { + logUtil.logAuditMessage(vds.getVdsGroupId(), null, vds, + logType, + new HashMap<String, String>() { + { + put("storageDevice", device.getName()); + } + }); + } + + private boolean supportsGlusterDiskProvisioning(VDSGroup cluster) { + return cluster.supportsGlusterService() + && GlusterFeatureSupported.glusterDiskProvisioning(cluster.getcompatibility_version()); + } + +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/SyncStorageDevicesCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/SyncStorageDevicesCommand.java new file mode 100644 index 0000000..75e338b --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/SyncStorageDevicesCommand.java @@ -0,0 +1,37 @@ +package org.ovirt.engine.core.bll.gluster; + +import org.ovirt.engine.core.bll.VdsCommand; +import org.ovirt.engine.core.bll.VdsValidator; +import org.ovirt.engine.core.common.AuditLogType; +import org.ovirt.engine.core.common.action.VdsActionParameters; + +public class SyncStorageDevicesCommand<T extends VdsActionParameters> extends VdsCommand<T> { + + public SyncStorageDevicesCommand(T parameters) { + super(parameters); + } + + @Override + protected boolean canDoAction() { + VdsValidator validator = new VdsValidator(getVds()); + return validate(validator.isUp()); + } + + @Override + protected void setActionMessageParameters() { + super.setActionMessageParameters(); + addCanDoActionMessageVariable("VdsName", getVds().getName()); + } + + @Override + protected void executeCommand() { + + StorageDeviceSyncJob.getInstance().refreshStorageDevicesFromServer(getVds()); + setSucceeded(true); + } + + @Override + public AuditLogType getAuditLogTypeValue() { + return AuditLogType.SYNC_STORAGE_DEVICES_IN_HOST; + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java index b75a46a..acedb4e 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java @@ -384,6 +384,10 @@ USER_FORCE_SELECTED_SPM_STOP_FAILED(4096, AuditLogSeverity.ERROR), GLUSTER_GEOREP_SESSION_DELETED_FROM_CLI(4097, AuditLogSeverity.WARNING), GLUSTER_GEOREP_SESSION_DETECTED_FROM_CLI(4098, AuditLogSeverity.WARNING), + NEW_STORAGE_DEVICE_DETECTED(4101), + STORAGE_DEVICE_REMOVED_FROM_THE_SYSTEM(4102), + SYNC_STORAGE_DEVICES_IN_HOST(4103), + USER_FORCE_SELECTED_SPM(159), USER_VDS_RESTART(41), USER_FAILED_VDS_RESTART(107, AuditLogSeverity.ERROR), diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java index 23dc3e1..5294d60 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java @@ -1,6 +1,7 @@ package org.ovirt.engine.core.common.action; import java.util.HashMap; + import org.ovirt.engine.core.common.businessentities.ActionGroup; public enum VdcActionType { @@ -300,6 +301,7 @@ StopRemoveGlusterVolumeBricks(1423, ActionGroup.MANIPULATE_GLUSTER_VOLUME, false, QuotaDependency.NONE), CommitRemoveGlusterVolumeBricks(1424, ActionGroup.MANIPULATE_GLUSTER_VOLUME, false, QuotaDependency.NONE), RefreshGlusterVolumeDetails(1425, ActionGroup.MANIPULATE_GLUSTER_VOLUME, QuotaDependency.NONE), + SyncStorageDevices(1426, ActionGroup.MANIPULATE_HOST, QuotaDependency.NONE), // Scheduling Policy AddClusterPolicy(1450, ActionGroup.EDIT_STORAGE_POOL_CONFIGURATION, false, QuotaDependency.NONE), diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java index 332f1e2..f0d86b7 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java @@ -1247,6 +1247,13 @@ GlusterRefreshRateLight, /** + * Refresh rate (in seconds) for Storage Devices. + */ + @TypeConverterAttribute(Integer.class) + @DefaultValueAttribute("7200") + GlusterRefreshRateStorageDevices, + + /** * Refresh rate (in seconds) for heavy-weight gluster data i.e. commands to fetch such data adds a considerable * overhead on the GlusterFS processes. */ @@ -1387,6 +1394,10 @@ @DefaultValueAttribute("true") GlusterGeoReplicationEnabled, + @TypeConverterAttribute(Boolean.class) + @DefaultValueAttribute("true") + GlusterDiskProvisioningEnabled, + @TypeConverterAttribute(Integer.class) @DefaultValueAttribute("3600") GlusterRefreshRateGeoRepDiscovery, diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/gluster/GlusterFeatureSupported.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/gluster/GlusterFeatureSupported.java index 2b2a529..c58ba64 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/gluster/GlusterFeatureSupported.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/gluster/GlusterFeatureSupported.java @@ -91,4 +91,15 @@ public static boolean glusterGeoReplication(Version version) { return supportedInConfig(ConfigValues.GlusterGeoReplicationEnabled, version); } + + /** + * + * @param version + * Compatibility version to check for. + * @return <code>true</code> if disk provisioning feature is enabled, + * <code>false</code> if it's not. + */ + public static boolean glusterDiskProvisioning(Version version) { + return supportedInConfig(ConfigValues.GlusterDiskProvisioningEnabled, version); + } } diff --git a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties index ee7c448..b94b240 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties @@ -804,6 +804,9 @@ GLUSTER_BRICK_STATUS_CHANGED=Detected change in status of brick ${brickpath} of volume ${glusterVolumeName} from ${oldValue} to ${newValue}. GLUSTER_GEOREP_SESSION_DELETED_FROM_CLI=Detected deletion of geo-replication session ${geoRepSessionKey} from volume ${glusterVolumeName} GLUSTER_GEOREP_SESSION_DETECTED_FROM_CLI=Detected new geo-replication session ${geoRepSessionKey} for volume ${glusterVolumeName}. Adding it to engine. +NEW_STORAGE_DEVICE_DETECTED=Found new storage device ${storageDevice} from host ${VdsName} +STORAGE_DEVICE_REMOVED_FROM_THE_SYSTEM=Removed the storage device ${storageDevice} from host ${VdsName} +SYNC_STORAGE_DEVICES_IN_HOST=Manually synced the storage devices from host ${VdsName} VDS_UNTRUSTED=Host ${VdsName} was set to non-operational. Host is not trusted by the attestation service. USER_ADDED_NETWORK_QOS=Network QoS ${QosName} was added. (User: ${UserName}) USER_FAILED_TO_ADD_NETWORK_QOS=Failed to add Network QoS ${QosName}. (User: ${UserName}) diff --git a/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql b/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql index 90b6e02..52fbc47 100644 --- a/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql +++ b/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql @@ -150,6 +150,7 @@ select fn_db_add_config_value('GlusterRefreshRateHooks', '7200', 'general'); select fn_db_add_config_value('GlusterRefreshRateLight', '5', 'general'); select fn_db_add_config_value('GlusterRefreshRateHeavy', '300', 'general'); +select fn_db_add_config_value('GlusterRefreshRateStorageDevices', '7200', 'general'); select fn_db_add_config_value('GlusterSupport', 'false', '3.0'); select fn_db_add_config_value_for_versions_up_to('GlusterSupportForceCreateVolume', 'false', '3.3'); select fn_db_add_config_value('GlusterVolumeOptionGroupVirtValue','virt','general'); @@ -164,6 +165,14 @@ select fn_db_add_config_value('GlusterRefreshRateGeoRepStatus', '300', 'general'); select fn_db_add_config_value('GlusterRefreshRateGeoRepDiscovery', '3600', 'general'); +-- Gluster Disk Provisioning -- +select fn_db_add_config_value_for_versions_up_to('GlusterDiskProvisioningEnabled', 'false', '3.0'); +select fn_db_add_config_value_for_versions_up_to('GlusterDiskProvisioningEnabled', 'false', '3.1'); +select fn_db_add_config_value_for_versions_up_to('GlusterDiskProvisioningEnabled', 'false', '3.2'); +select fn_db_add_config_value_for_versions_up_to('GlusterDiskProvisioningEnabled', 'false', '3.3'); +select fn_db_add_config_value_for_versions_up_to('GlusterDiskProvisioningEnabled', 'false', '3.4'); +select fn_db_add_config_value_for_versions_up_to('GlusterDiskProvisioningEnabled', 'false', '3.5'); + -- OpenStack related select fn_db_add_config_value('KeystoneAuthUrl', '', 'general'); -- To view, visit http://gerrit.ovirt.org/36429 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I651bb51873a96d491c5a5f51147cb72be958985a Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Ramesh N <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
