Skip to content

Commit eafeb04

Browse files
committed
Add verify_no_swap_on_osdisk case
1 parent 340f891 commit eafeb04

File tree

2 files changed

+101
-3
lines changed

2 files changed

+101
-3
lines changed

lisa/tools/swap.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT license.
33
import re
4-
from typing import Optional, Type
4+
from typing import List, Optional, Type
55

6+
from lisa.base_tools import Cat
67
from lisa.executable import Tool
78
from lisa.tools.lsblk import Lsblk
89
from lisa.tools.rm import Rm
9-
from lisa.util import find_patterns_in_lines
10+
from lisa.util import (
11+
LisaException,
12+
find_patterns_groups_in_lines,
13+
find_patterns_in_lines,
14+
)
1015

1116

1217
class SwapOn(Tool):
@@ -28,6 +33,14 @@ def command(self) -> str:
2833

2934

3035
class Swap(Tool):
36+
# Filename Type Size Used Priority
37+
# /dev/sdb2 partition 1020 0 -2
38+
# /swapfile file 200M 15M -3
39+
# /mnt/swapfile file 2097148 0 -4
40+
_SWAPS_PATTERN = re.compile(
41+
r"(?P<filename>\S+)\s+(?P<type>\S+)\s+(?P<size>\d+)\w?\s+(?P<used>\d+)\w?\s+(?P<priority>-?\d+)" # noqa: E501
42+
)
43+
3144
@property
3245
def command(self) -> str:
3346
raise NotImplementedError()
@@ -53,6 +66,26 @@ def is_swap_enabled(self) -> bool:
5366
lsblk = self.node.tools[Lsblk].run().stdout
5467
return "SWAP" in lsblk
5568

69+
def get_swap_partitions(self) -> List[str]:
70+
# run 'cat /proc/swaps' or 'swapon -s' and parse the output
71+
# The output is in the following format:
72+
# <Filename> <Type> <Size> <Used> <Priority>
73+
cat = self.node.tools[Cat]
74+
swap_result = cat.run("/proc/swaps", shell=True, sudo=True)
75+
if swap_result.exit_code != 0:
76+
# Try another way to get swap information
77+
swap_result = self.node.tools[SwapOn].run("-s")
78+
if swap_result.exit_code != 0:
79+
raise LisaException("Failed to get swap information")
80+
81+
output = swap_result.stdout
82+
swap_parts: List[str] = []
83+
swap_entries = find_patterns_groups_in_lines(output, [self._SWAPS_PATTERN])[0]
84+
for swap_entry in swap_entries:
85+
if swap_entry["type"] == "partition":
86+
swap_parts.append(swap_entry["filename"])
87+
return swap_parts
88+
5689
def create_swap(
5790
self, path: str = "/tmp/swap", size: str = "1M", count: int = 1024
5891
) -> None:
@@ -84,3 +117,19 @@ def is_swap_enabled(self) -> bool:
84117
return True
85118

86119
return False
120+
121+
def get_swap_partitions(self) -> List[str]:
122+
# run 'swapinfo -k' and parse the output
123+
# The output is in the following format:
124+
# <Device> <1K-blocks> <Used> <Avail> <Capacity>
125+
swap_result = self.run("-k")
126+
if swap_result.exit_code != 0:
127+
raise LisaException("Failed to get swap information")
128+
129+
output = swap_result.stdout
130+
swap_parts: List[str] = []
131+
swap_entries = find_patterns_groups_in_lines(output, [self._SWAP_ENTRIES])[0]
132+
# FreeBSD doesn't have swap files, only partitions
133+
for swap_entry in swap_entries:
134+
swap_parts.append(swap_entry["device"])
135+
return swap_parts

microsoft/testsuites/core/azure_image_standard.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
from lisa.sut_orchestrator import AZURE, HYPERV, READY
4141
from lisa.sut_orchestrator.azure.features import AzureDiskOptionSettings
4242
from lisa.sut_orchestrator.azure.tools import Waagent
43-
from lisa.tools import Cat, Dmesg, Journalctl, Ls, Lsblk, Lscpu, Pgrep, Ssh
43+
from lisa.tools import Cat, Dmesg, Journalctl, Ls, Lsblk, Lscpu, Pgrep, Ssh, Swap
4444
from lisa.util import (
4545
LisaException,
4646
PassedException,
@@ -1460,6 +1460,55 @@ def verify_omi_version(self, node: Node) -> None:
14601460
f"{minimum_secure_version} to prevent OMIGOD vulnerabilities."
14611461
) from e
14621462

1463+
@TestCaseMetadata(
1464+
description="""
1465+
This test verifies that there is no swap partition on the OS disk.
1466+
1467+
Azure's policy 200.3.3 Linux:
1468+
No swap partition on the OS disk. Swap can be requested for creation on the
1469+
local resource disk by the Linux Agent. It is recommended that a single root
1470+
partition is created for the OS disk.
1471+
1472+
There should be no Swap Partition on OS Disk. OS disk has IOPS limit. When
1473+
memory pressure causes swapping, IOPS limit may be reached easily and cause VM
1474+
performance to go down disastrously, because aside from memory issues in now
1475+
also has IO issues.
1476+
1477+
Steps:
1478+
1. Use 'cat /proc/swaps' or 'swapon -s' list all swap devices
1479+
Note: For FreeBSD, use 'swapinfo -k'.
1480+
2. Use 'lsblk' to identify the OS disk and get all the partitions
1481+
Note: For FreeBSD, if there is no lsblk, install it and run the command
1482+
3. Verify that no swap partition exists on the OS disk
1483+
""",
1484+
priority=1,
1485+
requirement=simple_requirement(supported_platform_type=[AZURE]),
1486+
)
1487+
def verify_no_swap_on_osdisk(self, node: Node) -> None:
1488+
swap_tool = node.tools[Swap]
1489+
swap_parts = swap_tool.get_swap_partitions()
1490+
if not swap_parts:
1491+
return
1492+
node.log.info(f"Swap partitions: {swap_parts}")
1493+
1494+
lsblk = node.tools[Lsblk]
1495+
os_disk = lsblk.find_disk_by_mountpoint("/")
1496+
# e.g. os_disk_partitions: ['sda1', 'sda2']
1497+
os_disk_partitions = [part.name for part in os_disk.partitions]
1498+
node.log.info(f"OS disk partitions: {os_disk_partitions}")
1499+
1500+
for swap_part in swap_parts:
1501+
for os_part in os_disk_partitions:
1502+
if os_part in swap_part:
1503+
raise LisaException(
1504+
f"Swap partition '{swap_part}' found on OS disk. There should"
1505+
" be no Swap Partition on OS Disk. OS disk has IOPS limit. "
1506+
"When memory pressure causes swapping, IOPS limit may be "
1507+
"reached easily and cause VM performance to go down "
1508+
"disastrously, because aside from memory issues in now also "
1509+
"has IO issues."
1510+
)
1511+
14631512
def _verify_version_by_pattern_value(
14641513
self,
14651514
node: Node,

0 commit comments

Comments
 (0)