Skip to content
View All / Assembler : Getting DB2 Traces Started to OPn

Assembler : Getting DB2 Traces Started to OPn

In the previous post I talked about getting our assembler monitor connected to DB2 for z/OS with the intention of getting some statistics traces running and gathering the data cut by DB2. This time we’re going to look at how we actually got the traces running.

 

As you’ll know from your extensive reading of the DB2 10 for z/OS manual Managing Performance (SC19-2978 – chapter 22, Programming for IFI), we need to setup a couple of things before we attempt to issue our start trace command. What may not be entirely clear is exactly how to provide them as the coding examples are a little vague.

 

Things You’ll Need To Start a Trace

Probably the most important thing to be clear on is what traces you want to start. We’re concentrating on Stats with our monitor code which are supplied directly from the READS call, but you may be a bit more ambitious. Let’s say you want to track Audit data in DB2 V10:

 

-START TRACE(AUDIT) CLASS(1,4,5,7) DEST(OPX)

 

The destination clause is important as it says that we want the output to be written to a buffer that we’re supplying. You should be aware that each DB2 subsystem only supports 8 of these, so it is extremely important that you tidy up after yourself when you’re finished (-STOP TRACE…). Note that the OPn buffer assigned to your code won’t be released until all traces writing to it are explicitly stopped. As DB2 writes to the supplied buffer as data becomes available losing the application that owns the buffer will cause the buffer to be cleared up and the traces to throw an error.

 

It’s also reasonably sensible to limit your application to using just one of these OPn destinations to ensure that other IFI users (e.g. replication and other monitoring solutions) aren’t excluded due to lack of resources. This means that if you want to monitor more than one trace type, you will need to issue your subsequent trace starts against the specific OPn assigned to your application, e.g.

 

-START TRACE(PERFM) CLASS(22) DEST(OP7)

 

For reference, the default destination (for the start trace command) varies depending on the trace type – for audit it’s SMF, but for performance traces it’s GTF. See the DB2 10 for z/OS Command Reference (SC19-2972) for details.

 

Having decided on the trace, we need to put the command in a data block that IFI can work with, like this:

 

+—-+—-+—————-+

| LL | 00 | Command |

+—-+—-+—————-+

<———–LL————->

 

E.g.

 

DS                          0F

CMND                          DS                          0CL50

LL                                  DC                          H’49’                                               LENGTH OF COMMAND + HEADER

LLZZ                             DC                          H’0′                                                  BINARY ZEROS

CMDSTR                      DC                         CL45′-START TRACE                 (AUDIT)                          CLASS(1,4,5,7)           DEST(OPX)’

 

We’ve got the command sorted out, so next we need to supply the buffer. Two parameters have to be passed to establish this:

  • The address of the buffer itself, and;
  • The Buffer Information block (mapped by DSNDWBUF)

The buffer information block (WBUF) might be better referred to as the buffer control block. Its main purpose is to provide a threshold and notification route for data reaching the buffer. The programmer can specify an ECB to POST and a threshold number of bytes written to trigger this. This is the main means for DB2 to notify you that your buffer is being filled.

The last item required before we can start our trace is the Instrumentation Facility Component Area (IFCA). This is how DB2 returns state information to the caller, so includes return and reason codes as well as byte count for returned data and OPn destination identifier(s). It is mapped by DSNDIFCA and has to be properly initialised on first use – i.e. set to zeros, and then the following fields set:

  • The length (IFCALEN)
  • Scope flag (IFCAFLGS) set to global (IFCAGLBL) if required (default is local)
  • Eyecatcher (IFCAID) set to ‘IFCA’
  • OPn trace owner (IFCAOWNR) set – 4 characters

IFCAOWNR should be set when starting a trace as it sets the ownership identifier for the trace buffer. The owner of the buffer is the only process that can issue READA requests against it.

 

Issuing the Command Through IFI

The following call will issue the command:

CALL (15),(WLI2CMD,MYIFCA,(6),CMND,BUFFINF),VL,MF=(E,CBLK)

Where:

  • R15 is the address of a stub to call DSNWLI2 (cf Assembler : Getting Connected to DB2 – https://db2dinosaur.blogspot.com/2013/05/assembler-getting-connected-to-db2.html) – code shown below
  • WLI2CMD is an 8 character constant :
  • WLI2CMD DC CL8 ‘COMMAND ‘
  • MYIFCA is the IFCA that we initialised as in the previous section
  • R6 is the pointer to our trace buffer. Note that the first full word should be set to it’s length.
  • CMND is the command buffer (as shown in the previous section) which holds the start trace command.
  • BUFFINF is the WBUF that we initialised as in the previous section.

DSNWLI Stub

The following is the stub code to drive the previously loaded DSNWLI2 CAF IFI EP:

 

DSNWLI                                                           DS                                              0H

USING                                     DSNWLI,R15                                      ADDRESSABILITY

STM                                          R14,R12,12(R13)                               SAVE CALLERS REGS

LA                                              R8,WLI2SA                                       OUR SAVE AREA

ST                                              R13,4(R8)                                          SAVE BACKWARD SA PTR

ST                                              R8,8(R13)                                          SAVE FORWARDS SA PTR

LR                                             R13,R8                                                ESTABLISH NEW SA

LR                                             R12,R15                                               SORT OUT ADDRESSABILITY

DROP R15

USING                                      DSNWLI,R12

L                                                 R15,ADSNWLI2                                 GET DSNWLI2 EP

BALR                                         R14,R15                                               AND CALL

L                                                 R13,WLI2SA+4                                  RESTORE CALLERS SA

L                                                 R14,12(R13)                                        RESTORE CALLERS REGS

LM                                             R0,R12,20(R13)

BR                                              R14                                                       RETURN RC=RC FROM DSNWLI2

DROP                                       R12

 

Checking The Results

Okay, we made the call and it returned – did it work? As well as the return code returned in R15, it is also returned in the IFCA as IFCARC1, with the DB2 reason code returned in IFCARC2.

 

If these are both zero, then things are looking good. Any text returned by DB2 (you might have done a -DISPLAY TRACE first) will be indicated by a non-zero IFCABM (number of bytes in the return area – pointed to by R6 in our example). If your buffer wasn’t big enough for everything, then IFCABMN will be non-zero. This can be caused by the trace data being too big for a buffer that is too small, but it can also be an indicator that the monitor isn’t keeping up with the volume of data that DB2 is pushing.

 

If you need to work with READA, then you’ll need to note which OPn DB2 assigned you. This can be determined from the IFCAOPNL and IFCAOPNR array, which records up to 8 active OPn buffer assignments. Once you’ve picked a winner, put the value in IFCAOPN for subsequent READA calls.

 

If you find you’re struggling to get the command processing to work, it might be worth looking at IFCAR15 as well, which gives some additional diagnostics – which can be translated as :

 

0 = Okay

4 = Something weird happened

8 = Probably a syntax error on the supplied command

12 = See IFCAR0 for command handler return code

16 = See IFCAR0 for command handler return code

20 = DB2 couldn’t allocate storage to give you a text message back

24 = MSTR short on storage?

28 = Insufficient CSA available

32 = User not authorised to issue the command

 

 

Seeing Is Believing

Before:

-dis trace(*)

DSNW127I     -DB2T CURRENT         TRACE ACTIVITY IS –

TNO TYPE       CLASS                            DEST  QUAL

01                         STAT     01,03,04,05,  SMF    NO

01                                       06

02                       ACCTG  01                       SMF NO

*********END OF DISPLAY TRACE SUMMARY DATA*********

DSN9022I -DB2T DSNWVCM1 ‘-DIS TRACE’ NORMAL COMPLETION

After:

-dis trace(*)

DSNW127I     -DB2T   CURRENT   TRACE   ACTIVITY IS –

TNO TYPE    CLASS                         DEST  QUAL

01     STAT     01,03,04,05,              SMF    NO

01                    06

02   ACCTG  01                                  SMF   NO

03  AUDIT   01,04,05,07                 OP1   NO

*********END OF DISPLAY TRACE SUMMARY DATA*********

DSN9022I -DB2T DSNWVCM1 ‘-DIS TRACE’ NORMAL COMPLETION