[HPADM] SUMMARY: How to find out how many record locks are active on a HPUX system

From: Dave Simmonds (Dave.Simmonds@pawis.com)
Date: Thu Feb 10 2005 - 09:48:24 EST


Original question:
Hi,

I want to find out how many record locks are active on an HPUX system
I can look at the kernel variable nflocks to see the size of the table, but
I want to know how many are active, so I can see if I'm getting near to
filling the table up.

Ideally I'd like to use either something like pstat or a direct read of
/dev/kmem (via nlist64 on /stand/vmunix)

Thanks,
Dave Simmonds

I got a number of replies suggesting 'glance -t', but I don't have glance.
Also kcweb was suggested, but I didn't look into that.
It was pointed out that I should have used the term 'file locking' rather
than 'record locking', but I think most people understood what I was on
about.

The most useful suggestion was from Anil Rajapure who suggested:
lsof | awk 'match("NrRwWuUx",substr($0,31,1))'|wc -l
lsof lists all the open files, and the awk selects files that are locked, wc
counts the no. of matching lines.
The problem with this is that if a process has a file open and more than one
lock on it, it will only show up in lsof output once, so the result will be
too small.

I therefore examined the lsof source code to see where it was getting it's
information from and came up with the following c program which runs down
the kernel locklist looking for slots that are in use.

/* locklist.c */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <nlist.h>
#include <sys/types.h>

char *kname = "/stand/vmunix";
char *kmem_name = "/dev/kmem";

#define NLIST struct nlist64

struct locklist {
     off_t ll_link; /* locks 4 this process, this file */
     short ll_count; /* reference count */
     short ll_flags; /* current flags: L_REMOTE, L_WANT, L_BUSY
*/
     off_t ll_proc; /* remove later */
     off_t ll_kthreadp; /* thread which owns region */
     off_t ll_start; /* starting offset */
     off_t ll_end; /* ending offset, zero is eof */
     short ll_type; /* type of lock (for fnctl) */
     off_t ll_vp; /* Inode owning this locklist */
     off_t ll_waitq; /* threads for this range only */
     off_t ll_fwd; /* in increasing order of LB */
     off_t ll_rev;
     off_t ll_sib_fwd; /* "siblings" - exact same region */
     off_t ll_sib_rev;
     };

int verbose = 0;

main(int argc, char *argv[])
{
        NLIST nList[] = {{"locklist"},{"nflocks"},{NULL}};
        struct locklist *locklist;
        uint32_t nflocks;
        int fd;
        unsigned int j,count = 0;

        if(argc > 1 && !strcmp(argv[1],"-v"))
                verbose = 1;
        if(nlist64(kname,nList))
        {
                fprintf(stderr,"nlist failed - error %d\n",errno);
                exit(3);
        }
        if(nList[0].n_value == 0L)
        {
                fprintf(stderr,"%s not found\n",nList[0].n_name);
                exit(3);
        }
        if(verbose)
                printf("locklist address = %lu\n",(unsigned long)nList[0].n_value);
        if(nList[1].n_value == 0L)
        {
                fprintf(stderr,"%s not found\n",nList[1].n_name);
                exit(3);
        }
        if(verbose)
                printf("nflocks address = %lu\n",(unsigned long)nList[1].n_value);
        if((fd = open(kmem_name,O_RDONLY)) == -1)
        {
                fprintf(stderr,"open kmem failed - error %d\n",errno);
                exit(3);
        }
        if(lseek(fd,(off_t)nList[1].n_value,SEEK_SET) == -1)
        {
                fprintf(stderr,"lseek kmem failed (%s) - error
%d\n",nList[1].n_name,errno);
                exit(3);
        }
        if(read(fd,&nflocks,sizeof(nflocks)) != sizeof(nflocks))
        {
                fprintf(stderr,"read kmem failed (%s) - error
%d\n",nList[0].n_name,errno);
                exit(3);
        }
        if(verbose)
        {
                printf("nflocks = %u\n",nflocks);
                printf("sizeof(struct locklist) = %d\n",sizeof(struct locklist));
                printf("sizeof(locklist) = %d\n",nflocks*sizeof(struct locklist));
        }
        if((locklist = (struct locklist *)malloc(nflocks*sizeof(struct locklist)))
== NULL)
        {
                fprintf(stderr,"malloc locklist failed - error %d\n",errno);
                exit(3);
        }
        if(lseek(fd,(off_t)nList[0].n_value,SEEK_SET) == -1)
        {
                fprintf(stderr,"lseek kmem failed (%s) - error
%d\n",nList[0].n_name,errno);
                exit(3);
        }
        if(read(fd,locklist,nflocks*sizeof(struct locklist)) !=
nflocks*sizeof(struct locklist))
        {
                fprintf(stderr,"read kmem failed (%s) - error
%d\n",nList[0].n_name,errno);
                exit(3);
        }
        for(j = 0;j < nflocks;j++)
        {
                if(!locklist[j].ll_count)
                        continue;
                if(verbose)
                {
                        printf("ll_count[%d] = %lu\n",j,locklist[j].ll_count);
                        printf("ll_kthreadp[%d] = %lu\n",j,locklist[j].ll_kthreadp);
                        printf("ll_start[%d] = %lu\n",j,locklist[j].ll_start);
                        printf("ll_end[%d] = %lu\n",j,locklist[j].ll_end);
                        printf("ll_type[%d] = %lu\n",j,locklist[j].ll_type);
                }
                count++;
/* I originally thought to use count += locklist[j].ll_count, but I just
want the number of slots used */
        }
        if(verbose)
                printf("number of active locks = %d\n",count);
        else
                printf("%d\n",count);
        exit(0);
}

If you are using a 64bit kernel, you need to compile with +DD64 otherwise
the data structures will be the wrong size.
Run the program with -v to get verbose output, otherwise it just prints the
no. of active locks.
It seems to work - if anyone can see anything wrong with the logic please
let me know!

Thanks,
Dave Simmonds

--
             ---> Please post QUESTIONS and SUMMARIES only!! <---
        To subscribe/unsubscribe to this list, contact majordomo@dutchworks.nl
       Name: hpux-admin@dutchworks.nl     Owner: owner-hpux-admin@dutchworks.nl
 
 Archives:  ftp.dutchworks.nl:/pub/digests/hpux-admin       (FTP, browse only)
            http://www.dutchworks.nl/htbin/hpsysadmin   (Web, browse & search)


This archive was generated by hypermail 2.1.7 : Sat Apr 12 2008 - 11:02:46 EDT