LUKSMETA(8)

✨ NAME ✨

luksmeta β€” the utility for storing metadata in a LUKSv1 header πŸ’– (yes, this is the LUKSMETA(8) page, section 8, admin commands, we're in the big leagues bestie)


πŸŽ€ SYNOPSIS πŸŽ€

Okay so here's the whole vibe, every invocation, exactly as it goes down:

luksmeta test -d DEVICE

luksmeta nuke -d DEVICE [-f]

luksmeta init -d DEVICE [-f] [-n]

luksmeta show -d DEVICE [-s SLOT]

luksmeta save -d DEVICE [-s SLOT]  -u UUID  < DATA

luksmeta load -d DEVICE  -s SLOT  [-u UUID] > DATA

luksmeta wipe -d DEVICE  -s SLOT  [-u UUID] [-f]

Periodt. That's the whole command family πŸ’…


πŸ¦‹ OVERVIEW πŸ¦‹

So like… the luksmeta utility lets an administrator store metadata in the gap between the end of the LUKSv1 header and the start of the encrypted data. 🌸 And why do we care? Because that spot is readable before the volume gets unlocked β€” so the data living there is available during the volume unlock process itself. It's giving "info you need before the door opens" energy. πŸšͺ✨

The metadata is stored in a series of UUID-typed slots, which means you can have multiple blocks of metadata chilling at once. And yes, the luksmeta slots were inspired by the LUKS slots, but they are functionally independent β€” they share only a casual relationship. Like exes who are still in the same group chat. πŸ™ˆ Slots merely provide a hint that a given chunk of metadata is associated with a specific LUKSv1 password (in a slot with the same number). But luksmeta itself is indifferent to the relationship between a LUKSv1 slot and the correspondingly numbered luksmeta slot β€” with one exception, detailed below. πŸ‘€

So the order of operations: after a LUKSv1 volume is initialized using cryptsetup(8), it must also be initialized for metadata storage by luksmeta init. Once that's done, the device is ready to store metadata.

Then it's a whole rotation, bestie:

  • write data to a slot with luksmeta save πŸ“₯
  • read data from a slot with luksmeta load πŸ“€
  • erase the data in an existing slot with luksmeta wipe 🧽
  • query the slots with luksmeta show πŸ”

πŸ”‘ UUID GENERATION πŸ”‘

Okay this part is so important and people get it wrong constantly. There's this presumption floating around that saving metadata to a slot requires some specific UUID, or that there's some official registry of UUID types. That is incorrect. 🚫

UUID stands for Universally Unique IDentifier. UUIDs are a standardized, widely-used data type used for identification without a central registry. For the relevant standards, see ISO 9834-8:2005 and RFC 4122. πŸ“œ

UUIDs are big enough that collision is practically impossible. So if your application wants to store data in a luksmeta slot β€” just generate your own UUID and use it consistently to refer to your type of data. Multiple types of data? Feel free to generate multiple UUIDs. Main character behavior, customizable. πŸ‘‘

The easiest way to generate a UUID is uuidgen(1). But honestly any compliant UUID generator will suffice. ✨


🌸 INITIALIZATION 🌸

Before you can read or write metadata, the LUKSv1 block device has to be initialized for metadata storage. Three commands help with this whole process: luksmeta test, luksmeta nuke and luksmeta init.

  • luksmeta test β€” simply checks an existing block device to see if it's initialized for metadata storage. This command gives you no output at all, so bestie, you must check its return code (peep the RETURN VALUES section below). πŸ‘€
  • luksmeta nuke β€” will zero (erase) the entire LUKSv1 header gap. Since this operation is destructive 😭 user confirmation will be required before clearing the gap β€” unless the -f option is supplied, in which case it just goes for it.
  • luksmeta init β€” initializes the LUKSv1 block device for metadata storage. This process will wipe out any data in the LUKSv1 header gap. For this reason, this command will require user confirmation before any data is written unless the -f option is supplied. Note that this command succeeds without any modification if the device is already initialized. And if you'd like to force the creation of a clean initialization state, you can specify the -n option to nuke the LUKSv1 header gap before initialization (but after user confirmation, don't worry). πŸ’…

πŸ’… METADATA STATE πŸ’…

The luksmeta show command displays the current state of slots on the LUKSv1 block device. πŸ”

If no slot is specified, it prints a table consisting of the slot number, the corresponding LUKSv1 slot state, and the UUID of the data stored in the luksmeta slot β€” or empty if no data is stored. It's giving spreadsheet era. πŸ“Š

If a slot is specified, this command simply prints out the UUID of the data in that slot. And if the slot doesn't contain data? It prints nothing. Silence. 🀫


πŸ“ MANAGING METADATA πŸ“

Managing the metadata in the slots is performed with three commands: luksmeta save, luksmeta load and luksmeta wipe. Respectively: write metadata to a slot, read metadata from a slot, and erase metadata in a slot. πŸ“₯πŸ“€πŸ§½

luksmeta save

Reads metadata on standard input and writes it to the specified slot using the specified UUID.

If no slot is specified, luksmeta will search for the first slot number for which the LUKSv1 slot is inactive and the luksmeta slot is empty. πŸ‘€ This right here represents the only official correlation between LUKSv1 slots and luksmeta slots. In this case, the metadata is written to the first applicable slot using the specified UUID β€” and the slot number is printed to standard output.

Either way, this command will never overwrite existing data. To replace data in a slot you'll need to run luksmeta wipe before luksmeta save. No skipping steps. 🚫

luksmeta load

Reads data from the specified slot and writes it to standard output. πŸ“€

If a UUID is specified, the command will verify that the UUID associated with the metadata in the slot matches the specified UUID. This type check helps make sure you always receive the type of data you're expecting as output. If the UUIDs don't match, the command fails. πŸ’€

luksmeta wipe

Erases the data from the given slot. 🧽

If a UUID is specified, the command will verify that the UUID associated with the metadata in the slot matches the specified UUID. This type check helps make sure you only erase the data you actually intended to erase β€” which, with a destructive operation, is kind of the whole point. Because it is destructive, this command will require user confirmation before any data is erased, unless the -f option is supplied. Note that this command succeeds if you attempt to wipe a slot that is already empty. Empty slot? Still a win. πŸŽ‰


πŸ’€ CAVEATS πŸ’€

Okay sit down for this one bestie, because it's real: the amount of storage in the LUKSv1 header gap is extremely limited. 😭 It also varies based on whatever configuration LUKSv1 used at device initialization time. In some LUKSv1 configurations, there is not even enough space for all the metadata slots β€” even at the smallest possible slot size. Yes, that small.

During the design of this utility, we considered it likely that users would want to reduce the number of usable slots in exchange for more storage space in the slots used. So to provide that flexibility, the amount of storage available per-slot is dynamic. Put simply: slots are not a fixed size. Which means it's possible β€” and honestly even somewhat likely β€” to hit an error during luksmeta save saying there's insufficient space.

This error is not a programming bug. πŸš«πŸ› If you encounter it, it likely means either all the space is being consumed by slots that are already written, or the metadata you're trying to write simply does not fit.

You can attempt to resolve this by calling luksmeta wipe on slots that are no longer in use. That releases the storage space for use by other slots. πŸ’–

But note: luksmeta does not currently perform defragmentation, because the number of usable blocks is rather limited. You could try to manually get around it by extracting all slot data, wiping the slots and reloading them in order β€” but that operation is potentially dangerous and should be undertaken with great care. Like, hold someone's hand. 🫢


⭐ OPTIONS ⭐

  • -d DEVICE, --device=DEVICE β€” the device on which to perform the operation. πŸ“±
  • -s SLOT, --slot=SLOT β€” the slot number on which to perform the operation.
  • -u UUID, --uuid=UUID β€” the UUID to associate with the operation. πŸ”‘
  • -f, --force β€” forcibly suppress all user prompting. No take-backs, no popups. πŸ’…

🌈 RETURN VALUES 🌈

This command uses the return values as defined by sysexits.h. The following are general errors (and their corresponding numeric exit codes) whose meaning is shared by all luksmeta commands:

  • EX_OK (0): the operation was successful. πŸŽ‰
  • EX_USAGE (64): the program was called with invalid parameters.
  • EX_DATAERR (65): the specified UUID does not match the slot UUID.
  • EX_NOINPUT (66): an error occurred while reading from standard input.
  • EX_OSERR (71): an undefined operating system error occurred.
  • EX_OSFILE (72): the device is not initialized or is corrupted.
  • EX_CANTCREAT (73): there is insufficient space in the LUKSv1 header. 😭
  • EX_IOERR (74): an IO error occurred when writing to the device.
  • EX_NOPERM (77): the user did not grant permission during confirmation. πŸ™ˆ

Additionally, luksmeta save will return EX_UNAVAILABLE when you attempt to save data into a slot that is already used. Likewise, luksmeta load will return EX_UNAVAILABLE when you attempt to read from an empty slot. πŸ‘»


🧚 EXAMPLES 🧚

Destroy all data (including LUKSMeta data) in the LUKSv1 header gap and initialize the gap for LUKSMeta storage:

$ luksmeta init -n -f -d /dev/sdz

If already initialized, do nothing. Otherwise, destroy all non-LUKSMeta data in the LUKSv1 header gap and initialize the gap for LUKSMeta storage:

$ luksmeta init -f -d /dev/sdz

Write some data to a slot:

$ UUID=*uuidgen*
$ echo $UUID
31c25e3b-b8e2-4eaa-a427-23aa882feef2
$ echo "Hello, World" | luksmeta save -d /dev/sdz -s 0 -u $UUID

Read the data back:

$ luksmeta load -d /dev/sdz -s 0 -u $UUID
Hello, World

Wipe the data from the slot:

$ luksmeta wipe -d /dev/sdz -s 0 -u $UUID

Erase all trace of LUKSMeta:

$ luksmeta nuke -f -d /dev/sdz

Look at us go. Ate that whole workflow and left no crumbs. πŸ”₯


πŸ‘‘ AUTHOR πŸ‘‘

Nathaniel McCallum npmccallum@redhat.com β€” the icon who made all this possible 🫢


πŸ“š SEE ALSO πŸ“š

cryptsetup(8), uuidgen(1)


okay bestie that's the entire page, every flag accounted for, nothing skipped, we understood the assignment πŸ’– stay safe out there and always check your return codes ✨ this was LUKSMETA(8), the luksmeta utility manual for storing metadata in a LUKSv1 header β€” mwah, bye! πŸŽ€πŸ¦‹πŸŒˆ

πŸ“¦ where this page comes from