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