September 7, 2021

exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen

集群上有proxintosh和truenas scale的2套VM Guest,不过最近又出现掉硬盘的问题 各种盘都掉过 一开始以为是盘柜的问题直接 改成直插问题还是存在 又以为数据线质量降低了 换了SAS线问题依旧。最终想起来这个海盗船CSM750W是长城代工,品质可能真的是有瑕疵 一般的机器带带没问题 服务器可能不适合 恰好手头有个闲置的台达650W,各方面标称的输出都比这个CSM小一点点 不过历经磨难仍然坚挺 相信可以继续用 于是就动手换起来了。

结果经过昨晚一夜的高压IO Stress test+GPU+内存带宽的高压测试 除了温度比CMS750高了少许 标题提到的IO异常果真没有继续出现。之前用CSM750的时候只要IO随便加点压力内存跑点质数运算还没开始就可能出现掉盘ATA指令重置之类的情况 这下果然就好了 不得不手撕这个长城代工的垃圾货 标称可吹得响亮 实际负载情况却大有问题 万万没想到又是这个电源的锅 只好给老妈那台不常用的客厅电脑用用了 反正带个一俩块盘又是集成显卡相信问题不大。再不济我还有个SFX的小500W silverstone的备着

解决了硬件上的问题开始看Proxmox的软件了 最近proxmox跟着debian bullseye除了新版 由于我的Proxintosh依赖dkms上的vendor_reset插件,刚好可以用次旧版的Proxintosh安上5.11.22的比较新的内核来用proxintosh的VFIO.所以决定宿主机旧暂不追新了 不过软路由上的宿主我已经更新到PVE 7说句实话 新版增加的高级功能还没来得及体验 短期可能不一定用得上 还是把旧版调试调试 增加点想要的功能。 比如我希望直接在面板就能监控硬盘的健康状态和温度 免得我手动敲一堆命令去查手册

google了一圈儿,发现很多文章解决了他们自己的问题 但是我的盘用他们提供的hddtemp的方法是一个也认不出来 hddtemp.db的数据库也是万年没有更新的意思 很多文章提供反查并插入数据更新来解决hddtemp不认新硬盘温度的方法 我照做了 数据库很明显有合乎语法的记录但是软件却不命中 我只能另辟蹊径 当然还是感谢这些文章提供了我总体思路 我利用磁盘哨兵来搞定了温控的问题 磁盘哨兵hdSentinel的商业版在WINDOWS平台上是要花钱的,但是linux甚至arm版linux上是免费软件 虽然功能单一 但胜在体积小巧用法简单。

我按照前人的思路找到/usr/share/perl5/PVE/API2/Nodes.pm文件  找到$res->{pveversion} = PVE::pvecfg::package() . "/" . 这行的位置下面 增加了自己的温控和主频还有硬盘温度的采集方法:

	$res->{thermalstate} = `sensors`;
	$res->{cpusensors} = `lscpu | grep MHz`;
	$res->{hdd_temperatures} = `hdSentinel |grep -e Device -e Temp -e Health -e Model`;

展示一下硬盘哨兵整理的磁盘列表结果:

HDD Device  0: /dev/sda
HDD Model ID : Samsung SSD 840 PRO Series
Temperature  : 36 °C
Highest Temp.: 50 °C
Health       : 84 %
HDD Device  1: /dev/sdb
HDD Model ID : Crucial_CT256M550SSD1
Temperature  : 39 °C
Highest Temp.: 58 °C
Health       : 78 %
HDD Device  2: /dev/sdc
HDD Model ID : INTEL SSDSC2KW512G8
Temperature  : 36 °C
Highest Temp.: 62 °C
Health       : 94 %
HDD Device  3: /dev/sdd
HDD Model ID : INTEL SSDSC2KW256G8
Temperature  : 35 °C
Highest Temp.: 43 °C
Health       : 99 %
HDD Device  4: /dev/sde
HDD Model ID : Samsung SSD 860 EVO 500GB
Temperature  : 35 °C
Highest Temp.: 61 °C
Health       : 80 %
HDD Device  5: /dev/sdf
HDD Model ID : Samsung SSD 860 EVO 500GB
Temperature  : 36 °C
Highest Temp.: 59 °C
Health       : 80 %

由于nvme盘里装了proxintosh 所以直通硬件没有显示在这个列表里 我也并不在乎这个蓝盘的温度所以没有增加nvme盘的选项 不过代码各位看官可以自己增加修改不多说了

搜索/usr/share/pve-manager/js目录下的pvemanagerlib.js定位到下面这块代码 调整高度到您觉得合适得高度 不要超过你要适配的屏幕大小就行

	Ext.create('Ext.window.Window', {
	    modal: true,
	    width: 800,
	    height: 600,
	    resizable: true,
	    layout: 'fit',
	    title: gettext('Status') + ': ' + zpool,
        ...
        });

以及这里的高度 原则一致 Padding也是根据自己要适配的屏幕需求来自己修改

Ext.define('PVE.node.StatusView', {
    extend: 'Proxmox.panel.StatusView',
    alias: 'widget.pveNodeStatus',

    height: 540,
    bodyPadding: '7 7 7 7',

    layout: {
	type: 'table',
	columns: 2,
	tableAttrs: {
	    style: {
		width: '100%',
	    },
	},
    ...
});

然后新增资源数据的解析方法: 我对原作者的解析部分根据我的机器情况做出了自己的修改 看官可以一边吃瓜一边批评指教 我自认为我的更简单更短小 没考虑什么性能什么的。实际运行情况也显示对资源开销并不大。

{
		itemId: 'thermal',
		colspan: 2,
		printBar: false,
		title: gettext('Temperature'),
		textField: 'thermalstate',
		renderer:function(value){
		  const c0 = value.match(/nct6798-isa-0290.*?\+([\d\.]+)?/)[1];
		  const c1 = value.match(/k10temp-pci-0300.*?\+([\d\.]+)?/)[1];
		  return `AUXTIN+\d[0-3]: ${c0}   |  Tctl: ${c1} `
	   }     
	},
	{
	    itemId: 'version',
	    colspan: 2,
	    printBar: false,
	    title: gettext('PVE Manager Version'),
	    textField: 'pveversion',		
	    value: '',
	},

	{
        itemId: 'thermal',
        colspan: 2,
        printBar: false,
        title: gettext('CPU 温度'),
        textField: 'thermalstate',
        renderer:function(value){
        const c0 = value.match(/Tctl.*?\+([\d\.]+)Â/)[1];
        const c1 = value.match(/Tccd1.*?\+([\d\.]+)Â/)[1];
		const d0 = value.match(/Tdie.*?\+([\d\.]+)Â/)[1];
        return `Tdie: ${d0} ℃ | Tctl: ${c0} ℃ | Tccd1: ${c1} ℃`
        }
	},

	{
        itemId: 'MHz',
        colspan: 2,
        printBar: false,
        title: gettext('CPU 频率'),
        textField: 'cpusensors',
        renderer:function(value){
        const f0 = value.match(/CPU MHz.*?([\d]+)/)[1];
		const f1 = value.match(/CPU min MHz.*?([\d]+)/)[1];
        const f2 = value.match(/CPU max MHz.*?([\d]+)/)[1];
        return `CPU Time: ${f0} MHz | Min: ${f1} MHz  | Max: ${f2} MHz`
        }
	},

	{
		itemId: 'hdd-temperatures',
		colspan: 2,
		printBar: false,
		title: gettext('HDD Temperatures'),
		textField: 'hdd_temperatures',
		renderer: function(value) {
			value = value.replace(/Â/g, '');
			// console.log(value);
			array = value.split('%')			
			return array.map(entry => (entry)).join('%'+"\n"+'</br>') ;						
		}
	}

 

我没有修改移动版界面的内容 但是看官如果有需求相信动动手就能实现 下面截个图展示一下效果: