예제 #1
0
  @DB
  public void handleDownloadEvent(HostVO host, VolumeVO volume, Status dnldStatus) {
    if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED)
        || (dnldStatus == Status.ABANDONED)) {
      VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId());
      synchronized (_listenerVolumeMap) {
        _listenerVolumeMap.remove(volumeHost);
      }
    }

    VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId());

    Transaction txn = Transaction.currentTxn();
    txn.start();

    if (dnldStatus == Status.DOWNLOADED) {

      // Create usage event
      long size = -1;
      if (volumeHost != null) {
        size = volumeHost.getSize();
        volume.setSize(size);
        this._volumeDao.update(volume.getId(), volume);
      } else {
        s_logger.warn("Failed to get size for volume" + volume.getName());
      }
      String eventType = EventTypes.EVENT_VOLUME_UPLOAD;
      if (volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
        UsageEventUtils.publishUsageEvent(
            eventType,
            volume.getAccountId(),
            host.getDataCenterId(),
            volume.getId(),
            volume.getName(),
            null,
            0l,
            size,
            volume.getClass().getName(),
            volume.getUuid());
      }
    } else if (dnldStatus == Status.DOWNLOAD_ERROR
        || dnldStatus == Status.ABANDONED
        || dnldStatus == Status.UNKNOWN) {
      // Decrement the volume and secondary storage space count
      _resourceLimitMgr.decrementResourceCount(
          volume.getAccountId(), com.cloud.configuration.Resource.ResourceType.volume);
      _resourceLimitMgr.recalculateResourceCount(
          volume.getAccountId(),
          volume.getDomainId(),
          com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
    }
    txn.commit();
  }
    @Override
    protected void runInContext() {
      // 1. Select all entries with download_state = Not_Downloaded or Download_In_Progress
      // 2. Get corresponding volume
      // 3. Get EP using _epSelector
      // 4. Check if SSVM is owned by this MS
      // 5. If owned by MS then send command to appropriate SSVM
      // 6. In listener check for the answer and update DB accordingly
      List<VolumeDataStoreVO> volumeDataStores =
          _volumeDataStoreDao.listByVolumeState(
              Volume.State.NotUploaded, Volume.State.UploadInProgress);
      for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
        try {
          DataStore dataStore =
              storeMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
          EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
          if (ep == null) {
            s_logger.warn(
                "There is no secondary storage VM for image store " + dataStore.getName());
            continue;
          }
          VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
          if (volume == null) {
            s_logger.warn("Volume with id " + volumeDataStore.getVolumeId() + " not found");
            continue;
          }
          Host host = _hostDao.findById(ep.getId());
          UploadStatusCommand cmd = new UploadStatusCommand(volume.getUuid(), EntityType.Volume);
          if (host != null && host.getManagementServerId() != null) {
            if (_nodeId == host.getManagementServerId().longValue()) {
              Answer answer = null;
              try {
                answer = ep.sendMessage(cmd);
              } catch (CloudRuntimeException e) {
                s_logger.warn(
                    "Unable to get upload status for volume "
                        + volume.getUuid()
                        + ". Error details: "
                        + e.getMessage());
                answer = new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN, e.getMessage());
              }
              if (answer == null || !(answer instanceof UploadStatusAnswer)) {
                s_logger.warn(
                    "No or invalid answer corresponding to UploadStatusCommand for volume "
                        + volumeDataStore.getVolumeId());
                continue;
              }
              handleVolumeStatusResponse((UploadStatusAnswer) answer, volume, volumeDataStore);
            }
          } else {
            String error =
                "Volume "
                    + volume.getUuid()
                    + " failed to upload as SSVM is either destroyed or SSVM agent not in 'Up' state";
            handleVolumeStatusResponse(
                new UploadStatusAnswer(cmd, UploadStatus.ERROR, error), volume, volumeDataStore);
          }
        } catch (Throwable th) {
          s_logger.warn(
              "Exception while checking status for uploaded volume "
                  + volumeDataStore.getExtractUrl()
                  + ". Error details: "
                  + th.getMessage());
          if (s_logger.isTraceEnabled()) {
            s_logger.trace("Exception details: ", th);
          }
        }
      }

      // Handle for template upload as well
      List<TemplateDataStoreVO> templateDataStores =
          _templateDataStoreDao.listByTemplateState(
              VirtualMachineTemplate.State.NotUploaded,
              VirtualMachineTemplate.State.UploadInProgress);
      for (TemplateDataStoreVO templateDataStore : templateDataStores) {
        try {
          DataStore dataStore =
              storeMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
          EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
          if (ep == null) {
            s_logger.warn(
                "There is no secondary storage VM for image store " + dataStore.getName());
            continue;
          }
          VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
          if (template == null) {
            s_logger.warn("Template with id " + templateDataStore.getTemplateId() + " not found");
            continue;
          }
          Host host = _hostDao.findById(ep.getId());
          UploadStatusCommand cmd =
              new UploadStatusCommand(template.getUuid(), EntityType.Template);
          if (host != null && host.getManagementServerId() != null) {
            if (_nodeId == host.getManagementServerId().longValue()) {
              Answer answer = null;
              try {
                answer = ep.sendMessage(cmd);
              } catch (CloudRuntimeException e) {
                s_logger.warn(
                    "Unable to get upload status for template "
                        + template.getUuid()
                        + ". Error details: "
                        + e.getMessage());
                answer = new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN, e.getMessage());
              }
              if (answer == null || !(answer instanceof UploadStatusAnswer)) {
                s_logger.warn(
                    "No or invalid answer corresponding to UploadStatusCommand for template "
                        + templateDataStore.getTemplateId());
                continue;
              }
              handleTemplateStatusResponse(
                  (UploadStatusAnswer) answer, template, templateDataStore);
            }
          } else {
            String error =
                "Template "
                    + template.getUuid()
                    + " failed to upload as SSVM is either destroyed or SSVM agent not in 'Up' state";
            handleTemplateStatusResponse(
                new UploadStatusAnswer(cmd, UploadStatus.ERROR, error),
                template,
                templateDataStore);
          }
        } catch (Throwable th) {
          s_logger.warn(
              "Exception while checking status for uploaded template "
                  + templateDataStore.getExtractUrl()
                  + ". Error details: "
                  + th.getMessage());
          if (s_logger.isTraceEnabled()) {
            s_logger.trace("Exception details: ", th);
          }
        }
      }
    }
예제 #3
0
  @Override
  public void handleVolumeSync(HostVO ssHost) {
    if (ssHost == null) {
      s_logger.warn("Huh? ssHost is null");
      return;
    }
    long sserverId = ssHost.getId();
    if (!(ssHost.getType() == Host.Type.SecondaryStorage
        || ssHost.getType() == Host.Type.LocalSecondaryStorage)) {
      s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host");
      return;
    }

    Map<Long, TemplateInfo> volumeInfos = listVolume(ssHost);
    if (volumeInfos == null) {
      return;
    }

    List<VolumeHostVO> dbVolumes = _volumeHostDao.listBySecStorage(sserverId);
    List<VolumeHostVO> toBeDownloaded = new ArrayList<VolumeHostVO>(dbVolumes);
    for (VolumeHostVO volumeHost : dbVolumes) {
      VolumeVO volume = _volumeDao.findById(volumeHost.getVolumeId());
      // Exists then don't download
      if (volumeInfos.containsKey(volume.getId())) {
        TemplateInfo volInfo = volumeInfos.remove(volume.getId());
        toBeDownloaded.remove(volumeHost);
        s_logger.info(
            "Volume Sync found " + volume.getUuid() + " already in the volume host table");
        if (volumeHost.getDownloadState() != Status.DOWNLOADED) {
          volumeHost.setErrorString("");
        }
        if (volInfo.isCorrupted()) {
          volumeHost.setDownloadState(Status.DOWNLOAD_ERROR);
          String msg = "Volume " + volume.getUuid() + " is corrupted on secondary storage ";
          volumeHost.setErrorString(msg);
          s_logger.info("msg");
          if (volumeHost.getDownloadUrl() == null) {
            msg =
                "Volume ("
                    + volume.getUuid()
                    + ") with install path "
                    + volInfo.getInstallPath()
                    + "is corrupted, please check in secondary storage: "
                    + volumeHost.getHostId();
            s_logger.warn(msg);
          } else {
            toBeDownloaded.add(volumeHost);
          }

        } else { // Put them in right status
          volumeHost.setDownloadPercent(100);
          volumeHost.setDownloadState(Status.DOWNLOADED);
          volumeHost.setInstallPath(volInfo.getInstallPath());
          volumeHost.setSize(volInfo.getSize());
          volumeHost.setPhysicalSize(volInfo.getPhysicalSize());
          volumeHost.setLastUpdated(new Date());
          _volumeHostDao.update(volumeHost.getId(), volumeHost);

          if (volume.getSize() == 0) {
            // Set volume size in volumes table
            volume.setSize(volInfo.getSize());
            _volumeDao.update(volumeHost.getVolumeId(), volume);
          }

          if (volInfo.getSize() > 0) {
            try {
              String url = _volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl();
              _resourceLimitMgr.checkResourceLimit(
                  _accountMgr.getAccount(volume.getAccountId()),
                  com.cloud.configuration.Resource.ResourceType.secondary_storage,
                  volInfo.getSize() - UriUtils.getRemoteSize(url));
            } catch (ResourceAllocationException e) {
              s_logger.warn(e.getMessage());
              _alertMgr.sendAlert(
                  _alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED,
                  volume.getDataCenterId(),
                  volume.getPodId(),
                  e.getMessage(),
                  e.getMessage());
            } finally {
              _resourceLimitMgr.recalculateResourceCount(
                  volume.getAccountId(),
                  volume.getDomainId(),
                  com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
            }
          }
        }
        continue;
      }
      // Volume is not on secondary but we should download.
      if (volumeHost.getDownloadState() != Status.DOWNLOADED) {
        s_logger.info(
            "Volume Sync did not find "
                + volume.getName()
                + " ready on server "
                + sserverId
                + ", will request download to start/resume shortly");
        toBeDownloaded.add(volumeHost);
      }
    }

    // Download volumes which haven't been downloaded yet.
    if (toBeDownloaded.size() > 0) {
      for (VolumeHostVO volumeHost : toBeDownloaded) {
        if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download
          continue;
        }
        s_logger.debug(
            "Volume "
                + volumeHost.getVolumeId()
                + " needs to be downloaded to "
                + ssHost.getName());
        downloadVolumeToStorage(
            _volumeDao.findById(volumeHost.getVolumeId()),
            ssHost,
            volumeHost.getDownloadUrl(),
            volumeHost.getChecksum(),
            volumeHost.getFormat());
      }
    }

    // Delete volumes which are not present on DB.
    for (Long uniqueName : volumeInfos.keySet()) {
      TemplateInfo vInfo = volumeInfos.get(uniqueName);
      DeleteVolumeCommand dtCommand =
          new DeleteVolumeCommand(ssHost.getStorageUrl(), vInfo.getInstallPath());
      try {
        _agentMgr.sendToSecStorage(ssHost, dtCommand, null);
      } catch (AgentUnavailableException e) {
        String err =
            "Failed to delete "
                + vInfo.getTemplateName()
                + " on secondary storage "
                + sserverId
                + " which isn't in the database";
        s_logger.error(err);
        return;
      }

      String description =
          "Deleted volume "
              + vInfo.getTemplateName()
              + " on secondary storage "
              + sserverId
              + " since it isn't in the database";
      s_logger.info(description);
    }
  }