]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
ubik-clone-support-20010212
authorHartmut Reuter <reuter@rzg.mpg.de>
Mon, 12 Feb 2001 21:57:57 +0000 (21:57 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 12 Feb 2001 21:57:57 +0000 (21:57 +0000)
Changes needed to support ubik (non-voting) clones.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================
Needed kaserver support for ubik clones

====================
Needed support for ubik clones for the ptserver

====================
Support for ubik clones in vlserver

====================
auth layer support for ubik readonly clones

====================
ubik library support for readonly clones

13 files changed:
src/auth/cellconfig.c
src/auth/writeconfig.c
src/bozo/bos.c
src/kauth/kaserver.c
src/ptserver/ptserver.c
src/ubik/beacon.c
src/ubik/recovery.c
src/ubik/ubik.c
src/ubik/ubik.p.h
src/ubik/ubik_int.xg
src/ubik/udebug.c
src/ubik/vote.c
src/vlserver/vlserver.c

index 4a31cac638d7a7df63b1da15cad019eab2be8282..81f78dd8f159133240e310fff7da1aa1325283a0 100644 (file)
@@ -218,7 +218,7 @@ register char *adir; {
     tdir->name = (char *) malloc(strlen(adir)+1);
     strcpy(tdir->name, adir);
 
-    code = afsconf_OpenInternal(tdir);
+    code = afsconf_OpenInternal(tdir, 0, 0);
     if (code) {
        char *afsconf_path, *getenv(), afs_confdir[128];
 
@@ -272,7 +272,7 @@ register char *adir; {
        }
        tdir->name = (char *) malloc(strlen(afsconf_path)+1);
        strcpy(tdir->name, afsconf_path);
-       code = afsconf_OpenInternal(tdir);
+       code = afsconf_OpenInternal(tdir, 0, 0);
        if (code) {
            free(tdir->name);
            free(tdir);
@@ -322,8 +322,11 @@ static int GetCellNT(struct afsconf_dir *adir)
 #endif /* AFS_NT40_ENV */
 
 
-static int afsconf_OpenInternal(adir)
-register struct afsconf_dir *adir; {
+static int afsconf_OpenInternal(adir, cell, clones)
+register struct afsconf_dir *adir; 
+char *cell;
+char clones[];
+{
     FILE *tf;
     register char *tp, *bp;
     register struct afsconf_entry *curEntry;
@@ -409,7 +412,10 @@ register struct afsconf_dir *adir; {
                return -1;
            }
            i = curEntry->cellInfo.numServers;
-           code = ParseHostLine(tbuffer, (char *) &curEntry->cellInfo.hostAddr[i], curEntry->cellInfo.hostName[i]);
+           if (cell && !strcmp(cell, curEntry->cellInfo.name)) 
+                code = ParseHostLine(tbuffer, (char *) &curEntry->cellInfo.hostAddr[i], curEntry->cellInfo.hostName[i], &clones[i]);
+           else
+                code = ParseHostLine(tbuffer, (char *) &curEntry->cellInfo.hostAddr[i], curEntry->cellInfo.hostName[i], 0);
            if (code) {
                if (code == AFSCONF_SYNTAX) {
                    for (bp=tbuffer; *bp != '\n'; bp++) {       /* Take out the <cr> from the buffer */
@@ -442,17 +448,26 @@ register struct afsconf_dir *adir; {
 }
 
 /* parse a line of the form
- *"128.2.1.3   #hostname"
+ *"128.2.1.3   #hostname" or
+ *"[128.2.1.3]  #hostname" for clones
  * into the appropriate pieces.  
  */
-static ParseHostLine(aline, addr, aname)
-register struct sockaddr_in *addr;
-char *aline, *aname; {
+static ParseHostLine(aline, addr, aname, aclone)
+    char *aclone;
+    register struct sockaddr_in *addr;
+    char *aline, *aname; 
+{
     int c1, c2, c3, c4;
     register afs_int32 code;
     register char *tp;
 
-    code = sscanf(aline, "%d.%d.%d.%d #%s", &c1, &c2, &c3, &c4, aname);
+    if (*aline == '[') {
+        if (aclone) *aclone = 1;
+        code = sscanf(aline, "[%d.%d.%d.%d] #%s", &c1, &c2, &c3, &c4, aname);
+    } else {
+        if (aclone) *aclone = 0;
+        code = sscanf(aline, "%d.%d.%d.%d #%s", &c1, &c2, &c3, &c4, aname);
+    }
     if (code != 5) return AFSCONF_SYNTAX;
     addr->sin_family = AF_INET;
     addr->sin_port = 0;
@@ -501,6 +516,30 @@ char *arock; {
 }
 
 afs_int32 afsconf_SawCell = 0;
+
+afsconf_GetExtendedCellInfo(adir, acellName, aservice, acellInfo, clones)
+    struct afsconf_dir *adir;
+    char *aservice;
+    char *acellName;
+    struct afsconf_cell *acellInfo; 
+    char clones[];
+{
+    afs_int32 code;
+    char *cell;
+
+    code = afsconf_GetCellInfo(adir, acellName, aservice, acellInfo);
+    if (code) 
+       return code;
+
+    if (acellName) 
+       cell = acellName;
+    else
+       cell = (char *) &acellInfo->name;
+
+    code = afsconf_OpenInternal(adir, cell, clones);
+    return code;
+}
+
 afsconf_GetCellInfo(adir, acellName, aservice, acellInfo)
 struct afsconf_dir *adir;
 char *aservice;
@@ -520,8 +559,8 @@ struct afsconf_cell *acellInfo; {
        tcell = acellName;
        cnLen = strlen(tcell)+1;
        lcstring (tcell, tcell, cnLen);
-       afsconf_SawCell = 1;                       /* will ignore the AFSCELL switch on future */
-                                                  /* call to afsconf_GetLocalCell: like klog  */
+       afsconf_SawCell = 1;    /* will ignore the AFSCELL switch on future */
+                               /* call to afsconf_GetLocalCell: like klog  */
     } else {
        i = afsconf_GetLocalCell(adir, tbuffer, sizeof(tbuffer));
        if (i) {
@@ -643,7 +682,7 @@ register struct afsconf_dir *adir; {
     register afs_int32 code;
     code = afsconf_CloseInternal(adir);
     if (code) return code;
-    code = afsconf_OpenInternal(adir);
+    code = afsconf_OpenInternal(adir, 0, 0);
     return code;
 }
 
index 925cf999b149da060acde4d4f4951742f56bba37..9e0d81f38125893d21c22ffea8e10417c55f5c46 100644 (file)
@@ -74,7 +74,20 @@ register struct afsconf_cell *aci; {
 afsconf_SetCellInfo(adir, apath, acellInfo)
 struct afsconf_dir *adir;
 char *apath;
-struct afsconf_cell *acellInfo; {
+struct afsconf_cell *acellInfo; 
+{
+    afs_int32 code;
+
+    code = afsconf_SetExtendedCellInfo(adir, apath, acellInfo, (char *)0);
+    return code;
+}
+   
+afsconf_SetExtendedCellInfo(adir, apath, acellInfo, clones)
+    struct afsconf_dir *adir;
+    char *apath;
+    struct afsconf_cell *acellInfo; 
+    char clones[];
+{
     register afs_int32 code;
     register int fd;
     char tbuffer[1024];
@@ -121,7 +134,10 @@ struct afsconf_cell *acellInfo; {
        code = acellInfo->hostAddr[i].sin_addr.s_addr;  /* net order */
        if (code == 0) continue;    /* delete request */
        code = ntohl(code);     /* convert to host order */
-       fprintf(tf, "%d.%d.%d.%d    #%s\n", (code>>24) & 0xff, (code>>16)&0xff, (code>>8)&0xff, code&0xff, acellInfo->hostName[i]);
+        if (clones && clones[i])
+            fprintf(tf, "[%d.%d.%d.%d]  #%s\n", (code>>24) & 0xff, (code>>16)&0xff, (code>>8)&0xff, code&0xff, acellInfo->hostName[i]);
+        else
+           fprintf(tf, "%d.%d.%d.%d    #%s\n", (code>>24) & 0xff, (code>>16)&0xff, (code>>8)&0xff, code&0xff, acellInfo->hostName[i]);
     }
     if (ferror(tf)) {
        fclose(tf);
index f6c1085191ae5d2c677bb1df2a4a2d7b81824d47..f487335b535980ae7653eb656603799a52f756ef 100644 (file)
@@ -707,10 +707,21 @@ register struct cmd_syndesc *as; {
     register struct rx_connection *tconn;
     register afs_int32 code;
     register struct cmd_item *ti;
+    char name[MAXHOSTCHARS];
     
     tconn = GetConn(as, 0);
     for(ti = as->parms[1].items; ti; ti=ti->next) {
-       code = BOZO_AddCellHost(tconn, ti->data);
+        if (as->parms[2].items) {
+           if (strlen(ti->data) > MAXHOSTCHARS - 3) {
+               fprintf(stderr, "bos: host name too long\n");
+               return E2BIG;
+           }
+            name[0] = '[';
+            strcpy(&name[1],ti->data);
+            strcat((char *)&name, "]");
+            code = BOZO_AddCellHost(tconn, name);
+        } else 
+           code = BOZO_AddCellHost(tconn, ti->data);
        if (code)
            printf("bos: failed to add host %s (%s)\n", ti->data, em(code));
     }
@@ -1885,6 +1896,7 @@ main(argc, argv)
     ts = cmd_CreateSyntax("addhost", AddHost, 0, "add host to cell dbase");
     cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name");
     cmd_AddParm(ts, "-host", CMD_LIST, 0, "host name");
+    cmd_AddParm(ts, "-clone", CMD_FLAG, CMD_OPTIONAL, "vote doesn't count");
     add_std_args (ts);
 
     ts = cmd_CreateSyntax("removehost", RemoveHost, 0,
index e3374eef6c6488002a989f92299aa9ac030aa203..3bb2cf37bb89885e095e637d656c42c5fa692785 100644 (file)
@@ -156,6 +156,8 @@ main (argc, argv)
     int          servers;
     int          initFlags;
     int   level;                       /* security level for Ubik */
+    afs_int32 i;
+    char  clones[MAXHOSTSPERCELL];
 
     struct rx_service *tservice;
     struct rx_securityClass *sca[1];
@@ -282,15 +284,21 @@ main (argc, argv)
     OpenLog(AFSDIR_SERVER_KALOG_FILEPATH); 
     SetupLogSignals();
 #endif
+    code = afsconf_GetExtendedCellInfo (KA_conf, cell, AFSCONF_KAUTHSERVICE,
+                                    &cellinfo, &clones);
     if (servers) {
        if (code = ubik_ParseServerList(argc, argv, &myHost, serverList)) {
            com_err(whoami, code, "Couldn't parse server list");
            exit(1);
        }
+        cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
+        for (i=1; i<MAXSERVERS; i++) {
+            if (!serverList[i]) break;
+            cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
+        }
+        cellinfo.numServers = i;
     }
     else {
-       code = afsconf_GetCellInfo (KA_conf, cell, AFSCONF_KAUTHSERVICE,
-                                   &cellinfo);
        code = convert_cell_to_ubik (&cellinfo, &myHost, serverList);
        if (code) goto abort;
        ViceLog (0, ("Using server list from %s cell database.\n", cell));
@@ -313,8 +321,13 @@ main (argc, argv)
     ubik_CheckRXSecurityRock = (char *)KA_conf;
 
     ubik_nBuffers = 80;
-    code = ubik_ServerInit (myHost, htons(AFSCONF_KAUTHPORT), serverList,
-                           dbpath, &KA_dbase);
+    if (servers)
+        code = ubik_ServerInit (myHost, htons(AFSCONF_KAUTHPORT), serverList,
+                            dbpath, &KA_dbase);
+    else
+        code = ubik_ServerInitByInfo (myHost, htons(AFSCONF_KAUTHPORT), 
+                           &cellinfo, &clones, dbpath, &KA_dbase);
+
     if (code) {
        com_err(whoami, code, "Ubik init failed");
        exit(2);
index 291251f34876b52d712df01450ea02b2fc0db076..e29fe7cfd1e62beddf86d0e54b1f916eb3d2c187 100644 (file)
@@ -64,7 +64,6 @@ void main (argc, argv)
   char **argv;
 {
     register afs_int32 code;
-    afs_int32 serverList[MAXSERVERS];
     afs_int32 myHost;
     register struct hostent *th;
     char hostname[64];
@@ -81,6 +80,7 @@ void main (argc, argv)
     int kerberosKeys;                  /* set if found some keys */
     afs_int32 i,j;
     int lwps = 3;
+    char clones[MAXHOSTSPERCELL];
 
     const char *pr_dbaseName;
     char *whoami = "ptserver";
@@ -189,7 +189,8 @@ void main (argc, argv)
     bcopy(th->h_addr,&myHost,sizeof(afs_int32));
         
     /* get list of servers */
-    code = afsconf_GetCellInfo(prdir,(char *)0,"afsprot",&info);
+    code = afsconf_GetExtendedCellInfo(prdir,(char *)0,"afsprot",
+                       &info, &clones);
     if (code) {
        com_err (whoami, code, "Couldn't get server list");
        PT_EXIT(2);
@@ -197,11 +198,6 @@ void main (argc, argv)
     pr_realmName = info.name;
     pr_realmNameLen = strlen (pr_realmName);
 
-    for (i=0,j=0;i<info.numServers;i++)
-       if (info.hostAddr[i].sin_addr.s_addr != myHost) /* ubik already tacks myHost onto list */
-           serverList[j++] = info.hostAddr[i].sin_addr.s_addr;
-    serverList[j] = 0;
-
 #if 0
     /* get keys */
     code = afsconf_GetKey(prdir,999,&tkey);
@@ -234,8 +230,8 @@ void main (argc, argv)
      * and the header are in separate Ubik buffers then 120 buffers may be
      * required. */
     ubik_nBuffers = 120 + /*fudge*/40;
-    code = ubik_ServerInit(myHost, htons(AFSCONF_PROTPORT), serverList,
-                          pr_dbaseName, &dbase);
+    code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info,
+                           &clones, pr_dbaseName, &dbase);
     if (code) {
        com_err (whoami, code, "Ubik init failed");
        PT_EXIT(2);
index 63687facf08a4f517700a5ac1d830f0dd02b14bf..59fb4c8d63f9c5b0d1d1b6ef955905ea004f9f51 100644 (file)
@@ -24,6 +24,7 @@
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <rx/rx_multi.h>
+#include <afs/cellconfig.h>
 #ifndef AFS_NT40_ENV
 #include <afs/afsutil.h>
 #include <afs/netutils.h>
@@ -38,6 +39,8 @@ static afs_int32 syncSiteUntil = 0;       /* valid only if amSyncSite */
 int ubik_amSyncSite = 0;           /* flag telling if I'm sync site */
 static nServers;                   /* total number of servers */
 static char amIMagic=0;                    /* is this host the magic host */
+char amIClone=0;                    /* is this a clone which doesn't vote */
+static char ubik_singleServer = 0;
 extern struct rx_securityClass *rxnull_NewClientSecurityObject();
 int (*ubik_CRXSecurityProc)();
 char *ubik_CRXSecurityRock;
@@ -91,11 +94,11 @@ ubeacon_AmSyncSite() {
     register afs_int32 rcode;
     
     /* special case for fast startup */
-    if (nServers == 1) {
+    if (nServers == 1 && !amIClone) {
        return 1;       /* one guy is always the sync site */
     }
 
-    if (ubik_amSyncSite == 0) rcode = 0;  /* if I don't think I'm the sync site, say so */
+    if (ubik_amSyncSite == 0 || amIClone) rcode = 0;  /* if I don't think I'm the sync site, say so */
     else {
        now = FT_ApproxTime();
        if (syncSiteUntil <= now) {         /* if my votes have expired, say so */
@@ -127,17 +130,43 @@ ubeacon_AmSyncSite() {
  * is sync site.  Without the magic host hack, if anyone crashed in a 2
  * site system, we'd be out of business.
  */
+ubeacon_InitServerListByInfo(ame, info, clones)
+    afs_int32 ame;
+    struct afsconf_cell *info;
+    char clones[];
+{
+    afs_int32 code;
+
+    code = ubeacon_InitServerListCommon(ame, info, clones, 0);
+    return code;
+}
+
 ubeacon_InitServerList(ame, aservers)
     afs_int32 ame;
-    register afs_int32 aservers[]; {
+    register afs_int32 aservers[];
+{
+    afs_int32 code;
+
+    code = ubeacon_InitServerListCommon(ame, (struct afsconf_cell *)0, 0,
+                                                       aservers);
+    return code;
+}
+
+ubeacon_InitServerListCommon(ame, info, clones, aservers)
+    afs_int32 ame;
+    struct afsconf_cell *info;
+    char clones[];
+    register afs_int32 aservers[];
+{
     register struct ubik_server *ts;
+    afs_int32 me = -1;
     register afs_int32 servAddr;
     register afs_int32 i, code;
     afs_int32 magicHost;
     struct ubik_server *magicServer;
 
     /* verify that the addresses passed in are correct */
-    if ( code = verifyInterfaceAddress(&ame, aservers ))
+    if (code = verifyInterfaceAddress(&ame, info, aservers))
        return code;
 
     /* get the security index to use, if we can */
@@ -150,28 +179,79 @@ ubeacon_InitServerList(ame, aservers)
        ubikSecIndex = 0;
        ubikSecClass = rxnull_NewClientSecurityObject();
     }
-    i = 0;
     magicHost =        ntohl(ame);     /* do comparisons in host order */
     magicServer = (struct ubik_server *) 0;
-    while (servAddr = *aservers++) {
-       if (i >= MAXSERVERS) return UNHOSTS;        /* too many hosts */
-       ts = (struct ubik_server *) malloc(sizeof(struct ubik_server));
-       bzero(ts, sizeof(struct ubik_server));
-       ts->next = ubik_servers;
-       ubik_servers = ts;
-       ts->addr[0] = servAddr; /* primary address in  net byte order */
-       ts->vote_rxcid = rx_NewConnection(servAddr, ubik_callPortal, VOTE_SERVICE_ID, ubikSecClass, ubikSecIndex);      /* for vote reqs */
-       ts->disk_rxcid = rx_NewConnection(servAddr, ubik_callPortal, DISK_SERVICE_ID, ubikSecClass, ubikSecIndex);      /* for disk reqs */
-       ts->up = 1;
-       if (ntohl((afs_uint32) servAddr) < (afs_uint32) magicHost) {
-           magicHost = ntohl(servAddr);
-           magicServer = ts;
+
+    if (info) {
+        for (i = 0; i < info->numServers; i++) {
+            if (ntohl((afs_uint32) info->hostAddr[i].sin_addr.s_addr) ==
+                                                ntohl((afs_uint32) ame)) {
+                me = i;
+                if (clones[i]) {
+                    amIClone = 1;
+                    magicHost = 0;
+                }
+            }
+        }
+        nServers = 0;
+        for (i = 0; i < info->numServers; i++) {
+            if (i == me) continue;
+           ts = (struct ubik_server *) malloc(sizeof(struct ubik_server));
+           bzero(ts, sizeof(struct ubik_server));
+           ts->next = ubik_servers;
+           ubik_servers = ts;
+            ts->addr[0] = info->hostAddr[i].sin_addr.s_addr;
+            if (clones[i]) {
+                ts->isClone = 1;
+            } else {
+                if (!magicHost || 
+               ntohl((afs_uint32) ts->addr[0]) < (afs_uint32) magicHost) {
+                    magicHost = ntohl(ts->addr[0]);
+                    magicServer = ts;
+                }
+                ++nServers;
+            }
+           ts->vote_rxcid = rx_NewConnection(servAddr, ubik_callPortal, 
+               VOTE_SERVICE_ID, 
+               ubikSecClass, ubikSecIndex);            /* for vote reqs */
+           ts->disk_rxcid = rx_NewConnection(servAddr, ubik_callPortal, 
+               DISK_SERVICE_ID, ubikSecClass, 
+               ubikSecIndex);                          /* for disk reqs */
+           ts->up = 1;
+       }
+    } else {
+        i = 0;
+        while (servAddr = *aservers++) {
+           if (i >= MAXSERVERS) return UNHOSTS;            /* too many hosts */
+           ts = (struct ubik_server *) malloc(sizeof(struct ubik_server));
+           bzero(ts, sizeof(struct ubik_server));
+           ts->next = ubik_servers;
+           ubik_servers = ts;
+           ts->addr[0] = servAddr;     /* primary address in  net byte order */
+           ts->vote_rxcid = rx_NewConnection(servAddr, ubik_callPortal, 
+               VOTE_SERVICE_ID, 
+               ubikSecClass, ubikSecIndex);            /* for vote reqs */
+           ts->disk_rxcid = rx_NewConnection(servAddr, ubik_callPortal, 
+               DISK_SERVICE_ID, ubikSecClass, 
+               ubikSecIndex);                          /* for disk reqs */
+           ts->isClone = 0;                    /* don't know about clones */
+           ts->up = 1;
+           if (ntohl((afs_uint32) servAddr) < (afs_uint32) magicHost) {
+               magicHost = ntohl(servAddr);
+               magicServer = ts;
+           }
+           i++;
        }
-       i++;
     }
     if (magicServer) magicServer->magic        = 1;    /* remember for when counting votes */
-    else amIMagic = 1;
-    nServers = i+1;    /* count this server as well as the remotes */
+
+    if (!amIClone && !magicServer) amIMagic = 1;
+    if (info) {
+        if (!amIClone) 
+            ++nServers;        /* count this server as well as the remotes */
+    } else
+        nServers = i+1;                /* count this server as well as the remotes */
+
     ubik_quorum        = (nServers>>1)+1;      /* compute the majority figure */
                                        /* send addrs to all other servers */
     code = updateUbikNetworkAddress(ubik_host);
@@ -182,7 +262,19 @@ ubeacon_InitServerList(ame, aservers)
     r_retryInterval = 2;       
     r_nRetries = (RPCTIMEOUT/r_retryInterval);
 */
-    if (nServers == 1) {    /* special case 1 server */
+    if (info) {
+       if (!ubik_servers)              /* special case 1 server */
+           ubik_singleServer = 1;
+       if (nServers == 1 && !amIClone) {
+           ubik_amSyncSite = 1;        /* let's start as sync site */
+           syncSiteUntil = 0x7fffffff; /* and be it quite a while */
+       }
+    } else {
+       if (nServers == 1)              /* special case 1 server */
+           ubik_singleServer = 1;
+    }
+
+    if (ubik_singleServer) {   
         if (!ubik_amSyncSite) ubik_dprint("Ubik: I am the sync site - 1 server\n");
        ubik_amSyncSite = 1;
        syncSiteUntil = 0x7fffffff; /* quite a while */
@@ -222,7 +314,7 @@ ubeacon_Interact() {
 
        lastWakeupTime = FT_ApproxTime();   /* started a new collection phase */
 
-       if (nServers == 1) continue;    /* special-case 1 server for speedy startup */
+        if (ubik_singleServer) continue;    /* special-case 1 server for speedy startup */
 
        if (!uvote_ShouldIRun()) continue;  /* if voter has heard from a better candidate than us, don't bother running */
 
@@ -233,7 +325,7 @@ ubeacon_Interact() {
            prepare to send them an r multi-call containing the beacon message */
        i = 0;      /* collect connections */
        for(ts = ubik_servers; ts; ts=ts->next) {
-           if (ts->up && ts->addr[0] != ubik_host[0]) {
+            if (ts->up && ts->addr[0] != ubik_host[0]) {
                servers[i] = ts;
                connections[i++] = ts->vote_rxcid;
            }
@@ -279,7 +371,8 @@ ubeacon_Interact() {
                    ts->lastVoteTime = code;
                    if (code < oldestYesVote) oldestYesVote = code;
                    ts->lastVote = 1;
-                   yesVotes += 2;
+                    if (!ts->isClone)
+                       yesVotes += 2;
                    if (ts->magic) yesVotes++;  /* the extra epsilon */
                    ts->up = 1; /* server is up (not really necessary: recovery does this for real) */
                    ts->beaconSinceDown = 1;
@@ -340,16 +433,20 @@ ubeacon_Interact() {
 *
 * Return Values : 0 on success, non-zero on failure
 */
-verifyInterfaceAddress(ame, aservers)
-afs_uint32 *ame;               /* one of my interface addr in net byte order */
-afs_uint32 aservers[];         /* list of all possible server addresses */
+static verifyInterfaceAddress(ame, info, aservers)
+    struct afsconf_cell *info;
+    afs_uint32 aservers[];     /* list of all possible server addresses */
+    afs_uint32 *ame;           /* one of my interface addr in net byte order */
 {
-    afs_uint32 myAddr[UBIK_MAX_INTERFACE_ADDR], *servList;
+    afs_uint32 myAddr[UBIK_MAX_INTERFACE_ADDR], *servList, tmpAddr;
     int        count, index, found, i, j, totalServers, start, end;
 
-    /* count the number of servers */
-    for ( totalServers=0, servList = aservers; *servList; servList++)
-       totalServers++;
+    if (info)
+        totalServers = info->numServers;
+    else {                             /* count the number of servers */
+        for ( totalServers=0, servList = aservers; *servList; servList++)
+           totalServers++;
+    }
 
 #ifdef AFS_NT40_ENV 
     /* for now use getaddr(). use getAllAddr when implemented */
@@ -407,34 +504,41 @@ afs_uint32 aservers[];    /* list of all possible server addresses */
     */
     for ( j=0, found = 0; j < count; j++)
     {
-       for ( i=0; i < totalServers; i++)
-           if ( myAddr[j] == aservers[i] )     
-           {
-               *ame = aservers[i];
-               aservers[i]  = 0 ; 
+       for ( i=0; i < totalServers; i++) {
+            if (info)
+               tmpAddr = ntohl((afs_uint32) info->hostAddr[i].sin_addr.s_addr);
+           else 
+               tmpAddr = aservers[i];
+            if ( myAddr[j] == tmpAddr) {
+                *ame = tmpAddr;
+               if (!info)
+                   aservers[i]  = 0 ; 
                found = 1;
            }
+       }
     }
     if ( found )
        ubik_print("Using %s as my primary address\n", afs_inet_ntoa(*ame) );
 
-    /* get rid of servers which were purged because all 
-    ** those interface addresses are myself 
-    */
-    for ( start=0, end=totalServers-1; (start<end) ; start++, end--)
-    {
-       /* find the first zero entry from the beginning */
-       for ( ; (start < end) && ( aservers[start] ); start++);
-
-       /* find the last non-zero entry from the end */
-       for ( ; (end >= 0) && ( !aservers[end] ); end-- );
-
-       /* if there is nothing more to purge, exit from loop */
-       if ( start >= end ) break;
+    if (!info) {
+        /* get rid of servers which were purged because all 
+        ** those interface addresses are myself 
+        */
+        for ( start=0, end=totalServers-1; (start<end) ; start++, end--)
+        {
+           /* find the first zero entry from the beginning */
+           for ( ; (start < end) && ( aservers[start] ); start++);
+    
+           /* find the last non-zero entry from the end */
+           for ( ; (end >= 0) && ( !aservers[end] ); end-- );
+    
+           /* if there is nothing more to purge, exit from loop */
+           if ( start >= end ) break;
 
-       /* move the entry */
-       aservers[start] = aservers[end];
-       aservers[end]   = 0;            /* this entry was moved */
+           /* move the entry */
+           aservers[start] = aservers[end];
+           aservers[end]   = 0;                /* this entry was moved */
+        }
     }
        
     /* update all my addresses in ubik_host in such a way 
index c3aa09cf61ef9a9564d5f3aed85e586bd1237d16..6de9dccecb19037bb90c53f389e6a0d047965d23 100644 (file)
@@ -425,6 +425,7 @@ urecovery_Interact() {
            bestDBVersion.counter = 0;
            for(ts=ubik_servers; ts; ts=ts->next) {
                if (!ts->up) continue;  /* don't bother with these guys */
+                if (ts->isClone) continue;
                code = DISK_GetVersion(ts->disk_rxcid, &ts->version);
                if (code == 0) {
                    /* perhaps this is the best version */
index 4b6618dadfe418dea7b74cf3cacb24a84be935b9..79116338213e0a446779b0e6af1d166ae2fcafc3 100644 (file)
@@ -20,6 +20,7 @@
 #include <lock.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
+#include <afs/cellconfig.h>
 
 #define UBIK_INTERNALS
 #include "ubik.h"
@@ -145,7 +146,8 @@ afs_int32 ContactQuorum(aproc, atrans, aflags, aparm0, aparm1, aparm2, aparm3, a
            ts->beaconSinceDown = 0;
            urecovery_LostServer(); /* tell recovery to try to resend dbase later */
        } else {            /* success */
-           okcalls++;      /* count up how many worked */
+            if (!ts->isClone)
+               okcalls++;          /* count up how many worked */
            if (aflags & CStampVersion) {
                ts->version = atrans->dbase->version;
            }
@@ -161,12 +163,43 @@ afs_int32 ContactQuorum(aproc, atrans, aflags, aparm0, aparm1, aparm2, aparm3, a
     Note that the host named by myHost should not also be listed in serverList.
 */
 
+int ubik_ServerInitByInfo(myHost, myPort, info, clones, pathName, dbase)
+    struct afsconf_cell *info;  /* in */
+    char clones[];
+    afs_int32 myHost;
+    short myPort;
+    char *pathName;    /* in */
+    struct ubik_dbase **dbase; /* out */ 
+{
+     afs_int32 code;
+    
+     code = ubik_ServerInitCommon(myHost, myPort, info, clones, 0, pathName, dbase);
+     return code;
+}
+
 int ubik_ServerInit(myHost, myPort, serverList, pathName, dbase)
+    afs_int32 serverList[];    /* in */
     afs_int32 myHost;
     short myPort;
+    char *pathName;    /* in */
+    struct ubik_dbase **dbase; /* out */ 
+{
+     afs_int32 code;
+    
+     code = ubik_ServerInitCommon(myHost, myPort, (struct afsconf_cell *)0, 0,
+                       serverList, pathName, dbase);
+     return code;
+}
+
+int ubik_ServerInitCommon(myHost, myPort, info, clones, serverList, pathName, dbase)
+    afs_int32 myHost;
+    short myPort;
+    struct afsconf_cell *info;  /* in */
+    char clones[];
     afs_int32 serverList[];    /* in */
     char *pathName;    /* in */
-    struct ubik_dbase **dbase; /* out */ {
+    struct ubik_dbase **dbase; /* out */ 
+{
     register struct ubik_dbase *tdb;
     register afs_int32 code;
     PROCESS junk;
@@ -245,7 +278,10 @@ int ubik_ServerInit(myHost, myPort, serverList, pathName, dbase)
     if (code) return code;
     code = urecovery_Initialize(tdb);
     if (code) return code;
-    code = ubeacon_InitServerList(myHost, serverList);
+    if (info)
+        code = ubeacon_InitServerListByInfo(myHost, info, clones);
+    else 
+        code = ubeacon_InitServerList(myHost, serverList);
     if (code) return code;
 
     /* now start up async processes */
index e0c681ab48e171f27ce46dab2cbbaba634e6b13b..bf75fbc8d3aba4536eba1df58dac43ed82d84417 100644 (file)
@@ -248,6 +248,7 @@ struct ubik_server {
     char beaconSinceDown;              /* did beacon get through since last crash? */
     char currentDB;                    /* is dbase up-to-date */
     char magic;                                /* the one whose vote counts twice */
+    char isClone;                       /* is only a clone, doesn't vote */
 };
 
 /* hold and release functions on a database */
@@ -258,6 +259,7 @@ struct ubik_server {
 
 /* list of all servers in the system */
 extern struct ubik_server *ubik_servers;
+extern char amIClone;
 
 /* network port info */
 extern short ubik_callPortal;
index 36bde6999bb6922d67351498681b7c17f77fa52a..df8e7f731d3106a41d67a0581d5bf2471fa22df0 100644 (file)
@@ -167,6 +167,8 @@ statindex 11
 #define        VOTE_GETSYNCSITE        10003
 #define VOTE_DEBUG             10004
 #define VOTE_SDEBUG            10005
+#define VOTE_XDEBUG             10006
+#define VOTE_XSDEBUG            10007
 
 /* Vote package interface calls */
 Beacon         (IN afs_int32 state,
@@ -186,6 +188,13 @@ Debug              (OUT ubik_debug *db) = VOTE_DEBUG;
 SDebug         (IN afs_int32 which, 
                OUT ubik_sdebug *db) = VOTE_SDEBUG;
 
+XDebug          (OUT ubik_debug *db,
+                 OUT afs_int32 *isClone) = VOTE_XDEBUG;
+
+XSDebug         (IN afs_int32 which,
+                 OUT ubik_sdebug *db,
+                 OUT afs_int32 *isClone) = VOTE_XSDEBUG;
+
 /* This package handles calls used to pass writes, begins and ends to other servers */
 package DISK_
 statindex 12
index 71602b12dcf21ea4ac46320707dbffdd1aa88db8..25862484596b68ea18bb94f3ed233dc4299c104d 100644 (file)
@@ -86,6 +86,7 @@ struct cmd_syndesc *as; {
     struct ubik_debug udebug;
     struct ubik_sdebug usdebug;
     int                oldServer =0;   /* are we talking to a pre 3.5 server? */
+    afs_int32 isClone = 0;
 
     int32p = (as->parms[2].items ? 1 : 0);
 
@@ -128,7 +129,8 @@ struct cmd_syndesc *as; {
     tconn = rx_NewConnection(hostAddr, port, VOTE_SERVICE_ID, sc, 0);
     
     /* now do the main call */
-    code = VOTE_Debug(tconn, &udebug);
+    code = VOTE_XDebug(tconn, &udebug, &isClone);
+    if (code) code = VOTE_Debug(tconn, &udebug);
     if ( code == RXGEN_OPCODE )        
     {
        oldServer = 1;                  /* talking to a pre 3.5 server */
@@ -205,7 +207,10 @@ struct cmd_syndesc *as; {
                   udebug.epochTime, udebug.tidCounter);
        }
     } else {
-       printf("I am not sync site\n");
+        if (isClone) 
+           printf("I am a clone and never can become sync site\n");
+        else
+           printf("I am not sync site\n");
        inhostAddr.s_addr = htonl(udebug.lowestHost);
        diff = udebug.now - udebug.lowestTime;
        printf("Lowest host %s was set %d secs ago\n", inet_ntoa(inhostAddr), diff);
@@ -239,13 +244,16 @@ struct cmd_syndesc *as; {
     if (int32p || udebug.amSyncSite) {
        /* now do the subcalls */
        for(i=0;;i++) {
-           if ( oldServer )
-           {                           /* pre 3.5 server */
-               memset(&usdebug, 0, sizeof(usdebug)); 
-               code = VOTE_SDebugOld(tconn, i, &usdebug);
+            isClone = 0;
+            code = VOTE_XSDebug(tconn, i, &usdebug, &isClone);
+            if (code < 0) {
+               if ( oldServer ) {                      /* pre 3.5 server */
+                   memset(&usdebug, 0, sizeof(usdebug)); 
+                   code = VOTE_SDebugOld(tconn, i, &usdebug);
+               }
+               else
+                   code = VOTE_SDebug(tconn, i, &usdebug);
            }
-           else
-               code = VOTE_SDebug(tconn, i, &usdebug);
            if (code > 0) break;        /* done */
            if (code < 0) {
                printf("error code %d from VOTE_SDebug\n", code);
@@ -253,12 +261,15 @@ struct cmd_syndesc *as; {
            }
            inhostAddr.s_addr = htonl(usdebug.addr);
            /* otherwise print the structure */
-           printf("\nServer%s", afs_inet_ntoa(htonl(usdebug.addr))); 
+           printf("\nServer (%s", afs_inet_ntoa(htonl(usdebug.addr))); 
            for ( j=0;((usdebug.altAddr[j]) && 
                                (j<UBIK_MAX_INTERFACE_ADDR-1)); j++)
                printf(" %s", afs_inet_ntoa(htonl(usdebug.altAddr[j])));
-           printf(" ): (db %d.%d)\n",
+           printf("): (db %d.%d)",
                   usdebug.remoteVersion.epoch, usdebug.remoteVersion.counter);
+            if (isClone)
+                printf("    is only a clone!");
+           printf("\n");
 
            if (usdebug.lastVoteTime == 0) {
               printf("    last vote never rcvd \n");
index 1739fe51cf00abc0a10bd22f3add89e8efa6967e..3d9eb891eb5e61e351847c3c26068fe29e46b675 100644 (file)
@@ -172,6 +172,8 @@ SVOTE_Beacon(rxcall, astate, astart, avers, atid)
     afs_int32 vote;
     struct rx_connection *aconn;
     struct rx_peer *rxp;
+    struct ubik_server *ts;
+    int isClone = 0;
 
     now = FT_ApproxTime();                     /* close to current time */
     if (rxcall)        {                               /* caller's host */
@@ -188,8 +190,15 @@ SVOTE_Beacon(rxcall, astate, astart, avers, atid)
                                        afs_inet_ntoa(rx_HostOf(rxp)));
                 return 0; /* I don't know about you: vote no */
         }
-    } else
+        for (ts = ubik_servers; ts; ts = ts->next) {
+            if (ts->addr[0] == otherHost) break;
+        }
+        if (!ts) ubik_dprint("Unknown host %x has sent a beacon\n", otherHost);
+        if (ts && ts->isClone) isClone = 1;
+    } else {
        otherHost = ubik_host[0];                       /* this host */
+        isClone = amIClone;
+    }
 
     ubik_dprint("Received beacon type %d from host %s\n", astate, 
                                afs_inet_ntoa(otherHost));
@@ -211,8 +220,11 @@ SVOTE_Beacon(rxcall, astate, astart, avers, atid)
        seconds, we ignore its presence in lowestHost: it may have crashed.
        Note that we don't ever let anyone appear in our lowestHost if we're
        lower than them, 'cause we know we're up. */
-    if (ntohl((afs_uint32) otherHost) <= ntohl((afs_uint32) lowestHost)
-       || lowestTime + BIGTIME < now) {
+    /* But do not consider clones for lowesHost since they never may become
+       sync site */
+    if (!isClone &&
+        (ntohl((afs_uint32) otherHost) <= ntohl((afs_uint32) lowestHost)
+        || lowestTime + BIGTIME < now)) {
        lowestTime = now;
        lowestHost = otherHost;
     }
@@ -223,8 +235,9 @@ SVOTE_Beacon(rxcall, astate, astart, avers, atid)
        lowest.  Need to prove: if one guy in the system is lowest and knows
        he's lowest, these loops don't occur.  because if someone knows he's
        lowest, he will send out beacons telling others to vote for him. */
-    if (ntohl((afs_uint32) ubik_host[0]) <= ntohl((afs_uint32) lowestHost)
-       || lowestTime + BIGTIME < now) {
+    if (!amIClone &&
+        (ntohl((afs_uint32) ubik_host) <= ntohl((afs_uint32) lowestHost)
+        || lowestTime + BIGTIME < now)) {
        lowestTime = now;
        lowestHost = ubik_host[0];
     }
@@ -261,7 +274,18 @@ SVOTE_Beacon(rxcall, astate, astart, avers, atid)
        /* someone else *is* a sync site, just say no */
        if (syncHost && syncHost != otherHost)
            return 0;
+    } else  /* fast startup if this is the only non-clone */
+    if (lastYesHost == 0xffffffff && otherHost == ubik_host[0]) {
+       int i = 0;
+        for (ts = ubik_servers; ts; ts = ts->next) {
+            if (ts->addr[0] == otherHost) continue;
+           if (!ts->isClone) i++;
+       }
+       if (!i) lastYesHost = otherHost;
     }
+       
+
+    if (isClone) return 0; /* clone never can become sync site */
 
     /* Don't promise sync site support to more than one host every BIGTIME
        seconds.  This is the heart of our invariants in this system. */
@@ -293,7 +317,19 @@ SVOTE_Beacon(rxcall, astate, astart, avers, atid)
 SVOTE_SDebug(rxcall, awhich, aparm)
     struct rx_call *rxcall;
     afs_int32 awhich;
-    register struct ubik_sdebug *aparm; {
+    register struct ubik_sdebug *aparm;
+{
+    afs_int32 code, isClone;
+    code = SVOTE_XSDebug(rxcall, awhich, aparm, &isClone);
+    return code;
+}
+
+SVOTE_XSDebug(rxcall, awhich, aparm, isclone)
+    afs_int32 *isclone;
+    struct rx_call *rxcall;
+    afs_int32 awhich;
+    register struct ubik_sdebug *aparm; 
+{
     register struct ubik_server *ts;
     register int i;
     for(ts=ubik_servers; ts; ts=ts->next) {
@@ -309,12 +345,24 @@ SVOTE_SDebug(rxcall, awhich, aparm)
            aparm->up = ts->up;
            aparm->beaconSinceDown = ts->beaconSinceDown;
            aparm->currentDB = ts->currentDB;
+            *isclone = ts->isClone;
            return 0;
        }
     }
     return 2;
 }
 
+SVOTE_XDebug(rxcall, aparm, isclone)
+    struct rx_call *rxcall;
+    register struct ubik_debug *aparm;
+    afs_int32 *isclone;
+{
+    afs_int32 code;
+
+    code = SVOTE_Debug(rxcall, aparm);
+    *isclone = amIClone;
+    return code;
+}
 
 /* handle basic network debug command.  This is the global state dumper */
 SVOTE_Debug(rxcall, aparm)
index e57e41081a8c68b606a1271e9d733f0029dd9eaa..6f17df50d02b2be5e23ddb1a5bc5ac2bce7ac458 100644 (file)
@@ -106,7 +106,6 @@ int argc;
 char   **argv;
 {
     register afs_int32   code;
-    afs_int32      serverList[MAXSERVERS];
     afs_int32              myHost;
     struct rx_service      *tservice;
     struct rx_securityClass *sc[3];
@@ -121,7 +120,8 @@ char        **argv;
     int noAuth = 0, index, i;
     extern int rx_extraPackets;
     char commandLine[150];
-
+    char clones[MAXHOSTSPERCELL];
 #ifdef AFS_AIX32_ENV
     /*
      * The following signal action for AIX is necessary so that in case of a 
@@ -214,15 +214,12 @@ char      **argv;
     signal(SIGXCPU, CheckSignal_Signal);
 #endif
     /* get list of servers */
-    code = afsconf_GetCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE,&info);
+    code = afsconf_GetExtendedCellInfo(tdir,(char *)0, AFSCONF_VLDBSERVICE,
+                                       &info, &clones);
     if (code) {
        printf("vlserver: Couldn't get cell server list for 'afsvldb'.\n");
        exit(2);
     }
-    for (index=0,i = 0;index<info.numServers;index++)
-       if (info.hostAddr[index].sin_addr.s_addr != myHost) /* ubik already tacks myHost onto list */
-           serverList[i++] = info.hostAddr[index].sin_addr.s_addr;
-     serverList[i] = 0;
 
     vldb_confdir = tdir;               /* Preserve our configuration dir */
     /* rxvab no longer supported */
@@ -237,7 +234,8 @@ char        **argv;
     ubik_SRXSecurityRock = (char *) tdir;
     ubik_CheckRXSecurityProc = afsconf_CheckAuth;
     ubik_CheckRXSecurityRock = (char *) tdir;
-    code = ubik_ServerInit(myHost, htons(AFSCONF_VLDBPORT), serverList, vl_dbaseName, &VL_dbase);
+    code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_VLDBPORT), &info,
+                                &clones, vl_dbaseName, &VL_dbase);
     if (code) {
        printf("vlserver: Ubik init failed with code %d\n",code);
        exit(2);