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