Re: SHOW DEVICE/FILES with FORTRAN?

From: heuveltjes (heuveltjes_at_email.msn.com)
Date: 10/11/04


Date: Sun, 10 Oct 2004 23:00:55 -0400


"dooley" <dooleys@snowy.net.au> wrote in message
news:1ca82fc6.0410101613.42cb7479@posting.google.com...
> David Froble <davef@tsoft-inc.com> wrote in message
news:<4168D59D.8070807@tsoft-inc.com>...
> >
> > I don't think that locks are involved. There could be open files for
which
> > there isn't a lock.
> If the file is open there is always at least one lock,
> rms bucket/record locks are always sub-locks of the file lock.
> Phil

Most interesting file opens are done by RMS, and indeed you could use GETLKI
to (in exec mode) to find a list of open files. I'll include a C program
(hack) that does just that. Should be easy enough to translate to Fortran
:-).

SHOW FILE/DEV walks kernel structures and has no API.
Best I can see you'll have to spawn it and parse it's output.

Hein.

$ typ FILELOCK_SHOW.C

#define MAXDEVICE 200
#define MAXDEVNAMLEN 64
#define MAXDEVLOCKNAM 13
#define MAXFILNAMLEN 80
#define MAXPID 16
/*
** FILELOCK_SHOW.C Hein van den Heuvel, HP, Oct 2004
** Based on BLOCKING.C, Hein van den Heuvel, Digital, July 1995
**
** List all rms file locks or for a specified PID or for a sepcified
device.
** Have fun,
** Hein van den Heuvel
*/

#include <prvdef>
#include <lkidef>
#include <lckdef>
#include <descrip>
#include <string>
#include <ctype>
#include <stdio>
#include <ssdef>
#include <rms>
#define terminator 0,0,0,0
#define EFN 1

static char devnam[MAXDEVICE][MAXDEVNAMLEN]; /* counted string */
static char devlocknames[MAXDEVICE][MAXDEVLOCKNAM+1];
static int device_count = 0;

typedef struct { short len, cod; void *address; unsigned short *retlen; }
item;
typedef struct { unsigned int len; void *address; } desc;

int sys$getlkiw(), sys$getjpi(), sys$setprv(), sys$cmexec(),
        sys$device_scan(), sys$getdvi(), lib$fid_to_name(), str$upcase(),
        sys$open(), sys$connect(), sys$get(), sys$read();
int make_device_name_list(), print_filename_and_record() ;
char *find_device_name();
int make_device_name_list(), print_filename();

main(int argc, char *argv[])
{
    int stat, s, i, l, parent, lock_id, lock_pid;
    int wildcard=0, pid=0, locks=0;
    unsigned short retlen=0;
    struct lkidef lkibuf[100], *lki;
    struct { unsigned all : 16, one : 15, too_small : 1 ;} lkilen;
    int privs[] = { PRV$M_WORLD | PRV$M_CMEXEC , 0};
    void *search_devnam=NULL;
    desc search_devnam_desc;

#pragma nostandard /* Using address of variable where constant is standard
*/

    struct { int rms; unsigned short fid_num, fid_seq, fid_rvn;
                char devlocknam[22] ;} resnam;

    item getlki_items[] = { 4, LKI$_LOCKID, &lock_id, 0,
                               4, LKI$_PID, &lock_pid, 0,
                              31, LKI$_RESNAM, &resnam, &retlen,
                               4, LKI$_PARENT, &parent, 0,
                               terminator};
    int help,
      getlki_args[] = {7, EFN, (int) &wildcard, (int)
&getlki_items,terminator};

#pragma standard

    /*
    ** First get some temporary privs for the GETLKI in EXEC mode later on.
    */
    stat = sys$setprv ( 1, privs, 0, 0);
    if (stat != SS$_NORMAL) return (stat & -2);

    help = 1;

    if (argc > 1) {
      int option;
      option = *(int *)argv[1];
      if (option == 'all') {
        help=0;
        if (argc > 2) {
          /*
          ** second argument, if present, specifies wildcarded device name
          ** to look for. For lock on matching devices, the RMS files name
          ** and locked record is attempted to be displayed.
          */
          search_devnam_desc.len = strlen(argv[2]);
          search_devnam_desc.address = (void *) argv[2];
          search_devnam = &search_devnam_desc;
          str$upcase (&search_devnam_desc, &search_devnam_desc);
          printf (" Looking for rms file locks on %s\n\n", argv[2]);
          } else {
          printf (" Looking for ALL rms file locks\n\n");
          } /* arcg > 2 */
        } /* all */

      if (option == 'pid') {

        /*
        ** third argument, specifies PID to look for.
        */
        if (argc > 2) {
          sscanf (argv[2], "%x", &pid);
          if (pid > MAXPID) {
            printf (" Looking for RMS file locks for PID %8X\n\n", pid);
            help=0;
            }
          } /* argc > 2 */
        } /* pid */

      } /* argc > 1 */

    if (help) {
      printf ("Usage %s [pid|all] [<pid>|<wildcarded-device]\n", argv[0]);
      printf (" pid - Display RMS file locks for all or specified pid.\n");
      printf (" all - Display all RMS file locks.\n");
printf ("The search_devnam argument accepts the standard wildcard
characters,\n");
printf ("the asterisk (*), which matches any sequence of characters, and
the\n");
printf ("percent sign(%), which matches any one character. An exact match
is\n");
printf ("used for comparison. For example, to match all unit 0 DU devices
on\n");
printf ("any controller, specify *DU%0. This string is compared to the
most\n");
printf ("complete device name (DVI$_ALLDEVNAM).\n");

      return 1;
      }

(void) make_device_name_list(search_devnam);

    /*
    ** Main loop. Get a lock, any lock.
    ** Find out wether it is held by specified process, and waiting.
    */
    stat = sys$cmexec (&sys$getlkiw, &getlki_args);
    while (stat & 1) {
        int x;
        x = (pid < MAXPID) ? 1 : (lock_pid == pid);

        locks++;
        if ( (resnam.rms == 'RMS$') && (parent==0) && x ) {

            /*
            ** Have RMS file lock
            */
            print_filename ( lock_pid, &resnam.devlocknam[0],
&resnam.fid_num);
            } /* PID ? */
        stat = sys$cmexec (&sys$getlkiw, &getlki_args);
        } /* while stat ? */
    if (stat == SS$_NOMORELOCK) stat = SS$_NORMAL;
    printf (" Done. Scanned %d locks.\n", locks);
    return stat;
}

int print_filename ( int pid, char *devlocknam, unsigned short (*fid)[3])
{
    int device_number, stat, i, l;
    char buf[512];
static char filnam[MAXFILNAMLEN+1];
    desc devnam_desc, filnam_desc = {0, filnam};

    for (device_number=0;
         strcmp ((char *) devlocknames[device_number], devlocknam);
         device_number++) if (device_number == device_count) return 0;

    devnam_desc.len = devnam[device_number][0];
    devnam_desc.address = &devnam[device_number][1];
    filnam_desc.len = MAXFILNAMLEN;
    stat = lib$fid_to_name(&devnam_desc, fid, &filnam_desc, &filnam_desc);
    filnam[filnam_desc.len] = 0;
    printf ( "%08X %s %s\n", pid, &devnam[device_number][1], filnam);
    return stat;
}

int make_device_name_list(desc *search_devnam)
    {

#include <dvidef>
#include <dcdef>
/* #include <dvsdef> does not exist, hand coded defines follow */
#define DVS$_DEVCLASS 1
#define DVS$_DEVTYPE 2
#define SS$_NOMOREDEV 2648

    int i, stat, context[] = {0,0}, devclass = DC$_DISK;
    unsigned short int retlen;
    desc devnam_desc;
    item getdvi_items[] = { MAXDEVLOCKNAM, DVI$_DEVLOCKNAM,0, 0,
terminator};
    item device_items[] = { 4, DVS$_DEVCLASS, &devclass, 0, terminator};
    /*
    ** Build two arrays with DISK device names and their lock names.
    */
    for (i=0; i<MAXDEVICE; i++) {
        devnam_desc.len = MAXDEVNAMLEN-1;
        devnam_desc.address = &devnam[i][1];
        stat = sys$device_scan (&devnam_desc, &devnam_desc,
            search_devnam, device_items, context);
        devnam[i][0]=devnam_desc.len;
        if (stat & 1) {
            devnam[i][devnam_desc.len+1]=0; /* Null terminate */
            getdvi_items[0].address = devlocknames[i];
            getdvi_items[0].retlen = &retlen;

            stat = sys$getdvi (0,0,&devnam_desc,getdvi_items,0,0,0,0);
            if (stat != SS$_NORMAL) return stat;
            devlocknames[i][retlen] = 0;
        }
        else {
            if (stat == SS$_NOMOREDEV) {
                device_count = i;
                i = MAXDEVICE;
            }
            break;
        }
    }
    return stat;
}



Relevant Pages

  • [GIT] NFS client fixes for linux 2.6.17
    ... Use FL_ACCESS flag to test and/or wait for local locks before we try ... and only send the RPC request to the server if this was the ... int status = -ENOLCK; ... goto again; ...
    (Linux-Kernel)
  • Re: skipping locks, mutex_owned, usb
    ... ukbd_poll(keyboard_t *kbd, int on) ... of 'infinite' recursion because mtx_ownedalways returns false. ... I skip all lock/unlock/etc operations in the post-panic context. ... mtx_trylock'should' return when we actually act as if no locks ...
    (freebsd-arch)
  • Re: Objects in use
    ... declare @objid int, ... @dbid int, ... so show all the locks. ...
    (microsoft.public.sqlserver.programming)
  • [PATCH][RT] futex: protect against pi_blocked_on corruption during requeue PI -V2
    ... The requeue_pi mechanism introduced proxy locking of the rtmutex. ... a waiter that has been woken by a timeout or signal. ... locks even if PI_WAKEUP_INPROGRESS is set. ... int clockrt, u32 __user *uaddr2) ...
    (Linux-Kernel)
  • RE: Change/delete file is denied while sufficient rights
    ... When you open files they ... get locks on them which normally get cleared automatically. ... > has modify rights. ... The file server has been updated a few weeks ago and used to be ...
    (microsoft.public.windows.server.general)