[PATCH] nvme: make providing NGUID as UUID usage less scary
AlanCui4080
me at alancui.cc
Mon May 11 00:59:28 PDT 2026
Hi,
On Monday, 11 May 2026 06:19,you wrote:
> TBH, I'm not sure why should this be a warning or an info log. This
> looks like a debug print to me.
>
> Keith WDYT?
By the way, current way how kernel generate UUID by NGUID is
not compliant with RFC 4122 and NVMe spec.
[alan at AlanArchDesktop ~]$ cat /sys/block/nvme0n1/uuid
00000000-0000-0000-a428-xxxxxxxxxxxx
[alan at AlanArchDesktop ~]$ cat /sys/block/nvme0n1/nguid
00000000-0000-0000-a428-xxxxxxxxxxxx
And according to NVMe 1.4 spec 7.10.6 UUID
The Universally Unique Identifier is defined in RFC4122 and con-
tained in the Namespace Identification Descriptor
So,
According to RFC 4122 4.3 Algorithm for Creating a Name-Based UUID:
> The version 3 or 5 UUID is meant for generating UUIDs from "names"
> that are drawn from, and unique within, some "name space". The
> concept of name and name space should be broadly construed, and not
> limited to textual names. For example, some name spaces are the
> domain name system, URLs, ISO Object IDs (OIDs), X.500 Distinguished
> Names (DNs), and reserved words in a programming language. The
> mechanisms or conventions used for allocating names and ensuring
> their uniqueness within their name spaces are beyond the scope of
> this specification.
...
> The algorithm for generating a UUID from a name and a name space are
> as follows:
> o Allocate a UUID to use as a "name space ID" for all UUIDs
> generated from names in that name space; see Appendix C for some
> pre-defined values.
> o Choose either MD5 [4] or SHA-1 [8] as the hash algorithm; If
> backward compatibility is not an issue, SHA-1 is preferred.
> o Convert the name to a canonical sequence of octets (as defined by
> the standards or conventions of its name space); put the name
> space ID in network byte order.
> o Compute the hash of the name space ID concatenated with the name.
> o Set octts zero through 3 of the time_low field to octets zero
> through 3 of the hash.
> o Set octets zero and one of the time_mid field to octets 4 and 5 of
> the hash.
> o Set octets zero and one of the time_hi_and_version field to octets
> 6 and 7 of the hash.
> o Set the four most significant bits (bits 12 through 15) of the
> time_hi_and_version field to the appropriate 4-bit version number
> from Section 4.1.3.
> o Set the clock_seq_hi_and_reserved field to octet 8 of the hash.
> o Set the two most significant bits (bits 6 and 7) of the
> clock_seq_hi_and_reserved to zero and one, respectively.
> o Set the clock_seq_low field to octet 9 of the hash.
> o Set octets zero through five of the node field to octets 10
> through 15 of the hash.
> o Convert the resulting UUID to local byte order.
However, the NVMe spec does not specified a namespace ID, so,
I selected a stirng "nqn.2014-08.org.nvmexpress:nguid",
then do SHA1 on it, get 4dead072-6b40-f992-9447-40f235d55fee,
then replace the version to '5' and variant to '1' to follow RFC 4122, get 4dead072-6b40-1992-8447-40f235d55fee
So for the NGUID A42812345678ABCD, a way to generate a canonnical
UUID is:
```
import uuid
namespace = uuid.UUID('4dead072-6b40-1992-8447-40f235d55fee')
nguid_bytes = bytes.fromhex('A42812345678ABCD')
result_uuid = uuid.uuid5(namespace, nguid_bytes)
print(result_uuid)
```
Resulting 9f4344db-6bf0-5782-b8a9-a08b6aa55169.
It's too complicated, right? RFC9562 provides us UUIDv8,
> UUIDv8 provides a format for experimental or vendor-specific
> use cases. The only requirement is that the variant and version
> bits MUST be set as defined in Sections 4.1 and 4.2.
Let's set the first 6 avalible custom bytes to "NGUID:",
move the first 4bits of NGUID before the variant 4bits .
So for the NGUID A42812345678ABCD, it's 78718573-6858-800A-8428-12345678abcd.
Alan.
More information about the Linux-nvme
mailing list