OneLinersCommand workbench
Guides
System Administration / Storage & Filesystems / Security

Migrate a Linux root filesystem to a larger disk with minimal downtime

Copy an Ubuntu root filesystem to a larger ext4 disk, preserve Linux metadata, rebuild UUID-based boot artifacts, perform a controlled cutover, and retain the original disk as a tested rollback.

150 min11 stepsHigh-impact changeRevision 2
Save or explore
Save to collectionCreate a collection in the sidebar first.
0 of 11 steps completed
Goal

Move a conventional Ubuntu Server 24.04 root filesystem to a larger disk without block-cloning ambiguity, while limiting downtime to an offline delta and a reversible boot change.

Supported environments
  • Ubuntu Server 24.04 LTS
  • ext4 1.0 compatible feature set
  • rsync 3.2+, 3.4.x
  • GNU GRUB 2.12+, 2.14
Prerequisites
  • Independent backup Create an application-consistent backup outside both disks and restore a representative protected file before the maintenance window.test -s /root/restore-test/{{restoredSample}}
  • Console and firmware access Prove that an operator can select either disk and boot recovery media without relying on SSH from the migrating root.
  • Target identity Record target model, serial, capacity, by-id path, signatures, mount state, and relationship to LVM, RAID, encryption, and swap.lsblk -e7 -o NAME,PATH,MODEL,SERIAL,SIZE,TYPE,FSTYPE,UUID,MOUNTPOINTS
  • Storage and boot design Document source root layering, separate mounts, UEFI or BIOS mode, Secure Boot policy, target partitions, UUID plan, and rollback owner.
  • Application consistency plan Define how databases, queues, containers, virtual machines, and file writers will be flushed or stopped before the final delta.
Operating boundary

OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.

Full guide

What you will build

System
  • A separately formatted ext4 root filesystem on a larger disk, copied with Linux ownership, hard links, ACLs, extended attributes, devices, and filesystem boundaries handled deliberately.
  • A bootable Ubuntu installation whose target `/etc/fstab`, initramfs, and GRUB configuration refer to stable UUIDs rather than the old disk name.
  • A reversible cutover in which the original disk remains untouched and bootable until the new root has passed filesystem, service, network, package, and reboot checks.
Observable outcome
  • The target tree passes a reviewed dry-run, a full copy, and an offline delta copy without crossing ephemeral or separately mounted filesystems accidentally.
  • Firmware starts GRUB from the intended disk, the initramfs resolves the new root UUID, and `findmnt /` proves that the running root is the new filesystem.
  • The operator can select the original disk from firmware or GRUB and return to the previous root if any checkpoint fails.

Architecture

How the parts fit together

The migration separates data transfer from boot activation. Rsync creates a metadata-preserving copy below a temporary mount, while pseudo-filesystems are excluded and later bind-mounted only for the chroot. The target fstab identifies filesystems by UUID. A chroot rebuilds initramfs and GRUB using the target tree, then an offline delta closes the write gap before firmware is asked to boot the new disk.

Original root diskThe known-good source and rollback path. It is read during copy but is not repartitioned, reformatted, or removed during the acceptance window.
Target root filesystemA new ext4 filesystem mounted at `/mnt/new-root`, large enough for current data, operating headroom, package caches, logs, and future growth.
Target boot pathEither a new EFI System Partition mounted at `/boot/efi` for UEFI or GRUB installed to the whole target disk for legacy BIOS.
Rsync transferCopies the root filesystem without following separate mounts and preserves the metadata Ubuntu services expect.
Chroot boot repairMakes the copied tree temporarily behave like a running root so initramfs and GRUB are generated against the target layout.
Firmware or hypervisorSelects the target disk for the first boot while retaining an explicit route back to the original disk.
  1. Inventory the live mount graph, boot mode, encryption, LVM, free space, packages, services, and recovery access before selecting any device.
  2. Create the target partition and filesystem only after its stable hardware identity has been matched twice.
  3. Preview and perform a metadata-preserving root copy while excluding runtime pseudo-filesystems and respecting filesystem boundaries.
  4. Write target UUIDs, bind runtime filesystems, enter the target chroot, and rebuild initramfs plus the appropriate GRUB installation.
  5. Stop mutable workloads, perform an offline delta copy, validate again, and make a single controlled boot attempt.
  6. Accept the migration only after the new root identity, services, network, package manager, logs, and a second reboot are healthy.

Assumptions

  • The source is Ubuntu Server 24.04 LTS using a conventional ext4 root filesystem. Encrypted root, ZFS root, bcache, multipath, md RAID, unusual LVM layering, or Secure Boot key changes need a design specific to that stack.
  • The target disk is equal to or larger than the used source data plus operational headroom, and it is not a member of any active volume group, RAID set, mounted filesystem, swap device, or application data path.
  • The operator has hypervisor, cloud recovery, remote management, or physical console access and can explicitly choose either disk in firmware.
  • Applications with transactional state are stopped or exported consistently before the final delta. Copying a live database directory does not create a supported database backup.
  • A separate tested backup exists outside both disks. Keeping the old disk is rollback convenience, not a substitute for backup.
  • The example uses a new GPT layout. On UEFI it creates an EFI System Partition; on legacy BIOS a GPT BIOS boot partition or an existing supported layout must be prepared before `grub-install`.

Key concepts

Filesystem UUID
An identifier stored in filesystem metadata. Using `UUID=` in fstab and the kernel root argument avoids relying on `/dev/sdX` or `/dev/nvmeXnY` names that can change between boots.
Filesystem boundary
A transition from one mounted filesystem to another. `rsync --one-file-system` prevents a root copy from silently traversing separate data, network, container, or pseudo-filesystems.
Pseudo-filesystem
A runtime kernel or process view such as `/proc`, `/sys`, `/dev`, and `/run`. These are mounted for a chroot but are not copied as ordinary persistent files.
Initramfs
The early userspace image loaded with the kernel. It discovers the root device and contains storage, encryption, LVM, RAID, and filesystem support needed before the real root can mount.
Chroot
A process view that treats the copied target directory as `/`. Bind-mounting runtime filesystems lets package and boot tools inspect devices and the running kernel while writing into the target tree.
Offline delta
A final rsync pass after mutable services are stopped. It transfers changes made after the first copy and closes the consistency gap before cutover.
UEFI System Partition
A small FAT filesystem identified as an ESP. UEFI firmware reads boot files from it; it is distinct from the Linux root filesystem and must be mounted at the target `/boot/efi` during installation.

Before you copy

Values used in this guide

{{targetDisk}}

Whole target disk selected by stable hardware identity. Never substitute a partition here.

Example: /dev/disk/by-id/nvme-SAMSUNG_MZQL21T9HCJR-00A07_S64NNX0R123456
{{targetRootPartition}}

New partition that will contain the ext4 root filesystem.

Example: /dev/nvme1n1p2
{{targetEfiPartition}}

New EFI System Partition for UEFI hosts. BIOS hosts use the documented BIOS layout instead.

Example: /dev/nvme1n1p1
{{targetMount}}

Temporary empty directory used as the target root during copy and chroot operations.

Example: /mnt/new-root
{{targetRootUuid}}

Filesystem UUID returned by blkid for the newly formatted root partition.

Example: 9d6f8a67-0f0d-4f5b-b32c-6d9c819e2e31
{{targetEfiUuid}}

FAT volume UUID returned for the target EFI System Partition on UEFI systems.

Example: 4B2A-91F0
{{sourceRootDevice}}

Current root source recorded before migration and used only for comparison and rollback documentation.

Example: /dev/mapper/ubuntu--vg-ubuntu--lv
{{restoredSample}}

Representative protected file restored from the independent backup before and after migration.

Example: etc/ssh/sshd_config

Security and production boundaries

  • Device names are untrusted until correlated with model, serial, size, transport, existing signatures, mount graph, and stable `/dev/disk/by-id` links. Formatting the wrong disk is immediate data loss.
  • The copied tree contains password hashes, host keys, service credentials, tokens, personal data, logs, and private application state. Keep both disks under the same encryption and physical-access policy.
  • A copied host identity can create duplicate SSH host keys, machine IDs, DHCP leases, cluster membership, monitoring identity, and database node identity if both disks or cloned machines run simultaneously.
  • Do not disable Secure Boot, encryption, mandatory access control, or measured-boot policy simply to make the first boot succeed. Stop and adapt the boot path to the existing security boundary.
  • The chroot can modify the target boot configuration and package state. Inspect every mount beneath the target and leave the chroot before unmounting in reverse order.

Stop before continuing if

  • Stop if the target disk identity cannot be proved independently from model, serial, size, existing signatures, mounts, and by-id links.
  • Stop if the system uses an unmodeled root stack such as encryption, RAID, ZFS root, multipath, or separate `/usr` and the required initramfs and boot design is not documented.
  • Stop if there is no tested off-disk backup and no console path for selecting the original disk.
  • Stop if the rsync dry-run crosses an unexpected mount, omits a required filesystem, reports unreadable files, or changes the intended directory nesting.
  • Stop if `fstab`, initramfs, GRUB probing, or chroot validation references the old root for the target boot entry.
  • Stop after any failed first-boot checkpoint. Preserve logs, boot the old disk, and diagnose before modifying either source or target further.
01

verification

Inventory the live root, mounts, boot mode, and candidate disk

read-only

Capture enough stable evidence to distinguish the source, every separate mount, and the unused target before any destructive command is composed.

Why this step matters

A root migration is safe only when the operator understands the current mount and boot topology and can distinguish the target disk from every live device.

What to understand

Record root, boot, EFI, swap, data, network, container, and bind mounts. A separate filesystem must be migrated or retained explicitly rather than disappearing behind `--one-file-system`.

The firmware mode determines GRUB installation. `/sys/firmware/efi` identifies a UEFI boot of the running kernel; its absence normally indicates a legacy BIOS boot.

Capture the package and failed-unit baseline so post-boot comparison does not mistake a pre-existing fault for migration damage.

System changes

  • Writes only the reviewed inventory file under `/root`; it does not alter disks, mounts, boot configuration, or services.

Syntax explained

lsblk -e7 -o ...
Lists block devices with loop devices excluded and includes model, serial, size, filesystem, UUID, and mount relationships.
findmnt -R /
Shows the recursive mount graph below root so separate filesystems and pseudo-filesystems are visible.
findmnt -no SOURCE /
Prints the current root source for rollback documentation without parsing human-oriented output.
Command
sudo sh -c "{ date -u; cat /etc/os-release; uname -r; echo root=\$(findmnt -no SOURCE /); lsblk -e7 -o NAME,PATH,MODEL,SERIAL,SIZE,TYPE,FSTYPE,UUID,MOUNTPOINTS; findmnt -R /; swapon --show; test -d /sys/firmware/efi && echo boot=UEFI || echo boot=BIOS; systemctl --failed --no-pager; } > /root/root-migration-inventory.txt" && sudo cat /root/root-migration-inventory.txt
Example output / evidence
Tue Jul 28 00:15:00 UTC 2026
PRETTY_NAME="Ubuntu 24.04.2 LTS"
root=/dev/mapper/ubuntu--vg-ubuntu--lv
boot=UEFI
0 loaded units listed.

Checkpoint: Approve the source and target identities

sudo cat /root/root-migration-inventory.txt && readlink -f {{targetDisk}}

Continue whenThe current root, firmware mode, every separate mount, and the unused target model/serial/size are documented and independently reviewed.

Stop whenThe target is mounted, contains an active signature, participates in LVM/RAID/swap, or cannot be matched to a stable hardware identity.

If this step fails

The same filesystem appears at multiple paths or several devices back one root.

Likely causeThe host uses bind mounts, overlay filesystems, LVM, RAID, encryption, or a container storage layer not covered by a simple device view.

Safe checks
  • findmnt -R -o TARGET,SOURCE,FSTYPE,OPTIONS /
  • lsblk -f
  • sudo pvs; sudo vgs; sudo lvs

ResolutionDocument the actual stack and switch to a migration method designed for it; do not infer a single physical source from `/dev` naming.

Security notes

  • The inventory may reveal UUIDs, hostnames, topology, and storage serials; keep it root-readable and remove it after the change record is complete.

Alternatives

  • Use provider or hypervisor inventory APIs to corroborate the guest device serial and attachment mapping.

Stop conditions

  • Do not proceed on a guessed target device or an undocumented root stack.
02

warning

Prove backup, restore, console, and old-disk boot recovery

read-only

Test the recovery path before preparing the target. The original disk and a separate backup are different safeguards and both are required.

Why this step matters

Recovery access and an independent backup must work before any destructive target preparation because the migration can expose latent source faults as well as operator errors.

What to understand

Boot recovery media or a provider rescue environment and prove that it can see the original root, network, and backup location.

Create an application-consistent backup outside both disks and restore a representative protected file, not merely a directory listing.

Record the current firmware entry or boot order so an operator can select the original disk without relying on the migrated installation.

System changes

  • Creates backup and restore-test evidence outside the target disk; no source boot configuration changes are made.

Syntax explained

efibootmgr -v
Shows UEFI boot entries and device paths when the running system was booted in UEFI mode.
test -s
Requires the restored sample to exist and contain data before the checkpoint succeeds.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

test -s /root/restore-test/{{restoredSample}} && echo 'restore sample: readable' && { test -d /sys/firmware/efi && sudo efibootmgr -v || echo 'legacy BIOS: record firmware disk order'; }
Example output / evidence
restore sample: readable
BootCurrent: 0003
Boot0003* ubuntu HD(1,GPT,...)/File(\EFI\ubuntu\shimx64.efi)

Checkpoint: Prove recovery before destruction

test -s /root/restore-test/{{restoredSample}} && echo 'restore sample: readable' && { test -d /sys/firmware/efi && sudo efibootmgr -v || echo 'legacy BIOS: record firmware disk order'; }

Continue whenA restored sample is readable and the operator has written evidence for selecting and booting the original disk.

Stop whenThe backup cannot restore, console access is absent, or the original disk cannot be selected independently.

If this step fails

The backup job reports success but the sample restore is empty or unusable.

Likely causeThe wrong backup scope, encryption key, application export, permissions, or retention generation was selected.

Safe checks
  • stat /root/restore-test/{{restoredSample}}
  • file /root/restore-test/{{restoredSample}}
  • sha256sum /root/restore-test/{{restoredSample}}

ResolutionCorrect the backup and repeat the restore drill before touching the target disk.

Security notes

  • Do not store recovery credentials, decryption keys, or backup tokens in the copied root or in shell history.

Alternatives

  • Take an application-consistent provider snapshot only when its restore path has been tested and it resides in a separate failure domain.

Stop conditions

  • No tested restore means no migration approval.
03

warning

Create the target GPT, EFI partition, and ext4 root

danger

After a second target-identity review, erase only the approved target and create the documented UEFI layout. BIOS and custom boot layouts require the matching reviewed plan.

Why this step matters

Partitioning and formatting are the irreversible portion of this workflow, so the command is gated by stable device identity, a signatures review, and an explicit target-only plan.

What to understand

The example creates a 1 GiB FAT32 ESP followed by an ext4 root on a UEFI host. Adjust sizing for a separate `/boot`, swap, recovery, or BIOS boot partition before running anything.

`wipefs -n` is a read-only signatures preview. Any unexpected filesystem, RAID, LVM, encryption, or partition signature is a reason to stop.

The root UUID is generated by the filesystem and recorded after formatting; it must not be copied from the old root.

System changes

  • Replaces the target disk partition table and creates new FAT32 and ext4 filesystems. Existing target data becomes inaccessible.

Syntax explained

wipefs --no-act
Lists signatures without erasing them so the destructive command can be reviewed.
parted --script ... mklabel gpt
Creates a new GPT partition table non-interactively on the exact whole target disk.
mkpart ESP fat32 1MiB 1025MiB
Creates aligned space for a UEFI System Partition while leaving the initial protective area.
mkfs.ext4 -L ubuntu-root
Creates a new ext4 filesystem with a human-readable label; its generated UUID remains the stable boot identity.
Command
Fill variables0/3 ready

Values stay on this page and are never sent or saved.

sudo wipefs --no-act {{targetDisk}} && sudo parted --script {{targetDisk}} -- mklabel gpt mkpart ESP fat32 1MiB 1025MiB set 1 esp on mkpart ubuntu-root ext4 1025MiB 100% && sudo partprobe {{targetDisk}} && sudo mkfs.fat -F 32 -n EFI-SYSTEM {{targetEfiPartition}} && sudo mkfs.ext4 -L ubuntu-root {{targetRootPartition}}
Example output / evidence
Disk {{targetDisk}}: 1.8 TiB
Partition Table: gpt
mkfs.fat 4.2 (2021-01-31)
Creating filesystem with 488112128 4k blocks and 122028032 inodes
Filesystem UUID: 9d6f8a67-0f0d-4f5b-b32c-6d9c819e2e31

Checkpoint: Verify the new target layout

lsblk -f {{targetDisk}} && sudo blkid {{targetRootPartition}} {{targetEfiPartition}}

Continue whenOnly the target disk shows the new GPT partitions; root is ext4 with a unique UUID and the ESP is vfat.

Stop whenThe printed target differs from the approved model/serial, any partition path is ambiguous, or formatting reports an I/O error.

If this step fails

The expected partition nodes do not appear after parted completes.

Likely causeThe kernel has not reread the partition table, the device is busy, or the naming convention differs.

Safe checks
  • sudo partprobe {{targetDisk}}
  • lsblk {{targetDisk}}
  • journalctl -k -n 50 --no-pager

ResolutionStop, unmount only confirmed target users, reread the table, and re-inventory paths. Never substitute a guessed partition name.

Security notes

  • Use `/dev/disk/by-id` where tooling accepts it and confirm the resolved device immediately before the destructive command.

Alternatives

  • Create the target layout from Ubuntu installation or recovery media so the live source cannot keep the target busy.

Stop conditions

  • Do not run parted or mkfs while any target partition is mounted or its identity remains uncertain.
04

command

Mount the target root and target EFI filesystem explicitly

caution

Use a clean temporary hierarchy and prove the backing device for both target mount points before copying data.

Why this step matters

A clean, isolated mount point ensures the destination path cannot accidentally resolve into the source root or hide an earlier incomplete target mount.

What to understand

The target directory must be empty before mounting. `findmnt --target` proves which filesystem backs the path after the mount.

The target ESP is mounted inside the target root so the later chroot writes boot files to the new disk rather than the source ESP.

Do not bind `/dev`, `/proc`, `/sys`, or `/run` yet; the copy step excludes them and the chroot step adds them deliberately.

System changes

  • Mounts the new root and target EFI filesystem below the temporary target directory; persistent fstab is not changed yet.

Syntax explained

install -d -m 0755
Creates explicit target directories with predictable ownership and permissions.
mount --source ... --target ...
Uses unambiguous named options for the exact source and destination.
findmnt --target
Resolves the filesystem that actually backs the target path rather than trusting the shell string.
Command
Fill variables0/3 ready

Values stay on this page and are never sent or saved.

sudo install -d -m 0755 {{targetMount}} && sudo mount --source {{targetRootPartition}} --target {{targetMount}} && sudo install -d -m 0755 {{targetMount}}/boot/efi && sudo mount --source {{targetEfiPartition}} --target {{targetMount}}/boot/efi && findmnt --target {{targetMount}} && findmnt --target {{targetMount}}/boot/efi
Example output / evidence
TARGET          SOURCE           FSTYPE OPTIONS
/mnt/new-root   /dev/nvme1n1p2  ext4   rw,relatime
/mnt/new-root/boot/efi /dev/nvme1n1p1 vfat rw,relatime

Checkpoint: Prove every target mount

findmnt --target {{targetMount}} && findmnt --target {{targetMount}}/boot/efi && df -h {{targetMount}}

Continue whenThe target root partition backs the temporary root, the target EFI partition backs its `/boot/efi`, and capacity exceeds the planned source data plus headroom.

Stop whenEither mount resolves to the source disk, the target directory was non-empty, or capacity is insufficient.

If this step fails

The target mount succeeds but available space is unexpectedly small.

Likely causeThe wrong partition was mounted, partition sizing was incorrect, or reserved filesystem space differs from the plan.

Safe checks
  • findmnt -no SOURCE,FSTYPE,OPTIONS {{targetMount}}
  • lsblk -b {{targetDisk}}
  • sudo tune2fs -l {{targetRootPartition}} | grep -E 'Block count|Reserved block count|Block size'

ResolutionUnmount the target and correct the layout before copying. Do not start with an undersized root.

Security notes

  • Do not mount the target with weakened options merely to complete the copy; preserve the intended production mount policy.

Alternatives

  • Perform all target mounts from recovery media for the cleanest offline boundary.

Stop conditions

  • Stop if `findmnt` does not show the exact approved target devices.
05

verification

Preview the root copy and every exclusion

read-only

Review a metadata-preserving dry-run that stays on the source root filesystem and omits runtime pseudo-filesystems, swap, and the mounted target.

Why this step matters

The itemized dry-run exposes filesystem-boundary, exclusion, metadata, and nesting mistakes before any source content is written to the target.

What to understand

`-a` preserves normal archive metadata but not hard links, ACLs, or xattrs, so `-HAX` is explicit. `--numeric-ids` avoids remapping ownership by account names.

`--one-file-system` keeps the copy on the current root filesystem. Required separate filesystems such as `/home` or `/var` need their own reviewed migration path.

Pseudo-filesystems, the target mount, swap files, and transient paths are excluded. Empty mount-point directories are created later as needed.

The trailing slash on `/` means copy the contents into the target root rather than creating an extra directory level.

System changes

  • Reads source and target metadata and produces an itemized plan; `--dry-run` prevents file transfer.

Syntax explained

-aHAXn
Uses archive mode, preserves hard links, ACLs, and extended attributes, and performs a dry-run.
--numeric-ids
Preserves UID and GID numbers exactly instead of mapping names.
--one-file-system
Prevents traversal into separately mounted filesystems below root.
--itemize-changes
Prints a compact reason code for every planned path creation or metadata/content difference.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo rsync -aHAXn --numeric-ids --one-file-system --itemize-changes --exclude='{{targetMount}}/***' --exclude='/dev/***' --exclude='/proc/***' --exclude='/sys/***' --exclude='/run/***' --exclude='/tmp/***' --exclude='/swapfile' / {{targetMount}}/
Example output / evidence
cd+++++++++ etc/
>f+++++++++ etc/os-release
cd+++++++++ var/
>f+++++++++ var/lib/dpkg/status
Number of files: 184,206 (reg: 142,018, dir: 19,844, link: 22,221, dev: 123)

Checkpoint: Approve the exact transfer plan

sudo rsync -aHAXn --numeric-ids --one-file-system --itemize-changes --exclude='{{targetMount}}/***' --exclude='/dev/***' --exclude='/proc/***' --exclude='/sys/***' --exclude='/run/***' --exclude='/tmp/***' --exclude='/swapfile' / {{targetMount}}/

Continue whenThe plan creates the expected root hierarchy, does not nest `/` under another directory, and contains no target, pseudo-filesystem, or unplanned separate-mount content.

Stop whenAny critical directory is absent, an unexpected mount is traversed, an unreadable file appears, or the destination nesting is wrong.

If this step fails

The dry-run lists the target tree recursively inside itself.

Likely causeThe target is mounted beneath the source root and its exclusion does not match the canonical path.

Safe checks
  • findmnt --target {{targetMount}}
  • realpath {{targetMount}}
  • sudo rsync -n --list-only / {{targetMount}}/ | head -n 30

ResolutionCorrect the exact anchored exclusion or mount the target outside the copied hierarchy from recovery media; never start a self-recursive copy.

Security notes

  • ACL and xattr preservation can fail when destination support or mount options differ; an apparently successful content copy is not sufficient evidence.

Alternatives

  • Use a filesystem-native send/receive or storage replication method when it preserves required metadata and has a tested rollback.

Stop conditions

  • The full dry-run must be reviewed and free of unexplained errors before removing `-n`.
06

command

Perform and verify the bulk metadata-preserving copy

caution

Transfer the approved root hierarchy, preserve the log and exit status, then repeat the dry-run to expose incomplete metadata or persistent read errors.

Why this step matters

The first full transfer moves the bulk of the data while the old root remains the active system, reducing the later outage to a smaller delta and boot cutover.

What to understand

Capture rsync output and exit status. Exit codes 23 or 24 need explanation; they must not be accepted as a complete root.

Do not use `--delete` on the first pass. The target is new, and deletion adds risk without resolving source consistency.

After transfer, compare metadata with another dry-run and inspect representative privileged files, hard links, ACLs, and xattrs.

System changes

  • Creates a metadata-preserving copy of the source root filesystem on the new target without activating it for boot.

Syntax explained

-aHAX
Copies the approved hierarchy and preserves archive metadata, hard links, ACLs, and extended attributes.
--info=progress2,stats2
Reports total transfer progress and final statistics without treating progress output as integrity evidence.
--numeric-ids
Keeps ownership numerically identical, including accounts that may not resolve during recovery.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo rsync -aHAX --numeric-ids --one-file-system --info=progress2,stats2 --exclude='{{targetMount}}/***' --exclude='/dev/***' --exclude='/proc/***' --exclude='/sys/***' --exclude='/run/***' --exclude='/tmp/***' --exclude='/swapfile' / {{targetMount}}/ 2>&1 | sudo tee /root/root-migration-rsync.log
Example output / evidence
184,206 files to consider
146.31G 100% 112.40MB/s 0:22:13 (xfr#142018, to-chk=0/184206)
Number of files: 184,206
Total transferred file size: 146.31G

Checkpoint: Prove the bulk copy is complete

sudo rsync -aHAXn --numeric-ids --one-file-system --itemize-changes --exclude='{{targetMount}}/***' --exclude='/dev/***' --exclude='/proc/***' --exclude='/sys/***' --exclude='/run/***' --exclude='/tmp/***' --exclude='/swapfile' / {{targetMount}}/ | tail -n 30

Continue whenThe verification dry-run shows only explainable changes made after the bulk copy and no persistent metadata or read errors.

Stop whenRsync reports partial transfer, I/O errors, unsupported metadata, vanished persistent files, or an unexpectedly large unexplained delta.

If this step fails

Rsync exits 23 or 24.

Likely causePermissions, I/O faults, active application churn, disappearing files, an excluded mount, or unsupported ACL/xattr operations caused a partial transfer.

Safe checks
  • grep -E 'rsync:|failed:|vanished' /root/root-migration-rsync.log
  • journalctl -k --since '1 hour ago' --no-pager
  • df -h {{targetMount}}; df -i {{targetMount}}

ResolutionPreserve the log, correct the source or destination condition, and repeat the copy. Do not continue to boot configuration with an unexplained partial transfer.

Security notes

  • The target now contains a second complete copy of host secrets; apply encryption and access controls before leaving it unattended.

Alternatives

  • Run the complete copy offline from recovery media when applications cannot be quiesced or source churn is too high.

Stop conditions

  • Do not treat rsync progress reaching 100% as success without exit status and the verification dry-run.
07

config

Write and validate the target UUID-based fstab

caution

Replace only the target root and EFI entries in the copied configuration, preserve the original copy, and validate the target file without rebooting.

Why this step matters

The copied fstab still describes the source layout, so the target must be rewritten with verified UUIDs before any initramfs or GRUB generation.

What to understand

Back up the copied fstab inside the target. Change only entries whose backing filesystem is intentionally replaced; preserve separately retained mounts.

`findmnt --verify --tab-file` checks parsing and device references without rebooting. It does not prove the bootloader can find the root.

Keep root mount options equal to the accepted source policy unless the new filesystem design explicitly changes them.

Use the displayed entries as replacements for the matching root and EFI rows, not as a complete fstab. Retain reviewed entries for separate `/home`, `/var`, swap, network storage, and application filesystems.

System changes

  • Changes only the target copy of `/etc/fstab` and records its original copied version for rollback.

Syntax explained

UUID={{targetRootUuid}}
Selects the target root by filesystem identity rather than an unstable kernel device name.
0 1
Disables dump and schedules the root filesystem for the first filesystem-check pass.
findmnt --verify --tab-file
Parses the target fstab and validates referenced sources without using the live system fstab.
sudoedit
Opens the target copy through the configured privileged editor so the operator can preserve every unrelated reviewed mount entry.
File {{targetMount}}/etc/fstab
Configuration
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

UUID={{targetRootUuid}} / ext4 defaults 0 1
UUID={{targetEfiUuid}} /boot/efi vfat umask=0077 0 1
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo cp --archive {{targetMount}}/etc/fstab {{targetMount}}/etc/fstab.before-root-migration && sudoedit {{targetMount}}/etc/fstab && sudo findmnt --verify --verbose --tab-file {{targetMount}}/etc/fstab
Example output / evidence
Success, no errors or warnings detected
/
   [ ] target exists
/boot/efi
   [ ] target exists

Checkpoint: Validate target filesystem identities

sudo findmnt --verify --verbose --tab-file {{targetMount}}/etc/fstab && grep -E '^[^#].+[[:space:]]/(|boot/efi)[[:space:]]' {{targetMount}}/etc/fstab

Continue whenThe target fstab parses successfully; root refers to the new ext4 UUID and UEFI `/boot/efi` refers to the target ESP UUID.

Stop whenThe old root UUID remains on the target root entry, a required separate mount disappeared, or findmnt reports an error.

If this step fails

findmnt reports an unreachable UUID.

Likely causeThe value was copied incorrectly, the filesystem was reformatted after recording it, or the wrong partition is mounted.

Safe checks
  • sudo blkid {{targetRootPartition}} {{targetEfiPartition}}
  • findmnt --target {{targetMount}}
  • findmnt --target {{targetMount}}/boot/efi

ResolutionRe-read UUIDs from the mounted target devices, correct only the target fstab, and repeat validation.

Security notes

  • Do not weaken mount flags such as `nodev`, `nosuid`, or `noexec` without reviewing application requirements and the original policy.

Alternatives

  • Use systemd native mount units when the environment already manages mounts that way, preserving equivalent ordering and failure semantics.

Stop conditions

  • An invalid or ambiguous target fstab blocks chroot and cutover.
08

warning

Chroot into the target and rebuild initramfs and GRUB

danger

Bind runtime filesystems into the copied tree, rebuild early userspace, generate UUID-aware menu entries, and install GRUB to the target boot path that matches the host firmware mode.

Why this step matters

Rebuilding initramfs and GRUB from inside the target tree makes early boot aware of the target root UUID and writes boot files to the intended target disk.

What to understand

Bind mounts give the chroot access to devices, kernel interfaces, and runtime state. DNS configuration may need an explicit temporary bind on systems where `/etc/resolv.conf` points into `/run`.

On UEFI, mount the target ESP and use `grub-install --target=x86_64-efi --efi-directory=/boot/efi`. On BIOS, install to the whole target disk, never the root partition.

`update-initramfs -u -k all` refreshes installed kernel images. `update-grub` generates menu entries and normally uses root UUID heuristics.

Inspect `grub.cfg` and initramfs metadata after generation; command success alone does not prove that the selected root identity is correct.

System changes

  • Bind-mounts runtime filesystems under the target, rebuilds target initramfs images, generates target GRUB configuration, and installs GRUB boot files to the target boot path.

Syntax explained

mount --rbind /dev
Recursively exposes devices and nested device mounts such as `/dev/pts` inside the target chroot.
mount --make-rslave
Prevents unmount events inside the chroot from propagating back to the live host mount namespace.
update-initramfs -u -k all
Updates initramfs images for installed target kernels so storage and filesystem discovery is available during early boot.
grub-install --target=x86_64-efi
Installs the x86-64 UEFI GRUB files into the mounted target ESP; BIOS systems require the matching platform command.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

for path in dev proc sys run; do sudo mount --rbind "/$path" "{{targetMount}}/$path" && sudo mount --make-rslave "{{targetMount}}/$path"; done && sudo chroot {{targetMount}} sh -c 'update-initramfs -u -k all && update-grub && grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu --recheck'
Example output / evidence
update-initramfs: Generating /boot/initrd.img-6.8.0-71-generic
Found linux image: /boot/vmlinuz-6.8.0-71-generic
Installing for x86_64-efi platform.
Installation finished. No error reported.

Checkpoint: Inspect target boot artifacts

sudo chroot {{targetMount}} sh -c "grub-probe / && grep -R 'root=UUID={{targetRootUuid}}' /boot/grub/grub.cfg | head && lsinitramfs /boot/initrd.img-\$(ls /lib/modules | sort -V | tail -n1) | head"

Continue whenGRUB probes the target filesystem, generated Linux entries contain the target root UUID, and the latest initramfs is readable.

Stop whenGRUB or initramfs references the old root, the target ESP was not mounted, secure-boot requirements are unresolved, or installation targets a partition incorrectly.

If this step fails

grub-install reports that EFI variables are not supported.

Likely causeThe live system booted in BIOS mode, efivarfs is unavailable, or the chroot lacks the required runtime mount.

Safe checks
  • test -d /sys/firmware/efi && echo UEFI || echo BIOS
  • findmnt /sys/firmware/efi/efivars
  • findmnt {{targetMount}}/boot/efi

ResolutionUse recovery media booted in the intended firmware mode, mount efivarfs and the target ESP correctly, or install the documented BIOS target. Do not mix firmware modes accidentally.

Security notes

  • Keep Secure Boot packages and signing policy intact. A bootloader that works only after disabling security controls is not an accepted migration.

Alternatives

  • On cloud images with provider-specific boot tooling, use the provider-supported boot repair process instead of generic GRUB installation.

Stop conditions

  • Do not change firmware order until the target boot artifacts explicitly identify the new root.
09

warning

Stop writers and perform the final offline delta

danger

Enter the maintenance state defined for this host, flush application state, remove chroot bind mounts, and repeat the approved transfer before shutdown.

Why this step matters

Stopping mutable workloads and repeating the transfer closes the gap created during the online bulk copy while keeping the source disk as the authoritative root until shutdown.

What to understand

Place the host in an approved maintenance state and stop databases, queues, container runtimes, and application writers in dependency order.

Run an application-specific flush, checkpoint, or export before stopping where required. A filesystem-level copy cannot invent transactional consistency.

The final rsync may use `--delete` only when the target is proven to be the dedicated new root and the dry-run deletion list is reviewed. The example omits deletion by default.

Unmount chroot bind mounts before the delta so runtime views are never copied into the target.

System changes

  • Stops selected production writers temporarily and updates the target tree with changes made since the bulk copy.

Syntax explained

systemctl isolate rescue.target
Stops most multi-user services while keeping a local recovery shell; use only with confirmed console access.
rsync -aHAX --numeric-ids
Repeats the approved metadata-preserving copy and transfers only changed content.
sync
Requests that dirty filesystem buffers be written before the final shutdown; it is not application consistency by itself.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo systemctl isolate rescue.target && for path in run sys proc dev; do sudo umount -R "{{targetMount}}/$path" 2>/dev/null || true; done && sudo rsync -aHAX --numeric-ids --one-file-system --itemize-changes --exclude='{{targetMount}}/***' --exclude='/dev/***' --exclude='/proc/***' --exclude='/sys/***' --exclude='/run/***' --exclude='/tmp/***' --exclude='/swapfile' / {{targetMount}}/ && sync
Example output / evidence
>f.st...... var/lib/systemd/random-seed
>f.st...... var/log/journal/0f92.../system.journal
sent 28.14M bytes  received 96.02K bytes
rsync exit status: 0

Checkpoint: Approve the offline target

sudo rsync -aHAXn --numeric-ids --one-file-system --itemize-changes --exclude='{{targetMount}}/***' --exclude='/dev/***' --exclude='/proc/***' --exclude='/sys/***' --exclude='/run/***' --exclude='/tmp/***' --exclude='/swapfile' / {{targetMount}}/

Continue whenAfter the offline delta, the verification dry-run has no unexplained persistent changes and all application consistency checks are recorded.

Stop whenA writer is still active, database checks are incomplete, the delta reports errors, or the remaining persistent change set is unexplained.

If this step fails

Files continue changing after services were supposedly stopped.

Likely causeA timer, socket, container, cron job, user process, logging path, or dependent service still writes to the source.

Safe checks
  • systemctl list-timers --all --no-pager
  • systemctl --type=service --state=running --no-pager
  • lsof +D /var/lib/{{application}} 2>/dev/null | head

ResolutionIdentify and stop the writer using the service's supported shutdown procedure, then repeat the final delta and application checkpoint.

Security notes

  • Rescue mode can terminate remote access and monitoring; use it only with working console access and an approved maintenance window.

Alternatives

  • Boot recovery media and perform the entire final sync with the source root mounted read-only.

Stop conditions

  • Do not reboot toward the target while persistent source writes or copy errors remain.
10

verification

Boot the target once and verify root identity plus service health

read-only

Use a one-time firmware boot selection, prove the running root UUID, compare the captured baseline, and boot the target a second time before acceptance.

Why this step matters

A one-time boot selection limits blast radius: the original boot order and disk remain available while the new root proves identity and service health.

What to understand

Use the firmware one-time boot menu or hypervisor boot override for the first attempt rather than immediately removing the source or permanently rewriting order.

On the new system, `findmnt` and the kernel command line must both identify the target root. A successful login alone can still be the old root.

Compare failed units, network addresses, routes, listeners, package database, logs, time, storage space, and application checks against the baseline.

Reboot the target a second time after acceptance checks. A boot that succeeds only once is not sufficient evidence.

System changes

  • Shuts down the source system and asks firmware or the hypervisor to boot the target disk once; persistent source data remains unchanged.

Syntax explained

findmnt -no SOURCE,UUID,FSTYPE,OPTIONS /
Prints the active root source and identity from the newly booted system.
cat /proc/cmdline
Shows the kernel root argument supplied by GRUB and initramfs.
systemctl --failed
Lists failed units for comparison with the recorded source baseline.
Command
findmnt -no SOURCE,UUID,FSTYPE,OPTIONS / && grep -o 'root=[^ ]*' /proc/cmdline && systemctl is-system-running && systemctl --failed --no-pager && ip -brief address && ip route && sudo ss -lntup
Example output / evidence
/dev/nvme1n1p2 9d6f8a67-0f0d-4f5b-b32c-6d9c819e2e31 ext4 rw,relatime
root=UUID=9d6f8a67-0f0d-4f5b-b32c-6d9c819e2e31
running
0 loaded units listed.

Checkpoint: Accept the new root only with evidence

findmnt -no SOURCE,UUID,FSTYPE,OPTIONS / && grep -o 'root=[^ ]*' /proc/cmdline && systemctl --failed --no-pager && ip -brief address && ip route && sudo ss -lntup

Continue whenRoot and kernel command line identify the target UUID, no new failed units appear, expected networking and listeners exist, and application checks pass.

Stop whenThe running root is still the source, any critical unit or network path fails, the filesystem is read-only, or logs show storage errors.

If this step fails

The system boots but `findmnt /` still identifies the old root.

Likely causeFirmware selected the original disk, GRUB chain-loaded the old installation, or the target boot entry still contains the source UUID.

Safe checks
  • findmnt -no SOURCE,UUID /
  • cat /proc/cmdline
  • sudo efibootmgr -v 2>/dev/null || true

ResolutionDo not modify the live old root. Shut down, select the target boot entry explicitly, or repair target GRUB from recovery media.

Security notes

  • Do not run both disks as independent clones on the same network; duplicate host and service identities can violate access and cluster assumptions.

Alternatives

  • Temporarily detach the old disk only after target boot files have been validated and console access can reattach it quickly.

Stop conditions

  • Any critical acceptance failure triggers shutdown and an explicit boot of the original disk.
11

instruction

Retain the original disk through the acceptance window

read-only

Keep the source offline and unchanged until normal workloads, monitoring, backup restore, package operations, logs, and a second reboot prove the target.

Why this step matters

Keeping the original disk unchanged for a defined period creates a fast rollback while monitoring and backup jobs prove that the migration survives normal operations.

What to understand

Retain the source offline to prevent identity conflicts and accidental divergence. Label it with host, date, source UUID, and change record.

Run normal workload, backup, monitoring, package update, and reboot checks from the new root before the acceptance window ends.

Retirement must be a separate approved destructive change. Wiping the source during migration removes the simplest rollback prematurely.

System changes

  • Records acceptance evidence and keeps the source disk offline; no source erase or target boot change occurs in this step.

Syntax explained

journalctl -b -p warning
Shows warnings and more severe messages from the current target boot for storage and service review.
systemctl is-system-running
Summarizes whether systemd considers the boot running, degraded, or still starting.
findmnt --verify
Revalidates the active fstab and mount relationships after the target boot.
Command
systemctl is-system-running && sudo findmnt --verify --verbose && journalctl -b -p warning --no-pager | tail -n 100 && systemctl --failed --no-pager
Example output / evidence
running
Success, no errors or warnings detected
0 loaded units listed.

Checkpoint: Close the acceptance window deliberately

systemctl is-system-running && sudo findmnt --verify --verbose && journalctl -b -p warning --no-pager | tail -n 100 && systemctl --failed --no-pager

Continue whenThe target remains healthy after normal workload and a second reboot, backups restore, monitoring is current, and no unexplained storage warnings remain.

Stop whenBackups, monitoring, package management, reboot, or application recovery has not been proven on the new root.

If this step fails

The host is healthy but backup or monitoring systems still reference the old disk identity.

Likely causeInventory, alert labels, filesystem UUID targets, or recovery documentation were not updated after cutover.

Safe checks
  • findmnt -no UUID /
  • ls -l /dev/disk/by-id/
  • systemctl list-timers --all --no-pager | grep -E 'backup|monitor'

ResolutionUpdate external inventory and jobs, execute a backup plus restore drill, and extend the acceptance window until evidence is complete.

Security notes

  • The offline source still contains current secrets. Store and eventually sanitize it under the same media-handling policy as a production backup.

Alternatives

  • Retain an immutable image or provider snapshot when physical retention of the source disk is impractical and restoration has been tested.

Stop conditions

  • Do not erase or reuse the original disk before formal acceptance and a verified independent backup.

Finish line

Verification checklist

Active root identityfindmnt -no SOURCE,UUID,FSTYPE,OPTIONS /Shows the target root partition, its recorded UUID, ext4, and the approved mount options.
Kernel root argumentgrep -o 'root=[^ ]*' /proc/cmdlineShows `root=UUID=` with the target root UUID.
Mount configurationsudo findmnt --verify --verboseReturns success with no unresolved sources or ordering errors.
System healthsystemctl is-system-running && systemctl --failed --no-pagerReturns running and no new failed units compared with the source baseline.
Storage diagnosticsjournalctl -b -k -p warning --no-pager | tail -n 100Contains no unexplained target I/O, ext4, controller, or timeout warnings.
Backup and reboottest -s /root/post-migration-restore/{{restoredSample}} && uptime -sA post-migration backup restores a readable sample and the target remains healthy after a second boot.

Recovery guidance

Common problems and safe checks

The first boot drops into an initramfs shell and reports that the root UUID does not exist.

Likely causeThe target fstab, generated GRUB command line, or initramfs contains the old UUID, the target storage driver is absent, or the expected partition is not visible.

Safe checks
  • cat /proc/cmdline
  • blkid
  • ls -l /dev/disk/by-uuid
  • cat /etc/fstab

ResolutionBoot the original disk, mount and chroot into the target, correct the target UUID, ensure required storage packages and modules are installed, rebuild every active initramfs, regenerate GRUB, and retry one controlled boot.

Firmware does not list the target disk or immediately starts the original disk.

Likely causeThe ESP was not mounted during installation, the UEFI NVRAM entry was not created, the BIOS core image was installed to the wrong device, or firmware boot order still prefers the source.

Safe checks
  • test -d /sys/firmware/efi && echo UEFI || echo BIOS
  • findmnt /boot/efi
  • efibootmgr -v
  • grub-probe /mnt/new-root

ResolutionKeep the original boot path unchanged. Remount the correct target ESP or identify the whole BIOS disk, reinstall GRUB from the target chroot, inspect the generated entry, and use a one-time firmware boot selection before changing persistent order.

The new root boots but services fail, permissions differ, or applications cannot read protected files.

Likely causeACLs, xattrs, hard links, sparse files, numeric ownership, a separate mount, application state, or mandatory-access-control labels were not transferred or restored as expected.

Safe checks
  • rsync -aHAXn --numeric-ids --one-file-system / /mnt/new-root/
  • getfacl -p /etc /mnt/new-root/etc
  • getfattr -d -m- /etc/ssh/sshd_config /mnt/new-root/etc/ssh/sshd_config
  • systemctl --failed --no-pager

ResolutionBoot the old root, preserve diagnostics, correct the copy scope or metadata support, repeat the offline delta into the target, and do not weaken permissions or security policy to hide an incomplete transfer.

Unmounting the target reports that it is busy.

Likely causeA shell, editor, chroot process, or nested bind mount still has an open reference below the target.

Safe checks
  • findmnt -R /mnt/new-root
  • fuser -vm /mnt/new-root
  • ps -ef | grep '[c]hroot /mnt/new-root'

ResolutionExit the chroot, stop only the identified target-scoped process, and unmount `/run`, `/sys`, `/proc`, `/dev/pts`, `/dev`, `/boot/efi`, then the target root in reverse order. Do not use a lazy unmount to conceal an active process before cutover.

After the procedure

Alternatives and next steps

Consider these alternatives

  • When the root lives entirely in LVM, add a new physical volume and use `pvmove` so the logical volume and filesystem UUID remain unchanged; verify boot placement separately.
  • Use a hypervisor, cloud, SAN, or filesystem block-level migration when it provides application-consistent snapshots, replicated boot metadata, and a tested rollback.
  • Perform a clean Ubuntu installation on the larger disk and restore configuration plus application data when the old system has accumulated unknown packages, unsupported boot customizations, or integrity concerns.
  • Use image-based cloning only when the destination is not smaller, UUID duplication is handled, unused blocks and encryption implications are understood, and expansion is rehearsed.

Operate it safely

  • Keep the original disk offline but unchanged through an agreed acceptance window that includes workload verification, monitoring, backups, patching, and at least one additional reboot.
  • Update monitoring, inventory, recovery documentation, firmware order, disk-health alerts, and asset records with the new model, serial, UUID, and rollback deadline.
  • Run the normal backup job from the new root, restore a representative file to an isolated path, and record evidence before retiring the old disk.
  • If the old disk will be reused, remove duplicate filesystems and sensitive data only after change approval, acceptance completion, and a verified independent backup.

Reference

Frequently asked questions

Why use rsync instead of `cp -a`?

Rsync provides a reviewable dry-run, filesystem-boundary control, explicit ACL/xattr/hard-link preservation, itemized differences, repeatable delta passes, and well-defined exit diagnostics. Those controls make an operational cutover easier to inspect and repeat.

Can this be completed without downtime?

The bulk copy can run online, but a generic root migration still needs a controlled offline or quiesced delta so mutable service state is consistent. Storage- or application-specific replication may shorten that window, but it does not remove acceptance and rollback work.

Should the old and new root have the same UUID?

No for this file-level procedure. A unique target UUID prevents ambiguity while both disks are attached. The target fstab, initramfs, and GRUB configuration are updated to that new identity.

When should I prefer a clean installation?

Prefer a clean installation when the source is unsupported, compromised, poorly inventoried, or built on an unclear storage and boot stack. Restore only reviewed configuration and application data into the new baseline.

Recovery

Rollback

Shut the target down and boot the unchanged original disk explicitly; do not attempt an in-place repair while critical services are running from an uncertain root.

  1. From console or firmware, power off the failed target boot and select the original disk's known-good entry.
  2. After the old root boots, confirm `findmnt /`, networking, services, application state, and monitoring before reopening traffic.
  3. Preserve the failed target disk, boot logs, initramfs output, GRUB configuration, fstab, rsync log, and device inventory for diagnosis.
  4. Correct the target while it is mounted below a recovery environment; repeat fstab, initramfs, GRUB, offline delta, and one-time boot checkpoints.
  5. Do not erase either disk until the change owner accepts a stable target and an independent restore has passed.

Evidence

Sources and review

Verified 2026-07-24Review due 2026-10-22
rsync 3.4.4 manualofficialUbuntu grub-install manualofficialUbuntu update-initramfs manualofficialfstab Linux manual pageofficialUbuntu parted manualofficial