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>
21 #include <sys/types.h>
25 #include <netinet/in.h>
28 #include <afs/voldefs.h>
31 #include <afs/vlserver.h>
33 #include <afs/afsint.h>
38 #include "vsutils_prototypes.h"
39 #include "lockprocs_prototypes.h"
41 /* Finds an index in VLDB entry that matches the volume type, server, and partition.
42 * If type is zero, will match first index of ANY type (RW, BK, or RO).
43 * If server is zero, will match first index of ANY server and partition
44 * Zero is a valid partition field.
47 FindIndex(struct nvldbentry
*entry
, afs_uint32 server
, afs_int32 part
, afs_int32 type
)
52 for (e
= 0; (e
< entry
->nServers
) && !error
; e
++) {
53 if (!type
|| (entry
->serverFlags
[e
] & type
)) {
54 if ((!server
|| (entry
->serverPartition
[e
] == part
))
56 || VLDB_IsSameAddrs(entry
->serverNumber
[e
], server
,
60 return -1; /* quit when we are looking for RW entry (there's only 1) */
66 "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
67 entry
->serverNumber
[e
], error
);
71 if (e
>= entry
->nServers
)
72 return -1; /* Didn't find it */
74 return e
; /* return the index */
77 /* Changes the rw site only */
79 SetAValue(struct nvldbentry
*entry
, afs_uint32 oserver
, afs_int32 opart
,
80 afs_uint32 nserver
, afs_int32 npart
, afs_int32 type
)
84 e
= FindIndex(entry
, oserver
, opart
, type
);
86 return; /* If didn't find it, just return */
88 entry
->serverNumber
[e
] = nserver
;
89 entry
->serverPartition
[e
] = npart
;
91 /* Now move rest of entries up */
92 if ((nserver
== 0L) && (npart
== 0L)) {
93 for (e
++; e
< entry
->nServers
; e
++) {
94 entry
->serverNumber
[e
- 1] = entry
->serverNumber
[e
];
95 entry
->serverPartition
[e
- 1] = entry
->serverPartition
[e
];
96 entry
->serverFlags
[e
- 1] = entry
->serverFlags
[e
];
101 /* Changes the RW site only */
103 Lp_SetRWValue(struct nvldbentry
*entry
, afs_uint32 oserver
, afs_int32 opart
,
104 afs_uint32 nserver
, afs_int32 npart
)
106 SetAValue(entry
, oserver
, opart
, nserver
, npart
, ITSRWVOL
);
109 /* Changes the RO site only */
111 Lp_SetROValue(struct nvldbentry
*entry
, afs_uint32 oserver
,
112 afs_int32 opart
, afs_uint32 nserver
, afs_int32 npart
)
114 SetAValue(entry
, oserver
, opart
, nserver
, npart
, ITSROVOL
);
117 /* Returns success if this server and partition matches the RW entry */
119 Lp_Match(afs_uint32 server
, afs_int32 part
,
120 struct nvldbentry
*entry
)
122 if (FindIndex(entry
, server
, part
, ITSRWVOL
) == -1)
127 /* Return the index of the RO entry (plus 1) if it exists, else return 0 */
129 Lp_ROMatch(afs_uint32 server
, afs_int32 part
, struct nvldbentry
*entry
)
131 return (FindIndex(entry
, server
, part
, ITSROVOL
) + 1);
134 /* Return the index of the RW entry if it exists, else return -1 */
136 Lp_GetRwIndex(struct nvldbentry
*entry
)
138 return (FindIndex(entry
, 0, 0, ITSRWVOL
));
141 /*initialize queue pointed by <ahead>*/
143 Lp_QInit(struct qHead
*ahead
)
149 /*add <elem> in front of queue <ahead> */
151 Lp_QAdd(struct qHead
*ahead
, struct aqueue
*elem
)
155 if (ahead
->count
== 0) {
168 Lp_QScan(struct qHead
*ahead
, afs_int32 id
, int *success
, struct aqueue
**elem
)
173 while (cptr
!= NULL
) {
174 if (cptr
->ids
[RWVOL
] == id
) {
185 /*return the element in the beginning of the queue <ahead>, free
186 *the space used by that element . <success> indicates if enumeration was ok*/
188 Lp_QEnumerate(struct qHead
*ahead
, int *success
, struct aqueue
*elem
)
193 if (ahead
->count
> 0) { /*more elements left */
196 ahead
->next
= ahead
->next
->next
;
197 strncpy(elem
->name
, temp
->name
, VOLSER_OLDMAXVOLNAME
);
198 for (i
= 0; i
< 3; i
++) {
199 elem
->ids
[i
] = temp
->ids
[i
];
200 elem
->copyDate
[i
] = temp
->copyDate
[i
];
201 elem
->isValid
[i
] = temp
->isValid
[i
];
206 } else /*queue is empty */
211 Lp_QTraverse(struct qHead
*ahead
)
214 struct aqueue
*old
, *new;
218 count
= ahead
->count
;
220 ("traversing the internal queue, which groups all the related volumes on a per partition basis\n");
222 printf("---------------------------\n");
223 printf("%s RW-Id %lu", old
->name
, (unsigned long)old
->ids
[RWVOL
]);
224 if (old
->isValid
[RWVOL
])
228 printf("RO-Id %lu", (unsigned long)old
->ids
[ROVOL
]);
229 if (old
->isValid
[ROVOL
])
233 printf("BACKUP-Id %lu", (unsigned long)old
->ids
[BACKVOL
]);
234 if (old
->isValid
[BACKVOL
])
239 printf("---------------------------\n");