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