Skip to content

Commit adfae5d

Browse files
committed
Enhance memory usage reporting with detailed breakdown for system, VM, Docker, and ZFS memory in Unraid sensors
1 parent 6410171 commit adfae5d

File tree

4 files changed

+345
-47
lines changed

4 files changed

+345
-47
lines changed

custom_components/unraid/api/disk_operations.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,15 @@ async def collect_disk_info(self) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]
416416
# Get all disk information in a single command, but without SMART data first
417417
# This prevents waking up disks in standby mode
418418
cmd = (
419-
# Get disk usage for standard Unraid mounts
419+
# Get disk usage for standard Unraid mounts and all cache pools
420420
"echo '===DISK_USAGE==='; "
421-
"df -P -B1 /mnt/disk[0-9]* /mnt/cache* /mnt/user* 2>/dev/null | grep -v '^Filesystem' | awk '{print $6,$2,$3,$4}'; "
421+
"df -P -B1 /mnt/disk[0-9]* /mnt/user* 2>/dev/null | grep -v '^Filesystem' | awk '{print $6,$2,$3,$4}'; "
422+
# Get all cache pools (including those with special characters)
423+
"mount | grep -E '/mnt/' | grep -v -E '(fuse\\.shfs|/var/lib/docker|/etc/libvirt)' | grep -v -E '/mnt/(disk[0-9]+|user[0-9]*|disks|remotes|addons|rootshare)' | awk '{print $3}' | while read mount_point; do "
424+
" if [ -d \"$mount_point\" ] && mountpoint -q \"$mount_point\"; then "
425+
" df -P -B1 \"$mount_point\" 2>/dev/null | grep -v '^Filesystem' | awk '{print $6,$2,$3,$4}'; "
426+
" fi; "
427+
"done; "
422428
# Get mount points and devices (including ZFS and other custom mounts)
423429
"echo '===MOUNT_INFO==='; "
424430
"mount | grep -E '/mnt/' | awk '{print $1,$3,$5}'; "

custom_components/unraid/api/smart_operations.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,14 @@ async def get_smart_data(
150150
_LOGGER.error("Invalid disk number in %s", device)
151151
return {"state": "error", "error": "Invalid device name", "temperature": None}
152152
else:
153-
_LOGGER.error("Unrecognized device format: %s", device)
154-
return {"state": "error", "error": "Invalid device name", "temperature": None}
153+
# Check if this is a ZFS pool name
154+
zfs_device = await self._resolve_zfs_pool_device(device)
155+
if zfs_device:
156+
device_path = zfs_device
157+
_LOGGER.debug("Resolved ZFS pool '%s' to device '%s'", device, device_path)
158+
else:
159+
_LOGGER.error("Unrecognized device format: %s", device)
160+
return {"state": "error", "error": "Invalid device name", "temperature": None}
155161

156162
# Strip partition numbers from device path for SMART data collection
157163
# For example, convert /dev/nvme0n1p1 to /dev/nvme0n1
@@ -562,4 +568,35 @@ async def get_usb_detection_stats(self) -> Dict[str, Any]:
562568
def clear_usb_cache(self) -> None:
563569
"""Clear USB detection cache (useful for testing or troubleshooting)."""
564570
self._usb_detector.clear_cache()
565-
_LOGGER.info("USB detection cache cleared")
571+
_LOGGER.info("USB detection cache cleared")
572+
573+
async def _resolve_zfs_pool_device(self, pool_name: str) -> Optional[str]:
574+
"""Resolve ZFS pool name to underlying physical device path."""
575+
try:
576+
# Check if this is a ZFS pool
577+
zpool_cmd = f"zpool list -H -o name {pool_name} 2>/dev/null"
578+
result = await self._instance.execute_command(zpool_cmd)
579+
580+
if result.exit_status != 0 or not result.stdout.strip():
581+
# Not a ZFS pool
582+
return None
583+
584+
# Get the underlying devices for this ZFS pool
585+
devices_cmd = f"zpool list -v -H {pool_name} | grep -E '^\\s+\\w+' | awk '{{print $1}}' | head -1"
586+
devices_result = await self._instance.execute_command(devices_cmd)
587+
588+
if devices_result.exit_status == 0 and devices_result.stdout.strip():
589+
device = devices_result.stdout.strip()
590+
# Ensure device path starts with /dev/
591+
if not device.startswith('/dev/'):
592+
device = f"/dev/{device}"
593+
594+
_LOGGER.debug("ZFS pool '%s' resolved to device '%s'", pool_name, device)
595+
return device
596+
597+
_LOGGER.warning("Could not resolve ZFS pool '%s' to physical device", pool_name)
598+
return None
599+
600+
except Exception as err:
601+
_LOGGER.debug("Error resolving ZFS pool '%s': %s", pool_name, err)
602+
return None

0 commit comments

Comments
 (0)