以下介紹 Linux 備份方法
本指南目的為建立一個可以直接透過虛擬機開機的虛擬硬碟
請注意,僅能透過虛擬機直接開機,若要直接使用實體機開機可能無法或是要另外設定
事前準備與注意事項
首先你需要一顆額外的硬碟,使用此方法的一個前提是,你不能掛載來源硬碟
也就是說,你最少需要
- 來源硬碟
- LiveUSB 當作系統
- 另一顆硬碟,外接或放在電腦裡面沒差
接著,你基本上需要使用 LiveUSB 開機
開機後,來源硬碟那顆不能掛載上來
而額外的那顆硬碟,本身請先格式化,例如 Brtfs 之類的
這些步驟完成後在往下
依賴套件安裝
首先,確認有安裝 qemu,沒有的話,使用以下指令安裝
sudo dnf install qemu
虛擬硬碟掛載相關
建立 QCOW2 映像檔(大小最小需大於等於來源磁碟)
使用以下命令建立虛擬硬碟
qemu-img create -f qcow2 test.qcow2 120G

參數:-f qcow2 指定格式為 QCOW2(支援快照且動態增長空間)
test.qcow2 是你要建立虛擬硬碟的路徑及檔名
1G 是硬碟的虛擬大小。
請自行更改
並請注意大小最小需大於等於來源磁碟
載入 NBD 模組
nbd 模組有點像是給虛擬硬碟一個掛載點,這裡要先載入這個模組
使用以下命令載入 Linux 核心的 nbd 模組
sudo modprobe nbd max_part=8
請注意如果要設定 max_part 的話,不要小於 4,會出事
掛載虛擬硬碟
使用以下命令將虛擬硬碟掛載到 nbd 上
sudo qemu-nbd -c /dev/nbd0 test.qcow2
/dev/nbd0 請設定為你要實際掛載的位置
例如 /dev/nbd1 之類的都可以
這裡使用 /dev/nbd0
test.qcow2 是剛剛建立虛擬硬碟的位置及檔名
掛載完後,現在 /dev/nbd0 在系統中就像一顆剛插上去的實體硬碟,你可以用 lsblk 看到它。
確認掛載成功
lsblk | grep nbd

應該要看到剛掛載為 nbd0 並顯示剛剛分配的空間
以這邊為例是 10G
設定分割表及磁區相關操作
啟動 KDE Partition Manager
首先選擇剛剛的 nbd0

接著選擇 New Partition Table

選擇 GPT

點選 Create New Partition Table
之後你會看到一個顯示 unallocate

這代表我們還沒格式化它
但沒關係,現在我們去要備份的那顆硬碟(注意:此時備份的那顆硬碟不能掛載,也就是來源硬碟不能掛載)
而那顆硬碟可能會長成這樣(以系統碟為例)

照理說我們應該要先格式化硬碟才能繼續之類的
但這裡我們可以直接複製整個磁區來取代它
你可以直接點磁區的那個區塊(上面那個有顏色的地方)
然後 Crtl+C Crtl+V 到新的那顆 nbd 即可
而因為這邊我僅作示範,所以先隨便分三個磁區

都設定完後
記得點左上角的 Apply,否則系統不會做任何操作

更改磁碟 ID 相關
查看 nbd 相關資訊
sudo fdisk -x /dev/nbd0

可以看到我們有幾個重要資訊
Disk identifier: 25BDF3F9-D9D2-4F8A-9A2C-F282E6BE1BA3
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/nbd0p1 2048 4196351 4194304 0FC63DAF-8483-4772-8E79-3D69D8477DE4 C02A8C28-DCD6-4E90-8BC7-4443ED813166
/dev/nbd0p2 4196352 8390655 4194304 0FC63DAF-8483-4772-8E79-3D69D8477DE4 E977A3D4-3AF0-4B6E-A074-23B760793746
/dev/nbd0p3 8390656 12584959 4194304 0FC63DAF-8483-4772-8E79-3D69D8477DE4 8BBC01F3-AB90-4153-9227-5C47A57453F0
這裡需要注意的是 Disk identifier 以及每個分區的 Type-UUID 與 UUID
等等會用到
查看要備份的目標硬碟相關資訊
fdisk -x /dev/nvme0n1

一樣可以看到我們有幾個重要資訊
Disk identifier: D356EF25-CA85-4E80-88CC-19046A20857C
Device Start End Sectors Type-UUID UUID Name Attrs
/dev/nvme0n1p1 2048 4095 2048 21686148-6449-6E6F-744E-656564454649 4DD9ED3C-EB33-4233-B03E-BD6B5E3E6DF7
/dev/nvme0n1p2 4096 2101247 2097152 BC13C2FF-59E6-4262-A352-B275FD6F7172 5104E937-01D8-4357-97AB-660AA3E4F456
/dev/nvme0n1p3 2101248 209713151 207611904 0FC63DAF-8483-4772-8E79-3D69D8477DE4 D3336CA9-5AB2-4638-B3A9-1CA94E708A9C
同樣需要注意的是 Disk identifier 以及每個分區的 Type-UUID 與 UUID
等等會用到
修改 Disk identifier
使用以下指令進入 fdisk 工具
sudo fdisk /dev/nbd0
會出現以下資訊
~/test_virtual_disk
sudo fdisk /dev/nbd0
Welcome to fdisk (util-linux 2.40.4).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help):
這裡輸入 x 進入 Expert 模式以修改進階設定
Command (m for help): x
Expert command (m for help):
輸入 i 進入輸入模式
Expert command (m for help): i
Enter new disk UUID (in 8-4-4-4-12 format):
輸入 i 之後,輸入硬碟 UUID
請注意,這裡 UUID 請使用剛剛 /dev/nvme0n1 得知的 Disk identifier,簡單說,我們的目標就是將虛擬硬碟的 Disk identifier 更改為與實際我們備份硬碟的 Disk identifier 相同
直接輸入要備份的那顆硬碟的 Disk identifier,在這裡就是 /dev/nvme0n1 的
Enter new disk UUID (in 8-4-4-4-12 format): D356EF25-CA85-4E80-88CC-19046A20857C
Disk identifier changed from 25BDF3F9-D9D2-4F8A-9A2C-F282E6BE1BA3 to D356EF25-CA85-4E80-88CC-19046A20857C.
Expert command (m for help):
輸入 r 後輸入 w
完成寫入,在寫入之前,所有操作都是暫存而已
修改該磁碟各分區的 UUID
使用以下指令進入 fdisk 工具
sudo fdisk /dev/nbd0
~/test_virtual_disk
sudo fdisk /dev/nbd0
Welcome to fdisk (util-linux 2.40.4).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help):
輸入 x
輸入 u
選擇分區
Command (m for help): x
Expert command (m for help): u
Partition number (1-3, default 3): 1
輸入新的uuid
Partition number (1-3, default 3): 1
New UUID (in 8-4-4-4-12 format): 21686148-6449-6E6F-744E-656564454649
Partition UUID changed from C02A8C28-DCD6-4E90-8BC7-4443ED813166 to 21686148-6449-6E6F-744E-656564454649.
Expert command (m for help):
輸入 r 後輸入 w
完成寫入,在寫入之前,所有操作都是暫存而已
修改該磁碟各分區的 TYPE-UUID
使用以下指令進入 fdisk 工具
sudo fdisk /dev/nbd0
~/test_virtual_disk
sudo fdisk /dev/nbd0
Welcome to fdisk (util-linux 2.40.4).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help):
輸入 m
輸入 t
GPT
M enter protective/hybrid MBR
Generic
d delete a partition
F list free unpartitioned space
l list known partition types
n add a new partition
p print the partition table
t change a partition type
v verify the partition table
i print information about a partition
e resize a partition
Misc
m print this menu
x extra functionality (experts only)
Script
I load disk layout from sfdisk script file
O dump disk layout to sfdisk script file
Save & Exit
w write table to disk and exit
q quit without saving changes
Create a new label
g create a new empty GPT partition table
G create a new empty SGI (IRIX) partition table
o create a new empty MBR (DOS) partition table
s create a new empty Sun partition table
Command (m for help): t
Partition number (1-3, default 3):
選擇分區
Command (m for help): t
Partition number (1-3, default 3): 1
Partition type or alias (type L to list all):
輸入新的type uuid
Command (m for help): t
Partition number (1-3, default 3): 1
Partition type or alias (type L to list all): 21686148-6449-6E6F-744E-656564454649
Changed type of partition 'Linux filesystem' to 'BIOS boot'.
Command (m for help):
輸入 r 後輸入 w
完成寫入,在寫入之前,所有操作都是暫存而已
卸載硬碟
qemu-nbd -d /dev/nbd0
備份完成
確認備份是否正確
一般啟用情境
接著我們要確認這份備份是否正確
我們使用虛擬機進行確認
-
首先進入
Virt Manager或是Virtual Machine Manager總之一樣的意思我們可以看到他長這樣

-
點選左上角,建立新虛擬統
並選擇匯入現有磁碟映像,點下一步
-
選擇
本機瀏覽,並找到你當初存放qcow2的位置
-
接著選擇你的系統及版本,以我為例,我使用的是
Ubuntu 22.04
所以選這個選項
-
設定 CPU 及 RAM 的使用量,隨便,高興就好

-
接著,記得要勾選
在安裝前自訂組態,如果忘記勾選,前面全部重來,這很重要
-
下一步後,在韌體選擇
UEFI X86_64:/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2
實際選項可能不一樣,但總之就找關鍵字UEFI、OVMF_CODE_4M這兩個就對了,不要選到secure boot相關的,可能會出事
-
這裡有點重要,預設應該是
QXL,先不用動他,有問題再改VGA

-
都確認好後,點選右下角
套用並點左上角開始安裝,如果正常應該可以直接開機

故障排除
在過程中,你可能會遇到
這個

這個

這個

或是這個

然後還有他 X 的這種直接卡住

還有這個,只有游標

最後甚至好了,直接一片黑,連游標都沒有了

以上族繁不及備載
有以上情況,你有兩種辦法
- 擺爛,反正我磁區已經複製到虛擬硬碟了,也顯示有占用了,所以應該備份好了,就當他有了,然後可能你的資料有問題
- 還是檢查一下好了
假設你想選 2 的話呢?
我剛好有一些解法,雖然可能不能解決你的問題
但解決我的了
首先,在虛擬機開機的時候一直按 esc,應該會進入 grub,像以下這樣

接著,請下以下命令
ls
我們要先知道裡面長什麼樣子
你可能得到結果是
grub> ls
(proc) (memdisk) (hd0) (hd0,gpt2) (hd0,gpt1)
接著,你必須要確認你的系統在哪一個分區,所以對每一個分區 ls,你有幾個分區就做幾次,因為我只有兩個,所以做兩次
以下是輸出
grub> ls (hd0,gpt2)/
error: unknown filesystem.
grub> ls (hd0,gpt2)
Partition hd0,gpt2: No known filesystem detected - Partition start at 525312KiB - Total size 976236544KiB
grub> _
可以看到 gpt2 明顯比較大,所以開機磁區應該在這,所以我們下
ls (hd0,gpt2)/boot/
確認這個磁區裡面有沒有 boot 資料夾,以及看裡面有什麼東西
結果如下
grub> ls (hd0,gpt2)/boot/
efi/ grub/ config-6.8.0-60-generic vmlinuz-6.8.0-60-generic initrd.img initrd.img.old memtest86+.bin memtest86+.elf memtest86+_multiboot.bin vmlinuz
vmlinuz.old config-6.8.0-87-generic config-6.8.0-90-generic vmlinuz-6.8.0-87-generic System.map-6.8.0-87-generic System.map-6.8.0-90-generic
System.map-6.8.0-60-generic initrd.img-6.8.0-87-generic vmlinuz-6.8.0-90-generic initrd.img-6.8.0-60-generic initrd.img-6.8.0-90-generic
這裡我們可以看到很多 kernel 的版本,這裡我們選最新的
vmlinuz-6.8.0-90-generic,並且對應的映像是 initrd.img-6.8.0-90-generic
這樣我們確認到,kernel 確實存在
接著我們下以下這些命令
set root=(hd0,gpt2)
linux /boot/vmlinuz-6.8.0-90-generic root=/dev/vda2 ro quiet splash nomodeset
initrd /boot/initrd.img-6.8.0-90-generic
boot
需要注意的點是
/boot/vmlinuz-6.8.0-90-generic,請換成你自己看到的最新的 kernel
/dev/vda2,請換成你自己的磁區
/boot/initrd.img-6.8.0-90-generic,也是換成你自己的映像
簡單說我這邊的命令都是參考,需要自行替換
詳細一點的解釋如下
set root=(hd0,gpt2)
# 告訴 GRUB「檔案系統的根目錄在哪」
# hd0 = 第一顆硬碟
# gpt2 = GPT 分區表的第二個分區(ext4 系統分區)
# 系統才知道後面的路徑去哪裡找
linux /boot/vmlinuz-6.8.0-90-generic root=/dev/vda2 ro quiet splash nomodeset
# linux = GRUB 指令,載入 Linux kernel
# /boot/vmlinuz-6.8.0-90-generic = kernel 映像檔路徑
# root=/dev/vda2 = 告訴 kernel 開機後根目錄在哪(virtio 磁碟所以是 vda)
# ro = 一開始用唯讀方式掛載根目錄(正常開機流程)
# quiet splash = 安靜模式 + 顯示開機畫面
# nomodeset = 禁用顯卡 KMS,用基本顯示驅動
initrd /boot/initrd.img-6.8.0-90-generic
# 載入 initial ramdisk
# 這是開機早期需要的驅動和工具的暫存檔案系統
# 必須跟 kernel 版本配對
boot
# 執行開機,把控制權交給 kernel
理論上全部都下完之後,應該就可以開機了
開機進入系統後,應該就會像這樣

進去後,記得要做一些事
首先,我們進 CMD
輸入
sudo nano /etc/default/grub
我們需要改些開機相關的
把
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
改成
GRUB_CMDLINE_LINUX_DEFAULT=""
Crtl+O 儲存後,Crtl+X 離開
之後輸入
sudo update-grub
確定更新完 grub 後,關機
並回到上面 一般啟用情境 中的 8.
把顯示改成 VGA
之後應該就能正常開機了
故障原因推測
其實我不是很確定究竟問題在哪
但大概是跟顯示有關的,主要是開機時的那三個參數
quiet splash nomodeset
這些參數有以下意思
quiet
- 減少開機時顯示的 kernel 訊息
- 只顯示錯誤和重要訊息
splash
- 啟動時開機動畫
- 顯示圖形化的開機畫面(例如 Ubuntu logo)
- 拿掉的話會看到文字訊息而不是 logo
nomodeset
- 禁用 Kernel Mode Setting(KMS)
- 阻止 kernel 載入顯卡的原生驅動
- 強制用基本的 VESA/VGA framebuffer 顯示
- 解析度會較低,但相容性最高
在我自己測試後,發現只要沒有 quiet 跟 splash 的話,並且顯示改成 VGA 就可以正常開機
如果拿掉 quiet 跟 splash 後,還是使用 QXL 的話,一樣會黑畫面
因此我推測是顯示協定的相關問題
但查這個搞了我很久
所以就先停在這了
以上是目前的解法