in plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java [928:1378]
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
boolean success = super.configure(name, params);
if (!success) {
return false;
}
try {
loadUefiProperties();
} catch (FileNotFoundException e) {
LOGGER.error("uefi properties file not found due to: " + e.getLocalizedMessage());
}
storageLayer = new JavaStorageLayer();
storageLayer.configure("StorageLayer", params);
String domrScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.DOMR_SCRIPTS_DIR);
String hypervisorScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HYPERVISOR_SCRIPTS_DIR);
String kvmScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.KVM_SCRIPTS_DIR);
String networkScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.NETWORK_SCRIPTS_DIR);
String storageScriptsDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.STORAGE_SCRIPTS_DIR);
String tungstenScriptsDir = (String) params.get("tungsten.scripts.dir");
if (tungstenScriptsDir == null) {
tungstenScriptsDir = getDefaultTungstenScriptsDir();
}
final String bridgeType = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.NETWORK_BRIDGE_TYPE);
if (bridgeType == null) {
this.bridgeType = BridgeType.NATIVE;
} else {
this.bridgeType = BridgeType.valueOf(bridgeType.toUpperCase());
}
Boolean dpdk = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.OPENVSWITCH_DPDK_ENABLED);
if (this.bridgeType == BridgeType.OPENVSWITCH && BooleanUtils.isTrue(dpdk)) {
dpdkSupport = true;
dpdkOvsPath = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.OPENVSWITCH_DPDK_OVS_PATH);
if (dpdkOvsPath != null && !dpdkOvsPath.endsWith("/")) {
dpdkOvsPath += "/";
}
}
directDownloadTemporaryDownloadPath = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.DIRECT_DOWNLOAD_TEMPORARY_DOWNLOAD_LOCATION);
cachePath = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HOST_CACHE_LOCATION);
params.put("domr.scripts.dir", domrScriptsDir);
virtRouterResource = new VirtualRoutingResource(this);
success = virtRouterResource.configure(name, params);
if (!success) {
return false;
}
dcId = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ZONE);
clusterId = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CLUSTER);
updateHostPasswdPath = Script.findScript(hypervisorScriptsDir, VRScripts.UPDATE_HOST_PASSWD);
if (updateHostPasswdPath == null) {
throw new ConfigurationException("Unable to find update_host_passwd.sh");
}
modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
if (modifyVlanPath == null) {
throw new ConfigurationException("Unable to find modifyvlan.sh");
}
versionStringPath = Script.findScript(kvmScriptsDir, "versions.sh");
if (versionStringPath == null) {
throw new ConfigurationException("Unable to find versions.sh");
}
patchScriptPath = Script.findScript(kvmScriptsDir, "patch.sh");
if (patchScriptPath == null) {
throw new ConfigurationException("Unable to find patch.sh");
}
heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
if (heartBeatPath == null) {
throw new ConfigurationException("Unable to find kvmheartbeat.sh");
}
createVmPath = Script.findScript(storageScriptsDir, "createvm.sh");
if (createVmPath == null) {
throw new ConfigurationException("Unable to find the createvm.sh");
}
manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh");
if (manageSnapshotPath == null) {
throw new ConfigurationException("Unable to find the managesnapshot.sh");
}
resizeVolumePath = Script.findScript(storageScriptsDir, "resizevolume.sh");
if (resizeVolumePath == null) {
throw new ConfigurationException("Unable to find the resizevolume.sh");
}
vmActivityCheckPath = Script.findScript(kvmScriptsDir, "kvmvmactivity.sh");
if (vmActivityCheckPath == null) {
throw new ConfigurationException("Unable to find kvmvmactivity.sh");
}
nasBackupPath = Script.findScript(kvmScriptsDir, "nasbackup.sh");
if (nasBackupPath == null) {
throw new ConfigurationException("Unable to find nasbackup.sh");
}
createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh");
if (createTmplPath == null) {
throw new ConfigurationException("Unable to find the createtmplt.sh");
}
securityGroupPath = Script.findScript(networkScriptsDir, "security_group.py");
if (securityGroupPath == null) {
throw new ConfigurationException("Unable to find the security_group.py");
}
ovsTunnelPath = Script.findScript(networkScriptsDir, "ovstunnel.py");
if (ovsTunnelPath == null) {
throw new ConfigurationException("Unable to find the ovstunnel.py");
}
routerProxyPath = Script.findScript("scripts/network/domr/", "router_proxy.sh");
if (routerProxyPath == null) {
throw new ConfigurationException("Unable to find the router_proxy.sh");
}
ovsPvlanDhcpHostPath = Script.findScript(networkScriptsDir, "ovs-pvlan-kvm-dhcp-host.sh");
if (ovsPvlanDhcpHostPath == null) {
throw new ConfigurationException("Unable to find the ovs-pvlan-kvm-dhcp-host.sh");
}
ovsPvlanVmPath = Script.findScript(networkScriptsDir, "ovs-pvlan-kvm-vm.sh");
if (ovsPvlanVmPath == null) {
throw new ConfigurationException("Unable to find the ovs-pvlan-kvm-vm.sh");
}
hostHealthCheckScriptPath = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HEALTH_CHECK_SCRIPT_PATH);
if (StringUtils.isNotBlank(hostHealthCheckScriptPath) && !new File(hostHealthCheckScriptPath).exists()) {
LOGGER.info(String.format("Unable to find the host health check script at: %s, " +
"discarding it", hostHealthCheckScriptPath));
}
setupTungstenVrouterPath = Script.findScript(tungstenScriptsDir, "setup_tungsten_vrouter.sh");
if (setupTungstenVrouterPath == null) {
throw new ConfigurationException("Unable to find the setup_tungsten_vrouter.sh");
}
updateTungstenLoadbalancerStatsPath = Script.findScript(tungstenScriptsDir, "update_tungsten_loadbalancer_stats.sh");
if (updateTungstenLoadbalancerStatsPath == null) {
throw new ConfigurationException("Unable to find the update_tungsten_loadbalancer_stats.sh");
}
updateTungstenLoadbalancerSslPath = Script.findScript(tungstenScriptsDir, "update_tungsten_loadbalancer_ssl.sh");
if (updateTungstenLoadbalancerSslPath == null) {
throw new ConfigurationException("Unable to find the update_tungsten_loadbalancer_ssl.sh");
}
final boolean isDeveloper = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.DEVELOPER);
if (isDeveloper) {
params.putAll(getDeveloperProperties());
}
convertInstanceVerboseMode = BooleanUtils.isTrue(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VIRTV2V_VERBOSE_ENABLED));
pool = (String)params.get("pool");
if (pool == null) {
pool = "/root";
}
final String instance = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.INSTANCE);
hypervisorType = HypervisorType.getType(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HYPERVISOR_TYPE));
String hooksDir = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ROLLING_MAINTENANCE_HOOKS_DIR);
rollingMaintenanceExecutor = BooleanUtils.isTrue(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ROLLING_MAINTENANCE_SERVICE_EXECUTOR_DISABLED)) ? new RollingMaintenanceAgentExecutor(hooksDir) :
new RollingMaintenanceServiceExecutor(hooksDir);
hypervisorURI = LibvirtConnection.getHypervisorURI(hypervisorType.toString());
networkDirectSourceMode = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.NETWORK_DIRECT_SOURCE_MODE);
networkDirectDevice = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.NETWORK_DIRECT_DEVICE);
pingTestPath = Script.findScript(kvmScriptsDir, "pingtest.sh");
if (pingTestPath == null) {
throw new ConfigurationException("Unable to find the pingtest.sh");
}
linkLocalBridgeName = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.PRIVATE_BRIDGE_NAME);
if (linkLocalBridgeName == null) {
if (isDeveloper) {
linkLocalBridgeName = "cloud-" + instance + "-0";
} else {
linkLocalBridgeName = "cloud0";
}
}
guestBridgeName = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.GUEST_NETWORK_DEVICE);
if (guestBridgeName == null) {
guestBridgeName = privBridgeName;
}
privNwName = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.PRIVATE_NETWORK_NAME);
if (privNwName == null) {
if (isDeveloper) {
privNwName = "cloud-" + instance + "-private";
} else {
privNwName = "cloud-private";
}
}
enableSSLForKvmAgent();
configureLocalStorage();
/* Directory to use for Qemu sockets like for the Qemu Guest Agent */
String qemuSocketsPathVar = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.QEMU_SOCKETS_PATH);
qemuSocketsPath = new File(qemuSocketsPathVar);
// This value is never set. Default value is always used.
String value = (String)params.get("scripts.timeout");
timeout = Duration.standardSeconds(NumbersUtil.parseInt(value, 30 * 60));
stopTimeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.STOP_SCRIPT_TIMEOUT) * 1000;
cmdsTimeout = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CMDS_TIMEOUT) * 1000;
noMemBalloon = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MEMBALLOON_DISABLE);
manualCpuSpeed = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HOST_CPU_MANUAL_SPEED_MHZ);
videoHw = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_VIDEO_HARDWARE);
videoRam = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_VIDEO_RAM);
// Reserve 1GB unless admin overrides
dom0MinMem = ByteScaleUtils.mebibytesToBytes(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HOST_RESERVED_MEM_MB));
dom0MinCpuCores = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HOST_RESERVED_CPU_CORE_COUNT);
// Support overcommit memory for host if host uses ZSWAP, KSM and other memory
// compressing technologies
dom0OvercommitMem = ByteScaleUtils.mebibytesToBytes(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.HOST_OVERCOMMIT_MEM_MB));
if (BooleanUtils.isTrue(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.KVMCLOCK_DISABLE))) {
noKvmClock = true;
}
if (BooleanUtils.isTrue(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_RNG_ENABLE))) {
rngEnable = true;
rngBackendModel = RngBackendModel.valueOf(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_RNG_MODEL).toUpperCase());
rngPath = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_RNG_PATH);
rngRateBytes = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_RNG_RATE_BYTES);
rngRatePeriod = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_RNG_RATE_PERIOD);
}
watchDogModel = WatchDogModel.valueOf(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_WATCHDOG_MODEL).toUpperCase());
watchDogAction = WatchDogAction.valueOf(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_WATCHDOG_ACTION).toUpperCase());
LibvirtConnection.initialize(hypervisorURI);
Connect conn = null;
try {
conn = LibvirtConnection.getConnection();
if (this.bridgeType == BridgeType.OPENVSWITCH) {
if (conn.getLibVirVersion() < 10 * 1000 + 0) {
throw new ConfigurationException("Libvirt version 0.10.0 required for openvswitch support, but version " + conn.getLibVirVersion() + " detected");
}
}
} catch (final LibvirtException e) {
throw new CloudRuntimeException(e.getMessage());
}
// destroy default network, see https://libvirt.org/sources/java/javadoc/org/libvirt/Network.html
try {
Network network = conn.networkLookupByName("default");
LOGGER.debug("Found libvirt default network, destroying it and setting autostart to false");
if (network.isActive() == 1) {
network.destroy();
}
if (network.getAutostart()) {
network.setAutostart(false);
}
} catch (final LibvirtException e) {
LOGGER.warn("Ignoring libvirt error.", e);
}
if (HypervisorType.KVM == hypervisorType) {
/* Does node support HVM guest? If not, exit */
if (!IsHVMEnabled(conn)) {
throw new ConfigurationException("NO HVM support on this machine, please make sure: " + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. "
+ "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)");
}
}
hypervisorPath = getHypervisorPath(conn);
try {
hvVersion = conn.getVersion();
hvVersion = hvVersion % 1000000 / 1000;
hypervisorLibvirtVersion = conn.getLibVirVersion();
hypervisorQemuVersion = conn.getVersion();
} catch (final LibvirtException e) {
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)
enableIoUring = isIoUringEnabled();
LOGGER.info("IO uring driver for Qemu: " + (enableIoUring ? "enabled" : "disabled"));
final String cpuArchOverride = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.GUEST_CPU_ARCH);
if (StringUtils.isNotEmpty(cpuArchOverride)) {
guestCpuArch = cpuArchOverride;
LOGGER.info("Using guest CPU architecture: " + guestCpuArch);
}
guestCpuMode = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.GUEST_CPU_MODE);
if (guestCpuMode != null) {
guestCpuModel = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.GUEST_CPU_MODEL);
if (hypervisorLibvirtVersion < 9 * 1000 + 10) {
LOGGER.warn("Libvirt version 0.9.10 required for guest cpu mode, but version " + prettyVersion(hypervisorLibvirtVersion) +
" detected, so it will be disabled");
guestCpuMode = "";
guestCpuModel = "";
}
params.put("guest.cpu.mode", guestCpuMode);
params.put("guest.cpu.model", guestCpuModel);
}
final String cpuFeatures = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.GUEST_CPU_FEATURES);
if (cpuFeatures != null) {
this.cpuFeatures = new ArrayList<String>();
for (final String feature: cpuFeatures.split(" ")) {
if (!feature.isEmpty()) {
this.cpuFeatures.add(feature);
}
}
}
final String[] info = NetUtils.getNetworkParams(privateNic);
kvmhaMonitor = new KVMHAMonitor(null, info[0], heartBeatPath);
final Thread ha = new Thread(kvmhaMonitor);
ha.start();
storagePoolManager = new KVMStoragePoolManager(storageLayer, kvmhaMonitor);
final Map<String, String> bridges = new HashMap<String, String>();
params.put("libvirt.host.bridges", bridges);
params.put("libvirt.host.pifs", pifs);
params.put("libvirt.computing.resource", this);
params.put("libvirtVersion", hypervisorLibvirtVersion);
configureVifDrivers(params);
/*
switch (_bridgeType) {
case OPENVSWITCH:
getOvsPifs();
break;
case NATIVE:
default:
getPifs();
break;
}
*/
if (pifs.get("private") == null) {
LOGGER.error("Failed to get private nic name");
throw new ConfigurationException("Failed to get private nic name");
}
if (pifs.get("public") == null) {
LOGGER.error("Failed to get public nic name");
throw new ConfigurationException("Failed to get public nic name");
}
LOGGER.debug("Found pif: " + pifs.get("private") + " on " + privBridgeName + ", pif: " + pifs.get("public") + " on " + publicBridgeName);
canBridgeFirewall = canBridgeFirewall(pifs.get("public"));
localGateway = Script.runSimpleBashScript("ip route show default 0.0.0.0/0|head -1|awk '{print $3}'");
if (localGateway == null) {
LOGGER.warn("No default IPv4 gateway found");
}
migrateDowntime = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MIGRATE_DOWNTIME);
migratePauseAfter = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MIGRATE_PAUSEAFTER);
migrateWait = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MIGRATE_WAIT);
configureAgentHooks();
migrateSpeed = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MIGRATE_SPEED);
if (migrateSpeed == -1) {
//get guest network device speed
migrateSpeed = 0;
final String speed = Script.runSimpleBashScript("ethtool " + pifs.get("public") + " |grep Speed | cut -d \\ -f 2");
if (speed != null) {
final String[] tokens = speed.split("M");
if (tokens.length == 2) {
try {
migrateSpeed = Integer.parseInt(tokens[0]);
} catch (final NumberFormatException e) {
LOGGER.trace("Ignoring migrateSpeed extraction error.", e);
}
LOGGER.debug("device " + pifs.get("public") + " has speed: " + String.valueOf(migrateSpeed));
}
}
params.put("vm.migrate.speed", String.valueOf(migrateSpeed));
}
bridges.put("linklocal", linkLocalBridgeName);
bridges.put("public", publicBridgeName);
bridges.put("private", privBridgeName);
bridges.put("guest", guestBridgeName);
getVifDriver(TrafficType.Control).createControlNetwork(linkLocalBridgeName);
configureDiskActivityChecks();
final KVMStorageProcessor storageProcessor = new KVMStorageProcessor(storagePoolManager, this);
storageProcessor.configure(name, params);
storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor);
Boolean iscsiCleanUpEnabled = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ISCSI_SESSION_CLEANUP_ENABLED);
if (BooleanUtils.isTrue(iscsiCleanUpEnabled)) {
IscsiStorageCleanupMonitor isciCleanupMonitor = new IscsiStorageCleanupMonitor();
final Thread cleanupMonitor = new Thread(isciCleanupMonitor);
cleanupMonitor.start();
} else {
LOGGER.info("iscsi session clean up is disabled");
}
setupMemoryBalloonStatsPeriod(conn);
return true;
}