Rocket U2 | UniVerse & UniData

 View Only
Expand all | Collapse all

LIST.READU

  • 1.  LIST.READU

    Posted 02-07-2023 14:27
    Being used to the Unidata format, when running this command in Universe the file the lock is in does not display. We have common keys across many files so the format of this tool is very unhelpful to us! Does anyone have the syntax, alternate command, or custom ditty that shows all the pertinent info for a lock at one time? IE login, date/time, file, ID, process ID, User ID?

    Thanks for the help!

    ------------------------------
    Kathleen Hambrick
    Programmer at Colwell
    ------------------------------


  • 2.  RE: LIST.READU

    Posted 02-08-2023 05:49
    From TCL, LIST.READU EVERY DETAIL and PORT.STATUS as an admin user works well on Nix OS. The inode data can be used to find the actual filename that pertains to the key reported by LIST.READU. I use the OS find command with -inode parameter. If a parameter to one of those UV commands is not working, be sure the VOC has a record for that argument as found in the UV account VOC. PORT.STATUS gives at least one os process pid. I use the os ps -ef command and egrep to find the PORT STATUS Info such as pid,tty, and login name. The os last command shows some user details. To view os process environment variables, i use ps ewww | tr ' ' '\n'  to view and format the output. I wonder if this forum has a code repo somewhere. Im sure all those commands could be bundled together to make a custom ditty. Good luck!




    ------------------------------
    Mike Bojaczko
    PROGRAMMER ANALYST
    US
    ------------------------------



  • 3.  RE: LIST.READU

    ROCKETEER
    Posted 02-08-2023 06:17
    Kathleen,

    This will not help you at the moment but starting at UniVerse 12 it apdopts the same lock structure and methodolgy as UniData.
    So at UniVerse 12 the output of LIST.READU is 

    >LIST.READU

    Active Locks:
    Device.... Inode.... FileName. UsrNo Pid.... LoginId ItemId... M LockTime.......
    2016955433 977405710 C:\u2\UV\ 2 14840 Jonatha LOGIN X Feb 8 09:39:01

    >LIST.READU DETAIL

    Active Locks:
    Device.... Inode.... FileName. UsrNo Pid.... LoginId ItemId... M LockTime.......
    2016955433 281474977405710 C:\u2\UV\HS.SALES\VOC 2 14840 Jonathan LOGIN X Wed Fe
    b 8 09:39:01 2023

    >LIST.READU EVERY

    Active Locks:
    Device.... Inode.... FileName. UsrNo Pid.... LoginId ItemId... M LockTime.......
    2016955433 977405710 C:\u2\UV\ 2 14840 Jonatha LOGIN X Feb 8 09:39:01


    >LIST.READU EVERY DETAIL

    Active Locks:
    Device.... Inode.... FileName. UsrNo Pid.... LoginId ItemId... M LockTime.......
    2016955433 281474977405710 C:\u2\UV\HS.SALES\VOC 2 14840 Jonathan LOGIN X Wed Fe
    b 8 09:39:01 2023

    You also have the option in UniVerse to add the word INTERNAL to get the information back in an array for processing in your own programs.

    >LIST.READU DETAIL INTERNAL
    2016955433ý281474977405710ýC:\u2\UV\HS.SALES\VOCý2ý14840ýJonathanýLOGINýXýWed Fe
    b 8 09:39:01 2023

    Also the uvglm_tool and uvulc_tool has been added to match the glm_tool and ulc_tool utlities in UniData.

    Prior to 12 you can use the following methods.

    >LIST.READU
    Active Record Locks:
    Device.... Inode.... Netnode Userno Lmode Pid Login Id Item-ID........
    .....
    5768565761 176284 0 111 91 RU 21954800 root LOGIN

    You can search for the inode using find with the '-i' option, the example works quickly as the file is in the current directory.

    >sh -c "find . -i 176284"
    ./VOC

    You can also search the whole machine for files with matching inodes, this could take some time :-)

    >sh -c "cd / ; find . -i 176284 -print"
    ./disk1/uv1132/HS.SALES/VOC
    ./proc/21954800/fd/5
    ./proc/21954800/fd/10
    ./proc/21954800/fd/12

    UniVerse uses an internal method to calculate the device number it uses, I currently don't have a program that will work on all platforms to display which path maps to the device number, which you would need to shorten the method above and not having to search from root.

    The above methods work for UNIX, Windows is different again.

    ------------------------------
    Jonathan Smith
    UniData ATS
    Rocket Support
    ------------------------------



  • 4.  RE: LIST.READU

    Posted 02-08-2023 10:20
    This is not working for me... I found a '-inum' option that looked equal to your '-i' but it does not seem to work...

    01 list.readu

    Active Record Locks:
    Device.... Inode.... Netnode Userno Lmode Pid Login Id Item-ID........
    .....
    64770 19132140 0 95 169 RU 993343 kathleen BTIC100
    64770 19132140 0 95 169 RU 993343 kathleen FINISH.TICKET.1

    [root@ibm uv]# find . -inum 19132140
    [root@ibm uv]#

    ideas?


    ------------------------------
    Kathleen Hambrick
    Programmer at Colwell
    ------------------------------



  • 5.  RE: LIST.READU

    ROCKETEER
    Posted 02-08-2023 10:31
    If you are on AIX you should be using 'find . -i nnnnnn'
    What OS are you using
    Also try doing LIST.READU INTERNAL to check to see if the LIST.READU output is being truncated.


    ------------------------------
    Jonathan Smith
    UniData ATS
    Rocket Support
    ------------------------------



  • 6.  RE: LIST.READU

    Posted 02-08-2023 10:48
    The internal command returns the same as without - no cutoff issue

    CPE OS Name: cpe:/o:redhat:enterprise_linux:8::baseos
    Kernel: Linux 4.18.0-425.10.1.el8_7.x86_64

    ------------------------------
    Kathleen Hambrick
    Programmer at Colwell
    ------------------------------



  • 7.  RE: LIST.READU

    ROCKETEER
    Posted 02-08-2023 11:03
    Do you think the file exists in the current directory or in a sub directory from where the find command is being run? If so, it should find it. Maybe you need to run the command at a higher level to expand the search?

    ------------------------------
    Neil Morris
    Universe Advanced Technical Support
    Rocket Software
    ------------------------------



  • 8.  RE: LIST.READU

    ROCKETEER
    Posted 02-08-2023 11:04
    Kathleen,

    I tested on one of our redhat systems and the -inum with find works (see below). Maybe you need to drop a line to your Linux Admin to see why it is not working.

    >LIST.READU

    Active Record Locks:
    Device.... Inode.... Netnode Userno Lmode Pid Login Id Item-ID........
    .....
    2058 784223 0 2 5 RU 25251 root TIME
    2058 1045519 0 1 88 RU 25168 root LOGIN

    >sh -c "find . -inum 1045519"
    ./VOC

    >sh -c "uname -a"
    Linux dentrp 2.6.32-504.el6.x86_64 #1 SMP Tue Sep 16 01:56:35 EDT 2014 x86_64 x8
    6_64 x86_64 GNU/Linux
    >sh -c "uv -version"
    UniVerse 11.3.1


    ------------------------------
    Jonathan Smith
    UniData ATS
    Rocket Support
    ------------------------------



  • 9.  RE: LIST.READU

    Posted 02-08-2023 11:08
    Will "find /" instead of "find ." get it ?




  • 10.  RE: LIST.READU

    ROCKETEER
    Posted 02-08-2023 11:07
    Kathlean,

    I just thought you may not get a result if the file doesn't exist in the current directory with 'find .' as it only works from the current directory down. If you want to search from the root file system down (as in my first response), it may take a while but try

    sh -c 'cd / ; find . -inum nnnnnnn'


    ------------------------------
    Jonathan Smith
    UniData ATS
    Rocket Support
    ------------------------------



  • 11.  RE: LIST.READU

    Posted 02-08-2023 12:03
    When Universe in their infinite wisdom decided to write a lock table output that DID NOT TELL YOU at all what the filename was it was such a stunning disappointment.  The MAIN thing you need to know is what is the name of the file!

    This is one of the main things I fix on each system on which I work
    I've been doing that for about twenty years, meanwhile the experts at Rocket don't seem to get *it* and have never created a tool to do this.

    If you have a system that regularly has twenty to ninety locks, you don't want to have to run the "find" on *every* *single* *line* of the output, it would take a half hour when you need to know the answer right now.

    You can tell this pisses me off :)

    At any rate.

    I run a batch process every week to create an inode-xref file, logging through each and every account in the system
    and then i rewrite the LIST.READU to use my xref file to display the actual file name

    As has been mentioned you need to be at root when you do the find
    That doesn't even always work since you have can remote files since Unix is so nice to users in the first place....

    ------------------------------
    Will Johnson
    Systems Analyst
    Rocket Forum Shared Account
    ------------------------------



  • 12.  RE: LIST.READU

    Posted 02-08-2023 08:06
    Edited by Andrew Milne 02-08-2023 09:46

    Hi Kathleen,

    We have from within SB Client, we run Universe on Windows, a utility that provides this

    list users
    this was written by K3 who provide  our ERP  this the definition
    shows lulu config
    The above executes a Paragraph, which in turn calls another Paragraph / s which have already grabbed some info from the standard LIST.READU -EVERY COMMAND
    I can't share the code as its subject to K3 copyright, but it does show what appears to be relatively simple process to grab all the info you ask for and present in a nice format.
    Perhaps our rocketeers could generate something similar ??
    I hope this helps 
    Thanks
    Andy


    ------------------------------
    Andrew Milne
    Business Systems Manager
    Potter and Moore Innovations
    Peterborough, Cambs GB
    ------------------------------



  • 13.  RE: LIST.READU

    PARTNER
    Posted 02-09-2023 06:22

    Hi Kathleen,

    1/ On each account, run ACCOUNT.FILE.STATS ALL it'll populate the uv/STAT.FILE file. (read docs about it)

    build a q-ptr to it SET.FILE UV STAT.FILE UNIVERSE.STAT.FILE then you can LIST UNIVERSE.STAT.FILE FILENAME.LONG FILEINODE FILEDEV INODE.DEV 

    I suggest you index INODE.DEV

    CREATE.INDEX UNIVERSE.STAT.FILE INODE.DEV NO,NULLS 

    BUILD.INDEX UNIVERSE.STAT.FILE ALL 

    2/ build a basic which capture LIST.READU EVERY DETAIL INTERNAL 

    execute 'LIST.READU EVERY DETAIL INTERNAL' capturing LRU
    open 'UNIVERSE.STAT.FILE' to f.stat.file else ... 
    for x = 1 to dcount(LRU,@am)
        * LRU<x,1> is DEVICE
        * LRU<x,2> is INODE 
        r.stat.file=''
        selectindex 'INODE.DEV', LRU<x,1>:'.':LRU<x,2> from F.STAT.FILE to s 
        if status() then 
           * not found ... use OS calls 
        end else 
            readnext k.stat.file from s 
            read r.stat.file from f.stat.file,k.stat.file then 
                * check dict stat.file .. 1==filename, 2 == filepath, ... 
            end 
        end 
        * show result          
        print convert(@vm,char(9),LRU<x>):' ':r.stat.file<1> 
    next x 

    If the inode is not found, use OS call to define filename/filepath 

    on unix 

    find `df -i | while read fs inodes iused ifree iuse mounted; do if [[ ${mounted::1} == '/' ]]; then stat --printf %d:%n $mounted ;echo ; fi; done | grep " : DEVICE : " | cut -d ':' -f2` -inum " : INODE : " 2>/dev/null
    on windows 
    execute 'dos /c "fsutil volume list"' capturing volumes
    loop
       remote volume from volumes setting eov 
       execute 'DOS /C "fsutil file queryfilenamebyid ' : volume[1, 2] : ' ' : INODE"' capturing CAP
       NBZ = len(CAP)
       for Z = NBZ to 1 step -1
            if CAP[Z, 2] = volume[1,2] then FILEPATH = trim(CAP[Z, 999])<1> ; exit
       next Z
    while eov and FILEPATH = '' do repeat 
    About login date/time, ... I suggest userinfo(1,LRU<x,7>,U) or userinfo(2,LRU<x,4>,U) ... cf 
    UNIVERSE.INCLUDEUSERINFO.H 
    I hope this help.



    ------------------------------
    manu fernandes
    ------------------------------



  • 14.  RE: LIST.READU

    Posted 02-09-2023 15:53

    Hi Manu - thanks for this detail - I did not know about the ACCOUNT.FILE.STATS so that was very helpful! But we have MANY accounts, so that is kinda a pain for us. We do not have very many locks though - so I'd like to try your "find `df -i" but I don't follow how it gets the inum to search for.... you have 'read fs inodes' - where does 'fs' come from? 

    Thanks!!



    ------------------------------
    Kathleen Hambrick
    Programmer at Colwell
    ------------------------------



  • 15.  RE: LIST.READU

    PARTNER
    Posted 02-10-2023 05:21

    hi Kathleen,

    For performance and reusability, I suggest the AFS method.

    About account.file.stat on many account, I suggest you perform it in a loop like 

    $OPTIONS PICK
    SYS9006  = SYSTEM(9006)
    ASSIGN 1 TO SYSTEM(9006) ;** SET 9006 TO NOT EXECUTE REMOTE LOGIN-PROC
    ORIGIN = @WHO 
    EXECUTE 'SSELECT UV.ACCOUNT' RTNLIST S
    LOOP WHILE READNEXT ACNT FROM S DO 
         CRT ACNT 
         EXECUTE 'LOGTO ':ACNT 
         EXECUTE 'ACCOUNT.FILE.STATS ALL' ;* it's executed into ACNT account
         EXECUTE 'LOGTO ':ORIGIN
         EXECUTE 'WHO'
    REPEAT 
    ASSIGN SYS9006 TO SYSTEM(9006)
    END
    

    About the linux/bash command 

    find `df -i | while read fs inodes iused ifree iuse mounted; do if [[ ${mounted::1} == '/' ]]; then stat --printf %d:%n $mounted ;echo ; fi; done | grep " : DEVICE : " | cut -d ':' -f2` -inum " : INODE : " 2>/dev/null
    find will work on the result of backtick df-i ... backtick  used to define the path of DEVICE number
    df -i  return a list of filesystem 
    Filesystem      Inodes   IUsed   IFree IUse% Mounted on       
    /dev/sda3       901120  390122  510998   44% /               
    ... 
    the result is piped to bash/while read fs inodes iused ifree iuse mounted;
     the read load a line from pipe and set each variable with the value of the 'columns' , try this to undestand :
    df -i | while read fs inodes iused ifree iuse mounted; do echo $fs - $inodes - $iused - $ifree - $iuse - $mounted; done
    while the read load values, the do perform a stat on $mounted path 
    the stat print the  device_number : rootpath of device
    the result is piped to grep DEVICE it filter only the filesystem corresponding with DEVICE number. 
    the result is piped to cut to extract the rootpath of the device 
    then ... find work on rootpath  -inum INODE 
    I hope tis help
    manu


    ------------------------------
    manu fernandes
    ------------------------------



  • 16.  RE: LIST.READU

    ROCKETEER
    Posted 02-10-2023 13:20

    Kathleen,

    Another approach for you. These examples work for AIX, so the find command used would need to be modified for Linux to use -inum and not -i. This routine runs the LIST.READU DETAIL command and gives you the option to select an individual lock you are interested in, obviously this will be slow as it searchs it real time.

    PROGRAM JDS.LIST.READU
    EXECUTE 'LIST.READU DETAIL' CAPTURING OUTPUT
    IF OUTPUT<2> = "No locks or semaphores active." THEN
      CRT
      CRT OUTPUT<2>
      CRT
      STOP
    END
    NOL = DCOUNT(OUTPUT,@AM)
    GOSUB L100.DISPLAY.LOCKS
    EXIT.PROG = 0
    LOOP
      CRT "Enter the lock number to display the file " :
      INPUT LOCK.NO
      LOCK.NO = UPCASE(LOCK.NO)
      IF LOCK.NO = "E" OR LOCK.NO = "Q" OR LOCK.NO = "X" OR LOCK.NO = "" THEN EXIT.PROG = 1
    UNTIL EXIT.PROG DO
      BEGIN CASE
      CASE LOCK.NO = "R"
        GOSUB L100.DISPLAY.LOCKS
      CASE NOT(NUM(LOCK.NO))
        CRT "Input a lock number, R to Refresh or E,Q,X or '' to Exit"
      CASE LOCK.NO LE 0
        CRT "No such lock"
      CASE LOCK.ARRAY<LOCK.NO> = ""
        CRT "No such lock"
      CASE 1
        CRT "Checking Please Wait"
        DEVNO = LOCK.ARRAY<LOCK.NO,1>
        INO = LOCK.ARRAY<LOCK.NO,2>
        ERROR = 0
        ERROR.MESS = ""
        FILENAME = ""
        CALL DEVNO.INO(DEVNO,INO,ERROR,ERROR.MESS,FILENAME)
        IF ERROR THEN
          CRT "Checking returned the following error(s)"
          ERR.CNT = DCOUNT(ERROR.MESS<1>,@VM)
          FOR ERR.NXT = 1 TO ERR.CNT
            CRT ERROR.MESS<1,ERR.NXT>
          NEXT ERR.NXT
        END ELSE
          CRT "Filename = " : FILENAME
        END
      END CASE  
    REPEAT
    STOP
    L100.DISPLAY.LOCKS:
    CRT OUTPUT<1>
    CRT OUTPUT<2>
    CRT OUTPUT<3>
    CNTR = 0
    CNTR = 0
    LOCK.ARRAY = ""
    FOR LN.NXT = 4 TO NOL
      IF OUTPUT<LN.NXT> NE "" THEN
        CNTR += 1
        CRT OUTPUT<LN.NXT> : " (Lock " : CNTR "R#5" : ")"
        OLINE = TRIM(OUTPUT<LN.NXT>)
        LOCK.ARRAY<CNTR,1> = FIELD(OLINE," ",1)
        LOCK.ARRAY<CNTR,2> = FIELD(OLINE," ",2)
      END
    NEXT LN.NXT
    CRT
    RETURN
    END

    It calls the following program to map the dno , ino

    SUBROUTINE DEVNO.INO(DEVNO,INO,ERROR,ERROR.MESS,FILENAME)
    ERROR = 0
    ERROR.MESS = ""
    FILENAME = ""
    IF DEVNO = "" OR INO = "" THEN
      ERROR = 1
      ERROR.MESS<1,-1> = "Device or Ino not supplied"
      RETURN
    END
    IF NOT(NUM(DEVNO)) THEN
      ERROR = 1
      ERROR.MESS<1,-1> = "Invalid Devno"
      RETURN
    END
    IF NOT(NUM(INO)) THEN
      ERROR = 1
      ERROR.MESS<1,-1> = "Invalid Inode"
    END
    EXECUTE 'STATUS DISKS' CAPTURING OUTPUT
    NOL = DCOUNT(OUTPUT,@AM)
    FDEV = 0
    FOR LN.NXT = 2 TO NOL WHILE NOT(FDEV)
      LINE = TRIM(OUTPUT<LN.NXT>)
      IF LINE = "" THEN CONTINUE
      MPOINT = FIELD(LINE," ",7)
      OPENPATH MPOINT TO F.MPOINT THEN
        STATUS MPOINT.STATUS FROM F.MPOINT THEN
          IF MPOINT.STATUS<11> = DEVNO THEN
     * Found Device
            FMPOINT = MPOINT
            FDEV = 1 
          END
        END ELSE
          ERROR = 1
          ERROR.MESS<1,-1> = "Unable to get information on mount point " : MPOINT
        END
      END ELSE
        ERROR = 1
        ERROR.MESS<1,-1> = "Unable to open path to " : MPOINT
      END
      CLOSE F.MPOINT
    NEXT LN.NXT
    IF FDEV THEN
      EXEC.STMT = "cd " : FMPOINT : " ; find . -inum " : INO
      EXECUTE 'sh -c ' : SQUOTE(EXEC.STMT) CAPTURING OUTPUT
      IF OUTPUT<1> NE "" THEN
        ERROR = 0
        ERROR.MESS = ""
        FILENAME = OUTPUT<1>
      END ELSE
        ERROR = 1
        ERROR.MESS<1,-1> = "Unable to locate file via Dno / Ino"
      END
    END ELSE
      ERROR = 1
      ERROR.MESS<1,-1> = "Unable to find Dno in mount points"
    END
    RETURN
    END

    From TCL> 

    RUN BP JDS.LIST.READU

    Active Record Locks:
    Device.............. Inode..............  Netnode Userno   Lmode        Pid Login Id Item-ID.............
     9223372200063533058               51195        0    111   37 RU   24838220 root      DUMMY   (Lock     1)
     9223372200063533058               51144        0    111   37 RU   24838220 root      DUMMY   (Lock     2)
     9223372200063533058               51195        0    111   81 RU   24838220 root       LOGIN   (Lock     3)

    Enter the lock number to display the file 3
    Checking Please Wait
    Filename = ./accounts/uv/jds/VOC

    Enter the lock number to display the file E

    Now if wanted to take this a step further and prebuild a file with all the devno / ino combinations, you can use the following the program to open each file in an account, get it's dno and ino and map it into a look up file, similar to the other example but without the the overhead of running account file stats. This program takes only a few seconds to run in an account.

    OPEN "DNO.INO.LOG" TO F.LOGFILE ELSE
      CRT "CANNOT OPEN DNO.INO.LOG"
      STOP
    END
    EXECUTE 'SELECT VOC'
    LOOP WHILE READNEXT K.VOC DO
      OPEN "DATA",K.VOC TO F.FILE THEN
        GOSUB L100.LOG.DNO.INO
        CLOSE F.FILE
      END
      OPEN "DICT",K.VOC TO F.FILE THEN
        GOSUB L100.LOG.DNO.INO
        CLOSE F.FILE
      END
    REPEAT
    STOP
    L100.LOG.DNO.INO: 
    FILEPATH = FILEINFO(F.FILE,2)
    STATUS FILESTATUS FROM F.FILE THEN
      DNO = FILESTATUS<10>
      INO = FILESTATUS<11>
      K.LOGFILE = DNO : "." : INO
      R.LOGFILE = FILEPATH
      WRITE R.LOGFILE ON F.LOGFILE,K.LOGFILE
    END
    RETURN
    END

    You could then use this program to do your LIST.READU

    PROGRAM JDS.LIST.READU2
    OPEN "DNO.INO.LOG" TO F.DNO.INO.LOG ELSE
      CRT "CANNOT OPEN DNO.INO.LOG"
      STOP
    END
    EXECUTE 'LIST.READU DETAIL' CAPTURING OUTPUT
    IF OUTPUT<2> = "No locks or semaphores active." THEN
      CRT
      CRT OUTPUT<2>
      CRT
      STOP
    END
    NOL = DCOUNT(OUTPUT,@AM)
    CRT OUTPUT<1>
    CRT OUTPUT<2>
    CRT OUTPUT<3>
    CNTR = 0
    CNTR = 0
    LOCK.ARRAY = ""
    FOR LN.NXT = 4 TO NOL
      IF OUTPUT<LN.NXT> NE "" THEN
        OLINE = TRIM(OUTPUT<LN.NXT>)
        DNO = FIELD(OLINE," ",1)
        INO = FIELD(OLINE," ",2)
        READ R.DNO.INO.LOG FROM F.DNO.INO.LOG,INO:".":DNO THEN
          CRT R.DNO.INO.LOG<1> "L#40" : OUTPUT<LN.NXT>[41,999]
        END ELSE
          CRT OUTPUT<LN.NXT>
        END
      END
    NEXT LN.NXT
    CRT
    END

    Final comment ... if you RESIZE a file the inode will change or if you move it around at the OS level it is also likely to change.

    Hope these provide a simple, fast workaround for those of you not at UV 12 yet.

    so from TCL

    >LIST.READU DETAIL

    Active Record Locks:
    Device.............. Inode..............  Netnode Userno   Lmode        Pid Login Id Item-ID.............
     9223372200063533058               51195        0    111   81 RU   24838220 root         LOGIN

    >RUN BP JDS.LIST.READU2

    Active Record Locks:
    Device.............. Inode..............  Netnode Userno   Lmode        Pid Login Id Item-ID.............
    /disk2/accounts/uv/jds/VOC                      0    111   81 RU   24838220 root            LOGIN



    ------------------------------
    Jonathan Smith
    UniData ATS
    Rocket Support
    ------------------------------