Is there a TSO command written in REXX or CLIST that can determine WHO has enqueued a dataset?
Categories:
Identifying Dataset Enqueues on z/OS with REXX and CLIST

Discover how to programmatically determine which TSO user or job has enqueued a specific dataset on a z/OS mainframe, leveraging REXX and CLIST for system information retrieval.
On IBM z/OS mainframes, dataset enqueues (also known as locks) are crucial for maintaining data integrity, preventing multiple users or processes from simultaneously modifying the same resource. When a dataset is enqueued, other attempts to access it in a conflicting manner will be blocked. Identifying who holds an enqueue is a common operational task, especially when troubleshooting resource contention or unexpected delays. This article explores how REXX and CLIST, two powerful scripting languages on z/OS, can be used to programmatically query and determine the owner of a dataset enqueue.
Understanding z/OS Enqueues
An enqueue is a serialization mechanism used by z/OS to control access to shared resources. When a program or user needs exclusive or shared access to a dataset, it issues an ENQ macro. The system then grants the enqueue if no conflicting enqueues exist. If a conflict arises, the requesting task waits until the enqueue is released. Dataset enqueues are typically managed by the Global Resource Serialization (GRS) component, which tracks all enqueues across the system or sysplex. The information we seek—who holds the enqueue—is stored within GRS control blocks.
flowchart TD A[User/Job Request Access] --> B{Dataset ENQ Issued} B --> C{GRS Checks Enqueue Table} C -->|No Conflict| D[Access Granted, Enqueue Held] C -->|Conflict Exists| E[Request Waits, Enqueue Owner Identified] D --> F[Processing Complete] F --> G[Dataset DEQ Issued] E --> G
Simplified z/OS Dataset Enqueue Process Flow
Methods for Querying Enqueues
While there isn't a single, direct TSO command like WHOENQ <dataset_name>
that returns the owner, the information can be extracted using system utilities and programming interfaces. The primary tools available are the D GRS,RES=(dataset_name)
console command and the ISPF 3.3
(Dataset Information Utility) panel, which internally use system services. REXX and CLIST can automate the execution of these commands or interact with system services to parse the output.
Using REXX to Parse D GRS,RES Output
The D GRS,RES=(dataset_name)
console command is the most direct way to see enqueue information. REXX can issue this command via TSO CONSOLE
or TSO MVS
and then parse the output. The key is to look for the 'OWNER' line in the display. This method requires appropriate console authority.
/* REXX to find dataset enqueue owner */
ARG DSNAME
IF DSNAME = '' THEN DO
SAY 'Usage: ENQWHO <dataset_name>'
EXIT
END
ADDRESS MVS 'D GRS,RES=('DSNAME')'
DO WHILE QUEUED() > 0
PULL LINE
IF POS('OWNER=',LINE) > 0 THEN DO
PARSE VAR LINE . 'OWNER=' OWNER_JOBNAME '(' OWNER_ASID ')' .
SAY 'Dataset' DSNAME 'is enqueued by:' OWNER_JOBNAME '(ASID:'OWNER_ASID')'
EXIT
END
END
SAY 'No active enqueue found for dataset' DSNAME
EXIT
REXX script to query dataset enqueue owner using D GRS,RES
Using CLIST with LISTDS and SYSOUT Parsing
CLIST can also be used, though it might be slightly more cumbersome for complex parsing compared to REXX. A common CLIST approach involves using the LISTDS
command with the ENQ
option, which provides some enqueue information, or again, issuing the D GRS,RES
command and capturing SYSOUT. The LISTDS
command, however, primarily shows if a dataset is currently in use, not necessarily the specific owner in the same detail as D GRS,RES
.
PROC 1 DSNAME
IF &STR(&DSNAME) = &STR() THEN DO
WRITE USAGE: ENQWHO <DATASET_NAME>
EXIT
END
ISPEXEC SELECT CMD(D GRS,RES=(&DSNAME)) NEWAPPL(ISR) PASSLIB
/* The above command will display output to the console. */
/* To capture and parse, you would typically redirect console output */
/* or use a more advanced interface like ISPF services. */
/* A simpler CLIST might use LISTDS, but it's less precise for owner. */
/* Example using LISTDS (less detailed for owner) */
SET &SYSOUT = &STR()
LISTDS '&DSNAME' ENQ
IF &LASTCC = 0 THEN DO
SET &SYSOUT = &SYSDVAL
/* Parse &SYSOUT for 'IN USE BY' or similar */
IF &DATALEN(&SYSOUT) > 0 THEN DO
WRITE &STR(&DSNAME) IS IN USE. Check LISTDS output for details.
END ELSE DO
WRITE &STR(&DSNAME) IS NOT CURRENTLY IN USE (via LISTDS).
END
END ELSE DO
WRITE ERROR LISTING DATASET &STR(&DSNAME)
END
EXIT
CLIST example using LISTDS (less direct for owner identification)
D GRS,RES
output in future z/OS versions, which could break REXX or CLIST scripts that rely on specific string positions or patterns. Consider using system programming interfaces (e.g., SVC 87 for GRS information) for more robust solutions if available and within your skill set.Advanced Considerations and Alternatives
For more robust and programmatic access to enqueue information, particularly in a sysplex environment, system programming interfaces (APIs) are often preferred. These include using the GRS ENQ/DEQ services directly from assembler or high-level languages like C, or leveraging products like IBM's System Display and Search Facility (SDSF) which provides a structured way to view enqueues. However, for quick, interactive checks from TSO, the REXX approach parsing D GRS,RES
output remains a practical solution.
1. Prepare your REXX environment
Ensure your REXX exec is stored in a dataset allocated to your SYSEXEC
or SYSPROC
concatenation, or explicitly EXEC
it from its PDS member.
2. Grant necessary authority
To issue D GRS,RES
from a TSO REXX exec, your TSO user ID typically needs console operator authority or specific RACF permissions to issue MVS commands.
3. Execute the REXX script
From TSO READY prompt, type EXEC 'your.rexx.pds(ENQWHO)' 'YOUR.DATASET.NAME'
and press Enter. The script will display the owner if an enqueue is found.