Merge branch '4.16'

This commit is contained in:
nvazquez 2022-05-23 08:16:52 -03:00
commit 96594aec28
No known key found for this signature in database
GPG Key ID: 656E1BCC8CB54F84
5 changed files with 92 additions and 24 deletions

View File

@ -289,5 +289,5 @@ iscsi.session.cleanup.enabled=false
# Manually set the host CPU MHz, in cases where CPU scaling support detected value is wrong
# host.cpu.manual.speed.mhz=0
# Enable/disable IO driver for Qemu / It's enabled by default on KVM agents
# Enable/disable IO driver for Qemu (in case it is not set CloudStack can also detect if its supported by qemu)
# enable.io.uring=true

View File

@ -54,13 +54,6 @@ public class AgentProperties{
*/
public static final Property<Boolean> ENABLE_MANUALLY_SETTING_CPU_TOPOLOGY_ON_KVM_VM = new Property<Boolean>("enable.manually.setting.cpu.topology.on.kvm.vm", true);
/**
* Enable manually IO driver on KVM's VM. <br>
* Data type: boolean.<br>
* Default value: true.
*/
public static final Property<Boolean> ENABLE_IO_URING = new Property<Boolean>("enable.io.uring", true);
public static class Property <T>{
private final String name;
private final T defaultValue;

View File

@ -324,6 +324,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
public final static String HOST_CACHE_PATH_PARAMETER = "host.cache.location";
public final static String CONFIG_DIR = "config";
private boolean enableIoUring;
private final static String ENABLE_IO_URING_PROPERTY = "enable.io.uring";
public static final String BASH_SCRIPT_PATH = "/bin/bash";
@ -1142,6 +1144,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
s_logger.trace("Ignoring libvirt error.", e);
}
// Enable/disable IO driver for Qemu (in case it is not set CloudStack can also detect if its supported by qemu)
// Do not remove - switching it to AgentProperties.Property may require accepting null values for the properties default value
String enableIoUringConfig = (String) params.get(ENABLE_IO_URING_PROPERTY);
enableIoUring = isIoUringEnabled(enableIoUringConfig);
s_logger.info("IO uring driver for Qemu: " + (enableIoUring ? "enabled" : "disabled"));
final String cpuArchOverride = (String)params.get("guest.cpu.arch");
if (StringUtils.isNotEmpty(cpuArchOverride)) {
_guestCpuArch = cpuArchOverride;
@ -2997,6 +3005,33 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return storagePool.getPhysicalDisk(data.getPath());
}
/**
* Check if IO_URING is supported by qemu
*/
protected boolean isIoUringSupportedByQemu() {
s_logger.debug("Checking if iouring is supported");
String command = getIoUringCheckCommand();
if (org.apache.commons.lang3.StringUtils.isBlank(command)) {
s_logger.debug("Could not check iouring support, disabling it");
return false;
}
int exitValue = executeBashScriptAndRetrieveExitValue(command);
return exitValue == 0;
}
protected String getIoUringCheckCommand() {
String[] qemuPaths = { "/usr/bin/qemu-system-x86_64", "/usr/libexec/qemu-kvm", "/usr/bin/qemu-kvm" };
for (String qemuPath : qemuPaths) {
File file = new File(qemuPath);
if (file.exists()) {
String cmd = String.format("ldd %s | grep -Eqe '[[:space:]]liburing\\.so'", qemuPath);
s_logger.debug("Using the check command: " + cmd);
return cmd;
}
}
return null;
}
/**
* Set Disk IO Driver, if supported by the Libvirt/Qemu version.
* IO Driver works for:
@ -3004,13 +3039,34 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
* (ii) Libvirt >= 6.3.0
*/
protected void setDiskIoDriver(DiskDef disk) {
if (getHypervisorLibvirtVersion() >= HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING
&& getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING
&& AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ENABLE_IO_URING)) {
if (enableIoUring) {
disk.setIoDriver(DiskDef.IoDriver.IOURING);
}
}
/**
* IO_URING supported if the property 'enable.io.uring' is set to true OR it is supported by qemu
*/
private boolean isIoUringEnabled(String enableIoUringConfig) {
boolean meetRequirements = getHypervisorLibvirtVersion() >= HYPERVISOR_LIBVIRT_VERSION_SUPPORTS_IO_URING
&& getHypervisorQemuVersion() >= HYPERVISOR_QEMU_VERSION_SUPPORTS_IO_URING;
if (!meetRequirements) {
return false;
}
return enableIoUringConfig != null ?
Boolean.parseBoolean(enableIoUringConfig):
(isBaseOsUbuntu() || isIoUringSupportedByQemu());
}
private boolean isBaseOsUbuntu() {
Map<String, String> versionString = getVersionStrings();
String hostKey = "Host.OS";
if (MapUtils.isEmpty(versionString) || !versionString.containsKey(hostKey) || versionString.get(hostKey) == null) {
return false;
}
return versionString.get(hostKey).equalsIgnoreCase("ubuntu");
}
private KVMPhysicalDisk getPhysicalDiskFromNfsStore(String dataStoreUrl, DataTO data) {
final String volPath = dataStoreUrl + File.separator + data.getPath();
final int index = volPath.lastIndexOf("/");
@ -3888,10 +3944,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
private String executeBashScript(final String script) {
return createScript(script).execute();
}
private Script createScript(final String script) {
final Script command = new Script("/bin/bash", _timeout, s_logger);
command.add("-c");
command.add(script);
return command.execute();
return command;
}
private int executeBashScriptAndRetrieveExitValue(final String script) {
Script command = createScript(script);
command.execute();
return command.getExitValue();
}
public List<VmNetworkStatsEntry> getVmNetworkStat(Connect conn, String vmName) throws LibvirtException {

View File

@ -148,7 +148,11 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
final String target = command.getDestinationIp();
xmlDesc = dm.getXMLDesc(xmlFlag);
xmlDesc = replaceIpForVNCInDescFile(xmlDesc, target);
// Limit the VNC password in case the length is greater than 8 characters
// Since libvirt version 8 VNC passwords are limited to 8 characters
String vncPassword = org.apache.commons.lang3.StringUtils.truncate(to.getVncPassword(), 8);
xmlDesc = replaceIpForVNCInDescFileAndNormalizePassword(xmlDesc, target, vncPassword);
String oldIsoVolumePath = getOldVolumePath(disks, vmName);
String newIsoVolumePath = getNewVolumePathIfDatastoreHasChanged(libvirtComputingResource, conn, to);
@ -449,9 +453,10 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
* </graphics>
* @param xmlDesc the qemu xml description
* @param target the ip address to migrate to
* @param vncPassword if set, the VNC password truncated to 8 characters
* @return the new xmlDesc
*/
String replaceIpForVNCInDescFile(String xmlDesc, final String target) {
String replaceIpForVNCInDescFileAndNormalizePassword(String xmlDesc, final String target, String vncPassword) {
final int begin = xmlDesc.indexOf(GRAPHICS_ELEM_START);
if (begin >= 0) {
final int end = xmlDesc.lastIndexOf(GRAPHICS_ELEM_END) + GRAPHICS_ELEM_END.length();
@ -459,6 +464,9 @@ public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCo
String graphElem = xmlDesc.substring(begin, end);
graphElem = graphElem.replaceAll("listen='[a-zA-Z0-9\\.]*'", "listen='" + target + "'");
graphElem = graphElem.replaceAll("address='[a-zA-Z0-9\\.]*'", "address='" + target + "'");
if (org.apache.commons.lang3.StringUtils.isNotBlank(vncPassword)) {
graphElem = graphElem.replaceAll("passwd='([^\\s]+)'", "passwd='" + vncPassword + "'");
}
xmlDesc = xmlDesc.replaceAll(GRAPHICS_ELEM_START + CONTENTS_WILDCARD + GRAPHICS_ELEM_END, graphElem);
}
}

View File

@ -571,16 +571,16 @@ public class LibvirtMigrateCommandWrapperTest {
@Test
public void testReplaceIpForVNCInDescFile() {
final String targetIp = "192.168.22.21";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(fullfile, targetIp);
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFileAndNormalizePassword(fullfile, targetIp, null);
assertTrue("transformation does not live up to expectation:\n" + result, targetfile.equals(result));
}
@Test
public void testReplaceIpForVNCInDesc() {
public void testReplaceIpAndPasswordForVNCInDesc() {
final String xmlDesc =
"<domain type='kvm' id='3'>" +
" <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1' passwd='123456789012345'>" +
" <listen type='address' address='10.10.10.1'/>" +
" </graphics>" +
" </devices>" +
@ -588,22 +588,23 @@ public class LibvirtMigrateCommandWrapperTest {
final String expectedXmlDesc =
"<domain type='kvm' id='3'>" +
" <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10'>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10' passwd='12345678'>" +
" <listen type='address' address='10.10.10.10'/>" +
" </graphics>" +
" </devices>" +
"</domain>";
final String targetIp = "10.10.10.10";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(xmlDesc, targetIp);
final String password = "12345678";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFileAndNormalizePassword(xmlDesc, targetIp, password);
assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
}
@Test
public void testReplaceFqdnForVNCInDesc() {
public void testReplaceFqdnAndPasswordForVNCInDesc() {
final String xmlDesc =
"<domain type='kvm' id='3'>" +
" <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local'>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local' passwd='123456789012345'>" +
" <listen type='address' address='localhost.local'/>" +
" </graphics>" +
" </devices>" +
@ -611,13 +612,14 @@ public class LibvirtMigrateCommandWrapperTest {
final String expectedXmlDesc =
"<domain type='kvm' id='3'>" +
" <devices>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain'>" +
" <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain' passwd='12345678'>" +
" <listen type='address' address='localhost.localdomain'/>" +
" </graphics>" +
" </devices>" +
"</domain>";
final String targetIp = "localhost.localdomain";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(xmlDesc, targetIp);
final String password = "12345678";
final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFileAndNormalizePassword(xmlDesc, targetIp, password);
assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
}
@ -789,5 +791,4 @@ public class LibvirtMigrateCommandWrapperTest {
Assert.assertTrue(replaced.contains("csdpdk-7"));
Assert.assertFalse(replaced.contains("csdpdk-1"));
}
}