mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-4810: Enable hypervisor snapshots for CloudStack-managed storage (for XenServer and VMware)
This commit is contained in:
parent
497feab841
commit
0ddbae580e
|
|
@ -4818,13 +4818,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
auth.setChapName(chapName);
|
||||
auth.setChapSecret(chapSecret);
|
||||
|
||||
if (StringUtils.isNotBlank(mutualChapName) &&
|
||||
StringUtils.isNotBlank(mutualChapSecret)) {
|
||||
auth.setMutualChapInherited(false);
|
||||
auth.setMutualChapAuthenticationType(strAuthType);
|
||||
auth.setMutualChapName(mutualChapName);
|
||||
auth.setMutualChapSecret(mutualChapSecret);
|
||||
}
|
||||
auth.setMutualChapInherited(false);
|
||||
auth.setMutualChapAuthenticationType(strAuthType);
|
||||
auth.setMutualChapName(mutualChapName);
|
||||
auth.setMutualChapSecret(mutualChapSecret);
|
||||
|
||||
target.setAuthenticationProperties(auth);
|
||||
|
||||
|
|
|
|||
|
|
@ -1192,14 +1192,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException {
|
||||
protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType) throws XmlRpcException, XenAPIException {
|
||||
Volume.Type type = volume.getType();
|
||||
|
||||
if (vdi == null) {
|
||||
vdi = mount(conn, vmName, volume);
|
||||
}
|
||||
VDI vdi = mount(conn, vmName, volume);
|
||||
|
||||
if ( vdi != null ) {
|
||||
if ("detached".equals(vdi.getNameLabel(conn))) {
|
||||
vdi.setNameLabel(conn, vmName + "-DATA");
|
||||
}
|
||||
|
||||
Map<String, String> smConfig = vdi.getSmConfig(conn);
|
||||
for (String key : smConfig.keySet()) {
|
||||
if (key.startsWith("host_")) {
|
||||
|
|
@ -1684,37 +1686,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
vm = createVmFromTemplate(conn, vmSpec, host);
|
||||
|
||||
for (DiskTO disk : vmSpec.getDisks()) {
|
||||
VDI vdi = null;
|
||||
|
||||
if (disk.getData() instanceof VolumeObjectTO) {
|
||||
Map<String, String> details = disk.getDetails();
|
||||
boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
|
||||
|
||||
if (isManaged) {
|
||||
String iScsiName = details.get(DiskTO.IQN);
|
||||
String storageHost = details.get(DiskTO.STORAGE_HOST);
|
||||
String chapInitiatorUsername = disk.getDetails().get(DiskTO.CHAP_INITIATOR_USERNAME);
|
||||
String chapInitiatorSecret = disk.getDetails().get(DiskTO.CHAP_INITIATOR_SECRET);
|
||||
Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
|
||||
String vdiNameLabel = vmName + "-DATA";
|
||||
|
||||
SR sr = getIscsiSR(conn, iScsiName, storageHost, iScsiName,
|
||||
chapInitiatorUsername, chapInitiatorSecret, true);
|
||||
|
||||
vdi = getVDIbyUuid(conn, disk.getPath(), false);
|
||||
|
||||
if (vdi == null) {
|
||||
vdi = createVdi(sr, vdiNameLabel, volumeSize);
|
||||
|
||||
iqnToPath.put(iScsiName, vdi.getUuid(conn));
|
||||
}
|
||||
else {
|
||||
vdi.setNameLabel(conn, vdiNameLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), vdi);
|
||||
createVbd(conn, disk, vmName, vm, vmSpec.getBootloader());
|
||||
}
|
||||
|
||||
if (vmSpec.getType() != VirtualMachine.Type.User) {
|
||||
|
|
@ -1821,46 +1793,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
s_logger.debug("The VM is in stopped state, detected problem during startup : " + vmName);
|
||||
}
|
||||
}
|
||||
|
||||
if (state != State.Running) {
|
||||
disconnectManagedVolumes(conn, vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void disconnectManagedVolumes(Connection conn, VM vm) {
|
||||
try {
|
||||
Set<VBD> vbds = vm.getVBDs(conn);
|
||||
|
||||
for (VBD vbd : vbds) {
|
||||
VDI vdi = vbd.getVDI(conn);
|
||||
SR sr = null;
|
||||
|
||||
try {
|
||||
sr = vdi.getSR(conn);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sr.getNameLabel(conn).startsWith("/iqn.")) {
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
|
||||
if (vbdr.currentlyAttached) {
|
||||
vbd.unplug(conn);
|
||||
}
|
||||
|
||||
vbd.destroy(conn);
|
||||
|
||||
vdi.setNameLabel(conn, "detached");
|
||||
|
||||
umount(conn, vdi);
|
||||
|
||||
handleSrAndVdiDetach(sr.getNameLabel(conn));
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
s_logger.debug(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4061,8 +3993,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
|
||||
try {
|
||||
if (vm.getPowerState(conn) == VmPowerState.HALTED) {
|
||||
disconnectManagedVolumes(conn, vm);
|
||||
|
||||
Set<VIF> vifs = vm.getVIFs(conn);
|
||||
List<Network> networks = new ArrayList<Network>();
|
||||
for (VIF vif : vifs) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import com.xensource.xenapi.Pool;
|
|||
import com.xensource.xenapi.SR;
|
||||
import com.xensource.xenapi.Types;
|
||||
import com.xensource.xenapi.Types.BadServerResponse;
|
||||
import com.xensource.xenapi.Types.VmPowerState;
|
||||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
import com.xensource.xenapi.VBD;
|
||||
import com.xensource.xenapi.VDI;
|
||||
|
|
@ -164,19 +165,39 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
|
||||
@Override
|
||||
public AttachAnswer attachVolume(AttachCommand cmd) {
|
||||
String vmName = cmd.getVmName();
|
||||
String vdiNameLabel = vmName + "-DATA";
|
||||
DiskTO disk = cmd.getDisk();
|
||||
DataTO data = disk.getData();
|
||||
|
||||
try {
|
||||
Connection conn = hypervisorResource.getConnection();
|
||||
String vmName = cmd.getVmName();
|
||||
String vdiNameLabel = vmName + "-DATA";
|
||||
|
||||
VDI vdi = null;
|
||||
Connection conn = this.hypervisorResource.getConnection();
|
||||
VM vm = null;
|
||||
|
||||
boolean vmNotRunning = true;
|
||||
|
||||
try {
|
||||
vm = this.hypervisorResource.getVM(conn, vmName);
|
||||
|
||||
VM.Record vmr = vm.getRecord(conn);
|
||||
|
||||
vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
|
||||
}
|
||||
catch (CloudRuntimeException ex) {
|
||||
}
|
||||
|
||||
Map<String, String> details = cmd.getDisk().getDetails();
|
||||
boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
|
||||
|
||||
// if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here)
|
||||
// this should probably never actually happen
|
||||
if (vmNotRunning && !isManaged) {
|
||||
return new AttachAnswer(disk);
|
||||
}
|
||||
|
||||
VDI vdi = null;
|
||||
|
||||
if (isManaged) {
|
||||
String iScsiName = details.get(DiskTO.IQN);
|
||||
String storageHost = details.get(DiskTO.STORAGE_HOST);
|
||||
|
|
@ -184,56 +205,64 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
String chapInitiatorSecret = disk.getDetails().get(DiskTO.CHAP_INITIATOR_SECRET);
|
||||
Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
|
||||
|
||||
SR sr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName,
|
||||
chapInitiatorUsername, chapInitiatorSecret, true);
|
||||
SR sr = this.hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true);
|
||||
|
||||
vdi = hypervisorResource.getVDIbyUuid(conn, data.getPath(), false);
|
||||
|
||||
if (vdi == null) {
|
||||
vdi = hypervisorResource.createVdi(sr, vdiNameLabel, volumeSize);
|
||||
}
|
||||
|
||||
if (vmNotRunning) {
|
||||
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());
|
||||
}
|
||||
|
||||
// Look up the VM
|
||||
VM vm = hypervisorResource.getVM(conn, vmName);
|
||||
/* For HVM guest, if no pv driver installed, no attach/detach */
|
||||
boolean isHVM;
|
||||
if (vm.getPVBootloader(conn).equalsIgnoreCase("")) {
|
||||
isHVM = true;
|
||||
} else {
|
||||
isHVM = false;
|
||||
}
|
||||
boolean isHVM = vm.getPVBootloader(conn).equalsIgnoreCase("");
|
||||
|
||||
VMGuestMetrics vgm = vm.getGuestMetrics(conn);
|
||||
boolean pvDrvInstalled = false;
|
||||
if (!hypervisorResource.isRefNull(vgm) && vgm.getPVDriversUpToDate(conn)) {
|
||||
|
||||
if (!this.hypervisorResource.isRefNull(vgm) && vgm.getPVDriversUpToDate(conn)) {
|
||||
pvDrvInstalled = true;
|
||||
}
|
||||
|
||||
if (isHVM && !pvDrvInstalled) {
|
||||
s_logger.warn(": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected");
|
||||
|
||||
return new AttachAnswer("You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso.");
|
||||
}
|
||||
|
||||
// Figure out the disk number to attach the VM to
|
||||
String diskNumber = null;
|
||||
Long deviceId = disk.getDiskSeq();
|
||||
if( deviceId != null ) {
|
||||
if( deviceId.longValue() == 3 ) {
|
||||
|
||||
if (deviceId != null) {
|
||||
if (deviceId.longValue() == 3) {
|
||||
String msg = "Device 3 is reserved for CD-ROM, choose other device";
|
||||
|
||||
return new AttachAnswer(msg);
|
||||
}
|
||||
if(hypervisorResource.isDeviceUsed(conn, vm, deviceId)) {
|
||||
|
||||
if (this.hypervisorResource.isDeviceUsed(conn, vm, deviceId)) {
|
||||
String msg = "Device " + deviceId + " is used in VM " + vmName;
|
||||
|
||||
return new AttachAnswer(msg);
|
||||
}
|
||||
|
||||
diskNumber = deviceId.toString();
|
||||
} else {
|
||||
diskNumber = hypervisorResource.getUnusedDeviceNum(conn, vm);
|
||||
}
|
||||
// Create a new VBD
|
||||
|
||||
VBD.Record vbdr = new VBD.Record();
|
||||
|
||||
vbdr.VM = vm;
|
||||
vbdr.VDI = vdi;
|
||||
vbdr.bootable = false;
|
||||
|
|
@ -241,6 +270,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
vbdr.mode = Types.VbdMode.RW;
|
||||
vbdr.type = Types.VbdType.DISK;
|
||||
vbdr.unpluggable = true;
|
||||
|
||||
VBD vbd = VBD.create(conn, vbdr);
|
||||
|
||||
// Attach the VBD to the VM
|
||||
|
|
@ -248,9 +278,10 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
|
||||
// Update the VDI's label to include the VM name
|
||||
vdi.setNameLabel(conn, vdiNameLabel);
|
||||
DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(diskNumber), vdi.getUuid(conn), disk.getType());
|
||||
return new AttachAnswer(newDisk);
|
||||
|
||||
DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(diskNumber), vdi.getUuid(conn), disk.getType());
|
||||
|
||||
return new AttachAnswer(newDisk);
|
||||
} catch (XenAPIException e) {
|
||||
String msg = "Failed to attach volume" + " for uuid: " + data.getPath() + " due to " + e.toString();
|
||||
s_logger.warn(msg, e);
|
||||
|
|
@ -326,55 +357,73 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Answer dettachVolume(DettachCommand cmd) {
|
||||
String vmName = cmd.getVmName();
|
||||
DiskTO disk = cmd.getDisk();
|
||||
DataTO data = disk.getData();
|
||||
|
||||
try {
|
||||
Connection conn = hypervisorResource.getConnection();
|
||||
// Look up the VDI
|
||||
VDI vdi = hypervisorResource.mount(conn, null, null, data.getPath());
|
||||
// Look up the VM
|
||||
VM vm = hypervisorResource.getVM(conn, vmName);
|
||||
/* For HVM guest, if no pv driver installed, no attach/detach */
|
||||
boolean isHVM;
|
||||
if (vm.getPVBootloader(conn).equalsIgnoreCase("")) {
|
||||
isHVM = true;
|
||||
} else {
|
||||
isHVM = false;
|
||||
Connection conn = this.hypervisorResource.getConnection();
|
||||
|
||||
String vmName = cmd.getVmName();
|
||||
VM vm = null;
|
||||
|
||||
boolean vmNotRunning = true;
|
||||
|
||||
try {
|
||||
vm = this.hypervisorResource.getVM(conn, vmName);
|
||||
|
||||
VM.Record vmr = vm.getRecord(conn);
|
||||
|
||||
vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
|
||||
}
|
||||
VMGuestMetrics vgm = vm.getGuestMetrics(conn);
|
||||
boolean pvDrvInstalled = false;
|
||||
if (!hypervisorResource.isRefNull(vgm) && vgm.getPVDriversUpToDate(conn)) {
|
||||
pvDrvInstalled = true;
|
||||
}
|
||||
if (isHVM && !pvDrvInstalled) {
|
||||
s_logger.warn(": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected");
|
||||
return new DettachAnswer("You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso.");
|
||||
catch (CloudRuntimeException ex) {
|
||||
}
|
||||
|
||||
// if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here)
|
||||
// this should probably never actually happen
|
||||
if (vmNotRunning && !cmd.isManaged()) {
|
||||
return new DettachAnswer(disk);
|
||||
}
|
||||
|
||||
// Look up all VBDs for this VDI
|
||||
Set<VBD> vbds = vdi.getVBDs(conn);
|
||||
if (!vmNotRunning) {
|
||||
/* For HVM guest, if no pv driver installed, no attach/detach */
|
||||
boolean isHVM = vm.getPVBootloader(conn).equalsIgnoreCase("");
|
||||
|
||||
// Detach each VBD from its VM, and then destroy it
|
||||
for (VBD vbd : vbds) {
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
VMGuestMetrics vgm = vm.getGuestMetrics(conn);
|
||||
boolean pvDrvInstalled = false;
|
||||
|
||||
if (vbdr.currentlyAttached) {
|
||||
vbd.unplug(conn);
|
||||
if (!this.hypervisorResource.isRefNull(vgm) && vgm.getPVDriversUpToDate(conn)) {
|
||||
pvDrvInstalled = true;
|
||||
}
|
||||
|
||||
vbd.destroy(conn);
|
||||
if (isHVM && !pvDrvInstalled) {
|
||||
s_logger.warn(": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected");
|
||||
return new DettachAnswer("You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso.");
|
||||
}
|
||||
|
||||
VDI vdi = this.hypervisorResource.mount(conn, null, null, data.getPath());
|
||||
|
||||
// Look up all VBDs for this VDI
|
||||
Set<VBD> vbds = vdi.getVBDs(conn);
|
||||
|
||||
// Detach each VBD from its VM, and then destroy it
|
||||
for (VBD vbd : vbds) {
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
|
||||
if (vbdr.currentlyAttached) {
|
||||
vbd.unplug(conn);
|
||||
}
|
||||
|
||||
vbd.destroy(conn);
|
||||
}
|
||||
|
||||
// Update the VDI's label to be "detached"
|
||||
vdi.setNameLabel(conn, "detached");
|
||||
|
||||
this.hypervisorResource.umount(conn, vdi);
|
||||
}
|
||||
|
||||
// Update the VDI's label to be "detached"
|
||||
vdi.setNameLabel(conn, "detached");
|
||||
|
||||
hypervisorResource.umount(conn, vdi);
|
||||
|
||||
if (cmd.isManaged()) {
|
||||
hypervisorResource.handleSrAndVdiDetach(cmd.get_iScsiName());
|
||||
}
|
||||
|
|
@ -386,7 +435,6 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected SR getSRByNameLabel(Connection conn, String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException {
|
||||
Set<SR> srs = SR.getByNameLabel(conn, nameLabel);
|
||||
if (srs.size() != 1) {
|
||||
|
|
|
|||
|
|
@ -217,22 +217,13 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
|||
|
||||
String chapInitiatorSecret = accountDetail.getValue();
|
||||
|
||||
StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(volumeInfo.getPoolId(), SolidFireUtil.USE_MUTUAL_CHAP_FOR_VMWARE);
|
||||
accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_TARGET_USERNAME);
|
||||
|
||||
boolean useMutualChapForVMware = new Boolean(storagePoolDetail.getValue());
|
||||
String chapTargetUsername = accountDetail.getValue();
|
||||
|
||||
String chapTargetUsername = null;
|
||||
String chapTargetSecret = null;
|
||||
accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_TARGET_SECRET);
|
||||
|
||||
if (useMutualChapForVMware) {
|
||||
accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_TARGET_USERNAME);
|
||||
|
||||
chapTargetUsername = accountDetail.getValue();
|
||||
|
||||
accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_TARGET_SECRET);
|
||||
|
||||
chapTargetSecret = accountDetail.getValue();
|
||||
}
|
||||
String chapTargetSecret = accountDetail.getValue();
|
||||
|
||||
return new ChapInfoImpl(chapInitiatorUsername, chapInitiatorSecret,
|
||||
chapTargetUsername, chapTargetSecret);
|
||||
|
|
|
|||
|
|
@ -168,23 +168,6 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
|
|||
details.put(SolidFireUtil.CLUSTER_DEFAULT_MAX_IOPS, String.valueOf(lClusterDefaultMaxIops));
|
||||
details.put(SolidFireUtil.CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS, String.valueOf(fClusterDefaultBurstIopsPercentOfMaxIops));
|
||||
|
||||
String useMutualChapForVMware = Boolean.TRUE.toString();
|
||||
|
||||
try {
|
||||
useMutualChapForVMware = getValue(SolidFireUtil.USE_MUTUAL_CHAP_FOR_VMWARE, url);
|
||||
|
||||
if (useMutualChapForVMware == null || new Boolean(useMutualChapForVMware)) {
|
||||
useMutualChapForVMware = Boolean.TRUE.toString();
|
||||
}
|
||||
else {
|
||||
useMutualChapForVMware = Boolean.FALSE.toString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
}
|
||||
|
||||
details.put(SolidFireUtil.USE_MUTUAL_CHAP_FOR_VMWARE, useMutualChapForVMware);
|
||||
|
||||
// this adds a row in the cloud.storage_pool table for this SolidFire cluster
|
||||
return dataStoreHelper.createPrimaryDataStore(parameters);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,6 @@ public class SolidFireUtil
|
|||
public static final String CHAP_TARGET_USERNAME = "chapTargetUsername";
|
||||
public static final String CHAP_TARGET_SECRET = "chapTargetSecret";
|
||||
|
||||
public static final String USE_MUTUAL_CHAP_FOR_VMWARE = "useMutualChapForVMware";
|
||||
|
||||
public static long createSolidFireVolume(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword,
|
||||
String strSfVolumeName, long lSfAccountId, long lTotalSize, boolean bEnable512e, final String strCloudStackVolumeSize,
|
||||
long lMinIops, long lMaxIops, long lBurstIops)
|
||||
|
|
|
|||
|
|
@ -1454,11 +1454,19 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
}
|
||||
}
|
||||
|
||||
StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId());
|
||||
|
||||
if (hostId != null) {
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
|
||||
if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumePool.isManaged()) {
|
||||
sendCommand = true;
|
||||
}
|
||||
}
|
||||
|
||||
Answer answer = null;
|
||||
|
||||
if (sendCommand) {
|
||||
StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId());
|
||||
|
||||
DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
|
||||
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
|
||||
|
||||
|
|
@ -1867,21 +1875,28 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
boolean sendCommand = (vm.getState() == State.Running);
|
||||
AttachAnswer answer = null;
|
||||
Long hostId = vm.getHostId();
|
||||
|
||||
if (hostId == null) {
|
||||
hostId = vm.getLastHostId();
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
|
||||
if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
|
||||
sendCommand = true;
|
||||
}
|
||||
}
|
||||
|
||||
StoragePoolVO volumeToAttachStoragePool = null;
|
||||
HostVO host = null;
|
||||
StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
|
||||
|
||||
if (hostId != null) {
|
||||
host = _hostDao.findById(hostId);
|
||||
|
||||
if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumeToAttachStoragePool.isManaged()) {
|
||||
sendCommand = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendCommand) {
|
||||
volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
|
||||
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
|
||||
if (host.getHypervisorType() == HypervisorType.KVM &&
|
||||
volumeToAttachStoragePool.isManaged() &&
|
||||
volumeToAttach.getPath() == null) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue