include-afsconfig-before-param-h-20010712
[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 RCSID("$Header$");
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 <afs/voldefs.h>
29 #include <rx/xdr.h>
30 #include <rx/rx.h>
31 #include <afs/vlserver.h>
32 #include <afs/nfs.h>
33 #include <afs/afsint.h>
34 #include "volint.h"
35 #include "volser.h"
36 #include "lockdata.h"
37
38 /* Finds an index in VLDB entry that matches the volume type, server, and partition.
39  * If type is zero, will match first index of ANY type (RW, BK, or RO).
40  * If server is zero, will match first index of ANY server and partition 
41  * Zero is a valid partition field.
42  */
43 int FindIndex(entry, server, part, type)
44     struct nvldbentry *entry;
45     afs_int32             server, part, type;
46 {
47     int e;
48     afs_int32 error = 0;
49
50     for (e=0; (e < entry->nServers) && !error; e++) {
51         if (!type || (entry->serverFlags[e] & type)) {
52            if ( (!server || (entry->serverPartition[e] == part)) &&
53                 (!server || VLDB_IsSameAddrs(entry->serverNumber[e],server,&error)) )
54               break;
55            if (type == ITSRWVOL)
56               return -1;        /* quit when we are looking for RW entry (there's only 1) */
57         }
58     }
59
60     if (error) {
61        fprintf(STDERR, 
62                "Failed to get info about server's %d address(es) from vlserver (err=%d)\n", 
63                entry->serverNumber[e], error);
64        return -1;
65     }
66
67     if (e >= entry->nServers)
68        return -1;    /* Didn't find it */
69
70     return e;        /* return the index */
71 }
72
73 /* Changes the rw site only */
74 SetAValue (entry, oserver, opart, nserver, npart, type)
75      struct nvldbentry *entry;
76      afs_int32             oserver, opart, nserver, npart, type;
77 {
78     int e;
79     afs_int32 error = 0;
80
81     e = FindIndex(entry, oserver, opart, type);
82     if (e == -1)
83        return;              /* If didn't find it, just return */
84
85     entry->serverNumber[e]    = nserver;
86     entry->serverPartition[e] = npart;
87
88     /* Now move rest of entries up */
89     if ((nserver == 0L) && (npart == 0L)) {
90        for (e++; e<entry->nServers; e++) {
91           entry->serverNumber[e-1]    = entry->serverNumber[e];
92           entry->serverPartition[e-1] = entry->serverPartition[e];
93           entry->serverFlags[e-1]     = entry->serverFlags[e];
94        }
95     }
96 }
97
98 /* Changes the RW site only */
99 Lp_SetRWValue (entry, oserver, opart, nserver, npart)
100      struct nvldbentry *entry;
101      afs_int32             oserver, opart, nserver, npart;
102 {
103     SetAValue (entry, oserver, opart, nserver, npart, ITSRWVOL);
104 }
105
106 /* Changes the RO site only */
107 Lp_SetROValue(entry, oserver, opart, nserver, npart)
108      struct nvldbentry *entry;
109      afs_int32             oserver, opart, nserver, npart;
110 {
111     SetAValue (entry, oserver, opart, nserver, npart, ITSROVOL);
112 }
113
114 /* Returns success if this server and partition matches the RW entry */
115 Lp_Match(server, part, entry)
116     afs_int32             server, part;
117     struct nvldbentry *entry;
118 {
119     if (FindIndex(entry, server, part, ITSRWVOL) == -1)
120        return 0;
121     return 1;
122 }
123
124 /* Return the index of the RO entry (plus 1) if it exists, else return 0 */
125 Lp_ROMatch(server, part, entry)
126      afs_int32             server, part;
127      struct nvldbentry *entry;
128 {
129    return (FindIndex(entry,server,part,ITSROVOL) + 1);
130 }
131
132 /* Return the index of the RW entry if it exists, else return -1 */
133 Lp_GetRwIndex(entry)
134      struct nvldbentry *entry;
135 {
136     return (FindIndex(entry,0,0,ITSRWVOL));
137 }
138
139 /*initialize queue pointed by <ahead>*/
140 Lp_QInit(ahead)
141      struct qHead *ahead;
142 {
143    ahead->count = 0;
144    ahead->next  = (struct aqueue *)0;
145 }
146
147 /*add <elem> in front of queue <ahead> */
148 Lp_QAdd(ahead,elem)
149      struct qHead *ahead;
150      struct aqueue *elem;
151 {
152     struct aqueue *temp;
153
154     if(ahead->count == 0) {
155         ahead->count += 1;
156         ahead->next = elem;
157         elem->next = (struct aqueue *)0;
158     }
159     else {
160         temp = ahead->next;
161         ahead->count += 1;
162         ahead->next = elem;
163         elem->next = temp;
164     }
165 }
166
167 Lp_QScan(ahead,id,success, elem)
168      struct qHead *ahead;
169      struct aqueue **elem;
170      afs_int32 id;
171      int *success;
172 {   struct aqueue *cptr;
173
174     cptr = ahead->next;
175     while(cptr != (struct aqueue *)0) {
176         if(cptr->ids[RWVOL] == id) {
177             *success = 1;
178             *elem = cptr;
179             return 0;
180         }
181         cptr = cptr->next;
182     }
183     *success = 0;
184     return 0;
185 }
186
187 /*return the element in the beginning of the queue <ahead>, free
188 *the space used by that element . <success> indicates if enumeration was ok*/
189 Lp_QEnumerate(ahead,success, elem)
190      struct qHead *ahead;
191      struct aqueue *elem;
192      int *success;
193 {
194     int i;
195     struct aqueue *temp;
196
197     if(ahead->count > 0) {/*more elements left */
198         ahead->count -= 1;
199         temp = ahead->next;
200         ahead->next = ahead->next->next;
201         strncpy(elem->name,temp->name,VOLSER_OLDMAXVOLNAME);
202         for(i= 0; i < 3; i++){
203             elem->ids[i] = temp->ids[i];
204             elem->copyDate[i] = temp->copyDate[i];
205             elem->isValid[i] = temp->isValid[i];
206         }
207         elem->next = (struct aqueue *)0;
208         *success = 1;
209         free(temp);
210     }
211     else /*queue is empty*/
212         *success = 0;
213 }
214
215 Lp_QTraverse(ahead)
216      struct qHead *ahead;
217 {
218     int count;
219     struct aqueue *old, *new;
220
221     old = ahead->next;
222     new = old->next;
223     count = ahead->count;
224     printf("traversing the internal queue, which groups all the related volumes on a per partition basis\n");
225     while(count >  0) {
226         printf("---------------------------\n");
227         printf("%s RW-Id %u",old->name,old->ids[RWVOL]);
228         if(old->isValid[RWVOL])
229             printf(" valid ");
230         else printf(" invalid ");
231         printf("RO-Id %u",old->ids[ROVOL]);
232         if(old->isValid[ROVOL])
233             printf(" valid ");
234         else printf(" invalid ");
235         printf("BACKUP-Id %u",old->ids[BACKVOL]);
236         if(old->isValid[BACKVOL])
237             printf(" valid ");
238         else printf(" invalid ");
239         printf("\n");
240         printf("---------------------------\n");
241         old = new;
242         if(count != 1) new = new->next;
243         count--;
244     }
245 }