LFS-CHANGELOG(1)

πŸ“¦ version 2.17.58, in ubuntu stonking

✨ LFS-CHANGELOG β€” bestie's guide to reading and clearing Lustre changelogs ✨

okay so basically: lfs-changelog and lfs-changelog_clear are the client utilities that read changelogs and clear them. They live in the Lustre User Utilities manual, section 1, and honestly? they're giving "I keep receipts on every metadata change on your MDT" energy and I'm obsessed. πŸ’…


🌸 NAME 🌸

lfs-changelog, lfs-changelog_clear β€” client utility to read and clear Lustre changelogs. that's it, that's the vibe πŸ¦‹


πŸŽ€ SYNOPSIS πŸŽ€

lfs changelog [--follow] [--user USERNAME] [--mask MASK] MDTNAME
              [STARTREC [ENDREC]]
lfs changelog_clear MDTNAME ID ENDREC

literally copy-paste-able, no cap πŸ“‹


πŸ’– DESCRIPTION πŸ’–

So lfs changelog displays the metadata changes on an MDT. Start point STARTREC and end point ENDREC are optional β€” like, you can be as specific or as ✨go with the flow✨ as you want.

Then lfs changelog_clear is the glow-up moment: it says "hey, changelog records previous to ENDREC are no longer of interest to a particular consumer ID", which potentially lets the MDT free up disk space. very demure, very mindful, very freeing-up-your-storage. πŸ’Ύβœ¨

An ENDREC of 0 means the current last record. so 0 = "everything up to now", periodt.

Also!! important bestie lore: changelog consumers must be registered on the MDT node using lctl-changelog_register(8). no registration, no changelog, iykyk. πŸ”‘


🧚 OPTIONS 🧚

  • --follow β€” block and wait for new changelog records to arrive. she sits there. she waits. she's patient, she's loyal, she's a golden retriever in flag form πŸ•
  • --user USERNAME β€” specify a registered changelog username for filtering. The format of USERNAME can be a username or numeric ID, e.g., "cl1", "cl1-user", "1", or "user". so flexible, so versatile, we love a low-maintenance argument πŸ’…
  • --mask MASK β€” specify a changelog event filtering mask, in the same format as lctl-changelog_register(8), e.g., "creat,unlnk,+open,-hsm". If MASK is not specified, the user's MASK specified to lctl-changelog_register(8) will be used. the + and - are doing their little add/remove dance and honestly iconic ✨

πŸ”₯ RETURN VALUES πŸ”₯

Return 0 on success, or a errno value on failure. that's the whole story, no plot twist 😌


πŸ’€ ERRORS πŸ’€

  • EINVAL β€” one or more invalid arguments are given. you gave her the wrong info, she's not mad, she's just disappointed πŸ₯²
  • ENOENT β€” MDT's changelog char device or changelog user not found. she looked. she really looked. it's not there. πŸ”
  • EACCES β€” not enough permissions to open the changelog char device. By default, the device is only accessible to the root user. that's right bestie, root-only by default, no sneaking in πŸ’…πŸ”’
  • EIO β€” failed to read the changelog record on the MDT. the read just... didn't read. it's giving corrupted vibes 😭

🫢 NOTES 🫢

okay so listen up, this one's important: certain userspace tools might rely on past Lustre behavior of displaying the shard's parent FID instead of the real parent FID, in changelog records related to striped directories or filesystem objects contained within them. sounds niche? maybe. does it matter? yes.

If this behavior is needed for compatibility, please set mdd.*.enable_shard_pfid=1.

⚠️ Warning bestie: this tunable might be deprecated in a future Lustre release. so don't get too attached. πŸ’”

🌈 EXAMPLES 🌈

✨ Register 2 changelog consumers on MDT0000:

mds# lctl --device lfs1-MDT0000 changelog_register
lfs1-MDT0000: Registered changelog userid 'cl1'
mds# lctl --device lfs1-MDT0000 changelog_register -u dirs -m mkdir+rmdir
lfs1-MDT0000: Registered changelog userid 'cl2-dirs'

two consumers registered, two little serializers watching the timeline 🫢

✨ Set changelog mask to generate changelogs for file creations:

mds# lctl set_param mdd.lfs1-MDT0000.changelog_mask=CREAT
mdd.lfs1-MDT0000.changelog_mask=CREAT

✨ Generate changelogs by creating some files on the fs:

client# touch /mnt/lfs1/test{1..101}

brace expansion said "I'll make 101 files and I'll do it in one line" πŸ’…

✨ Read changelog from number 0 to 99 on MDT0000:

client# lfs changelog lfs1-MDT0000 0 99
0 01CREAT 11:03:54.129724442 2022.11.22 ... p=[0x200000007:0x1:0x0] test1
 ....
99 01CREAT 11:03:54.129724465 2022.11.22 ... p=[0x200000007:0x1:0x0] test100

look at those creation records, they're literally timestamped receipts 🧾✨

✨ Read changelog records using registered user cl1:

client# lfs changelog --user cl1 lfs1-MDT0000
100 01CREAT 11:03:54.129724492 2022.11.22 ... p=[0x200000007:0x1:0x0] test101

filtering by user? we love a curated feed πŸŽ€

✨ Read changelog records for registered user cl2-dirs with an extra filter mask:

client# lfs changelog --user cl2-dirs --mask unlnk lfs1-MDT0000
No record found.

she searched for unlinks and found none. No record found. the most anticlimactic but correct ending 😭

✨ Inform MDT0000 that changelogs lower than 100 are not needed for user cl1:

client# lfs changelog_clear lfs1-MDT0000 cl1 99

✨ Inform MDT0000 that changelogs lower than 200 are not needed for user cl2-dirs:

client# lfs changelog_clear lfs1-MDT0000 cl2-dirs 199

✨ The changelogs from 0 to 99 are cleared by the MDT:

client# lfs changelog lfs1-MDT0000 0
100 01CREAT 11:03:54.129724492 2022.11.22 ... p=[0x200000007:0x1:0x0] test101

poof. gone. the MDT said "cleared πŸ’…" and disk space was freed. we love a happy ending 🌸


⭐ AVAILABILITY ⭐

lfs changelog and lfs changelog_clear are part of the lustre(7) filesystem package since release 2.0.0. OG status, been here since the beginning of the Lustre 2.x era πŸ‘‘


πŸ‘‘ SEE ALSO πŸ‘‘

lfs(1), llapi_changelog_clear(3), llapi_changelog_recv(3), llapi_changelog_start(3), llapi_changelog_start_user(3), lctl-changelog_deregister(8), lctl-changelog_register(8)

go read those too bestie, they're the extended universe πŸ¦‹


and that's the whole page!! this was brought to you by the Lustre manual, dated 2025-11-25, page LFS-CHANGELOG(1) β€” stay curious, stay root-privileged, and clear your changelogs responsibly πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from