Merge 1.8.0~pre4 packaging into master
[pkg-k5-afs_openafs.git] / src / budb / db_lock.c
blob244175a38602813ffea32428a71291efc3d19f23
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>
13 #include <roken.h>
15 #include <ubik.h>
16 #include <afs/afsutil.h>
17 #include <afs/audit.h>
18 #include <afs/bubasics.h>
20 #include "budb_errs.h"
21 #include "database.h"
22 #include "budb_internal.h"
23 #include "error_macros.h"
25 #define DBH_POS(ptr) ( (char *) (ptr) - (char *) &db.h )
27 afs_int32 FreeAllLocks(struct rx_call *, afs_uint32);
28 afs_int32 FreeLock(struct rx_call *, afs_uint32);
29 afs_int32 GetInstanceId(struct rx_call *, afs_uint32 *);
30 afs_int32 GetLock(struct rx_call *, afs_uint32, afs_int32, afs_int32,
31 afs_uint32 *);
33 afs_int32
34 SBUDB_FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
36 afs_int32 code;
38 code = FreeAllLocks(call, instanceId);
39 osi_auditU(call, BUDB_FrALckEvent, code, AUD_END);
40 return code;
43 afs_int32
44 FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
46 db_lockP startPtr, endPtr;
47 struct ubik_trans *ut;
48 afs_int32 code;
50 if (callPermitted(call) == 0)
51 return (BUDB_NOTPERMITTED);
53 code = InitRPC(&ut, LOCKWRITE, 1);
54 if (code)
55 return (code);
57 startPtr = &db.h.textLocks[0];
58 endPtr = &db.h.textLocks[TB_NUM - 1];
59 while (startPtr <= endPtr) {
60 if ((ntohl(startPtr->lockState) == 1)
61 && (ntohl(startPtr->instanceId) == instanceId)
62 ) {
63 /* release the lock */
64 startPtr->lockState = 0; /* unlock it */
65 startPtr->lockTime = 0;
66 startPtr->expires = 0;
67 startPtr->instanceId = 0;
68 dbwrite(ut, DBH_POS(startPtr), (char *)startPtr,
69 sizeof(db_lockT));
71 startPtr++;
73 code = ubik_EndTrans(ut);
74 return (code);
77 afs_int32
78 SBUDB_FreeLock(struct rx_call *call, afs_uint32 lockHandle)
80 afs_int32 code;
82 code = FreeLock(call, lockHandle);
83 osi_auditU(call, BUDB_FreLckEvent, code, AUD_END);
84 return code;
87 afs_int32
88 FreeLock(struct rx_call *call, afs_uint32 lockHandle)
90 db_lockP lockPtr = 0;
91 struct ubik_trans *ut;
92 afs_int32 code;
94 if (callPermitted(call) == 0)
95 return (BUDB_NOTPERMITTED);
97 code = InitRPC(&ut, LOCKWRITE, 1);
98 if (code)
99 return (code);
101 if (checkLockHandle(ut, lockHandle) == 0)
102 ABORT(BUDB_BADARGUMENT);
104 lockPtr = &db.h.textLocks[lockHandle - 1];
106 lockPtr->lockState = 0; /* unlock it */
107 lockPtr->lockTime = 0;
108 lockPtr->expires = 0;
109 lockPtr->instanceId = 0;
110 dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
112 code = ubik_EndTrans(ut);
113 return (code);
115 abort_exit:
116 ubik_AbortTrans(ut);
117 return (code);
120 afs_int32
121 SBUDB_GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
123 afs_int32 code;
125 code = GetInstanceId(call, instanceId);
126 osi_auditU(call, BUDB_GetIIdEvent, code, AUD_END);
127 return code;
130 afs_int32
131 GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
133 struct ubik_trans *ut;
134 afs_int32 code;
135 afs_int32 instanceValue;
137 LogDebug(4, "GetInstanceId:\n");
139 /* *** Allow anyone to get the instance id ***
140 * if ( callPermitted(call) == 0 )
141 * return(BUDB_NOTPERMITTED);
144 code = InitRPC(&ut, LOCKWRITE, 1);
145 if (code)
146 return (code);
148 instanceValue = ntohl(db.h.lastInstanceId) + 1;
150 set_header_word(ut, lastInstanceId, htonl(instanceValue));
152 code = ubik_EndTrans(ut);
153 return (code);
157 afs_int32
158 SBUDB_GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
159 afs_int32 expiration, afs_uint32 *lockHandle)
161 afs_int32 code;
163 code = GetLock(call, instanceId, lockName, expiration, lockHandle);
164 osi_auditU(call, BUDB_GetLckEvent, code, AUD_END);
165 return code;
168 afs_int32
169 GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
170 afs_int32 expiration, afs_uint32 *lockHandle)
172 struct timeval tv;
173 db_lockP lockPtr;
174 struct ubik_trans *ut;
176 afs_int32 code;
178 if (callPermitted(call) == 0)
179 return (BUDB_NOTPERMITTED);
181 if ((lockName < 0) || (lockName >= TB_NUM))
182 return (BUDB_BADARGUMENT);
184 /* get the current time */
185 gettimeofday(&tv, 0);
187 code = InitRPC(&ut, LOCKWRITE, 1);
188 if (code)
189 return (code);
191 lockPtr = &db.h.textLocks[lockName];
193 if ((ntohl(lockPtr->lockState) != 0) /* lock set */
194 &&(ntohl(lockPtr->expires) > tv.tv_sec) /* not expired */
196 if (ntohl(lockPtr->instanceId) == instanceId)
197 code = BUDB_SELFLOCKED;
198 else
199 code = BUDB_LOCKED;
200 goto abort_exit;
203 lockPtr->lockState = htonl(1); /* lock it */
204 lockPtr->lockTime = htonl(tv.tv_sec); /* when locked */
205 lockPtr->expires = htonl(tv.tv_sec + expiration);
206 lockPtr->instanceId = htonl(instanceId);
207 code = dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
208 if (code)
209 ABORT(code);
211 *lockHandle = (afs_uint32) (lockName + 1);
212 code = ubik_EndTrans(ut);
213 return (code);
215 abort_exit:
216 ubik_AbortTrans(ut);
217 return (code);
221 /* checkLockHandle
222 * exit:
223 * 0 - if invalid handle
224 * 1 - if handle is valid
227 checkLockHandle(struct ubik_trans *ut, afs_uint32 lockHandle)
229 return (((lockHandle > 0) && (lockHandle <= TB_NUM)) ? 1 : 0);