rendered paste bodyIndex: 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 */