}
}
@Override
public AttachAnswer attachVolume(AttachCommand cmd) {
DiskTO disk = cmd.getDisk();
DataTO data = disk.getData();
try {
String vmName = cmd.getVmName();
String vdiNameLabel = vmName + "-DATA";
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 = disk.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) {
vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel);
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());
}
/* For HVM guest, if no pv driver installed, no attach/detach */
boolean isHVM = vm.getPVBootloader(conn).equalsIgnoreCase("");
VMGuestMetrics vgm = vm.getGuestMetrics(conn);
boolean pvDrvInstalled = false;
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) {
String msg = "Device 3 is reserved for CD-ROM, choose other device";
return new AttachAnswer(msg);
}
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);
}
VBD.Record vbdr = new VBD.Record();
vbdr.VM = vm;
vbdr.VDI = vdi;
vbdr.bootable = false;
vbdr.userdevice = diskNumber;
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
vbd.plug(conn);
// 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);
} catch (XenAPIException e) {
String msg = "Failed to attach volume" + " for uuid: " + data.getPath() + " due to " + e.toString();
s_logger.warn(msg, e);