Operating System - OpenVMS

Finding file LUNS used for a process

Shael Richmond
Frequent Advisor

Finding file LUNS used for a process

is there a way to peek into another process and see how many LUNS have been allocated? We have folks forgetting lib$free_lun and were looking for a way to double check them.
Honored Contributor

Re: Finding file LUNS used for a process

You are looking for a form of reference counting.

Only Fortran and BASIC tend to have "LUNs", AFAIK.

OpenVMS processes do not generally have "LUNs", they have "I/O channels".

I would strongly suggest writing some (simple) diagnostic code here, and maintaining your own reference counters. Jacket the lib$get_lun and lib$free_lun and related calls, and particularly centralize these and other tasks (such as memory management) that involve shared resources.

This instrumentation and integrated debugging is usually the easiest approach, and the most easily tailored to your specific needs here.

If you have (or can add) an exit handler for the application, you can also then look at the reference counter when the application exits, and (wait for it) log a diagnostic for failed releases.

If you want to look at the open I/O channels for a process, then use the ANALYZE /SYSTEM tools.

GEIN $ set process/privil=cmkrnl ! or =ALL)
GEIN $ analyze/system

OpenVMS (TM) Alpha system analyzer

SDA> show process/channel

Process index: 0050 Name:...

The gnarly approach is to intercept the calls in question, but that's usually less effective (and arguably more work) than adjusting and documenting and refactoring (spotty) application code. John Gillings has posted some fake-RTL tools (search for /gillings fake rtl/ and you shall find...) and there are other examples around, if you do choose this approach. (I much prefer instrumented application code, as you can log what you need that way.)
John Gillings
Honored Contributor

Re: Finding file LUNS used for a process


LIB$GET_LUN and LIB$FREE_LUN are very, very simple routines. They keep a bitmap of available LUNs in a static location. They're allocated sequentially using a FFS or FFC instruction (Find First Set/Clear).

A FAKE_LIBRTL could be used to trace calls, but if you work out the LIBRTL PSECT and offset of the bitmap, then use SDA to locate it in another process.

Use SHOW PROCESS/IMAGE to determine the PSECTs then EXAMINE to peek at the contents.

Source code would help, but single stepping by instruction through the LIBRTL routines should give enough clues to work out where it is.

Note that there's nothing magic about a "LUN". It's just a number. The LIB$ routines don't know or care if or when you open or close a channel on the LUN.
A crucible of informative mistakes
Respected Contributor

Re: Finding file LUNS used for a process

If you are looking for a quick way to see how far along a proces is in using hte available LUNs, place the "current" LUN acquired from a call to GET_LUN in a known location that you can examine with SDA. The LUNs are allocated in a particular order such that the actual LUN number can indicate the maximum that have been used. This is an approximate number. The code sequence would look like this:


Realize that the LUN_LOCATION variable should be in a common area and would be the highwater mark for LUN usage. Freeing a LUN may make a hole that can get re-used, but at least this would give you a fairly accurate estimate of the usage.

Mike Kier
Valued Contributor

Re: Finding file LUNS used for a process

Not quite.

On my V7.3-2 system, LIB$GET_LUN returns 119-100 in descending order followed by 299-120 also in descending order.
Practice Random Acts of VMS Marketing
Respected Contributor

Re: Finding file LUNS used for a process

Excuse my rented fingers. The code we use uses MIN not MAX. We verify the quantity this way. We allocate the ones from 100-119 as "fixed" LUNs for specific files in the app. Therefore, the only available LUNs are in the range of 120-299. In order for this to work in your case, verify that the LUN is greater than 120 and use the MIN function to gauge the LUN count.


Sorry about the confusion.
Honored Contributor

Re: Finding file LUNS used for a process

Dan is suggesting the start of writing integrated diagnostic code.

And if you're going to do that, then do yourself a huge favor and set up some central logging routines and then figure out how to start writing the diagnostics such that you can include other details in the diagnostic log file (eg: timestamps, other data) if and when needed.

Or with the diagnostics written to a diagnostic mailbox or out to a syslog server or somewhat other more complex approaches.

For basic diagnostic stuff, writing output to a log file (opened for shared-read!) usually works fine.

I'd stay away from writing diagnostics into shared memory, at least until you really need to do that. Dealing with the memory interlocking can get a little gnarly, if you're not familiar with the topic.
John Gillings
Honored Contributor

Re: Finding file LUNS used for a process


You can do this right now with no code changes. It just takes a bit of forensic work and CMKRNL privilege.

An actual experiment. On a V7.3-2 Alpha system I wrote a little program to allocate a bunch of LUNs, then free them:

.title getlun
.psect data,rd,wrt,noexe
myluns: .BLKL 100
.psect code,rd,nowrt,exe
.entry start,^M
MOVAB myluns,R2
MOVL #30,R3
MOVL #30,R3
SOBGTR R3,FreeLoop
.END start

Compile, link and run with DEBUG. Stepping into LIB$GET_LUN and looking at the addresses I found the bit map at address 122480

$ run getlun

OpenVMS Alpha Debug64 Version V8.3-008


DBG> Step
stepped to GETLUN\START\%LINE 6
6: MOVAB myluns,R2
DBG> Step
stepped to GETLUN\START\%LINE 7
7: MOVL #30,R3
DBG> Step
stepped to GETLUN\START\%LINE 9
9: PUSHAL (R2)+
DBG> Step
stepped to GETLUN\START\%LINE 10
DBG> Step/Into
stepped to SHARE$LIBRTL_CODE0+89700
%DEBUG-I-SOURCESCOPE, source lines not available for %PC in scope number 0
Displaying source for 1\%PC
DBG> set image librtl
%DEBUG-I-NODSTS, no Debugger Symbol Table: no DSF file found and
DBG> set step instruction
DBG> Step
stepped to LIB$GET_LUN+4: STQ R27,(SP)
DBG> Step ! prologue
stepped to LIB$GET_LUN+8: STQ R26,#X0010(SP)
DBG> Step ! prologue
stepped to LIB$GET_LUN+0C: STQ FP,#X0018(SP)
DBG> Step ! prologue
stepped to LIB$GET_LUN+10: BIS R31,SP,FP
DBG> Step ! prologue
stepped to LIB$GET_LUN+14: LDQ R18,#X0028(R27)
DBG> Step ! Get address of bitmap into R18
stepped to LIB$GET_LUN+18: BIS R31,R31,R0
DBG> ex r18
0\%R18: 0000000000122480

From another process, using SDA and looking at the image layout, the LIBRTL data PSECT is at 112000, so the magic offset is 122480-112000=10480:

SDA> show proc/images=all
Process index: 003A Name: JG1 Extended PID: 000EFA3A

Process activated images

Image Name/Link Time/Section Type Start End Type IMCB Sym Vect Maj,Minor ID Base End ImageOff
--------------------------------------- -------- -------- ------------ -------- -------- ------------ -------- -------- --------
GETLUN 00010000 000401FF MAIN 7FF500D0 15,8784656
16-JUN-2011 08:15:40.31

LIBRTL 00112000 001639FF GLBL SHR 7FF505D0 0011E5C0 1,1
17-JUL-2007 10:18:51.27
System Resident Code 80C2A000 80CF69FF 00000000

SYS$SSISHR 00164000 001943FF GLBL PRT SHR 7FF548B0 00184220 1,1000
20-AUG-2004 17:00:44.42

DEBUG 00196000 002E6FFF MRGD SHR 7FF51150 001AA6D0 5,1
14-JUN-2006 13:19:07.83

SHRIMGMSG 0030A000 003109FF MRGD SHR 7FF51030 0030A000 107,15341581
1-OCT-2003 21:18:59.71

DBGTBKMSG 00312000 0031F9FF MRGD 7FF53760 00312000 109,13609879
9-OCT-2007 07:37:12.68

SYS$PUBLIC_VECTORS 8F304998 8F307037 GLBL 7FF4E740 00184270 106,6270694

SYS$BASE_IMAGE 8F323330 8F337E9F GLBL 7FF51AA0 8F323330 106,6271228

Total images = 8 Pages allocated = 271

Watching the bit map whilst stepping through the loop looks like this:

SDA> ex 122480 ! Before entering loop, empty
LIBRTL+10480: 00000000.00000000 "........"
SDA> ex 122480 ! allocated one
LIBRTL+10480: 00000000.00000001 "........"
SDA> ex 122480 ! allocated two
LIBRTL+10480: 00000000.00000003 "........"
SDA> ex 122480 ! allocated three
LIBRTL+10480: 00000000.00000007 "........"
SDA> ex 122480 ! at end of getloop
LIBRTL+10480: 00000000.3FFFFFFF "...?...."
SDA> ex 122480 ! first iteration of free loop
LIBRTL+10480: 00000000.1FFFFFFF "........"

So, first run the above program on your version, architecture and patch level to determine the offset for your system. This a one-off exercise. The offset won't change unless LIBRTL is updated.

Any process you want to check, go into SDA, SET PROCESS and SHOW PROCESS/IMAGE=ALL to locate the LIBRTL PSECT. You can then examine the bitmap using the offset you found. Unfortunately although SDA displays LIBRTL as if it were a symbol, it doesn't actually define it.
A crucible of informative mistakes