Operating System - OpenVMS
1752750 Members
5114 Online
108789 Solutions
New Discussion юеВ

Re: First lock on a resource

 
SOLVED
Go to solution
ptrskg
Frequent Advisor

First lock on a resource

Hi,

Is there any way to determine if a my call to sys$enqw is the first one, in a cluster, on a specific resource?
The only way I know about is to scan the lock database with sys$getlki to search for the resource name but that would be to expensive.
Thanks for any idea's.

Peter
9 REPLIES 9
Jur van der Burg
Respected Contributor

Re: First lock on a resource

Scanning won't work, because after the scan and before you enqueue someone else may get the resource.

You need to enqueue a resource with the SYNCSTS flag. Depending on the return value you know if there was someone else (SS$_NORMAL) or not (SS$_SYNCH).

Watch out that you don't create timing holes in your lock protocol.

Jur.
ptrskg
Frequent Advisor

Re: First lock on a resource

Hi,

Is it really that simple, can't I get the SS$_SYNCH even if somebody else have a NL lock granted on the resource?

Peter
Hein van den Heuvel
Honored Contributor

Re: First lock on a resource

You may also want to add the LCK$M_EXPEDITE flag.

I typically use the SS$_VALNOTVALID status to decide what to do next.

Cheers,
Hein.
Hoff
Honored Contributor

Re: First lock on a resource

Sequencing locks can have its quirks and (if you don't get it right) risks of weirdnesses and deadlocks; it's often best (as Hein points) to use the lock value block; that'll get you close to what you want.

I'd tend to stay inside the lock manager and use lock states here; doing table scans risks opening windows.

I might well approach the lock management state machine here with an INITIALIZED lock resource (or mayhap with the name PRIMARY, depending on what you're up to) and have the appropriate process(es) request an exclusive lock on that resource during startup. First process gets it, every other requestor is queued. If a queued request for the lock is granted, the original process (or cluster node) has exited and the process now granted the lock performs the necessary configuration investigation and initialization (or restart) processing.

For those unfamiliar with locks and the lock manager, there's an introduction here:

http://64.223.189.234/node/492


Jon Pinkley
Honored Contributor

Re: First lock on a resource

Peter,

Can you explain why it is important to know if you are the first one to hold a resource?

Is there some one-time initialization that must be done and you don't want multiple instances attempting to do it simultaneously?

Also, the question is a bit ambiguous to me. By "first one" do you mean the first time since the cluster was formed that a lock on resource xyzzy was taken? Or do you mean this process is the only one with a lock on the resource which I was just granted, in other words, your lock request caused a resource block to be created? I know of no status that will return that information.

Why do you care is someone else has a NL lock on the resource?

If you take out an EX mode lock with LCK$M_NOQUEUE, and you get SS$_NORMAL status, then you were the first non-NL lock on the resource.

Hein, can you expound on the LCK$M_EXPEDITE flag and SS$_VALNOTVALID status?

Assuming you meant the LCK$M_VALBLK instead of LCK$M_EXPEDITE, I am not convinced that SS$_VALNOTVALID status would indicate that the resource block had just been instantiated (perhaps you were not trying to imply that). If no other holders have written the value block, and you request the value block, I believe that the SS$_VALNOTVALID status will be returned, even if there are other holders of the lock. If you can be sure that everyone is following the rules of your locking protocol, and the then using the value block may be a possible way to detect if you are the first holder of the resource that is obeying the rules of the locking protocol. It isn't clear to me how the LCK$M_EXPEDITE flag would help here.


Jon
it depends
Hein van den Heuvel
Honored Contributor
Solution

Re: First lock on a resource

Jon,

The EXPEDITE option is a race condition protection.
From the RMS listings (RM0LOCKFILE) :

! Create a new Null mode RMS file lock. Avoid lock manager queue lockout
! by using the LCK$M_EXPEDITE option. A Null mode lock creation with the
! LCK$M_EXPEDITE option should be granted synchronously with no stall
! needed so no completion or blocking AST is specified. If not granted
! synchronously then bugcheck. On success, set granted mode to Null mode.

Yes, you would also need LCK$M_VALBLK.
If the value block is not valid, then for all practical purposes you are the first one with the lock. Convert up, check again, initialize, down and away you go.

fwiw,
Hein.
John Gillings
Honored Contributor

Re: First lock on a resource

Peter,

If you need to know if you're the first in the cluster, I'd suggest you use an independent resource. Have resources RES and RES_1ST.

Step 1 is to request RES_1ST EX mode with flag LCK$M_NOQUEUE. If the call succeeds, you're the first. Keep the lock at EX mode.

Use the other resource however you've been using it already, without knowing or caring about the sequence of requests. Indeed, in a race you could potentially be second or subsequent requestor for RES, but RES_1ST arbitrates who is considered "first".

Having an independent resource helps avoid timing windows. It can also be used as a "deadman" lock if the role of "first" needs to failover. (if you don't get your lock on the 1st attempt, issue an EX mode $ENQ against it with an AST to fire if you ever get it).
A crucible of informative mistakes
ptrskg
Frequent Advisor

Re: First lock on a resource

Hi,
Thanks all for your input to my problem.
I will go for Hein's solution using the "lock value block" validation mechanism.

Peter
Jon Pinkley
Honored Contributor

Re: First lock on a resource

Peter,

We are still guessing what problem you were trying to solve.

You may want to read this earlier thread.

http://forums.itrc.hp.com/service/forums/questionanswer.do?threadId=1178555

And read the sections about the lock value block and things that can invalidate it here.

http://h71000.www7.hp.com/doc/82FINAL/4527/4527pro_045.html

I still maintain that LCK$M_EXPEDITE will not help you determine if you were the first holder of the lock, and I would not describe the problem it avoids as a race condition. Its purpose is to allow a new NL lock request to be granted synchronously even when there are locks waiting in the resource's WAIT queue. Without that flag, a NL lock can be blocked indefinitely. This is discussed in the other thread I referenced, and it is easy to reproduce. I attached a log file to my reply to the first thread above (dated Nov 24, 2007 03:46:48 GMT) Here's a direct link to the attachment

http://forums.itrc.hp.com/service/forums/getattachment.do?attachmentId=296046&ext=.txt

This is also described in the excellent, but long out of print, "VAXCluster Principles" by Roy G. Davis in Figure 6-10 at the top of page 6-12.

This is not in conflict with the comments in the code that Hein referenced.

You can also read the manual.

Good luck,

Jon
it depends