1752590 Members
3097 Online
108788 Solutions
New Discussion юеВ

Reading locked files

 
mpradhan
Advisor

Reading locked files

Hello,

I have locked files, I am looking for ways to read them via sys$open() and sys$read() using block IO. Is there any FAB flag that I must use to let this happen?

I have a test code which keeps the file locked using fcntl, read shared or exclusive. Now, if I try to open the same file from another application it fails with error '%RMS-E-FLK, file currently locked by another user'. 

Any help is appreciated.

 

Thanks,

Manoj

17 REPLIES 17
Hein van den Heuvel
Honored Contributor

Re: Reading locked files

 

Do you have control over the code/program for the second user?

The first accessor may/will define what other can do through the FAB$M_SHR.

To allow other reader, specify FAB$V_SHRGET, to allow writers FAB$V_SHRUPD ( and/or PUT, DEL ... all the same really).

Now any subsequent opener must also approve of prior opens.  

So if yo specified a WRITE option in FAB$M_FAC, then the other SHR has to allow write otherwise they'll get that FLK error.

For BLOCKIO (readers0 I suspect you want look at using FAB$V_UPI

Finally if you want to really blow through exclusive access, like BACK/IGNORE=INTERLOCK, then check out the IO Reference manual and look for FIB$V_NOLOCK 

hth,

Hein

 

 

mpradhan
Advisor

Re: Reading locked files

No, I dont have access to the other program which might have locked the file, this could be an applicaiton writing to log files, etc. 

I have tried Block IO with V_UPI to no avail. 

I cannot use BACKUP /IGNORE=INTERLOCK.

All my code is sys$open based and hence moving to sys$qiow would be quite a change to just acheive a read access to a locked file :(.

 

This part of my example code which is trying to open.

pFab->fab$b_fac = FAB$M_BIO | FAB$M_GET; // block IO
pFab->fab$l_xab = (char*)&xabsum;

pFab->fab$b_shr |= FAB$V_SHRGET|FAB$V_SHRPUT|FAB$V_SHRDEL|FAB$V_SHRUPD|FAB$V_UPI;

status = sys$open(pFab);
if (!(status & 1)) {
cerr << "sys$open(" << _sFileName << ") failed error=" << status << endl; <--- I Get the error here when other program has the file locked (see below for other program code).
return -1;
}

 

Program that's locking the file (this is an example code)

h = open( argv[1],O_RDWR, 0666, "shr=nql" );
if( h < 0 )
{
perror("failed open a file");
return 1;
}
printf( "opened..." );

lk.l_type =RDLCK;
lk.l_whence = SEEK_SET;
lk.l_start = 0;
lk.l_len = 0;

rc = fcntl( h, F_SETLK, &lk );
if( rc != 0 )
{
printf( "\n" );
perror( "fcntl failed" );
close(h);
return 1;
}

printf( "file is locked.\n\nPress Enter to unlock..." );

Hein van den Heuvel
Honored Contributor

Re: Reading locked files

As I write in the first reply, if the first opener does not grant shared access then you are dead in the water.

The example shown does NOT grant access, for that to happen you need to add something like  "shr=nql,get"

Please note that NQL is a minor performance option and does NOT change the (FILE) locking behaviour at all. It only applies for RMS RECORD locks, and the C-RTL is not using record mode untill you tell it to (CTX=REC).

Suggestion: to check out what is happening use ANALYZE/SYSTEM ... SET PROC "proc with program running" ... SHOW PROC /RMS=(RAB,FAB)

I added a SLEEP to help with that.

Hein 

#include  <unistd.h>
#include  <stdio.h>
#include  <sys/types.h>
#include  <unistd.h>
#include  <fcntl.h>
main(int argc, char **argv) {
  int h, rc;
  struct flock lk;
  h = open( argv[1],O_RDWR, 0666, "shr=nql,get" );
  if( h < 0 ) {
    perror("failed open a file");
    return 1;
  }
  printf( "opened..." );
  sleep(1000);

  lk.l_type =F_RDLCK;
  lk.l_whence = SEEK_SET;
  lk.l_start = 0;
  lk.l_len = 0;
 rc = fcntl( h, F_SETLK, &lk );
 if( rc != 0 ) {
    printf( "\n" );
    perror( "fcntl failed" );
   close(h);
   return 1;
  }
  printf( "file is locked.\n\nPress Enter to unlock..." );
}
mpradhan
Advisor

Re: Reading locked files

"if the first opener does not grant shared access then you are dead in the water"- holds true only if we are going sys$open() route, not if we are going sys$qio() route, correct?

since I have no control over the other process, is sys$qio() my only programatic opton to be able to read locked files?

Hoff
Honored Contributor

Re: Reading locked files

What's your goal?   Those locks are there to ensure data consistency and integrity, after all.

Override those and the "eavesdropping" application can get corrupt data.

This is basically the same as yanking out a copy of the data from underneath a running relational database. 

As for tools that do this, callable convert and callable backup are both available for generating the requested "data".   Yes, both CONVERT and BACKUP are also available as callable APIs.

Or use the C extensions to RMS, as was mentioned earlier.

As with most folks that have written their own "backup" tools and those that have experimented with such "fun" as the imfamous BACKUP /IGNORE=INTERLOCK, successful results of these sequences are far from certain.   Data can be cached, after all.

There are examples of more properly coordinating shared access around, too.

mpradhan
Advisor

Re: Reading locked files

my goal is to be able to read a locked file, no matter what sharing option the application (the one which currently has the lock) had while opening the file for reading. I am aware that this will be a blind read and will result in inconsistent data.

arent the examples (under hoffman labs) and fab$b_shr for the application which opened the file for writing, i.e. the writer (or the first application which opened the file) controls how the file is shared with subsequent applications?

I have experimented with fab$b_shr and no matter what I do, if the locking applicaiton already has a lock and has no sharing with others, then my read application always fails to open the file. 

If a swithc the code in reader application to use sys$qio instead, then I can open the file with V_NOLOCK. 

Hoff
Honored Contributor

Re: Reading locked files

The share SHR settings are how the first application allows access to subsequent processes; how sharing is declared, and how the application tells RMS what can and should be cached in memory and what should be maintained on disk; how access should be coordinated.   That pointer to that example was an attempt to show you how to add options to the fopen call, given your stated requirement that RMS calls cannot be (directly) used.

Since you want inconsistent data, the switches you need here are RAB$V_NLK and RAB$V_RRL.   Those disable locking and enable what's known as read regardless; you get whatever happens to be on disk at the time, though you should not expect to reliably receive errors or diagnostics even in the event of a locking-related collision.

Now to specify these settings on a fopen?  See the code example mentioned previously and see the help on the creat() function, and see the OpenVMS C documentation for creat() and fopen(), and see the RMS documentation for details on the switches.   If you're on a not-ancient OpenVMS version, use the following command to get an overview of the options available on creat() , and which include the NLK and RRL settings:

$ help crtl creat arguments

Between that and the C documentation, the names of the NLK and the RRL switches (and the assocated RMS documentation for RAB$V_NLK and RAB$V_RRL), and the previously-cited examples of OpenVMS C fopen calls, you should be able to access the requested potentially-corrupt data.  

Or if you're inclined to write somewhat less of your own code, just use callable convert (conv$convert) or callable BACKUP.

Hein van den Heuvel
Honored Contributor

Re: Reading locked files

 >>>  the switches you need here are RAB$V_NLK and RAB$V_RRL.   

I call BS-squared.

- RAB options only play a role when you can get into the file. If the first opener choses to disallow that, like Hoff indicates himself, then that's irrelevant.

- NLK + RRL is inferior to, or with the right SET RMS equal to NQL, which is already requested. A seemingly reasonable but actually futile request.

>> Those disable locking and enable what's known as read regardless;.  

Yes and no. Mostly no. NLK and RRL both still request a record lock, so locking is no disabled. But for NLK the lock is converted to NL immediately upon getting it, and for RRL the record data is returned with a warning it was not locked upon NOT getting the lock. 

Now with SET RMS [/SYSTEM] /QUERY_LOCK=DISABLE the COMBINATION will indeed diable RECORD locking completely, but file locking stays in effect.

As Manoj indicates, only QIO ACCESS + FIB$V_NOLOCK will blow through that if the process r image has.SYSPRV.

Manoj>> If a swithc the code in reader application to use sys$qio instead, then I can open the file with V_NOLOCK. 

Correct.

 

Hein.

 

abrsvc
Respected Contributor

Re: Reading locked files

As Manoj indicates, only QIO ACCESS + FIB$V_NOLOCK will blow through that if the process r image has.SYSPRV.

Manoj>> If a swithc the code in reader application to use sys$qio instead, then I can open the file with V_NOLOCK. 

Correct.

Hein.

 

==================

 

Be warned (as stated before).  This needs to be emphassized here.

Using this method will not cause a flush of the cache and may result in reading stale +/or incomplete data.

Dan