@@ -17,6 +17,16 @@ NUL bytes, uses a lot of disk space, and can take a while. So instead, in this d
1717focusing on how to do these things more efficiently, copying only those parts of the partitions
1818holding the data.
1919
20+ - If you have the overlay filesystem enabled, I suggest disabling it before pulling the images,
21+ just to make later configuration easier.
22+
23+ - If you flashed the SD card with the RPi Imager, then do the following on the RPi
24+ to prevent ` cloud-init ` from modifying the system configuration on the clones.
25+ - ` sudo apt purge -y cloud-init && sudo apt autoremove -y `
26+ - ` sudo rm -rvf /etc/cloud/ /var/lib/cloud/ /boot/firmware/{user-data,network-config} `
27+
28+ In the following, replace ` /dev/sdX ` with the source SD card's device name.
29+
2030- Partition table:
2131 - Dump the table via: ` sudo sfdisk -d /dev/sdX | tee part_table `
2232 - To prevent conflicts, remove unique identifiers via:
@@ -37,72 +47,84 @@ holding the data.
3747 - ` sudo e2image -pra /dev/sdX2 sdX2.img `
3848 - ` sudo e2image -pra /dev/sdX3 sdX3.img ` (optional if you have a ` data ` partition)
3949
40- - ` sudo chown -c $USER:$USER *.img `
41- - ` chmod -c a-w *.img* `
50+ - Adjust permissions on image files:
51+ - ` sudo chown -c $USER:$USER *.img* `
52+ - ` chmod -c a-w *.img* part_table `
4253
4354- If you want to back up these files into one:
4455 - ` tar --create --file rpi-images.tar --verbose --sparse -- part_table sdX?.img* `
45- - Alternatively, compressed, which can save a lot of space (in one test I ran, 50%):
56+ - Alternatively, compressed, which can save a lot of space (in a few tests I ran, over 50%):
4657 ` tar --create --file rpi-images.tgz -I 'gzip -9' --verbose --sparse -- part_table sdX?.img `
4758 (in this case it's more efficient if you didn't compress the FAT backup above)
4859
4960
50- ⚠️ Untested Stuff Follows
51- --------------------------
52-
53- This document is a work in progress and I have not tested the following yet.
54-
55-
5661Writing Images to an SD Card
5762----------------------------
5863
5964** ⚠️ DANGER ZONE:** Make sure you're writing to the correct device!
6065
66+ Remove the original source SD card from your system, at least until new UUIDs are generated (below).
67+ In the following, replace ` /dev/sdY ` with the clone SD card's device name.
68+
6169- Partition table:
62- - ` sudo sfdisk /dev/sdX < part_table `
63- - TODO: I don't see the "data" label in the sfdisk output, do I need to do that manually?
70+ - ` sudo sfdisk /dev/sdY < part_table `
6471
6572- FAT Partition:
66- - ` zcat sdX1.img.gz | sudo dd of=/dev/sdX1 status=progress `
73+ - ` zcat sdX1.img.gz | sudo dd of=/dev/sdY1 status=progress `
74+ - Alternatively, if it was uncompressed: ` sudo dd if=sdX1.img of=/dev/sdY1 status=progress `
6775
6876- ext4 Partitions:
69- - ` sudo e2image -pra sdX2.img /dev/sdX2 `
70- - ` sudo e2image -pra sdX3.img /dev/sdX3 ` (optional)
77+ - ` sudo e2image -pra sdX2.img /dev/sdY2 `
78+ - ` sudo e2image -pra sdX3.img /dev/sdY3 ` (optional)
7179
7280
7381Post-Clone Updates
7482------------------
7583
76- Mount the system ext4 partition on a Linux system.
84+ ** ⚠️ DANGER ZONE:** Make sure you're writing to the correct device and directories!
85+
86+ In the following, replace ` /dev/sdY ` with the clone SD card's device name.
7787
78- - TODO: ` sudo lsblk -o+PARTUUID,UUID /dev/sdX ` and ` sudo tune2fs -U random /dev/sdX1 ` for ` .../etc/fstab ` update?
79- - ** and** adjust ` root=PARTUUID=... ` in ` /boot/firmware/cmdline.txt ` !
88+ - Check the partition IDs via ` sudo lsblk -o+PARTUUID,UUID,LABEL /dev/sdY ` ,
89+ then generate new UUIDs as follows:
90+ - ` sudo fatlabel -ir /dev/sdY1 `
91+ - ` sudo tune2fs -U random /dev/sdY2 `
92+ - ` sudo tune2fs -U random /dev/sdY3 `
93+ - Note: In case you need to adjust partition labels later, see ` e2label ` and ` fatlabel ` .
94+ The usual partition labels are ` bootfs ` and ` rootfs ` (and the optional ` data ` ).
8095
81- - machine-id, Hostname
82- - TODO: Test ` sudo systemd-firstboot --root=/media/... --hostname=... --setup-machine-id --force `
83- - TODO: Check that ` /etc/hostname ` * and* ` /etc/hosts ` were modified
96+ Mount the clone's FAT ` bootfs ` and ext4 ` rootfs ` . In the following, I will assume that
97+ they are mounted at ` /media/USER/bootfs ` and ` /media/USER/rootfs ` .
8498
85- - SSH Host Keys
86- - ` sudo rm .../etc/ssh/ssh_host_* `
99+ - ` sudo lsblk -o+PARTUUID /dev/sdY ` , then:
100+ - ` sudo vi /media/USER/bootfs/cmdline.txt ` and edit ` root=PARTUUID=... ` to match the new ` PARTUUID `
101+ - ` sudo vi /media/USER/rootfs/etc/fstab ` and edit all of the ` PARTUUID= ` fields to match the new ` PARTUUID ` s
87102
88- - Bluetooth pairings
89- - ` sudo bash -c 'rm -rf .../var/lib/bluetooth/[0-9A-Fa-f]*' `
90- (wildcard expansion needs to happen with root permissions)
103+ - ` sudo ./clone-delete.sh /media/USER/rootfs ` to delete various files that will be re-generated
91104
92- - ` sudo vi .../etc/machine-info ` for ` PRETTY_HOSTNAME ` etc.
93- - ` sudo rm -rf .../var/log/journal/* .../var/log/* .../var/cache/* .../var/lib/systemd/random-seed `
105+ - machine-id and Hostname
106+ - ` sudo systemd-firstboot --root=/media/USER/rootfs --hostname=HOSTNAME --setup-machine-id --force `
107+ - ` sudo vi /media/USER/rootfs/etc/hosts ` and replace all instances of the old hostname there too
94108
95- - TODO: Test: if the processor architectures are the same,
96- ` sudo chroot /media/... /usr/sbin/make-ssl-cert generate-default-snakeoil --force-overwrite `
109+ - If you have this file, ` sudo vi /media/USER/rootfs/etc/machine-info ` and edit ` PRETTY_HOSTNAME ` etc.
97110
98111
99112Post-Boot Updates on Clone
100113--------------------------
101114
102- - SSL Certs (if the processor architectures are different)
103- - ` sudo make-ssl-cert generate-default-snakeoil --force-overwrite `
104- - SSH Keys should have been regenerated, but if you want to play it safe:
115+ - Regenerate SSH Host keys:
116+ - ` sudo rm -vf /etc/ssh/ssh_host_* ` (Note: The ssh service doesn't re-generate these files on boot,
117+ and will refuse to start if they're missing, which is why we don't do this until after the first
118+ boot of the clone.)
105119 - ` sudo dpkg-reconfigure openssh-server `
120+ - ` sudo systemctl restart ssh `
121+
122+ - SSL Certs - only if you had/have the package ` ssl-cert ` installed:
123+ - ` sudo make-ssl-cert generate-default-snakeoil --force-overwrite `
124+
125+ - Do any other customization steps needed for your system here.
126+
127+ - If you had the overlay filesystem enabled, reenable it now.
106128
107129
108130More Information
@@ -112,7 +134,7 @@ More Information
112134- < https://wiki.archlinux.org/title/Disk_cloning#Versatile_cloning_solutions >
113135
114136
115- <!-- spell: ignore PARTUUID blkid cmdline dhcpcd dpkg firstboot sfdisk zcat snakeoil -->
137+ <!-- spell: ignore PARTUUID blkid cmdline dhcpcd dpkg firstboot sfdisk zcat snakeoil fatlabel bootfs rootfs Imager autoremove -->
116138
117139Author, Copyright, and License
118140------------------------------
0 commit comments