51d1bcdbeac4b2ee7ce4d749c2a975e8bd8a72b1 galt Wed May 27 18:34:11 2020 -0700 added -timeout=1 and -host=blat1a options diff --git src/hg/utils/blatServersCheck/blatServersCheck.c src/hg/utils/blatServersCheck/blatServersCheck.c index f5617a3..6c2dc69 100644 --- src/hg/utils/blatServersCheck/blatServersCheck.c +++ src/hg/utils/blatServersCheck/blatServersCheck.c @@ -12,82 +12,102 @@ #include "hgConfig.h" #include "genoFind.h" #include "net.h" #include "hash.h" #include "obscure.h" char *database = NULL; char *host = NULL; char *user = NULL; char *password = NULL; struct sqlConnection *conn = NULL; char *blatServersTableName = "blatServers"; +int timeout = 10; // default timeout in seconds + +char *hostFilter = NULL; // default to searching all hosts + void usage() /* Explain usage and exit. */ { errAbort( "blatServersCheck - Check the blatServers table matches running gfServers\n" "usage:\n" " blatServersCheck profile\n" "profile should be from hg.conf like central or rrcentral\n" "options:\n" + " -timeout=10 timeout in seconds.\n" + " -host=blatx only check records with matching host.\n" " -verbose=2 can show details for each server.\n" "\n" ); } static struct optionSpec options[] = { + {"timeout", OPTION_INT}, + {"host", OPTION_STRING}, {"-help", OPTION_BOOLEAN}, {NULL, 0}, }; char *getCfgOption(char *config, char *setting) /* get setting for specified config */ { char temp[256]; safef(temp, sizeof(temp), "%s.%s", config, setting); char *value = cfgOption(temp); if (!value) errAbort("setting %s not found!",temp); return value; } +void setSocketTimeout(int sockfd, int delayInSeconds) +// put socket read timeout so it will not take forever to timeout during a read +{ +struct timeval tv; +tv.tv_sec = delayInSeconds; +tv.tv_usec = 0; +setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv); +setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof tv); +} + int statusServer(char *hostName, char *portName, boolean isTrans, struct hash *versionHash) /* Send status message to server arnd report result. * Returns -1 for connection error. * Returns -2 for error reading string. * Returns -3 for type mismatch. * Returns -4 for host mismatch. * Returns -5 for port mismatch. */ { char buf[256]; int sd = 0; int ret = 0; /* Put together command. */ -sd = gfMayConnect(hostName, portName); +sd = netConnectWithTimeout(hostName, atoi(portName), timeout * 1000); // 10 seconds connect timeout if (sd == -1) { warn("Error connecting to %s:%s", hostName, portName); return -1; } +setSocketTimeout(sd, timeout); + sprintf(buf, "%sstatus", gfSignature()); mustWriteFd(sd, buf, strlen(buf)); for (;;) { if (netGetString(sd, buf) == NULL) { warn("Error reading status information from %s:%s", hostName, portName); ret = -2; // error reading response break; } if (sameString(buf, "end")) { break; } @@ -144,31 +164,34 @@ * Returns -1 for 2bit name mismatch * Returns -2 for name mot found in targetDb, probably obsolete * Returns -3 for targetDb.seqFile does not match fileName on gfServer */ { char buf[256]; int sd = 0; int fileCount; int i; int ret = 0; char twoBitName[256]; safef(twoBitName, sizeof twoBitName, "%s.2bit", db); /* Put together command. */ -sd = netMustConnectTo(hostName, portName); +sd = netConnectWithTimeout(hostName, atoi(portName), timeout * 1000); // 10 seconds connect timeout + +setSocketTimeout(sd, timeout); + sprintf(buf, "%sfiles", gfSignature()); mustWriteFd(sd, buf, strlen(buf)); /* Get count of files, and then each file name. */ if (netGetString(sd, buf) != NULL) { fileCount = atoi(buf); for (i=0; i<fileCount; ++i) // could have multiples if .nib used? { char *fileName = netRecieveString(sd, buf); //printf("%s\n", fileName); verbose(2, "%s\n", fileName); // if .nib, cannot confirm the name. if (endsWith(fileName,".nib")) { @@ -256,48 +279,53 @@ getTargetDb(conn, targetDbHash); struct sqlResult *sr; char **row; char query[256]; int totalRows = 0; verbose(1, "-------------------\n"); verbose(1, "Reading table %s\n", blatServersTableName); totalRows = sqlTableSize(conn, blatServersTableName); verbose(1,"totalRows=%d\n", totalRows); +verbose(1,"\n"); + if (totalRows==0) { errAbort("table %s is empty!", blatServersTableName); } int errCount = 0; sqlSafef(query,sizeof(query), "select db, host, port, isTrans from %s", blatServersTableName); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { char *db = row[0]; char *host = row[1]; char *portStr = row[2]; unsigned int port = sqlUnsigned(portStr); unsigned int trans = sqlUnsigned(row[3]); boolean isTrans = (trans == 1); + if (hostFilter && !sameString(hostFilter, host)) + continue; // skip + int res = statusServer(host, portStr, isTrans, versionHash); int res2 = 0; if (res != -1) // if not a connection error, proceed. { res2 = getFileList(host, portStr, db, targetDbHash); } safef(hashKey, sizeof hashKey, "%s:%s", host, portStr); struct hashEl *hel = hashLookup(hash, hashKey); if (hel == NULL) { hashAdd(hash, hashKey, NULL); } else { warn("duplicate host:port %s found", hashKey); @@ -332,21 +360,25 @@ verbose(1, "\n"); if (errCount > 0) errAbort("error count=%d", errCount); } int main(int argc, char *argv[]) /* Process command line. */ { optionInit(&argc, argv, options); if ((argc != 2) || optionExists("-help")) usage(); +timeout = optionInt("timeout", timeout); + +hostFilter = optionVal("host", hostFilter); + blatServersCheck(argv[1]); printf("No errors found!\n"); return 0; }