/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.ceph; import java.net.URI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.ceph.CephClient; import com.emc.storageos.ceph.CephClientFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.BlockSnapshot; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.exceptions.DeviceControllerErrors; import com.emc.storageos.exceptions.DeviceControllerException; import com.emc.storageos.svcs.errorhandling.model.ServiceError; import com.emc.storageos.volumecontroller.DefaultSnapshotOperations; import com.emc.storageos.volumecontroller.TaskCompleter; /** * Snapshot related operation for Ceph cluster * * See http://docs.ceph.com/docs/master/rbd/rbd-snapshot/#snapshot-basics for basic snapshot operations details. * * The implementation is based on Ceph Hammer feature set. * */ public class CephSnapshotOperations extends DefaultSnapshotOperations { private static Logger _log = LoggerFactory.getLogger(CephSnapshotOperations.class); private DbClient _dbClient; private CephClientFactory _cephClientFactory; private CephClient getClient(StorageSystem storage) { return CephUtils.connectToCeph(_cephClientFactory, storage); } public void setDbClient(DbClient dbClient) { _dbClient = dbClient; } public void setCephClientFactory(CephClientFactory cephClientFactory) { _cephClientFactory = cephClientFactory; } @Override public void createSingleVolumeSnapshot(StorageSystem storage, URI snapshot, Boolean createInactive, Boolean readOnly, TaskCompleter taskCompleter) throws DeviceControllerException { try (CephClient cephClient = getClient(storage)) { BlockSnapshot blockSnapshot = _dbClient.queryObject(BlockSnapshot.class, snapshot); Volume volume = _dbClient.queryObject(Volume.class, blockSnapshot.getParent().getURI()); StoragePool pool = _dbClient.queryObject(StoragePool.class, volume.getPool()); String id = CephUtils.createNativeId(blockSnapshot); cephClient.createSnap(pool.getPoolName(), volume.getNativeId(), id); blockSnapshot.setNativeId(id); blockSnapshot.setDeviceLabel(blockSnapshot.getLabel()); blockSnapshot.setIsSyncActive(true); _dbClient.updateObject(blockSnapshot); taskCompleter.ready(_dbClient); } catch (Exception e) { _log.error("Snapshot creation failed", e); ServiceError error = DeviceControllerErrors.ceph.operationFailed("createSingleVolumeSnapshot", e.getMessage()); taskCompleter.error(_dbClient, error); } } @Override public void deleteSingleVolumeSnapshot(StorageSystem storage, URI snapshot, TaskCompleter taskCompleter) throws DeviceControllerException { try (CephClient cephClient = getClient(storage)) { BlockSnapshot blockSnapshot = _dbClient.queryObject(BlockSnapshot.class, snapshot); Volume volume = _dbClient.queryObject(Volume.class, blockSnapshot.getParent().getURI()); StoragePool pool = _dbClient.queryObject(StoragePool.class, volume.getPool()); cephClient.deleteSnap(pool.getPoolName(), volume.getNativeId(), blockSnapshot.getNativeId()); blockSnapshot.setInactive(true); _dbClient.updateObject(blockSnapshot); taskCompleter.ready(_dbClient); } catch (Exception e) { _log.error("Snapshot deletion failed", e); ServiceError error = DeviceControllerErrors.ceph.operationFailed("deleteSingleVolumeSnapshot", e.getMessage()); taskCompleter.error(_dbClient, error); } } }