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 <afs/voldefs.h>
25 #include <afs/vlserver.h>
27 #include <afs/afsint.h>
32 #include "vsutils_prototypes.h"
33 #include "lockprocs_prototypes.h"
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.
41 FindIndex(struct nvldbentry
*entry
, afs_uint32 server
, afs_int32 part
, afs_int32 type
)
46 for (e
= 0; (e
< entry
->nServers
) && !error
; e
++) {
47 if (!type
|| (entry
->serverFlags
[e
] & type
)) {
48 if ((!server
|| (entry
->serverPartition
[e
] == part
))
50 || VLDB_IsSameAddrs(entry
->serverNumber
[e
], server
,
53 if (type
== VLSF_RWVOL
)
54 return -1; /* quit when we are looking for RW entry (there's only 1) */
60 "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
61 entry
->serverNumber
[e
], error
);
65 if (e
>= entry
->nServers
)
66 return -1; /* Didn't find it */
68 return e
; /* return the index */
71 /* Changes the rw site only */
73 SetAValue(struct nvldbentry
*entry
, afs_uint32 oserver
, afs_int32 opart
,
74 afs_uint32 nserver
, afs_int32 npart
, afs_int32 type
)
78 e
= FindIndex(entry
, oserver
, opart
, type
);
80 return; /* If didn't find it, just return */
82 entry
->serverNumber
[e
] = nserver
;
83 entry
->serverPartition
[e
] = npart
;
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
];
95 /* Changes the RW site only */
97 Lp_SetRWValue(struct nvldbentry
*entry
, afs_uint32 oserver
, afs_int32 opart
,
98 afs_uint32 nserver
, afs_int32 npart
)
100 SetAValue(entry
, oserver
, opart
, nserver
, npart
, VLSF_RWVOL
);
103 /* Changes the RO site only */
105 Lp_SetROValue(struct nvldbentry
*entry
, afs_uint32 oserver
,
106 afs_int32 opart
, afs_uint32 nserver
, afs_int32 npart
)
108 SetAValue(entry
, oserver
, opart
, nserver
, npart
, VLSF_ROVOL
);
111 /* Returns success if this server and partition matches the RW entry */
113 Lp_Match(afs_uint32 server
, afs_int32 part
,
114 struct nvldbentry
*entry
)
116 if (FindIndex(entry
, server
, part
, VLSF_RWVOL
) == -1)
121 /* Return the index of the RO entry (plus 1) if it exists, else return 0 */
123 Lp_ROMatch(afs_uint32 server
, afs_int32 part
, struct nvldbentry
*entry
)
125 return (FindIndex(entry
, server
, part
, VLSF_ROVOL
) + 1);
128 /* Return the index of the RW entry if it exists, else return -1 */
130 Lp_GetRwIndex(struct nvldbentry
*entry
)
132 return (FindIndex(entry
, 0, 0, VLSF_RWVOL
));
135 /*initialize queue pointed by <ahead>*/
137 Lp_QInit(struct qHead
*ahead
)
143 /*add <elem> in front of queue <ahead> */
145 Lp_QAdd(struct qHead
*ahead
, struct aqueue
*elem
)
149 if (ahead
->count
== 0) {
162 Lp_QScan(struct qHead
*ahead
, afs_int32 id
, int *success
, struct aqueue
**elem
)
167 while (cptr
!= NULL
) {
168 if (cptr
->ids
[RWVOL
] == id
) {
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*/
182 Lp_QEnumerate(struct qHead
*ahead
, int *success
, struct aqueue
*elem
)
187 if (ahead
->count
> 0) { /*more elements left */
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
];
200 } else /*queue is empty */
205 Lp_QTraverse(struct qHead
*ahead
)
208 struct aqueue
*old
, *new;
212 count
= ahead
->count
;
214 ("traversing the internal queue, which groups all the related volumes on a per partition basis\n");
216 printf("---------------------------\n");
217 printf("%s RW-Id %lu", old
->name
, (unsigned long)old
->ids
[RWVOL
]);
218 if (old
->isValid
[RWVOL
])
222 printf("RO-Id %lu", (unsigned long)old
->ids
[ROVOL
]);
223 if (old
->isValid
[ROVOL
])
227 printf("BACKUP-Id %lu", (unsigned long)old
->ids
[BACKVOL
]);
228 if (old
->isValid
[BACKVOL
])
233 printf("---------------------------\n");