Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4a2692d46 |
No files matched your search
@@ -5,7 +5,7 @@ use warnings;
|
||||
use Exporter 'import';
|
||||
|
||||
use PVE::PVEMod::Config qw(%config $process_type $pve_mod_working_dir);
|
||||
use PVE::PVEMod::Utils qw(debug check_executable setup_collector_signals safe_write_json);
|
||||
use PVE::PVEMod::Utils qw(debug check_executable setup_collector_signals safe_write_json read_sysfs);
|
||||
use PVE::PVEMod::Store qw(update_intel_gpu_rrd);
|
||||
|
||||
our @EXPORT_OK = qw(
|
||||
@@ -13,10 +13,30 @@ our @EXPORT_OK = qw(
|
||||
collector_for_intel_device
|
||||
);
|
||||
|
||||
use constant INTEL_VENDOR_ID => '8086';
|
||||
|
||||
# ============================================================================
|
||||
# Intel GPU — device discovery
|
||||
# ============================================================================
|
||||
|
||||
# Resolve the PCI vendor ID (lowercase, e.g. "8086") from either a
|
||||
# "vendor=XXXX" descriptor or a "DDDD:BB:DD.F" address looked up via sysfs.
|
||||
sub _get_pci_vendor_id {
|
||||
my ($path) = @_;
|
||||
|
||||
if ($path =~ /vendor=([0-9a-fA-F]{4})/) {
|
||||
return lc($1);
|
||||
}
|
||||
|
||||
if ($path =~ m{^pci:([0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.\d+)$}) {
|
||||
my $vendor = read_sysfs("/sys/bus/pci/devices/$1/vendor");
|
||||
$vendor =~ s/^0x//i;
|
||||
return lc($vendor);
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub get_intel_gpu_devices {
|
||||
my @devices = ();
|
||||
my $fh;
|
||||
@@ -43,6 +63,11 @@ sub get_intel_gpu_devices {
|
||||
chomp;
|
||||
if (/^(card\d+)\s+(.+?)\s+(pci:[^\s]+)/) {
|
||||
my ($card, $name, $path) = ($1, $2, $3);
|
||||
my $vendor = _get_pci_vendor_id($path);
|
||||
if (!defined $vendor || $vendor ne INTEL_VENDOR_ID) {
|
||||
debug(__LINE__, "Skipping non-Intel device: $card ($path) vendor=" . ($vendor // 'unknown'));
|
||||
next;
|
||||
}
|
||||
push @devices, {
|
||||
card => $card,
|
||||
name => $name,
|
||||
|
||||
@@ -17,7 +17,7 @@ our @EXPORT_OK = qw(
|
||||
# Debug / Version
|
||||
# ============================================================================
|
||||
|
||||
our $DEBUG_ENABLED; # derived from %config{debug}{mod_debug} after ini load, below
|
||||
our $DEBUG_ENABLED = 1;
|
||||
our $VERSION = 'version-placeholder';
|
||||
|
||||
# ============================================================================
|
||||
@@ -43,7 +43,6 @@ our %config = (
|
||||
gpu_history => 0,
|
||||
},
|
||||
debug => {
|
||||
mod_debug => 0,
|
||||
log_enabled => 0,
|
||||
log_file => '/tmp/pve-mod-debug.log',
|
||||
lm_sensors_mode => 0,
|
||||
@@ -160,6 +159,4 @@ sub _load_ini_file {
|
||||
_load_ini_file($CONF_FILE);
|
||||
_load_ini_file($_) for glob("$CONFD_DIR/*.conf");
|
||||
|
||||
$DEBUG_ENABLED = $config{debug}{mod_debug};
|
||||
|
||||
1;
|
||||
@@ -30,11 +30,7 @@ ignore_temp_below=5
|
||||
|
||||
# Debug mode: when a collector's mode is 1, the real tool is not required.
|
||||
# Data is read from the file path instead. Useful for development/testing.
|
||||
# Note: debug settings are only read at pveproxy startup — restart pveproxy
|
||||
# after changing them. Debug output goes to the journal (journalctl -u pveproxy),
|
||||
# plus log_file if log_enabled=1.
|
||||
[debug]
|
||||
mod_debug=0
|
||||
lm_sensors_mode=0
|
||||
lm_sensors_output_file=/tmp/sensors-output.json
|
||||
intel_mode=0
|
||||
|
||||
@@ -59,6 +59,24 @@ _check_nvidia_tool() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Resolve the PCI vendor ID (lowercase, e.g. "8086") from either a
|
||||
# "vendor=XXXX" descriptor or a "DDDD:BB:DD.F" address looked up via sysfs.
|
||||
_get_pci_vendor_id() {
|
||||
local path="$1" vendor=""
|
||||
if [[ "$path" =~ vendor=([0-9a-fA-F]{4}) ]]; then
|
||||
vendor="${BASH_REMATCH[1]}"
|
||||
elif [[ "$path" =~ ^pci:([0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-9]+)$ ]]; then
|
||||
local vfile="/sys/bus/pci/devices/${BASH_REMATCH[1]}/vendor"
|
||||
[[ -f "$vfile" ]] && vendor=$(cat "$vfile")
|
||||
vendor="${vendor#0x}"
|
||||
fi
|
||||
echo "${vendor,,}"
|
||||
}
|
||||
|
||||
_is_intel_pci_device() {
|
||||
[[ "$(_get_pci_vendor_id "$1")" == "8086" ]]
|
||||
}
|
||||
|
||||
# --- standard API ------------------------------------------------------------
|
||||
|
||||
node_info_defaults() {
|
||||
@@ -78,7 +96,6 @@ node_info_defaults() {
|
||||
DEBUG_AMD=0; DEBUG_AMD_FILE="/tmp/amd-gpu-devices.json"
|
||||
DEBUG_UPS=0; DEBUG_UPS_FILE="/tmp/ups-output.json"
|
||||
DEBUG_LOG=0; DEBUG_LOG_FILE="/tmp/pve-mod-debug.log"
|
||||
DEBUG_MOD=0
|
||||
}
|
||||
|
||||
node_info_load_conf() {
|
||||
@@ -125,7 +142,6 @@ node_info_load_conf() {
|
||||
debug.ups_output_file) DEBUG_UPS_FILE="$val" ;;
|
||||
debug.log_enabled) DEBUG_LOG="$val" ;;
|
||||
debug.log_file) DEBUG_LOG_FILE="$val" ;;
|
||||
debug.mod_debug) DEBUG_MOD="$val" ;;
|
||||
esac
|
||||
done < "$NODE_INFO_CONF"
|
||||
}
|
||||
@@ -340,7 +356,15 @@ node_info_configure() {
|
||||
warn "No Intel GPUs in debug file."
|
||||
fi
|
||||
elif _check_or_install_tool intel_gpu_top intel-gpu-tools "Intel GPU tools (intel-gpu-tools)"; then
|
||||
intelCards=$(intel_gpu_top -L 2>/dev/null | grep -E '^card[0-9]+' || true)
|
||||
local rawIntelCards
|
||||
rawIntelCards=$(intel_gpu_top -L 2>/dev/null | grep -E '^card[0-9]+' || true)
|
||||
# Filter out non-Intel devices (e.g. AMD cards misdetected when intel-gpu-tools is installed on non-Intel hardware)
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
if [[ "$line" =~ (pci:[^[:space:]]+) ]] && _is_intel_pci_device "${BASH_REMATCH[1]}"; then
|
||||
intelCards+="${intelCards:+$'\n'}$line"
|
||||
fi
|
||||
done <<< "$rawIntelCards"
|
||||
if [[ -n "$intelCards" ]]; then
|
||||
info "Intel GPU(s) detected:"
|
||||
echo "$intelCards" | while IFS= read -r line; do echo " $line"; done
|
||||
@@ -365,7 +389,7 @@ node_info_configure() {
|
||||
echo "$json" > "$DEBUG_INTEL_FILE"
|
||||
info "Intel GPU device list saved to $DEBUG_INTEL_FILE"
|
||||
else
|
||||
warn "No Intel GPUs detected by intel_gpu_top."
|
||||
warn "No Intel GPUs detected by intel_gpu_top (or none had an Intel PCI vendor ID)."
|
||||
fi
|
||||
fi
|
||||
#endregion Intel GPU
|
||||
@@ -514,11 +538,7 @@ ignore_temp_below=${IGNORE_TEMP_BELOW}
|
||||
|
||||
# Debug mode: when a collector's mode is 1, the real tool is not required.
|
||||
# Data is read from the file path instead. Useful for development/testing.
|
||||
# Note: debug settings are only read at pveproxy startup — restart pveproxy
|
||||
# after changing them. Debug output goes to the journal (journalctl -u pveproxy),
|
||||
# plus log_file if log_enabled=1.
|
||||
[debug]
|
||||
mod_debug=${DEBUG_MOD}
|
||||
lm_sensors_mode=${DEBUG_LM_SENSORS}
|
||||
lm_sensors_output_file=${DEBUG_LM_SENSORS_FILE}
|
||||
intel_mode=${DEBUG_INTEL}
|
||||
|
||||
@@ -67,27 +67,3 @@ Each feature requires the corresponding tool to be installed on the Proxmox host
|
||||
## Debug Mode
|
||||
|
||||
Each collector supports a debug mode that reads from a local file instead of executing the real tool. Useful for development and testing without physical hardware.
|
||||
|
||||
### Per-collector debug files
|
||||
|
||||
Set the collector's `_mode` flag to `1` in the `[debug]` section of `/etc/pve-mod/conf.d/node_info.conf` and populate its file(s) with sample data, captured from a real host via the commands below:
|
||||
|
||||
| Collector | Enable flag | File | Content | Example to generate it |
|
||||
|-----------|-------------|------|---------|-------------------------|
|
||||
| Temperature sensors | `lm_sensors_mode` | `lm_sensors_output_file` | Raw `sensors -j` JSON output | `sensors -j > /tmp/sensors-output.json` |
|
||||
| Intel GPU | `intel_mode` | `intel_devices_file` | Device list, one line per GPU (`intel_gpu_top -L` format) | `intel_gpu_top -L > /tmp/intel-gpu-devices.json` |
|
||||
| | | `intel_output_file` | Continuous `intel_gpu_top` stats output | `intel_gpu_top -d /dev/dri/card0 -s 1000 -l > /tmp/intel-gpu-output.txt` |
|
||||
| NVIDIA GPU | `nvidia_mode` | `nvidia_devices_file` | Device list CSV | `nvidia-smi --query-gpu=index,name --format=csv > /tmp/nvidia-smi-devices.csv` |
|
||||
| | | `nvidia_output_file` | Stats CSV | `nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,utilization.memory,memory.used,memory.total,power.draw,power.limit,fan.speed --format=csv,nounits > /tmp/nvidia-smi-output.csv` |
|
||||
| AMD GPU | `amd_mode` | `amd_devices_file` | Placeholder — collector not yet implemented | — |
|
||||
| UPS | `ups_mode` | `ups_output_file` | Raw `upsc` key: value output (despite the `.json` name, it's plain text, not JSON) | `upsc ups@192.168.1.50 > /tmp/ups-output.json` |
|
||||
|
||||
### Verbose module logging (mod_debug)
|
||||
|
||||
Set `mod_debug=1` in the `[debug]` section of `/etc/pve-mod/conf.d/node_info.conf`, then restart `pveproxy` (`systemctl restart pveproxy`) — the setting is only read at startup. With it enabled, the mod logs each internal step (collector start/stop, cache hits, file reads, etc.) to the journal, viewable with:
|
||||
|
||||
```sh
|
||||
journalctl -u pveproxy -f
|
||||
```
|
||||
|
||||
Set `log_enabled=1` (and optionally `log_file`) in the same section to also persist this output to a file.
|
||||
Reference in new issue
Block a user