|
147 | 147 | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef;
|
148 | 148 | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef;
|
149 | 149 | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
|
| 150 | +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.MemBalloonDef; |
150 | 151 | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
|
151 | 152 | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
|
152 | 153 | import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
|
|
221 | 222 | * pool | the parent of the storage pool hierarchy * }
|
222 | 223 | **/
|
223 | 224 | public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer {
|
224 |
| - private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); |
| 225 | + protected static Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); |
225 | 226 |
|
226 | 227 | private static final String CONFIG_VALUES_SEPARATOR = ",";
|
227 | 228 |
|
@@ -448,6 +449,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
448 | 449 |
|
449 | 450 | protected Boolean enableManuallySettingCpuTopologyOnKvmVm = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ENABLE_MANUALLY_SETTING_CPU_TOPOLOGY_ON_KVM_VM);
|
450 | 451 |
|
| 452 | + protected LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); |
| 453 | + |
| 454 | + /** |
| 455 | + * Virsh command to set the memory balloon stats period.<br><br> |
| 456 | + * 1st parameter: the VM ID or name;<br> |
| 457 | + * 2nd parameter: the period (in seconds). |
| 458 | + */ |
| 459 | + private static final String COMMAND_SET_MEM_BALLOON_STATS_PERIOD = "virsh dommemstat %s --period %s --live"; |
| 460 | + |
451 | 461 | protected long getHypervisorLibvirtVersion() {
|
452 | 462 | return _hypervisorLibvirtVersion;
|
453 | 463 | }
|
@@ -1298,9 +1308,84 @@ public boolean configure(final String name, final Map<String, Object> params) th
|
1298 | 1308 | s_logger.info("iscsi session clean up is disabled");
|
1299 | 1309 | }
|
1300 | 1310 |
|
| 1311 | + setupMemoryBalloonStatsPeriod(conn); |
| 1312 | + |
1301 | 1313 | return true;
|
1302 | 1314 | }
|
1303 | 1315 |
|
| 1316 | + /** |
| 1317 | + * Gets the ID list of the VMs to set memory balloon stats period. |
| 1318 | + * @param conn the Libvirt connection. |
| 1319 | + * @return the list of VM IDs. |
| 1320 | + */ |
| 1321 | + protected List<Integer> getVmsToSetMemoryBalloonStatsPeriod(Connect conn) { |
| 1322 | + List<Integer> vmIdList = new ArrayList<>(); |
| 1323 | + Integer[] vmIds = null; |
| 1324 | + try { |
| 1325 | + vmIds = ArrayUtils.toObject(conn.listDomains()); |
| 1326 | + } catch (final LibvirtException e) { |
| 1327 | + s_logger.error("Unable to get the list of Libvirt domains on this host.", e); |
| 1328 | + return vmIdList; |
| 1329 | + } |
| 1330 | + vmIdList.addAll(Arrays.asList(vmIds)); |
| 1331 | + s_logger.debug(String.format("We have found a total of [%s] VMs (Libvirt domains) on this host: [%s].", vmIdList.size(), vmIdList.toString())); |
| 1332 | + |
| 1333 | + if (vmIdList.isEmpty()) { |
| 1334 | + s_logger.info("Skipping the memory balloon stats period setting, since there are no VMs (active Libvirt domains) on this host."); |
| 1335 | + } |
| 1336 | + return vmIdList; |
| 1337 | + } |
| 1338 | + |
| 1339 | + /** |
| 1340 | + * Gets the current VM balloon stats period from the agent.properties file. |
| 1341 | + * @return the current VM balloon stats period. |
| 1342 | + */ |
| 1343 | + protected Integer getCurrentVmBalloonStatsPeriod() { |
| 1344 | + if (Boolean.TRUE.equals(AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MEMBALLOON_DISABLE))) { |
| 1345 | + s_logger.info(String.format("The [%s] property is set to 'true', so the memory balloon stats period will be set to 0 for all VMs.", |
| 1346 | + AgentProperties.VM_MEMBALLOON_DISABLE.getName())); |
| 1347 | + return 0; |
| 1348 | + } |
| 1349 | + Integer vmBalloonStatsPeriod = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.VM_MEMBALLOON_STATS_PERIOD); |
| 1350 | + if (vmBalloonStatsPeriod == 0) { |
| 1351 | + s_logger.info(String.format("The [%s] property is set to '0', this prevents memory statistics from being displayed correctly. " |
| 1352 | + + "Adjust (increase) the value of this parameter to correct this.", AgentProperties.VM_MEMBALLOON_STATS_PERIOD.getName())); |
| 1353 | + } |
| 1354 | + return vmBalloonStatsPeriod; |
| 1355 | + } |
| 1356 | + |
| 1357 | + /** |
| 1358 | + * Sets the balloon driver of each VM to get the memory stats at the time interval defined in the agent.properties file. |
| 1359 | + * @param conn the Libvirt connection. |
| 1360 | + */ |
| 1361 | + protected void setupMemoryBalloonStatsPeriod(Connect conn) { |
| 1362 | + List<Integer> vmIdList = getVmsToSetMemoryBalloonStatsPeriod(conn); |
| 1363 | + Integer currentVmBalloonStatsPeriod = getCurrentVmBalloonStatsPeriod(); |
| 1364 | + for (Integer vmId : vmIdList) { |
| 1365 | + Domain dm = null; |
| 1366 | + try { |
| 1367 | + dm = conn.domainLookupByID(vmId); |
| 1368 | + parser.parseDomainXML(dm.getXMLDesc(0)); |
| 1369 | + MemBalloonDef memBalloon = parser.getMemBalloon(); |
| 1370 | + if (!MemBalloonDef.MemBalloonModel.VIRTIO.equals(memBalloon.getMemBalloonModel())) { |
| 1371 | + s_logger.debug(String.format("Skipping the memory balloon stats period setting for the VM (Libvirt Domain) with ID [%s] and name [%s] because this VM has no memory" |
| 1372 | + + " balloon.", vmId, dm.getName())); |
| 1373 | + } |
| 1374 | + String setMemBalloonStatsPeriodCommand = String.format(COMMAND_SET_MEM_BALLOON_STATS_PERIOD, vmId, currentVmBalloonStatsPeriod); |
| 1375 | + String setMemBalloonStatsPeriodResult = Script.runSimpleBashScript(setMemBalloonStatsPeriodCommand); |
| 1376 | + if (StringUtils.isNotBlank(setMemBalloonStatsPeriodResult)) { |
| 1377 | + s_logger.error(String.format("Unable to set up memory balloon stats period for VM (Libvirt Domain) with ID [%s] due to an error when running the [%s] " |
| 1378 | + + "command. Output: [%s].", vmId, setMemBalloonStatsPeriodCommand, setMemBalloonStatsPeriodResult)); |
| 1379 | + continue; |
| 1380 | + } |
| 1381 | + s_logger.debug(String.format("The memory balloon stats period [%s] has been set successfully for the VM (Libvirt Domain) with ID [%s] and name [%s].", |
| 1382 | + currentVmBalloonStatsPeriod, vmId, dm.getName())); |
| 1383 | + } catch (final LibvirtException e) { |
| 1384 | + s_logger.warn("Failed to set up memory balloon stats period." + e.getMessage()); |
| 1385 | + } |
| 1386 | + } |
| 1387 | + } |
| 1388 | + |
1304 | 1389 | private void enableSSLForKvmAgent(final Map<String, Object> params) {
|
1305 | 1390 | final File keyStoreFile = PropertiesUtil.findConfigFile(KeyStoreUtils.KS_FILENAME);
|
1306 | 1391 | if (keyStoreFile == null) {
|
|
0 commit comments