2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
14 #include <sys/types.h>
18 #include <netinet/in.h>
21 #include <afs/afsutil.h>
23 #include <afs/bubasics.h>
24 #include "budb_errs.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
,
39 SBUDB_FreeAllLocks(struct rx_call
*call
, afs_uint32 instanceId
)
43 code
= FreeAllLocks(call
, instanceId
);
44 osi_auditU(call
, BUDB_FrALckEvent
, code
, AUD_END
);
49 FreeAllLocks(struct rx_call
*call
, afs_uint32 instanceId
)
51 db_lockP startPtr
, endPtr
;
52 struct ubik_trans
*ut
;
55 if (callPermitted(call
) == 0)
56 return (BUDB_NOTPERMITTED
);
58 code
= InitRPC(&ut
, LOCKWRITE
, 1);
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
)
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
,
78 code
= ubik_EndTrans(ut
);
83 SBUDB_FreeLock(struct rx_call
*call
, afs_uint32 lockHandle
)
87 code
= FreeLock(call
, lockHandle
);
88 osi_auditU(call
, BUDB_FreLckEvent
, code
, AUD_END
);
93 FreeLock(struct rx_call
*call
, afs_uint32 lockHandle
)
96 struct ubik_trans
*ut
;
99 if (callPermitted(call
) == 0)
100 return (BUDB_NOTPERMITTED
);
102 code
= InitRPC(&ut
, LOCKWRITE
, 1);
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
);
126 SBUDB_GetInstanceId(struct rx_call
*call
, afs_uint32
*instanceId
)
130 code
= GetInstanceId(call
, instanceId
);
131 osi_auditU(call
, BUDB_GetIIdEvent
, code
, AUD_END
);
136 GetInstanceId(struct rx_call
*call
, afs_uint32
*instanceId
)
138 struct ubik_trans
*ut
;
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);
153 instanceValue
= ntohl(db
.h
.lastInstanceId
) + 1;
155 set_header_word(ut
, lastInstanceId
, htonl(instanceValue
));
157 code
= ubik_EndTrans(ut
);
163 SBUDB_GetLock(struct rx_call
*call
, afs_uint32 instanceId
, afs_int32 lockName
,
164 afs_int32 expiration
, afs_uint32
*lockHandle
)
168 code
= GetLock(call
, instanceId
, lockName
, expiration
, lockHandle
);
169 osi_auditU(call
, BUDB_GetLckEvent
, code
, AUD_END
);
174 GetLock(struct rx_call
*call
, afs_uint32 instanceId
, afs_int32 lockName
,
175 afs_int32 expiration
, afs_uint32
*lockHandle
)
179 struct ubik_trans
*ut
;
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);
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
;
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
));
216 *lockHandle
= (afs_uint32
) (lockName
+ 1);
217 code
= ubik_EndTrans(ut
);
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);