Merge pull request #1121 from shapeblue/4.6-cloudstack-9083

[4.6] CLOUDSTACK-9083: Add disk serial to kvm virt xmlAdds disk serial ids based on volume uuids to the virt xml. This may be useful
for appliances/software that needs some serial ids on the VM disks. This does not
impact existing/running VMs, the vm virt xmls will be updates for running VMs
the next time they are stopped/started.

For testing, disk serial (of debian based systemvm) in the virt xml matched that
in /sys/devices/pci0000:00:0000:00:07.0/virtio4/block/vda/serial.

We currently don't support scsi-blcok devices for which serial is not supported,
for this we've added a DeviceType (LUN) which may be used in future and a check
to not add the serial to the xml if disk type is LUN.
Refer: https://libvirt.org/formatdomain.html#elementsDisks

* pr/1121:
  CLOUDSTACK-9083: Add disk serial to kvm virt xml

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2015-11-30 15:10:31 +05:30
commit 7dcc6540e7
4 changed files with 30 additions and 4 deletions

View File

@ -2140,6 +2140,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (data instanceof VolumeObjectTO) {
final VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data;
disk.setSerial(diskUuidToSerial(volumeObjectTO.getUuid()));
if (volumeObjectTO.getBytesReadRate() != null && volumeObjectTO.getBytesReadRate() > 0) {
disk.setBytesReadRate(volumeObjectTO.getBytesReadRate());
}
@ -2419,6 +2420,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
public String diskUuidToSerial(String uuid) {
String uuidWithoutHyphen = uuid.replace("-","");
return uuidWithoutHyphen.substring(0, Math.min(uuidWithoutHyphen.length(), 20));
}
private String getIqn() {
try {
final String textToFind = "InitiatorName=";

View File

@ -419,7 +419,7 @@ public class LibvirtVMDef {
public static class DiskDef {
public enum DeviceType {
FLOPPY("floppy"), DISK("disk"), CDROM("cdrom");
FLOPPY("floppy"), DISK("disk"), CDROM("cdrom"), LUN("lun");
String _type;
DeviceType(String type) {
@ -524,6 +524,7 @@ public class LibvirtVMDef {
private Long _iopsReadRate;
private Long _iopsWriteRate;
private DiskCacheMode _diskCacheMode;
private String _serial;
private boolean qemuDriver = true;
public void setDeviceType(DeviceType deviceType) {
@ -708,6 +709,10 @@ public class LibvirtVMDef {
this.qemuDriver = qemuDriver;
}
public void setSerial(String serial) {
this._serial = serial;
}
@Override
public String toString() {
StringBuilder diskBuilder = new StringBuilder();
@ -761,6 +766,10 @@ public class LibvirtVMDef {
}
diskBuilder.append("/>\n");
if (_serial != null && !_serial.isEmpty() && _deviceType != DeviceType.LUN) {
diskBuilder.append("<serial>" + _serial + "</serial>");
}
if ((_deviceType != DeviceType.CDROM) &&
(s_libvirtVersion >= 9008) &&
(s_qemuVersion >= 1001000) &&

View File

@ -950,7 +950,7 @@ public class KVMStorageProcessor implements StorageProcessor {
return null;
}
protected synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final int devId) throws LibvirtException,
protected synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final int devId, final String serial) throws LibvirtException,
InternalErrorException {
List<DiskDef> disks = null;
Domain dm = null;
@ -986,6 +986,7 @@ public class KVMStorageProcessor implements StorageProcessor {
}
} else {
diskdef = new DiskDef();
diskdef.setSerial(serial);
if (attachingPool.getType() == StoragePoolType.RBD) {
if(resource.getHypervisorType() == Hypervisor.HypervisorType.LXC){
// For LXC, map image to host and then attach to Vm
@ -1028,6 +1029,7 @@ public class KVMStorageProcessor implements StorageProcessor {
final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
final String vmName = cmd.getVmName();
final String serial = resource.diskUuidToSerial(vol.getUuid());
try {
final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
@ -1035,7 +1037,7 @@ public class KVMStorageProcessor implements StorageProcessor {
final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue());
attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue(), serial);
return new AttachAnswer(disk);
} catch (final LibvirtException e) {
@ -1054,12 +1056,13 @@ public class KVMStorageProcessor implements StorageProcessor {
final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
final String vmName = cmd.getVmName();
final String serial = resource.diskUuidToSerial(vol.getUuid());
try {
final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue());
attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue(), serial);
storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());

View File

@ -389,6 +389,14 @@ public class LibvirtComputingResourceTest {
assertNotNull(stats);
}
@Test
public void diskUuidToSerialTest() {
String uuid = "38400000-8cf0-11bd-b24e-10b96e4ef00d";
String expected = "384000008cf011bdb24e";
LibvirtComputingResource lcr = new LibvirtComputingResource();
Assert.assertEquals(expected, lcr.diskUuidToSerial(uuid));
}
@Test
public void testUUID() {
String uuid = "1";