DLM_LOCK(3)
π DLM_LOCK(3) π
okay bestie, welcome to the libdlm manual section 3 page for dlm_lock β yes it's a whole page about ONE function family and yes it's giving main character energy π₯
β¨ NAME β¨
dlm_lock β acquire or convert a DLM lock π
πΈ SYNOPSIS πΈ
#include <libdlm.h>
int dlm_lock(uint32_t mode,
struct dlm_lksb *lksb,
uint32_t flags,
const void *name,
unsigned int namelen,
uint32_t parent, /* unused */
void (*astaddr) (void *astarg),
void *astarg,
void (*bastaddr) (void *astarg),
void *range); /* unused */
int dlm_lock_wait(uint32_t mode,
struct dlm_lksb *lksb,
uint32_t flags,
const void *name,
unsigned int namelen,
uint32_t parent, /* unused */
void *bastarg,
void (*bastaddr) (void *bastarg),
void *range); /* unused */
int dlm_ls_lock(dlm_lshandle_t lockspace,
uint32_t mode,
struct dlm_lksb *lksb,
uint32_t flags,
const void *name,
unsigned int namelen,
uint32_t parent, /* unused */
void (*astaddr) (void *astarg),
void *astarg,
void (*bastaddr) (void *astarg),
void *range); /* unused */
int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
uint32_t mode,
struct dlm_lksb *lksb,
uint32_t flags,
const void *name,
unsigned int namelen,
uint32_t parent, /* unusued */
void *bastarg,
void (*bastaddr) (void *bastarg),
void *range); /* unused */
int dlm_ls_lockx(dlm_lshandle_t lockspace,
uint32_t mode,
struct dlm_lksb *lksb,
uint32_t flags,
const void *name,
unsigned int namelen,
uint32_t parent, /* unused */
(*astaddr) (void *astarg),
void *astarg,
void (*bastaddr) (void *astarg),
uint64_t *xid,
uint64_t *timeout);
(yes the typo in /* unusued */ is canon, we keep it, do not touch it π
)
π¦ DESCRIPTION π¦
dlm_lock and all its little siblings acquire and convert locks in the DLM. that's the whole vibe.
dlm_lock() operations are asynchronous. so here's the tea: if your call to dlm_lock returns an error, the operation failed and the AST routine is NOT getting called, periodt. but if dlm_lock returns 0? bestie, it's still possible the lock operation will fail π. the AST routine gets called when the locking is complete or has failed, and the status comes back in the lksb.
dlm_lock_wait() will just sit there and wait until the lock operation has completed, then hands you the final completion status. no AST chaos, just patience β¨
dlm_ls_lock() is the same as dlm_lock() but it takes a lockspace argument. that lockspace has to have been previously opened by dlm_lockspace_open() or dlm_lockspace_create() β no opening, no locking, iykyk π«Ά
For conversion operations the name and namelen are ignored, and the lock ID in the LKSB is what identifies the lock you're converting.
If a lock value block is specified then, in general, a grant or a conversion to an equal-level or higher-level lock mode reads the lock value from the resource into the caller's lock value block. when a lock conversion from EX or PW to an equal-level or lower-level lock mode happens, the contents of the caller's lock value block get written into the resource. If the LVB is invalidated, the lksb.sb_flags member will be set to DLM_SBF_VALNOTVALID. Lock value blocks are always 32 bytes long, no cap, that's just the size π
If the AST routines or parameter get passed to a conversion operation, they will overwrite those values that were passed to a previous dlm_lock call. so yeah, they're replacing the old ones, not stacking.
mode β the lock mode to acquire or convert to π
LKM_NLMODEβ NULL LockLKM_CRMODEβ Concurrent readLKM_CWMODEβ Concurrent writeLKM_PRMODEβ Protected readLKM_PWMODEβ Protected writeLKM_EXMODEβ Exclusive
flags β these affect how the lock call operates π
LKF_NOQUEUEβ Don't queue the lock. If it cannot be granted return-EAGAINLKF_CONVERTβ Convert an existing lockLKF_VALBLKβ Lock has a value blockLKF_QUECVTβ Put conversion to the back of the queueLKF_EXPEDITEβ Grant a NL lock immediately regardless of other locks on the conversion queueLKF_PERSISTENTβ Specifies a lock that will not be unlocked when the process exits; it will become an orphan lock.LKF_CONVDEADLKβ Enable internal conversion deadlock resolution where the lock's granted mode may be set to NL andDLM_SBF_DEMOTEDis returned inlksb.sb_flags.LKF_NODLCKWTβ Do not consider this lock when trying to detect deadlock conditions.LKF_NODLCKBLKβ Not implementedLKF_NOQUEUEBASTβ Send blocking ASTs even for NOQUEUE operationsLKF_HEADQUEβ Add locks to the head of the convert or waiting queueLKF_NOORDERβ Avoid the VMS rules on grant orderLKF_ALTPRβ If the requested mode can't be granted (generally CW), try to grant in PR and returnDLM_SBF_ALTMODE.LKF_ALTCWβ If the requested mode can't be granted (generally PR), try to grant in CW and returnDLM_SBF_ALTMODE.LKF_TIMEOUTβ The lock will time out per the timeout arg.
lksb β Lock Status block π
This structure contains the returned lock ID, the actual status of the lock operation (all lock ops are asynchronous, remember bestie) and the value block if LKF_VALBLK is set.
name
Name of the lock. Can be binary, max 64 bytes. Ignored for lock conversions. (Should be a string to work with debugging tools.) π§
namelen
Length of the above name. Ignored for lock conversions.
parent
ID of parent lock or NULL if this is a top-level lock. This is currently unused.
ast
Address of AST routine to be called when the lock operation completes. The final completion status of the lock will be in the lksb. the AST routine must not be NULL.
astargs
Argument to pass to the AST routine (most people pass the lksb in here but it can be anything you like.) π
bast
Blocking AST routine. address of a function to call if this lock is blocking another. The function will be called with astargs.
range
This is unused.
xid
Optional transaction ID for deadlock detection.
timeout
Timeout in centiseconds. If it takes longer than this to acquire the lock (usually because it is already blocked by another lock), then the AST will trigger with ETIMEDOUT as the status. If the lock operation is a conversion then the lock will remain at its current status. If this is a new lock then the lock will not exist and any LKB in the lksb will be invalid. This is ignored without the LKF_TIMEOUT flag.
π« Return values π«
0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
EINVALβ An invalid parameter was passed to the call (eg bad lock mode or flag)ENOMEMβ A (kernel) memory allocation failedEAGAINβLKF_NOQUEUEwas requested and the lock could not be grantedEBUSYβ The lock is currently being locked or convertedEFAULTβ The userland buffer could not be read/written by the kernel (this indicates a library problem)EDEADLOCKβ The lock operation is causing a deadlock and has been cancelled. If this was a conversion then the lock is reverted to its previously granted state. If it was a new lock then it has not been granted. (NB Only conversion deadlocks are currently detected)
If an error is returned in the AST, then lksb.sb_status is set to the one of the above values instead of zero.
π Structures π
struct dlm_lksb {
int sb_status; /* Final status of lock operation */
uint32_t sb_lkid; /* ID of lock. Returned from dlm_lock()
on first use. Used as input to
dlm_lock() for a conversion operation */
char sb_flags; /* Completion flags, see above */
char sb_lvbptr; /* Optional pointer to lock value block */
};
β EXAMPLE β
int status;
struct dlm_lksb lksb;
status = dlm_lock_wait(LKM_EXMODE,
&lksb,
LKF_NOQUEUE,
"MyLock",
strlen("MyLock"),
0, // Parent,
NULL, // bast arg
NULL, // bast routine,
NULL); // Range
if (status == 0)
dlm_unlock_wait(lksb.sb_lkid, 0, &lksb);
π SEE ALSO π
libdlm(3), dlm_unlock(3), dlm_open_lockspace(3), dlm_create_lockspace(3), dlm_close_lockspace(3), dlm_release_lockspace(3)
and that's the page bestie!! this whole thing lives in the libdlm functions corner of the manual, and it's dated July 5, 2007 β old but iconic, like a limited edition lip gloss from 2007 that still hits πβ¨ go forth and lock responsibly π«Άπ
π¦ where this page comes from
- debian bookworm: libdlm-dev 4.2.0-2 Β· GPL-2.0-or-later
- debian trixie: libdlm-dev 4.3.0-3 Β· GPL-2.0-or-later
- fedora 43: dlm 4.3.0-6.fc43 Β· GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.0-or-later
- fedora 44: dlm 4.3.0-8.fc44 Β· GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.0-or-later
- opensuse-leap 16.0: libdlm 4.3.0-160000.3.2 Β· GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later
- opensuse-leap 16.0: libdlm 4.3.0-160000.3.2 Β· GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later
- opensuse-leap 16.0: libdlm 4.3.0-160000.3.2 Β· GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later
- opensuse-leap 16.0: libdlm 4.3.0-160000.3.2 Β· GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later
- ubuntu jammy: libdlm-dev 4.1.1-1build1 Β· GPL-2.0-or-later
- ubuntu noble: libdlm-dev 4.2.0-3build1 Β· GPL-2.0-or-later
- ubuntu questing: libdlm-dev 4.3.0-3build1
- ubuntu resolute: libdlm-dev 4.3.0-3build2 Β· GPL-2.0-or-later
- ubuntu stonking: libdlm-dev 4.3.0-3build2 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms