在OpenWrt中,最困難,也最痛苦的就是給squashfs韌體磁碟擴容了!
官方擴容的文件
我是研究大神的影片後學習到的,在此自己整理的筆記,大家一起學習吧!
OpenWrt空間擴容:這波補充超有料!韓風Talk
OpenWrt的空間擴容問題,可以這麼直接解決!(非f2fs檔案系統的)
重要提示:在新版本OpenWrt中,如果你的磁碟是M.2口的SSD,那麼你在X86裝置上硬碟刷寫韌體時,很大機率檔案系統會被寫成f2fs檔案系統(不是常規的ext4檔案系統),並且無法線上掛載擴容,因此“很多人(M.2固態刷了squashfs韌體的玩家)無法實現硬碟擴容”
識別檔案系統的方法很簡單:
df -Th
或者lsblk -f
檢視即可辨別
1.安裝需要的軟體:
root@ImmortalWrt:~# opkg install lsblk fdisk resize2fs losetup blkid f2fs-tools tree
Installing lsblk (2.39-2) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/lsblk_2.39-2_x86_64.ipk
Installing libmount1 (2.39-2) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/libmount1_2.39-2_x86_64.ipk
Package fdisk (2.39-2) installed in root is up to date.
Installing resize2fs (1.47.0-2) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/resize2fs_1.47.0-2_x86_64.ipk
Installing losetup (2.39-2) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/losetup_2.39-2_x86_64.ipk
Installing blkid (2.39-2) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/blkid_2.39-2_x86_64.ipk
Installing f2fs-tools (1.16.0-1) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/f2fs-tools_1.16.0-1_x86_64.ipk
Installing f2fsck (1.16.0-1) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/23.05.3/packages/x86_64/base/f2fsck_1.16.0-1_x86_64.ipk
Configuring f2fsck.
Configuring f2fs-tools.
Configuring resize2fs.
Configuring libmount1.
Configuring lsblk.
Configuring losetup.
Configuring blkid.
Configuring tree.
2.檢視磁碟分割槽情況
root@ImmortalWrt:~# fdisk -l
Disk /dev/loop0: 291.06 MiB, 305201152 bytes, 596096 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
GPT PMBR size mismatch (680479 != 123091919) will be corrected by write.
The backup GPT table is corrupt, but the primary appears OK, so that will be used.
The backup GPT table is not on the end of the device.
Disk /dev/sda: 58.69 GiB, 63023063040 bytes, 123091920 sectors
Disk model: SanDisk SSD i110
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 20C60F33-AFC6-96E2-AE0B-E001AE609500
Device Start End Sectors Size Type
/dev/sda1 512 66047 65536 32M Linux filesystem
/dev/sda2 66048 680447 614400 300M Linux filesystem
/dev/sda128 34 511 478 239K BIOS boot
Partition table entries are not in disk order.
我們明確了幾個點:
1、我們需要操作的整個磁碟叫 /dev/sda ,總容量58.69G(Disk /dev/sda: 58.69 GiB)
2、我們需要擴容的分割槽是/dev/sda2 ,這裡的Start是66048,原始空間300M(/dev/sda2 66048 680447 614400 300M Linux filesystem)
3.使用fdisk命令對磁碟從新分割槽(擴容)
1、fdisk /dev/sda
擴容磁碟
2、輸入p回車(列印磁碟資訊),觀察後確人:將來要刪除的是第二個盤 /dev/sda2(以p列印的順序為準)
root@ImmortalWrt:~# fdisk /dev/sda
Welcome to fdisk (util-linux 2.39).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
GPT PMBR size mismatch (680479 != 123091919) will be corrected by write.
The backup GPT table is corrupt, but the primary appears OK, so that will be used.
The backup GPT table is not on the end of the device. This problem will be corrected by write.
This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to umount all file systems, and swapoff all swap
partitions on this disk.
Command (m for help): p
Disk /dev/sda: 58.69 GiB, 63023063040 bytes, 123091920 sectors
Disk model: SanDisk SSD i110
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 20C60F33-AFC6-96E2-AE0B-E001AE609500
Device Start End Sectors Size Type
/dev/sda1 512 66047 65536 32M Linux filesystem
/dev/sda2 66048 680447 614400 300M Linux filesystem
/dev/sda128 34 511 478 239K BIOS boot
Partition table entries are not in disk order.
Command (m for help):
3、輸入d回車(刪除分割槽命令),選擇2回車(選擇刪除第二個分割槽)
Device Start End Sectors Size Type
/dev/sda1 512 66047 65536 32M Linux filesystem
/dev/sda2 66048 680447 614400 300M Linux filesystem
/dev/sda128 34 511 478 239K BIOS boot
Partition table entries are not in disk order.
Command (m for help): d
Partition number (1,2,128, default 128): 2
Partition 2 has been deleted.
Command (m for help):
4、輸入n回車(建立一個新分割槽),輸入2回車(設定盤序號還是剛剛的2號盤),然後必須要注意,之前2號盤的Start是66048,所以新建立的盤的Start也必須是66048,然後回車。
輸入+5g,代表直接新建分割槽為5GB(這樣寫方便,不用計算)
Do you want to remove the signature? [Y]es/[N]o: n(移除之前的識別符號這裡一定要選n)
列印分割槽表,確認無誤後,輸入w(儲存,正式寫入,並同步分割槽表)
Command (m for help): n
Partition number (2-127, default 2): 2
First sector (66048-123091886, default 67584): 66048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (66048-123091886, default 123090943): +5g
Created a new partition 2 of type 'Linux filesystem' and of size 5 GiB.
Partition #2 contains a squashfs signature.
Do you want to remove the signature? [Y]es/[N]o: n
Command (m for help): p
Disk /dev/sda: 58.69 GiB, 63023063040 bytes, 123091920 sectors
Disk model: SanDisk SSD i110
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 20C60F33-AFC6-96E2-AE0B-E001AE609500
Device Start End Sectors Size Type
/dev/sda1 512 66047 65536 32M Linux filesystem
/dev/sda2 66048 10551295 10485248 5G Linux filesystem
/dev/sda128 34 511 478 239K BIOS boot
Partition table entries are not in disk order.
Command (m for help): w
The partition table has been altered.
Syncing disks.
root@ImmortalWrt:~#
4.檢查新的分割槽表狀態
1、使用fdisk -l
列出所有磁碟上的分割槽表資訊,我們看到磁碟分割槽表已經是5G的空間狀態了
root@ImmortalWrt:~# fdisk -l
Disk /dev/loop0: 291.06 MiB, 305201152 bytes, 596096 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sda: 58.69 GiB, 63023063040 bytes, 123091920 sectors
Disk model: SanDisk SSD i110
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 20C60F33-AFC6-96E2-AE0B-E001AE609500
Device Start End Sectors Size Type
/dev/sda1 512 66047 65536 32M Linux filesystem
/dev/sda2 66048 10551295 10485248 5G Linux filesystem
/dev/sda128 34 511 478 239K BIOS boot
Partition table entries are not in disk order.
2、使用df -Th
檢視檔案系統磁碟空間使用情況
root@ImmortalWrt:~# df -Th
Filesystem Type Size Used Available Use% Mounted on
/dev/root squashfs 9.0M 9.0M 0 100% /rom
tmpfs tmpfs 906.0M 1.1M 904.9M 0% /tmp
/dev/loop0 f2fs 289.1M 63.1M 226.0M 22% /overlay
overlayfs:/overlay overlay 289.1M 63.1M 226.0M 22% /
/dev/sda1 vfat 31.9M 7.9M 24.1M 25% /boot
/dev/sda1 vfat 31.9M 7.9M 24.1M 25% /boot
tmpfs tmpfs 512.0K 0 512.0K 0% /dev
/dev/sda1 vfat 31.9M 7.9M 24.1M 25% /mnt/sda1
root@ImmortalWrt:~#
我們看到,檔案系統並沒有正確識別到新分配的overlay的 / 根分割槽的空間,還是289.1M
5.檢視當前掛載的迴圈裝置狀態
root@ImmortalWrt:~# losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 9371648 1 0 /sda2 0 512
root@ImmortalWrt:~#
結合df-Th
命令我們看到,/ 這個掛載點使用了 overlay 檔案系統技術,並且要記住“OFFSET的偏移量是9371648”,未來也要一致才可以!
loop 裝置 /dev/loop0
被對映到了 /sda2
檔案上,也就是說現在/sda2
用overlay技術,掛載為/目錄
總結
- 只讀層:
/dev/root
(型別為squashfs
)。 - 可寫層:
/overlay
(型別為f2fs
,透過/dev/loop0
對映到/sda2
檔案)。 - 最終掛載點:
/
(型別為overlay
,整合了只讀層和可寫層)。
這就是為什麼squashfs
的檔案系統可以有“恢復到出廠設定”功能,而ext4檔案系統沒法恢復的原理。(因為這個根目錄既可以有隻讀層的資料,又有安裝軟體,修改配置檔案的資料)
6.現在我們要重新掛載剛剛建立好的迴圈裝置,以實現替換的目的
因為剛剛講了這個/
根目錄是混合型的,必須精確指明哪裡是隻讀的,哪裡是可寫的,所以這個“OFFSET的偏移量是9371648”
root@ImmortalWrt:~# losetup -f -o 9371648 /dev/sda2
root@ImmortalWrt:~# losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop1 0 9371648 0 0 /dev/sda2 0 512
/dev/loop0 0 9371648 1 0 /sda2 0 512
root@ImmortalWrt:~#
這裡注意區別,/dev/sda2是分割槽,沒有掛載具體位置,/sda2已經掛載在/
根目錄,
7.為了確保資料的一致性,我們先掛載一下資料,檢查一下資料是否存在,在解除安裝釋放資源。因為磁碟剛剛被全刪除了,後面重啟可能會丟失資料,這樣做保險一些。
root@ImmortalWrt:~# mount /dev/loop1 /mnt
root@ImmortalWrt:/mnt# tree -L 2 /mnt
/mnt
├── upper
│ ├── boot
│ ├── etc
│ ├── lib
│ ├── mnt
│ ├── sbin
│ └── usr
└── work
└── work
10 directories, 0 files
root@ImmortalWrt:~# umount /dev/loop1
8.確認掛載的迴圈裝置的檔案系統格式(是f2fs,還是)
root@ImmortalWrt:/# lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0 f2fs rootfs_data 1858fcd6-7767-11ef-979c-5fec82ce50f5 225.9M 22% /overlay
loop1 f2fs rootfs_data 1858fcd6-7767-11ef-979c-5fec82ce50f5
sda
├─sda1 vfat kernel 1234-ABCD 24.1M 25% /mnt/sda1
│ /boot
│ /boot
├─sda2 squashfs 0 100% /rom
└─sda128
root@ImmortalWrt:/#
9.如果是f2fs的檔案系統,執行擴容命令,重新整理檔案
root@ImmortalWrt:/# resize.f2fs -f /dev/loop1
Info: Force to resize
Info: MKFS version
"Linux version 5.15.162 (buildbot@buildbot.infra.immortalwrt.org) (x86_64-openwrt-linux-musl-gcc (OpenWrt GCC 12.3.0 r27917-81a1f98d5b) 12.3.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Thu Jul 18 06:35:54 2024"
Info: FSCK version
from "Linux version 5.15.162 (buildbot@buildbot.infra.immortalwrt.org) (x86_64-openwrt-linux-musl-gcc (OpenWrt GCC 12.3.0 r27917-81a1f98d5b) 12.3.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Thu Jul 18 06:35:54 2024"
to "Linux version 5.15.162 (buildbot@buildbot.infra.immortalwrt.org) (x86_64-openwrt-linux-musl-gcc (OpenWrt GCC 12.3.0 r27917-81a1f98d5b) 12.3.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Thu Jul 18 06:35:54 2024"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: Segments per section = 1
Info: Sections per zone = 1
Info: total FS sectors = 596096 (291 MB)
Info: CKPT version = 43a353a3
Info: Duplicate valid checkpoint to mirror position 512 -> 1024
Info: Write valid nat_bits in checkpoint
[FIX] (move_one_curseg_info:2921) --> Move curseg[0] 3 -> 10 after 2c00
[FIX] (move_one_curseg_info:2921) --> Move curseg[1] 6 -> 13 after 2c00
[FIX] (move_one_curseg_info:2921) --> Move curseg[2] 4 -> 11 after 2c00
[FIX] (move_one_curseg_info:2921) --> Move curseg[3] 0 -> e after 2c00
[FIX] (move_one_curseg_info:2921) --> Move curseg[4] 1 -> f after 2c00
[FIX] (move_one_curseg_info:2921) --> Move curseg[5] 2 -> 14 after 2c00
Info: Write valid nat_bits in checkpoint
Try to do defragement: Done
[migrate_ssa: 272] Info: Done to migrate SSA blocks: sum_blkaddr = 0xe00 -> 0x2200
[migrate_nat: 389] Info: Done to migrate NAT blocks: nat_blkaddr = 0xa00 -> 0xa00
[migrate_sit: 447] Info: Done to restore new SIT blocks: 0x600
[rebuild_checkpoint: 486] Info: Overprovision ratio = 2.150%
[rebuild_checkpoint: 487] Info: Overprovision segments = 55 (GC reserved = 53)
Info: Write valid nat_bits in checkpoint
[rebuild_checkpoint: 603] Info: Done to rebuild checkpoint blocks
[update_superblock: 765] Info: Done to update superblock
Done: 0.799958 secs
root@ImmortalWrt:/#
10.如果是ext4檔案系統,執行擴容命令,重新整理檔案
root@ImmortalWrt:/# resize2fs -f /dev/loop1
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/sdb1 is mounted on /overlay; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 24
The filesystem on /dev/loop1 is now 52428539 (4k) blocks long.
11.擴容後,重啟前的最後一件重要的事(有EFI引導的要注意)
如果你的韌體是帶efi的
# 帶-efi的
immortalwrt-23.05.3-x86-64-generic-squashfs-combined-efi.img
immortalwrt-23.05.3-x86-64-generic-ext4-combined-efi.img
# 不帶-efi的
immortalwrt-23.05.3-x86-64-generic-squashfs-combined.img
immortalwrt-23.05.3-x86-64-generic-ext4-combined.img
確認你的uuid,是sda2的PARTUUID="cfd7abf3-cf18-4a4a-95e4-46f2013c080f",
root@ImmortalWrt:/# blkid
/dev/loop1: LABEL="rootfs_data" UUID="1858fcd6-7767-11ef-979c-5fec82ce50f5" BLOCK_SIZE="4096" TYPE="f2fs"
/dev/loop0: LABEL="rootfs_data" UUID="1858fcd6-7767-11ef-979c-5fec82ce50f5" BLOCK_SIZE="4096" TYPE="f2fs"
/dev/sda2: BLOCK_SIZE="262144" TYPE="squashfs" PARTUUID="cfd7abf3-cf18-4a4a-95e4-46f2013c080f"
/dev/sda128: PARTUUID="20c60f33-afc6-96e2-ae0b-e001ae609580"
/dev/sda1: SEC_TYPE="msdos" LABEL_FATBOOT="kernel" LABEL="kernel" UUID="1234-ABCD" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="20c60f33-afc6-96e2-ae0b-e001ae609501"
root@ImmortalWrt:/#
並修改你的系統啟動引導
root@ImmortalWrt:/# vim /boot/grub/grub.cfg
把裡面的2個uuid都改成,sda2的PARTUUID cfd7abf3-cf18-4a4a-95e4-46f2013c080f
root@ImmortalWrt:/# cat /boot/grub/grub.cfg
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 --rtscts=off
terminal_input console serial; terminal_output console serial
set default="0"
set timeout="3"
search -l kernel -s root
menuentry "ImmortalWrt" {
linux /boot/vmlinuz root=PARTUUID=cfd7abf3-cf18-4a4a-95e4-46f2013c080f rootwait console=tty0 console=ttyS0,115200n8 noinitrd
}
menuentry "ImmortalWrt (failsafe)" {
linux /boot/vmlinuz failsafe=true root=PARTUUID=cfd7abf3-cf18-4a4a-95e4-46f2013c080f rootwait console=tty0 console=ttyS0,115200n8 noinitrd
}
root@ImmortalWrt:/#
12.執行reboot,重啟後生效,檢查最後的分割槽成果!
BusyBox v1.36.1 (2024-07-18 06:35:54 UTC) built-in shell (ash)
.___ __ .__
| | _____ _____ ____________/ |______ | |
| |/ \ / \ / _ \_ __ \ __\__ \ | |
| | Y Y \ Y Y ( <_> ) | \/| | / __ \| |__
|___|__|_| /__|_| /\____/|__| |__| (____ /____/
\/ \/ BE FREE AND UNAFRAID \/
-----------------------------------------------------
ImmortalWrt 23.05.3, r27917-81a1f98d5b
-----------------------------------------------------
root@ImmortalWrt:~# df -Th
Filesystem Type Size Used Available Use% Mounted on
/dev/root squashfs 9.0M 9.0M 0 100% /rom
tmpfs tmpfs 906.0M 104.0K 905.9M 0% /tmp
/dev/loop0 f2fs 5.0G 162.8M 4.8G 3% /overlay
overlayfs:/overlay overlay 5.0G 162.8M 4.8G 3% /
tmpfs tmpfs 512.0K 0 512.0K 0% /dev
/dev/sda1 vfat 31.9M 7.9M 24.1M 25% /mnt/sda1
root@ImmortalWrt:~#
我們可以看到,可用空間已經變成了5G,大功告成。
13.有EFI引導的,必須修改引導,沒有EFI引導的(傳統bios引導的,這取決你當時安裝的是什麼版本),可以跳過這步,直接reboot,重啟後就擴容成功了。