2 * Copyright 2000, International Business Machines Corporation and others.
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
13 * Instituition: ITC, CMU
17 #include <afsconfig.h>
18 #include <afs/param.h>
22 #include <sys/types.h>
26 #include <netinet/in.h>
29 #include <afs/voldefs.h>
32 #include <afs/vlserver.h>
34 #include <afs/afsint.h>
40 #include "vsutils_prototypes.h"
41 #include "lockprocs_prototypes.h"
43 struct ubik_client *cstruct;
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.
51 FindIndex(struct uvldbentry *entry, afs_uint32 server, afs_int32 part, afs_int32 type)
58 if (server && !afs_uuid_is_nil(&entry->serverNumber[0])) {
59 afs_int32 vcode, m_uniq=0;
61 ListAddrByAttributes m_attrs;
64 m_attrs.Mask = VLADDR_IPADDR;
65 m_attrs.ipaddr = htonl(server);
67 m_addrs.bulkaddrs_val = 0;
68 m_addrs.bulkaddrs_len = 0;
70 ubik_VL_GetAddrsU( cstruct, 0, &m_attrs,
74 uuid_valid = (vcode == 0);
77 for (e = 0; (e < entry->nServers) && !error; e++) {
78 if (!type || (entry->serverFlags[e] & type)) {
79 if ((!server || (entry->serverPartition[e] == part))
81 || (uuid_valid && afs_uuid_equal(&m_uuid, &entry->serverNumber[e]))
82 || VLDB_IsSameAddrs(entry->serverUnique[e], server, &error)))
85 return -1; /* quit when we are looking for RW entry (there's only 1) */
91 "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
92 entry->serverUnique[e], error);
96 if (e >= entry->nServers)
97 return -1; /* Didn't find it */
99 return e; /* return the index */
102 /* Changes the rw site only */
104 SetAValue(struct uvldbentry *entry, afs_uint32 oserver, afs_int32 opart,
105 afs_uint32 nserver, afs_int32 npart, afs_int32 type)
109 e = FindIndex(entry, oserver, opart, type);
111 return; /* If didn't find it, just return */
113 entry->serverUnique[e] = nserver;
114 entry->serverPartition[e] = npart;
116 /* Now move rest of entries up */
117 if ((nserver == 0L) && (npart == 0L)) {
118 for (e++; e < entry->nServers; e++) {
119 entry->serverUnique[e - 1] = entry->serverUnique[e];
120 entry->serverPartition[e - 1] = entry->serverPartition[e];
121 entry->serverFlags[e - 1] = entry->serverFlags[e];
126 /* Changes the RW site only */
128 Lp_SetRWValue(struct nvldbentry *entryp, afs_uint32 oserver, afs_int32 opart,
129 afs_uint32 nserver, afs_int32 npart)
131 struct uvldbentry uentry;
133 nvlentry_to_uvlentry(entryp, &uentry);
134 SetAValue(&uentry, oserver, opart, nserver, npart, ITSRWVOL);
135 uvlentry_to_nvlentry(&uentry, entryp);
139 Lp_SetRWValueU(struct uvldbentry *entry, afs_uint32 oserver, afs_int32 opart,
140 afs_uint32 nserver, afs_int32 npart)
142 SetAValue(entry, oserver, opart, nserver, npart, ITSRWVOL);
145 /* Changes the RO site only */
147 Lp_SetROValue(struct nvldbentry *entryp, afs_uint32 oserver,
148 afs_int32 opart, afs_uint32 nserver, afs_int32 npart)
150 struct uvldbentry uentry;
152 nvlentry_to_uvlentry(entryp, &uentry);
153 SetAValue(&uentry, oserver, opart, nserver, npart, ITSROVOL);
154 uvlentry_to_nvlentry(&uentry, entryp);
158 Lp_SetROValueU(struct uvldbentry *entry, afs_uint32 oserver,
159 afs_int32 opart, afs_uint32 nserver, afs_int32 npart)
161 SetAValue(entry, oserver, opart, nserver, npart, ITSROVOL);
164 /* Returns success if this server and partition matches the RW entry */
166 Lp_Match(afs_uint32 server, afs_int32 part,
167 struct nvldbentry *entryp)
169 struct uvldbentry uentry;
171 nvlentry_to_uvlentry(entryp, &uentry);
172 if (FindIndex(&uentry, server, part, ITSRWVOL) == -1)
174 uvlentry_to_nvlentry(&uentry, entryp);
179 Lp_MatchU(afs_uint32 server, afs_int32 part,
180 struct uvldbentry *entry)
182 if (FindIndex(entry, server, part, ITSRWVOL) == -1)
187 /* Return the index of the RO entry (plus 1) if it exists, else return 0 */
189 Lp_ROMatch(afs_uint32 server, afs_int32 part, struct nvldbentry *entryp)
191 struct uvldbentry uentry;
194 nvlentry_to_uvlentry(entryp, &uentry);
195 idx = (FindIndex(&uentry, server, part, ITSROVOL) + 1);
197 uvlentry_to_nvlentry(&uentry, entryp);
202 Lp_ROMatchU(afs_uint32 server, afs_int32 part, struct uvldbentry *entry)
204 return (FindIndex(entry, server, part, ITSROVOL) + 1);
207 /* Return the index of the RW entry if it exists, else return -1 */
209 Lp_GetRwIndex(struct nvldbentry *entryp)
211 struct uvldbentry uentry;
214 nvlentry_to_uvlentry(entryp, &uentry);
215 idx = (FindIndex(&uentry, 0, 0, ITSRWVOL));
217 uvlentry_to_nvlentry(&uentry, entryp);
222 Lp_GetRwIndexU(struct uvldbentry *entry)
224 return (FindIndex(entry, 0, 0, ITSRWVOL));
227 /*initialize queue pointed by <ahead>*/
229 Lp_QInit(struct qHead *ahead)
235 /*add <elem> in front of queue <ahead> */
237 Lp_QAdd(struct qHead *ahead, struct aqueue *elem)
241 if (ahead->count == 0) {
254 Lp_QScan(struct qHead *ahead, afs_int32 id, int *success, struct aqueue **elem)
259 while (cptr != NULL) {
260 if (cptr->ids[RWVOL] == id) {
271 /*return the element in the beginning of the queue <ahead>, free
272 *the space used by that element . <success> indicates if enumeration was ok*/
274 Lp_QEnumerate(struct qHead *ahead, int *success, struct aqueue *elem)
279 if (ahead->count > 0) { /*more elements left */
282 ahead->next = ahead->next->next;
283 strncpy(elem->name, temp->name, VOLSER_OLDMAXVOLNAME);
284 for (i = 0; i < 3; i++) {
285 elem->ids[i] = temp->ids[i];
286 elem->copyDate[i] = temp->copyDate[i];
287 elem->isValid[i] = temp->isValid[i];
292 } else /*queue is empty */
297 Lp_QTraverse(struct qHead *ahead)
300 struct aqueue *old, *new;
304 count = ahead->count;
306 ("traversing the internal queue, which groups all the related volumes on a per partition basis\n");
308 printf("---------------------------\n");
309 printf("%s RW-Id %lu", old->name, (unsigned long)old->ids[RWVOL]);
310 if (old->isValid[RWVOL])
314 printf("RO-Id %lu", (unsigned long)old->ids[ROVOL]);
315 if (old->isValid[ROVOL])
319 printf("BACKUP-Id %lu", (unsigned long)old->ids[BACKVOL]);
320 if (old->isValid[BACKVOL])
325 printf("---------------------------\n");