Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / budb / db_lock.c
blob59334b390f18f168a12bcb3a9ca2bcfba9c8257c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <afsconfig.h>
11 #include <afs/param.h>
14 #include <sys/types.h>
15 #ifdef AFS_NT40_ENV
16 #include <winsock2.h>
17 #else
18 #include <netinet/in.h>
19 #include <sys/time.h>
20 #endif
21 #include <afs/afsutil.h>
22 #include <ubik.h>
23 #include <afs/bubasics.h>
24 #include "budb_errs.h"
25 #include "database.h"
26 #include "budb_internal.h"
27 #include "error_macros.h"
28 #include "afs/audit.h"
30 #define DBH_POS(ptr) ( (char *) (ptr) - (char *) &db.h )
32 afs_int32 FreeAllLocks(struct rx_call *, afs_uint32);
33 afs_int32 FreeLock(struct rx_call *, afs_uint32);
34 afs_int32 GetInstanceId(struct rx_call *, afs_uint32 *);
35 afs_int32 GetLock(struct rx_call *, afs_uint32, afs_int32, afs_int32,
36 afs_uint32 *);
38 afs_int32
39 SBUDB_FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
41 afs_int32 code;
43 code = FreeAllLocks(call, instanceId);
44 osi_auditU(call, BUDB_FrALckEvent, code, AUD_END);
45 return code;
48 afs_int32
49 FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
51 db_lockP startPtr, endPtr;
52 struct ubik_trans *ut;
53 afs_int32 code;
55 if (callPermitted(call) == 0)
56 return (BUDB_NOTPERMITTED);
58 code = InitRPC(&ut, LOCKWRITE, 1);
59 if (code)
60 return (code);
62 startPtr = &db.h.textLocks[0];
63 endPtr = &db.h.textLocks[TB_NUM - 1];
64 while (startPtr <= endPtr) {
65 if ((ntohl(startPtr->lockState) == 1)
66 && (ntohl(startPtr->instanceId) == instanceId)
67 ) {
68 /* release the lock */
69 startPtr->lockState = 0; /* unlock it */
70 startPtr->lockTime = 0;
71 startPtr->expires = 0;
72 startPtr->instanceId = 0;
73 dbwrite(ut, DBH_POS(startPtr), (char *)startPtr,
74 sizeof(db_lockT));
76 startPtr++;
78 code = ubik_EndTrans(ut);
79 return (code);
82 afs_int32
83 SBUDB_FreeLock(struct rx_call *call, afs_uint32 lockHandle)
85 afs_int32 code;
87 code = FreeLock(call, lockHandle);
88 osi_auditU(call, BUDB_FreLckEvent, code, AUD_END);
89 return code;
92 afs_int32
93 FreeLock(struct rx_call *call, afs_uint32 lockHandle)
95 db_lockP lockPtr = 0;
96 struct ubik_trans *ut;
97 afs_int32 code;
99 if (callPermitted(call) == 0)
100 return (BUDB_NOTPERMITTED);
102 code = InitRPC(&ut, LOCKWRITE, 1);
103 if (code)
104 return (code);
106 if (checkLockHandle(ut, lockHandle) == 0)
107 ABORT(BUDB_BADARGUMENT);
109 lockPtr = &db.h.textLocks[lockHandle - 1];
111 lockPtr->lockState = 0; /* unlock it */
112 lockPtr->lockTime = 0;
113 lockPtr->expires = 0;
114 lockPtr->instanceId = 0;
115 dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
117 code = ubik_EndTrans(ut);
118 return (code);
120 abort_exit:
121 ubik_AbortTrans(ut);
122 return (code);
125 afs_int32
126 SBUDB_GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
128 afs_int32 code;
130 code = GetInstanceId(call, instanceId);
131 osi_auditU(call, BUDB_GetIIdEvent, code, AUD_END);
132 return code;
135 afs_int32
136 GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
138 struct ubik_trans *ut;
139 afs_int32 code;
140 afs_int32 instanceValue;
142 LogDebug(4, "GetInstanceId:\n");
144 /* *** Allow anyone to get the instance id ***
145 * if ( callPermitted(call) == 0 )
146 * return(BUDB_NOTPERMITTED);
149 code = InitRPC(&ut, LOCKWRITE, 1);
150 if (code)
151 return (code);
153 instanceValue = ntohl(db.h.lastInstanceId) + 1;
155 set_header_word(ut, lastInstanceId, htonl(instanceValue));
157 code = ubik_EndTrans(ut);
158 return (code);
162 afs_int32
163 SBUDB_GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
164 afs_int32 expiration, afs_uint32 *lockHandle)
166 afs_int32 code;
168 code = GetLock(call, instanceId, lockName, expiration, lockHandle);
169 osi_auditU(call, BUDB_GetLckEvent, code, AUD_END);
170 return code;
173 afs_int32
174 GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
175 afs_int32 expiration, afs_uint32 *lockHandle)
177 struct timeval tv;
178 db_lockP lockPtr;
179 struct ubik_trans *ut;
181 afs_int32 code;
183 if (callPermitted(call) == 0)
184 return (BUDB_NOTPERMITTED);
186 if ((lockName < 0) || (lockName >= TB_NUM))
187 return (BUDB_BADARGUMENT);
189 /* get the current time */
190 gettimeofday(&tv, 0);
192 code = InitRPC(&ut, LOCKWRITE, 1);
193 if (code)
194 return (code);
196 lockPtr = &db.h.textLocks[lockName];
198 if ((ntohl(lockPtr->lockState) != 0) /* lock set */
199 &&(ntohl(lockPtr->expires) > tv.tv_sec) /* not expired */
201 if (ntohl(lockPtr->instanceId) == instanceId)
202 code = BUDB_SELFLOCKED;
203 else
204 code = BUDB_LOCKED;
205 goto abort_exit;
208 lockPtr->lockState = htonl(1); /* lock it */
209 lockPtr->lockTime = htonl(tv.tv_sec); /* when locked */
210 lockPtr->expires = htonl(tv.tv_sec + expiration);
211 lockPtr->instanceId = htonl(instanceId);
212 code = dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
213 if (code)
214 ABORT(code);
216 *lockHandle = (afs_uint32) (lockName + 1);
217 code = ubik_EndTrans(ut);
218 return (code);
220 abort_exit:
221 ubik_AbortTrans(ut);
222 return (code);
226 /* checkLockHandle
227 * exit:
228 * 0 - if invalid handle
229 * 1 - if handle is valid
232 checkLockHandle(struct ubik_trans *ut, afs_uint32 lockHandle)
234 return (((lockHandle > 0) && (lockHandle <= TB_NUM)) ? 1 : 0);