@Override public void run() { try { List<VolumeVO> volumes = _volsDao.listAll(); Map<Long, List<VolumeCommand>> commandsByPool = new HashMap<Long, List<VolumeCommand>>(); for (VolumeVO volume : volumes) { List<VolumeCommand> commands = commandsByPool.get(volume.getPoolId()); if (commands == null) { commands = new ArrayList<VolumeCommand>(); commandsByPool.put(volume.getPoolId(), commands); } VolumeCommand vCommand = new VolumeCommand(); vCommand.volumeId = volume.getId(); vCommand.command = new GetFileStatsCommand(volume); commands.add(vCommand); } ConcurrentHashMap<Long, VolumeStats> volumeStats = new ConcurrentHashMap<Long, VolumeStats>(); for (Iterator<Long> iter = commandsByPool.keySet().iterator(); iter.hasNext(); ) { Long poolId = iter.next(); List<VolumeCommand> commandsList = commandsByPool.get(poolId); long[] volumeIdArray = new long[commandsList.size()]; Commands commands = new Commands(OnError.Continue); for (int i = 0; i < commandsList.size(); i++) { VolumeCommand vCommand = commandsList.get(i); volumeIdArray[i] = vCommand.volumeId; commands.addCommand(vCommand.command); } List<StoragePoolHostVO> poolhosts = _storagePoolHostDao.listByPoolId(poolId); for (StoragePoolHostVO poolhost : poolhosts) { Answer[] answers = _agentMgr.send(poolhost.getHostId(), commands); if (answers != null) { long totalBytes = 0L; for (int i = 0; i < answers.length; i++) { if (answers[i].getResult()) { VolumeStats vStats = (VolumeStats) answers[i]; volumeStats.put(volumeIdArray[i], vStats); totalBytes += vStats.getBytesUsed(); } } break; } } } // We replace the existing volumeStats so that it does not grow with no bounds _volumeStats = volumeStats; } catch (AgentUnavailableException e) { s_logger.debug(e.getMessage()); } catch (Throwable t) { s_logger.error("Error trying to retrieve volume stats", t); } }
@Override public String reserveVirtualMachine( VMEntityVO vmEntityVO, String plannerToUse, DeploymentPlan planToDeploy, ExcludeList exclude) throws InsufficientCapacityException, ResourceUnavailableException { // call planner and get the deployDestination. // load vm instance and offerings and call virtualMachineManagerImpl // FIXME: profile should work on VirtualMachineEntity VMInstanceVO vm = _vmDao.findByUuid(vmEntityVO.getUuid()); VirtualMachineProfileImpl<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vm); DataCenterDeployment plan = new DataCenterDeployment( vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { plan = new DataCenterDeployment( planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId()); } List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); if (!vols.isEmpty()) { VolumeVO vol = vols.get(0); StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); if (!pool.isInMaintenance()) { long rootVolDcId = pool.getDataCenterId(); Long rootVolPodId = pool.getPodId(); Long rootVolClusterId = pool.getClusterId(); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { Long clusterIdSpecified = planToDeploy.getClusterId(); if (clusterIdSpecified != null && rootVolClusterId != null) { if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) { // cannot satisfy the plan passed in to the // planner throw new ResourceUnavailableException( "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); } } plan = new DataCenterDeployment( planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId(), null, null); } else { plan = new DataCenterDeployment( rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, null); } } } DeploymentPlanner planner = ComponentContext.getComponent(plannerToUse); DeployDestination dest = null; if (planner.canHandle(vmProfile, plan, exclude)) { dest = planner.plan(vmProfile, plan, exclude); } if (dest != null) { // save destination with VMEntityVO VMReservationVO vmReservation = new VMReservationVO( vm.getId(), dest.getDataCenter().getId(), dest.getPod().getId(), dest.getCluster().getId(), dest.getHost().getId()); Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>(); for (Volume vo : dest.getStorageForDisks().keySet()) { volumeReservationMap.put(vo.getId(), dest.getStorageForDisks().get(vo).getId()); } vmReservation.setVolumeReservation(volumeReservationMap); vmEntityVO.setVmReservation(vmReservation); _vmEntityDao.persist(vmEntityVO); return vmReservation.getUuid(); } else { throw new InsufficientServerCapacityException( "Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); } }
@DB protected void scheduleSnapshots() { String displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, _currentTimestamp); s_logger.debug("Snapshot scheduler.poll is being called at " + displayTime); List<SnapshotScheduleVO> snapshotsToBeExecuted = _snapshotScheduleDao.getSchedulesToExecute(_currentTimestamp); s_logger.debug( "Got " + snapshotsToBeExecuted.size() + " snapshots to be executed at " + displayTime); // This is done for recurring snapshots, which are executed by the system automatically // Hence set user id to that of system long userId = 1; for (SnapshotScheduleVO snapshotToBeExecuted : snapshotsToBeExecuted) { long policyId = snapshotToBeExecuted.getPolicyId(); long volumeId = snapshotToBeExecuted.getVolumeId(); VolumeVO volume = _volsDao.findById(volumeId); if (volume.getPoolId() == null) { // this volume is not attached continue; } if (_snapshotPolicyDao.findById(policyId) == null) { _snapshotScheduleDao.remove(snapshotToBeExecuted.getId()); } if (s_logger.isDebugEnabled()) { Date scheduledTimestamp = snapshotToBeExecuted.getScheduledTimestamp(); displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, scheduledTimestamp); s_logger.debug( "Scheduling 1 snapshot for volume " + volumeId + " for schedule id: " + snapshotToBeExecuted.getId() + " at " + displayTime); } long snapshotScheId = snapshotToBeExecuted.getId(); SnapshotScheduleVO tmpSnapshotScheduleVO = null; try { tmpSnapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheId); Long eventId = EventUtils.saveScheduledEvent( User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:" + volumeId, 0); Map<String, String> params = new HashMap<String, String>(); params.put("volumeid", "" + volumeId); params.put("policyid", "" + policyId); params.put("ctxUserId", "1"); params.put("ctxAccountId", "1"); params.put("ctxStartEventId", String.valueOf(eventId)); CreateSnapshotCmd cmd = new CreateSnapshotCmd(); ApiDispatcher.getInstance().dispatchCreateCmd(cmd, params); params.put("id", "" + cmd.getEntityId()); params.put("ctxStartEventId", "1"); AsyncJobVO job = new AsyncJobVO(); job.setUserId(userId); // Just have SYSTEM own the job for now. Users won't be able to see this job, but // it's an internal job so probably not a huge deal. job.setAccountId(1L); job.setCmd(CreateSnapshotCmd.class.getName()); job.setInstanceId(cmd.getEntityId()); job.setCmdInfo(GsonHelper.getBuilder().create().toJson(params)); long jobId = _asyncMgr.submitAsyncJob(job); tmpSnapshotScheduleVO.setAsyncJobId(jobId); _snapshotScheduleDao.update(snapshotScheId, tmpSnapshotScheduleVO); } finally { if (tmpSnapshotScheduleVO != null) { _snapshotScheduleDao.releaseFromLockTable(snapshotScheId); } } } }