7ab1c57fa9397c554423f4f6d407d6ba770dce95
[openafs.git] / src / volser / lockprocs.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
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  */
9
10 /*
11  *  Module:         lockprocs.c
12  *  System:         Volser
13  *  Instituition:   ITC, CMU
14  *  Date:           December, 88
15  */
16
17 #include <afsconfig.h>
18 #include <afs/param.h>
19
20 #include <roken.h>
21
22 #include <sys/types.h>
23 #ifdef AFS_NT40_ENV
24 #include <winsock2.h>
25 #else
26 #include <netinet/in.h>
27 #endif
28 #include <string.h>
29 #include <afs/voldefs.h>
30 #include <rx/xdr.h>
31 #include <rx/rx.h>
32 #include <afs/vlserver.h>
33 #include <afs/nfs.h>
34 #include <afs/afsint.h>
35 #include "volint.h"
36 #include "volser.h"
37 #include "lockdata.h"
38
39 #include "vsutils_prototypes.h"
40 #include "lockprocs_prototypes.h"
41
42 /* Finds an index in VLDB entry that matches the volume type, server, and partition.
43  * If type is zero, will match first index of ANY type (RW, BK, or RO).
44  * If server is zero, will match first index of ANY server and partition
45  * Zero is a valid partition field.
46  */
47 static int
48 FindIndex(struct uvldbentry *entry, afs_uint32 server, afs_int32 part, afs_int32 type)
49 {
50     int e;
51     afs_int32 error = 0;
52
53     for (e = 0; (e < entry->nServers) && !error; e++) {
54         if (!type || (entry->serverFlags[e] & type)) {
55             if ((!server || (entry->serverPartition[e] == part))
56                 && (!server
57                     || VLDB_IsSameAddrs(entry->serverUnique[e], server,
58                                         &error)))
59                 break;
60             if (type == ITSRWVOL)
61                 return -1;      /* quit when we are looking for RW entry (there's only 1) */
62         }
63     }
64
65     if (error) {
66         fprintf(STDERR,
67                 "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
68                 entry->serverUnique[e], error);
69         return -1;
70     }
71
72     if (e >= entry->nServers)
73         return -1;              /* Didn't find it */
74
75     return e;                   /* return the index */
76 }
77
78 /* Changes the rw site only */
79 static void
80 SetAValue(struct uvldbentry *entry, afs_uint32 oserver, afs_int32 opart,
81           afs_uint32 nserver, afs_int32 npart, afs_int32 type)
82 {
83     int e;
84
85     e = FindIndex(entry, oserver, opart, type);
86     if (e == -1)
87         return;                 /* If didn't find it, just return */
88
89     entry->serverUnique[e] = nserver;
90     entry->serverPartition[e] = npart;
91
92     /* Now move rest of entries up */
93     if ((nserver == 0L) && (npart == 0L)) {
94         for (e++; e < entry->nServers; e++) {
95             entry->serverUnique[e - 1] = entry->serverUnique[e];
96             entry->serverPartition[e - 1] = entry->serverPartition[e];
97             entry->serverFlags[e - 1] = entry->serverFlags[e];
98         }
99     }
100 }
101
102 /* Changes the RW site only */
103 void
104 Lp_SetRWValue(struct nvldbentry *entryp, afs_uint32 oserver, afs_int32 opart,
105               afs_uint32 nserver, afs_int32 npart)
106 {
107     struct uvldbentry uentry;
108
109     nvlentry_to_uvlentry(entryp, &uentry);
110     SetAValue(&uentry, oserver, opart, nserver, npart, ITSRWVOL);
111     uvlentry_to_nvlentry(&uentry, entryp);
112 }
113
114 void
115 Lp_SetRWValueU(struct uvldbentry *entry, afs_uint32 oserver, afs_int32 opart,
116               afs_uint32 nserver, afs_int32 npart)
117 {
118     SetAValue(entry, oserver, opart, nserver, npart, ITSRWVOL);
119 }
120
121 /* Changes the RO site only */
122 void
123 Lp_SetROValue(struct nvldbentry *entryp, afs_uint32 oserver,
124               afs_int32 opart, afs_uint32 nserver, afs_int32 npart)
125 {
126     struct uvldbentry uentry;
127
128     nvlentry_to_uvlentry(entryp, &uentry);
129     SetAValue(&uentry, oserver, opart, nserver, npart, ITSROVOL);
130     uvlentry_to_nvlentry(&uentry, entryp);
131 }
132
133 void
134 Lp_SetROValueU(struct uvldbentry *entry, afs_uint32 oserver,
135               afs_int32 opart, afs_uint32 nserver, afs_int32 npart)
136 {
137     SetAValue(entry, oserver, opart, nserver, npart, ITSROVOL);
138 }
139
140 /* Returns success if this server and partition matches the RW entry */
141 int
142 Lp_Match(afs_uint32 server, afs_int32 part,
143          struct nvldbentry *entryp)
144 {
145     struct uvldbentry uentry;
146
147     nvlentry_to_uvlentry(entryp, &uentry);
148     if (FindIndex(&uentry, server, part, ITSRWVOL) == -1)
149         return 0;
150     uvlentry_to_nvlentry(&uentry, entryp);
151     return 1;
152 }
153
154 int
155 Lp_MatchU(afs_uint32 server, afs_int32 part,
156          struct uvldbentry *entry)
157 {
158     if (FindIndex(entry, server, part, ITSRWVOL) == -1)
159         return 0;
160     return 1;
161 }
162
163 /* Return the index of the RO entry (plus 1) if it exists, else return 0 */
164 int
165 Lp_ROMatch(afs_uint32 server, afs_int32 part, struct nvldbentry *entryp)
166 {
167     struct uvldbentry uentry;
168     int idx;
169
170     nvlentry_to_uvlentry(entryp, &uentry);
171     idx = (FindIndex(&uentry, server, part, ITSROVOL) + 1);
172     if (idx)
173         uvlentry_to_nvlentry(&uentry, entryp);
174     return idx;
175 }
176
177 int
178 Lp_ROMatchU(afs_uint32 server, afs_int32 part, struct uvldbentry *entry)
179 {
180     return (FindIndex(entry, server, part, ITSROVOL) + 1);
181 }
182
183 /* Return the index of the RW entry if it exists, else return -1 */
184 int
185 Lp_GetRwIndex(struct nvldbentry *entryp)
186 {
187     struct uvldbentry uentry;
188     int idx;
189
190     nvlentry_to_uvlentry(entryp, &uentry);
191     idx = (FindIndex(&uentry, 0, 0, ITSRWVOL));
192     if (idx > -1)
193         uvlentry_to_nvlentry(&uentry, entryp);
194     return idx;
195 }
196
197 int
198 Lp_GetRwIndexU(struct uvldbentry *entry)
199 {
200     return (FindIndex(entry, 0, 0, ITSRWVOL));
201 }
202
203 /*initialize queue pointed by <ahead>*/
204 void
205 Lp_QInit(struct qHead *ahead)
206 {
207     ahead->count = 0;
208     ahead->next = NULL;
209 }
210
211 /*add <elem> in front of queue <ahead> */
212 void
213 Lp_QAdd(struct qHead *ahead, struct aqueue *elem)
214 {
215     struct aqueue *temp;
216
217     if (ahead->count == 0) {
218         ahead->count += 1;
219         ahead->next = elem;
220         elem->next = NULL;
221     } else {
222         temp = ahead->next;
223         ahead->count += 1;
224         ahead->next = elem;
225         elem->next = temp;
226     }
227 }
228
229 int
230 Lp_QScan(struct qHead *ahead, afs_int32 id, int *success, struct aqueue **elem)
231 {
232     struct aqueue *cptr;
233
234     cptr = ahead->next;
235     while (cptr != NULL) {
236         if (cptr->ids[RWVOL] == id) {
237             *success = 1;
238             *elem = cptr;
239             return 0;
240         }
241         cptr = cptr->next;
242     }
243     *success = 0;
244     return 0;
245 }
246
247 /*return the element in the beginning of the queue <ahead>, free
248 *the space used by that element . <success> indicates if enumeration was ok*/
249 void
250 Lp_QEnumerate(struct qHead *ahead, int *success, struct aqueue *elem)
251 {
252     int i;
253     struct aqueue *temp;
254
255     if (ahead->count > 0) {     /*more elements left */
256         ahead->count -= 1;
257         temp = ahead->next;
258         ahead->next = ahead->next->next;
259         strncpy(elem->name, temp->name, VOLSER_OLDMAXVOLNAME);
260         for (i = 0; i < 3; i++) {
261             elem->ids[i] = temp->ids[i];
262             elem->copyDate[i] = temp->copyDate[i];
263             elem->isValid[i] = temp->isValid[i];
264         }
265         elem->next = NULL;
266         *success = 1;
267         free(temp);
268     } else                      /*queue is empty */
269         *success = 0;
270 }
271
272 void
273 Lp_QTraverse(struct qHead *ahead)
274 {
275     int count;
276     struct aqueue *old, *new;
277
278     old = ahead->next;
279     new = old->next;
280     count = ahead->count;
281     printf
282         ("traversing the internal queue, which groups all the related volumes on a per partition basis\n");
283     while (count > 0) {
284         printf("---------------------------\n");
285         printf("%s RW-Id %lu", old->name, (unsigned long)old->ids[RWVOL]);
286         if (old->isValid[RWVOL])
287             printf(" valid ");
288         else
289             printf(" invalid ");
290         printf("RO-Id %lu", (unsigned long)old->ids[ROVOL]);
291         if (old->isValid[ROVOL])
292             printf(" valid ");
293         else
294             printf(" invalid ");
295         printf("BACKUP-Id %lu", (unsigned long)old->ids[BACKVOL]);
296         if (old->isValid[BACKVOL])
297             printf(" valid ");
298         else
299             printf(" invalid ");
300         printf("\n");
301         printf("---------------------------\n");
302         old = new;
303         if (count != 1)
304             new = new->next;
305         count--;
306     }
307 }