Thursday, August 13, 2026

𝘇/𝗢𝗦 𝟯.𝟮 𝗗𝗮𝘁𝗮𝘀𝗲𝘁 𝗢𝘃𝗲𝗿𝗳𝗹𝗼𝘄 𝗗𝗲𝗳𝗲𝗰𝘁: 𝗥𝗲𝗰𝗼𝗿𝗱 𝗟𝗼𝘀𝘀 𝗕𝗲𝘆𝗼𝗻𝗱 𝘁𝗵𝗲 𝟲𝟱,𝟱𝟯𝟱-𝗧𝗿𝗮𝗰𝗸 𝗟𝗶𝗺𝗶𝘁

A batch job was executed to consolidate data from the most recent 13 generations of a GDG, representing approximately 13 months of historical information.

The process consists of 13 sequential steps, with each step appending its output records to a single output dataset. The dataset was allocated on a single DASD volume.

Dataset attributes:
  • RECFM: FB
  • LRECL: 21
  • BLKSIZE: 27,993
The number of records appended by each processing step is shown below:

Step

Records Written

STEP100

37,923,095

STEP110

44,967,733

STEP120

57,202,964

STEP130

44,714,138

STEP140

43,599,256

STEP150

43,838,386

STEP160

45,313,346

STEP170

46,349,138

STEP180

45,525,353

STEP190

46,162,534

STEP200

46,518,402

STEP210

45,979,524

STEP220

46,381,066

Total records written from STEP100 to STEP220 : 594,474,935

But the Final dataset had only 70,325,745 records.
 

Dataset Track Limitation

The output dataset was allocated as a basic-format sequential dataset, which is limited to a maximum of 65,535 tracks per volume.
 
When the dataset grows beyond this limit:
 
  1. The system can no longer correctly address the entire dataset.
  2. It effectively treats the dataset as if it contains only the records corresponding to the overflowed tracks at the beginning of the file.
  3. Existing records are overwritten as additional data is appended.
  4. Consequently, part of the previously accumulated data is lost.

First Overflow Event (After STEP130)

Step

Records Written

Running Record Count

Calculated Tracks

STEP100

37,923,095

37,923,095

14,225

STEP110

44,967,733

82,890,828

31,092

STEP120

57,202,964

140,093,792

52,549

STEP130

44,714,138

184,807,930

69,321


At the completion of STEP130, the dataset reaches 69,321 tracks, exceeding the maximum addressable limit of 65,535 tracks.

Overflow tracks: 69,321 - 65,535 = 3,785 tracks

System now thinks the dataset has 3785 tracks instead of 69,331 tracks.
3785 tracks equates to first 10,090,810 records written by STEP100. 

At this point, the system begins reusing existing track addresses, causing subsequent writes to overwrite data already present in the dataset

The process then continues appending additional data:

Step

Records Written

Running Record Count

Calculated Tracks

STEP100

10,090,810


3,785

STEP140

43,599,256

53,690,066

20,139            

STEP150

43,838,386

97,528,452

36,582

STEP160

45,313,346

142,841,798

53,579

STEP170

46,349,138

189,190,936

70,965

 
At the completion of STEP170, the dataset again exceeds the track limit.
 
Overflow: 70,965 − 65,535 = 5,430 tracks
 
5,430 tracks corresponds to approximately 14,475,047 records, consisting of:
  • First 10,090,810 records written from STEP100  
  • First 4,384,237 records written from STEP140
Subsequent write operations reuse track addresses that have already been used, causing newly written records to overwrite previously stored data.

Processing then continues with the next set of steps:

Step

Records Written

Running Record Count

Calculated Tracks

STEP100

10,090,810

 

3,785

STEP140

4,384,237

 

1,645

STEP180

45,525,353

60,000,400

22,506

STEP190

46,162,534

106,162,934

39,821

STEP200

46,518,402

152,681,336

57,270

STEP210

45,979,524

198,660,860

74,517


At the completion of STEP210, the dataset exceeds the addressable limit for a third time.
 
Overflow tracks: 74,517 - 65,535 = 8,982 tracks

8,982 tracks corresponds to approximately 23,944,679 records, consisting of:
  • First 10,090,810 records written from STEP100  
  • First 4,384,237 records written from STEP140
  • First 9,469,632 records written from STEP180
The final processing step STEP220 then appends an additional 46,381,066 records.
 
Final Dataset Contents
 
After all overflow events and the completion of the final processing step, the dataset contained records originating from only a subset of the processing steps.
 

Step Contribution Retained in Final Dataset

Record Count

STEP100 

10,090,810

STEP140 

4,384,237

STEP180 

9,469,632

STEP220

46,381,066

Total Records in Final Dataset

70,325,745

 
Conclusion
 
The multiple overflow events caused entire sections of data written by several intermediate processing steps to be overwritten. As a result, the final dataset did not contain a continuous history of all records written during the batch execution. Instead, it consisted of:
  • First 10,090,810 records written by STEP100
  • First 4,384,237 records written by STEP140
  • First 9,469,632 records written by STEP180
  • All records written by STEP220

Sunday, August 9, 2026

𝗣𝗼𝘁𝗲𝗻𝘁𝗶𝗮𝗹 𝘇/𝗢𝗦 𝟯.𝟮 𝗗𝗲𝗳𝗲𝗰𝘁: 𝗕𝗮𝘀𝗶𝗰 𝗙𝗼𝗿𝗺𝗮𝘁 𝗦𝗲𝗾𝘂𝗲𝗻𝘁𝗶𝗮𝗹 𝗗𝗮𝘁𝗮𝘀𝗲𝘁𝘀 𝗘𝘅𝗰𝗲𝗲𝗱𝗶𝗻𝗴 𝘁𝗵𝗲 𝟲𝟱𝗞 𝗧𝗿𝗮𝗰𝗸 𝗟𝗶𝗺𝗶𝘁

A Mainframe Storage Group reached 99% utilization, resulting in unexpected abends for production jobs utilizing that storage group. As an immediate workaround, additional volumes were added to the storage group to restore capacity and prevent further job failures.

Following the temporary fix, we investigated which datasets were consuming the most space within the storage group. We identified the top storage-consuming datasets and analyzed the jobs responsible for creating them. The investigation revealed that a DB2 Image Copy job was generating these datasets.

The DB2 Image Copy job created backup datasets as GDG (Generation Data Group) generations on a daily basis. Since a new generation was created every day, the storage group's utilization continued to grow. To manage disk space, the job included mechanism to migrate older image copy generations to tape while retaining only the latest generation on disk.

Our analysis showed that most image copy datasets were being successfully migrated to tape. However, a small number of datasets remained on disk and were not being migrated. We further analyzed these datasets and compared the storage group growth trend. The investigation showed that the abnormal growth started after the z/OS 3.2 upgrade.

We then focused on understanding why these specific image copy datasets were not migrating to tape after the z/OS 3.2 upgrade. The problematic datasets were found to be multi-volume datasets, and occupying more than 65,535 tracks in one or more volumes. These datasets were Basic Format Sequential Datasets.

According to IBM documentation, Basic Format Sequential Datasets are limited to 65,535 tracks per volume. However, these datasets exceeded that limit. As a result, SMS was unable to migrate them to tape, causing the datasets to remain on disk and contributing significantly to the continued growth of the storage group.

SMS migration was failing with following messages.

ARC1001I DB2XXX.AAAAA.BBBBBBBB.CCCCCCCC.G5123V00 MIGRATE FAILED, RC=0099,
ARC1001I (CONT.) REAS=0040 
ARC1299I UNSUPPORTED DATA SET FOR MIGRATION

Reason code 40 says:
The data set occupies more than 65535 tracks and it is not a VSAM, PDSE, or extended format data set.

Based on the findings, it appears that the z/OS 3.2 was allowing Basic Format Sequential Datasets to exceed the documented 65K track limit per volume. This behavior is likely a defect.

Friday, August 7, 2026

𝗪𝗵𝘆 𝗗𝗦𝗟𝗜𝗦𝗧(𝟯.𝟰) 𝗥𝗲𝗽𝗼𝗿𝘁𝗲𝗱 𝟲% 𝗮𝗻𝗱 𝟯% 𝗨𝘁𝗶𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗼𝗻 𝗙𝘂𝗹𝗹𝘆 𝗢𝗰𝗰𝘂𝗽𝗶𝗲𝗱 𝗠𝘂𝗹𝘁𝗶-𝗩𝗼𝗹𝘂𝗺𝗲 𝗗𝗮𝘁𝗮𝘀𝗲𝘁𝘀: 𝗔 𝗗𝗙𝗦𝗢𝗥𝗧 𝗜𝗻𝘃𝗲𝘀𝘁𝗶𝗴𝗮𝘁𝗶𝗼𝗻

The below dataset spans four volumes, yet DSLIST reports utilization values of only 6% and 3% for the first two volumes. Since sequential datasets normally fill earlier volumes before extending to additional volumes, these figures appeared anomalous and warranted further investigation.

The following DSLIST 3.4 output shows the dataset allocation across four volumes.

Command - Enter "/" to select action                  Message           Volume
      Tracks  %     XT Device  Dsorg Recfm Lrecl Blksz  Created    Referred   
-------------------------------------------------------------------------------
         XY67890.PRODHIST.ORDRARCH.BACK.DATA                             XXX710
       69745   6    16 3390     PS   FB      228 27816 2026/08/07 2026/08/07  
-------------------------------------------------------------------------------
         XY67890.PRODHIST.ORDRARCH.BACK.DATA                             XXX674
       67860   3    11 3390     PS   FB      228 27816 2026/08/07 2026/08/07  
-------------------------------------------------------------------------------
         XY67890.PRODHIST.ORDRARCH.BACK.DATA                             XXX612
       60320 100    14 3390     PS   FB      228 27816 2026/08/07 2026/08/07  
-------------------------------------------------------------------------------
         XY67890.PRODHIST.ORDRARCH.BACK.DATA                             XXX678
       60320  93    11 3390     PS   FB      228 27816 2026/08/07 2026/08/07  
 
                             Data Set Information                            
                                     
 Data Set Name . . . . : XY67890.PRODHIST.ORDRARCH.BACK.DATA            
                                                                        
 General Data                          Current Allocation              
  Management class . . : XXXACTX        Allocated megabytes : 13,701   
  Storage class  . . . : XXXX           Allocated extents . : 52       
   Volume serial . . . : XXX710 +                                      
   Device type . . . . : 3390                                          
  Data class . . . . . : DCXXXXX                                       
   Organization  . . . : PS            Current Utilization             
   Record format . . . : FB             Used megabytes  . . : 6,532    
   Record length . . . : 228            Used extents  . . . : 2        
   Block size  . . . . : 27816                                         
   1st extent megabytes: 100                                           
   Secondary megabytes : 400           Dates                           
   Data set name type  :                Creation date . . . : 2026/08/07
   Data set encryption : NO             Referenced date . . : 2026/08/07
                                        Expiration date . . : ***None***
 
The following DFSORT job was used to determine how records are distributed across the dataset's four volumes.
 
The first DFSORT step reads the entire dataset and provides the total record count. Subsequent DFSORT steps specify VOL=(,,2), VOL=(,,3), and VOL=(,,4), causing processing to begin from the second, third, and fourth volume respectively. By subtracting the resulting record counts, the number of records residing on each individual volume can be derived.

 
 
//STEP010  EXEC PGM=SORT                                         
//SORTIN   DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA,DISP=SHR    
//SORTOUT  DD DUMMY                                              
//SYSOUT   DD SYSOUT=*                                           
//SYSIN    DD *                                                  
  SORT FIELDS=COPY                                               
//*                                                              
//STEP020  EXEC PGM=SORT                                         
//SORTIN   DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA,DISP=SHR,   
//            VOL=(,,2)                                          
//SORTOUT  DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA.SNGLVOL2,   
//            DISP=(,CATLG),                                     
//            SPACE=(1,(200,200),RLSE),AVGREC=M                  
//SYSOUT   DD SYSOUT=*                                           
//SYSIN    DD *                                                  
  SORT FIELDS=COPY                                               
//*                                                              
//STEP030  EXEC PGM=SORT                                         
//SORTIN   DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA,DISP=SHR,   
//            VOL=(,,3)                                          
//SORTOUT  DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA.SNGLVOL3,   
//            DISP=(,CATLG),                                     
//            SPACE=(1,(200,200),RLSE),AVGREC=M                  
//SYSOUT   DD SYSOUT=*                                         
//SYSIN    DD *                                                
  SORT FIELDS=COPY                                             
//*                                                            
//STEP040  EXEC PGM=SORT                                       
//SORTIN   DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA,DISP=SHR, 
//            VOL=(,,4)                                        
//SORTOUT  DD DSN=XY67890.PRODHIST.ORDRARCH.BACK.DATA.SNGLVOL4, 
//            DISP=(,CATLG),                                   
//            SPACE=(1,(200,200),RLSE),AVGREC=M                
//SYSOUT   DD SYSOUT=*                                         
//SYSIN    DD *                                                
  SORT FIELDS=COPY                                             
//*                                                            
 
Below is the SYSOUT of each step
 
SORTIN   : RECFM=FB   ; LRECL=   228; BLKSIZE= 27816  
SORTIN   : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA    
SORTOUT  : DSNAME=NULLFILE                            
RCD IN   62025525, OUT   62025525 
 
SORTIN   : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA        
SORTOUT  : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA.SNGLVOL2
RCD IN   45007745, OUT   45007745 
 
SORTIN   : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA           
SORTOUT  : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA.SNGLVOL3  
RCD IN   28449905, OUT   28449905 
 
SORTIN   : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA         
SORTOUT  : DSNAME=XY67890.PRODHIST.ORDRARCH.BACK.DATA.SNGLVOL4
RCD IN   13731825, OUT   13731825 
 
Record Distribution Across Volumes
 

Volume

Record Count Calculation

Records in Volume

XXX710 (Vol 1)

62,025,525 − 45,007,745

17,017,780

XXX674 (Vol 2)

45,007,745 − 28,449,905

16,557,840

XXX612 (Vol 3)

28,449,905 − 13,731,825

14,718,080

XXX678 (Vol 4)

Remaining Records

13,731,825

 
Dataset Size and Track Usage Calculation
 

Volume

Dataset Size (Bytes)

Track Calculation

Tracks Used

XXX710(Vol 1)

3,880,053,840

3,880,053,840 ÷ (2 × 27,816)

69,745

XXX674(Vol 2)

3,775,187,520

3,775,187,520 ÷ (2 × 27,816)

67,860

XXX612(Vol 3)

3,355,722,240

3,355,722,240 ÷ (2 × 27,816)

60,320

XXX678(Vol 4)

3,130,856,100

3,130,856,100 ÷ (2 × 27,816)

56,278

 
Formula Used
Dataset Size (Bytes) = Records × LRECL
Tracks Used = Dataset Size ÷ (2 × BLKSIZE)
 
where:
LRECL = 228
BLKSIZE = 27816
 
DSLIST vs. DFSORT Comparison of Volume Utilization
 

Volume

DSLIST Tracks

DSLIST Used %

Calculated Tracks

Used (DFSORT)

Comparison

XXX710

69,745

6%

69,745

Exact match

XXX674

67,860

3%

67,860

Exact match

XXX612

60,320

100%

60,320

Exact match

XXX678

60,320

93%

56,278

Close match. 60,320 × 93% = 56,098 tracks, which is very close to the calculated value of 56,278 tracks

 
 
Conclusion
 
Although DSLIST reports utilization values of only 6% and 3% for volumes XXX710 and XXX674, DFSORT analysis confirms that both volumes are effectively 100% utilized by dataset data. The calculated track usage matches the DSLIST track counts exactly, demonstrating that the reported percentages are misleading and do not reflect the actual occupancy of these volumes.
 

For basic format sequential datasets, the maximum number of tracks that can be addressed on a single volume is 65,535. When DSLIST encounters an allocation that exceeds this limit, it appears to calculate the utilization percentage using only the tracks beyond 65,535.
  • Volume XXX710: 69,745 tracks allocated
    • Excess tracks = 69,745 − 65,535 = 4,210
    • DSLIST reported utilization = 4,210 / 69,745 ≈ 6%
  • Volume XXX674: 67,860 tracks allocated
    • Excess tracks = 67,860 − 65,535 = 2,325
    • DSLIST reported utilization = 2,325 / 67,860 ≈ 3%
As a result, DSLIST displays 6% and 3% utilization for the first two volumes even though those volumes are effectively full. The percentages reflect only the tracks beyond the 65,535-track threshold rather than the actual space utilization of the volumes.

The dataset XY67890.PRODHIST.ORDRARCH.BACK.DATA is a basic-format sequential dataset. According to IBM documentation,https://www.ibm.com/docs/en/zos/2.1.0?topic=set-types-dasd-sequential-data-sets, a basic-format sequential dataset on a single volume is limited to a maximum of 65,535 tracks.

However, the system appears to allow allocations that exceed this documented limit. This behavior may indicate a z/OS defect.
 

Sunday, August 2, 2026

𝗨𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱𝗶𝗻𝗴 𝗦𝗕𝟯𝟳 𝗮𝗻𝗱 𝗦𝗘𝟯𝟳 𝗔𝗯𝗲𝗻𝗱𝘀 𝗳𝗼𝗿 𝗦𝗲𝗾𝘂𝗲𝗻𝘁𝗶𝗮𝗹 𝗗𝗮𝘁𝗮𝘀𝗲𝘁𝘀

When a program continuously writes data to an output sequential dataset, SB37 and SE37 abends can occur if additional space is required. Let's examine how these abends occur using the following DD statement:
 
//OUTFILE DD DSN=USERID.OUTFILE,
// DISP=(,CATLG,CATLG),
// SPACE=(TRK,(1,1),RLSE),
// LRECL=30,RECFM=FB,VOL=(,,,1)
 
Case 1: SB37 Abend
 
An SB37 abend occurs when the dataset has exhausted all the space that can be allocated to it according to its space definition, but the program still needs additional space.
 
For the DD statement shown above:
  • Primary allocation = 1 track
  • Secondary allocation = 1 track
  • Maximum number of extents allowed for a sequential dataset on a volume = 16 (1 primary extent + 15 secondary extents)
Therefore, the maximum space that can be allocated to USERID.OUTFILE on a single volume is:
  • 1 primary track
  • 15 secondary tracks
Total = 16 tracks
 
If the program continues writing records after all 16 tracks have been allocated, no additional extents can be obtained. As a result, the job terminates with an SB37 abend.
 
Case 2: SE37 Abend
 
An SE37 abend occurs when the system attempts to allocate a new secondary extent, but the required space is NOT available on the volume.

Using the same DD statement:
 
//OUTFILE DD DSN=USERID.OUTFILE,
// DISP=(,CATLG,CATLG),
// SPACE=(TRK,(1,1),RLSE),
// LRECL=30,RECFM=FB,VOL=(,,,1)
 
Each time the dataset requires additional space, the system attempts to allocate a secondary extent of 1 track. If sufficient free space is not available on the specified volume, the requested secondary extent cannot be allocated.

In this situation, even though the dataset has not yet reached its maximum limit of 16 extents, the allocation request fails and the job abends with SE37.

Note: If the system cannot allocate the requested primary space, the job step will fail with "JCL error" before execution begins. In such cases, the allocation fails with the message: IGD17272I VOLUME SELECTION HAS FAILED FOR INSUFFICIENT SPACE

Monday, July 27, 2026

Building an MQ Queue Depth Alert Program in COBOL

The following COBOL program is an IBM MQ queue monitoring utility that checks the depth of queues and reports queues that are approaching capacity.

The program:

-> Connects to an IBM MQ Queue Manager.
-> Reads a list of queue names from an input file.
-> For each queue:
     Opens the queue for inquiry.
     Retrieves:
        Current Queue Depth  
        Maximum Queue Depth  
-> Calculates 70% of the maximum queue depth.
-> Displays the queue name if the current depth is greater than or equal to 70% of its maximum capacity.
-> Closes the queue.
-> Disconnects from MQ after all queues are processed.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. INQDEPTH.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INPUT-FILE        ASSIGN TO INFILE.

       DATA DIVISION.
       FILE SECTION.

       FD  INPUT-FILE.
       01  INPUT-REC                   PIC X(48).

       WORKING-STORAGE SECTION.
       01  WS-EOF                      PIC X(01) VALUE 'N'.
       01  WS-CUR-DEPTH                PIC 9(9).
       01  WS-MAX-DEPTH                PIC 9(9).
       01  WS-CALC                     PIC 9(9).
       01  MQ-QM-NAME                  PIC X(48) VALUE SPACES.
       01  MQ-HCONN                    PIC S9(9) COMP-5 VALUE ZERO.
       01  MQ-RC                       PIC S9(9) BINARY.
       01  MQ-RSN                      PIC S9(9) BINARY.
       01  MQ-HOBJ                     PIC S9(9) BINARY.
       01  WS-OPTIONS                  PIC S9(9) BINARY.
       01  WS-SELECTORCOUNT            PIC S9(9) BINARY VALUE 2.
       01  WS-SELECTORS-TABLE.
           05  WS-SELECTORS            PIC S9(9) BINARY OCCURS 2 TIMES.
       01  WS-INTATTRCOUNT             PIC S9(9) BINARY VALUE 2.
       01  WS-INTATTRS-TABLE.
           05  WS-INTATTRS             PIC S9(09) BINARY OCCURS 2 TIMES.
       01  WS-CHARATTRLENGTH           PIC S9(9) BINARY VALUE ZERO.
       01  WS-CHARATTRS                PIC X(01) VALUE LOW-VALUES.

       01  MQM-OBJECT-DESCRIPTOR.
           COPY CMQODV.
       01  MQM-MESSAGE-DESCRIPTOR.
           COPY CMQMDV.
       01  MQM-PUT-MESSAGE-OPTIONS.
           COPY CMQPMOV.
       01  MQM-GET-MESSAGE-OPTIONS.
           COPY CMQGMOV.
       01  MQM-CONSTANTS.
           COPY CMQV SUPPRESS.

       PROCEDURE DIVISION.
       0000-MAIN.

           PERFORM 1000-INITIALIZATION
           PERFORM 2000-PROCESS
              THRU 2000-PROCESS-EXIT
             UNTIL WS-EOF = 'Y'
           PERFORM 3000-TERMINATION
           GOBACK.

       1000-INITIALIZATION.

           ACCEPT MQ-QM-NAME.

           CALL 'MQCONN' USING
                MQ-QM-NAME
                MQ-HCONN
                MQ-RC
                MQ-RSN

           IF MQ-RC = MQCC-FAILED
              DISPLAY 'MQCONN MQ-RC: ' MQ-RC ' MQ-RSN: ' MQ-RSN
           END-IF.
           OPEN INPUT INPUT-FILE.

       2000-PROCESS.

           READ INPUT-FILE
             AT END MOVE 'Y' TO WS-EOF
           END-READ

           IF WS-EOF = 'Y'
              GO TO 2000-PROCESS-EXIT
           END-IF

           PERFORM 2100-OPEN-FOR-INQ
           IF MQ-RC NOT = MQCC-OK
              GO TO 2000-PROCESS-EXIT
           END-IF

           MOVE MQIA-CURRENT-Q-DEPTH TO WS-SELECTORS(1)
           MOVE MQIA-MAX-Q-DEPTH     TO WS-SELECTORS(2)
           MOVE 2                    TO WS-INTATTRCOUNT
                                        WS-SELECTORCOUNT

           CALL 'MQINQ' USING MQ-HCONN
                              MQ-HOBJ
                              WS-SELECTORCOUNT
                              WS-SELECTORS-TABLE
                              WS-INTATTRCOUNT
                              WS-INTATTRS-TABLE
                              WS-CHARATTRLENGTH
                              WS-CHARATTRS
                              MQ-RC
                              MQ-RSN.

           IF MQ-RC NOT = MQCC-OK
              DISPLAY 'QUEUE: ' INPUT-REC
              DISPLAY 'MQINQ  MQ-RC: ' MQ-RC ' MQ-RSN: ' MQ-RSN
           ELSE
              MOVE WS-INTATTRS (1)     TO WS-CUR-DEPTH
              MOVE WS-INTATTRS (2)     TO WS-MAX-DEPTH
              IF WS-CUR-DEPTH > 0
                 COMPUTE WS-CALC = WS-MAX-DEPTH * 0.7
                 IF WS-CUR-DEPTH >= WS-CALC
                    DISPLAY INPUT-REC ' ' WS-CUR-DEPTH ' ' WS-MAX-DEPTH
                 END-IF
              END-IF
           END-IF
           PERFORM 2200-CLOSE-QUEUE.

       2000-PROCESS-EXIT.
           EXIT.

       2100-OPEN-FOR-INQ.

           MOVE MQOT-Q             TO MQOD-OBJECTTYPE
           MOVE INPUT-REC          TO MQOD-OBJECTNAME
           COMPUTE WS-OPTIONS = MQOO-INQUIRE +
                                 MQOO-FAIL-IF-QUIESCING.
           CALL 'MQOPEN' USING MQ-HCONN
                               MQOD
                               WS-OPTIONS
                               MQ-HOBJ
                               MQ-RC
                               MQ-RSN.
           IF MQ-RC NOT = MQCC-OK
              DISPLAY 'QUEUE: ' INPUT-REC
              DISPLAY 'MQOPEN MQ-RC: ' MQ-RC ' MQ-RSN: ' MQ-RSN
           END-IF.

       2100-OPEN-FOR-INQ-EXIT.
           EXIT.

       2200-CLOSE-QUEUE.

           CALL 'MQCLOSE' USING MQ-HCONN
                                MQ-HOBJ
                                MQCO-NONE
                                MQ-RC
                                MQ-RSN.

           IF MQ-RC NOT = MQCC-OK
              DISPLAY 'QUEUE: ' INPUT-REC
              DISPLAY 'MQCLOSE MQ-RC: ' MQ-RC ' MQ-RSN: ' MQ-RSN
           END-IF.

       2200-CLOSE-QUEUE-EXIT.
           EXIT.

       3000-TERMINATION.

           CALL 'MQDISC' USING
                MQ-HCONN
                MQ-RC
                MQ-RSN.

           IF MQ-RC = MQCC-FAILED
              DISPLAY 'MQDISC MQ-RC: ' MQ-RC ' MQ-RSN: ' MQ-RSN
           END-IF.

           CLOSE INPUT-FILE.

       3000-TERMINATION-EXIT.
           EXIT.