Index: src/afs/afs_pioctl.c =================================================================== RCS file: /cvs/openafs/src/afs/afs_pioctl.c,v retrieving revision 1.110.2.34 diff -r1.110.2.34 afs_pioctl.c 121a122,126 > /* > * Patch for Google Summer of Code - implementing a random server > * rank > */ > DECL_PIOCTL(PSetSPrefsRand); 223a229 > PSetSPrefsRand, /* 70 - Randomize the server preference list */ 3550a3557,3659 > > static int > afs_randsetsprefs(struct spref *sp, unsigned int num, unsigned int vlonly) > { > struct srvAddr *sa; > int i, j, k, matches, touchedSize; > struct server *srvr = NULL; > afs_int32 touched[34]; > int isfs; > > touchedSize = 0; > for (k = 0; k < num; sp++, k++) { > if (debugsetsp) { > printf("sp host=%x, rank=%d\n", sp->host.s_addr, sp->rank); > } > matches = 0; > ObtainReadLock(&afs_xserver); > > i = SHash(sp->host.s_addr); > for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { > if (sa->sa_ip == sp->host.s_addr) { > srvr = sa->server; > isfs = (srvr->cell && (sa->sa_portal == srvr->cell->fsport)) > || (sa->sa_portal == AFS_FSPORT); > if ((!vlonly && isfs) || (vlonly && !isfs)) { > matches++; > break; > } > } > } > > if (sa && matches) { /* found one! */ > if (debugsetsp) { > printf("sa ip=%x, ip_rank=%d\n", sa->sa_ip, sa->sa_iprank); > } > sa->sa_iprank = afs_randomMod15(); > afs_SortOneServer(sa->server); > > if (srvr->cell) { > /* if we don't know yet what cell it's in, this is moot */ > for (j = touchedSize - 1; > j >= 0 && touched[j] != srvr->cell->cellNum; j--) > /* is it in our list of touched cells ? */ ; > if (j < 0) { /* no, it's not */ > touched[touchedSize++] = srvr->cell->cellNum; > if (touchedSize >= 32) { /* watch for ovrflow */ > ReleaseReadLock(&afs_xserver); > ReSortCells(touchedSize, touched, vlonly); > touchedSize = 0; > ObtainReadLock(&afs_xserver); > } > } > } > } > > ReleaseReadLock(&afs_xserver); > /* if we didn't find one, start to create one. */ > /* Note that it doesn't have a cell yet... */ > if (!matches) { > afs_uint32 temp = sp->host.s_addr; > srvr = > afs_GetServer(&temp, 1, 0, (vlonly ? AFS_VLPORT : AFS_FSPORT), > WRITE_LOCK, (afsUUID *) 0, 0); > srvr->addr->sa_iprank = afs_randomMod15(); > afs_PutServer(srvr, WRITE_LOCK); > } > } /* for all cited preferences */ > > ReSortCells(touchedSize, touched, vlonly); > return 0; > } > > > /* > * VIOC_SETSPREFSRAND (70) - Set server ranks randomly > * > * \param[in] ain the server preferences to be set > * \param[out] aout not in use > * > * \retval EIO Error if the afs daemon hasn't started yet > * \retval EACCES Error if the user doesn't have super-user credentials > * > * \post set the server preferences, calling a function > * > * \notes this may only be performed by the local root user. > */ > > DECL_PIOCTL(PSetSPrefsRand) > { > struct spref *sp; > AFS_STATCNT(PSetSPrefs); > if (!afs_resourceinit_flag) /* afs daemons haven't started yet */ > return EIO; /* Inappropriate ioctl for device */ > > > if (!afs_osi_suser(*acred)) > return EACCES; > > sp = (struct spref *)ain; > afs_randsetsprefs(sp, ainSize / (sizeof(struct spref)), 0 /*!vlonly */ ); > return 0; > } > Index: src/venus/fs.c =================================================================== RCS file: /cvs/openafs/src/venus/fs.c,v retrieving revision 1.30.2.21 diff -r1.30.2.21 fs.c 3215a3216,3287 > GetPrefCmdRand(struct cmd_syndesc *as, void *arock) > { > afs_int32 code; > struct cmd_item *ti; > char *name, tbuffer[20]; > afs_int32 addr; > FILE *outfd; > int resolve; > int vlservers = 0; > struct ViceIoctl blob; > struct sprefrequest *in; > struct sprefinfo *out; > int i; > > ti = as->parms[0].items; /* -file */ > if (ti) { > if (debug) > fprintf(stderr, "opening file %s\n", ti->data); > if (!(outfd = freopen(ti->data, "w", stdout))) { > perror(ti->data); > return 1; > } > } > > ti = as->parms[1].items; /* -numeric */ > resolve = !(ti); > ti = as->parms[2].items; /* -vlservers */ > vlservers |= (ti ? DBservers : 0); > /* ti = as->parms[3].items; -cell */ > > in = (struct sprefrequest *)space; > in->offset = 0; > > do { > blob.in_size = sizeof(struct sprefrequest); > blob.in = (char *)in; > blob.out = space; > blob.out_size = MAXSIZE; > > in->num_servers = > (MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref); > in->flags = vlservers; > > code = pioctl(0, VIOC_GETSPREFSRAND, &blob, 1); /* VIOC_GETSPREFSRAND */ > if (code) { > perror("randomserverprefs pioctl"); > return 1; > } > > out = (struct sprefinfo *)blob.out; > > for (i = 0; i < out->num_servers; i++) { > if (resolve) { > name = hostutil_GetNameByINet(out->servers[i].server.s_addr); > } else { > addr = ntohl(out->servers[i].server.s_addr); > sprintf(tbuffer, "%d.%d.%d.%d", (addr >> 24) & 0xff, > (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); > name = tbuffer; > } > printf("%-50s %5u\n", name, out->servers[i].rank); > } > > in->offset = out->next_offset; > } while (out->next_offset > 0); > > return 0; > } > > > > static int 3509a3582,3591 > ts = cmd_CreateSyntax("randomserverprefs", GetPrefCmdRand, NULL, > "get server ranks"); > cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, > "output to named file"); > cmd_AddParm(ts, "-numeric", CMD_FLAG, CMD_OPTIONAL, "addresses only"); > cmd_AddParm(ts, "-vlservers", CMD_FLAG, CMD_OPTIONAL, "VL servers"); > /* cmd_AddParm(ts, "-cell", CMD_FLAG, CMD_OPTIONAL, "cellname"); */ > cmd_CreateAlias(ts, "gp"); > > Index: src/config/venus.h =================================================================== RCS file: /cvs/openafs/src/config/venus.h,v retrieving revision 1.12.2.8 diff -r1.12.2.8 venus.h 161a162 > #define VIOC_GETSPREFSRAND _VICEIOCTL(70) /* randomize server ranks */