Search in sources :

Example 1 with DataObjectInStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.

the class DataObjectManagerImpl method createAsync.

@Override
public void createAsync(DataObject data, DataStore store, AsyncCompletionCallback<CreateCmdResult> callback, boolean noCopy) {
    DataObjectInStore obj = objectInDataStoreMgr.findObject(data, store);
    DataObject objInStore = null;
    boolean freshNewTemplate = false;
    if (obj == null) {
        try {
            objInStore = objectInDataStoreMgr.create(data, store);
            freshNewTemplate = true;
        } catch (Throwable e) {
            obj = objectInDataStoreMgr.findObject(data, store);
            if (obj == null) {
                CreateCmdResult result = new CreateCmdResult(null, null);
                result.setSuccess(false);
                result.setResult(e.toString());
                callback.complete(result);
                return;
            }
        }
    }
    if (!freshNewTemplate && obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
        try {
            objInStore = waitingForCreated(data, store);
        } catch (Exception e) {
            CreateCmdResult result = new CreateCmdResult(null, null);
            result.setSuccess(false);
            result.setResult(e.toString());
            callback.complete(result);
            return;
        }
        CreateCmdResult result = new CreateCmdResult(null, null);
        callback.complete(result);
        return;
    }
    try {
        ObjectInDataStoreStateMachine.Event event = null;
        if (noCopy) {
            event = ObjectInDataStoreStateMachine.Event.CreateOnlyRequested;
        } else {
            event = ObjectInDataStoreStateMachine.Event.CreateRequested;
        }
        objectInDataStoreMgr.update(objInStore, event);
    } catch (NoTransitionException e) {
        try {
            objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationFailed);
        } catch (Exception e1) {
            s_logger.debug("state transation failed", e1);
        }
        CreateCmdResult result = new CreateCmdResult(null, null);
        result.setSuccess(false);
        result.setResult(e.toString());
        callback.complete(result);
        return;
    } catch (ConcurrentOperationException e) {
        try {
            objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationFailed);
        } catch (Exception e1) {
            s_logger.debug("state transation failed", e1);
        }
        CreateCmdResult result = new CreateCmdResult(null, null);
        result.setSuccess(false);
        result.setResult(e.toString());
        callback.complete(result);
        return;
    }
    CreateContext<CreateCmdResult> context = new CreateContext<CreateCmdResult>(callback, objInStore);
    AsyncCallbackDispatcher<DataObjectManagerImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
    caller.setCallback(caller.getTarget().createAsynCallback(null, null)).setContext(context);
    store.getDriver().createAsync(store, objInStore, caller);
    return;
}
Also used : DataObjectInStore(org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) ObjectInDataStoreStateMachine(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) Event(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event)

Example 2 with DataObjectInStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.

the class DataObjectManagerImpl method waitingForCreated.

protected DataObject waitingForCreated(DataObject dataObj, DataStore dataStore) {
    long retries = this.waitingRetries;
    DataObjectInStore obj = null;
    do {
        try {
            Thread.sleep(waitingTime);
        } catch (InterruptedException e) {
            s_logger.debug("sleep interrupted", e);
            throw new CloudRuntimeException("sleep interrupted", e);
        }
        obj = objectInDataStoreMgr.findObject(dataObj, dataStore);
        if (obj == null) {
            s_logger.debug("can't find object in db, maybe it's cleaned up already, exit waiting");
            break;
        }
        if (obj.getState() == ObjectInDataStoreStateMachine.State.Ready) {
            break;
        }
        retries--;
    } while (retries > 0);
    if (obj == null || retries <= 0) {
        s_logger.debug("waiting too long for template downloading, marked it as failed");
        throw new CloudRuntimeException("waiting too long for template downloading, marked it as failed");
    }
    return objectInDataStoreMgr.get(dataObj, dataStore, null);
}
Also used : CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataObjectInStore(org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore)

Example 3 with DataObjectInStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.

the class DataObjectManagerImpl method createInternalStateOnly.

@Override
public DataObject createInternalStateOnly(DataObject data, DataStore store) {
    DataObjectInStore obj = objectInDataStoreMgr.findObject(data, store);
    DataObject objInStore = null;
    if (obj == null) {
        objInStore = objectInDataStoreMgr.create(data, store);
    }
    try {
        ObjectInDataStoreStateMachine.Event event = null;
        event = ObjectInDataStoreStateMachine.Event.CreateRequested;
        objectInDataStoreMgr.update(objInStore, event);
        objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationSuccessed);
    } catch (NoTransitionException e) {
        s_logger.debug("Failed to update state", e);
        throw new CloudRuntimeException("Failed to update state", e);
    } catch (ConcurrentOperationException e) {
        s_logger.debug("Failed to update state", e);
        throw new CloudRuntimeException("Failed to update state", e);
    }
    return objInStore;
}
Also used : ObjectInDataStoreStateMachine(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) DataObjectInStore(org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) Event(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event)

Example 4 with DataObjectInStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.

the class ObjectInDataStoreManagerImpl method update.

@Override
public boolean update(DataObject data, Event event) throws NoTransitionException, ConcurrentOperationException {
    DataObjectInStore obj = this.findObject(data, data.getDataStore());
    if (obj == null) {
        throw new CloudRuntimeException("can't find mapping in ObjectInDataStore table for: " + data);
    }
    boolean result = true;
    if (data.getDataStore().getRole() == DataStoreRole.Image || data.getDataStore().getRole() == DataStoreRole.ImageCache) {
        switch(data.getType()) {
            case TEMPLATE:
                result = this.stateMachines.transitTo(obj, event, null, templateDataStoreDao);
                break;
            case SNAPSHOT:
                result = this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao);
                break;
            case VOLUME:
                result = this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao);
                break;
        }
    } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) {
        result = this.stateMachines.transitTo(obj, event, null, templatePoolDao);
    } else if (data.getType() == DataObjectType.SNAPSHOT && data.getDataStore().getRole() == DataStoreRole.Primary) {
        result = this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao);
    } else {
        throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole());
    }
    if (!result) {
        throw new ConcurrentOperationException("Multiple threads are trying to update data object state, racing condition");
    }
    return true;
}
Also used : CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataObjectInStore(org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException)

Example 5 with DataObjectInStore

use of org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore in project cloudstack by apache.

the class StorageCacheManagerImpl method createCacheObject.

@Override
public DataObject createCacheObject(DataObject data, DataStore store) {
    DataObject objOnCacheStore = null;
    final Object lock;
    final DataObjectType type = data.getType();
    final String typeName;
    final long storeId = store.getId();
    final long dataId = data.getId();
    /*
         * Make sure any thread knows own lock type.
         */
    if (type == DataObjectType.TEMPLATE) {
        lock = templateLock;
        typeName = "template";
    } else if (type == DataObjectType.VOLUME) {
        lock = volumeLock;
        typeName = "volume";
    } else if (type == DataObjectType.SNAPSHOT) {
        lock = snapshotLock;
        typeName = "snapshot";
    } else {
        String msg = "unsupported DataObject comes, then can't acquire correct lock object";
        throw new CloudRuntimeException(msg);
    }
    s_logger.debug("check " + typeName + " cache entry(id: " + dataId + ") on store(id: " + storeId + ")");
    DataObject existingDataObj = null;
    synchronized (lock) {
        DataObjectInStore obj = objectInStoreMgr.findObject(data, store);
        if (obj != null) {
            State st = obj.getState();
            long miliSeconds = 10000;
            long timeoutSeconds = 3600;
            long timeoutMiliSeconds = timeoutSeconds * 1000;
            Date now = new Date();
            long expiredEpoch = now.getTime() + timeoutMiliSeconds;
            Date expiredDate = new Date(expiredEpoch);
            /*
                 * Waiting for completion of cache copy.
                 */
            while (st == ObjectInDataStoreStateMachine.State.Allocated || st == ObjectInDataStoreStateMachine.State.Creating || st == ObjectInDataStoreStateMachine.State.Copying) {
                /*
                     * Threads must release lock within waiting for cache copy and
                     * must be waken up at completion.
                     */
                s_logger.debug("waiting cache copy completion type: " + typeName + ", id: " + obj.getObjectId() + ", lock: " + lock.hashCode());
                try {
                    lock.wait(miliSeconds);
                } catch (InterruptedException e) {
                    s_logger.debug("[ignored] interupted while waiting for cache copy completion.");
                }
                s_logger.debug("waken up");
                now = new Date();
                if (now.after(expiredDate)) {
                    String msg = "Waiting time exceeds timeout limit(" + timeoutSeconds + " s)";
                    throw new CloudRuntimeException(msg);
                }
                obj = objectInStoreMgr.findObject(data, store);
                st = obj.getState();
            }
            if (st == ObjectInDataStoreStateMachine.State.Ready) {
                s_logger.debug("there is already one in the cache store");
                DataObject dataObj = objectInStoreMgr.get(data, store, null);
                dataObj.incRefCount();
                existingDataObj = dataObj;
            }
        }
        if (existingDataObj == null) {
            s_logger.debug("create " + typeName + " cache entry(id: " + dataId + ") on store(id: " + storeId + ")");
            objOnCacheStore = store.create(data);
        }
        lock.notifyAll();
    }
    if (existingDataObj != null) {
        return existingDataObj;
    }
    if (objOnCacheStore == null) {
        s_logger.error("create " + typeName + " cache entry(id: " + dataId + ") on store(id: " + storeId + ") failed");
        return null;
    }
    AsyncCallFuture<CopyCommandResult> future = new AsyncCallFuture<CopyCommandResult>();
    CopyCommandResult result = null;
    try {
        objOnCacheStore.processEvent(Event.CreateOnlyRequested);
        dataMotionSvr.copyAsync(data, objOnCacheStore, future);
        result = future.get();
        if (result.isFailed()) {
            objOnCacheStore.processEvent(Event.OperationFailed);
        } else {
            objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer());
            objOnCacheStore.incRefCount();
            return objOnCacheStore;
        }
    } catch (InterruptedException e) {
        s_logger.debug("create cache storage failed: " + e.toString());
        throw new CloudRuntimeException(e);
    } catch (ExecutionException e) {
        s_logger.debug("create cache storage failed: " + e.toString());
        throw new CloudRuntimeException(e);
    } finally {
        if (result == null) {
            objOnCacheStore.processEvent(Event.OperationFailed);
        }
        synchronized (lock) {
            /*
                 * Wake up all threads waiting for cache copy.
                 */
            s_logger.debug("wake up all waiting threads(lock: " + lock.hashCode() + ")");
            lock.notifyAll();
        }
    }
    return null;
}
Also used : DataObjectInStore(org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore) Date(java.util.Date) AsyncCallFuture(org.apache.cloudstack.framework.async.AsyncCallFuture) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) State(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) ExecutionException(java.util.concurrent.ExecutionException) DataObjectType(com.cloud.agent.api.to.DataObjectType) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)

Aggregations

CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)5 DataObjectInStore (org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore)5 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)3 DataObject (org.apache.cloudstack.engine.subsystem.api.storage.DataObject)3 NoTransitionException (com.cloud.utils.fsm.NoTransitionException)2 ObjectInDataStoreStateMachine (org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine)2 Event (org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event)2 DataObjectType (com.cloud.agent.api.to.DataObjectType)1 Date (java.util.Date)1 ExecutionException (java.util.concurrent.ExecutionException)1 CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)1 CreateCmdResult (org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult)1 State (org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State)1 AsyncCallFuture (org.apache.cloudstack.framework.async.AsyncCallFuture)1