4ca736a6e7b2cb37dab66d050ed3f84c79e3a2ad galt Sun Aug 11 02:11:32 2019 -0700 Adding new utility blatServersCheck to make it easy for people to check the consistency of the blatServer tables against the actual gfServers running on blat machines. diff --git src/hg/utils/blatServersCheck/blatServersCheck.c src/hg/utils/blatServersCheck/blatServersCheck.c new file mode 100644 index 0000000..d1d5e84 --- /dev/null +++ src/hg/utils/blatServersCheck/blatServersCheck.c @@ -0,0 +1,305 @@ +/* Copyright (C) 2013 The Regents of the University of California + * See README in this or parent directory for licensing information. */ + + +/* blatServersCheck - Check that the blatServers table value match the + * actual running gfServers. + */ + +#include "common.h" +#include "options.h" +#include "jksql.h" +#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"; + +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" + " -verbose=2 can show details for each server.\n" + "\n" +// TODO copied from another progrma, not sure it still works here. +// "Use the HGDB_CONF environment variable to specify which configuration to use, for example\n" +// "HGDB_CONF=/usr/local/apache/cgi-bin/hg.conf\n" + ); +} + + +static struct optionSpec options[] = { +/* + {"chunkSize", OPTION_INT}, + {"chunkWait", OPTION_INT}, + {"squealSize", OPTION_INT}, + {"purgeStart", OPTION_INT}, + {"purgeEnd", OPTION_INT}, + {"purgeTable", OPTION_STRING}, + {"dryRun", OPTION_STRING}, +*/ + {"showVersion", OPTION_BOOLEAN}, + {"-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; +} + +int statusServer(char *hostName, char *portName, boolean isTrans, struct hash *versionHash) +/* Send status message to server arnd report result. + * Returns -1 for error reading string. + * Returns -2 for type mismatch. + * Returns -3 for host mismatch. + * Returns -4 for port mismatch. + */ +{ +char buf[256]; +int sd = 0; +int ret = 0; + +/* Put together command. */ +sd = netMustConnectTo(hostName, portName); +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 = -1; + break; + } + if (sameString(buf, "end")) + { + break; + } + else + { + verbose(2, "%s\n", buf); + if (startsWith("version ", buf)) + { + char *hashKey = buf+strlen("version "); + hashIncInt(versionHash, hashKey); // count how many with this version + } + if (startsWith("type ", buf)) + { + if (sameString(buf, "type translated") && !isTrans) + { + warn("type mismatch: gfServer says type translated but db says isTrans==0"); + ret = -2; // type mismatch + break; + } + if (sameString(buf, "type nucleotide") && isTrans) + { + warn("type mismatch: gfServer says type nucleotide but db says isTrans==1"); + ret = -2; // type mismatch + break; + } + } + if (startsWith("host ", buf)) + { + if (!sameString(buf+strlen("host "), hostName)) + { + warn("host mismatch: gfServer says %s but db says db=%s", buf, hostName); + ret = -3; // host mismatch + break; + } + } + if (startsWith("port ", buf)) + { + if (!sameString(buf+strlen("port "), portName)) + { + warn("port mismatch: gfServer says %s but db says port=%s", buf, portName); + ret = -4; // port mismatch // probably never happens. + break; + } + } + } + } +close(sd); +return(ret); +} + + +int getFileList(char *hostName, char *portName, char *db) +/* Get and display input file list. */ +{ +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); +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 (!endsWith(fileName,".nib")) + { + if (!sameString(fileName, twoBitName)) + { + warn("2bit name mismatch fileName=%s twoBitName=%s", fileName, twoBitName); + ret = -1; // 2bit name mismatch + break; + } + } + } + } +close(sd); +return ret; +} + + +void blatServersCheck(char *config) +/* Check blatServers table against running gfServers */ +{ + +struct hash *hash = hashNew(12); +struct hash *versionHash = hashNew(6); + +char hashKey[256]; + +/* get connection info */ +database = getCfgOption(config, "db" ); +host = getCfgOption(config, "host" ); +user = getCfgOption(config, "user" ); +password = getCfgOption(config, "password"); + +conn = sqlConnectRemote(host, user, password, database); + +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); + +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); + + int res = statusServer(host, portStr, isTrans, versionHash); + int res2 = getFileList(host, portStr, db); + 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); + } + + if ((res != 0) || (res2 != 0) || (hel != NULL)) + { + ++errCount; + verbose(1, "db=%s host=%s port=%d isTrans=%d res=%d res2=%d\n\n", db, host, port, trans, res, res2); + } + else + { + verbose(2, "db=%s host=%s port=%d isTrans=%d res=%d res2=%d\n\n", db, host, port, trans, res, res2); + } + } + + +sqlFreeResult(&sr); +sqlDisconnect(&conn); + +// Show a count of how many servers were of each gfServer version +struct hashEl *el, *list = hashElListHash(versionHash); +slSort(&list, hashElCmp); +verbose(1, "version count\n"); +verbose(1, "-------------\n"); +for (el = list; el != NULL; el = el->next) + { + verbose(1, "%s %d\n", el->name, ptToInt(el->val)); + } +hashElFreeList(&list); + +for (el = list; el != NULL; el = el->next) + { + verbose(1, "%s %d\n", el->name, ptToInt(el->val)); + } +hashElFreeList(&list); +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(); + +//char *hgdbConf = getenv("HGDB_CONF"); +//if (hgdbConf) +// printf("\nHGDB_CONF = %s\n\n", hgdbConf); + +blatServersCheck(argv[1]); + +printf("No errors found!\n"); + +return 0; +}