Copy an XFS Filesystem Safely with xfs_copy
You will finish with a sector-independent copy of an XFS filesystem on another device or in an image file. The copy gets a new filesystem UUID, so it can be used as a separate filesystem without colliding with its source. Allow 15 to 30 minutes for preparation and checking, plus the time needed to read the filesystem.
The route
Jump straight to the step you need, or tick off Done means at the end.
The examples here use xfs_copy 6.6.0 from xfsprogs 6.6.0-1ubuntu2.1. You need an XFS source, a target with enough capacity, and permission to read the source and write the target. Writing a real block device normally requires elevated privileges.
Warning
A target device is overwritten. Confirm its identity twice before running the copy. The source must be unmounted, mounted read-only, or frozen. Copying a normally mounted, writable filesystem can produce an inconsistent or corrupt result.
1. Check the installed command
This is an ordinary, read-only check. It does not need sudo:
$ xfs_copy -V
xfs_copy version 6.6.0
$ dpkg-query -W -f='${Package} ${Version}\n' xfsprogs
xfsprogs 6.6.0-1ubuntu2.1
Your version may differ. Read the local manual for the installed version before copying a production filesystem, especially if the command came from another distribution.
2. Choose and verify the source and target
Set explicit shell variables for the paths. Replace the placeholders with the paths from your change plan. A regular file target becomes a filesystem image; a device target receives a filesystem directly.
$ SOURCE=/dev/mapper/vg0-data
$ TARGET=/dev/mapper/vg0-data-copy
$ printf 'source: '; readlink -f "$SOURCE"
$ printf 'target: '; readlink -f "$TARGET"
$ lsblk -o NAME,PATH,SIZE,FSTYPE,MOUNTPOINTS "$SOURCE" "$TARGET"
Stop if either path is not the object you expect. Do not use a mounted target. If the target is a file, choose a new pathname and check the filesystem holding it has room. The image has the source filesystem's logical size, although an image file on XFS can consume roughly the source's used data and log space because free blocks are skipped and sparse files are efficient.
Checkpoint
Write down the source and target paths. A typo at this point is more dangerous than a typo in an option.
3. Put the source in a consistent state
The safest choices are an unmounted source or a read-only mount. If the filesystem must remain mounted, freeze it for the copy. Freezing blocks new modifications and flushes pending data, metadata and log information, so this can pause applications using that mount.
$ sudo xfs_freeze -f /srv/data
$ sudo xfs_copy "$SOURCE" "$TARGET"
$ sudo xfs_freeze -u /srv/data
Keep the unfreeze command ready before starting. If the copy fails, unfreeze the source once you have captured the error and log path. Do not leave a live service blocked while investigating a copy failure.
If you can unmount the source instead, do that through the service's normal shutdown and mount-management procedure. Do not guess which processes are safe to stop. A read-only mount still needs to be a genuinely read-only view for the whole copy.
4. Copy to one target
With an unmounted, read-only or frozen source, run the copy. This command changes the target and may need elevated privileges:
$ sudo xfs_copy -L /var/tmp/xfs-copy-data.log "$SOURCE" "$TARGET"
source filesystem copied successfully
The exact progress and success text can vary. The useful result is exit status 0:
$ printf 'exit status: %s\n' "$?"
exit status: 0
xfs_copy uses synchronous writes and records diagnostics to standard error and its log. By default the log is a generated file under /var/tmp; -L gives you a predictable location. Keep that log with the change record until the target has been checked.
5. Copy to several targets in parallel
You can pass more than one target. The command writes them in parallel, creating one additional thread for each target:
$ sudo xfs_copy -L /var/tmp/xfs-copy-2026-09-28.log \
"$SOURCE" \
/dev/mapper/vg0-data-copy-a \
/dev/mapper/vg0-data-copy-b
Parallel output does not make target checks optional. A write error aborts that target while other copies continue. The command exits with status 1 if any target fails, even when another target succeeds. Inspect the log and treat each target as a separate result.
6. Use an image file when that is the right target
A file target is useful for an image workflow or for moving the copy through storage that is not a block device:
$ IMAGE=/srv/images/data-copy.xfs
$ sudo xfs_copy -b -L /var/tmp/xfs-copy-image.log "$SOURCE" "$IMAGE"
$ ls -lh "$IMAGE"
$ file "$IMAGE"
The -b option selects buffered I/O so direct I/O is not attempted on target filesystems that do not support it. It does not make the source safe to copy while it is changing. The output file is created if it does not exist, so check the name first and never point it at a valuable existing file without an explicit replacement plan.
7. Understand the UUID and clone boundary
Normally, each new target is identical in filesystem content but receives a new unique filesystem identifier. That is what you want when the source and copy will be mounted as separate filesystems. Verify the identifiers with an XFS inspection tool before mounting both in the same host environment:
$ sudo xfs_info "$SOURCE" | grep -E 'meta-data=.*uuid'
$ sudo xfs_info "$TARGET" | grep -E 'meta-data=.*uuid'
The formatting of xfs_info output is host-specific. Confirm that the target is recognised as XFS and that the UUID values are different. If your workflow needs a true duplicate UUID, use xfs_copy -d only when the new filesystem replaces the original, such as a disk replacement. Do not use -d for two independently mounted copies.
8. Handle the common boundaries
xfs_copy does not copy an XFS filesystem with a real-time section or an external log. It will abort with an error. Check the filesystem design before scheduling a long copy; if either feature is present, use a workflow designed for it rather than forcing a block-level substitute.
For a source that is much smaller than a replacement disk and will later be grown, the manual recommends mkfs.xfs followed by xfsdump and xfsrestore instead. That workflow can produce a better layout than copying and then using xfs_growfs. This is a performance and layout decision, not a reason to ignore the source-consistency rule.
When a target fails, check the exact target named in the diagnostic, its writable state and available capacity. A failed target may contain an incomplete filesystem, so do not mount or reuse it as if the copy had succeeded. Correct the cause, clear or replace the target deliberately, and rerun the copy. The source itself is not altered by xfs_copy.
Done means
- The installed
xfs_copyversion and package were recorded. - The source was unmounted, read-only or frozen for the entire copy.
- Every target path was checked and any destructive overwrite was authorised.
- The command returned exit status 0 for each required target and its log was retained.
- The target is recognised as XFS and has a new UUID unless this is an intentional replacement clone.
- Any frozen source was unfrozen, and failed or incomplete targets were not mounted as valid copies.