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