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

From: Dave Simmonds (Dave.Simmonds_at_pawis.com)
Date: 02/10/05

  • Next message: Stephanie Chung: "[HPADM] Fwd: Re: [SUMMARY] Emacs Vs PuTTy"
    To: <hpux-admin@dutchworks.nl>
    Date: Thu, 10 Feb 2005 14:48:24 -0000
    
    

    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)
    

  • Next message: Stephanie Chung: "[HPADM] Fwd: Re: [SUMMARY] Emacs Vs PuTTy"

    Relevant Pages

    • Re: Recursion bug in -rt
      ... >> the theory that the locks themselves would not deadlock. ... As I said, if you don't want futex to deadlock the kernel, the ... >> the kernel deadlocks or not, because the deadlocking of the user app ...
      (Linux-Kernel)
    • RE: FUSYN and RT
      ... There will never be deadlocks involving both types of locks, ... debugged the error must be in Fusyn based code. ... >>should not give problems in the kernel. ... Fusyns are kernel locks that are exposed to user space (much as ...
      (Linux-Kernel)
    • Re: Futex queue_me/get_user ordering
      ... It means anything you can do with one futex, ... If you change futex_wait to be "atomic", and then have userspace locks ... but considering it's only Glibc which is ... I agree it would probably not slow the kernel, ...
      (Linux-Kernel)
    • Re: PREEMPT_RT and I-PIPE: the numbers, take 3
      ... >>If you were suggesting this to be run on an SMP system, ... I'm suggesting that you and other folks understand the basic ideas ... be different if the kernel were compiled in an unrealistic way. ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: Fine grained locking (was: FreeBSD mail list etiquitte)
      ... > their Giant kernel lock, ... They then have fine-grained locking ... > pointers accessed in a read form under two different locks). ... the BGL in FreeBSD, are actually code locks, not data locks. ...
      (freebsd-hackers)