|
FunctionThe v_lockctl service controls
advisory byte-range locks on a file.
RequirementsOperation |
Environment |
---|
Authorization: |
Supervisor state or problem state, any PSW key |
Dispatchable unit mode: |
Task |
Cross memory mode: |
PASN = HASN |
AMODE (BPX1VLO): |
31-bit |
AMODE (BPX4VLO): |
64-bit |
ASC mode: |
Primary mode |
Interrupt status: |
Enabled for interrupts |
Locks: |
Unlocked |
Control parameters: |
All parameters must be addressable by the caller and in the
primary address space. |
FormatCALL BPX1VLO,(OSS,
Command,
Vlock_length,
Vlock,
Return_value,
Return_code,
Reason_code)
AMODE 64 callers use BPX4VLO with the same parameters.
Parameters- OSS
- Supplied and returned parameter
- Type:
- Structure
- Length:
- OSS#LENGTH (from the BPXYOSS macro)
The name of an area that contains operating-system-specific
parameters. This area is mapped by the BPXYOSS macro (see BPXYOSS — Map operating system specific information).
- Command
- Supplied parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword that contains one of the
integer values that is mapped in the BPXYVLOK macro and indicates
the action that is to be performed. For the list of commands, see BPXYVLOK — Map the interface block for v_lockctl.
- Vlock_length
- Supplied parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword that contains the length
of Vlock. To determine the value of Vlock_length, use the BPXYVLOK
macro (see BPXYVLOK — Map the interface block for v_lockctl).
- Vlock
- Supplied and returned parameter
- Type:
- Structure
- Length:
- Specified by the Vlock_length parameter
The name of an area that contains the lock request
information. This area is mapped by the BPXYVLOK macro (see BPXYVLOK — Map the interface block for v_lockctl).
- Return_value
- Returned parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword in which the v_lockctl service
returns 0 if the request is successful, or -1 if
it is not successful.
- Return_code
- Returned parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword in which the v_lockctl service
stores the return code. The v_lockctl service returns Return_code
only if Return_value is - 1. See z/OS UNIX System Services Messages and Codes
for a complete list of possible return code values. The v_lockctl
service can return one of the following values in the Return_code
parameter: Return_code |
Explanation |
---|
EAGAIN |
The Lock command was requested, but the lock conflicts with
a lock on an overlapping part of the file that is already set by another
locker. |
EDEADLK |
The Lockwait command was requested, but the potential for deadlock
was detected. The following reason codes can accompany the return
code: JRBrlmDeadLockDetected, JRBrlmPromotePending, JRBrlmAlreadyWaiting,
JRBrlmUnlockWhileWait. |
EINTR |
A LockWait request was interrupted by a signal. |
EINVAL |
Parameter error. The following reason codes can accompany the
return code: JRBadEntryCode, JRInvalidVlok, JRInvalidServerPid, JRNoLockerToken,
JRBrlmLockerNotRegistered, JRBrlmBadLType, JRBrlmObjectMissing, JRBrlmInvalidRange,
JRBrlmBadL_Whence. |
EPERM |
The operation is not permitted. The caller of the service is
not registered as a lock server. |
ENOENT |
The LockCancel command was requested, but an
exactly matching lock request was not found on the object's waiting
queue. |
- Reason_code
- Returned parameter
- Type:
- Integer
- Length:
- Fullword
The name of a fullword in which the v_lockctl service
stores the reason code. The v_lockctl service returns a Reason_code
only if Return_value is -1. Reason_code further qualifies
the Return_code value. See z/OS UNIX System Services Messages and Codes
for the reason codes.
Usage notes- The v_lockctl service locks out other cooperating lockers from
part of a file, so that the locker can read or write to that part
of the file without interference from others.
All locks are advisory
only. Client and local processes can use locks to inform each other
that they want to protect parts of a file, but locks do not prevent
I/O on the locked parts. A process that has appropriate permissions
on a file can perform whatever I/O it chooses, regardless of the locks
that are set. Therefore, file locking is only a convention, and it
works only when all processes respect the convention.
- Registering as a locker (Vlok#RegLocker): Each locker
must be registered before it issues any lock requests. On a Vlok#RegLocker command,
the following Vlock fields are provided by the caller:
- VlokID
- The Vlok#ID (from the BPXYVLOK macro).
- VlokLen
- The length of the Vlock structure.
- VlokServerPID
- The process ID of the lock server. If 0 is specified, the caller's
PID is used.
- VlokClientPID
- A server-generated process ID that uniquely identifies the client
within this server PID.
Other fields in the Vlock area should be set to
zeros.
The following Vlock field is returned to the caller: - VlokLockerTok
- A token to identify the locker on subsequent lock requests.
- On a Vlok#Query, Vlok#Lock, Vlok#LockWait, or Vlok#Unlock command,
the following Vlock fields are provided by the caller:
- VlokID
- The Vlok#ID (from the BPXYVLOK macro).
- VlokLen
- The length of the Vlock structure.
- VlokLockerTok
- The locker.
- VlokClientTID
- The client's thread ID.
- VlokObjClass
- The file object class. The possible classes are defined in the
BPXYVLOK macro; see BPXYVLOK — Map the interface block for v_lockctl.
- VlokObjID
- The file object uniquely within the class. For an HFS file, VlokObjID
contains the device number and FID of the file.
- VlokObjTok
- A token that was returned on the previous lock request for this
object. This field is optional, but will improve performance for multiple
lock requests.
- VlokBrlk
- Lock information describing the byte-range. This area is mapped
by BPXYBRLK (see note 5). The following
BPXYBRLK fields must be provided:
Command |
Required fields |
---|
Vlok#Query |
l_type, l_whence, l_start, l_len |
Vlok#Lock |
l_type, l_whence, l_start, l_len |
Vlok#LockWait |
l_type, l_whence, l_start, l_len |
Vlok#Unlock |
l_whence, l_start, l_len |
- VlokVnToken
- (Optional) The vnode token for a UNIX file
system object. The use of this optional parameter can improve the
performance of any operation that specifies a file system object.
Additionally, for the Vlok#UnLoadLocks function,
this also indicates that share reservations for the file are to be
appended to the unloaded byte range locks (see note 11 for more information).
Other fields in the Vlock area should be set to
zeros.
The following Vlock fields are returned to the caller: - VlokObjTok
- A token to identify the object on a subsequent lock request.
- VlokBrlk
- On Query, lock information that describes a lock that would prevent
the proposed lock from being set.
- On a Vlok#Lock, Vlok#LockWait, and Vlok#LockAsy command,
the caller can pass an open token in the OSS by providing the following
field:
- OssOpenToken
- Contains an open token with which the byte range lock should be
associated
For open tokens other than those created with OPEN_NLM_SHR,
the lock owner becomes associated with the open token. Thus, when
a v_close() is issued using that open token, all
byte range locks on this file that were obtained by this lock owner
will be released.
- Locking operations are controlled with a structure that
is mapped by BPXYBRLK. This structure is needed whether the request
is for setting a lock, releasing a lock, or querying a particular
byte range for a lock. The following is a description of the BPXYBRLK
structure:
- Obtaining locks (Vlok#Lock and Vlok#LockWait): Locks can
be set by specifying a Vlok#Lock as the Command
parameter. If the lock cannot be obtained, a return value of -1 is
returned, along with an appropriate return code and reason code.
Locks
can also be set by specifying Vlok#LockWait as the
Command parameter. If the lock cannot be obtained because another
process has a lock on all or part of the requested range, the LockWait
request waits until the specified range becomes free and the request
can be completed.
If a signal interrupts a call to
the v_lockctl service while it is waiting in a LockWait operation,
the function returns with a return value of -1, and
a return code of EINTR.
LockWait operations have the potential
for encountering deadlocks. This happens when locker A is waiting
for locker B to unlock a region, and B is waiting for A to unlock
a different region. If the system detects that a LockWait request
might cause a deadlock, the v_lockctl service returns with a return
value of -1 and a return code of EDEADLK.
- Asynchronous locking:
- Obtaining an asynchronous lock (Vlok#LockAsy): The Vlok#LockAsy
command parameter is used to request an asynchronous lock. The lock
request is either satisfied immediately or is queued for asynchronous
completion. The v_lockctl call will not block. The caller should expect
to receive the asynchronous lock completion through the sigtimedwait() or sigwaitinfo() interfaces.
These provide an event queue for lock completions based on queued
signals and is the same as that used with asynchronous I/O completions.
The caller can specify the signal number and signal value to pass
back on the asynchronous completion.
The Vlock structure
is set up just as it would be for the Vlok#LockWait function with
the addition of a caller-supplied Aiocb structure that specifies the
signal information and holds the results of the completed asynchronous
request. The new fields in the Vlock structure for this function are: - VlokAiocbLen
- Length of the Aiocb structure
- VlokAiocb
- Address of the Aiocb structure
The Aiocb must remain valid for the life of
an asynchronous request and its use is similar to that for an aio_read
call. The following Aiocb fields are provided by the caller: - aio_sigevent.sigev_signo
- The signal number
- aio_sigevent.sigev_value
- An application-specific data value to be passed with the signal
- aio_exitdata
- An application data area (not touched by the system)
The rest of the Aiocb should be zeroed out.
The
following Aiocb fields are returned to the caller: - aio_rv
- The return value
- aio_rc
- The return code
- aio_rsn
- The reason code
The Return_value from v_lockctl() indicates
the outcome of the call, as follows: - +1
- The lock will be granted asynchronously.
- 0
- The lock was granted immediately.
- –1
- The lock request failed as indicated by the accompanying return
code and reason code.
When the Return_value from v_lockctl() is +1,
the final result of the lock request is determined when the completion
signal is pulled from the signal queue using sigtimedwait() or sigwaitinfo().
At that point, the aio_rv field will contain 0 if
the lock was granted or –1 (with accompanying values
in aio_rc and aio_rsn) if the lock was not granted. Generally, a request
will only fail asynchronously if it is canceled.
When
the Return_value from v_lockctl() is 0 or –1,
the request has immediately succeeded or failed, respectively, and
no signal is sent.
As with any asynchronous operation,
the request may complete before the v_lockctl() call returns to the
caller.
A lock owner may only have one outstanding lock request
at a time on any particular range. This includes pending asynchronous
requests and blocked synchronous requests. In other words, waiting
locks for the same owner cannot intersect. Similarly, unlock requests
may not be issued for any range that intersects with a pending lock
request from the same lock owner.
- Canceling an asynchronous lock request (Vlok#LockCancel): To
cancel a specific, outstanding asynchronous lock request, call the
v_lockctl service with a command parameter of Vlok#LockCancel and
a Vlock structure that contains all the information from the original
Vlok#LockAsy request: object, owner, Brlk information, and Aiocb.
You
must use the same Aiocb on both the original Vlok#LockAsy request
and theVlok#LockCancel request and the Aiocb must not have been modified
between the two calls. When the Vlok#LockAsy request returns with
a return value of 1, an asynchronous request token is also returned
in the Aiocb and that token must be present on any subsequent call
to cancel the lock request.
An asynchronous lock request can
only be canceled if it is still waiting for the lock to be granted.
When a pending request is successfully canceled, the Return_value
from v_lockctl() will be 0 and
a lock completion signal will be sent with an aio_rc of ECANCELED.
When an exact match for the request is not found on the object's waiting
queue, the Return_value from v_lockctl() will be –1 and
the Return_code will be ENOENT.
There is a race condition
between a pending lock being canceled and its being granted, so there
is always a chance that the call to cancel the lock request will fail
because the successful lock completion signal has already been sent.
Note, too, that at the time the v_lockctl call to cancel the lock
request returns to the caller, the completion signal (either for the
lock being granted or for its being canceled) may still be on the
application's signal queue. Therefore, the application must handle
the coordination between the caller of the cancel request and the
handler of the completion signal.
- Refer to note 16 for the effects
of a purge request on asynchronous locks.
- Effects of changing file system ownership in a sysplex: If
the ownership of a file system is changed within a sysplex environment
(for instance, by using the chmount shell command), pending asynchronous
locks will be lost. This special situation is indicated by a lock
failure of the original request with an aio_rc of EAGAIN and a lower
half-word value in aio_rsn of 0x0607 (the value of
the JrOwnerMoved reason code). The v_lockctl call must be issued again
to request the asynchronous lock from the new owner. At such time,
the lock may be immediately granted or it may again enter a pending
state.
- Determining lock status (Vlok#Query): A process can determine
locking information about a file by using Vlok#Query as the
Command parameter. The VlokBrlk structure should describe a lock operation
that the caller would like to perform. When the v_lockctl service
returns, the structure is modified to describe the first lock found
that would prevent the proposed lock operation from completing successfully.
If
a lock is found that would prevent the proposed lock from being set,
the Query request returns a modified structure whose l_whence value
is always SEEK_SET, whose l_start value gives the offset of the locked
portion from the beginning of the file, whose l_len value is set to
the length of the locked portion of the file, and whose l_pid value
is set to the ClientProcessID of the locker that is holding the lock.
If there are no locks that would prevent the proposed lock operation
from completing successfully, the returned structure is modified to
have an l_type of F_UNLCK, but otherwise it remains unchanged.
- Multiple lock requests: A locker can have several locks
on a file simultaneously, but can have only one type of lock set on
any given byte. Therefore, if a locker sets a new lock on part of
a file that it had previously locked, the locker has only one lock
on that part of the file, and the lock type is the one that was given
by the most recent locking operation.
- Returning blocker information: A request to the v_lockctl
service that cannot be granted can return information about the lock
that is blocking the request from being granted. The blocking lock
shares at least part of the range that was requested and may be from
a granted lock range or a waiting lock request. The returned information
is in the form of a BRLM_RangeLock structure, defined in IGWLBINT
for PL/X and in BPXYVFSI for C.
The caller requests the return
of blocker information by specifying in VlokBlockingLock the
address of an area in primary storage where the output BRLM_RangeLock
may be placed. VlokBlkLockLen specifies the length of this
output area. The storage for the output area is assumed to be in the
caller's key.
Blocker information can be returned in
the following cases: - A Vlok#Lock or Vlok#LockWait request fails with a return code
of EAGAIN or EDEADLK
- A Vlok#Query request finds a blocking lock
- A Vlok#LockAsy request returns with a Return_value of +1
The output BRLM_RangeLock area (or, at a minimum, the server
PID in the first word) should be zeroed out before the call to the
v_lockctl service. If the contents are changed upon completion of
the call, then information about a blocking lock was returned. Note
that the blocking lock was blocking this request when the v_lockctl
call was issued but is subject to change at any time.
- Query all locks for an object (Vlok#UnLoadLocks): The
Vlok#UnLoadLocks request provides an interface to the BRLM UnloadLocks
function and also obtains the share reservations for file system objects.
The
information is returned as a chain of BRLM_UnloadLocksList structures,
each of which contains control information and an array of (Object,
Rangelock) pairs, each of which describe one locked range or share
reservation. The storage for the chain of structures is obtained in
the caller's primary address space, is in the caller's key, and is
owned by the caller's TCB. Each structure in the chain must be freed
by the caller using the MVS™ storage
release service. The unloaded lock list segments may be of different
lengths so the ull_length field must be used when the storage is released.
These structures are defined in IGWLBINT for PL/X and in BPXYVFSI
for C.
The following Vlock fields are provided by the caller: - VlokObject
- The class and ID of the object
- VlokUllSubPool
- An MVS storage subpool number
for the areas to be obtained. For unauthorized callers, this number
must be between 1 and 127.
- VlokUllRetWaiters
- When set to Vlok#RetWaiters, all locks for the specified objects
are returned, including waiting locks, pending asynchronous locks,
and held locks. When set to Vlok#RetHeldOnly, only held locks for
the specified objects are returned. When set to Vlok#RetAllObj, all
the locks for all the objects are returned. Waiting locks are identified
by the RlWaiting flag in the BRLM_Rangelock structure.
- VlokUllMaskLen and VlokUllInMaskPtr
- (Optional) When VlokUllMaskLen is non-zero, it specifies the length
of the object mask whose address is passed in VlokUllInMaskPtr.
This is a 16-byte mask as defined by VlokObjectMask. The VlokObject
and this mask are used together to determine which locks are returned.
The mask is logically ANDed with the object ID of each lock and
the result is compared with the VlokObject that is passed. The algorithm
is as follows: if ( (LockObject & PassedObjectMask) == VlokObject )
{ The lock will be returned. }
For example, to get all
the locks for all objects that are files in the UNIX File System with a devno of 8, specify
the following. (This example is shown in hexadecimal with blanks
inserted for readability.) VlokObject: 00000000 00000008 00000000 00000000
Mask: FFFFFFFF FFFFFFFF 00000000 00000000
VlokUllRetWaiters
can be set to Vlok#RetHeldOnly or to Vlok#RetWaiters to further filter
what locks are returned. Note that if VlokUllRetWaiters is set to
Vlok#RetAllObj, the object mask is ignored and all locks for all objects
are returned.
- VlokVnToken
- (Optional) A vnode token for the VlokObject. Also indicates that
the object's share reservations should be appended to the byte range
locks that are returned. This must be the same file as identified
by the VlokObject.
The following Vlock field is returned to the
caller: - VlokUllOutListPtr
- The address of the first member of the output chain of BRLM_UnloadLocksList
structures, or zero.
Zero or more BRLM_UnloadLocksList structures
will be produced by BRLM. For file system objects when a vnode token
is supplied, the unloaded locks will be followed by zero or more BRLM_UnloadLocksList
structures for the share reservations. Share reservations may be placed
in the unused slots of the last BRLM structure. The BRLM_UnloadLocksList
structures may have varying numbers of locks returned in their array
section so the ull_count field must be used to step through the arrays.
The Return_value will contain the total number of locks and share
reservations that were returned.
For each byte range lock, the
rl_access field will be set to the type of lock: rl_shared, rl_excl,
or rl_shr2excl.
For each share reservation, the rl_access field
will be set to rl_openmodes. The rl_openacc and rl_opendeny fields
will be set to the current Shr_Access and Shr_Deny modes, respectively,
for that open. (Refer to v_open (BPX1VOP, BPX4VOP) — Open or create a file for more information
about these modes.)
- Releasing locks (Vlok#Unlock): When an Vlok#Unlock request
is made to unlock a byte region of a file, all locks that are held
by that locker within the specified region are released. In other
words, each byte that is specified on an Unlock request is freed from
any lock that is held against it by the requesting locker.
- Locks are not inherited by a child process that is created with
the fork service.
- Effects of close and process termination: All locks (those
that are owned, pending, or waiting) for a given lock owner on a specific
file will be released if any of the owner's open tokens for that file
are closed with a v_close call. This includes any open token that
was opened by this lock owner or one that was opened by a different
lock owner but was subsequently used by this lock owner on a v_lockctl
call. Owned locks are unlocked; pending and waiting locks are canceled.
(This does not apply to open tokens created with OPEN_NLM_SHR.)
If
the registered server process terminates, all locks that are associated
with this process are unlocked or canceled. Since the process is terminating,
lock completion signals will not be delivered.
- If the lock server terminates, all locks are released.
- Purging locks (Vlok#Purge): The Vlok#Purge
command releases all locks on all files that are held by a locker
or a group of lockers. This is primarily a pass through to BRLM. It
will purge all types of byte range locks: held locks, waiting locks,
or pending asynchronous locks. It does not affect share reservations
or open tokens.
The purge interface is implemented using two bit
masks that are logically ANDed with the object ID and owner ID, respectively,
of each lock before they are compared with the passed arguments. The
algorithm is as follows: if ( (PassedObject == (LockObject & PassedObjectMask))
&& (PassedOwner == (LockOwner & PassedOwnerMask)) )
{ The lock will be purged. }
This purge function
is enhanced and extended from the previously existing v_lockctl purge
function. The following Vlock fields are provided by the caller: - VlokObject
- The object's 16-byte identifier
- VlokServerPID
- The process ID of the lock server whose locks are to be released.
- VlokClientPID
- A server-generated process ID that uniquely identifies the client
whose locks are to be released. If binary ones are specified, all
locks for all clients of the specified server are released.
- VlokClientTID
- The client's thread ID for which locks are to be released. If
binary ones are specified, all locks for the specified client and
server are released.
- VlokPgMasks
- Points to a pair of 16-byte bit masks for the object and owner,
respectively. These are defined as VlokObjectMask and VlokOwnerMask.
- VlokPgMaskslen
- Specifies the length of the bit mask pair being passed, which
is 32
The three subfields of the lock owner ID (VlokServerPID,
VlokClientPID, VlokClientTID) are considered to be a single concatenated
16-byte field with respect to the owner mask. Since VlokServerPID
is automatically set to the server's PID by the LFS, the first four
bytes of the owner mask will be set to all ones so that the server
may only purge locks that it has obtained.
Other fields in the
Vlock area should be set to zeros.
- Purging locks held on an object by a server: The following
Vlock fields are provided by the caller:
- VlokObject
- The 16-byte identifier of a specific object
- VlokObjectMask
- All X'FF', for matches on just the specific object
- VlokLocker
- All zeroes
- VlokClientTID
- All zeroes
- VlokLockerMask
- All zeroes, for matches on any owner with the same server PID
- Purging locks held by a client user: The following Vlock
fields are provided by the caller:
- VlokObject
- Zero
- VlokObjectMask
- All zeroes, for matches on every object
- VlokClientPID
- The appropriate client PID
- VlokClientTID
- The appropriate client TID, TID subset (padded with zeroes), or
all zeroes
- VlokLockerMask
- X'FF', left-justified for a length matching the appropriate
subset of the 16-byte owner ID, and then padded with X'00'.
For instance:
- 16 bytes of X'FF' for exactly one lock owner
- 12 bytes of X'FF' for, perhaps, all processes for a specific
user at a specific client
- 8 bytes of X'FF' for all client TIDs for a given client
PID
- Effects of purge on asynchronous locks: If a set of locks
being purged includes pending asynchronous locks, those lock requests
will be canceled.
If a set of asynchronous lock requests are purged,
the application will not be able to immediately tell which pending
requests have been canceled and which had been granted and then were
unlocked. When the call to purge returns to the caller, the lock completion
signals will have all been sent but they may still be on the signal
queue. The application can coordinate the purge operation with the
signal handler after the purge completes by calling sigqueue() with
a special signal number or value to flush the queue of these lock
completion signals. If only a single thread handles the signal queue,
then the appearance of this flush signal will indicate that all of
the successful and ECANCELED signals have arrived and have been processed.
- Each locker should be unregistered when it has finished issuing
lock requests. On a Vlok#UnregLocker command, the following Vlock
field is provided by the caller:
- VlokID
- Vlok#ID (from the BPXYVLOK macro)
- VlokLen
- The length of the Vlock structure
- VlokLockerTok
- A token to identify the locker to unregister
Other fields in the Vlock area should be set to
zeros.
|