package org.ovirt.engine.core.bll.storage; import java.util.List; import java.util.concurrent.TimeUnit; import org.ovirt.engine.core.bll.Backend; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.SetStoragePoolStatusParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.storage_pool; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation; import org.ovirt.engine.core.utils.timer.SchedulerUtil; import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl; public final class StoragePoolStatusHandler { private static java.util.HashMap<Guid, StoragePoolStatusHandler> _nonOperationalPools = new java.util.HashMap<Guid, StoragePoolStatusHandler>(); private Guid poolId; private String timerId; private StoragePoolStatusHandler(Guid poolId) { this.poolId = poolId; timerId = null; } private SchedulerUtil getScheduler() { return SchedulerUtilQuartzImpl.getInstance(); } private StoragePoolStatusHandler scheduleTimeout() { Class[] argTypes = new Class[0]; Object[] args = new Object[0]; Integer timeout = Config.<Integer> GetValue(ConfigValues.StoragePoolNonOperationalResetTimeoutInMin); timerId = getScheduler().scheduleAOneTimeJob(this, "onTimeout", argTypes, args, timeout, TimeUnit.MINUTES); return this; } private void deScheduleTimeout() { if (timerId != null) { getScheduler().deleteJob(timerId); timerId = null; } } @OnTimerMethodAnnotation("onTimeout") public void onTimeout() { if (_nonOperationalPools.containsKey(poolId)) { try { storage_pool pool = DbFacade.getInstance().getStoragePoolDAO().get(poolId); if (pool != null && pool.getstatus() == StoragePoolStatus.NotOperational) { NonOperationalPoolTreatment(pool); } } catch (java.lang.Exception e) { } } } public static void PoolStatusChanged(Guid poolId, StoragePoolStatus status) { if (_nonOperationalPools.containsKey(poolId) && status != StoragePoolStatus.NotOperational) { StoragePoolStatusHandler handler = _nonOperationalPools.get(poolId); if (handler != null) { synchronized (handler) { handler.deScheduleTimeout(); } } synchronized (_nonOperationalPools) { _nonOperationalPools.remove(poolId); } } else if (status == StoragePoolStatus.NotOperational) { synchronized (_nonOperationalPools) { _nonOperationalPools.put(poolId, new StoragePoolStatusHandler(poolId).scheduleTimeout()); } } } private static void NonOperationalPoolTreatment(storage_pool pool) { boolean changeStatus = false; if (StorageHandlingCommandBase.GetAllRunningVdssInPool(pool).size() > 0) { changeStatus = true; } if (changeStatus) { log.info("Moving data center " + pool.getname() + " with Id " + pool.getId() + " to status Problematic from status NotOperational on a one time basis to try to recover"); Backend.getInstance().runInternalAction( VdcActionType.SetStoragePoolStatus, new SetStoragePoolStatusParameters(pool.getId(), StoragePoolStatus.Problematic, AuditLogType.SYSTEM_CHANGE_STORAGE_POOL_STATUS_PROBLEMATIC_FROM_NON_OPERATIONAL)); synchronized (_nonOperationalPools) { _nonOperationalPools.remove(pool.getId()); } } } public static void Init() { List<storage_pool> allPools = DbFacade.getInstance().getStoragePoolDAO().getAll(); for (storage_pool pool : allPools) { if (pool.getstatus() == StoragePoolStatus.NotOperational) { PoolStatusChanged(pool.getId(), StoragePoolStatus.NotOperational); } } } private static LogCompat log = LogFactoryCompat.getLog(StoragePoolStatusHandler.class); }