分类 操作系统 下的文章

这一次历时接近一天的CentOS 8扩容翻车和修复事件,终于让我对之前一直觉得深奥而不愿接触的Linux LVM(Logical Volume Management,逻辑卷管理)分区管理机制有了基本而全面的认识,算是又填上了Linux基本操作在存储管理方面的一个大坑。

LVM采用了一种三层的整体结构,自底向上依次是Physival Volume物理卷Volume Group(物理)卷组Logical Volume逻辑卷。其中物理卷对应传统意义上,在诸如Windows上磁盘管理,或者Linux上GParted中为分区分配的物理空间;卷组和RAID 0十分相似,即在逻辑地址空间中将某些指定的物理卷“融合”起来,形成逻辑意义上的“磁盘”;逻辑卷则和物理卷相似,只不过其是在一个卷组内进行分区空间的指派,最后一个分区对应的就是一个逻辑卷,对逻辑卷进行分区格式化,初始化文件系统就可以使用(当然,前提是系统支持且识别这种LVM分区布局)。

用一个十分有意思的方法来解释就是,物理硬盘加上LVM,会形成一个“螺旋上升”的结构:

物理磁盘(硬盘)->物理分区(物理卷)->逻辑磁盘(卷组)->逻辑分区(逻辑卷)

这决定了建立一个可用的LVM逻辑卷,需要依次进行物理卷、卷组和逻辑卷的创建三个步骤。

可以看到,即使加了LVM,仍然没有逃脱磁盘需要先分区后使用的本质。但是LVM的一个优势在于,上层系统所使用的是“逻辑卷”,而不是“物理卷”,也就是说,此时的上层系统不知道底层的物理数据分布的同时,还可以正常使用(当然,Linux内核是知道数据的物理分布的,毕竟LVM需要在此处实现)。这意味着,LVM可以实现跨磁盘的分区创建和管理;也可以实现分区本身在磁介质上的非连续存储。对于个人用户来说,可能算不上有意义的功能;但是对于企业用户来说,对于可能大到一块磁盘都装不下的单文件来说,这是一种解决方案。换个角度来说,LVM方案能做到的不仅仅是实现一种无RAID情况下超大文件存储的可能,还可以起到简化mount操作的作用。将一组完成同一业务功能的磁盘建立为LVM逻辑卷,可以极大地简化分区挂载/卸在脚本的复杂度,并且增加指令的可读性。

在Linux的LVM实现中,划分了三个指令簇,分别对应LVM三个层次的操作,如下表所示。

功能 PV管理命令 VG管理命令 LV管理命令
s 摘要 pvs vgs lvs
scan 扫描 pvscan vgscan lvscan
create 创建 pvcreate vgcreate lvcreate
display 显示 pvdisplay vgdisplay lvdisplay
remove 移除 pvremove vgremove lvremove
extend 扩展 - vgextend lvextend
reduce 压缩 - vgreduce lvreduce

在某些场景下(比如dracut中),这些指令不会单独存在,需要添加lvm前缀,将指令作为参数使用,如lvm pvscan

在对LVM有了初步的认识之后,进行这次修改的流程介绍:删除LVM卷组内的swap分区,将多出来的空间分配给同一卷组内的系统根分区root

步骤依次如下:

  1. 删除cl卷组中的swap分区:由于swap分区本身就属于缓存的性质,无需进行数据的保存。

    lvremove /dev/cl/swap
  2. 建议先保存数据)扩容根分区:
    有两种方式可以选择,区别在于手动或者自动对于文件系统的大小调整。在本示例中,删除swap分区释放的空间为2GiB。
    手动:
    lvresize -L +2G /dev/cl/root
    xfs_growfs /dev/cl/root

    自动:

    lvresize --resizefs -L +2G /dev/cl/root

需要注意的一点是,xfs只支持分区扩容(ext4支持分区压缩)。如果想要分区压缩的话,只能手动备份数据,重建分区再恢复数据。

这个操作平凡无奇,网上也能找到不少教程,重点是完成操作准备重启开机的时候,问题来了:

[ OK ] Reached target initrd root device.

一看到这个,就知道大事不妙,一定是磁盘配置出了问题。果不其然,等待数分钟后,dracut开头的命令行带着日志文件出现在了我的屏幕上。

仔细阅读日志文件,发现其中提到了“swap分区找不到”的相关消息,而swap分区又是我手动操作进行的删除操作,看来是有哪里的配置残留没有清理干净。折腾了半天dracut重建之后,发现无济于事,后来突然想起来可能与内核参数有关,遂修改/etc/sysconfig/grub文件,将其中与swap分区有关的参数全部删除,重新生成配置文件后,重启。

然后与预期一样的是,系统启动过程恢复了正常。其中有一点很奇怪的地方是,可能是由于我手动重建initramfs镜像的原因,并无法使用升级后的内核启动,而只能使用与安装盘版本一致的初始内核启动成功。于是出现了偷懒的新内核修复方法:

dnf reinstall kernel*-4.18.0-193.14.2.el8_2 

后面的版本信息根据自己的需要进行更改,上方示例中的版本信息是文章撰写时的最新内核信息,可能随着时间推移发生改变。

参考:https://www.cnblogs.com/diantong/p/10554831.html

HTTPS为网络安全传输带来了很大帮助,但是会因为其严格的措施,导致在很多地方出现奇怪的报错= =

这次的主角是Powershell,具体情境是在使用Download-File命令的时候,出现如下的错误信息:

The underlying connection was closed: An unexpected error occurred on a send.

两个StackOverflow链接解君愁:
https://stackoverflow.com/questions/41674518/powershell-setting-security-protocol-to-tls-1-2
https://stackoverflow.com/questions/36265534/invoke-webrequest-ssl-fails

简单总结,就是因为Powershell中需要对系统使用的HTTPS加密协议进行显式声明,然而因为我用的系统版本过低,某些常用的协议(比如TLS 1.2)并没有被默认加入到这个声明列表中,导致协议握手失败。

再次放图:

不愧是巨硬.jpg

好在可以通过Powershell命令对允许使用的加密协议进行修改:

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3 -bor [System.Net.SecurityProtocolType]::Tls -bor [System.Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls12;

在Powershell中读取.NET对象的属性的时候,有点像IPv6指定端口一样,需要先用中括号将对象包裹起来,然后再用两个冒号连接需要读取的属性名称。

后来找到了更简单的写法:

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12';

到此结束。

如题,竟然是Windows SDK版本的原因= =

在网上找了半天好像都没人遇到这个问题,看到这个才受到启发:https://forum.juce.com/t/missing-corecrt-h-and-windows-h-files-vs-2017/29195

如果新建了v141工具集的项目,再把Windows SDK版本设置为最新的话,就会找不到SDK里的头文件。要在设置里明确制定SDK的版本才行(例如我的是10.0.17763.0)。估计是VS2017支持自动识别的最高SDK版本是10.0.16299.0,超过了这个版本的话就不能自动识别了,导致IntelliSense认为找不到Windows SDK。

今天在看acmeair的bash脚本的时候,发现里面有这么一行指令:

sed "s#IMAGE_NAME#${IMAGENAME}#g" ${YAML_FILE} > temp.yaml

当时想了一下,感觉那里不对劲:根据网上的教程来看的话,seds命令的用法不是类似于's/regexp/repl/g'这种格式吗?

然后仔细一想,既然能发布出来的代码,又是来自可信平台(IBM Cloud),肯定是有其原因的,或者说,至少是可以运行的。然后就动手尝试了一下:

echo '1 2' | sed -e 's/ / ^ /g'     #1
echo '1 2' | sed -e 's# # ^ #g'     #2
echo '1 2' | sed -e 's@ @ ^ @g'     #3
echo '1 2' | sed -e 's\ \ ^ \g'     #4
echo '1 2' | sed -e 's啊 啊 ^ 啊g'   #5

首先显而易见的,1是肯定可行的,可以将1 2这个字符串替换为1 ^ 2。意料之外的是,2-4全部可行,都能够正确地完成替换工作。5属于脑洞大开的想法。在发现前面1-4都能够使用任意单字符作为分隔符的话,那么中文字符可以完成相同的功能吗?

答案是否定的。sed给出了如下的错误信息:

sed: -e 表达式 #1, 字符 2: delimiter character is not a single-byte character↵
sed: -e expression #1, char 13: unknown option to `s'

其中第一行是在中文环境下的报错信息,第二行是英文环境。可以看到,在常见的环境下,都是不支持将多字节字符作为分隔符的。毕竟在计算机行业中,非英文语言体系的字符基本都可以视作“异端”,往往不能享受到英文字符的“优待”,需要使用一个以上字节进行信息的储存,所以对于只能使用单字节字符作为分隔符的sed来说自然会产生错误。

(思考题:那为何可以使用sed替换中文文本?) (答案是,只要sed将脚本序列和输入的数据流都视为单字节字符流,就可以使用字符序列替换的方法完成任务了)

实际上,在咕果上,能找到和sed分隔符相关的资料少之又少;有人在Unix论坛上发问了,虽然问题最终由作者自己看书解决,但是他并未分享自己看的是哪本书;StackOverflow上还有老哥说这就是注释,根本不能用的,等等。

直到后来看到了这个:https://backreference.org/2010/02/20/using-different-delimiters-in-sed/

博主说了这么一句:

It's a not-so-known fact that sed can use any character as separator for the "s" command.

真是not-so-known,网络上都没什么热门资料阐述这一点的= =

于是问题最终解决:

sed "s#IMAGE_NAME#${IMAGENAME}#g" ${YAML_FILE} > temp.yaml

等价于

sed "s/IMAGE_NAME/${IMAGENAME}/g" ${YAML_FILE} > temp.yaml

顺便给出上面使用的样例的升级版:(工作必备,除了你没人看得懂,专家职称、升职加薪预定

echo '1 2' | sed -e 's \  \ ^\  g'

附录:对于非ssed指令,仍然可以通过\*...*的方式,使用任意自定义的字符作为正则表达式的分隔符。

这是从去年开始的黑苹果大坑系列的延续。本来大约在五月份的时候就已经完成配置了,但是当时忙着补课就把记录这茬给忘了= =

机型是在最原始的GL553VD配置上替换了一些硬件。具体改动如下:

  1. 网卡由Realtek RTL8723BE替换为Intel AC7265
  2. 新增Samsung PM981系列512G M.2固态硬盘一块。

之前本来用的是qiuchenly的Clover,但是在安装的时候都进不了安装器界面;后来在pcbeta上寻找本机型的支持情况,换了MohammadtaghiFarkhondekar的Clover。但是使用最新版的时候会出现一接入外置HDMI屏幕就立马重启的情况,后来发现需要使用V8而不是最新版,可以避免这个问题。

然后手动升级一下AppleALC.kext、手动安装itlwm.kext以解决声卡和无线网卡两个问题。可能还需要手动升级一下蓝牙的驱动IntelBluetoothFirmware.kext。(手写Intel Wifi驱动也太赞了吧 やばいですね☆

顺带一提,旧版本AppleALC.kext能够正常驱动外置扬声器,但是耳机糊的没法听;升级版本后问题解决,但是需要注意一下,如果是从Windows重启到Mac OS这种热启动行为的话,外置扬声器是可能出现没有声音的情况的。此时应该从Windows关机后,重新按开机键进入Mac OS,方可解决问题。

安装系统的话,尽量低于10.15系列,因为在该系列下,fn快捷键都失效了。因而我的选择是10.14.6。

记住在安装和二次部署Mac OS的时候一定不要联网(包括有线和无线网)!在安装时联网的话,安装器会联网检查系统版本,不让安装太久以前的系统(根据个人实测,至少在10.15.5发布的时候安装10.14.6会失败的)。此时还是可以断网并使用命令行修改系统时间,继续安装的。二次部署的时候联网,我只能说「前功尽弃,请从头开始安装」——因为我也解释不清为什么会失败,只是知道这样一定出事罢了。

关于手头这块PM981,之前网络上流传有说苹果无法识别一类的,但是根据我的实际使用而言,在合适的配置之下,它不会妨碍系统启动,也能进行基本的使用,可以进行文件的读取(因为是NTFS格式,所以没有测试写入),但是进行高强度的读写时还是会翻车的(从PM981直接读取系统镜像的时候,读取速度达到了惊人的3.1GB/s,近乎满速,但是在验证镜像完整性的时候直接重启了)。这是由于PM981是Windows机型侧的OEM产品,三棒和苹果自然都没有理由为这一款产品在苹果系统上进行适配。如果要使用固态硬盘作为启动磁盘的话,建议还是选择其它在市场上广泛零售,或者是标注了有较好Mac系统兼容性的型号吧。