之前下雨的时候家里又跳闸了。想来想去，去京东买了个APC的BK650M2-CH的UPS。本文记述如何让NUC在UPS电量低的时候自动关机。前言因为Linux在我的印象中一直是很脆弱的那种角色（它很强大，但也很脆弱），尤其是ext4时代经常有人说突然掉电之后会有什么文件系统损毁之类的事情。虽然Btrfs已经不会出现这个问题了，但我对突然掉电还是耿耿于怀。前几天我家又停电了，于是便考虑买个UPS。我买的型号是APC的BK650M2-CH，特征就不介绍了。我这边测试让NUC跑满s-tui，保持CPU使用率100%，从UPS满电到UPS自动关机，一共能坚持35分钟。我想这35分钟怎么都够我找到新的电源了。就算找不到，我也有时间保存我的工作进度。再不济我直接进入挂起模式，只给内存供电，按照这个功耗那跟定比35分钟要多。于是问题来了：我睡觉的时候停电了怎么办？得想个办法能够让NUC在最坏情况下保护工作进度。关机是不现实的，因为有些软件并不会自动保存。那么挂起是一个措施，但谁来触发呢？我发现gnome桌面能够自动识别到UPS，但经过我的实际测试，就算是UPS低电量自动关机，就算是在此之前gnome也会提示UPS电量低，但他就是不会自动关机。我猜测可能还是UPS和电池供电不同吧。最开始我尝试了apcupsd，这个是专门给APC的UPS准备的。但我发现BK650M2-CH和他不兼容，具体表现是acpaccess读取不出来当前UPS的状态。只能作罢，后来看到一个叫做NUT的东西，叫Network UPS Tools，它可以监控UPS的状态，并通过网络将UPS的状态发送出去。这样一来，如果你有10台服务器都接在一个UPS上，那我们只需要将UPS连接到一台服务器上，然后其他服务器通过网络即可查询到UPS的状态，并实现自动关机。由于我目前的设备比较简单，只有NUC是没有内置电池的，所以本文使用standalone模式。安装配置NUT的安装很是方便：sudo zypper in nut安装完成后可以查询APC的UPS应该用哪些driver：cat /usr/share/nut/driver.list | grep "APC""APC" "ups" "3" "Back-UPS (USB)" "USB" "usbhid-ups"由于我的型号是使用USB进行通讯的，因此driver填写usbhid-ups就可以了。修改配置文件/etc/ups/ups.conf：[apc-bk650m2-ch] driver = usbhid-ups port = auto desc = "APC BK650M2-CH"然后修改/etc/ups/nut.conf：MODE=standalone这样我们就无需启动服务器和客户端了。由于我们不需要服务端，因此也无需修改upsd.conf和upsd.users文件。但我们还需要修改upsmon.conf：MONITOR apc-bk650m2-ch@localhost 1 upsmaster @UPSD_INITIAL_MASTER_PASSWORD@ master SHUTDOWNCMD "/usr/bin/systemctl suspend" SHUTDOWNEXIT no配置文件中默认的名字是myups，我们需要将MONITOR改成我们对应的。后面的数字1表示供电数量，由于这个UPS只提供只向我们系统提供1路供电。同时我们希望挂起系统而不是关闭系统，所以我们还要修改关机的命令（SHUTDOWNCMD）。同时因为是挂起，所以我们不希望NUT发出关机指令后退出，而是保持运行，所以还要调整SHUTDOWNEXIT。一切调整妥当之后：systemctl enable nut-driver-enumerator systemctl enable nut.target --now upsc apc-bk650m2-ch第一行用来启动一个叫做nut-driver-enumerator的服务，它的作用是根据ups.conf中定义的设备来拉起对应的driver。第二行用来启动nut服务，第三行用来查询测试nut服务是否和apc连接正常。如果正常的话，第三行会打印出：skyblond@crescent-rose:~> upsc apc-bk650m2-ch battery.charge: 100 battery.charge.low: 93 battery.mfr.date: 2001/01/01 battery.runtime: 3011 battery.runtime.low: 120 battery.type: PbAc battery.voltage: 13.6 battery.voltage.nominal: 12.0 device.mfr: American Power Conversion device.model: Back-UPS BK650M2-CH device.serial: 【数据删除】 device.type: ups driver.debug: 0 driver.flag.allow_killpower: 0 driver.name: usbhid-ups driver.parameter.pollfreq: 30 driver.parameter.pollinterval: 2 driver.parameter.port: auto driver.parameter.synchronous: auto driver.state: quiet driver.version: 2.8.2 driver.version.data: APC HID 0.100 driver.version.internal: 0.53 driver.version.usb: libusb-1.0.27 (API: 0x100010a) input.sensitivity: low input.transfer.high: 278 input.transfer.low: 160 input.voltage: 232.0 input.voltage.nominal: 220 ups.beeper.status: enabled ups.delay.shutdown: 20 ups.firmware: 294803G -292804G ups.load: 9 ups.mfr: American Power Conversion ups.mfr.date: 2024/03/24 ups.model: Back-UPS BK650M2-CH ups.productid: 0002 ups.realpower.nominal: 390 ups.serial: 【数据删除】 ups.status: OL ups.test.result: No test initiated ups.timer.reboot: 0 ups.timer.shutdown: -1 ups.vendorid: 051d测试现在我们拔掉UPS的电源，通过watch -n 5 upsc apc-bk650m2-ch来观测电量低时是否会自动挂起。第一次测试发现我这个ups很容易就发起Low Battery状态。尽管nut认为电池还有70%的余量，但只要ups发出Low Battery它就会发出关机指令。为了改进这个问题，我们让nut在battery.charge低于battery.charge.low的时候触发挂起。但默认情况下battery.charge.low是93，有点太高了。在ups.conf中修改：[apc-bk650m2-ch] ... ignorelb override.battery.charge.low = 75 追加一个忽略UPS的低电量通知，然后追加一行override即可把低阈值改为75%，随后重启服务：sudo service nut restart拔掉电源，再做测试，发现这次确实是在UPS电量低于75%的时候触发的挂起。最后我们再来计算一下找到不到设备的时候会发生什么：假如我要带着NUC去别的地方，那肯定不会带UPS。这样一来就会出现NUT在运行，但一直联系不上UPS的状况。经过测试，这种连不上的情况并不会导致异常挂起，但nut-monitor确实会一直尝试刷新。而每次刷新失败都会导致打印一些日志。解决方法嘛，也很简单：关掉服务就好了。如果不关的话其实也问题不大，无外乎就是打出一大堆日志。但openSUSE对日志大小有限制，不必担心日志写满磁盘。后记购入了UPS之后家里有过几次停电。最开始进入了挂起状态却还是没电了，恢复之后发现竟然是UPS没电了，我左思右想，最终发现：虽然笔记本电脑的充电器并没有连着UPS，但是磁带机使用雷电接口接入笔记本，雷电接口是可以提供PD协议快冲的。所以就算是停电了，磁带机本身待机功耗不大，可是它开始用UPS的电给笔记本充电，最终导致UPS电池耗尽。由于磁带机也不常用，现在基本上就是每两周备份的时候使用，因此平时不用的时候都拔掉电源，同时我还把进入挂起的电源电量从25%提高到了75%（之前文章里写的是25，后来改成75了），这样尽最大可能保证进入挂起状态后能够坚持到供电恢复，从而保证不丢数据。至此，停电再也不是我的心头大患了。-全文完-
上一篇文章介绍了我购买并配置Intel NUC13Pro的过程。在使用过程中，我发现有时候开机会找不到启动盘，有时候系统会突然卡死。本文将记述我逐步排查问题，并最终更换SSD的过程。SSD掉盘的三种形式其实在最开始的一周，这块金士顿的SSD并没有表现出太多的问题。偶尔在打开IDEA的时候会卡顿，有时候会直接导致系统卡死。我一开始以为是Swap的原因，因为Swap给的太小了，我平时工作需要开40多个Chrome标签，还有2个左右的IDEA，整体不够用。后来紧急从京东下单了一条DDR4 32GB的内存条，变成了8+32的配置，内存就赋予了很多，现在基本上日常占用在20GB左右，因此也就不着急升级到32+32了。但这个时候系统卡顿的情况还是会偶尔发生，但不是很频繁，我就没在意。第一次系统卡死发生后我就开启了Sysrq，这样我就可以通过REISUB来安全的重启系统了。但后来我发现了两个现象：首先就是卡死后重启有机率找不到SSD，表现形式就是BIOS提示A bootable drive has not been detected，进入bios后发现NVMe槽是空的，和没插盘是一样的。其次就是我注意到在按下Alt+PrtScr+R之后，输出会被强制切换到控制台，这个时候有机会能看到NVMe相关的报错，主要有三条：第一条的具体报错记不清了，大概就是Btrfs进行IO操作的时候因为超时失败了第二条也记不清了，大意是NVMe没有及时响应系统的请求，内核尝试reset控制器第三条则是一个Abort status: 0x371但大部分情况都能在重启后解决，于是我就没有当回事。直到周五晚上我打开IDEA，系统突然崩溃——和卡死不同，鼠标和UI都是有响应的，但任何从硬盘读数据的行为都会被阻塞（事后才知道，这个时候盘已经掉了，ui还能响应全靠内存的缓存）。于是我便重启了，重启之后看到控制台询问我的luks密码，我就按了电源键关机，睡觉去了。可等到周六我再开机，那盘就再也没出现过了。当时我想可能是因为金手指接触不良，我拆开擦擦就是了。结果拆开再装回去，还是不识别。我就很奇怪，于是就保持后盖打开，装好SSD，再开机——识别了。好的，那我们把后盖合上，然后再开机——系统找不到盘。我：？？？此时我心中有了一些假设，因为刚才拆下来擦金手指的时候我就觉得这块盘的做工极差——像是三星和西数的SSD，你轻微施力掰它，它的PCB是比较硬的，这种手感的回馈就是告诉你不要掰；而金士顿这块硬盘的PCB很薄，也很软，你轻微施力掰它，它就随着你用力而弯曲，没有太多的抵抗。而NUC为了节省空间，它的SSD并不是贴在主板上的，反而是悬空的。在垂直方向，先是网卡在主板上，然后是SSD摞在网卡上。所以我推测会不会是背盖上的散热条把SSD压弯了，导致M.2接口接触不良呢？针对这个假设，我做了一个实验：不装背盖：可以检测到盘装上背盖，但不拧螺丝：可以检测到盘装上背盖，用手旋紧螺丝：有机率可以检测到盘。如果遇到掉盘，拆下背盖后重新安放、拧紧装上背盖，用螺丝刀拧紧螺丝：我试了好几次，就是检测不到盘虽然不能确定就是散热条把SSD压弯了导致接触不良，但从结果来看，螺丝的松紧程度确实能够影响盘能不能被识别到。因此我想到了一个很简易的办法：把纸叠起来，垫在ssd底下。因为叠起来的纸有弹性，所以可以确保把SSD压在散热条上，这样就可以保证它处于正确的位置了。经过这样一番折腾，我成功地解决了PCB太软的问题。但这还并不是问题的全部。周六中午我在进行网络冲浪的时候，突然发现浏览器崩溃了，而且没有崩溃报告，同时所有需要从硬盘读数据的操作都卡住了。我很自然地按下Alt+PrtScr+R，看到了先前说的几条报错信息。于是我就去网络上搜索了一下，大部分结果都指向一个叫做APST的东西。这东西全称Autonomous Power State Transition，中文叫自动电源状态转换。这个功能的主要目的就是在你不使用或轻度使用NVMe盘时自动缩减功耗，从而为移动设备争取一些续航。但这种缩减功耗带来的就是响应延迟的上升，而这里我确实在控制台上看到一个timeout，所以我觉得有戏。根据ArchWiki)所说，Linux内核对于Power State最大延迟设置是25ms，任何超过25ms的硬盘都应该通过内核参数手动调整这个值，来避免Linux误认为NVMe盘出问题了。于是我通过sudo nvme id-ctrl /dev/nvme0n1查看了一下我这个盘的延迟：ps 0 : mp:5.00W operational enlat:0 exlat:0 rrt:0 rrl:0 rwt:0 rwl:0 idle_power:- active_power:- active_power_workload:- ps 1 : mp:3.50W operational enlat:0 exlat:200 rrt:1 rrl:1 rwt:0 rwl:0 idle_power:- active_power:- active_power_workload:- ps 2 : mp:2.50W operational enlat:0 exlat:1000 rrt:2 rrl:2 rwt:0 rwl:0 idle_power:- active_power:- active_power_workload:- ps 3 : mp:1.50W non-operational enlat:5000 exlat:5000 rrt:3 rrl:3 rwt:3 rwl:3 idle_power:- active_power:- active_power_workload:- ps 4 : mp:1.50W non-operational enlat:20000 exlat:70000 rrt:4 rrl:4 rwt:4 rwl:4 idle_power:- active_power:- active_power_workload:-总延迟是enlat + exlat，这么来看，如果SSD进入了4号电源状态，那么总共需要90ms才能响应系统的指令，这远超过Linux内核默认的25毫秒。所以我在YaST中添加了内核参数nvme_core.default_ps_max_latency_us=100000，我打出富裕量，给了100ms的超时。此时我以为这些问题都被解决了，可以高枕无忧了。但随后的事情让我直接去京东下单了新的SSD。故事发生在周六下午。我在为接下来的五一假期做准备，我计划带着这个NUC和一个便携屏幕出游。这个NUC比笔记本要轻大约一斤多，而这块便携屏幕不用的时候还可以给Switch用，我觉得甚是方便。于是便开始从家里的NAS拷贝一些要看的电影、动漫之类的。就在拷贝途中，整个系统突然崩溃了，那我能怎么办？重启呗。结果重启之后就找不到盘了。我这一想，纸也垫了，内核参数也加了，怎么就还是有问题呢？而且这次掉盘持续时间很长：无论怎么开机，就是提示找不到。我只能又拆开背盖。拆开背盖之后用手一摸SSD，我本意是想可能还是接触不良，我就伸手押着SSD头部，没想到我瞄的特别准，一手指头就按到主控上去了，当时我就后悔了——烫啊，真他妈烫啊。凉了差不多十分钟，盖上盖子再开机，SSD又像个好人似的了。于是我便继续复制影视作品，没想到，梅开二度，又来一次。这下我可就犯难了：垫上纸可能会导致SSD过热，毕竟纸基本不导热，而且更像是给SSD加了个褥子。可是不加纸吧，这动不动就掉盘，我真怕数据丢了。每次强制重启之后我都要用btrfs scrub检查一下数据和元数据，幸好没有出错。但是老这样不是办法啊，看了一眼时间，我还有机会，现在下单明天（周日）就能到。于是开始考虑购买哪一款SSD。首先排除三星，不是它不好——我笔记本的两条SSD都是三星的，我给亲戚组电脑也推荐的三星，我用的很满意——但就是太贵了。我这个月为了NUC和望远镜已经花了不少钱了，我想控制一下预算。但是又得避免因为控制预算而买到类似这个金士顿的情况，于是左思右想，买了2TB的西数SN580。虽然不是顶级产品线，比三星差了不老少，但是我从一些测评来看，它至少稳定，不会翻车，保修也靠谱，三年900TB写入，最主要的是2TB卖1000块钱，隔壁三星1千连1TB都不给你，还要什么自行车啊。周日上午硬盘如期而至，下面的问题就是怎么在不重装系统的情况下迁移并扩容硬盘。迁移启动盘如果是数据盘那就好办了，直接复制粘贴。但是系统盘的话有启动分区，还有好多安装的配置，如果重装的话就太麻烦了。我安装系统时使用了LUKS加密，并且开启了LVM，主文件系统是Btrfs。由于这次是从500GB到2TB的“升级”，所以相对来说还是容易一些。计划大体分两部：使用CloneZilla迁移数据，然后再想怎么扩容。ClonezillaClonezilla一直是一个我很喜欢的工具。它和dd不一样，clonezilla能够感知文件系统。对于没有全盘加密的分区，它可以只保留实际有数据的部分。对于有加密的分区，新版本还可以先解密再按照分区抓取。不过我这里的目的更像是1:1复制整个硬盘，所以我没有选择解密。整个盘500G，实际使用不到80GB，最终经过压缩，占用的数据量只有120GB左右。不过这个是新盘，如果用过一段时间的话，没被使用的部分会留下难以压缩的脏数据，这个到时候就麻烦了。这次好在我有可以用来存储的移动硬盘，因为移动硬盘也是固态，所以抓取很快就结束了。在抓取的过程中，我根据以前的经验，让SSD尽可能处在最佳状态：打开背盖、吹风扇。抓下来数据之后，保存下来就可以往新的SSD里还原了。还原的过程不需要任何额外的配置，由于分区大小不一样，我选择按照原始分区大小还原，之后由我手动来扩容。还原之后重启，看到屏幕上询问我LUKS密码的字样，我心头的石头就放下了一半。进到系统进行了简单的测试，确认文件系统没有任何错误之后可以进行扩容了。扩容本节的命令如果没有特殊说明，则都是在root权限下运行。扩容阶段我使用的是openSUSE TW的Gnome LiveCD，它里面包含了一个叫做GParted的图形工具，可以用来分区，比YaST的分区工具要好用。在分区工具里，我发现我的硬盘上竟然有4个分区：1个Linux的启动分区，1个Windows EFI分区（16MB），1个LVM数据卷，还有1个不知道是做什么的大小只有500MB的分区。虽然我在安装系统的时候指示安装器把Windows分区删掉，可能安装器以为我要Dual Boot，就没删干净。不过没关系，这里我们可以把他们删掉，这样一来，nvme0n1p1是Linux的启动分区，nvme0n1p3是LVM数据卷。这个数据卷前后都有空闲空间，虽然前面的空闲空间只有16MB，那也不能闲着。默认情况下LVM分区是没有解密挂载的，所以我们可以直接开始操作：在GParted里右键LVM卷选择Move，然后通过滑块调整，让前面的空闲空间变为0MB，然后把大小拉到最大。这样除了100MB的启动分区，剩下的就全都是LVM的天下了。保存结果后GParted需要将原来的数据复制过去，就是说前面的16MB不能空着，得让数据整体往前移动16MB。好在NVMe固态硬盘很快，没有十分钟就复制完了。接下来就是让LVM扩容。我在网上看到一些资料声称要给LUKS扩容。我查询了一些资料，发现LUKS是不需要扩容的，它本质是一种映射：你访问一个块，它把数据解密之后给你，它并不关心这个分区有多大，它只关心在数据写入磁盘之前进行加密、从磁盘读出来之后解密。由于先前我们使用GParted进行了位移操作，所以LVM肯定是没有挂载的。挂载LVM时只能往后延伸分区，并不能位移。如果你挂载了LVM，那么你可以通过关闭再打开的方式让LUKS设备刷新它的大小，或者通过如下命令让LUKS知晓你对分区的变更：cryptsetup resize <name>这里的name是解密挂载时的名称，如果你是让GParted挂载的，那么名字通常是<partition>_crypt，比如我的分区是nvme0n1p3，那么我解密挂载的设备就是nvme0n1p3_crypt。当LUKS能够检测到新的硬盘大小之后，我们就可以扩容LVM了。这里涉及到LVM的三个概念：PV，也称Physical Volume，即物理卷。物理卷是在磁盘中实际存储数据的分区，比如我们的nvme0n1p3VG，也称Volume Group，即卷组。一个卷组类似一个存储池，它将多个物理卷抽象成一个块设备，形成一个逻辑上的硬盘LV，也称Logical Volume，即逻辑卷。一个卷组可以分配出多个逻辑卷。逻辑卷就像是虚拟硬盘上的分区，这个也是我们实际给文件系统用的分区这样就看出来LVM的好处了：通过将多个物理设备抽象成逻辑概念，我们可以保持分区不动的情况下更换或调整物理设备。那么从这个结构中也能看出来，物理卷是最基础的一层，我们应该先扩容它：pvresize /dev/mapper/nvme0n1p3_crypt在没有任何多余选项的情况下，pvresize命令会让/dev/mapper/nvme0n1p3_crypt这个物理卷扩展到整个分区。如果你不知道这个路径该用什么，可以使用命令pvs查询所有可用的物理卷。通常情况下只有一个，因为livecd不会用lvm的。调整完成后再看pvs的输出结果，PSize变成1.82TB就算是成功了。接下来调整逻辑卷。我想调整两个，一个是Swap，从原来的2GB调整成8GB，然后是root，让它占满余下的分区。由于Btrfs可以缩小，所以这里我就让它先占满了。如果你使用的文件系统不支持缩小，那么扩容的时候最好谨慎一些，等不够用了给。不然等日后多了新的需求，却发现硬盘没地方了，那就有点尴尬了。首先来调整swap分区：lvresize -L+6G /dev/system/swap这里的意思是将/dev/system/swap的大小增加6GB。这个路径是怎么来的呢？使用lvs可以查询到，我的卷组名字叫system，swap分区的逻辑卷名字就叫swap，所以这个路径就是这样了。目前我看tab自动补全的效果还是不错的，如果实在不会写，可以让自动补全碰碰运气。现在分区的大小是变大了，可是上面的文件系统还没有扩容。好在swap分区不存在任何实际的数据，直接格式化就好了：mkswap /dev/system/swap这个时候注意检查一下原来系统的fstab，我这里发现fstab使用的是路径，也就是说无论分区的uuid怎么变，只要最后被挂载到/dev/system/swap的就是交换分区。如果你的fstab还在使用uuid的话，那这里要记录一下mkswap输出的新分区的uuid，之后你要自己更新fstab，不然系统是找不到swap分区的，可能会在启动的时候引发内核panic。接下来就可以扩容root分区了：lvresize -l+100%FREE /dev/system/root这里的小写字母L是通过比例来调整分区大小。显而易见，我这条指令让root分区的大小占满剩余空间。完成后查询lvs，确保分区大小如我所愿。最后就可以扩容btrfs了。我很喜欢btrfs的一个点就是它的好多操作就可以在线进行，并且交互简单明了：mkdir /mnt/root mount /dev/system/root /mnt/root这样一来我们就把原来的根分区挂载到/mnt/root路径了。然后使用btrfs进行在线扩容：btrfs filesystem resize max /mnt/root这样扩容就完成了。这时就可以修改fstab了（如果需要的话），路径是/mnt/root/etc/fstab。除此之外，还可以顺手检查一下数据和元数据是否正确：btrfs scrub start /mnt/root btrfs scrub status /mnt/root第一条命令启动scrub，第二条命令查询scrub的状态。当第二条命令返回的状态为finish，并且没有error时就万事大吉了。这个时候我们就可以卸载分区了，卸载之后还可以顺手检查一下btrfs的结构完整性：umount /mnt/root btrfs check /dev/system/root我本以为无事发生，结果走到7/7的时候出错了，说qgroup读不出来。这好办，qgroup是和quota（配额）有关的，虽然我现在不用，但是可以先修好：mount /dev/system/root /mnt/root btrfs quota disable /mnt/root btrfs quota enable /mnt/root # 执行完成后要等一会儿，开启配额后需要rescan umount /mnt/root这样一通操作之后再去做check，7/7全部通过，非常好。最后我们需要退出livecd，进入原本的系统看看是否一切正常。进系统进入系统之后除了检查数据在不在，还可以根据ArchWiki的简易配置一下Power State超时。这是新硬盘的电源状态：ps 0 : mp:4.80W operational enlat:0 exlat:0 rrt:0 rrl:0 rwt:0 rwl:0 idle_power:0.3000W active_power:4.80W active_power_workload:80K 128KiB SW ps 1 : mp:3.50W operational enlat:0 exlat:0 rrt:0 rrl:0 rwt:0 rwl:0 idle_power:0.3000W active_power:3.00W active_power_workload:80K 128KiB SW ps 2 : mp:2.40W operational enlat:0 exlat:0 rrt:0 rrl:0 rwt:0 rwl:0 idle_power:0.3000W active_power:2.00W active_power_workload:80K 128KiB SW ps 3 : mp:0.0150W non-operational enlat:1500 exlat:2500 rrt:3 rrl:3 rwt:3 rwl:3 idle_power:0.0150W active_power:- active_power_workload:- ps 4 : mp:0.0050W non-operational enlat:10000 exlat:6000 rrt:4 rrl:4 rwt:4 rwl:4 idle_power:0.0050W active_power:- active_power_workload:- ps 5 : mp:0.0033W non-operational enlat:176000 exlat:25000 rrt:5 rrl:5 rwt:5 rwl:5 idle_power:0.0033W active_power:- active_power_workload:-真不是我黑金士顿。金士顿那个p3和p4延迟差距巨大，可是功耗还都是1.5W。人家西数的蓝盘，在P3就降到15mW了，虽然P5的延迟比200ms还高，可是人家功率小啊，人家能干到3.3mW。金士顿，呸。除了配置内核参数之外，我还进行了一些简单的测试，比如持续拷贝大文件之类的。主要是给这块盘上点压力，看看会不会掉盘。目前为止也都很稳定。至此这一套换盘的操作也算是打完收工了。后日谈虽然这一次有惊无险的解决了问题，但时候回想起来，从原来的SSD里抓数据是最悬的——如果抓到一半盘突然暴毙，那我就只能重新装系统，重新配环境了，这得耽误多少事啊。这件事情你要说生气吧，倒也不至于，毕竟解决了。但是你说心平气和吧，我又不是很平和。其中我最想不明白的一点就是，Intel NUC一直以来溢价就比较高，我花五千多块钱买个NUC，去隔壁零刻能买俩。那我都花了这么多钱了，为什么不能给我配个好点的SSD呢？再后来我就想：你既然都知道它溢价严重，那你不想想它为什么溢价？你花了钱就得给你应得的配置，那还叫溢价吗？你猜为什么京东上裸机一直缺货？文章结尾再劝诫一下大家吧：买存储相关的设备，别碰金士顿。我这个OEM的盘是金士顿NV2系列的，500GB，当时得亏没买1TB的，不然肠子得悔青了。后来有一个国际友人得知此事后跟我说，Tom's Hardware有一篇关于这个硬盘的测评，最后的结论是：在大多数情况下，金士顿 NV2 根本不是我们可以推荐的硬盘，因为它可能配备的硬件范围让购买者风险太大。你可以买到优秀的 SM2269XT 控制器，也可以买到平庸的 SM2267XT 控制器。你可以购买 BiCS5 TLC 或速度更慢的 QLC。这些产品都没有 DRAM，而且在所有这些产品中，称这款产品为 PCIe 4.0 硬盘可能有失公允。在测试中，该硬盘即使在空闲时也会发热，而且耗电量相当大，因此对于包括笔记本电脑在内的许多机器来说，它并不是理想之选。它的优势在于其令人惊叹的价格，这使得它除了作为主硬盘外，或许还能用于其他用途。除此之外，你可能并不希望掷骰子来赌运气。最好从最坏的角度看：这是一款经济型硬盘，旨在以低廉的价格增加更多 NVMe 级存储空间。如果您使用过 A400 或 NV1，那么您就会知道 NV2 的预期效果。许多主板都配备了自己的 M.2 散热器或屏蔽罩，这也有助于缓解这款硬盘可能存在的发热问题，从而减轻其缺点之一。我们的样品都使用了 SMI SM2267XT 控制器，它在 TLC 或 QLC 上的表现都不尽如人意。无论是哪种情况，闪存的性能其实都不差。只是市场上还有很多更好的选择。价格确实是您在考虑 NV2 时必须考虑的最终因素。如果它的价格与 SATA 替代品相比具有竞争力，那么作为游戏硬盘也许还不错，但这意味着你需要更高的容量。在容量较低的情况下，它只是一种廉价升级旧机器的方式——但我们没有对这些 SKU 进行评测。这时候我想到了我买的SN580，正好也有一篇测评，结论是这么说的：蓝盘 SN580 是西部数据推出的一款相对低成本的产品，它不冒任何风险，但却能提供令人满意的体验。它汲取了 SN570 和 SN770 的基因，是一款介于两者之间的硬盘，其核心是一款出色的经济型固态硬盘。虽然称其为 PCIe 4.0 硬盘有些夸张，但它确实比 SN570 性能更强、缓存更好，而且没有踩到 SN770 的脚趾。在大多数情况下，它将以更低的价格带来与 SN770 相当的体验，尽管这表明 SN770 最终会被取代。SN580 拥有相当不错的保修服务，软件支持也不差。这些都不是主要的优势，但加上西部数据成熟的设计，它是一款非常可靠的硬盘。无论您的用途如何，它都是一个不错的选择。西部数据在硬盘硬件上确实有过更新换代的历史，比如 SN550 和 SATA 蓝盘，但从测试和推出的情况来看，SN580 是一款值得信赖的经济型硬盘。它并不是我们见过的最令人兴奋的产品，但这并不意味着它不好或没有用武之地。我们已经测试过这个级别的许多优秀硬盘，即 4-5GBps 范围内的无 DRAM PCIe 4.0 硬盘，它们提供的出色体验甚至可以与高端硬盘媲美。但 2TB 硬盘可能是个例外，许多 2TB 硬盘都换成了 QLC，不过 SN770、SN570 和现在的 SN580 并不适用。如果您正在寻找一款预算充足的 2TB TLC 硬盘，那么 SN580 将是您的不二之选。与 SN570 相比，SN580 在性能上的小幅提升和缓存设计上的改进是一大优势，这将带来更好、更高效的使用体验。SN580 的真正竞争对手是 SN770，以及以 Predator GM7 为代表的更高端无 DRAM 4.0 产品。虽然 SN580 有西部数据的名字，但后者可能会以相当的成本提供更好的体验。就 SN770 而言，它仍然是一款出色的硬盘，但可能需要及时更新。这样一来，SN580 就成了一个安全、全面的选择，没有任何新意或令人兴奋的功能。它只是填补了阵容中的一个位置，在这个位置上，它可以碾压金士顿 NV2 等不太理想的经济型 PCIe 4.0 硬盘。剩下的就是价格了。看起来不错。-全文完。本片撰写于Linux上。-
之前写过一篇帮朋友配置Intel NUC的文章，没想到今天我也有自己的NUC了。本篇记述我为这个NUC安装和配置系统的全过程。硬件选取本来一开始是没打算买主机的，因为我家这边夏天经常停电，不过不搭配UPS使用的话，频繁的突然断电早晚会把文件系统弄坏。但这次下定决心买NUC，主要还是因为发工资了，并且工作用的电脑一直没到，开虚拟机笔记本又过热，笔记本一过热电池就鼓包，活生生变成一个安全隐患。所以想来想去，不如买一个永除后患。说起mini主机，我第一个想到的就是Intel NUC。现在这个赛道，Intel NUC已经卖给华硕了，国产品牌也有不少后起之秀，比如零刻，价格便宜，性能更好。不过我买都买了，也就不多说什么了。我觉得Intel虽然把NUC卖给了华硕，但两家毕竟都是大厂，最基本的保障还是有的。而且我买NUC的目的主要是运行Linux，虽然零刻那边价格便宜，但是不知道Linux支持怎么样。如果到时候又得关安全启动，又得调着调那，最后还有一堆东西不兼容，那就麻烦了。好消息：Intel NUC用到现在，安全启动不用关，什么也不用调，装出来的系统直接就能用，也没发现有什么硬件不兼容的问题。特别好。这里要点名批评雷蛇：都什么年代了，还在BIOS里偷工减料。我买你们家的笔记本，在上面跑个Linux怎么了？且不说Linux支持有多差，甚至哟肚饿发行版本跑都跑不起来，电池还老鼓包。什么玩意儿啊，呸。至于型号，我买的是NUC13ANHi7，就是i7厚款。京东买的，自带16GB内存和500GB的NVMe固态。本来想买裸机然后回来自己插，这样的话钱不会差太多，但东西更好。可是裸机京东没货了，迫不得已只能买了个16GB内存的版本。好在对于Linux来说，500GB的固态算是够用，目前只是工作使用，未来打算将除了打游戏之外的需求都搬到NUC上，不过那是之后的事情了。内存只有16GB，对于Linux本身还是够用的，不过大家从我之前的文章也看出来了，我是写Java的，那IDEA开起来，Gradle daemon后台一跑，再来几个数据库的Docker，还有Chrome，开他十几个标签，直接给16GB的内存干满了——浏览器用掉了一半的内存，Java用掉了剩下的一半。数据库和Linux系统只能在swap中夹缝求生。所以下个月发了工资第一件事就是升级一下内存，直接干到64GB拉满。在存储方面我也考虑了一下，原本打算做个Btrfs的RAID 1，但是后来发现有点亏。虽然说我这个NUC能插三个盘：一个NVMe固态，尺寸是2280，一个M.2 B key的SATA固态（NGFF），但尺寸是2242，还有一个就是2.5英寸的SATA硬盘位。第一个槽位的NVMe暂且好办——买来的时候已经插上了，暂时不需要更换。虽然是金士顿的，但总不能刚到手就暴毙吧。第二个NGFF的就不好办了——我目前没找到哪个大牌子还在做这个协议的硬盘。淘宝上能找到的全都是杂牌子，2TB的硬盘能卖到726，这价格我真的有点不敢碰。最后SATA的盘位也好办，京东上随便找个三星镁光之类的冲就完了。所以归根结底，我觉得Intel NUC这个2242的B key槽位就很鸡肋，哪怕你整一个2242的NVMe呢？所以之后升级的话我可能就要考虑放弃这个槽位，只扩容SATA盘位了。如果硬要扩展的话也不是不行。所有数据都放在主盘上，然后可以重建的数据放在SATA盘上，比如BT下载之类的，总之就是丢了可以在下回来的。至于2242那个盘，那就只能存放一些本地有备份的，比如有些电影想拿出来再看一遍，那就放到这个盘上，万一崩盘了也不会造成任何麻烦。至于性能，我这个型号的NUC用的CPU是13代I7 1360P。从跑分来看这个CPU甚至要比我现在笔记本的i7 10875H还要高。不过实际使用来看，可能是内存不够吃，浏览器反而有卡顿的感觉。不过以现代CPU的性能来看，只要不是土豆，只要你不跑高性能运算，大部分情况下，包括开发，都是够用的。瓶颈和限制都在外部：比如电源功率上不去，散热跟不上，内存频率低/不够用。。。反正我觉得Intel NUC对我来说是够用的。那么决定好硬件之后，京东下单从上海调货，花费5299，后来想起来自己没有USB鼠标，只有键盘，又跑去戴尔那边买了个20块钱的光学鼠标。装系统一如既往地，我选择了openSUSE。这次也一样，在Leap和Tumbleweed之间纠结了一下，最后选择了风滚草。由于买的是带硬盘的配置，所以硬盘上带了个Windows 11，但是我不想折腾这个东西，但也不想放过这个机会，所以为了以备不时之需，我选用CloneZilla搞了个整盘克隆。如果之后有需要的话可以通过这个克隆文件把Windows 11还原回去。克隆完毕之后我又去华硕的官网搜索我这个NUC的型号，找到对应的BIOS更新。一开始我还担心这玩意儿别是非得进Windows才能更新吧，后来我看提供了一个CAP文件。开机按F7就可以直接从U盘里读这个文件进行BIOS更新。体验极佳，这里要点名表扬Intel。一切都准备妥当之后，烧写openSUSE的镜像，保持安全启动打开（当然还顺手跳了一下散热设置，然风扇转的更激进一些），开始安装。有些老生常谈的项目就不多说了，什么插根网线调成DHCP、配置主机名之类的，这些就略过了。桌面我选的GNOME，抽象，但是好用。至于分区加密，我这次选上了启用LVM。这次读了wiki才知道，如果你不启用LVM就开启加密，那开机一次要输入好几次密码才能解锁全部分区。如果启用了LVM，那么每次开机只需要输入一次密码，就能够解锁全部分区了。非常好。关于这个LVM还得多说几句。LVM全称叫做Linux逻辑卷管理。它是从硬件层面，也就是块设备的层面，将不同的硬盘统一进行抽象，这样当你配置全盘加密或者软件RAID的时候就不用触及Linux的fstab了，只需要在LVM里修改设备就好了。不过这里我还在想，LVM的功能是不是会和Btrfs重复？因为Btrfs也能提供类似软件RAID的功能，同时也不需要触及fstab，只要把硬盘加进存储池里就好了。后来我的老板给出了一个不同的见解：他说LVM从块设备级别提供了更灵活的硬盘管理方式。你可以使用LVM创建一个大的存储池，然后将上面的逻辑卷格式化成不同的分区，然后挂载；而Btrfs只能是Btrfs。假如你需要再加一个swap分区，如果有LVM的话，你只需要新增一块硬盘，然后在上面划分一个逻辑卷，mkswap就可以了。但Btrfs就做不到，因为它只是一个文件系统。所以如果后续不出意外的话，大家可能会看到一篇我写LVM扩容的文章。至于文件系统的配置，主文件系统当然是Btrfs，它的快照还是比较好用的。使用独立的交换分区，但大小只有2GB，一开始我寻思这16GB的内存还能不够吃？意思意思得了。现在看来，还真不够。如果后续不打算加内存的话，交换分区还是得大一点。虽然这个后期可以调，但是调就意味着你得先缩小一个分区，然后把这个分区的容量加给swap。有些文件系统不支持缩小，那就麻烦了。最后就是其他的杂项了，什么开启安全启动、CPU缓解策略（这个本来想禁用的，后来想想，为了工作的信息安全，还是开开吧）、防火墙、ssh什么的就不多说了。并不是什么很重要的事，全看个人需求，你开了也罢，关了也好，看着来。配置系统完事之后就是配置系统了。从哪里开始呢？从开机开始。开机问题因为目前我的NUC独占一个外接显示器，而我的笔记本在支架上。我目前使用的蓝牙键鼠可以配对多个设备，并且可以切换。所以我就没把键盘再拿出来，怪麻烦的。但这样有个问题：我的键盘是蓝牙的，但蓝牙到系统启动之后才有，可是要启动系统就得先输入密码解锁LUKS。可是要输入密码，就得现有蓝牙，要有蓝牙就得先进系统，要进系统就得解锁LUKS，要解锁LUKS就得……看到问题了吧？我这个蓝牙键盘不能解锁全盘加密。也就是说这个NUC只要关了，我再开就不行了，因为输不了密码。怎么办呢？我咨询了群友，群友说有一种很高级的蓝牙适配器，能够记住曾经配对过的键盘，并把它作为普通键盘呈现。我虽然没有听过这种蓝牙适配器，不过我推断这应该是以前的老黄历了。你想啊，这都2024年了，怎么会有这么好心的蓝牙适配器？我灵机一动，想了个土办法：把装系统用的薄膜键盘放在旁边备着。等需要开机输密码了就插上，不用的时候就拔了搁一边。反正是之前买东西送的，个儿不大，也不占地方。不过这个键盘不知道咋回事，输密码的时候自动开启Fn，导致键盘右边的字母全都变成小键盘的数字了。刚开始装完系统重启后输入密码，直接给我干到GRUB的启动界面了，我一想，坏了，别是我安装的时候输错密码了吧。就当我想输入reboot的时候，看到屏幕上写了个reb66t，我一看，啊？左思右想，原来是Fn开了，那输密码的时候按着Fn就行了。其实这个问题我还有一个解决方案，就是利用TPM。使用fde-tools可以把LUKS的加密密钥封进TPM里，开机就可以自动解密了。就算之后因为系统更新导致解密失败，也可以手动输入密码，然后重新密封密钥。可是正当我准备跟着Wiki走的时候却发现，pcr-oracle这个包更新了，更新之后改了命令行，导致fde-tools对它调用失败。我寻思这种破坏式更新不是应该提升大版本号吗？哎，没办法，人家的项目，人家爱干啥干啥，我也管不了。不过我看4月19日fde tools的维护者已经把新的patch提交到openSUSE的工厂了。估计下次风滚草打包的时候就可以用了吧。如果之后可以了，我会在另写一篇文章的。上网问题众所周知，国内的网络质量一直一言难尽。而要想痛快地使用Linux，一个好的网络连接必不可少。之前在虚拟机里的时候我是用tailscale，我专门组了一台德国的服务器来帮我做流量中转。可是放到NUC上就不行了。不使用出口代理就能和节点UDP直连；可是只要一使用出口代理，节点立马不可达，只能用中继。中继就慢了啊，能跑到500KB每秒都算烧高香了。我一想这不行，还得是专业的软件做专业的事。软件就不介绍了，我相信各位读者各有神通。这里我介绍介绍怎么给Linux配置代理。我使用的是GNOME桌面，所以很自然地，就可以通过GNOME的设置来配置。其次就是修改/etc/sysconfig/proxy，这里面提供了一个比较方便的系统级代理，大概是SUSE才有的？当然，如果你用的不是SUSE，那传统的环境变量http_proxy和https_proxy也是一种办法。如果以上两个还不行，我们还可以借助第三方软件，一个叫做proxychains的软件（软件包proxychains-ng），它可以利用库注入来劫持应用的网络请求，让它强行通过代理。比如proxychains4 rclone copy ...，这样就可以让rclone在自身不吃代理的情况下，让它发出的流量走代理。当然了，各个软件都有自己的代理配置方法，比如Gradle、Git这些。关于Git要说一句，如果你使用ssh的话，那轻易是没法走代理的，如果使用http或者https克隆和推送，那可以直接走http和https代理。最后如果还是不行的话，那就只能祭出最终的大杀器了：软路由以旁路路由的身份提供透明代理。使用的是NekoRay，这个软件在openSUSE上有个很奇怪的问题，就是默认情况下找不到openssl。由于新版本的openssl和1.1版本不兼容，所以需要手动安装openssl 1.1的包，不然更新订阅的时候就会提示TLS握手失败。GNOME托盘图标处理完网络就可以开始说正事了。不知道GNOME这帮人怎么想的，把托盘图标给弄没了。这一个桌面管理器做的越来越抽象。好看到是好看，可是太抽象了容易耽误事儿。没有托盘图标，不说别的，就JetBrains那个ToolBox，开机自启之后就是运行在托盘里。没有托盘图标，你叫我怎么升级和更新IDE？好在并不是我一个人嫌弃没有托盘图标。就连Ubuntu都嫌弃，所以他们搞了一个插件，叫AppIndicator and KStatusNotifierItem Support。它的主要功能之一就是把托盘图标给整回来了。中文输入法GNOME倒是自带几种中文输入法，但我觉得都不好用。所以我选了Rime。由于GNOME上继承的输入法框架是iBus，你当然可以用fcitx，但是还是集成的用起来好一些吧。所以要安装的包有两个：rime和ibus-rime，安装之后记得先重启一下，不然刚装完进去GNOME的输入法设置是找不到Rime的。在GNOME里启用Rime之后，还需要一些配置。比如把候选字从竖着的调成横着的，把繁体中文调成简体中文。要调整候选字方向，在~/.config/ibus/rime/ibus_rime.custom.yaml文件中这样写：patch: "style/horizontal": true要调整候选字的个数，在~/.config/ibus/rime/default.custom.yaml里这样写：patch: "menu/page_size": 7配置文件调整完成之后，可以去托盘那里找到输入法的选项，选择部署即可读取最新的配置文件。要调整简体中文，在输入法激活时按F4，选择“朙月拼音·简体字”即可。备份如一开始所说，由于存储接口的不同，组软件RAID 1并不会带来特别大的好处，反而可能会导致性能较差的硬盘拖慢整个RAID的性能。但是没有RAID来提供冗余性，那该怎么保证数据的安全性呢？我想到了我之前一直在用的一个备份软件：Duplicati。这个软件支持多种后端存储，可以通过增量备份的形式保存不同时间的备份。我之前一直使用这个软件来备份我的Windows笔记本。刚好，这个软件也支持Linux。下载RPM包安装后发现缺少依赖，经过一番搜索，只需要手动安装gtk-sharp就好了。但是问题又来了：有些要备份的数据需要root权限才能读取，这该怎么办呢？搜索了半天，最后发现其实Duplicati的源码中包含了一个Service，但不知何故这个service文件并没有进到安装包里，我们手动配置一个就好了（/etc/systemd/system/duplicati.service）：[Unit] Description=Duplicati web-server After=network.target [Service] Nice=19 IOSchedulingClass=idle EnvironmentFile=-/etc/sysconfig/duplicati ExecStart=/usr/bin/duplicati-server Restart=on-failure [Install] WantedBy=multi-user.target配置完成后重载systemd并启用服务：sudo systemctl daemon-reload sudo systemctl enable --now duplicati由于Duplicati运行在root权限，因此建议只将webui暴露给localhost。之后打开浏览器，访问http://127.1:8200即可打开网页端了。关于存储后端，我使用的是BackBlaze的B2，我单独创建了一个桶用来存备份的东西，也不需要额外配置其他的什么锁和加密之类的。加密的部分我们使用Duplicati在上传之前完成即可。关于备份的内容，我目前备份了如下文件夹：/etc：系统的所有自定义配置/home：用户数据/opt：没有使用包管理器安装的软件/root：根用户的数据/srv：和当前服务器有关的特定数据，虽然我这不是服务器，但也备份上了/usr/local/bin/：用户自行安装的软件/usr/local/sbin：用户自行安装的特权软件/var/log：系统日志，以备系统崩溃时使用/var/opt：给opt下的软件用的var文件夹/var/spool：未完成的打印队列等/var/crash：崩溃日志/var/container-data：我自己偏好的容器数据文件夹其中关于/var是最难搞的，因为它里面有些数据值得备份，有些不值得，你得自己慢慢择。备份频率是每两小时备份一次，备份的保留策略我选的智能，因为我也不知道我要什么，所以就全自动了。目前来看价格上应该不会特别贵。B2存储每月每TB价格6美元，赠送2倍还是3倍月均存储的下载流量，不过我暂时用不上。这种能够随时存取的级别，这个价格就不算贵了，隔壁AWS差不多要20多美元一个月。我这块盘一共就500G，就算占满了，里面的数据天天变，还能变出10TB不成？我觉得成本上来看问题不大。结束语至此就算是全部都配置完了。至于后续的使用就全看个人了。像是我就安装了JetBrains ToolBox来管理写代码用的IDE，后来也安装了Docker，而且新版本的Docker也支持给cli挂代理了。所以整体还是比较顺利地，跟着官方文档走就可以了，也没有坑，因此这里也就不再详细介绍了。今天写完文章看了一眼，新快照出来了，fde-tools也更新了，新版本兼容了新的pcr-oracle。本来想跟着流程走一走，但没想到它要LUKS2，这玩意儿还是实验性功能。我一想，这也实验那也实验，万一哪天盘炸了，那我也就实验了。所以最终决定还是不要乱搞了，开机插键盘输入个密码也挺好。之后我打算买个小的UPS，断电了就直接进挂起，只有内存需要供电，那应该也能撑好久呢。除非是什么大的系统更新，不然应该不会需要频繁的重启输入密码。回想文章开头，说买NUC主要还是为了减轻笔记本的压力，不让电池过热鼓包。但是当我今天发现笔记本的触摸板按不下去的时候，我就知道，这电池又他妈鼓包了。操。至此之前欠下的债就算是还完了。虽然没有正式约定过每月一更，但是我还是希望保持这个更新频率。现在有了工作那肯定是得优先保证工作。如果像之前那样托更了的话，我会试图在几个月之内补上的。如果没补上的话，那就是真的鸽了。--全文完--
我朋友听闻Intel不再做NUC业务了，赶紧就买了个12代i7 Pro。买完之后找我帮忙配置系统，我决定将配置的思路和过程记录在本篇文章中，一方面为其他人提供一种可能的思路，另一方面也方便日后自己回顾。说起NUC，我一直很想要这么一个主机。我平常在笔记本上使用Windows，但出于开发考虑（虽然我主要开发Java），我希望有一个桌面Linux系统，而不只是跑在虚拟机里。迷你主机的厂商那么多，目前看只有Intel NUC对于Linux的支持最好。独立显卡不在我的需求之中，因此整个NUC里的硬件需要的驱动基本上都包含在Linux内核里了。但是出于种种原因（主要是太贵了），一直没能玩上。听闻Intel不再继续做NUC业务了，感觉甚是惋惜。听说华硕接手了NUC业务，但华硕家自己也有迷你主机业务，而且人家这一款明摆着只支持Windows。不知道这一接手，是新增了Linux支持，还是把Linux搞没了。需求总之，这是我朋友买的NUC：skyblond@【数据删除】:~> sudo neofetch ...... skyblond@【数据删除】 .,cdxxxoc,. .:kKMMMNWMMMNk:. --------------- cKMMN0OOOKWMMXo. A ;0MWk:' ':OMMk. OS: openSUSE Tumbleweed x86_64 ;WMK;' 'lKMMNM, :NMK' 'OMW; Host: NUC12WSHi7 M42761-303 cMW; WMMMN ,XMK' oMM. Kernel: 6.4.3-1-default .MMc ''^*~l. xMN: KM0 Uptime: 1 day, 23 hours, 2 mins 'MM. .NMO oMM Packages: 2643 (rpm), 6 (flatpak) .MM, .kMMl xMN Shell: bash 5.2.15 KM0 .kMM0' .dl>~,. .WMd CPU: 12th Gen Intel i7-1260P (16) @ 4.700GHz 'XM0. ,OMMK' OMMM7' .XMK GPU: Intel Alder Lake-P *WMO:. .;xNMMk' NNNMKl. .xWMx Memory: 2526MiB / 39609MiB ^ONMMNXMMMKx; V 'xNMWKkxllox0NMWk' ''''' ':dOOXXKOxl' 我朋友的需求比较独特。首先他想要一个插上显示器就能用的Linux桌面系统，其次还想要远程访问的功能，比如通过RDP和SMB之类的协议访问，后者将成为一个类似媒体中心的东西，在手机上远程访问机器上的资源什么的。最后还希望可以通过虚拟组网的方式访问这个NUC。原本我打算直接用PVE之类的系统给他来个All in One，装一个PVE，这样一来各自的功能可以直接放到对应的虚拟机里，就连软路由也不在话下，无论是openwrt还是opnsense都可以随便选。但是他说要一个插上显示器就能用的Linux桌面系统，这一下就把虚拟化的方案淘汰出局了。我想来想去，首先好像没有办法通过虚拟化透传Intel核显，其次就算可以好像也不能像英伟达的某些数据中心卡那样把一张显卡虚拟化传给多个虚拟机。所以思来想去，最后决定直接用普通的Linux发行版本来装系统。发行版本选择这里的发行版本选用的是openSUSE。原本想用openSUSE Leap，这个发行版本更新比较缓慢，但是能够达到和SUSE一样的二进制兼容性，换句话说就是和SUSE一样的稳定性，同时还有文档。但是在安装过程中发现有些软件包实在是太老了。从我的体验来看，openSUSE并不是一个很大众的发行版本，好多社区软件在打包的时候并不会考虑openSUSE，而是用Debian和Ubuntu更多一些，而后者在基础设施和软件包方面都更新一些，比如glibc，一些使用Ubuntu打包的AppImage在openSUSE Leap 15.5上根本没办法运行，因为人家使用了更新版本的glibc。出于系统稳定考虑，我不太想手动升级glibc这样的基础库，同时使用LD_PRELOAD这种方法加载库好像也不是很优雅。最终我放弃了openSUSE Leap，转而使用openSUSE Tumbleweed，一个相对稳定的滚动更新发行版本。安装的过程就不多说了：设定主机名、网卡启用DHCP。出于性能和方便考虑，我禁用了CPU缓解和防火墙，开启了SSH服务。网络服务管理器当然是选用NetworkManager，虽然我更偏向于Wicked，但面对桌面系统，还是NM的兼容性更好一些。除此之外好像就没什么了。关于分区，我朋友装了一条2TB的NVME硬盘，我这里也没有过多设计，主分区使用Btrfs，开辟了一块2GB的Swap分区，主分区启用快照，这样系统更新的时候自动打快照，不怕滚动更新滚崩了。桌面和输入法关于桌面，我参考了SUSE Linux Enterprise Desktop，也选用了GNOME桌面（Wayland）。进入桌面的第一件事当然就是安装托盘图标的插件（Tray Icons: Reloaded）了。我不理解为什么GNOME要取消托盘图标，总之我还是把它装回来了。然后就是设定sudo，将用户组wheel设定为无需密码。因为朋友把root密码设置的特别复杂，每次sudo都要输入特别长的一串，因此将自己的用户加入到wheel组后能够免去这样的麻烦。接下来还要解决网络的事情。我选择了clash verge和proxychain4，前者用于运行clash代理，后者用于给命令行程序挂代理。有些命令行程序并不会遵守环境变量中设定的代理，这个时候就需要用proxychain4给他们体面体面。由于是桌面环境，首先离不开的是中文输入法。GNOME默认使用ibus，同时系统里也内置了一些输入法，但我觉得不太好用。我选用了Rime输入法，安装起来也不算困难，按照维基页面走就可以了。安装完成后重启ibus就可以在设置里添加rime输入法了。这里我对Rime做了一些配置，我使用的是朙月拼音简体字，我将ibus rime的候选字配置成了横向，并将朙月拼音的候选词个数改成了7个。其他方面就没有太大变动了。有了中文输入法，我们就可以在Linux桌面上查阅资料了。接下来将安装一些专有的解码器。由于版权问题，openSUSE默认并不包含具有专利的解码器，这就使得一些视频无法正确解码播放。但好在packman源里提供了这些，并且中文维基也提到了如何安装，跟着说明走就行了。Podman和Cockpit处理完了桌面部分，接下来该考虑服务了。虽然我平时很喜欢用docker，但给别人装系统的时候我还是希望可以尽力避开的。不像包管理器安装的软件，docker中的镜像需要手动更新，除非安装诸如portainer这样的管理器。但这个管理器本身作为docker运行也需要手动更新。这样一来还得教会朋友怎么用docker，万一他手一滑弄坏了，我还得修，十分麻烦。但是麻烦归麻烦，容器确实是个好东西，尤其是配合正确的工具。这里我使用Cockpit来作为这个NUC的网页管理界面。这个管理界面不光支持基础的管理（命令行、存储、网络等），还有插件系统：配合packagekit能够更新软件包，配合KVM能够管理虚拟机，配合pmlogger能够记录性能信息，配合podman就能管理容器。现在它甚至还支持transactional update，很厉害。当然，如果能通过网页管理btrfs快照就更好了。不过目前来看，我们只需要它能够管理podman容器就可以了。这一需求也比较容易实现：首先按照说明安装cockpit，启动对应的服务。然后安装podman软件包和cockpit-podman这个插件包，随后登录到cockpit网页端，进入podman选项卡，第一次会提醒你podman没有运行，你可以设置开机自启动。之后就可以通过网页端管理容器了。虽然这一次没有用到容器，但这里先装上，以被后续不时之需。媒体中心 Plex接下来说说关于媒体中心的选择。我朋友原本打算使用SMB通过手机上的APP来访问NUC上的媒体资源。openSUSE上也对SMB提供了较为不错的支持，在YaST里简单配置一下就行了。后来我注意到SMB的账号密码和系统是分开的。我原本打算像Cockpit那样使用系统账号验证SMB访问，但经过一番搜索，我发现这种方式更像是一种安全隐患。SMB协议支持加密，但本身并不要求加密，也就是说你的SMB访问凭证会通过明文传输。如果你把SMB的密码也设置成了Linux的密码，那么这无异于将你的账号密码拱手送人。经过一番思索，我决定使用Plex。在媒体中心这类软件中，主要以Emby、Plex和开源免费的Jellyfin为主。我是用Plex主要是因为我已经购买了Plex的终身会员，并且Plex用起来比另外两个体验都要好一些。Plex的安装也比较简单：去官网下载对应系统的安装包，安装即可。openSUSE使用的是rpm包，下载之后使用rpm -i <file>命令安装即可。后续有更新的话也是类似地：下载新的安装包，然后使用rpm -U <file>来更新。Plex本身的设定比较简单。12代Intel处理器自带的核显比较强劲，因此我启用了硬件转码。在添加媒体库的时候，我在根目录下新建了一个data子卷。看起来是/data文件夹，但由于主分区是Btrfs且开启了快照，我当然不想每次打快照的时候都把庞大的媒体文件包含在列。因此通过新建子卷的方式来将媒体文件排除在快照备份之外。在媒体库本身的设定上，我发现默认设置已经好用了，只不过在使用上需要一些注意事项。其中电影比较简单，因为大多数电影都是一个MKV文件，如果有外挂字幕的话就把他们放在同一个文件夹里就好了。我的资源大部分都是海盗湾或者RARBG（注意不是RGB，是RBG）上下载的，因此Plex都能够直接识别。关于外挂字幕，例如电影文件叫做something.mp4，那么外挂字幕就要命名为something.zh.ass来表示这是电影文件的中文字幕。电视剧和动漫就是另一回事了。我这里一共有四部电视剧和一部动漫。其中《勿言推理》、《爱，死亡和机器人》还有《疑犯追踪》都比较简单：将文件夹的名字改成电视剧的英文名加年份，例如Person of Interest (2011)，年份以第一季为准。然后文件夹内按照季数分别创建Season 01这样的文件夹，最后在每季的文件夹中，保证每一集都有对应的集数即可，例如：S01E03.mp4。但是另一些就不太行了。比如《是，大臣》的第三季有一个圣诞特辑。我费了好大的劲才弄明白怎么匹配上。我下载时圣诞特辑作为第三季的最后一集，也就是S03E08，可是Plex只能识别到前七集。我查阅了Plex匹配用的TVDB，发现圣诞特辑算在特殊季，也就是Season 00，并且TVDB上还列出了两个我未曾听过的特辑。总之TVDB说这个要算S00E02，那就听人劝吃饱饭，果真Plex识别了。然后是动漫，动漫在大多数情况下也可以直接识别。OVA可以根据TVDB上的信息编码到Season 00，如果你还有额外的OP、ED、访谈等，那么需要避开Season 00在TVDB上已有的编码来存放。此外在折腾动漫的时候，我发现Plex有时候会扫不到媒体。我百思不得其解：这文件明明就在这儿，怎么Plex就是看不见呢？直到我调出了日志：Permission denied。原来Plex运行时会使用一个单独的plex用户，而我复制过去的文件的所有者会变成我自己。默认情况下，位于plex组的plex用户自然无法访问属于users组的我的文件。解决办法嘛，每次复制完文件想着给777就行了。但是人总有忘记的时候，于是我就用写了一个crontab用来自动处理权限：*/1 * * * * chown nobody:nobody -R /data && chmod 777 -R /data为了避免权限纷争，我索性把/data目录下的所有文件都变成nobody的，然后再给上777的权限。这个命令每分钟运行一次。当然，我也查阅到一些资料说nobody账户的权限应该设置为最小。同时nobody用户也不应该拥有任何文件，并且nobody用户应当只用于运行不需要特权的程序。但我认为这一点可能已经过时了——用户可以管理自己名下的资源，也就是说同样使用nobody账户运行的两个进程可能会相互干扰。更推荐的做法是为每个程序单独设置一个用户和组，像plex那样。此外，这里的/data目录只用于存放媒体文件，我不认为这样会引发什么安全隐患。此外这里还有一个小插曲：openSUSE竟然不自带crontab。不过这也好办：安装cronie这个包就可以了。至于文件管理，我原本想安装一个NextCloud，但是后来发现这东西要求一个公网指向的域名。我一想，算了，SFTP又不是不能用。虚拟组网和远程访问这里我选用了Tailscale作为虚拟组网的解决方案。同类的方案还有很多，我选用tailscale主要还是因为他简单好用，同时他们公司的博客上写了好多技术文章，感觉很不错。最近他们推出了分享功能，能够将自己的机器分享给别人。默认情况下别人可以向这台分享出去的机器发起连接，而出于安全考虑，这台分享出去的机器并不能像别人的设备发起连接（否则这台机器就会成为访问别人tailscale网络的跳板）。安装Tailscale相对简单，官方有openSUSE的仓库，只不过直连比较慢（大约32KB/s），使用proxychain4能够大幅提升下载速度。安装完成后使用tailscale up即可，对于服务，我推荐使用--unattended来与当前GUI用户解耦合，这样系统启动之后，即便没有用户登录，或者用户已经登出，tailscale仍然会在后台运行。分享也很简单，只要在控制台上选择分享，就可以生成一个邀请链接。其他人使用邀请链接后就可以将这台机器加入到自己的控制面板中。按照文档所说，其他人的其他设备也应该能够看到这台外部设备。但我在实践的时候并没有得到类似的体验：控制台能看见，但我的所有设备都看不到。我百思不得其解，后来查看命令行选项，发现在up的时候可以选择--force-reauth，即启动tailscale时强制重新向控制台认证。在这个过程中会重新拉取其他设备的信息和证书，在这之后我就可以看到别人分享进来的设备了。关于远程访问，之前提到的服务默认都是监听0.0.0.0的，因此可以直接通过tailscale访问。在管理方面，SSH和SFTP都是没问题的。Wayland下的GNOME桌面提供了一个gnome-remote-desktop包，提供了VNC和RDP访问。在GUI模式下，我发现必须得先登录GUI，然后才能使用这些远程访问的功能。并且每次重启之后RDP的密码还都会变。我尝试按照一些帖子说的，使用grdctl设置对应的参数，但是发现命令行下SSH登录并不能解锁GNOME的Keyring，通过一些办法解锁之后发现好像grdctl也没用。远程桌面在尝试无果后只好作罢。结语至此，这台NUC的配置就全部完成了。经过一阵测试，在随机重启（指我突然想起来的时候）的情况下，并没有发现有哪些服务失灵。姑且就认为是没有问题了，前几天交还给朋友，前几天在Plex上重新看了一遍吉卜力的《红猪》，感觉还都不错。真要说的话，唯一的问题就是存储太少了。以P结尾的12代i7处理器竟然出乎意料地完全够用，我还以为得像是4125那样。看来我确实是跟不上英特尔的命名了，听说他们还要砍掉i系列，从Ultra重新编号，彳亍口巴。总之，在安装配置的过程中遇到了不少小问题，但好在也都不算麻烦。除了在Plex调试媒体库的时候花费了不少时间（主要还是手动给权限总是忘），剩余的环节几乎都没花多少时间。只要耐心去Google，总能找到解决办法。如果实在找不到解决办法，机器是死的，人是活的——不用就不好了。-全文完-