Here are full steps that worked for me, verified, explained & enhanced with GPT-5 Thinking.
Umbrel: clone 1 TB → 2 TB on macOS
The destination disk will be overwritten. Triple-check identifiers by size.
Don’t boot the Pi with both old and new SSDs at the same time (duplicate UUIDs).
0) Clean shutdown of Umbrel (Raspberry Pi)
ssh umbrel@umbrel.local
sudo shutdown -h now
Wait until the Pi powers off. Unplug the old 1 TB SSD from the Pi.
1) Connect both SSDs to your Mac
- Plug in old 1 TB (source) and new 2 TB (destination).
Identify just the externals:
diskutil list external
Example mapping (adjust to your output):
❯ diskutil list external
/dev/disk4 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *2.0 TB disk4
1: Microsoft Basic Data T7 2.0 TB disk4s1
/dev/disk5 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *1.0 TB disk5
1: Linux Filesystem 1.0 TB disk5s1
Tip: Re-run diskutil list external
if you unplug/replug; numbers can change.
2) Unmount the whole disks (do NOT eject)
diskutil unmountDisk /dev/disk4
diskutil unmountDisk /dev/disk5
Unmounting frees the devices for raw cloning; “eject” would remove them from the system.
3) Keep the Mac awake
Run this in new Terminal tab/window.
caffeinate -dimsu
Leave this running while cloning. You’ll stop it later with Ctrl-C (Step 7).
Alternatively, use an app like Amphetamine.
4) Check which dd
you have installed
GNU with live progress vs. stock BSD
which gdd
which dd
dd --version # GNU dd prints a version; BSD dd will complain about --version
-
If which gdd
prints something like /opt/homebrew/bin/gdd
, you have GNU dd → you’ll get live progress.
-
If not installed, you can add it: brew install coreutils
(command is gdd
), or skip to step 5-alt)
Example output
/opt/homebrew/bin/gdd
/bin/dd
dd: unknown operand --version
5) Clone using gdd
(GNU dd) — with live progress
sudo gdd if=/dev/rdisk5 of=/dev/rdisk4 bs=4M status=progress conv=fsync
Flags
-
if=/dev/rdisk5
– input file: the raw source device (old 1 TB).
-
of=/dev/rdisk4
– output file: the raw destination device (new 2 TB).
-
rdisk*
vs disk*
– rdisk
is the raw device; it bypasses extra buffering for faster I/O on macOS.
-
bs=4M
– block size 4 MiB: reduces syscall overhead and usually maxes out USB-SSD throughput.
-
status=progress
– live progress (bytes copied, speed, elapsed). GNU gdd
feature only.
-
conv=fsync
– flushes all write buffers at the end, ensuring data is physically on disk when the command exits.
Example output
Mine took 1hr 34min
❯ sudo gdd if=/dev/rdisk5 of=/dev/rdisk4 bs=4M status=progress conv=fsync
245903654912 bytes (246 GB, 229 GiB) copied, 890 s, 276 MB/s
Optional resilience
slower; only if you suspect read errors on the old SSD:
sudo gdd if=/dev/rdisk5 of=/dev/rdisk4 bs=1M status=progress conv=noerror,sync,fsync
-
noerror
→ don’t stop on read errors; continue.
-
sync
→ zero-pad unreadable blocks so offsets stay aligned.
-
This protects against a flaky source but costs throughput.
5-alt) Clone using stock macOS dd
(BSD) — no live progress
sudo dd if=/dev/rdisk5 of=/dev/rdisk4 bs=4m conv=fsync
6) When the clone finishes
Eject both disks:
diskutil eject /dev/disk4
diskutil eject /dev/disk5
STOP CAFFEINATE: go to the window where it’s running and press Ctrl-C (or just close that window). This returns your Mac to normal sleep behavior.
7) Move the new 2 TB SSD to the Pi and boot
8) Expand the partition to use the full 2 TB (on the Pi)
Install the tool that provides growpart
:
sudo apt update
sudo apt install -y cloud-guest-utils
Why install this?
The clone copied a 1 TB partition layout onto a 2 TB disk. You now need to:
-
Grow the partition boundary to fill the disk (growpart
).
-
Resize the filesystem (ext4) to use that bigger partition (resize2fs
).
Identify the disk/partition:
lsblk -f
# Typically you'll see the SSD as /dev/sda with the main ext4 partition /dev/sda1
Grow the partition, then the filesystem:
sudo growpart /dev/sda 1
sudo resize2fs /dev/sda1
Verify and reboot:
df -h
sudo reboot
df -h
should now show ~2 TB available for your Umbrel data.
Sanity checklist
-
Pi boots normally with just the new SSD.
-
df -h
shows the main partition near 2 TB size.
-
Umbrel services behave the same as before.
Quick safety notes
-
Re-check diskutil list external
every time you reconnect drives; identifiers can change.
-
unmountDisk
(Step 2) is required so the raw devices aren’t in use; don’t skip it.
-
gdd
is optional but recommended for a real progress bar; stock dd
works fine with Ctrl-T.