如何创建启动盘的可启动克隆

如何创建启动盘的可启动克隆

在我的环境中,我有 2 台 MAC Mini、一台 Windows10 机器和 Ubuntu 20.04 LTS。在 MAC mini 上,我运行 SuperDuper 在外部硬盘上创建可启动克隆。在 Ubuntu 上可以做同样的事情吗?我看到了之前对此的回答,但它涉及许多步骤,需要摆弄 dd、/etc/fstab 和 grub,而且已经有好几年了。有没有新的更好的方法?我考虑过 Clonezilla,但它的网页上没有明确说明它会创建可启动克隆。我希望我的 Ubuntu 机器解决方案能够像 SuperDuper 对我的 MAC 那样工作。

答案1

我的第一个答案不是一般意义上的克隆系统。我已成功克隆所有内容并使其可启动。(这适用于 EFI|UEFI,包括 Mac,而不是 MBR 启动。)

设备配置:

mac2011-linux% lsblk -f|grep -v loop
NAME FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT
sda                                                                                           
├─sda1 vfat     FAT32 EFI                 67E3-17ED                             172.8M    12% /boot/efi
├─sda2 hfsplus        SSD 1T              0492d65c-8b14-356a-9d3d-337f44e8d58a                
├─sda3 hfsplus        Recovery HD         87867aee-1d5c-3c9e-ae36-8d2df5c162f1                
└─sda4 ext4     1.0                       dc68435c-f80c-4beb-a09b-69015ad516e6  161.5G    60% /
sdb                                                                                           
├─sdb1 vfat     FAT32 EFI                 B4A1-A82A                             172.8M    12% /media/alba/EFI
├─sdb2 ext4     1.0   Ubuntu backup       e370d38b-7cdf-4a2a-b9e5-cc4ff1723f51    165G    59% /media/alba/Ubun
├─sdb4 hfsplus        Mac OS X El Capitan 3771b656-357f-3ac4-a993-704353fc89b7                
└─sdb5 hfsplus        Recovery HD         1925d052-aca6-307a-8025-ad6321a399f4 

检查以上四个分区是否都已安装,如有必要请安装它们(使用 Ubuntu 磁盘)。

sdb2(Ubuntu 备份)是 Ubuntu 系统和用户文件的预期克隆,简称根分区。作为sdb外部设备,sdb2默认挂载为/media/alba/Ubuntu backupsdb1是 EFI 系统分区的预期克隆,挂载为/media/alba/EFI

每个分区必须具有不同的 UUID。FAT 分区的 UUID 只能通过格式化来更改。克隆分区应足够大,以包含原始分区的所有文件。

克隆根分区:

sudo rsync --archive --executability --hard-links --update --verbose --xattrs --one-file-system --delete --progress --exclude={/etc/fstab,/boot/grub/grub.cfg,/export,/home/alba/.cache,"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*",/lost+found} / /media/alba/Ubuntu\ backup

etc.的内容/dev不需要复制,因为它们没有用,或者不应该复制,因为 Ubuntu 创建了它们。但是,如果/devetc. 不存在,Ubuntu 将无法启动,因此只有/dev/*not /devetc. 被排除。

我还排除了/export配置中的 NFS 挂载。不排除/export可能会导致重复。

从原始版本复制/etc/fstab到克隆版本:

mac2011-linux% sudo cp /etc/fstab /media/alba/Ubuntu\ backup/etc/fstab

在 中/media/alba/Ubuntu\ backup/etc/fstab,用上面设备配置中找到的 UUID 替换原始根和 EFI 系统分区 UUID,以便:

mac2011-linux% sudo cat /media/alba/Ubuntu\ backup/etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda4 during installation
UUID=e370d38b-7cdf-4a2a-b9e5-cc4ff1723f51 /               ext4    errors=remount
-ro 0       1
# /boot/efi was on /dev/sda1 during installation
UUID=B4A1-A82A  /boot/efi       vfat    umask=0077      0       1
/swapfile                                 none            swap    sw            
  0       0

复制EFI系统分区:

mac2011-linux% sudo -i                                        
root@mac2011-linux:~# cp -r /boot/efi/* /media/alba/EFI

编辑/media/alba/EFI/EFI/ubuntu/grub.cfg以定义根分区,以便:

root@mac2011-linux:~# cat /media/alba/EFI/EFI/ubuntu/grub.cfg
search.fs_uuid e370d38b-7cdf-4a2a-b9e5-cc4ff1723f51 root hd1,gpt2 
set prefix=($root)'/boot/grub'
configfile $prefix/grub.cfg

GRUB 中的分区号与 Ubuntu 中的相同。

从原始文件复制到克隆文件/boot/grub/grub.cfg(就像对 所做的那样/etc/fstab)并使其可写:

root@mac2011-linux:~# chmod +w /media/alba/Ubuntu\ backup/boot/grub/grub.cfg

gpt4用克隆根分区 UUID替换所有位置gpt2并使用原始根分区 UUID。

重置权限:

root@mac2011-linux:~# chmod -w /media/alba/Ubuntu\ backup/boot/grub/grub.cfg

重启,在固件启动菜单中选择克隆 EFI。如果你没有犯错,那么 GRUB 将启动 Ubuntu,否则它会提示。

评论

我已在 GRUB shell 中检查过,hd0中使用的GRUB 设备号/boot/grub/grub.cfg与 无关/dev/sdb?。 无需对其进行编辑。

我建议在启动克隆时至少断开一次原始分区,以确保克隆可以自行启动。如果您不想打开计算机机箱,您可以检查克隆启动后是否可以卸载原始分区。

update-grub是不需要的,但是一旦您在克隆上启动,您就可以更新 GRUB 并在克隆上重新启动以检查克隆是否仍然可启动。

使用--delete-excludedinrsync将会消除/media/alba/Ubuntu\ backup/etc/fstab和的编辑/media/alba/Ubuntu\ backup/boot/grub/grub.cfg

Bash 脚本用于将 Ubuntu 备份/克隆到另一个分区是一个可以完成类似任务的脚本。

最好先手动克隆,以便了解和检查每个步骤,然后根据系统特点编写脚本。

如果原始文件发生变化,则应重新复制和编辑/etc/fstab以及EFI 系统分区。系统更新期间会发生这种情况。/boot/grub/grub.cfg

参考书目或参考文献

复制分区后,rsync 是否需要更改 UUID?

双重启动和文件 /boot/grub/grub.cfg — 使用哪一个?

UEFI

重启后,GRUB 在命令行中启动

如何在 Linux 上修复无法启动的 GRUB 2

Bash 脚本用于将 Ubuntu 备份/克隆到另一个分区

文件系统克隆 Arch Linux

答案2

创建必要的分区,设置标签并在连接两个设备的情况下运行脚本。

#!/bin/zsh
# automates the method explained in
# https://askubuntu.com/questions/1267225/how-to-create-a-bootable-clone-of-boot-disk/1327623#1327623
# USE CAREFULLY, THIS IS INTRINSICALLY DANGEROUS SOFTWARE
# Pierre ALBARÈDE 2021/4/24
# tested with Ubuntu 20.10

# Assumptions:
# - /boot is not on a separate partition.
# - root partition has label $UbuntuLabel and the first partition on the same device is the EFI system partition,
# - root partition backup has label $UbuntuBackupLabel and the first partition on the same device is available for the EFI system partition backup,
# - device names are like sd[a-z].

# To do:
# - pick and exclude duplicate mount (e. g. for NFS) from /etc/fstab to avoid overfilling the backup device,
# -check that backup volume partition sizes are enough.

# --- begin config
UbuntuLabel='Ubuntu'
UbuntuBackupLabel='Ubuntu backup'
logfile="rsync.log"
# excluded from rsync
# /swapfile can be big and transfering it is a waste of time,
# not having a swapfile backup makes some errors at boot and shutdown.
# excludedByUser='/export,"/home/*/.cache",/swapfile,$logfile'
excludedByUser='/export,"/home/*/.cache",$logfile'
# --- end config

# Partition attributes are named as in
# % lsblk -PO /dev/sda1
# [filtered]
# NAME="sda1" PATH="/dev/sda1" FSTYPE="vfat" FSUSED="24.1M" FSUSE%="12%" FSVER="FAT32" MOUNTPOINT="/boot/efi" LABEL="EFI" UUID="67E3-17ED" PTUUID="b5ca7ab4-d564-49a1-a43b-d9125d4dcbab" PTTYPE="gpt" PARTTYPE="c12a7328-f81f-11d2-ba4b-00a0c93ec93b" PARTTYPENAME="EFI System" PARTLABEL="EFI System Partition" PARTUUID="05bdacf6-78ff-451d-8c4d-bb812fd68e83" PKNAME="sda"
 
# Many attributes look similar, I use LABEL and UUID, not PARTLABEL and PTUUID, PARTUUID.

alias lsblkn='lsblk -n'

#########
# TESTS #
#########

# Are all UUIDs distinct?
[[ -n $(lsblkn -o UUID|grep '\S'|sort|uniq --repeated) ]]&&{echo "Error: not all UUIDs are distinct.  Did you use dd?";exit 1}

# Does only one partition exists with LABEL $UbuntuLabel?
[[ $(lsblkn -o LABEL|grep -x $UbuntuLabel|wc -l) != 1 ]]&&{echo "Error: $UbuntuLabel is not unique.";exit 1}

# Does only one partition exists with LABEL $UbuntuBackupLabel?
[[ $(lsblkn -o LABEL|grep -x $UbuntuBackupLabel|wc -l) != 1 ]]&&{echo "Error: $UbuntuBackupLabel is not unique.";exit 1}

#######################################
# DETERMINE PARTITION PATHS AND UUIDS #
#######################################
# paths for mount
# UUIDs for (display and) replacement in config files

# blkid (or findfs) finds only one occurrence, that is why I have checked unicity
UbuntuPath=$(blkid --label $UbuntuLabel)
UbuntuBackupPath=$(blkid --label $UbuntuBackupLabel)

devicePath=/dev/$(lsblkn -o PKNAME $UbuntuPath)
deviceBackupPath=/dev/$(lsblkn -o PKNAME $UbuntuBackupPath)

UbuntuUUID=$(lsblkn -o UUID $UbuntuPath)
echo "Ubuntu partition UUID:            $UbuntuUUID"

# EFI is always first partition with number 1
EFIPath="$devicePath"1
EFIUUID=$(lsblkn -o UUID $EFIPath)
echo "EFI system partition UUID:        $EFIUUID"

UbuntuBackupUUID=$(lsblkn -o UUID $UbuntuBackupPath)
echo "Ubuntu backup partition UUID:     $UbuntuBackupUUID"

EFIBackupPath="$deviceBackupPath"1
EFIBackupUUID=$(lsblkn -o UUID $EFIBackupPath)
echo "EFI system partition backup UUID: $EFIBackupUUID"

# determine GRUB partition number from Ubuntu partition name
# on original
UbuntuGpt=$(echo $UbuntuPath|sed "s/\/dev\/sd[a-z]/gpt/")
# on backup
UbuntuBackupGpt=$(echo $UbuntuBackupPath|sed "s/\/dev\/sd[a-z]/gpt/")

# I don't know how to determine GRUB device number but it does not matter so it is not changed (it is 0).


#########
# mount #
#########

# If we are here, Ubuntu must be mounted.

[[ -z $(findmnt $EFIPath) ]]&&{echo "Mounting EFI system partition.";udisksctl mount --block-device $EFIPath}

[[ -z $(findmnt $UbuntuBackupPath) ]]&&{echo "Mounting Ubuntu backup partition.";udisksctl mount --block-device $UbuntuBackupPath}

[[ -z $(findmnt $EFIBackupPath) ]]&&{echo "Mounting EFI system partition backup.";udisksctl mount --block-device $EFIBackupPath}

# All 4 partition are now mounted.

# determine destination mountpoints
# UbuntuBackupMountPoint should normally be /media/$USER/$UbuntuBackupLabel
UbuntuBackupMountPoint=$(lsblkn -o MOUNTPOINT "$UbuntuBackupPath")
EFIBackupMountPoint=$(lsblkn -o MOUNTPOINT "$deviceBackupPath"1)

echo "You are going to backup to:"
echo $UbuntuBackupMountPoint
echo $EFIBackupMountPoint

read -q "REPLY?Confirm by typing y?"

[[ $REPLY != 'y' ]]&&{echo "\nExiting without file change.";exit 0}
echo "\nProceeding with rsync."

##########
# BACKUP #
##########

# rsync would not transfer /etc/fstab and /boot/grub/grub.cfg and /media/$USER/EFI/EFI/ubuntu/grub.cfg after their backups have been edited and given a more recent date so I erase the backups. One could also cheat the modification time.

sudo rm $UbuntuBackupMountPoint{/etc/fstab,/boot/grub/grub.cfg}
sudo rm $EFIBackupMountPoint/EFI/ubuntu/grub.cfg

# Backup root partition, including /etc/fstab /boot/grub/grub.cfg.
# --archive = -rlptgoD
# --recursive, -r          recurse into directories
# --links, -l              copy symlinks as symlinks
# --perms, -p              preserve permissions
# --times, -t              preserve modification times
# --owner, -o              preserve owner (super-user only)
# --group, -g              preserve group
# -D          <             equivalent to --devices --specials
# --devices                preserve device files (super-user only)

# To debug, replace "rsync" by "echo" or use '--dry-run.
# Single quotes prevent eval to remove double quote around "/dev/*" and split words in '$UbuntuBackupLabel'.

eval sudo rsync --log-file=$logfile --archive --no-D --executability --hard-links --update --verbose --xattrs --one-file-system --delete --progress --exclude={$excludedByUser} --exclude={'"/dev/*"','"/proc/*"','"/sys/*"','"/tmp/*"','"/run/*"','"/mnt/*"','"/media/*"','"/lost+found/*"',$logfile} --delete-excluded / '$UbuntuBackupMountPoint'

# backup the EFI system partition
sudo rsync --recursive --times --delete /boot/efi/ $EFIBackupMountPoint

###############
# EDIT BACKUP #
###############

sudo sed -i "s/$EFIUUID/$EFIBackupUUID/g;s/$UbuntuUUID/$UbuntuBackupUUID/g" $UbuntuBackupMountPoint/etc/fstab

grubcfg=$UbuntuBackupMountPoint/boot/grub/grub.cfg
sudo chmod +w $grubcfg
sudo sed -i "s/$UbuntuUUID/$UbuntuBackupUUID/g;s/$UbuntuGpt/$UbuntuBackupGpt/g" $grubcfg
sudo chmod -w $grubcfg

# set root UUID in EFI
sed -i "s/$UbuntuUUID/$UbuntuBackupUUID/;s/$UbuntuGpt/$UbuntuBackupGpt/" $EFIBackupMountPoint/EFI/ubuntu/grub.cfg
exit 0

答案3

对于 cloenzilla,请检查目标驱动器/分区是否已格式化。然后在 Clonezilla 中选择专家模式并启用“-icds”选项。您还需要选择“按比例调整分区表大小”选项。如果您关闭、拔下电缆、重新启动、等待然后重新连接外部设备,您的外部设备应该会恢复。输入“lsblk”以确认它在那里。

答案4

我不知道您是否有一个大的备份磁盘,但如果有,您可以使用 GNOME 磁盘通过 ISO 进行复制。

步骤 1:在备份磁盘上创建磁盘映像

步骤 2:在新磁盘上恢复磁盘映像

我希望这有帮助

相关内容