Search in sources :

Example 1 with AttachAnswer

use of com.cloud.storage.command.AttachAnswer in project cosmic by MissionCriticalCloud.

the class VolumeApiServiceImpl method sendAttachVolumeCommand.

private VolumeVO sendAttachVolumeCommand(final UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) {
    String errorMsg = "Failed to attach volume " + volumeToAttach.getName() + " to VM " + vm.getHostName();
    boolean sendCommand = vm.getState() == State.Running;
    AttachAnswer answer = null;
    final Long hostId = vm.getHostId();
    HostVO host = null;
    final StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
    if (hostId != null) {
        host = _hostDao.findById(hostId);
        if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged()) {
            sendCommand = true;
        }
    }
    // volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
    final DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
    // if we don't have a host, the VM we are attaching the disk to has never been started before
    if (host != null) {
        try {
            volService.grantAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
        } catch (final Exception e) {
            volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
            throw new CloudRuntimeException(e.getMessage());
        }
    }
    if (sendCommand) {
        if (host != null && host.getHypervisorType() == HypervisorType.KVM && volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
            volumeToAttach.setPath(volumeToAttach.get_iScsiName());
            _volsDao.update(volumeToAttach.getId(), volumeToAttach);
        }
        final DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
        deviceId = getDeviceId(vm, deviceId);
        final DiskTO disk = new DiskTO(volTO, deviceId, volumeToAttach.getPath(), volumeToAttach.getVolumeType());
        final AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
        final ChapInfo chapInfo = volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore);
        final Map<String, String> details = new HashMap<>();
        disk.setDetails(details);
        details.put(DiskTO.MANAGED, String.valueOf(volumeToAttachStoragePool.isManaged()));
        details.put(DiskTO.STORAGE_HOST, volumeToAttachStoragePool.getHostAddress());
        details.put(DiskTO.STORAGE_PORT, String.valueOf(volumeToAttachStoragePool.getPort()));
        details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeToAttach.getSize()));
        details.put(DiskTO.IQN, volumeToAttach.get_iScsiName());
        details.put(DiskTO.MOUNT_POINT, volumeToAttach.get_iScsiName());
        details.put(DiskTO.PROTOCOL_TYPE, volumeToAttach.getPoolType() != null ? volumeToAttach.getPoolType().toString() : null);
        if (chapInfo != null) {
            details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
            details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
            details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
            details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
        }
        _userVmDao.loadDetails(vm);
        final Map<String, String> controllerInfo = new HashMap<>();
        controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
        controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
        cmd.setControllerInfo(controllerInfo);
        try {
            answer = (AttachAnswer) _agentMgr.send(hostId, cmd);
        } catch (final Exception e) {
            if (host != null) {
                volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
            }
            throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
        }
    }
    if (!sendCommand || answer != null && answer.getResult()) {
        // Mark the volume as attached
        if (sendCommand) {
            final DiskTO disk = answer.getDisk();
            _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), disk.getDiskSeq());
            volumeToAttach = _volsDao.findById(volumeToAttach.getId());
            if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
                volumeToAttach.setPath(answer.getDisk().getPath());
                _volsDao.update(volumeToAttach.getId(), volumeToAttach);
            }
        } else {
            deviceId = getDeviceId(vm, deviceId);
            _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
        }
        // insert record for disk I/O statistics
        VmDiskStatisticsVO diskstats = _vmDiskStatsDao.findBy(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
        if (diskstats == null) {
            diskstats = new VmDiskStatisticsVO(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
            _vmDiskStatsDao.persist(diskstats);
        }
        return _volsDao.findById(volumeToAttach.getId());
    } else {
        if (answer != null) {
            final String details = answer.getDetails();
            if (details != null && !details.isEmpty()) {
                errorMsg += "; " + details;
            }
        }
        if (host != null) {
            volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
        }
        throw new CloudRuntimeException(errorMsg);
    }
}
Also used : HashMap(java.util.HashMap) ChapInfo(com.cloud.engine.subsystem.api.storage.ChapInfo) VmDiskStatisticsVO(com.cloud.user.VmDiskStatisticsVO) HostVO(com.cloud.host.HostVO) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) CloudException(com.cloud.exception.CloudException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) MalformedURLException(java.net.MalformedURLException) AttachCommand(com.cloud.storage.command.AttachCommand) DataTO(com.cloud.agent.api.to.DataTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) StoragePoolVO(com.cloud.storage.datastore.db.StoragePoolVO) AttachAnswer(com.cloud.storage.command.AttachAnswer) DiskTO(com.cloud.agent.api.to.DiskTO)

Example 2 with AttachAnswer

use of com.cloud.storage.command.AttachAnswer in project cosmic by MissionCriticalCloud.

the class KvmStorageProcessor method attachVolume.

@Override
public Answer attachVolume(final AttachCommand cmd) {
    final DiskTO disk = cmd.getDisk();
    final VolumeObjectTO vol = (VolumeObjectTO) disk.getData();
    final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) vol.getDataStore();
    final String vmName = cmd.getVmName();
    final String serial = disk.getDiskSeq() + "-" + resource.diskUuidToSerial(vol.getUuid());
    try {
        final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
        storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath(), disk.getDetails());
        final KvmPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
        attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue(), serial);
        return new AttachAnswer(disk);
    } catch (final LibvirtException e) {
        logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
        storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
        return new AttachAnswer(e.toString());
    } catch (final InternalErrorException e) {
        logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
        return new AttachAnswer(e.toString());
    }
}
Also used : LibvirtException(org.libvirt.LibvirtException) PrimaryDataStoreTO(com.cloud.storage.to.PrimaryDataStoreTO) Connect(org.libvirt.Connect) VolumeObjectTO(com.cloud.storage.to.VolumeObjectTO) InternalErrorException(com.cloud.exception.InternalErrorException) DiskTO(com.cloud.agent.api.to.DiskTO) AttachAnswer(com.cloud.storage.command.AttachAnswer)

Example 3 with AttachAnswer

use of com.cloud.storage.command.AttachAnswer in project cosmic by MissionCriticalCloud.

the class XenServerStorageProcessor method attachIso.

@Override
public AttachAnswer attachIso(final AttachCommand cmd) {
    final DiskTO disk = cmd.getDisk();
    final DataTO data = disk.getData();
    final DataStoreTO store = data.getDataStore();
    String isoURL = null;
    if (store == null) {
        final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
        isoURL = iso.getName();
    } else {
        if (!(store instanceof NfsTO)) {
            s_logger.debug("Can't attach a iso which is not created on nfs: ");
            return new AttachAnswer("Can't attach a iso which is not created on nfs: ");
        }
        final NfsTO nfsStore = (NfsTO) store;
        isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath();
    }
    final String vmName = cmd.getVmName();
    try {
        final Connection conn = hypervisorResource.getConnection();
        VBD isoVBD = null;
        // Find the VM
        final VM vm = hypervisorResource.getVM(conn, vmName);
        // Find the ISO VDI
        final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, vmName, isoURL);
        // Find the VM's CD-ROM VBD
        final Set<VBD> vbds = vm.getVBDs(conn);
        for (final VBD vbd : vbds) {
            final String userDevice = vbd.getUserdevice(conn);
            final Types.VbdType type = vbd.getType(conn);
            if (userDevice.equals("3") && type == Types.VbdType.CD) {
                isoVBD = vbd;
                break;
            }
        }
        if (isoVBD == null) {
            throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: " + vmName);
        } else {
            // If an ISO is already inserted, eject it
            if (!isoVBD.getEmpty(conn)) {
                isoVBD.eject(conn);
            }
            // Insert the new ISO
            isoVBD.insert(conn, isoVDI);
        }
        return new AttachAnswer(disk);
    } catch (final XenAPIException e) {
        s_logger.warn("Failed to attach iso" + ": " + e.toString(), e);
        return new AttachAnswer(e.toString());
    } catch (final Exception e) {
        s_logger.warn("Failed to attach iso" + ": " + e.toString(), e);
        return new AttachAnswer(e.toString());
    }
}
Also used : Types(com.xensource.xenapi.Types) PrimaryDataStoreTO(com.cloud.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) Connection(com.xensource.xenapi.Connection) XenAPIException(com.xensource.xenapi.Types.XenAPIException) NfsTO(com.cloud.agent.api.to.NfsTO) XenAPIException(com.xensource.xenapi.Types.XenAPIException) InternalErrorException(com.cloud.exception.InternalErrorException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataTO(com.cloud.agent.api.to.DataTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VM(com.xensource.xenapi.VM) VBD(com.xensource.xenapi.VBD) VDI(com.xensource.xenapi.VDI) TemplateObjectTO(com.cloud.storage.to.TemplateObjectTO) DiskTO(com.cloud.agent.api.to.DiskTO) AttachAnswer(com.cloud.storage.command.AttachAnswer)

Example 4 with AttachAnswer

use of com.cloud.storage.command.AttachAnswer in project cosmic by MissionCriticalCloud.

the class XenServerStorageProcessor method attachVolume.

@Override
public AttachAnswer attachVolume(final AttachCommand cmd) {
    final DiskTO disk = cmd.getDisk();
    final DataTO data = disk.getData();
    try {
        final String vmName = cmd.getVmName();
        final String vdiNameLabel = vmName + "-DATA";
        final Connection conn = hypervisorResource.getConnection();
        VM vm = null;
        boolean vmNotRunning = true;
        try {
            vm = hypervisorResource.getVM(conn, vmName);
            final VM.Record vmr = vm.getRecord(conn);
            vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
        } catch (final CloudRuntimeException ex) {
        }
        final Map<String, String> details = disk.getDetails();
        final boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
        // this should probably never actually happen
        if (vmNotRunning && !isManaged) {
            return new AttachAnswer(disk);
        }
        VDI vdi = null;
        if (isManaged) {
            vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel);
            if (vmNotRunning) {
                final DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType());
                return new AttachAnswer(newDisk);
            }
        } else {
            vdi = hypervisorResource.mount(conn, null, null, data.getPath());
        }
        hypervisorResource.destroyUnattachedVBD(conn, vm);
        final VBD.Record vbdr = new VBD.Record();
        vbdr.VM = vm;
        vbdr.VDI = vdi;
        vbdr.bootable = false;
        vbdr.userdevice = "autodetect";
        final Long deviceId = disk.getDiskSeq();
        if (deviceId != null && !hypervisorResource.isDeviceUsed(conn, vm, deviceId)) {
            vbdr.userdevice = deviceId.toString();
        }
        vbdr.mode = Types.VbdMode.RW;
        vbdr.type = Types.VbdType.DISK;
        vbdr.unpluggable = true;
        final VBD vbd = VBD.create(conn, vbdr);
        // Attach the VBD to the VM
        try {
            vbd.plug(conn);
        } catch (final Exception e) {
            vbd.destroy(conn);
            throw e;
        }
        // Update the VDI's label to include the VM name
        vdi.setNameLabel(conn, vdiNameLabel);
        final DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(vbd.getUserdevice(conn)), vdi.getUuid(conn), disk.getType());
        return new AttachAnswer(newDisk);
    } catch (final Exception e) {
        final String msg = "Failed to attach volume for uuid: " + data.getPath() + " due to " + e.toString();
        s_logger.warn(msg, e);
        return new AttachAnswer(msg);
    }
}
Also used : Connection(com.xensource.xenapi.Connection) XenAPIException(com.xensource.xenapi.Types.XenAPIException) InternalErrorException(com.cloud.exception.InternalErrorException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataTO(com.cloud.agent.api.to.DataTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VM(com.xensource.xenapi.VM) VBD(com.xensource.xenapi.VBD) VDI(com.xensource.xenapi.VDI) DiskTO(com.cloud.agent.api.to.DiskTO) AttachAnswer(com.cloud.storage.command.AttachAnswer)

Example 5 with AttachAnswer

use of com.cloud.storage.command.AttachAnswer in project cosmic by MissionCriticalCloud.

the class XenServerStorageProcessor method dettachIso.

@Override
public Answer dettachIso(final DettachCommand cmd) {
    final DiskTO disk = cmd.getDisk();
    final DataTO data = disk.getData();
    final DataStoreTO store = data.getDataStore();
    String isoURL = null;
    if (store == null) {
        final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
        isoURL = iso.getName();
    } else {
        if (!(store instanceof NfsTO)) {
            s_logger.debug("Can't attach a iso which is not created on nfs: ");
            return new AttachAnswer("Can't attach a iso which is not created on nfs: ");
        }
        final NfsTO nfsStore = (NfsTO) store;
        isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath();
    }
    try {
        final Connection conn = hypervisorResource.getConnection();
        // Find the VM
        final VM vm = hypervisorResource.getVM(conn, cmd.getVmName());
        final String vmUUID = vm.getUuid(conn);
        // Find the ISO VDI
        final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, cmd.getVmName(), isoURL);
        final SR sr = isoVDI.getSR(conn);
        // Look up all VBDs for this VDI
        final Set<VBD> vbds = isoVDI.getVBDs(conn);
        // the ISO from it
        for (final VBD vbd : vbds) {
            final VM vbdVM = vbd.getVM(conn);
            final String vbdVmUUID = vbdVM.getUuid(conn);
            if (vbdVmUUID.equals(vmUUID)) {
                // If an ISO is already inserted, eject it
                if (!vbd.getEmpty(conn)) {
                    vbd.eject(conn);
                }
                break;
            }
        }
        if (!sr.getNameLabel(conn).startsWith("XenServer Tools")) {
            hypervisorResource.removeSR(conn, sr);
        }
        return new DettachAnswer(disk);
    } catch (final XenAPIException e) {
        final String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + "  due to " + e.toString();
        s_logger.warn(msg, e);
        return new DettachAnswer(msg);
    } catch (final Exception e) {
        final String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + "  due to " + e.getMessage();
        s_logger.warn(msg, e);
        return new DettachAnswer(msg);
    }
}
Also used : PrimaryDataStoreTO(com.cloud.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) DettachAnswer(com.cloud.storage.command.DettachAnswer) Connection(com.xensource.xenapi.Connection) XenAPIException(com.xensource.xenapi.Types.XenAPIException) NfsTO(com.cloud.agent.api.to.NfsTO) XenAPIException(com.xensource.xenapi.Types.XenAPIException) InternalErrorException(com.cloud.exception.InternalErrorException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataTO(com.cloud.agent.api.to.DataTO) VM(com.xensource.xenapi.VM) VBD(com.xensource.xenapi.VBD) VDI(com.xensource.xenapi.VDI) TemplateObjectTO(com.cloud.storage.to.TemplateObjectTO) DiskTO(com.cloud.agent.api.to.DiskTO) AttachAnswer(com.cloud.storage.command.AttachAnswer) SR(com.xensource.xenapi.SR)

Aggregations

DiskTO (com.cloud.agent.api.to.DiskTO)9 AttachAnswer (com.cloud.storage.command.AttachAnswer)9 InternalErrorException (com.cloud.exception.InternalErrorException)6 PrimaryDataStoreTO (com.cloud.storage.to.PrimaryDataStoreTO)5 Answer (com.cloud.agent.api.Answer)4 DataStoreTO (com.cloud.agent.api.to.DataStoreTO)4 DataTO (com.cloud.agent.api.to.DataTO)4 NfsTO (com.cloud.agent.api.to.NfsTO)4 TemplateObjectTO (com.cloud.storage.to.TemplateObjectTO)4 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)4 AttachCommand (com.cloud.storage.command.AttachCommand)3 DettachAnswer (com.cloud.storage.command.DettachAnswer)3 Connection (com.xensource.xenapi.Connection)3 XenAPIException (com.xensource.xenapi.Types.XenAPIException)3 VBD (com.xensource.xenapi.VBD)3 VDI (com.xensource.xenapi.VDI)3 VM (com.xensource.xenapi.VM)3 XmlRpcException (org.apache.xmlrpc.XmlRpcException)3 PrimaryStorageDownloadAnswer (com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer)2 CopyCmdAnswer (com.cloud.storage.command.CopyCmdAnswer)2