@Override public boolean deleteHost(Long hostId) { List<SnapshotVO> snapshots = _snapshotDao.listByHostId(hostId); if (snapshots != null && !snapshots.isEmpty()) { throw new CloudRuntimeException( "Can not delete this secondary storage due to there are still snapshots on it "); } List<Long> list = _templateDao.listPrivateTemplatesByHost(hostId); if (list != null && !list.isEmpty()) { throw new CloudRuntimeException( "Can not delete this secondary storage due to there are still private template on it "); } _vmTemplateHostDao.deleteByHost(hostId); HostVO host = _hostDao.findById(hostId); host.setGuid(null); _hostDao.update(hostId, host); _hostDao.remove(hostId); return true; }
private void checkStatusOfCurrentlyExecutingSnapshots() { SearchCriteria<SnapshotScheduleVO> sc = _snapshotScheduleDao.createSearchCriteria(); sc.addAnd("asyncJobId", SearchCriteria.Op.NNULL); List<SnapshotScheduleVO> snapshotSchedules = _snapshotScheduleDao.search(sc, null); for (SnapshotScheduleVO snapshotSchedule : snapshotSchedules) { Long asyncJobId = snapshotSchedule.getAsyncJobId(); AsyncJobVO asyncJob = _asyncJobDao.findById(asyncJobId); switch (asyncJob.getStatus()) { case AsyncJobResult.STATUS_SUCCEEDED: // The snapshot has been successfully backed up. // The snapshot state has also been cleaned up. // We can schedule the next job for this snapshot. // Remove the existing entry in the snapshot_schedule table. scheduleNextSnapshotJob(snapshotSchedule); break; case AsyncJobResult.STATUS_FAILED: // Check the snapshot status. Long snapshotId = snapshotSchedule.getSnapshotId(); if (snapshotId == null) { // createSnapshotAsync exited, successfully or unsuccessfully, // even before creating a snapshot record // No cleanup needs to be done. // Schedule the next snapshot. scheduleNextSnapshotJob(snapshotSchedule); } else { SnapshotVO snapshot = _snapshotDao.findById(snapshotId); if (snapshot == null || snapshot.getRemoved() != null) { // This snapshot has been deleted successfully from the primary storage // Again no cleanup needs to be done. // Schedule the next snapshot. // There's very little probability that the code reaches this point. // The snapshotId is a foreign key for the snapshot_schedule table // set to ON DELETE CASCADE. So if the snapshot entry is deleted, the // snapshot_schedule entry will be too. // But what if it has only been marked as removed? scheduleNextSnapshotJob(snapshotSchedule); } else { // The management server executing this snapshot job appears to have crashed // while creating the snapshot on primary storage/or backing it up. // We have no idea whether the snapshot was successfully taken on the primary or not. // Schedule the next snapshot job. // The ValidatePreviousSnapshotCommand will take appropriate action on this snapshot // If the snapshot was taken successfully on primary, it will retry backing it up. // and cleanup the previous snapshot // Set the userId to that of system. // _snapshotManager.validateSnapshot(1L, snapshot); // In all cases, schedule the next snapshot job scheduleNextSnapshotJob(snapshotSchedule); } } break; case AsyncJobResult.STATUS_IN_PROGRESS: // There is no way of knowing from here whether // 1) Another management server is processing this snapshot job // 2) The management server has crashed and this snapshot is lying // around in an inconsistent state. // Hopefully, this can be resolved at the backend when the current snapshot gets executed. // But if it remains in this state, the current snapshot will not get executed. // And it will remain in stasis. break; } } }