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
12 #include "lockprocs.h"
13 #include <afs/afs_AdminErrors.h>
16 * Functions that aren't prototyped, but that we use
19 extern int VL_CreateEntryN(), VL_CreateEntry(), VL_GetEntryByIDN(), VL_GetEntryByID(), VL_GetEntryByNameN(), VL_GetEntryByNameO(), VL_ReplaceEntryN(), VL_ReplaceEntry(), VL_ListAttributesN(), VL_ListAttributes(), VL_GetAddrsU();
22 * VLDB entry conversion routines.
23 * convert from one type of VLDB record to another. There are only
24 * two types "old" and "new".
27 static int OldVLDB_to_NewVLDB(
28 struct vldbentry *source,
29 struct nvldbentry *dest,
36 bzero(dest, sizeof(struct nvldbentry));
37 strncpy(dest->name, source->name, sizeof(dest->name));
38 for (i = 0; i < source->nServers; i++) {
39 dest->serverNumber[i] = source->serverNumber[i];
40 dest->serverPartition[i] = source->serverPartition[i];
41 dest->serverFlags[i] = source->serverFlags[i];
43 dest->nServers = source->nServers;
44 for (i = 0; i < MAXTYPES; i++)
45 dest->volumeId[i] = source->volumeId[i];
46 dest->cloneId = source->cloneId;
47 dest->flags = source->flags;
58 * We can fail to store the new to old VLDB record if there are more
59 * servers in the cell than the old format can handle. If we fail,
63 static int NewVLDB_to_OldVLDB(
64 struct nvldbentry *source,
65 struct vldbentry *dest,
72 bzero(dest, sizeof(struct vldbentry));
73 strncpy(dest->name, source->name, sizeof(dest->name));
74 if (source->nServers <= OMAXNSERVERS) {
75 for (i = 0; i < source->nServers; i++) {
76 dest->serverNumber[i] = source->serverNumber[i];
77 dest->serverPartition[i] = source->serverPartition[i];
78 dest->serverFlags[i] = source->serverFlags[i];
81 for (i = 0; i < MAXTYPES; i++)
82 dest->volumeId[i] = source->volumeId[i];
83 dest->cloneId = source->cloneId;
84 dest->flags = source->flags;
97 afs_cell_handle_p cellHandle,
98 struct nvldbentry *entryp,
101 struct vldbentry oentry;
102 afs_status_t tst = 0;
106 if (cellHandle->vos_new) {
107 tst = ubik_Call(VL_CreateEntryN, cellHandle->vos, 0, entryp);
109 if (tst == RXGEN_OPCODE) {
110 cellHandle->vos_new = 0;
116 if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
117 tst = ubik_Call(VL_CreateEntry, cellHandle->vos, 0, &oentry);
123 } while (tst == RXGEN_OPCODE);
131 int VLDB_GetEntryByID(
132 afs_cell_handle_p cellHandle,
135 struct nvldbentry *entryp,
138 struct vldbentry oentry;
139 afs_status_t tst = 0;
143 if (cellHandle->vos_new) {
144 tst = ubik_Call(VL_GetEntryByIDN, cellHandle->vos, 0, volid,
147 if (tst == RXGEN_OPCODE) {
148 cellHandle->vos_new = 0;
154 tst = ubik_Call(VL_GetEntryByID, cellHandle->vos, 0, volid,
157 rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
161 } while (tst == RXGEN_OPCODE);
169 int VLDB_GetEntryByName(
170 afs_cell_handle_p cellHandle,
172 struct nvldbentry *entryp,
175 struct vldbentry oentry;
176 afs_status_t tst = 0;
180 if (cellHandle->vos_new) {
181 tst = ubik_Call(VL_GetEntryByNameN, cellHandle->vos, 0, namep,
184 if (tst == RXGEN_OPCODE) {
185 cellHandle->vos_new = 0;
191 tst = ubik_Call(VL_GetEntryByNameO, cellHandle->vos, 0, namep,
194 rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
198 } while (tst == RXGEN_OPCODE);
206 int VLDB_ReplaceEntry(
207 afs_cell_handle_p cellHandle,
210 struct nvldbentry *entryp,
211 afs_int32 releasetype,
214 struct vldbentry oentry;
215 afs_status_t tst = 0;
219 if (cellHandle->vos_new) {
220 tst = ubik_Call(VL_ReplaceEntryN, cellHandle->vos, 0, volid,
221 voltype, entryp, releasetype);
223 if (tst == RXGEN_OPCODE) {
224 cellHandle->vos_new = 0;
230 if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
231 tst = ubik_Call(VL_ReplaceEntry, cellHandle->vos, 0, volid,
232 voltype, &oentry, releasetype);
238 } while (tst == RXGEN_OPCODE);
246 int VLDB_ListAttributes(
247 afs_cell_handle_p cellHandle,
248 VldbListByAttributes *attrp,
250 nbulkentries *blkentriesp,
253 bulkentries arrayEntries;
255 afs_status_t tst = 0;
259 if (cellHandle->vos_new) {
260 tst = ubik_Call(VL_ListAttributesN, cellHandle->vos, 0, attrp,
261 entriesp, blkentriesp);
263 if (tst == RXGEN_OPCODE) {
264 cellHandle->vos_new = 0;
270 memset((void *) &arrayEntries, 0, sizeof(arrayEntries));
271 tst = ubik_Call(VL_ListAttributes, cellHandle->vos, 0, attrp,
272 entriesp, arrayEntries);
274 blkentriesp->nbulkentries_val = (nvldbentry *) malloc(*entriesp * sizeof(*blkentriesp));
275 if (blkentriesp->nbulkentries_val != NULL) {
276 for(i=0;i< *entriesp;i++) {
277 OldVLDB_to_NewVLDB((struct vldbentry *) &arrayEntries.bulkentries_val[i], (struct nvldbentry *) &blkentriesp->nbulkentries_val[i], &tst);
282 if (arrayEntries.bulkentries_val) {
283 free(arrayEntries.bulkentries_val);
289 } while (tst == RXGEN_OPCODE);
297 int VLDB_ListAttributesN2(
298 afs_cell_handle_p cellHandle,
299 VldbListByAttributes *attrp,
302 afs_int32 *nentriesp,
303 nbulkentries *blkentriesp,
304 afs_int32 *nextindexp,
308 afs_status_t tst = 0;
310 tst = ubik_Call(VL_ListAttributesN2, cellHandle->vos, 0,
311 attrp, (name ? name : ""), thisindex,
312 nentriesp, blkentriesp, nextindexp);
323 int VLDB_IsSameAddrs(
324 afs_cell_handle_p cellHandle,
331 afs_status_t tst = 0;
333 ListAddrByAttributes attrs;
343 if (serv1 == serv2) {
346 goto fail_VLDB_IsSameAddrs;
349 bzero(&attrs, sizeof(attrs));
350 attrs.Mask = VLADDR_IPADDR;
351 attrs.ipaddr = serv1;
352 bzero(&addrs, sizeof(addrs));
353 bzero(&uuid, sizeof(uuid));
354 tst = ubik_Call(VL_GetAddrsU, cellHandle->vos, 0, &attrs, &uuid,
355 &unique, &nentries, &addrs);
358 goto fail_VLDB_IsSameAddrs;
361 addrp = addrs.bulkaddrs_val;
362 for (i = 0; i < nentries; i++, addrp++) {
363 if (serv2 == *addrp) {
370 fail_VLDB_IsSameAddrs:
379 * GetVolumeInfo - retrieve information about a particular volume.
383 * IN cellHandle - a handle that corresponds to the cell where the volume
386 * IN volid - the volume to be retrieved.
388 * OUT rentry - the vldb entry of the volume.
390 * OUT server - the address of the server where the volume resides in
393 * OUT partition - the volume to be retrieved.
395 * OUT voltype - the type of volume retrieved.
399 * No locks are obtained or released by this function
403 * Returns != 0 upon successful completion.
407 afs_cell_handle_p cellHandle,
409 struct nvldbentry *rentry,
411 afs_int32 *partition,
419 if (!VLDB_GetEntryByID(cellHandle, volid, -1, rentry, &tst)) {
421 goto fail_GetVolumeInfo;
424 if(volid == rentry->volumeId[ROVOL]){
426 for (i = 0; i < rentry->nServers; i++) {
427 if ( (index == -1) && (rentry->serverFlags[i] & ITSROVOL) &&
428 !(rentry->serverFlags[i] & RO_DONTUSE) )
433 goto fail_GetVolumeInfo;
435 *server = rentry->serverNumber[index];
436 *partition = rentry->serverPartition[index];
438 goto fail_GetVolumeInfo;
441 if ((index = Lp_GetRwIndex(cellHandle, rentry, &tst))<0) {
442 goto fail_GetVolumeInfo;
444 if(volid == rentry->volumeId[RWVOL]){
446 *server = rentry->serverNumber[index];
447 *partition = rentry->serverPartition[index];
448 } else if(volid == rentry->volumeId[BACKVOL]){
450 *server = rentry->serverNumber[index];
451 *partition = rentry->serverPartition[index];
464 * ValidateVolumeName - validate a potential volume name
468 * IN volumeName - the volume name to be validated.
472 * No locks are obtained or released by this function
476 * Returns != 0 upon successful completion.
479 int ValidateVolumeName(
480 const char *volumeName,
484 afs_status_t tst = 0;
487 if ((volumeName == NULL) || (*volumeName == 0)) {
488 tst = ADMVOSVOLUMENAMENULL;
489 goto fail_ValidateVolumeName;
492 if (!ISNAMEVALID(volumeName)) {
493 tst = ADMVOSVOLUMENAMETOOLONG;
494 goto fail_ValidateVolumeName;
497 len = strlen(volumeName);
499 if (((len > 8) && (!strcmp(&volumeName[len - 9], ".readonly"))) ||
500 ((len > 6) && (!strcmp(&volumeName[len - 7], ".backup")))) {
501 tst = ADMVOSVOLUMENAMEINVALID;
502 goto fail_ValidateVolumeName;
507 fail_ValidateVolumeName:
516 /*extract the name of volume <name> without readonly or backup suffixes
517 * and return the result as <rname>.
527 total = strlen(sname);
528 if((total > 9) && (!strcmp(&sname[total - 9],".readonly"))) {
529 /*discard the last 8 chars */
530 sname[total - 9] = '\0';
534 else if((total > 7) && (!strcmp(&sname[total - 7 ],".backup"))) {
535 /*discard last 6 chars */
536 sname[total - 7] = '\0';
541 strncpy(rname,name,VOLSER_OLDMAXVOLNAME);
549 * AddressMatch - determines if an IP address matches a pattern
553 * IN addrTest - the IP address to test, in either byte-order
554 * IN addrPattern - the IP address pattern, in the same byte-order
558 * No locks are obtained or released by this function
562 * Returns != 0 if the address matches the pattern specified
563 * (where 255 in any byte in the pattern indicates a wildcard).
573 /* Test the high byte */
574 bTest = addrTest >> 24;
575 bPattern = addrPattern >> 24;
576 if ((bTest != bPattern) && (bPattern != 255)) {
580 /* Test the next-highest byte */
581 bTest = (addrTest >> 16) & 255;
582 bPattern = (addrPattern >> 16) & 255;
583 if ((bTest != bPattern) && (bPattern != 255)) {
587 /* Test the next-to-lowest byte */
588 bTest = (addrTest >> 8) & 255;
589 bPattern = (addrPattern >> 8) & 255;
590 if ((bTest != bPattern) && (bPattern != 255)) {
594 /* Test the low byte */
595 bTest = addrTest & 255;
596 bPattern = addrPattern & 255;
597 if ((bTest != bPattern) && (bPattern != 255)) {
606 * RemoveBadAddresses - (optionally) removes addresses that are better ignored
610 * IN OUT totalp - the number of addresses in the addrsp structure
611 * IN OUT addrsp - a bulk array of addresses
615 * No locks are obtained or released by this function
619 * Returns != 0 upon successful completion.
622 static pthread_once_t badaddr_init_once = PTHREAD_ONCE_INIT;
623 static int addr_to_skip;
625 static void badaddr_once (void)
630 #define cszREG_IGNORE_KEY "Software\\TransarcCorporation\\AFS Control Center"
631 #define cszREG_IGNORE_VALUE "IgnoreBadAddrs"
634 * In order for this routine to do anything, it must first validate
635 * that the user of this machine wants this filtering to take place.
636 * There is an undocumented registry value which signifies that it's
637 * okay to filter bogus IP addresses--and, moreover, indicates
638 * the range of values which may be ignored. Check that value.
642 addr_to_skip = 0; /* don't ignore any addrs unless we find otherwise */
643 if (RegOpenKey (HKEY_LOCAL_MACHINE, cszREG_IGNORE_KEY, &hk) == 0) {
644 DWORD dwType = REG_DWORD;
645 DWORD dwSize = sizeof(addr_to_skip);
646 RegQueryValueEx (hk, cszREG_IGNORE_VALUE, 0,
647 &dwType, (PBYTE)&addr_to_skip, &dwSize);
654 * We only support this functionality (so far) on NT; on other
655 * platforms, we'll never ignore IP addresses. If the feature
656 * is needed in the future, here's the place to add it.
660 addr_to_skip = 0; /* don't skip any addresses */
666 int RemoveBadAddresses(
670 pthread_once (&badaddr_init_once, badaddr_once);
673 * If we've been requested to skip anything, addr_to_skip will be
674 * non-zero. It's actually an IP address of the form:
676 * A "255" means any value is acceptable, and any other value means
677 * the to-be-skipped address must match that value.
680 if (addr_to_skip && addrsp && addrsp->bulkaddrs_val) {
683 for ( ; iiRead < addrsp->bulkaddrs_len; ++iiRead) {
686 * Check this IP address to see if it should be skipped.
689 if (!AddressMatch(addrsp->bulkaddrs_val[iiRead],addr_to_skip)) {
692 * The address is okay; make sure it stays in the list.
695 if (iiWrite != iiRead) {
696 addrsp->bulkaddrs_val[iiWrite] =
697 addrsp->bulkaddrs_val[iiRead];
703 *totalp = (afs_int32)iiWrite;
704 addrsp->bulkaddrs_len = iiWrite;