今日(きょう)(さわ)がしく(たわむ)れ生きる人々の漫画映画(まんがえいが)

一些奇奇怪怪的分区布局

笔记本有个空 SATA 口, 就装了块机械. 日用的操作系统又是 Linux, SSD 就给 Linux. SSD 对我这种没钱的人又容易心疼, 就在 Linux 下弄了乱七八糟的分区.

固态

没什么好说, 要只是这样子那就不会那么麻烦了.

机械

前五个是 Windows 10 的分区, 后三个是 Linux 的. Linux 下的 /var 和 /home 独立出另外的分区还是比较常见的操作, 不说不说.

Ext4 外部日志分区

/dev/sda6 是 SSD 上的 root 分区的日志分区. 是的, ext4 分区的日志可以独立出来写到另一个分区, 甚至另一个硬盘也可以. 应该可以省点写入量, 但是其他方面有没有影响就不知道了. Arch Wiki 有简单的介绍 (https://wiki.archlinux.org/index.php/Ext4#Use_external_journal_to_optimize_performance):

For those with concerns about both data integrity and performance, the journaling can be significantly sped up with the journal_async_commit mount option. Note that it does not work with the balanced default of data=ordered, so this is only recommended when the filesystem is already cautiously using data=journal. You can then format a dedicated device to journal to with mke2fs -O journal_dev /dev/journal_device. Use tune2fs -J device=/dev/journal_device /dev/ext4_fs to assign the journal to an existing device, or replace tune2fs with mkfs.ext4 if you are making a new filesystem. —引用于 2019年8月8日

简单说就是 ext4 在挂载选项里设置了 data=journal (优先记录日志) 之后, 可以启用 journal_async_commit 来让写入日志和写入数据同时异步进行, 从而加快速度. 在这之后可以设置日志到外部的设备.

# # 把一个分区格式化成日志分区

mke2fs -O journal_dev /dev/journal_device

# 创建用以上分区作为日志分区的 ext4 分区

mkfs.ext4 -J device=/dev/journal_device /dev/ext4_fs

# 或者用以下命令来调整现有分区的日志设置

tune2fs -J device=/dev/journal_device /dev/ext4_fs

一般来说, 调整挂载选项是在 /etc/fstab 里改的. 这对于普通分区可行, 但是这次对 root 分区不行:

data={journal|ordered|writeback} Specifies the journalling mode for file data. Metadata is always journaled. To use modes other than ordered on the root filesystem, pass the mode to the kernel as boot parameter, e.g. rootflags=data=journal. —来自 mount 的 man page

然后就去改 GRUB 的内核参数, /etc/default/grub 里:

GRUB_CMDLINE_LINUX=”” 改为 GRUB_CMDLINE_LINUX=”rootflags=data=journal,journal_async_commit”

然后又在 /etc/fstab 里加上常见的什么 noatime,discard 之类的 (其实 journal_async_commit 应该也可以放在 fstab 里, 但是懒得试了).

继续作死

SSD 不那么心疼了, 但是 HDD 又心疼了. 笔记本电脑不可能当台式来用吧, 平时挪一挪磕一磕碰一碰也心疼. 正好常用软件装齐了, 脑洞大开一下, 要便携的时候换个 fstab 是不是就可以直接把机械硬盘休眠关掉了? 然后就想到另一个奇奇怪怪的分区方案 (已坑, 妥协了):

/ —- 根目录, ro 挂载, 不用日志 /var —- 不用机械的分区, 直接 tmpfs /home —- 同样直接 tmpfs

但是基本不知道怎么实现 (禁用日志好麻烦, 更改 fstab 好麻烦, 休眠硬盘好麻烦…). 先把用的到的东西列一列:

禁用日志: mount option: ro,noload 会不会有不用每次修改 fstab 的方法? 尝试: kernel para: init=… 休眠硬盘: hdparm, 但是就没有从一开始就整个硬盘禁用的方法吗…

剩下等我作完死先…(大坑预定)发现可能要把 systemd 学一遍, 然后自己写一个 target…(大坑确立) 待会儿待会儿待会儿, 好像 systemd 里有个 systemd-fstab-generator, 可以接受内核参数 fstab, 设成 fstab=no 就可以忽略 fstab 了? 之后试一下. (试了一下, 根文件系统只读会有很多很多出错, 待会儿试一下可读写但是关掉日志) 如果要设成根文件系统只读可能要依靠 overlay filesystem, 但是查了一下真是一脸懵逼, 不打算继续搞.

通过内核参数临时禁用日志/禁用 fstab

好了, 不打算搞了, 目前方案如下:

  1. 只挂载根文件系统, 用 noload 或者 norecovery 的挂载选项来禁用日志 (此时相应地要把之前提到的 data=journal,journal_async_commit 的选项删掉, 不兼容), 这样就不会用到机械硬盘了, 但是 SSD 必须可读写;
  2. 为了容易切换两种状态, 只用 GRUB 来调整相应的内核参数, 之后选择相应的 GRUB entry, 再在进入 Linux 后手动 hdparm -Y </dev/device> 让机械硬盘休眠停转, 就可以不用心疼机械了.

具体操作:

  1. 打开 /boot/grub/grub.cfg 把最常用的那个 menuentry 整个复制到 /boot/grub/custom.cfg, 作为编辑的基础, 我的是下面这样:

    ### BEGIN /etc/grub.d/10_linux ### menuentry ‘Manjaro Linux’ —class manjaro —class gnu-linux —class gnu —class os $menuentry_id_option ‘gnulinux-simple-d85fb039-b7e0-4e7e-ac24-f8fd16215efe’ { savedefault load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set root=’hd1,gpt2’ if [ x$feature_platform_search_hint = xy ]; then search —no-floppy —fs-uuid —set=root —hint-ieee1275=’ieee1275//dis k@0,gpt2’ —hint-bios=hd1,gpt2 —hint-efi=hd1,gpt2 —hint-baremetal=ahci1,gpt2
    d85fb039-b7e0-4e7e-ac24-f8fd16215efe else search —no-floppy —fs-uuid —set=root d85fb039-b7e0-4e7e-ac24-f8fd16 215efe fi linux /boot/vmlinuz-5.1-x86_64 root=UUID=d85fb039-b7e0-4e7e-ac24-f8fd1 6215efe rw rootflags=data=journal,journal_async_commit acpi_osi=! acpi_osi=’Wind ows 2018.2’ acpi_backlight=vendor modprobe.blacklist=nouveau initrd /boot/intel-ucode.img /boot/initramfs-5.1-x86_64.img }

  2. 要编辑的有两行: 其一:

    menuentry ‘Manjaro Linux’ —class manjaro —class gnu-linux —class gnu —class os $menuentry_id_option ‘gnulinux-simple-d85fb039-b7e0-4e7e-ac24-f8fd16215efe’

    1. menuentry 后面的 'Manjaro Linux' 改成容易记的其他名字如 'Manjaro Linux Portable', 这是开机时 GRUB 显示的名字; 2. $menuentry_id_option 后面的一长串东西改成喜欢的名字, 应该是作为 id, 所以独一无二会好一点 (但是似乎不改也没影响), 我改成了 'gnulinux-portable'. 3. 要编辑的两行: 其二:

    linux /boot/vmlinuz-5.1-x86_64 root=UUID=d85fb039-b7e0-4e7e-ac24-f8fd1 6215efe rw rootflags=data=journal,journal_async_commit acpi_osi=! acpi_osi=’Wind ows 2018.2’ acpi_backlight=vendor modprobe.blacklist=nouveau

    1. 其他不用管;
    2. (如果设置了外部日志的) 首先把 rootflags=data=journal,journal_async_commit 删掉, 不兼容;
    3. 添加 fstab=no (用空格与其他部分分隔开不用说了吧);
    4. 查看自己的 fstab, 添加上相应的 rootflags (因为不用 fstab 了, 所以要在这里手动设置), 我的 fstab 里挂载选项是 defaults,noatime,discard,data=journal,journal_async_commit ,所以添加 rootflags=noatime,discard,noload (比原来的 fstab 多了 noload, 当然如果不心疼 SSD 又没有设置外部日志的也可以不用多加这个 noload);
    5. 添加 systemd.unit=multi-user.target, 因为我的 Linux 默认直接进入图形界面 (默认 target 是 graphical.target), 没有了 /home 目录可能不能顺利进入, 所以设置这个让系统只进入命令行界面.
    6. 最后:

    menuentry ‘Manjaro Linux Portable’ —class manjaro —class gnu-linux —class gnu —class os $menuentry_id_option ‘gnulinux-portable’ { savedefault load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set root=’hd1,gpt2’ if [ x$feature_platform_search_hint = xy ]; then search —no-floppy —fs-uuid —set=root —hint-ieee1275=’ieee1275//disk@0,gpt2’ —hint-bios=hd1,gpt2 —hint-efi=hd1,gpt2 —hint-baremetal=ahci1,gpt2 d85fb039-b7e0-4e7e-ac24-f8fd16215efe else search —no-floppy —fs-uuid —set=root d85fb039-b7e0-4e7e-ac24-f8fd16215efe fi linux /boot/vmlinuz-5.1-x86_64 root=UUID=d85fb039-b7e0-4e7e-ac24-f8fd16215efe rw rootflags=noatime,discard,noload acpi_osi=! acpi_osi=’Windows 2018.2’ acpi_backlight=vendor modprobe.blacklist=nouveau fstab=no systemd.unit=multi-user.target initrd /boot/intel-ucode.img /boot/initramfs-5.1-x86_64.img }

  3. 当然, 开机之后要记得 hdparm -Y <机械硬盘>, 不然没用.

参考文献

评论