Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE option

 
SOLVED
Go to solution
madhav_poddar
Occasional Advisor

Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE option

There is a process that I am runnning, which involves opening the file and reading it later. I need to open this file in a way, such that, a second process can also open the same file with NOSHARE option enabled.

FIrstly, I opened my file (f1.txt;1) using sys$open with the FAB share options enabled (fab$v_shrput, fab$v_shrget, etc.).

Next, while the file is kept open by the process, I run the following command on the terminal (to replicate the opening of the file by the second process) :

$ OPEN/NOSHARE INP_FILE f1.txt;1
%DCL-E-OPENIN, error opening DKA0:[TEST_SMALL]F1.TXT;1 as input
-RMS-E-FLK, file currently locked by another user
$ OPEN INP_FILE f1.txt;1

$

When the file is opened with NOSHARE option, it fails. Whereas, without the NOSHARE option, it succeeds.

Is there a way I can open the file without locking it such that the second process can open it even with NOSHARE option enabled, i.e., both the process are able to open the same file concurrently.

 

6 REPLIES 6
Hein van den Heuvel
Honored Contributor

Re: Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE op

NO.

 

The requested file sharing must be compatible with file access from PAST and FUTURE.

If it is not compatible with prior, but still active open, the attempted open will fail, as you noticed.

If you allow no-share, and it succeeds, then no future other open can be done until non-share open is closed.

 

Hein

madhav_poddar
Occasional Advisor

Re: Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE op

Thanks for the reply Hein.

I observed that when we execute the command BACKUP/IGNORE=INTERLOCK, there were no locks enabled for the file and OPEN/NOSHARE works.

Backup involves opening the file and reading its attributes and contents. Hence the backup command might be using some FAB option while opening or some OPEN option internally. As far as I know, it uses FIB$V_NOLOCK during qio operations and for read option it might be using something like RAB$V_NLK.

Hence, is it possible to know how BACKUP/IGNORE=INTERLOCK opens the file without locking it ?

 

Madhav

Hein van den Heuvel
Honored Contributor
Solution

Re: Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE op

>> RAB$V_NLK.

RAB's are all about Records. RAB$V_NLK. tells RMS not to keep a record after reading a record (with lock!) .

To get there, the file must first be opened.

You are correct that FIB$V_NOLOCK is needed to 'break through' a file lock. This is NOT available through RMS and you cannot give RMS a 'channel' you perhaps opened with that option. RMS can give you a channel (FAB$V_UFO) to use for QIO, but not the other way around.

Attached a silly C program demonstrating how one could use FIB$V_NOLOCK to read a locked file with QIO's.

It writes what was read using RMS - $WRITE - no record interpretation attempted.Actually ... I could NOT attach it. Stupid forum only allows JPG, JPEG,GIF, PNG,BMP.  I

ll attached renamed to .BMP, and you'll have to save as .TXT, hopefully the forum does not check for a signature.  --- noop - "The contents of the attachment doesn't match its file type "

pasting the code below. Sillyness abounds in this world.

hth,

Hein

/*
** read_locked.c  Hein van den Heuvel, July 2006
**
** This program can be used to copy the allocated blocks from a locked file
** Much like BACKUP/IGNORE=INTERLOCK is use the ACP NOLOCK access to over-
** ride file interlock. This requires SYSPRV or CONTROL ACCESS to the file.
** Unlike BACKUP this program simply reads all ALLCOATED blocks as the
** EOF information is likely not to be updated by the active writer (zero).
** The program copies MOST file attributes, but not all as its intended
** use is limited to copy live log files and such.
**
** You may need to use SET FILE/ATTR=(EBK:x,FFB:y) on the output as needed.
**
** If the code format looks a little odd and dated... it is!
** This program is loosly basde on some old example which where floating
** around at Digital Equipment such as SET_EXTENT.
** Suspected authors: Barry Dysert, Guenther Froehlin, me?...
**
** Enjoy!
** Hein, HvdH Perfromance Consulting
**
*/

#define MAXBLOCKS 120
#define MAXBYTES MAXBLOCKS*512

#include atrdef
/*
**  libr/extr=fatdef/out=fatdef.h sys$library:sys$lib_c.tlb
*/
#include "fatdef.h"
#include fibdef
#include iodef
#include rms
#include stdio
#include stdlib
#include string

int sys$create(), sys$connect(), sys$write(), sys$close();
int sys$create(), sys$parse(), sys$search();
int sys$assign(), SYS$QIOW(), lib$stop();

main(argc,argv)
int argc;
char *argv[];
    {
    static char buf[MAXBYTES];
    static char *usage = "Usage: $ read_locked name output_name\n";
    static char esa[256], rsa[256];
    static int status, channel, bytes, vbn=1;
    static int file_hbk, file_nbytes, spec_nbytes;
    static struct FAB fab, out;
    static struct RAB rab;
    static struct NAM nam;
    static struct
        {
        short status;
        char not_used[6];
        } iosb;
    static struct
        {
        short count;
        short not_used;
        void *address;
        } fibdes;
    static struct fibdef fib;
    static struct atrdef atr[2];
FAT attributes;
    struct { int len; char *addr; } devnam_desc;

/******************************************************************************/

/*  Verify that we've been properly invoked */

    if (argc != 3) printf("%s",usage), exit(1);

/*  Use RMS to parse the file so that we get a FID of the QIO */

    fab = cc$rms_fab;
    fab.fab$l_fna = argv[1];
    fab.fab$b_fns = strlen (argv[1]);
    fab.fab$l_nam = &nam;

    nam = cc$rms_nam;
    nam.nam$l_esa = esa;
    nam.nam$b_ess = sizeof (esa) - 1;
    nam.nam$l_rsa = rsa;
    nam.nam$b_rss = sizeof (rsa) - 1;

    out = cc$rms_fab;
    out.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
    out.fab$l_fna = argv[2];
    out.fab$b_fns = strlen (argv[2]);

    rab = cc$rms_rab;
    rab.rab$l_fab = &out;
    rab.rab$l_rbf = buf;
    rab.rab$w_rsz = sizeof(buf);

    if (((status=sys$parse(&fab)) & 1) != 1) lib$stop(status);
    if (((status=sys$search(&fab)) & 1) != 1) lib$stop(status);

/* Get a channel for QIO access */

    devnam_desc.addr = nam.nam$l_dev;
    devnam_desc.len  = nam.nam$b_dev;
    if (((status=sys$assign(&devnam_desc,&channel,0,0,0)) & 1) != 1) lib$stop(status);

/*  Set up the structures required for the ACP interface */

    fibdes.count = sizeof(fib);
    fibdes.address = &fib;

    fib.fib$l_acctl    = FIB$M_NOLOCK;
    fib.fib$w_fid_num  = nam.nam$w_fid[0];
    fib.fib$w_fid_seq  = nam.nam$w_fid[1];
    fib.fib$w_fid_rvn  = nam.nam$w_fid[2];

    atr[0].atr$w_type  = ATR$C_RECATTR;
    atr[0].atr$w_size  = ATR$S_RECATTR;
    atr[0].atr$l_addr  = &attributes;
    atr[1].atr$w_type  = 0;
    atr[1].atr$w_size  = 0;

/*  Get the file's current attributes, such as hi-block, rfm,... */

    status = SYS$QIOW(0,channel,IO$_ACCESS|IO$M_ACCESS,&iosb,0,0,&fibdes,0,0,0,&atr,0);
    if ((status & 1) != 1) lib$stop(status);
    if ((iosb.status & 1) != 1) lib$stop(iosb.status);

/*  Validate the specified values (e.g. can't extend the file) */

    file_hbk = attributes.fat$w_hiblkl + (attributes.fat$w_hiblkh << 16);
    file_nbytes = file_hbk*512;

    out.fab$l_alq = file_hbk;
    out.fab$b_rat = attributes.fat$b_rattrib;
    out.fab$b_rfm = attributes.fat$b_rtype;
    out.fab$w_mrs = attributes.fat$w_maxrec;  /* LRL=fat$w_rsize ?? */
    out.fab$b_fsz = attributes.fat$b_vfcsize;
    status = sys$create ( &out ) ;
    if (status & 1) status = sys$connect ( &rab );
    while ((status & 1) && (file_nbytes > 0)) {

        if (file_nbytes >= MAXBYTES) {
                bytes = MAXBYTES;
                file_nbytes -= MAXBYTES;
        } else {
                bytes = file_nbytes;
                rab.rab$w_rsz = file_nbytes;
                file_nbytes = 0;
        }

        status = SYS$QIOW(0,channel,IO$_READVBLK,&iosb,0,0,&buf,bytes,vbn,0,0,0,0);
        vbn += MAXBLOCKS;
        if (status & 1) status = iosb.status;
        if (status & 1) status = sys$write ( &rab );
    }

/*  Release the files */

    (void) SYS$QIOW(0,channel,IO$_DEACCESS,&iosb,0,0,&fibdes,0,0,0,0,0);
    (void) sys$close ( &out );
    return status;
    }

 

madhav_poddar
Occasional Advisor

Re: Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE op

Thanks for the descriptive explanation, It was really informative. Since we aren't using sys$open to open, I was able to read the file data without aquiring a lock on it and It does solve major part of my issue.

In addition to reading the file data, I wanted to read the XAB blocks of the files as well as populate the member variables of FAB (such as fab$b_org). Earlier, this was being handled automatically (or made possible) when we were opening the file using sys$open.

Is there any documentation/example you could point me to, to be able to read these attributes via QIO and map them to XAB blocks (XABSUM, XABALL, XABFHC, FABITM, XABPRO)? Using IO$_ACCESS I can fill a struct atrdef, but mapping those to XAB blocks seem very daunting. Looking for some guidelines here.

 

Thanks

Madhav

Hein van den Heuvel
Honored Contributor

Re: Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE op


Too bad that RMS is not willing/able to pass along FIB$M_NOLOCK. That would solve everything right?

So you want (need) to use SYS$QIO(w) to open a file, but would like your functions to behave like SYS$OPEN, with it's implied SYS$DISPLAY filling in any XAB provided (except XABKEY I guess) to behave just like RMS.
That's a noble target, but properly more than actually needed.

Just 'walk' the XAB chain with a case statement on type and fill in the 'normal' interesting fields, if at all reasonable With code similar to the example ealier:
>> out.fab$b_rat = attributes.fat$b_rattrib;
>> out.fab$b_rfm = attributes.fat$b_rtype;


Work from the outside in: see what data you have in RAT and FID and find a place to put it.
Don't bother with XAMITM until you know for a fact your consumer will use it, and which one is needed.

STATITISTICS is the most commonly used but only applies to RMS so no need, not really.

Enjoy,
Hein.

 

madhav_poddar
Occasional Advisor

Re: Open file with no locks enabled,so that a 2nd process can access it concurrently with NOSHARE op

As correctly mentioned, I need a functionality similar to sys$display (since it only works for opened files). 

If I understood it correctly, I would need to manually fill the remaining fields based on data I already have or provide it with a default value. 

Is there an alternate way of doing this such that I am able to read all XAB blocks (including XABITM) as well as FAB attributes ?

 

Thanks,

Madhav