From 19ffc146fac828cd32b90c4d43d617de6c574556 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 2 Mar 2009 04:44:43 +0000 Subject: [PATCH] windows-afsd-server-uuid-20090301 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 | 4 +- src/WINNT/afsd/afsd_service.c | 1 + src/WINNT/afsd/cm_cell.c | 2 +- src/WINNT/afsd/cm_ioctl.c | 3 +- src/WINNT/afsd/cm_server.c | 72 +++++++++++++++++++++++++++++++++-- src/WINNT/afsd/cm_server.h | 6 ++- src/WINNT/afsd/cm_volume.c | 41 ++++++++++++++++++-- 7 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 5c6525795..d31233fed 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -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; } } diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index dc495491a..a1a8034b4 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -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"); diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index 7bf3055e0..a2a012af3 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -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); diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index d3ecaf0f2..c4abe3b06 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -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); diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index 7567d61cc..545f686e7 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -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); +} + + + diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index 93001b668..61a7d8a0e 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -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 */ diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index e107e1664..03862b84f 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -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 -- 2.39.5