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
10 #include <afs/param.h>
11 #include <afsconfig.h>
17 #include "lockprocs.h"
18 #include <afs/afs_AdminErrors.h>
28 * Functions that aren't prototyped, but that we use
31 extern int VL_CreateEntryN(), VL_CreateEntry(), VL_GetEntryByIDN(), VL_GetEntryByID(), VL_GetEntryByNameN(), VL_GetEntryByNameO(), VL_ReplaceEntryN(), VL_ReplaceEntry(), VL_ListAttributesN(), VL_ListAttributes(), VL_GetAddrsU();
34 * VLDB entry conversion routines.
35 * convert from one type of VLDB record to another. There are only
36 * two types "old" and "new".
39 static int OldVLDB_to_NewVLDB(
40 struct vldbentry *source,
41 struct nvldbentry *dest,
48 bzero(dest, sizeof(struct nvldbentry));
49 strncpy(dest->name, source->name, sizeof(dest->name));
50 for (i = 0; i < source->nServers; i++) {
51 dest->serverNumber[i] = source->serverNumber[i];
52 dest->serverPartition[i] = source->serverPartition[i];
53 dest->serverFlags[i] = source->serverFlags[i];
55 dest->nServers = source->nServers;
56 for (i = 0; i < MAXTYPES; i++)
57 dest->volumeId[i] = source->volumeId[i];
58 dest->cloneId = source->cloneId;
59 dest->flags = source->flags;
70 * We can fail to store the new to old VLDB record if there are more
71 * servers in the cell than the old format can handle. If we fail,
75 static int NewVLDB_to_OldVLDB(
76 struct nvldbentry *source,
77 struct vldbentry *dest,
84 bzero(dest, sizeof(struct vldbentry));
85 strncpy(dest->name, source->name, sizeof(dest->name));
86 if (source->nServers <= OMAXNSERVERS) {
87 for (i = 0; i < source->nServers; i++) {
88 dest->serverNumber[i] = source->serverNumber[i];
89 dest->serverPartition[i] = source->serverPartition[i];
90 dest->serverFlags[i] = source->serverFlags[i];
93 for (i = 0; i < MAXTYPES; i++)
94 dest->volumeId[i] = source->volumeId[i];
95 dest->cloneId = source->cloneId;
96 dest->flags = source->flags;
108 int VLDB_CreateEntry(
109 afs_cell_handle_p cellHandle,
110 struct nvldbentry *entryp,
113 struct vldbentry oentry;
114 afs_status_t tst = 0;
118 if (cellHandle->vos_new) {
119 tst = ubik_Call(VL_CreateEntryN, cellHandle->vos, 0, entryp);
121 if (tst == RXGEN_OPCODE) {
122 cellHandle->vos_new = 0;
128 if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
129 tst = ubik_Call(VL_CreateEntry, cellHandle->vos, 0, &oentry);
135 } while (tst == RXGEN_OPCODE);
143 int VLDB_GetEntryByID(
144 afs_cell_handle_p cellHandle,
147 struct nvldbentry *entryp,
150 struct vldbentry oentry;
151 afs_status_t tst = 0;
155 if (cellHandle->vos_new) {
156 tst = ubik_Call(VL_GetEntryByIDN, cellHandle->vos, 0, volid,
159 if (tst == RXGEN_OPCODE) {
160 cellHandle->vos_new = 0;
166 tst = ubik_Call(VL_GetEntryByID, cellHandle->vos, 0, volid,
169 rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
173 } while (tst == RXGEN_OPCODE);
181 int VLDB_GetEntryByName(
182 afs_cell_handle_p cellHandle,
184 struct nvldbentry *entryp,
187 struct vldbentry oentry;
188 afs_status_t tst = 0;
192 if (cellHandle->vos_new) {
193 tst = ubik_Call(VL_GetEntryByNameN, cellHandle->vos, 0, namep,
196 if (tst == RXGEN_OPCODE) {
197 cellHandle->vos_new = 0;
203 tst = ubik_Call(VL_GetEntryByNameO, cellHandle->vos, 0, namep,
206 rc = OldVLDB_to_NewVLDB(&oentry, entryp, &tst);
210 } while (tst == RXGEN_OPCODE);
218 int VLDB_ReplaceEntry(
219 afs_cell_handle_p cellHandle,
222 struct nvldbentry *entryp,
223 afs_int32 releasetype,
226 struct vldbentry oentry;
227 afs_status_t tst = 0;
231 if (cellHandle->vos_new) {
232 tst = ubik_Call(VL_ReplaceEntryN, cellHandle->vos, 0, volid,
233 voltype, entryp, releasetype);
235 if (tst == RXGEN_OPCODE) {
236 cellHandle->vos_new = 0;
242 if (NewVLDB_to_OldVLDB(entryp, &oentry, &tst)) {
243 tst = ubik_Call(VL_ReplaceEntry, cellHandle->vos, 0, volid,
244 voltype, &oentry, releasetype);
250 } while (tst == RXGEN_OPCODE);
258 int VLDB_ListAttributes(
259 afs_cell_handle_p cellHandle,
260 VldbListByAttributes *attrp,
262 nbulkentries *blkentriesp,
265 bulkentries arrayEntries;
267 afs_status_t tst = 0;
271 if (cellHandle->vos_new) {
272 tst = ubik_Call(VL_ListAttributesN, cellHandle->vos, 0, attrp,
273 entriesp, blkentriesp);
275 if (tst == RXGEN_OPCODE) {
276 cellHandle->vos_new = 0;
282 memset((void *) &arrayEntries, 0, sizeof(arrayEntries));
283 tst = ubik_Call(VL_ListAttributes, cellHandle->vos, 0, attrp,
284 entriesp, arrayEntries);
286 blkentriesp->nbulkentries_val = (nvldbentry *) malloc(*entriesp * sizeof(*blkentriesp));
287 if (blkentriesp->nbulkentries_val != NULL) {
288 for(i=0;i< *entriesp;i++) {
289 OldVLDB_to_NewVLDB((struct vldbentry *) &arrayEntries.bulkentries_val[i], (struct nvldbentry *) &blkentriesp->nbulkentries_val[i], &tst);
294 if (arrayEntries.bulkentries_val) {
295 free(arrayEntries.bulkentries_val);
301 } while (tst == RXGEN_OPCODE);
309 int VLDB_ListAttributesN2(
310 afs_cell_handle_p cellHandle,
311 VldbListByAttributes *attrp,
314 afs_int32 *nentriesp,
315 nbulkentries *blkentriesp,
316 afs_int32 *nextindexp,
320 afs_status_t tst = 0;
322 tst = ubik_Call(VL_ListAttributesN2, cellHandle->vos, 0,
323 attrp, (name ? name : ""), thisindex,
324 nentriesp, blkentriesp, nextindexp);
335 int VLDB_IsSameAddrs(
336 afs_cell_handle_p cellHandle,
343 afs_status_t tst = 0;
345 ListAddrByAttributes attrs;
355 if (serv1 == serv2) {
358 goto fail_VLDB_IsSameAddrs;
361 bzero(&attrs, sizeof(attrs));
362 attrs.Mask = VLADDR_IPADDR;
363 attrs.ipaddr = serv1;
364 bzero(&addrs, sizeof(addrs));
365 bzero(&uuid, sizeof(uuid));
366 tst = ubik_Call(VL_GetAddrsU, cellHandle->vos, 0, &attrs, &uuid,
367 &unique, &nentries, &addrs);
370 goto fail_VLDB_IsSameAddrs;
373 addrp = addrs.bulkaddrs_val;
374 for (i = 0; i < nentries; i++, addrp++) {
375 if (serv2 == *addrp) {
382 fail_VLDB_IsSameAddrs:
391 * GetVolumeInfo - retrieve information about a particular volume.
395 * IN cellHandle - a handle that corresponds to the cell where the volume
398 * IN volid - the volume to be retrieved.
400 * OUT rentry - the vldb entry of the volume.
402 * OUT server - the address of the server where the volume resides in
405 * OUT partition - the volume to be retrieved.
407 * OUT voltype - the type of volume retrieved.
411 * No locks are obtained or released by this function
415 * Returns != 0 upon successful completion.
419 afs_cell_handle_p cellHandle,
421 struct nvldbentry *rentry,
423 afs_int32 *partition,
431 if (!VLDB_GetEntryByID(cellHandle, volid, -1, rentry, &tst)) {
433 goto fail_GetVolumeInfo;
436 if(volid == rentry->volumeId[ROVOL]){
438 for (i = 0; i < rentry->nServers; i++) {
439 if ( (index == -1) && (rentry->serverFlags[i] & ITSROVOL) &&
440 !(rentry->serverFlags[i] & RO_DONTUSE) )
445 goto fail_GetVolumeInfo;
447 *server = rentry->serverNumber[index];
448 *partition = rentry->serverPartition[index];
450 goto fail_GetVolumeInfo;
453 if ((index = Lp_GetRwIndex(cellHandle, rentry, &tst))<0) {
454 goto fail_GetVolumeInfo;
456 if(volid == rentry->volumeId[RWVOL]){
458 *server = rentry->serverNumber[index];
459 *partition = rentry->serverPartition[index];
460 } else if(volid == rentry->volumeId[BACKVOL]){
462 *server = rentry->serverNumber[index];
463 *partition = rentry->serverPartition[index];
476 * ValidateVolumeName - validate a potential volume name
480 * IN volumeName - the volume name to be validated.
484 * No locks are obtained or released by this function
488 * Returns != 0 upon successful completion.
491 int ValidateVolumeName(
492 const char *volumeName,
496 afs_status_t tst = 0;
499 if ((volumeName == NULL) || (*volumeName == 0)) {
500 tst = ADMVOSVOLUMENAMENULL;
501 goto fail_ValidateVolumeName;
504 if (!ISNAMEVALID(volumeName)) {
505 tst = ADMVOSVOLUMENAMETOOLONG;
506 goto fail_ValidateVolumeName;
509 len = strlen(volumeName);
511 if (((len > 8) && (!strcmp(&volumeName[len - 9], ".readonly"))) ||
512 ((len > 6) && (!strcmp(&volumeName[len - 7], ".backup")))) {
513 tst = ADMVOSVOLUMENAMEINVALID;
514 goto fail_ValidateVolumeName;
519 fail_ValidateVolumeName:
528 /*extract the name of volume <name> without readonly or backup suffixes
529 * and return the result as <rname>.
539 total = strlen(sname);
540 if((total > 9) && (!strcmp(&sname[total - 9],".readonly"))) {
541 /*discard the last 8 chars */
542 sname[total - 9] = '\0';
546 else if((total > 7) && (!strcmp(&sname[total - 7 ],".backup"))) {
547 /*discard last 6 chars */
548 sname[total - 7] = '\0';
553 strncpy(rname,name,VOLSER_OLDMAXVOLNAME);
561 * AddressMatch - determines if an IP address matches a pattern
565 * IN addrTest - the IP address to test, in either byte-order
566 * IN addrPattern - the IP address pattern, in the same byte-order
570 * No locks are obtained or released by this function
574 * Returns != 0 if the address matches the pattern specified
575 * (where 255 in any byte in the pattern indicates a wildcard).
585 /* Test the high byte */
586 bTest = addrTest >> 24;
587 bPattern = addrPattern >> 24;
588 if ((bTest != bPattern) && (bPattern != 255)) {
592 /* Test the next-highest byte */
593 bTest = (addrTest >> 16) & 255;
594 bPattern = (addrPattern >> 16) & 255;
595 if ((bTest != bPattern) && (bPattern != 255)) {
599 /* Test the next-to-lowest byte */
600 bTest = (addrTest >> 8) & 255;
601 bPattern = (addrPattern >> 8) & 255;
602 if ((bTest != bPattern) && (bPattern != 255)) {
606 /* Test the low byte */
607 bTest = addrTest & 255;
608 bPattern = addrPattern & 255;
609 if ((bTest != bPattern) && (bPattern != 255)) {
618 * RemoveBadAddresses - (optionally) removes addresses that are better ignored
622 * IN OUT totalp - the number of addresses in the addrsp structure
623 * IN OUT addrsp - a bulk array of addresses
627 * No locks are obtained or released by this function
631 * Returns != 0 upon successful completion.
634 static pthread_once_t badaddr_init_once = PTHREAD_ONCE_INIT;
635 static int addr_to_skip;
637 static void badaddr_once (void)
642 #define cszREG_IGNORE_KEY "Software\\TransarcCorporation\\AFS Control Center"
643 #define cszREG_IGNORE_VALUE "IgnoreBadAddrs"
646 * In order for this routine to do anything, it must first validate
647 * that the user of this machine wants this filtering to take place.
648 * There is an undocumented registry value which signifies that it's
649 * okay to filter bogus IP addresses--and, moreover, indicates
650 * the range of values which may be ignored. Check that value.
654 addr_to_skip = 0; /* don't ignore any addrs unless we find otherwise */
655 if (RegOpenKey (HKEY_LOCAL_MACHINE, cszREG_IGNORE_KEY, &hk) == 0) {
656 DWORD dwType = REG_DWORD;
657 DWORD dwSize = sizeof(addr_to_skip);
658 RegQueryValueEx (hk, cszREG_IGNORE_VALUE, 0,
659 &dwType, (PBYTE)&addr_to_skip, &dwSize);
666 * We only support this functionality (so far) on NT; on other
667 * platforms, we'll never ignore IP addresses. If the feature
668 * is needed in the future, here's the place to add it.
672 addr_to_skip = 0; /* don't skip any addresses */
678 int RemoveBadAddresses(
682 pthread_once (&badaddr_init_once, badaddr_once);
685 * If we've been requested to skip anything, addr_to_skip will be
686 * non-zero. It's actually an IP address of the form:
688 * A "255" means any value is acceptable, and any other value means
689 * the to-be-skipped address must match that value.
692 if (addr_to_skip && addrsp && addrsp->bulkaddrs_val) {
695 for ( ; iiRead < addrsp->bulkaddrs_len; ++iiRead) {
698 * Check this IP address to see if it should be skipped.
701 if (!AddressMatch(addrsp->bulkaddrs_val[iiRead],addr_to_skip)) {
704 * The address is okay; make sure it stays in the list.
707 if (iiWrite != iiRead) {
708 addrsp->bulkaddrs_val[iiWrite] =
709 addrsp->bulkaddrs_val[iiRead];
715 *totalp = (afs_int32)iiWrite;
716 addrsp->bulkaddrs_len = iiWrite;