#3562 PR merged: Partuuid recovery¶
Labels: enhancement, fixed / solved / done
svlv opened issue at 2026-02-05 13:03:¶
Relax-and-Recover (ReaR) Pull Request Template¶
Please fill in the following items before submitting a new pull request:
Pull Request Details:¶
-
Type: Enhancement
-
Impact: Normal
-
Reference to related issue (URL):
-
How was this pull request tested?
The patch was tested over several months on multiple distributions and versions (RHEL, CentOS, Debian, Ubuntu) running on either EFI/GPT or BIOS/MBR, or BIOS+EFI/GPT.
For GPT partition tables,PARTUUIDs are successfully backed up and restored. For MBR partition tables, the patch makes no changes. I haven't encountered any issue with this patch (at least none that were visible to me). -
Description of the changes in this pull request:
Fixes https://github.com/rear/rear/issues/3561.
During backup, thePARTUUIDvalues are added tolayout/disklayout.conf. During recovery, these values are used to restorePARTUUIDs by runningsgdisk --partition-guid=<partguid> <dev>.
Ifsgdiskis not available or no validPARTUUIDvalue is present, this step is skipped because it is treated as optional.
PARTUUIDis added at the end of partition parameters because, in our setup, ReaR scripts are separated from the layout information. This is done for backward compatibility with previous ReaR scripts versions (I hope it is acceptable).
jsmeix commented at 2026-02-05 15:07:¶
@rear/contributors
please have a look here and review it (as time permits).
jsmeix commented at 2026-02-09 11:06:¶
@rear/contributors
all looks good now to me from plain looking at the code
so I would like to merge it on Thursday afternoon.
Please have a look here and review it (as time permits).
jsmeix commented at 2026-02-09 12:01:¶
@svlv
I would like to add some remarks and questions
about optional "cosmetic" naming issues
which are mostly my personal preference
so nothing is wrong with your current code.
It me it looks as if "partuuid"
written as partuuid or PARTUUID
is the proper name for what that is about
so I think this proper name should be used
consistently everywhere when that thingy is meant.
So I am wondering if the current functions
get_partition_guid() and set_partition_guid()
shouldn't be better named
get_partuuid() and set_partuuid()
?
Within those functions the locally used variable names
look meaningless and confusing to me.
I am wondering what a device versus a disk
actually is within the context of that functions.
I am also wondering what a guid is in contrast
to a partuuid - are they different or the same thing?
Cf. the section "Code must be easy to read" in
https://github.com/rear/rear/wiki/Coding-Style
According to how I understand those functions
from plain looking at the code I think
those functions are meant to do this:
get_partuuid() {
local partition_device=$1
local partuuid=""
if has_binary blkid; then
partuuid="$( blkid -s PARTUUID -o value "$partition_device" )"
# Fallback for cases when blkid is not available
elif [ -d /dev/disk/by-partuuid ]; then
local partition_symlink
for partition_symlink in /dev/disk/by-partuuid/*; do
if [ -h "$partition_symlink" ] && [ "$( readlink -f "$partition_symlink" )" = "$partition_device" ]; then
partuuid="${partition_symlink#/dev/disk/by-partuuid/}"
break
fi
done
fi
echo "$partuuid"
}
set_partuuid() {
local disk=$1
local partnum=$2
local partuuid=$3
if has_binary sgdisk; then
sgdisk --partition-guid="$partnum":"$partuuid" "$disk"
fi
}
I removed a 2>/dev/null because I assume
it is not needed, cf. the section
"What to do with stdin, stdout, and stderr" in
https://github.com/rear/rear/wiki/Coding-Style
I wonder if [ -h "$partition_symlink" ] is really reeded?
Couldn't
[ "$( readlink -f "$partition_symlink" )" = "$partition_device" ]
alone be good enough?
I wonder why readlink -f and not readlink -e ?
On my workstation it also works with readlink -e
so I wonder why not "all components must exist"
but only "all but the last component must exist"
cf. "man readlink".
Or do I misunderstand what those functions are meant to do?
By the way:
I know we have many such meaningless and confusing
variable names all over the place in existing ReaR code.
For example right now I had a look at
layout/prepare/GNU/Linux/100_include_partition_code.sh
and got immediately totally confused what device
versus disk means therein :-(
That (old) code is so confusing to me because of its bad
variable names that I won't dare to touch it to clean it up.
svlv commented at 2026-02-09 13:16:¶
@jsmeix
Regarding partition GUID vs. PARTUUID naming, I totally agree that it
would be better to choose a single term.
While reading articles and comments on this topic, I noticed that the
term partition GUID is quite commonly used ,
even GPT stands for GUID Partition Table, not UUID Partition Table.
That's why, in my initial draft, I named the functions
get_partition_guid and set_partition_guid. Later, during testing and
further investigation, I mostly used PARTUUID variant in tools like
blkid and lsblk, this led me to the conclusion that PARTUUIDs
would be more clear for users, since it is used in the util-linux
package and the /dev/disk/by-partuuid/ directory.
Did I consider unifying the naming and choosing just one term? Yes. However, I decided to leave it as is, since I wasn't sure that anyone would care about it. Personally, I'm more or less fine with non-unified naming, because renaming always takes some extra time.
I wonder if [ -h "$partition_symlink" ] is really reeded?
It can be removed, I mainly used it as a reminder that enries
/dev/disk/by-partuuid/ are supposed to be symlinks.
I wonder why readlink -f and not readlink -e ?
Because I don't use the resolved link afterward to do something with it,
e.g., to refer a device. I only use the path itself. But agree,
readlink -e is safer and it's probably the better choice here.
Or do I misunderstand what those functions are meant to do?
You got it correctly.
I'll fix your comments when I have time.
jsmeix commented at 2026-02-09 14:31:¶
Only out of curiosity:
Now I got interested in "GUID" versus "UUID":
The "ultimate answer to everything" ;-) tells
https://en.wikipedia.org/wiki/Universally_unique_identifier
A universally unique identifier (UUID) is a 128-bit number
used to identify information in computer systems.
The term globally unique identifier (GUID) is also used,
typically in software created by Microsoft
[https://www.rfc-editor.org/rfc/rfc4122]
I further asked Google AI
why is it called "GUID Partition Table"
and not "UUID Partition Table" ?
and got this reply (excerpts):
The Origins: Microsoft and Intel
The term GUID (Globally Unique Identifier) was popularized
by Microsoft and is heavily baked into the Windows ecosystem
and the Component Object Model (COM).
When Intel was developing the EFI (Extensible Firmware
Interface) specification in the late 990s - which eventually
became UEFI - they worked closely with Microsoft.
...
Technically, a GUID is a specific implementation of the
broader UUID (Universally Unique Identifier) standard.
jsmeix commented at 2026-02-10 13:12:¶
@svlv
thank you.
Much appreciated!
pcahyna commented at 2026-02-11 17:51:¶
Thank you, more faithful restoration of layout is always better.
I am afraid though that you need to change more than
usr/share/rear/layout/prepare/GNU/Linux/100_include_partition_code.sh.
Quick search reveals that the format of the partition entries in
disklayout is also used in at least:
usr/share/rear/layout/prepare/default/420_autoresize_last_partitions.sh
usr/share/rear/layout/prepare/default/430_autoresize_all_partitions.sh
usr/share/rear/layout/prepare/default/319_rename_xfs_configs.sh (these
three look important),
usr/share/rear/layout/save/default/950_verify_disklayout_file.sh
usr/share/rear/lib/layout-functions.sh (probably less important).
svlv commented at 2026-02-12 07:43:¶
Thanks @pcahyna. It is a good point. I'll fix it when I have time
svlv commented at 2026-02-12 13:13:¶
I am afraid though that you need to change more than usr/share/rear/layout/prepare/GNU/Linux/100_include_partition_code.sh. Quick search reveals that the format of the partition entries in disklayout is also used in at least: usr/share/rear/layout/prepare/default/420_autoresize_last_partitions.sh usr/share/rear/layout/prepare/default/430_autoresize_all_partitions.sh usr/share/rear/layout/prepare/default/319_rename_xfs_configs.sh (these three look important), usr/share/rear/layout/save/default/950_verify_disklayout_file.sh usr/share/rear/lib/layout-functions.sh (probably less important).
Corrected:
usr/share/rear/layout/prepare/default/420_autoresize_last_partitions.shusr/share/rear/layout/prepare/default/430_autoresize_all_partitions.shusr/share/rear/layout/prepare/default/319_rename_xfs_configs.shusr/share/rear/lib/layout-functions.sh
In usr/share/rear/layout/save/default/950_verify_disklayout_file.sh,
PARTUUIDs were left in junk.
The changes were tested by restoring to a bigger disk with the default
AUTORESIZE_PARTITIONS and when AUTORESIZE_PARTITIONS=true to test
changes in 430_autoresize_all_partitions.sh
svlv commented at 2026-02-14 08:30:¶
I've reviewed 420_autoresize_last_partitions.sh one more time and
noticed that for raid0 one important update it still required.
svlv commented at 2026-02-16 08:26:¶
Fixed finding part entries for RAID0 and RAID1 to auto-resize them.
Tested manually on Debian 13 with RAID0. The system uses two 10GB disks and is migrated into two 12GB disks.
Before the migration:
lsblk -o NAME,FSTYPE,UUID,PARTUUID,SIZE,MOUNTPOINTS
NAME FSTYPE UUID PARTUUID SIZE MOUNTPOINTS
sr0 1024M
vda 10G
├─vda1 vfat AED2-8E94 25896747-0b2f-4ab1-8f08-bcd96c8a852e 953M /boot/efi
└─vda2 linux_raid_member 1321c636-e080-979c-49dd-5cc43b2f4861 58810dc1-f22d-48b5-bead-62b4d9e2ab1b 9.1G
└─md0 ext4 f7e1c368-cf94-4955-88d8-10f20c54cabb 19G /
vdb 10G
└─vdb1 linux_raid_member 1321c636-e080-979c-49dd-5cc43b2f4861 6e1d9c2b-1a31-443d-a492-0108abe98012 10G
└─md0 ext4 f7e1c368-cf94-4955-88d8-10f20c54cabb 19G /
After the migration:
lsblk -o NAME,FSTYPE,UUID,PARTUUID,SIZE,MOUNTPOINTS
NAME FSTYPE UUID PARTUUID SIZE MOUNTPOINTS
sr0 iso9660 2026-02-14-17-46-44-00 271.7M
vda 12G
├─vda1 vfat AED2-8E94 25896747-0b2f-4ab1-8f08-bcd96c8a852e 953M /boot/efi
└─vda2 linux_raid_member 1321c636-e080-979c-49dd-5cc43b2f4861 58810dc1-f22d-48b5-bead-62b4d9e2ab1b 11.1G
└─md0 ext4 f7e1c368-cf94-4955-88d8-10f20c54cabb 23G /
vdb 12G
└─vdb1 linux_raid_member 1321c636-e080-979c-49dd-5cc43b2f4861 6e1d9c2b-1a31-443d-a492-0108abe98012 12G
└─md0 ext4 f7e1c368-cf94-4955-88d8-10f20c54cabb
svlv commented at 2026-02-17 07:11:¶
I've additionally tested autoresize for RAID1 - no issues with parsing
part entries.
Please let me know if anything else is required from my side.
jsmeix commented at 2026-02-24 14:25:¶
@rear/contributors
there is a false alarm of Codacy Static Code Analysis
https://github.com/rear/rear/pull/3562/checks?check_run_id=63720542563
How can I mark this specific alarm as false
so that it will not appear again at this code place?
See
https://github.com/rear/rear/pull/3562/changes
what it is about:
In usr/share/rear/lib/layout-functions.sh
this is added
# The regex defines the expected PARTUUID format.
# Pseudo-UUIDs (not RFC 4122–compliant) are intentionally allowed, as they can
# be manually assigned as PARTUUID using sgdisk. sgdisk primarily validates
# the length.
PARTUUID_REGEX="(no-partuuid|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"
Of course PARTUUID_REGEX is not used in
usr/share/rear/lib/layout-functions.sh
It is only set here as a global variable
which is used in other scripts.
jsmeix commented at 2026-02-24 14:29:¶
@rear/contributors
I would like to merge it next Monday (02. March) afternoon
unless there are objections.
Please have a look and review it (as time permits).
gdha commented at 2026-02-24 14:32:¶
@rear/contributors
there is a false alarm of Codacy Static Code Analysis https://github.com/rear/rear/pull/3562/checks?check_run_id=63720542563
How can I mark this specific alarm as false so that it will not appear again at this code place?
See https://github.com/rear/rear/pull/3562/changes what it is about: In usr/share/rear/lib/layout-functions.sh this is added
# The regex defines the expected PARTUUID format. # Pseudo-UUIDs (not RFC 4122–compliant) are intentionally allowed, as they can # be manually assigned as PARTUUID using sgdisk. sgdisk primarily validates # the length. PARTUUID_REGEX="(no-partuuid|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"Of course PARTUUID_REGEX is not used in usr/share/rear/lib/layout-functions.sh It is only set here as a global variable which is used in other scripts.
@jsmeix marked this issue as "false positive" in Codacy https://app.codacy.com/gh/rear/rear/pull-requests/3562/issues#issue-f8e82ff46f7010d94e11fc4206ec4e2c
svlv commented at 2026-02-24 14:34:¶
@jsmeix and @gdha
I can also add # shellcheck disable=SC2034 above the variable if it is
desirable.
jsmeix commented at 2026-02-24 15:48:¶
@gdha
seems I am somewhat blind but I fail to see how I could
mark an issue as "false positive" in Codacy
or can only you do that?
pcahyna commented at 2026-02-24 15:55:¶
@jsmeix and @gdha
I can also add
# shellcheck disable=SC2034above the variable if it is desirable.
Thanks for the proposal, but I don't think we should litter the code with such comments. Instead we should configure the tools to not report false positives (and am I right that warnings are reported only once and on subsequent PRs that do not touch this code line they don't appear again?)
svlv commented at 2026-02-27 12:47:¶
I've re-tested a fallback for getting PARTUUIDs for cases when blkid
is not available.
I know that blkid is put to the REQUIRED_PROGS array in
default.conf, however, particularly for getting PARTUUID there is a
fallback. To test the fallback I remaned blkid and removed it from the
REQUIRED_PROGS array.
Just in case if blkid will be removed from REQUIRED_PROGS in the
future
jsmeix commented at 2026-03-02 12:38:¶
@pcahyna
is it OK for you to be merged?
If yes, please approve it.
pcahyna commented at 2026-03-02 15:18:¶
Hi @svlv , the changes are fine, I would just like to do reshuffle the diffs a bit, see https://github.com/rear/rear/pull/3562/changes#r2794621337 and also some commits could be squashed together (you are introducing a new file, then you remove it).
If you don't mind I will do that myself, I often look at the git history and prefer to have it clean.
svlv commented at 2026-03-02 15:22:¶
@pcahyna
Yes, sure, please do it. Thank you
pcahyna commented at 2026-03-02 15:25:¶
@svlv by the way, I am just curious, is there a reason why to care about blkid not being available? It is part of util-linux, so a pretty basic utility, and we call it unconditionally at other places already, although a failure there is possibly not fatal.
Of course defensive programming is not bad at all, I just would like to know if you have a special reason for this.
pcahyna commented at 2026-03-02 15:36:¶
@svlv by the way, thank you for the thorough updates of all the places
where the layout file is being used. What did you use to find them? I
simply searched the code for the string ^part (not pattern, the
literal string), assuming that any processing of the layout file that
needs partition entries will use grep ^part or awk /^part/.
Hopefully that's enough...
svlv commented at 2026-03-02 15:45:¶
@pcahyna
I was curious how to get PARTUUID without blkid, relying on
/dev/disk/by-partuuid only.
Yes, I'm aware that blkid is part of GNU util-linux, but when you
are building util-linux package from source you may decide not to
build blkid.
After testing it on some systems (RHEL 7, 8, 9, 10) I decided to leave
this fallback because I though it might be useful for other individuals
who want to minimise REQUIRED_PROGS array as much as possible.
svlv commented at 2026-03-02 15:54:¶
What did you use to find them?
I used rg "\^part" and looked through the code where LAYOUT_FILE is
used.
pcahyna commented at 2026-03-02 16:12:¶
@pcahyna
Yes, sure, please do it. Thank you
Hmm it seems I am not allowed to commit to your branch. Perhaps it is because it is not in a personal fork, or you have not granted the permissions? https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork
I pushed it to my fork: https://github.com/pcahyna/rear/tree/partuuid-recovery , please reset your branch to it and force-push.
svlv commented at 2026-03-03 09:09:¶
By the way, all of these commits could be squashed. Re-writing git history made sense only if you wanted to keep them.
pcahyna commented at 2026-03-03 10:46:¶
@svlv of course I want to preserve the commits :-)
pcahyna commented at 2026-03-03 10:52:¶
Merging, thanks a lot for all the work!
[Export of Github issue for rear/rear.]