- esp32_server: Popen 后外部 SetPriorityClass(RT/High),native 自设会被钳成 High - 入库 skip_* 标定/实验脚本与 REPORT_ecat_skip_opt_20260917 - 前端 WIP:layout/app/polling/boot_ecat/index - 不含 lab/skip_meter 原始采样与 preview 截图
127 lines
4.4 KiB
Python
127 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""快照当前主机侧可回滚现场:I210 高级属性、中断亲和、ecat 进程。"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
|
LAB = os.path.join(ROOT, "lab", "skip_meter")
|
|
|
|
|
|
def ps(cmd: str) -> str:
|
|
r = subprocess.run(
|
|
["powershell", "-NoProfile", "-Command", cmd],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
errors="replace",
|
|
)
|
|
return (r.stdout or "") + (("ERR:" + r.stderr) if r.stderr else "")
|
|
|
|
|
|
def main() -> int:
|
|
os.makedirs(LAB, exist_ok=True)
|
|
snap = {"ts": time.time(), "host": os.environ.get("COMPUTERNAME")}
|
|
|
|
snap["adapters"] = ps(
|
|
"Get-NetAdapter | Select-Object Name,InterfaceDescription,LinkSpeed,Status,"
|
|
"ifIndex,MacAddress | ConvertTo-Json -Compress"
|
|
)
|
|
# I210 specifically
|
|
snap["i210"] = ps(
|
|
"Get-NetAdapter | Where-Object {$_.InterfaceDescription -match 'I210'} | "
|
|
"Select-Object Name,ifIndex,Status,LinkSpeed | ConvertTo-Json -Compress"
|
|
)
|
|
|
|
# advanced properties (restore-able)
|
|
snap["i210_adv"] = ps(
|
|
"Get-NetAdapterAdvancedProperty -Name '以太网 2' -ErrorAction SilentlyContinue | "
|
|
"Select-Object Name,DisplayName,DisplayValue,RegistryKeyword,RegistryValue | "
|
|
"ConvertTo-Json -Compress"
|
|
)
|
|
|
|
# interrupt moderation / RSS / power
|
|
for kw in (
|
|
"*InterruptModeration",
|
|
"*ReceiveBuffers",
|
|
"*TransmitBuffers",
|
|
"*EEE",
|
|
"*EnergyEfficient",
|
|
"*FlowControl",
|
|
"*PriorityVLANTag",
|
|
"*TCPChecksumOffload*",
|
|
"*IPChecksumOffload*",
|
|
"*VMQ",
|
|
"*RSS",
|
|
"*InterruptModerationRate",
|
|
):
|
|
snap[f"adv_{kw.strip('*').replace('*','_')}"] = ps(
|
|
f"Get-NetAdapterAdvancedProperty -Name '以太网 2' -ErrorAction SilentlyContinue | "
|
|
f"Where-Object {{$_.RegistryKeyword -like '{kw}'}} | "
|
|
f"Select-Object RegistryKeyword,DisplayValue,RegistryValue | ConvertTo-Json -Compress"
|
|
)
|
|
|
|
snap["power"] = ps(
|
|
"Get-NetAdapterPowerManagement -Name '以太网 2' -ErrorAction SilentlyContinue | "
|
|
"Select-Object Name,AllowComputerToTurnOffDevice,WakeOnMagicPacket,"
|
|
"WakeOnPattern,DeviceSleepOnDisconnect | ConvertTo-Json -Compress"
|
|
)
|
|
|
|
snap["ecat_proc"] = ps(
|
|
"Get-Process ecat_native -ErrorAction SilentlyContinue | "
|
|
"Select-Object Id,Path,StartTime,CPU,WorkingSet | ConvertTo-Json -Compress"
|
|
)
|
|
|
|
snap["ecat_cmdline"] = ps(
|
|
"Get-CimInstance Win32_Process -Filter \"Name='ecat_native.exe'\" | "
|
|
"Select-Object ProcessId,CommandLine | ConvertTo-Json -Compress"
|
|
)
|
|
|
|
# interrupt affinity via Get-NetAdapterInterrupt? not always available
|
|
snap["msi_affinity"] = ps(
|
|
"Get-NetAdapterAdvancedProperty -Name '以太网 2' -ErrorAction SilentlyContinue | "
|
|
"Where-Object {$_.DisplayName -match 'Interrupt|Affinity|RSS|Moderation|Buffer|Energy|Green|Flow|Offload'} | "
|
|
"Select-Object DisplayName,DisplayValue,RegistryKeyword | ConvertTo-Json -Compress"
|
|
)
|
|
|
|
# CPU topology quick
|
|
snap["cpu"] = ps(
|
|
"$env:NUMBER_OF_PROCESSORS; (Get-CimInstance Win32_Processor | "
|
|
"Select-Object Name,NumberOfCores,NumberOfLogicalProcessors | ConvertTo-Json -Compress)"
|
|
)
|
|
|
|
out = os.path.join(LAB, f"host_snap_{int(time.time())}.json")
|
|
with open(out, "w", encoding="utf-8") as f:
|
|
json.dump(snap, f, ensure_ascii=False, indent=2)
|
|
|
|
# also human-readable restore snippet
|
|
lines = []
|
|
lines.append("# Host snapshot restore notes")
|
|
lines.append(f"time={snap['ts']}")
|
|
lines.append("## I210 adapter advanced (raw)")
|
|
lines.append(snap.get("i210_adv", "")[:8000])
|
|
lines.append("## power")
|
|
lines.append(snap.get("power", "")[:4000])
|
|
lines.append("## ecat cmdline")
|
|
lines.append(snap.get("ecat_cmdline", "")[:2000])
|
|
txt = os.path.join(LAB, f"host_snap_{int(snap['ts'])}.txt")
|
|
with open(txt, "w", encoding="utf-8") as f:
|
|
f.write("\n".join(lines))
|
|
|
|
print("I210:", snap.get("i210", "")[:500])
|
|
print("CMDLINE:", snap.get("ecat_cmdline", "")[:800])
|
|
print("ADV keys sample:")
|
|
print(snap.get("msi_affinity", "")[:2500])
|
|
print("WROTE", out)
|
|
print("WROTE", txt)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|