| From: DEC:.REO.REOVTX::HUDSON "[email protected] - UK Software
Partner Engineering 830-4121" 22-APR-1997 14:16:24.86
To: nm%vbormc::"[email protected]"
CC: HUDSON
Subj: POINT 26401, example of lock manager
Hello Kjell R Christensen,
Thank-you for your ASAP question regarding example usage of the VMS lock
manager.
Unfortunately I do not know which COBOL example you are referring to, so I
don't know which lock manager routines you are interested in. But below is a
program in Pascal which shows how you can take out a lock and detect someone
else trying to use it (run it in two separate DCL sessions and you can see the
effect...
If this doesn't answer your question, please could you send me a mail with more
details of what kind of example you need
Regards
Nick Hudson
Digital Software Partner Engineering
[inherit ('sys$share:starlet', 'sys$share:pascal$lib_routines')]
program paslock(input,output);
type
uword = [word] 0..65535;
ubyte = [byte] 0..255;
lksb = packed record
cond_val : uword;
reserved : uword;
lkid : unsigned;
valblk : packed array [1..16] of ubyte;
end;
var
stat : unsigned;
ans : char;
event_flag : [volatile] unsigned;
my_lksb : lksb;
[asynchronous] procedure blkast_rtn;
{ We get here when our lock is stopping someone else have the lock }
begin
$setef(event_flag);
end;
begin
{ get an event flag for us to use }
stat := lib$get_ef(event_flag);
if (stat <> SS$_NORMAL) then lib$stop(stat);
ans := 'N';
while (ans <> 'Y') do
begin
write('Type "Y" to attempt to get hold of the lock ? ');
readln(ans);
end;
{ Make sure event flag is clear before we start }
$clref(event_flag);
my_lksb := zero;
stat := $enqw( lkmode := lck$k_exmode,
lksb := my_lksb,
resnam := 'MY_LOCK',
blkast := blkast_rtn);
if (stat <> SS$_NORMAL) then
begin
writeln('call to $enq failed, status was : ',stat);
lib$stop(stat);
end;
writeln('lock has been granted; waiting for someone to ask for it');
stat := $waitfr(event_flag);
if (stat <> SS$_NORMAL) then lib$stop(stat);
ans := 'N';
while (ans <> 'Y') do
begin
write('Someone wants the lock. Type "Y" to release it ? ');
readln(ans);
end;
stat := $deq(my_lksb.lkid);
if (stat <> SS$_NORMAL) then lib$stop(stat);
ans := 'N';
while (ans <> 'Y') do
begin
write('Lock has been dequeued. Type "Y" to finish ? ');
readln(ans);
end;
end.
|
| From: VBORMC::"[email protected]" "Kjell-Roald Christensen" 23-APR-1997 19:28:49.31
To: [email protected]
CC:
Subj: Re: POINT 26401, example of lock manager
<Computed Subform>
From: Kjell-Roald Christensen/SATCOM/NORWAY/NERA on 23.04.97 20:25
To: hudson @ rdgeng.enet.dec.com
cc:
<Computed Subform>
Dear Mr. Hudson
The example you gave me was exactly what I was looking for. I have
tested the program and it works fine in a cluster with distributed lock
manager.
However, some new questions did arise during the testing!
Could lock manager easily be used in a cluster environment to handle
active and standby processes? The lock,exe program gave confirmation to
that question. But can lock manager be used to switch P1,...PN from
NODE1 over to NODE2 in situations where P3 on NODE 1 fails/dies/get into
an exception state ? Either all processes are running 'correctly' on
the node or they all switch control (release the locks) over to the
standby node. The drawing below illustrate the simplest solution, were
each process independently will be switched over.
NODE 1
NODE 2
P1 -----------------> LOCK_P1<---------------------- P1
P2 -----------------> LOCK_P2<---------------------- P2
P3 etc... ...
P3
..
PN PN
How could lock-manger be used to make them all switch if one of them
fails?
Since I got such an adequate answer with the lock.exe example, I thought
there still might be some good solutions left behind.
I would appreciate, if possible, some guidelines on this matter, Any
references to relevant books are also welcome.
Our project are also having some difficulties with the interpretation of
message passing over the UCX TCP/IP.
The question is as follows:
Is it possible to read one and only one message received on a TCP/IP
connection if the sender set the PUSH flag for each message?
We have no way to make sure that a message is read before we receives a
new. Let say we receives two messages with the PUSH flag set in both.
Will the QIO read call return ALL bytes received since last read (in
this case all bytes in both messages) or only the first message?
When using UCX, how is the PUSH flag set? (Default??)
We use Open VMS 7.1 and UCX 4.1.
Best regards,
Kjel R. Christensen
hudson @ rdgeng.enet.dec.com
22.04.97 15:08
To: Kjell-Roald Christensen/SATCOM/NORWAY/NERA
cc: hudson @ rdgeng.enet.dec.com (bcc: Kjell-Roald
Christensen/SATCOM/NORWAY/NERA)
Subject: POINT 26401, example of lock manager
Hello Kjell R Christensen,
Thank-you for your ASAP question regarding example usage of the VMS lock
manager.
Unfortunately I do not know which COBOL example you are referring to, so I
don't know which lock manager routines you are interested in. But below is
a program in Pascal which shows how you can take out a lock and detect
someone else trying to use it (run it in two separate DCL sessions and you
can see the effect...
If this doesn't answer your question, please could you send me a mail with
more details of what kind of example you need
Regards
Nick Hudson
Digital Software Partner Engineering
[inherit ('sys$share:starlet', 'sys$share:pascal$lib_routines')]
program paslock(input,output);
type
uword = [word] 0..65535;
ubyte = [byte] 0..255;
lksb = packed record
cond_val : uword;
reserved : uword;
lkid : unsigned;
valblk : packed array [1..16] of ubyte;
end;
var
stat : unsigned;
ans : char;
event_flag : [volatile] unsigned;
my_lksb : lksb;
[asynchronous] procedure blkast_rtn;
{ We get here when our lock is stopping someone else have the lock }
begin
$setef(event_flag);
end;
begin
{ get an event flag for us to use }
stat := lib$get_ef(event_flag);
if (stat <> SS$_NORMAL) then lib$stop(stat);
ans := 'N';
while (ans <> 'Y') do
begin
write('Type "Y" to attempt to get hold of the lock ? ');
readln(ans);
end;
{ Make sure event flag is clear before we start }
$clref(event_flag);
my_lksb := zero;
stat := $enqw( lkmode := lck$k_exmode,
lksb := my_lksb,
resnam := 'MY_LOCK',
blkast := blkast_rtn);
if (stat <> SS$_NORMAL) then
begin
writeln('call to $enq failed, status was : ',stat);
lib$stop(stat);
end;
writeln('lock has been granted; waiting for someone to ask for it');
stat := $waitfr(event_flag);
if (stat <> SS$_NORMAL) then lib$stop(stat);
ans := 'N';
while (ans <> 'Y') do
begin
write('Someone wants the lock. Type "Y" to release it ? ');
readln(ans);
end;
stat := $deq(my_lksb.lkid);
if (stat <> SS$_NORMAL) then lib$stop(stat);
ans := 'N';
while (ans <> 'Y') do
begin
write('Lock has been dequeued. Type "Y" to finish ? ');
readln(ans);
end;
end.
% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from mail.vbo.dec.com (mail.vbo.dec.com [16.36.208.34]) by
vbormc.vbo.dec.com (8.7.3/8.7) with ESMTP id UAA28538 for
<[email protected]>; Wed, 23 Apr 1997 20:19:37 +0200
% Received: from server21.digital.fr (server21.digital.fr [193.56.15.21]) by
mail.vbo.dec.com (8.7.3/8.7) with ESMTP id UAA10134 for
<[email protected]>; Wed, 23 Apr 1997 20:28:11 +0200 (MET DST)
% Received: from notesmta.nera.no (gatekeeper.nera.no [195.1.205.130]) by
server21.digital.fr (8.7.5/8.7) with SMTP id UAA28174 for
<[email protected]>; Wed, 23 Apr 1997 20:33:27 +0200 (MET DST)
% Received: by notesmta.nera.no(Lotus SMTP MTA v1.05 (274.9 11-27-1996)) id
41256482.0065772B ; Wed, 23 Apr 1997 19:28:16 +0100
% X-Lotus-FromDomain: NERA
% From: "Kjell-Roald Christensen"<[email protected]>
% To: [email protected]
% Message-ID: <[email protected]>
% Date: Wed, 23 Apr 1997 20:25:50 +0100
% Subject: Re: POINT 26401, example of lock manager
% Mime-Version: 1.0
% Content-type: text/plain; charset=us-ascii
|
| From: DEC:.REO.REOVTX::HUDSON "[email protected] - UK Software
Partner Engineering 830-4121" 25-APR-1997 17:04:46.21
To: nm%VBORMC::"[email protected]"
CC: HUDSON
Subj: Re: POINT 26401, example of lock manager
Hello Kjel R. Christensen
Thanks for your mail.
Regarding the question on locking, I'll first put down what I think you are
describing:
You have two nodes in a cluster, each with a set of processes, P1..Pn.
You have a set of resources, R1..Rn.
On one of the nodes in the cluster, each process P1..Pn has a lock granted on a
corresponding resource, i.e. P1 locks R1, ... Pn locks Rn.
If any of the processes that owns a lock on a resource fails, then you want all
of the processes on that node to give up their locks so that the corresponding
processes on the other node will pick up all of those locks.
There are two techniques I think you'll use here. First is the "Dead Man's
Lock", and second is "Doorbell Lock"
Dead Man's Lock
---------------
A dead man's lock is so called because a lock is used to detect when a
component has failed, or died. It is a way to make sure that if you have many
processes running at once, only one of them is the "master" at any time, but if
that process dies, someone else will take over. This is how you implement it
on VMS:
As each process starts, it tries to take out an EX lock on a resource, say
"DML". If you use the flag "NOQUEUE", then that call will return straight
away. If it returns "SS$_NOTQUEUED", then you know that some other process
already has the lock. If the service returns success, then you know that you
have the lock.
If you have the lock, then you are the master process , and no-one else is
running yet. You then proceed to do whatever the "master" process does.
If you don't have the lock, then some other process somewhere is the master.
In this case, you must now call $ENQ (not $ENQW) saying you want to queue an EX
lock on the "DML" resource, and specifying an ast routine to run once the
request completes. Once you've queued this lock request, you carry on doing
whatever your program does when it's not the master process (maybe this is just
sitting around doing nothing).
Once your ast routine gets called, you know that you have the lock, which means
that the master process went away for some reason, and you are now the master.
Now you have to "tell" the non-ast part of your program to start acting as the
master. Typically you do this by setting an event flag in the ast routine
which the program will be looking at periodically.
Since locks are cluster-wide, on VMS you can use this technique to deal with a
node going away. In fact this is the technique that the VMS queue manager
uses.
Doorbell Lock
-------------
A doorbell lock is another way you can use the lock system to communicate
between processes on a cluster. Here, everyone takes out a lock on a resource
in such a mode that there are no conflicts - for example, everyone takes out a
lock in CR mode. They use the "blkast" parameter of $ENQ to specify a blocking
ast routine. When something happens such that one person wants to notify
everyone else of something, he converts his CR lock to an incompatible mode,
say EX. At this stage all the people with CR locks will be "blocking" the EX
lock, and they can be notified of this with a "blocking ast".
In your blocking AST routine, you convert your lock down to NL, which allows
the person who wants EX to get it (as soon as everyone has gone to NL). After
you convert to NL, you then try and convert back to CR again. So that you
don't get your CR lock back before the EX lock has been granted, you use
LCK$M_QUECVT in the call to $ENQ when you convert from NL to CR.
So normally, everyone has CR. When someone wants to "tell" the others
something, he converts to EX. Once the conversion to EX completes, he knows
that everyone else must have gone to NL. He can now convert back to CR, at
which point everyone else will also be allowed to go to CR, and you're back to
the beginning.
The important thing here is what people do in the blocking ast routine.
This depends on what information you are trying to communicate. As a very
simple example, perhaps one process might put a message in a text file called
"A.A", then take out the EX lock. When the others see the "doorbell" go, then
they know it's time to look in "A.A". Obviously you could use the lock-value
block to pass round extra information about the message, such as a filename.
I think you want to use a combination of these techniques.
For example, say you have a "control process" CP. CP is the first part of your
application to start running. It takes out a "cluster" dead man's lock, and so
whichever CP gets that "clustrer" lock knows it's on the "master node".
When CP is running, then your individual P1..Pn processes can start. They talk
to the CP on their node which (a) tells CP that they exist, and (b) lets CP
tell them whether they're on the "master node".
You then use a suitable combination of dead man's and doorbell locks to (a) let
CP know when any of the P processes has died, and (b) let CP tell all the P
processes that they must relinquish their L locks.
Whenever a P process dies, you can use a dead man's lock to make sure CP knows.
CP can then use a doorbell lock to tell all the other P processes to let go of
their locks. When they've done this, CP can let go of the "cluster" lock,
which means that the other node in the cluster will become the master, and CP
on that node can tell its P processes to start work.
Does this help?
I haven't looked at your TCP question yet, I'll do that next
Regards
Nick Hudson
Digital Software Partner Engineering
|
| From: DEC:.REO.REOVTX::HUDSON "[email protected] - UK Software Partner Engineering 830-4121" 28-APR-1997 11:43:25.91
To: VBORMC::"[email protected]"
CC: HUDSON
Subj: Re: POINT 26401, tcp/ip messages
Hello Kjel Christensen,
> Is it possible to read one and only one message received on a TCP/IP
> connection if the sender set the PUSH flag for each message?
> We have no way to make sure that a message is read before we receives a
> new. Let say we receives two messages with the PUSH flag set in both.
> Will the QIO read call return ALL bytes received since last read (in
> this case all bytes in both messages) or only the first message?
> When using UCX, how is the PUSH flag set? (Default??)
> We use Open VMS 7.1 and UCX 4.1.
If you are using stream protocol, then by definition you just have a stream of
bytes being sent/received. The system doesn't recognise any record boundaries,
and so your application must take care of this itself.
I don't believe that the setting of the PUSH option makes any difference here;
in the above case, your application won't see "two messages", it will just see
a load of bytes appearing. The bytes will be guaranteed to arrive in the order
that they were sent, but you won't get any kind of delimiter to tell you that
there were two (or more) separate "send()" (or whatever) operations at the
other end.
One way your application might work is if the sender and received agree that
each "message" is prefixed by a 32 bit code to say how big it is. Then when
you receive a byte stream, you can look at the first few bytes to work out how
much of the subsequent byte stream is the "message". In this case you should
use htonl() and ntohl() to format the 32 bit value, to guard against byte
ordering problems.
If you want record mode transmission then you have to use UDP protocol. But
this has the disadvantages that you have to code your application to take care
of messages being lost, received in the wrong order, or received multiple
times.
I hope this information is useful to you
Regards
Nick Hudson
Digital Software Partner Engineering
|
|
To: [email protected]
cc:
Subject: Re: POINT 26401, example of lock manager
Thanks for all help !
Currently developing a program that will make use of the automatic
switch-over algorithm witch you spesified i the mail. Looks good so far !
We are currently using C under OpenVMS for this, but are missing a LINT
pre-compiler. I looked up in the SPDs and found out that KAP (LINT for C
ver. 3.0 for Digital UNIX) is the only one arround !? .
Do we have a LINT for OpenVMS ??
Best regards,
Kjell R.
% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from mail.vbo.dec.com (mail.vbo.dec.com [16.36.208.34]) by
vbormc.vbo.dec.com (8.7.3/8.7) with ESMTP id QAA08033 for
<[email protected]>; Mon, 5 May 1997 16:46:16 +0200
% Received: from server21.digital.fr (server21.digital.fr [193.56.15.21]) by
mail.vbo.dec.com (8.7.3/8.7) with ESMTP id QAA00130 for
<[email protected]>; Mon, 5 May 1997 16:57:57 +0200 (MET DST)
% Received: from notesmta.nera.no (gatekeeper.nera.no [195.1.205.130]) by
server21.digital.fr (8.7.5/8.7) with SMTP id RAA00466 for
<[email protected]>; Mon, 5 May 1997 17:03:29 +0200 (MET DST)
% Received: by notesmta.nera.no(Lotus SMTP MTA v1.05 (274.9 11-27-1996)) id
4125648E.00574423 ; Mon, 5 May 1997 16:53:10 +0100
% X-Lotus-FromDomain: NERA
% From: "Kjell-Roald Christensen"<[email protected]>
% To: [email protected]
% Message-ID: <[email protected]>
% Date: Mon, 5 May 1997 15:55:20 +0100
% Subject: Re: POINT 26401, example of lock manager
% Mime-Version: 1.0
% Content-type: text/plain; charset=us-ascii
|