Bug 287679 - md(4) assigns non-unique GEOM::ident to vnode-based disks
Summary: md(4) assigns non-unique GEOM::ident to vnode-based disks
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Many People
Assignee: Mark Johnston
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-06-20 14:39 UTC by Phil Krylov
Modified: 2025-07-09 00:46 UTC (History)
3 users (show)

See Also:


Attachments
Minimal but changes struct layout with unknown impact (320 bytes, patch)
2025-06-20 14:39 UTC, Phil Krylov
no flags Details | Diff
Simple patch (1.47 KB, patch)
2025-06-20 14:40 UTC, Phil Krylov
no flags Details | Diff
A more invasive patch (1.55 KB, patch)
2025-06-20 14:41 UTC, Phil Krylov
no flags Details | Diff
Optimized patch (1.41 KB, patch)
2025-06-20 14:41 UTC, Phil Krylov
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Phil Krylov 2025-06-20 14:39:34 UTC
Created attachment 261438 [details]
Minimal but changes struct layout with unknown impact

In review D12230, support for GEOM::ident was added to vnode-backed md(4) devices. The message is saying, "This is useful for gmountver(8) regression tests."

At first, the identifier was generated as random, then, in an effort to improve uniqueness, it was changed to MD-DEV<fsid>-INO<fileid>, and merged in this state.

It's worth to notice that the buffer for this value is only 32 bytes long. Unfortunately, on a 64-bit system with ZFS, such identifier immediately gets truncated around the first digit of <fileid>, making its uniqueness much worse than random:

# ls -i /root/disk*
29580 /root/disk1
29828 /root/disk2
# mdconfig /root/disk1
md0
# mdconfig /root/disk2
md1
# geom md list | grep -E 'name|file|ident'
Geom name: md0
   file: /root/disk1
   ident: MD-DEV11968766667392717182-INO2
Geom name: md1
   file: /root/disk2
   ident: MD-DEV11968766667392717182-INO2

[Hmm, I'd like to have a look at those gmountver(8) regression tests, are they public?]

So, I see a number of solutions here.

1) md-ident-fix-minimal-but-changes-struct-layout.patch: Updates the buffer size to fit two UINT64_MAX decimal representations (51 bytes, rounded up to 64 bytes). Seems to work well, but I am not familiar enough with this code to suggest changing the struct layout: 

# geom md list | grep -E 'name|file|ident'
Geom name: md0
   file: /root/disk1
   ident: MD-DEV11968766667392717182-INO29580
Geom name: md1
   file: /root/disk2
   ident: MD-DEV11968766667392717182-INO29828

2) md-ident-fix-simple.patch: A little bit ugly. Via kvprintf's %r conversion specifier, uses base r36 to fit two 64-bit values in 26 bytes and have 5 more bytes left for our namespacing pleasure:

# geom md list | grep -E 'name|file|ident'
Geom name: md0
   file: /root/disk1
   ident: MD-2IXL9OT1ZWGAM-MTO
Geom name: md1
   file: /root/disk2
   ident: MD-2IXL9OT1ZWGAM-N0K

3) md-ident-fix-invasive.patch: A little less ugly, but adds another undocumented conversion specifier (%R) to kvprintf() to skip an extra uppercasing loop.

4) md-ident-fix-fast.patch: An ugly but speed-optimized solution which also has the benefit of touching less code parts than 2) and 3), but serializes the numbers in little-endian order:

# geom md list | grep -E 'name|file|ident'
Geom name: md0
   file: /root/disk1
   ident: MD-MAGWZ1TO9LXI2-OTM
Geom name: md1
   file: /root/disk2
   ident: MD-MAGWZ1TO9LXI2-K0N

I hope this helps.
Comment 1 Phil Krylov 2025-06-20 14:40:18 UTC
Created attachment 261439 [details]
Simple patch
Comment 2 Phil Krylov 2025-06-20 14:41:04 UTC
Created attachment 261440 [details]
A more invasive patch
Comment 3 Phil Krylov 2025-06-20 14:41:34 UTC
Created attachment 261441 [details]
Optimized patch
Comment 4 Konstantin Belousov freebsd_committer freebsd_triage 2025-06-20 14:51:41 UTC
Lets go with md-ident-fix-simple.patch.  Why do we need to upper-case the ident?
Comment 5 Mark Johnston freebsd_committer freebsd_triage 2025-06-20 14:52:32 UTC
Changing the struct layout is fine.  Most consumers handle a buffer of size DISK_IDENT_SIZE (256 bytes) for GEOM::ident.  I think you could reasonably use that buffer size here too.
Comment 6 Phil Krylov 2025-06-20 14:58:15 UTC
(In reply to Konstantin Belousov from comment #4)
> Why do we need to upper-case the ident?

That's how these idents look on real hard drives.
Comment 7 commit-hook freebsd_committer freebsd_triage 2025-06-25 22:32:13 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=5286b96c56ff5aa3c1cee824ab8564f0ffffc381

commit 5286b96c56ff5aa3c1cee824ab8564f0ffffc381
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-06-25 21:12:33 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-06-25 21:20:45 +0000

    md: Use a larger buffer for the ident string

    With the old size, the string could easily be truncated, resulting in
    non-unique identifiers.

    PR:             287679
    Reported by:    Phil Krylov <phil@krylov.eu>
    Reviewed by:    kib
    MFC after:      2 weeks

 sys/dev/md/md.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 8 Mark Johnston freebsd_committer freebsd_triage 2025-06-25 22:34:17 UTC
I went ahead and simply increased the buffer size.  There is one md_s structure per md device, so the memory overhead isn't too significant, and the new buffer size is still small relative to the total structure size.
Comment 9 commit-hook freebsd_committer freebsd_triage 2025-07-09 00:45:40 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=5098a5b48357d4d51ad8369330d292e6bbd7490e

commit 5098a5b48357d4d51ad8369330d292e6bbd7490e
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-06-25 21:12:33 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-07-09 00:44:18 +0000

    md: Use a larger buffer for the ident string

    With the old size, the string could easily be truncated, resulting in
    non-unique identifiers.

    PR:             287679
    Reported by:    Phil Krylov <phil@krylov.eu>
    Reviewed by:    kib
    MFC after:      2 weeks

    (cherry picked from commit 5286b96c56ff5aa3c1cee824ab8564f0ffffc381)

 sys/dev/md/md.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)