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