windows-afsd-server-uuid-20090301
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 2 Mar 2009 04:44:43 +0000 (04:44 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 2 Mar 2009 04:44:43 +0000 (04:44 +0000)
LICENSE MIT

Unlike the unix cache manager, on Windows the server uuid was not
recorded as part of the cm_server object.  This commit adds the uuid
and a flag to indicate if it is set or not.

A check is made in cm_UpdateVolumeLocation it confirm that the uuid
known to the CM is the same as the one being reported by the vl server.
If they differ, this is logged but no action is taken.

The contents of the cm_allServers list is now dumped in response to
"fs memdump" or a crash.  This includes the uuid, addr, type, flags,
downtime, caps, etc.

The server uuid is not useful at the moment because there is nothing
that the CM can use it for.  However, it might be useful for debugging
and it will be needed for extended callback support.

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/afsd_service.c
src/WINNT/afsd/cm_cell.c
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_server.h
src/WINNT/afsd/cm_volume.c

index 5c65257..d31233f 100644 (file)
@@ -464,7 +464,7 @@ static void afsd_InitServerPreferences(void)
             }
             else       /* add a new server without a cell */
             {
-                tsp = cm_NewServer(&saddr, CM_SERVER_VLDB, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
+                tsp = cm_NewServer(&saddr, CM_SERVER_VLDB, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
                 tsp->ipRank = (USHORT)dwRank;
             }
         }
@@ -534,7 +534,7 @@ static void afsd_InitServerPreferences(void)
             }
             else       /* add a new server without a cell */
             {
-                tsp = cm_NewServer(&saddr, CM_SERVER_FILE, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
+                tsp = cm_NewServer(&saddr, CM_SERVER_FILE, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
                 tsp->ipRank = (USHORT)dwRank;
             }
         }
index dc49549..a1a8034 100644 (file)
@@ -90,6 +90,7 @@ static void afsd_notifier(char *msgp, char *filep, long line)
     cm_DumpVolumes(afsi_file, "a", 0);
     cm_DumpSCache(afsi_file, "a", 0);
     cm_DumpBufHashTable(afsi_file, "a", 0);
+    cm_DumpServers(afsi_file, "a", 0);
     smb_DumpVCP(afsi_file, "a", 0);                    
     rx_DumpPackets(afsi_file, "a");
     rx_DumpCalls(afsi_file, "a");
index 7bf3055..a2a012a 100644 (file)
@@ -52,7 +52,7 @@ long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *hostnamep)
         }
     }       
     else
-        tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp, probe ? 0 : CM_FLAG_NOPROBE);
+        tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp, NULL, probe ? 0 : CM_FLAG_NOPROBE);
 
     /* Insert the vlserver into a sorted list, sorted by server rank */
     tsrp = cm_NewServerRef(tsp, 0);
index d3ecaf0..c4abe3b 100644 (file)
@@ -1687,7 +1687,7 @@ cm_IoctlSetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
         }
         else   /* add a new server without a cell */
         {
-            tsp = cm_NewServer(&tmp, type, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
+            tsp = cm_NewServer(&tmp, type, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
             tsp->ipRank = rank;
         }
        lock_ObtainMutex(&tsp->mx);
@@ -3016,6 +3016,7 @@ cm_IoctlMemoryDump(struct cm_ioctl *ioctlp, struct cm_user *userp)
     cm_DumpVolumes(hLogFile, cookie, 1);
     cm_DumpSCache(hLogFile, cookie, 1);
     cm_DumpBufHashTable(hLogFile, cookie, 1);
+    cm_DumpServers(hLogFile, cookie, 1);
     smb_DumpVCP(hLogFile, cookie, 1);
     rx_DumpCalls(hLogFile, cookie);
     rx_DumpPackets(hLogFile, cookie);
index 7567d61..545f686 100644 (file)
@@ -870,13 +870,14 @@ void cm_SetServerPrefs(cm_server_t * serverp)
            else serverp->ipRank = min(serverp->ipRank,CM_IPRANK_MED);
            /* same net */
        }       
-       /* random between 0..15*/
-       serverp->ipRank += min(serverp->ipRank, rand() % 0x000f);
     } /* and of for loop */
+
+    /* random between 0..15*/
+    serverp->ipRank += (rand() % 0x000f);
     lock_ReleaseRead(&cm_syscfgLock);
 }
 
-cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp, afs_uint32 flags) {
+cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp, afsUUID *uuidp, afs_uint32 flags) {
     cm_server_t *tsp;
 
     osi_assertx(socketp->sin_family == AF_INET, "unexpected socket family");
@@ -886,6 +887,10 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell
         memset(tsp, 0, sizeof(*tsp));
         tsp->type = type;
         tsp->cellp = cellp;
+        if (uuidp && !afs_uuid_is_nil(uuidp)) {
+            tsp->uuid = *uuidp;
+            tsp->flags |= CM_SERVERFLAG_UUID;
+        }
         tsp->refCount = 1;
         lock_InitializeMutex(&tsp->mx, "cm_server_t mutex", LOCK_HIERARCHY_SERVER);
         tsp->addr = *socketp;
@@ -908,7 +913,7 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell
         lock_ReleaseWrite(&cm_serverLock);     /* release server lock */
 
         if ( !(flags & CM_FLAG_NOPROBE) ) {
-            tsp->flags = CM_SERVERFLAG_DOWN;   /* assume down; ping will mark up if available */
+            tsp->flags |= CM_SERVERFLAG_DOWN;  /* assume down; ping will mark up if available */
             cm_PingServer(tsp);                        /* Obtain Capabilities and check up/down state */
         }
     }
@@ -1294,3 +1299,62 @@ void cm_FreeServerList(cm_serverRef_t** list, afs_uint32 flags)
   
     lock_ReleaseWrite(&cm_serverLock);
 }
+
+/* dump all servers to a file. 
+ * cookie is used to identify this batch for easy parsing, 
+ * and it a string provided by a caller 
+ */
+int cm_DumpServers(FILE *outputFile, char *cookie, int lock)
+{
+    int zilch;
+    cm_server_t *tsp;
+    char output[1024];
+    char uuidstr[128];
+    char hoststr[16];
+
+    if (lock)
+        lock_ObtainRead(&cm_serverLock);
+  
+    sprintf(output, "%s - dumping servers - cm_numFileServers=%d, cm_numVldbServers=%d\r\n", 
+            cookie, cm_numFileServers, cm_numVldbServers);
+    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+  
+    for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp)
+    {
+        char * type;
+        char * down;
+
+        switch (tsp->type) {
+        case CM_SERVER_VLDB:
+            type = "vldb";
+            break;
+        case CM_SERVER_FILE:
+            type = "file";
+            break;
+        default:
+            type = "unknown";
+        }
+
+        afsUUID_to_string(&tsp->uuid, uuidstr, sizeof(uuidstr));
+        afs_inet_ntoa_r(tsp->addr.sin_addr.s_addr, hoststr);
+        down = ctime(&tsp->downTime);
+        down[strlen(down)-1] = '\0';
+
+        sprintf(output, "%s - tsp=0x%p cell=%s addr=%-15s uuid=%s type=%s caps=0x%x flags=0x%x waitCount=%u rank=%u downTime=\"%s\" refCount=%u\r\n",
+                 cookie, tsp, tsp->cellp ? tsp->cellp->name : "", hoststr, uuidstr, type, 
+                 tsp->capabilities, tsp->flags, tsp->waitCount, tsp->ipRank, 
+                 (tsp->flags & CM_SERVERFLAG_DOWN) ?  down : "up",
+                 tsp->refCount);
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+    }
+    sprintf(output, "%s - Done dumping servers.\r\n", cookie);
+    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+  
+    if (lock)
+       lock_ReleaseRead(&cm_serverLock);
+
+    return (0);     
+}
+
+
+
index 93001b6..61a7d8a 100644 (file)
@@ -37,6 +37,7 @@ typedef struct cm_server {
     unsigned short ipRank;             /* server priority */
     cm_server_vols_t *  vols;           /* by mx */
     time_t downTime;                    /* by mx */
+    afsUUID uuid;                       /* by mx */
 } cm_server_t;
 
 enum repstate {srv_not_busy, srv_busy, srv_offline, srv_deleted};
@@ -60,6 +61,7 @@ typedef struct cm_serverRef {
 #define CM_SERVERFLAG_NO64BIT   0x8     /* server has no support for
                                            64-bit operations. */
 #define CM_SERVERFLAG_NOINLINEBULK 0x10        /* server has no support for inline bulk */
+#define CM_SERVERFLAG_UUID      0x20    /* server uuid is known */
 
 /* flags for procedures */
 #define CM_FLAG_CHECKUPSERVERS         1       /* check working servers */
@@ -78,7 +80,7 @@ typedef struct cm_serverRef {
 #define CM_MAXINTERFACE_ADDR          16
 
 extern cm_server_t *cm_NewServer(struct sockaddr_in *addrp, int type,
-       struct cm_cell *cellp, afs_uint32 flags);
+       struct cm_cell *cellp, afsUUID *uuidp, afs_uint32 flags);
 
 extern cm_serverRef_t *cm_NewServerRef(struct cm_server *serverp, afs_uint32 volID);
 
@@ -130,6 +132,8 @@ extern void cm_SetLanAdapterChangeDetected(void);
 
 extern void cm_RemoveVolumeFromServer(cm_server_t * serverp, afs_uint32 volID);
 
+extern int cm_DumpServers(FILE *outputFile, char *cookie, int lock);
+
 /* Protected by cm_syscfgLock (rw) */
 extern int cm_noIPAddr;         /* number of client network interfaces */
 extern int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */
index e107e16..03862b8 100644 (file)
@@ -321,6 +321,7 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
         afs_int32 bkID;
         afs_int32 serverNumber[NMAXNSERVERS];
         afs_int32 serverFlags[NMAXNSERVERS];
+        afsUUID   serverUUID[NMAXNSERVERS];
         afs_int32 rwServers_alldown = 1;
         afs_int32 roServers_alldown = 1;
         afs_int32 bkServers_alldown = 1;
@@ -331,6 +332,8 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
            rwServers_alldown = 0;
 #endif
 
+        memset(serverUUID, 0, sizeof(serverUUID));
+
         switch ( method ) {
         case 0:
             flags = vldbEntry.flags;
@@ -406,6 +409,7 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
                     for (k = 0; k < nentries && j < NMAXNSERVERS; j++, k++) {
                         serverFlags[j] = uvldbEntry.serverFlags[i];
                         serverNumber[j] = addrp[k];
+                        serverUUID[j] = uuid;
                     }
 
                     free(addrs.bulkaddrs_val);  /* This is wrong */
@@ -491,19 +495,48 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
             tempAddr = htonl(serverNumber[i]);
             tsockAddr.sin_addr.s_addr = tempAddr;
             tsp = cm_FindServer(&tsockAddr, CM_SERVER_FILE);
+            if (tsp && (method == 2) && (tsp->flags & CM_SERVERFLAG_UUID)) {
+                /* 
+                 * Check to see if the uuid of the server we know at this address
+                 * matches the uuid of the server we are being told about by the
+                 * vlserver.  If not, ...?
+                 */
+                if (!afs_uuid_equal(&serverUUID[i], &tsp->uuid)) {
+                    char uuid1[128], uuid2[128];
+                    char hoststr[16];
+
+                    afsUUID_to_string(&serverUUID[i], uuid1, sizeof(uuid1));
+                    afsUUID_to_string(&tsp->uuid, uuid2, sizeof(uuid2));
+                    afs_inet_ntoa_r(serverNumber[i], hoststr);
+
+                    osi_Log3(afsd_logp, "cm_UpdateVolumeLocation UUIDs do not match! %s != %s (%s)",
+                              osi_LogSaveString(afsd_logp, uuid1),
+                              osi_LogSaveString(afsd_logp, uuid2),
+                              osi_LogSaveString(afsd_logp, hoststr));
+                }
+            }
             if (!tsp) {
                 /* cm_NewServer will probe the server which in turn will
                  * update the state on the volume group object */
                 lock_ReleaseWrite(&volp->rw);
-                tsp = cm_NewServer(&tsockAddr, CM_SERVER_FILE, cellp, 0);
+                tsp = cm_NewServer(&tsockAddr, CM_SERVER_FILE, cellp, &serverUUID[i], 0);
                 lock_ObtainWrite(&volp->rw);
             }
-            /* if this server was created by fs setserverprefs */
+            osi_assertx(tsp != NULL, "null cm_server_t");
+                        
+            /*
+             * if this server was created by fs setserverprefs
+             * then it won't have either a cell assignment or 
+             * a server uuid.
+             */
             if ( !tsp->cellp ) 
                 tsp->cellp = cellp;
+            if ( (method == 2) && !(tsp->flags & CM_SERVERFLAG_UUID) && 
+                 !afs_uuid_is_nil(&serverUUID[i])) {
+                tsp->uuid = serverUUID[i];
+                tsp->flags |= CM_SERVERFLAG_UUID;
+            }
 
-            osi_assertx(tsp != NULL, "null cm_server_t");
-                        
             /* and add it to the list(s). */
             /*
              * Each call to cm_NewServerRef() increments the