Skip to content

Commit

Permalink
Merge branch '4.19'
Browse files Browse the repository at this point in the history
  • Loading branch information
JoaoJandre committed Nov 4, 2024
2 parents be24733 + a6cef7a commit 8af08dd
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected static final String DEFAULT_TUNGSTEN_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.VRouterVifDriver";
private final static long HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING = 6003000;
private final static long HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING = 5000000;
private final static long HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED = 7000000;

protected HypervisorType hypervisorType;
protected String hypervisorURI;
Expand Down Expand Up @@ -3050,7 +3051,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
}
} else if (volume.getType() != Volume.Type.ISO) {
final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
physicalDisk = storagePoolManager.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
physicalDisk = getStoragePoolMgr().getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
pool = physicalDisk.getPool();
}

Expand Down Expand Up @@ -3152,7 +3153,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
else {
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusType);
}
if (pool.getType() == StoragePoolType.Linstor) {
if (pool.getType() == StoragePoolType.Linstor && isQemuDiscardBugFree(diskBusType)) {
disk.setDiscard(DiscardType.UNMAP);
}
} else {
Expand Down Expand Up @@ -3299,6 +3300,16 @@ private boolean isIoUringEnabled() {
return isUbuntuHost() || isIoUringSupportedByQemu();
}

/**
* Qemu has a bug with discard enabled on IDE bus devices if qemu version < 7.0.
* <a href="https://bugzilla.redhat.com/show_bug.cgi?id=2029980">redhat bug entry</a>
* @param diskBus used for the disk
* @return true if it is safe to enable discard, otherwise false.
*/
public boolean isQemuDiscardBugFree(DiskDef.DiskBus diskBus) {
return diskBus != DiskDef.DiskBus.IDE || getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_IDE_DISCARD_FIXED;
}

public boolean isUbuntuHost() {
Map<String, String> versionString = getVersionStrings();
String hostKey = "Host.OS";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,7 @@ protected synchronized void attachOrDetachDisk(final Connect conn, final boolean
diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
} else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
if (attachingPool.getType() == StoragePoolType.Linstor) {
if (attachingPool.getType() == StoragePoolType.Linstor && resource.isQemuDiscardBugFree(busT)) {
diskdef.setDiscard(DiscardType.UNMAP);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@

import com.cloud.utils.net.NetUtils;

import com.cloud.vm.VmDetailConstants;
import org.apache.cloudstack.api.ApiConstants.IoDriverPolicy;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
import org.apache.cloudstack.utils.linux.CPUStat;
import org.apache.cloudstack.utils.linux.MemStat;
Expand Down Expand Up @@ -6415,4 +6418,114 @@ public void calculateVmMetricsTestOldStatsIsNotNullCalculatesUtilization() throw
Assert.assertEquals(newStats.getDiskReadKBs() - oldStats.getDiskReadKBs(), metrics.getDiskReadKBs(), 0);
Assert.assertEquals(newStats.getDiskWriteKBs() - oldStats.getDiskWriteKBs(), metrics.getDiskWriteKBs(), 0);
}

@Test
public void createLinstorVdb() throws LibvirtException, InternalErrorException, URISyntaxException {
final Connect connect = Mockito.mock(Connect.class);

final int id = random.nextInt(65534);
final String name = "test-instance-1";

final int cpus = 2;
final int speed = 1024;
final int minRam = 256 * 1024;
final int maxRam = 512 * 1024;
final String os = "Ubuntu";
final String vncPassword = "mySuperSecretPassword";

final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam,
maxRam, BootloaderType.HVM, os, false, false, vncPassword);
to.setVncAddr("");
to.setArch("x86_64");
to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
to.setVcpuMaxLimit(cpus + 1);
final HashMap<String, String> vmToDetails = new HashMap<>();
to.setDetails(vmToDetails);

String diskLinPath = "9ebe53c1-3d35-46e5-b7aa-6fc223ba0fcf";
final DiskTO diskTO = new DiskTO();
diskTO.setDiskSeq(1L);
diskTO.setType(Volume.Type.ROOT);
diskTO.setDetails(new HashMap<>());
diskTO.setPath(diskLinPath);

final PrimaryDataStoreTO primaryDataStoreTO = Mockito.mock(PrimaryDataStoreTO.class);
String pDSTOUUID = "9ebe53c1-3d35-46e5-b7aa-6fc223ac4fcf";
when(primaryDataStoreTO.getPoolType()).thenReturn(StoragePoolType.Linstor);
when(primaryDataStoreTO.getUuid()).thenReturn(pDSTOUUID);

VolumeObjectTO dataTO = new VolumeObjectTO();

dataTO.setUuid("12be53c1-3d35-46e5-b7aa-6fc223ba0f34");
dataTO.setPath(diskTO.getPath());
dataTO.setDataStore(primaryDataStoreTO);
diskTO.setData(dataTO);
to.setDisks(new DiskTO[]{diskTO});

String path = "/dev/drbd1020";
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);

when(libvirtComputingResourceSpy.getStoragePoolMgr()).thenReturn(storagePoolMgr);
when(storagePool.getType()).thenReturn(StoragePoolType.Linstor);
when(storagePoolMgr.getPhysicalDisk(StoragePoolType.Linstor, pDSTOUUID, diskLinPath)).thenReturn(vol);
when(vol.getPath()).thenReturn(path);
when(vol.getPool()).thenReturn(storagePool);
when(vol.getFormat()).thenReturn(PhysicalDiskFormat.RAW);

// 1. test Bus: IDE and broken qemu version -> NO discard
when(libvirtComputingResourceSpy.getHypervisorQemuVersion()).thenReturn(6000000L);
vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, DiskDef.DiskBus.IDE.name());
{
LibvirtVMDef vm = new LibvirtVMDef();
vm.addComp(new DevicesDef());
libvirtComputingResourceSpy.createVbd(connect, to, name, vm);

DiskDef rootDisk = vm.getDevices().getDisks().get(0);
assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
assertEquals(DiskDef.DiskBus.IDE, rootDisk.getBusType());
assertEquals(DiskDef.DiscardType.IGNORE, rootDisk.getDiscard());
}

// 2. test Bus: VIRTIO and broken qemu version -> discard unmap
vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, DiskDef.DiskBus.VIRTIO.name());
{
LibvirtVMDef vm = new LibvirtVMDef();
vm.addComp(new DevicesDef());
libvirtComputingResourceSpy.createVbd(connect, to, name, vm);

DiskDef rootDisk = vm.getDevices().getDisks().get(0);
assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
assertEquals(DiskDef.DiskBus.VIRTIO, rootDisk.getBusType());
assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
}

// 3. test Bus; IDE and "good" qemu version -> discard unmap
vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, DiskDef.DiskBus.IDE.name());
when(libvirtComputingResourceSpy.getHypervisorQemuVersion()).thenReturn(7000000L);
{
LibvirtVMDef vm = new LibvirtVMDef();
vm.addComp(new DevicesDef());
libvirtComputingResourceSpy.createVbd(connect, to, name, vm);

DiskDef rootDisk = vm.getDevices().getDisks().get(0);
assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
assertEquals(DiskDef.DiskBus.IDE, rootDisk.getBusType());
assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
}

// 4. test Bus: VIRTIO and "good" qemu version -> discard unmap
vmToDetails.put(VmDetailConstants.ROOT_DISK_CONTROLLER, DiskDef.DiskBus.VIRTIO.name());
{
LibvirtVMDef vm = new LibvirtVMDef();
vm.addComp(new DevicesDef());
libvirtComputingResourceSpy.createVbd(connect, to, name, vm);

DiskDef rootDisk = vm.getDevices().getDisks().get(0);
assertEquals(DiskDef.DiskType.BLOCK, rootDisk.getDiskType());
assertEquals(DiskDef.DiskBus.VIRTIO, rootDisk.getBusType());
assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
}
}
}
7 changes: 7 additions & 0 deletions plugins/storage/volume/linstor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2024-10-28]

### Fixed

- Disable discard="unmap" for ide devices and qemu < 7.0
https://bugzilla.redhat.com/show_bug.cgi?id=2029980

## [2024-10-04]

### Added
Expand Down
10 changes: 8 additions & 2 deletions ui/src/views/infra/UpdatePrimaryStorage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ export default {
},
created () {
this.initForm()
this.form.name = this.resource.name
},
computed: {
canUpdateNFSMountOpts () {
Expand All @@ -136,7 +135,14 @@ export default {
methods: {
initForm () {
this.formRef = ref()
this.form = reactive({ })
this.form = reactive({
name: this.resource.name,
tags: this.resource.tags,
isTagARule: this.resource.istagarule,
capacityBytes: this.resource.disksizetotal,
capacityIOPS: this.resource.capacityiops,
nfsMountOpts: this.resource.nfsmountopts
})
this.rules = reactive({ })
},
isAdmin () {
Expand Down

0 comments on commit 8af08dd

Please sign in to comment.