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);
}
}
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());
}
}
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());
}
}
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);
}
}
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);
}
}
Aggregations