天空 Blond - linux
type: channel
link: https://www.skyblond.info/tag/linux/
items: 【歪门邪道】探究Linux为什么突然死机 & 为NUC更换SSD
items: 【歪门邪道】使用Intel NUC作为Linux桌面主机
items: 【代码札记】零基础入门Linux套接字（socket）多播（multicast）
items: 【歪门邪道】修复小米MIX2在MIUI EU版上无法开启加密的问题
items: Arch札记 2
items: Arch札记
items: 旧电脑复活记

【歪门邪道】探究Linux为什么突然死机 & 为NUC更换SSD
type: item
date: 2024-05-01T01:54:00+08:00
description: 上一篇文章介绍了我购买并配置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.…

【歪门邪道】使用Intel NUC作为Linux桌面主机
type: item
date: 2024-04-24T21:02:05+08:00
description: 之前写过一篇帮朋友配置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更新。一开始我还担心…

【代码札记】零基础入门Linux套接字（socket）多播（multicast）
type: item
date: 2022-11-15T22:45:00+08:00
description: 这篇文章完全是意料之外的。起因是正在上研究生的大学同学突然拿着一个txt后缀的C代码问我怎么sendto怎么返回参数错误。经过一阵奇妙的发展，最终变成了我用一下午的时间简单入门了一下Linux的套接字多播。本文简单记述了这个过程。背景这里简单介绍一下背景吧。所谓的套接字，就是Socket，它是一个用C语言开发的抽象层，它主要作为计算机进程间通讯的端点，通过抽象，它隐藏了底层通讯的细节，而提供了一个统一的交互界面。套接字根据传输层协议主要分为两类，一类是packets，底层是TCP支持的，用于两个进程间（相对）可靠的一对一通信；另一类是datagrams，底层是UDP支持的，用于不那么可靠的通讯，可以一对一，也可以一对多。说起多播，它介于单播和广播之间。单播其实就是一对一。而广播是向网络中的全体无差别发送。多播，有时候也称为组播，它是向网络中特定一组目标发送数据。多播的用处比较广泛，假如说你想向许多人分发数据，例如直播影像。如果采用单播，那么来一个人你就得建立一个套接字给他发送数据，人多了就得同一份数据向好多个套接字里写入。如果采用广播，那么你的数据会无差别发送给网络中的所有主机，如果别人不想要你的数据，那处理这种数据（哪怕仅仅是简单的拒绝1）就变成了一种负担。采用多播，你可以指定一个多播地址，数据只需要向套接字中写入一次，所有加入了这个地址的主机都会收到这个消息；而没有订阅的主机则不会收到消息2。在这里我们并不以此构建什么应用，只是简单的写一个收发程序来验证这个事情。目标编写一个C程序，使用如下命令行启动：# Sender ./multicast s 172.16.71.138 224.0.0.1 9000 # Receiver ./multicast r 224.0.0.1 9000作为发送者启动时，程序将向多播套接字中写入数据；作为接收者启动时，程序将从多播套接字中读取数据。写入的数据由用户输入。实现有一说一，我从大一之后就没再写过C，一直写Java比较多。如果各位觉得这C代码总有一股子咖啡味儿，还请多担待。建立项目虽然是C语言，但是作为一个Java程序员，多少先得弄个项目。CLion默认采用CMake管理项目，那话不多说，配置文件CMakeLists.txt的内容如下：cmake_minimum_required(VERSION 3.22) project(LinuxNetwork C) set(CMAKE_C_STANDARD 11) add_executable(multicast src/multicast/main.c src/multicast/sender.c src/multicast/receiver.c src/multicast/receiver.h src/multicast/sender.h src/multicast/common.h) 这里要求CMake的最低版本号其实没什么讲究，只因为我自己用的版本是3.22，所以就用了这个。使用的标准是C11。这里为了项目规整，又为了给日后这个同学再来问我问题留出余地，这次的代码我放到了src/multicast文件夹中。等之后他要是还有别的问题，我就可以把之后的代码放到其他文件夹中，从而避免了频繁创建工程。其实写代码的时候顺序是自底向上（先完成底层收发，再写命令行的部分），但是写完代码需要写文章讲解的时候，就变成自顶向下了（先说命令行，再说底层细节），所以实际写代码时候的顺序应该是按文章介绍顺序反着来。项目结构这里一共有这么几个文件：main.c：主函数，负责解析命令行参数，根据参数调用对应的过程sender.c：作为发送者的实现sender.h：发送者的头文件，用于在主函数中引用receiver.c：作为接收者的实现receiver.h：接收者的头文件，用于在主函数中引用common.h：共用的定义，例如消息大小头文件三个头文件起到了类似接口的做用：先定义函数签名，以便其他人能够在代码还没有被写出来时继续各自的开发工作。sender.h：#ifndef LINUXNETWORK_SENDER_H #define LINUXNETWORK_SENDER_H void sender_run(char *local_if, char *multicast_ip, char *port_str); #endif //LINUXNETWORK_SENDER_H 发送者的实现主要有三个参数：本地网络接口（多播从哪个网口发）、多播IP和端口（往哪个多播发）。当用户没有指定本地网络接口的时候，可以将local_if设定为NULL，以便使用默认的设置。receiver.h：#ifndef LINUXNETWORK_RECEIVER_H #define LINUXNETW…

【歪门邪道】修复小米MIX2在MIUI EU版上无法开启加密的问题
type: item
date: 2021-02-28T11:17:16+08:00
description: 最近觉得在K20Pro上运行MIUI EU版体验不错，既得到了原版硬件驱动的支持，由得到了谷歌全家桶的体验（距离原生还是差很远，但原生与兼容性不可兼得，只能舍原生而找兼容性）。于是今天将原来的Mix2也换成了MIUI EU，在同步设置的时候发现没有开全盘加密，于是便开启。尝试了两次全都卡住了，经过一系列搜索，最终发现解决之道。准备工作刷机嘛，手机上什么TWRP之类的第三方Recovery就不用说了，其次要准备好Mix2的MIUI EU，我使用的稳定版，版本是V12.0.1.0.PDECNXM_v12-9。之后还要准备谷歌的platform-tools，主要是其中的adb。最后再来一个文本编辑器就齐活了。流程首先四清或全清，总之就是要干干净净的，然后通过卡刷刷入MIUI EU的ROM。然后不要重启进系统，而是直接重启到第三方Recovery中。在第三方Recovery中挂在System分区，打开ADB，拿到系统的fstab，该文件在Linux中指导内核挂载分区。安卓9使用如下命令：adb pull /system/vendor/etc/fstab.qcom根据安卓版本的设备的不同，该文件的位置和后缀名可能不同，需要自行寻找，有可能需要挂在Vendor分区。执行完命令之后手机中的fstab.qcom就会上传到电脑中。将其中的encryptable=ice修改成fileencryption=ice，其他的不要改动，尤其留意修改时使用的符号或空格等，修改不对可能导致手机无法启动。并且该方法只在第一次启动系统前有效。修改完成后使用如下命令将修改下载回手机：adb push fstab.qcom /system/vendor/etc/fstab.qcom完成后重启手机，进入系统。并在初始化设置中设置密码，随后手机将启动开启全盘加密。初次启动系统耗时较长，因为要加密全屏，请耐心等待。如果超过一小时还未启动，则考虑重新开始流程，应该是修改过程出了问题。验证系统设置中显示手机已经加密重启到第三方Recovery之后需要输入密码才能查看文件内容原理之前提到过，fstab是现代Linux系统中指导内核挂载磁盘分区的重要文件。以我们刚刚修改的为例：#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags> /dev/block/bootdevice/by-name/userdata /data ext4 noatime,nosuid,nodev,barrier=1,noauto_da_alloc wait,check,reservedsize=128M,fileencryption=ice,quota根据注释，第一个参数指定了挂载设备的名称，在Linux等PC机上，挂载的对象通常是/dev/sda/sda1之类的，而这里/dev/block/bootdevice/by-name/userdata则表示手机中实际存储用户数据的分区。第二个参数表示挂载到文件系统中的哪个位置：/data，即挂在后我们通过/data就能访问到原来位于/dev/block/bootdevice/by-name/userdata上面的数据。第三个参数表示该文件系统是什么格式的，这里是ext4，是一种常见的Linux下的格式，类似于Windows上的NTFS或者Fat32。第四个参数指定了内核以何种方式挂载。例如其中的noatime告诉内核，挂载后不要在访问文件的时候更新文件的访问时间，一方面加快了访存速度，另一方面也减少了写入次数，提高了存储器的寿命。而诸如nodev和nosuid则是为了提高安全性。而第五个参数则是指定安卓的文件系统管理器如何挂载磁盘。例如quota，是允许文件系统管理器针对该分区启用统计数据。其他参数姑且不谈，本文中起到关键作用的fileencryption正是出现在此列。在安卓5的时代，最先引入的是全盘加密，但是全盘加密有一个问题，就是手机启动后，用户未输入密码前，手机的全部数据都是加密的，用户只能拨打紧急电话或者输入密码解锁。如果用过水货HTC的话，或许会对一个白底界面有印象：输入密码解锁手机，或者拨打紧急电话。如果密码输入错误超过30次，那么手机将会自动清空数据。文中被修改的encryptable标志则是在那个时候引入的。这种全盘加密带来了诸多不便，首当其冲的便是闹钟功能，因为用户没有解密，所以闹钟在手机关闭后完全不起作用。于是为了解决这个问题，谷歌引入了文件级加密：在启用了直接启动特性的设备上，系统可以直接进入界面，这使得诸如闹钟之类的应用可以发挥作用。这种特性的基础便是文件级加密，它与全盘加密的区别在于，文件级加密的基本单位是文件，在逻辑上仍然可以识别出独立的文件，而不知道密码的…

Arch札记 2
type: item
date: 2017-08-28T22:26:00+08:00
description: 说出来你可能不信，是Arch先动的手。我想对于双显卡（Intel+Nvidia）的笔记本，可能显卡驱动是最要命的部分。一开始就什么都不管，一路安装，就能看到Plasma，而稍微一动显卡驱动再一重启，系统在启动之后就卡住了，一直是黑屏。所以我觉得。。。如果笔记本上有两块显卡而我又没法在Arch中将其发挥到极致，那么这于我而言有些不爽。[...]

Arch札记
type: item
date: 2017-08-14T22:00:00+08:00
description: 我就当真是不服这个Arch，在昨天弄好桌面环境之后，今天又把系统删了重装Arch，按照官方的wiki已经安装好了命令行。主要问题在于这个图形界面，而真电脑又不像虚拟机那样可以搞快照，不行就恢复，因此必须要谨慎行事。还好关于KDE的Plasma在Arch的wiki上有教程，因此，如果Arch还是不行的话，那我就认了，就用命令行，谁怕谁2333[...]

旧电脑复活记
type: item
date: 2017-08-13T13:42:00+08:00
description: 几经折腾修好了原来被电源取走性命的笔记本，按照惯例，除了常用机器安装windows之外，剩余的机器我都是安装成Linux的，之前的三星R518在跑不动win10之后我换成了ElementaryOS，用的很好，这次我打算尝试一下其他不一样的linux。[...]