diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-06-06 21:06:56 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-06-06 21:06:56 +0300 |
commit | 363bfa3d008da517ca284f9e83bfa5183f977e24 (patch) | |
tree | 5705f739a022bcf2633b5c68d3bbdc785facacf7 /src | |
parent | d0c73a249dd7719923612c6b3a23cfeb8c8720d0 (diff) | |
download | mysqlstat-363bfa3d008da517ca284f9e83bfa5183f977e24.tar.gz mysqlstat-363bfa3d008da517ca284f9e83bfa5183f977e24.tar.bz2 |
Reimplement replication OIDs as a table. Implement process list OIDs.
Diffstat (limited to 'src')
-rw-r--r-- | src/MYSQL-STAT-MIB.txt | 352 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/mysqlstat.c | 509 | ||||
-rw-r--r-- | src/mysqlstat_mib.mib2c | 384 |
4 files changed, 884 insertions, 369 deletions
diff --git a/src/MYSQL-STAT-MIB.txt b/src/MYSQL-STAT-MIB.txt index 1580837..8fbc0e6 100644 --- a/src/MYSQL-STAT-MIB.txt +++ b/src/MYSQL-STAT-MIB.txt @@ -18,19 +18,90 @@ IMPORTS FROM INET-ADDRESS-MIB; mysql MODULE-IDENTITY - LAST-UPDATED "201606060944Z" + LAST-UPDATED "201606061638Z" ORGANIZATION "Gray Software" CONTACT-INFO "Sergey Poznyakoff <gray@gnu.org>" DESCRIPTION "This MIB module defines objects for MySQL statistics." - REVISION "201606060944Z" + REVISION "201606061638Z" DESCRIPTION "First revision." ::= { enterprises 9163 101 } replication OBJECT IDENTIFIER ::= { mysql 1 } -replStatus OBJECT IDENTIFIER ::= { replication 1 } -replConfig OBJECT IDENTIFIER ::= { replication 2 } +processList OBJECT IDENTIFIER ::= { mysql 2 } + +-- +-- Replication Slave Status +-- + +replSlaveStatusTable OBJECT-TYPE + SYNTAX SEQUENCE OF ReplSlaveStatusEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table of replication status. On replication slave, + it contains a single row, describing the current + status." + ::= { replication 1 } + +replSlaveStatusEntry OBJECT-TYPE + SYNTAX ReplSlaveStatusEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry describing slave status." + INDEX { replSlaveIndex } + ::= { replSlaveStatusTable 1 } + +ReplSlaveStatusEntry ::= SEQUENCE { + replSlaveIndex Integer32, + replSlaveIOState ThreadStatusString, + replMasterLogFile DisplayString, + replReadMasterLogPos Counter32, + replRelayLogFile DisplayString, + replRelayLogPos Counter32, + replRelayMasterLogFile DisplayString, + replSlaveIORunning SlaveRunningState, + replSlaveSQLRunning TruthValue, + replLastSQLErrno Integer32, + replLastSQLError SQLErrorString, + replLastIOErrno Integer32, + replLastIOError SQLErrorString, + replExecMasterLogPos Counter32, + replRelayLogSpace Counter64, + replSecondsBehindMaster TimeStamp, + replMasterHost DisplayString, + replMasterUser DisplayString, + replMasterPort Integer32, + replConnectRetry TimeStamp, + replReplicateDoDB DisplayString, + replReplicateIgnoreDB DisplayString, + replReplicateDoTable DisplayString, + replReplicateIgnoreTable DisplayString, + replReplicateWildDoTable DisplayString, + replReplicateWildIgnoreTable DisplayString, + replSkipCounter Counter32, + replUntilCondition DisplayString, + replUntilLogFile DisplayString, + replUntilLogPos DisplayString, + replMasterServerId Integer32, + replMasterSSLAllowed DisplayString, + replMasterSSLCAFile DisplayString, + replMasterSSLCAPath DisplayString, + replMasterSSLCert DisplayString, + replMasterSSLCipher DisplayString, + replMasterSSLKey DisplayString, + replMasterSSLVerifyServerCert TruthValue +} + +replSlaveIndex OBJECT-TYPE + SYNTAX Integer32 (0..65535) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A number uniquely identifying slave status row." + ::= { replSlaveStatusEntry 1 } ThreadStatusString ::= TEXTUAL-CONVENTION DISPLAY-HINT "128t" @@ -46,7 +117,7 @@ replSlaveIOState OBJECT-TYPE "Describes what the thread is doing: trying to connect to the master, waiting for events from the master, reconnecting to the master, etc." - ::= { replStatus 1 } + ::= { replSlaveStatusEntry 2 } replMasterLogFile OBJECT-TYPE SYNTAX DisplayString @@ -55,7 +126,7 @@ replMasterLogFile OBJECT-TYPE DESCRIPTION "The name of the master binary log file from which the I/O thread is currently reading." - ::= { replStatus 2 } + ::= { replSlaveStatusEntry 3 } replReadMasterLogPos OBJECT-TYPE SYNTAX Counter32 @@ -64,7 +135,7 @@ replReadMasterLogPos OBJECT-TYPE DESCRIPTION "The position in the current master binary log file up to which the I/O thread has read." - ::= { replStatus 3 } + ::= { replSlaveStatusEntry 4 } replRelayLogFile OBJECT-TYPE SYNTAX DisplayString @@ -73,7 +144,7 @@ replRelayLogFile OBJECT-TYPE DESCRIPTION "The name of the relay log file from which the SQL thread is currently reading and executing." - ::= { replStatus 4 } + ::= { replSlaveStatusEntry 5 } replRelayLogPos OBJECT-TYPE SYNTAX Counter32 @@ -82,7 +153,7 @@ replRelayLogPos OBJECT-TYPE DESCRIPTION "The position in the current relay log file up to which the SQL thread has read and executed." - ::= { replStatus 5 } + ::= { replSlaveStatusEntry 6 } replRelayMasterLogFile OBJECT-TYPE SYNTAX DisplayString @@ -91,7 +162,7 @@ replRelayMasterLogFile OBJECT-TYPE DESCRIPTION "The name of the master binary log file containing the most recent event executed by the SQL thread." - ::= { replStatus 6 } + ::= { replSlaveStatusEntry 7 } SlaveRunningState ::= TEXTUAL-CONVENTION STATUS current @@ -107,7 +178,7 @@ replSlaveIORunning OBJECT-TYPE DESCRIPTION "Whether the I/O thread is started and has connected successfully to the master." - ::= { replStatus 7 } + ::= { replSlaveStatusEntry 8 } replSlaveSQLRunning OBJECT-TYPE SYNTAX TruthValue @@ -115,7 +186,7 @@ replSlaveSQLRunning OBJECT-TYPE STATUS current DESCRIPTION "Whether the SQL thread is started." - ::= { replStatus 8 } + ::= { replSlaveStatusEntry 9 } replLastSQLErrno OBJECT-TYPE SYNTAX Integer32 @@ -124,7 +195,7 @@ replLastSQLErrno OBJECT-TYPE DESCRIPTION "The error code of the last error that caused the SQL thread to stop." - ::= { replStatus 9 } + ::= { replSlaveStatusEntry 10 } SQLErrorString ::= TEXTUAL-CONVENTION DISPLAY-HINT "1024t" @@ -139,7 +210,7 @@ replLastSQLError OBJECT-TYPE DESCRIPTION "The error message describing the last error that caused the SQL thread to stop." - ::= { replStatus 10 } + ::= { replSlaveStatusEntry 11 } replLastIOErrno OBJECT-TYPE SYNTAX Integer32 @@ -148,7 +219,7 @@ replLastIOErrno OBJECT-TYPE DESCRIPTION "The error code of the last error that caused the IO thread to stop." - ::= { replStatus 11 } + ::= { replSlaveStatusEntry 12 } replLastIOError OBJECT-TYPE SYNTAX SQLErrorString @@ -157,7 +228,7 @@ replLastIOError OBJECT-TYPE DESCRIPTION "The error message describing the last error that caused the IO thread to stop." - ::= { replStatus 12 } + ::= { replSlaveStatusEntry 13 } replExecMasterLogPos OBJECT-TYPE SYNTAX Counter32 @@ -168,7 +239,7 @@ replExecMasterLogPos OBJECT-TYPE which the SQL thread has read and executed, marking the start of the next transaction or event to be processed." - ::= { replStatus 13 } + ::= { replSlaveStatusEntry 14 } replRelayLogSpace OBJECT-TYPE SYNTAX Counter64 @@ -177,7 +248,7 @@ replRelayLogSpace OBJECT-TYPE DESCRIPTION "The total combined size of all existing relay log files." - ::= { replStatus 14 } + ::= { replSlaveStatusEntry 15 } replSecondsBehindMaster OBJECT-TYPE SYNTAX TimeStamp @@ -188,7 +259,7 @@ replSecondsBehindMaster OBJECT-TYPE is. Basically, it reflects the time difference in seconds between the slave SQL thread and the slave I/O thread." - ::= { replStatus 15 } + ::= { replSlaveStatusEntry 16 } replMasterHost OBJECT-TYPE SYNTAX DisplayString @@ -196,7 +267,7 @@ replMasterHost OBJECT-TYPE STATUS current DESCRIPTION "The master host that the slave is connected to." - ::= { replConfig 1 } + ::= { replSlaveStatusEntry 17 } replMasterUser OBJECT-TYPE SYNTAX DisplayString @@ -205,7 +276,7 @@ replMasterUser OBJECT-TYPE DESCRIPTION "The user name of the account used to connect to the master." - ::= { replConfig 2 } + ::= { replSlaveStatusEntry 18 } replMasterPort OBJECT-TYPE SYNTAX Integer32 @@ -213,7 +284,7 @@ replMasterPort OBJECT-TYPE STATUS current DESCRIPTION "The port used to connect to the master." - ::= { replConfig 3 } + ::= { replSlaveStatusEntry 19 } replConnectRetry OBJECT-TYPE SYNTAX TimeStamp @@ -221,7 +292,7 @@ replConnectRetry OBJECT-TYPE STATUS current DESCRIPTION "The number of seconds between connect retries." - ::= { replConfig 4 } + ::= { replSlaveStatusEntry 20 } replReplicateDoDB OBJECT-TYPE SYNTAX DisplayString @@ -229,7 +300,7 @@ replReplicateDoDB OBJECT-TYPE STATUS current DESCRIPTION "The list of databases to replicate." - ::= { replConfig 5 } + ::= { replSlaveStatusEntry 21 } replReplicateIgnoreDB OBJECT-TYPE SYNTAX DisplayString @@ -237,7 +308,7 @@ replReplicateIgnoreDB OBJECT-TYPE STATUS current DESCRIPTION "The list of databases to exclude from replication." - ::= { replConfig 6 } + ::= { replSlaveStatusEntry 22 } replReplicateDoTable OBJECT-TYPE SYNTAX DisplayString @@ -245,7 +316,7 @@ replReplicateDoTable OBJECT-TYPE STATUS current DESCRIPTION "The list of tables to replicate." - ::= { replConfig 7 } + ::= { replSlaveStatusEntry 23 } replReplicateIgnoreTable OBJECT-TYPE SYNTAX DisplayString @@ -253,7 +324,7 @@ replReplicateIgnoreTable OBJECT-TYPE STATUS current DESCRIPTION "The list of tables to exclude from replication." - ::= { replConfig 8 } + ::= { replSlaveStatusEntry 24 } replReplicateWildDoTable OBJECT-TYPE SYNTAX DisplayString @@ -261,7 +332,7 @@ replReplicateWildDoTable OBJECT-TYPE STATUS current DESCRIPTION "The lists of table name patterns to replicate." - ::= { replConfig 9 } + ::= { replSlaveStatusEntry 25 } replReplicateWildIgnoreTable OBJECT-TYPE SYNTAX DisplayString @@ -269,7 +340,7 @@ replReplicateWildIgnoreTable OBJECT-TYPE STATUS current DESCRIPTION "The lists of table name patterns to exclude from replication." - ::= { replConfig 10 } + ::= { replSlaveStatusEntry 26 } replSkipCounter OBJECT-TYPE SYNTAX Counter32 @@ -278,7 +349,7 @@ replSkipCounter OBJECT-TYPE DESCRIPTION "The current value of the `sql_slave_skip_counter' system variable." - ::= { replConfig 11 } + ::= { replSlaveStatusEntry 27 } replUntilCondition OBJECT-TYPE SYNTAX DisplayString @@ -297,7 +368,7 @@ replUntilCondition OBJECT-TYPE * `Relay' if the slave is reading until a given position in its relay log." - ::= { replConfig 12 } + ::= { replSlaveStatusEntry 28 } replUntilLogFile OBJECT-TYPE SYNTAX DisplayString @@ -305,7 +376,7 @@ replUntilLogFile OBJECT-TYPE STATUS current DESCRIPTION "The log file name at which the SQL thread stops executing." - ::= { replConfig 13 } + ::= { replSlaveStatusEntry 29 } replUntilLogPos OBJECT-TYPE SYNTAX DisplayString @@ -314,7 +385,7 @@ replUntilLogPos OBJECT-TYPE DESCRIPTION "The position in replUntilLogFile at which the SQL thread stops executing." - ::= { replConfig 14 } + ::= { replSlaveStatusEntry 30 } replMasterServerId OBJECT-TYPE SYNTAX Integer32 @@ -322,7 +393,7 @@ replMasterServerId OBJECT-TYPE STATUS current DESCRIPTION "ID of the master server." - ::= { replConfig 15 } + ::= { replSlaveStatusEntry 31 } replMasterSSLAllowed OBJECT-TYPE SYNTAX DisplayString @@ -339,7 +410,7 @@ replMasterSSLAllowed OBJECT-TYPE * `Ignored' if an SSL connection is permitted but the slave server does not have SSL support enabled." - ::= { replConfig 16 } + ::= { replSlaveStatusEntry 32 } replMasterSSLCAFile OBJECT-TYPE SYNTAX DisplayString @@ -347,7 +418,7 @@ replMasterSSLCAFile OBJECT-TYPE STATUS current DESCRIPTION "File name of the Master CA file." - ::= { replConfig 17 } + ::= { replSlaveStatusEntry 33 } replMasterSSLCAPath OBJECT-TYPE SYNTAX DisplayString @@ -355,7 +426,7 @@ replMasterSSLCAPath OBJECT-TYPE STATUS current DESCRIPTION "Path to look for SSL CA files." - ::= { replConfig 18 } + ::= { replSlaveStatusEntry 34 } replMasterSSLCert OBJECT-TYPE SYNTAX DisplayString @@ -363,7 +434,7 @@ replMasterSSLCert OBJECT-TYPE STATUS current DESCRIPTION "File name of the master SSL certificate file." - ::= { replConfig 19 } + ::= { replSlaveStatusEntry 35 } replMasterSSLCipher OBJECT-TYPE SYNTAX DisplayString @@ -371,7 +442,7 @@ replMasterSSLCipher OBJECT-TYPE STATUS current DESCRIPTION "SSL ciphersuites in use." - ::= { replConfig 20 } + ::= { replSlaveStatusEntry 36 } replMasterSSLKey OBJECT-TYPE SYNTAX DisplayString @@ -379,7 +450,7 @@ replMasterSSLKey OBJECT-TYPE STATUS current DESCRIPTION "File name of the master key file." - ::= { replConfig 21 } + ::= { replSlaveStatusEntry 37 } replMasterSSLVerifyServerCert OBJECT-TYPE SYNTAX TruthValue @@ -387,9 +458,208 @@ replMasterSSLVerifyServerCert OBJECT-TYPE STATUS current DESCRIPTION "Whether to verify server SSL certificate." - ::= { replConfig 22 } + ::= { replSlaveStatusEntry 38 } + +-- +-- Table of Replication Slave Servers +-- + +-- replSlaveCount OBJECT-TYPE +-- SYNTAX Counter32 +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "Number of active replication slaves." +-- ::= { replSlave 1 } + +-- replSlaveTable OBJECT-TYPE +-- SYNTAX SEQUENCE OF ReplSlaveEntry +-- MAX-ACCESS not-accessible +-- STATUS current +-- DESCRIPTION +-- "A table of active replication slaves." +-- ::= { replSlave 2 } + +-- replSlaveEntry OBJECT-TYPE +-- SYNTAX ReplSlaveEntry +-- MAX-ACCESS not-accessible +-- STATUS current +-- DESCRIPTION +-- "An entry (conceptual row) describing a replication +-- slave server." +-- INDEX { replSlaveIndex } +-- ::= { replSlaveTable 1 } + +-- ReplSlaveEntry ::= SEQUENCE { +-- replSlaveIndex Integer32, +-- replSlaveHost DisplayString, +-- replSlaveUser DisplayString, +-- replSlaveCommand DisplayString, +-- replSlaveState DisplayString, +-- replSlaveTime TimeStamp, +-- replSlaveInfo DisplayString +-- } + +-- replSlaveIndex OBJECT-TYPE +-- SYNTAX Integer32 (0..65535) +-- MAX-ACCESS not-accessible +-- STATUS current +-- DESCRIPTION +-- "A number uniquely identifying each slave server." +-- ::= { replSlaveEntry 1 } + +-- replSlaveHost OBJECT-TYPE +-- SYNTAX DisplayString +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "Hostname of the server." +-- ::= { replSlaveEntry 2 } + +-- replSlaveUser OBJECT-TYPE +-- SYNTAX DisplayString +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "User name used by that server." +-- ::= { replSlaveEntry 3 } + +-- replSlaveCommand OBJECT-TYPE +-- SYNTAX DisplayString +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "Command being run." +-- ::= { replSlaveEntry 4 } + +-- replSlaveState OBJECT-TYPE +-- SYNTAX DisplayString +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "State of the connection." +-- ::= { replSlaveEntry 5 } + +-- replSlaveTime OBJECT-TYPE +-- SYNTAX TimeStamp +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "Timestamp of the last status change." +-- ::= { replSlaveEntry 6 } + +-- replSlaveInfo OBJECT-TYPE +-- SYNTAX DisplayString +-- MAX-ACCESS read-only +-- STATUS current +-- DESCRIPTION +-- "Additional info about the connection." +-- ::= { replSlaveEntry 7 } + +-- +-- Process List +-- + +processListTable OBJECT-TYPE + SYNTAX SEQUENCE OF ProcessListEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table of active threads." + ::= { processList 2 } + +processListEntry OBJECT-TYPE + SYNTAX ProcessListEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A conceptual row of process list table." + INDEX { processIndex } + ::= { processListTable 1 } + +ProcessListEntry ::= SEQUENCE { + processIndex Integer32, + processID Integer32, + processUser DisplayString, + processHost DisplayString, + processDatabase DisplayString, + processCommand DisplayString, + processTime TimeStamp, + processState DisplayString, + processInfo DisplayString +} + +processIndex OBJECT-TYPE + SYNTAX Integer32 (0..65535) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A number uniquely identifying each process." + ::= { processListEntry 1 } + +processID OBJECT-TYPE + SYNTAX Integer32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Thread ID." + ::= { processListEntry 2 } +processUser OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Connecting user." + ::= { processListEntry 3 } +processHost OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Remote hostname or IP." + ::= { processListEntry 4 } + +processDatabase OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Database name." + ::= { processListEntry 5 } + +processCommand OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Command being processed." + ::= { processListEntry 6 } + +processTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Running time of the thread." + ::= { processListEntry 7 } + +processState OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Process state." + ::= { processListEntry 8 } + +processInfo OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Information about the process." + ::= { processListEntry 9 } END -- Local variables: diff --git a/src/Makefile.am b/src/Makefile.am index 6463177..0b1ae43 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,12 +20,14 @@ dlmod_LTLIBRARIES = mysqlstat.la mysqlstat_la_SOURCES = \ mysqlstat.c\ mysqlstat.h\ - mysqlstat_mib.c + mysqlstat_mib.c\ + mysqlstat_mib.h BUILT_SOURCES = \ - mysqlstat_mib.c + mysqlstat_mib.c\ + mysqlstat_mib.h -mysqlstat_mib.c: mysqlstat_mib.mib2c MYSQL-STAT-MIB.txt +mysqlstat_mib.c mysqlstat_mib.h: mysqlstat_mib.mib2c MYSQL-STAT-MIB.txt .mib2c.c: MIBDIRS=${top_srcdir}/src:${NET_SNMP_MIBDIRS} MIBS="+MYSQL-STAT-MIB" \ diff --git a/src/mysqlstat.c b/src/mysqlstat.c index 3e89424..938439a 100644 --- a/src/mysqlstat.c +++ b/src/mysqlstat.c @@ -1,4 +1,4 @@ -/* This file is part of Mysqlstat -*- autoconf -*- +/* This file is part of Mysqlstat * Copyright (C) 2014-2016 Sergey Poznyakoff * * Mysqlstat is free software; you can redistribute it and/or modify @@ -19,6 +19,7 @@ #include <mysql/mysql.h> #undef NDEBUG #include <assert.h> +#include "mysqlstat_mib.h" static char *config_file = CONFDIR "/mysqlstat.cnf"; @@ -27,7 +28,7 @@ struct mysqlstat_connection { }; static void * -xalloc(size_t s) +xmalloc(size_t s) { void *p = malloc(s); assert(p != NULL); @@ -65,7 +66,7 @@ mysqlstat_connect(void) mysql_options(&conn->mysql, MYSQL_OPT_RECONNECT, &t); if (!mysql_real_connect(&conn->mysql, NULL, NULL, NULL, NULL, 0, NULL, 0)) { - snmp_log(LOG_ERR, "can't connect to MySQL: %s", + snmp_log(LOG_ERR, "can't connect to MySQL: %s\n", mysql_error(&conn->mysql)); free(conn); conn = NULL; @@ -82,280 +83,348 @@ mysqlstat_disconnect(mysqlstat_connection_t conn) free(conn); } -struct syment { - char *name; - char *value; -}; - -static unsigned int hash_size[] = { - 7, 17, 37, 101, 229, 487, 1009, 2039, 4091, 8191, 16411 -}; +unsigned mysqlstat_cache_timeout = CACHE_TIMEOUT; -/* |max_rehash| keeps the number of entries in |hash_size| table. */ -static unsigned int max_rehash = sizeof(hash_size) / sizeof(hash_size[0]); +#define __cat2__(a,b) a ## b +#define ASSIGN_STRING(e,m,s) \ + do { \ + if (s) { \ + (e)->__cat2__(m,_len) = strlen(s); \ + (e)->m = xmalloc((e)->__cat2__(m,_len)); \ + memcpy((e)->m, s, (e)->__cat2__(m,_len)); \ + } else { \ + (e)->__cat2__(m,_len) = 0; \ + (e)->m = NULL; \ + } \ + } while (0) -struct hashtab { - uint32_t hc; - struct syment *tab; -}; - -static void -syment_free(struct syment *ent) -{ - free(ent->name); - ent->name = NULL; - free(ent->value); - ent->value = NULL; -} +#define ASSIGN_ROW(e,m,r) ASSIGN_STRING(e,m,(r)[__cat2__(FI_,m)]) -static int -syment_matches(struct syment *ent, char const *name) -{ - if (!ent->name) - return 0; - return strcmp(ent->name, name) == 0; -} +#define STREQ(pat,str) (strcmp(#pat, str) == 0) -static uint32_t -hash_string(const char *name, uint32_t hashsize) + +static long +val_Slave_IO_Running(char const *val) { - unsigned i; - - for (i = 0; *name; name++) { - i <<= 1; - i ^= *(unsigned char*) name; - } - return i % hashsize; + if (strcmp(val, "Yes") == 0) + return 1; + else if (strcmp(val, "No") == 0) + return 2; + else if (strcmp(val, "Connected") == 0) + return 3; + return 4; } -static uint32_t -find_insert_pos(struct hashtab *ht, struct syment *ent) +static long +val_bool(char const *val) { - uint32_t i; - uint32_t pos = hash_string(ent->name, hash_size[ht->hc]); - - for (i = pos; ht->tab[i].name; ) { - i = (i + 1) % hash_size[ht->hc]; - if (i == pos) - /* FIXME: Error message? */ - abort(); - } - return i; + if (strcmp(val, "Yes") == 0) + return 1; + return 2; } static void -rehash(struct hashtab *ht) +store_slave_status_row(struct replSlaveStatusTable_entry *ent, + char const *name, char const *value) { - struct syment *oldtab = ht->tab; - uint32_t i, n; - - assert(ht->hc + 1 < max_rehash); - n = hash_size[ht->hc]; - ++ht->hc; - ht->tab = xcalloc(hash_size[ht->hc], sizeof(ht->tab[0])); - for (i = 0; i < n; i++) { - if (oldtab[i].name) - ht->tab[find_insert_pos(ht, &oldtab[i])] = oldtab[i]; + if (STREQ(Slave_IO_State, name)) { + ASSIGN_STRING(ent, replSlaveIOState, value); + } else if (STREQ(Master_Host, name)) { + ASSIGN_STRING(ent, replMasterHost, value); + } else if (STREQ(Master_User, name)) { + ASSIGN_STRING(ent, replMasterUser, value); + } else if (STREQ(Master_Port, name)) { + ent->replMasterPort = strtoul(value, NULL, 10); + } else if (STREQ(Connect_Retry, name)) { + ent->replConnectRetry = strtoul(value, NULL, 10); + } else if (STREQ(Master_Log_File, name)) { + ASSIGN_STRING(ent, replMasterLogFile, value); + } else if (STREQ(Read_Master_Log_Pos, name)) { + ent->replReadMasterLogPos = strtoul(value, NULL, 10); + } else if (STREQ(Relay_Log_File, name)) { + ASSIGN_STRING(ent, replRelayLogFile, value); + } else if (STREQ(Relay_Log_Pos, name)) { + ent->replRelayLogPos = strtoul(value, NULL, 10); + } else if (STREQ(Relay_Master_Log_File, name)) { + ASSIGN_STRING(ent, replMasterLogFile, value); + } else if (STREQ(Slave_IO_Running, name)) { + ent->replSlaveIORunning = val_Slave_IO_Running(value); + } else if (STREQ(Slave_SQL_Running, name)) { + ent->replSlaveSQLRunning = val_bool(value); + } else if (STREQ(Replicate_Do_DB, name)) { + ASSIGN_STRING(ent, replReplicateDoDB, value); + } else if (STREQ(Replicate_Ignore_DB, name)) { + ASSIGN_STRING(ent, replReplicateIgnoreDB, value); + } else if (STREQ(Replicate_Do_Table, name)) { + ASSIGN_STRING(ent, replReplicateDoTable, value); + } else if (STREQ(Replicate_Ignore_Table, name)) { + ASSIGN_STRING(ent, replReplicateIgnoreTable, value); + } else if (STREQ(Replicate_Wild_Do_Table, name)) { + ASSIGN_STRING(ent, replReplicateWildDoTable, value); + } else if (STREQ(Replicate_Wild_Ignore_Table, name)) { + ASSIGN_STRING(ent, replReplicateWildIgnoreTable, value); + } else if (STREQ(Last_IO_Errno, name)) { + ent->replLastIOErrno = strtoul(value, NULL, 10); + } else if (STREQ(Last_IO_Error, name)) { + ASSIGN_STRING(ent, replLastIOError, value); + } else if (STREQ(Last_SQL_Errno, name)) { + ent->replLastSQLErrno = strtoul(value, NULL, 10); + } else if (STREQ(Last_SQL_Error, name)) { + ASSIGN_STRING(ent, replLastSQLError, value); + } else if (STREQ(Skip_Counter, name)) { + ent->replSkipCounter = strtoul(value, NULL, 10); + } else if (STREQ(Exec_Master_Log_Pos, name)) { + ent->replExecMasterLogPos = strtoul(value, NULL, 10); + } else if (STREQ(Relay_Log_Space, name)) { + uint64_t n = strtoull(value, NULL, 10); + ent->replRelayLogSpace.high = n >> 32; + ent->replRelayLogSpace.low = n & 0xffffffff; + } else if (STREQ(Until_Condition, name)) { + ASSIGN_STRING(ent, replUntilCondition, value); + } else if (STREQ(Until_Log_File, name)) { + ASSIGN_STRING(ent, replUntilLogFile, value); + } else if (STREQ(Until_Log_Pos, name)) { + ASSIGN_STRING(ent, replUntilLogPos, value); + } else if (STREQ(Master_SSL_Allowed, name)) { + ASSIGN_STRING(ent, replMasterSSLAllowed, value); + } else if (STREQ(Master_SSL_CA_File, name)) { + ASSIGN_STRING(ent, replMasterSSLCAFile, value); + } else if (STREQ(Master_SSL_CA_Path, name)) { + ASSIGN_STRING(ent, replMasterSSLCAPath, value); + } else if (STREQ(Master_SSL_Cert, name)) { + ASSIGN_STRING(ent, replMasterSSLCert, value); + } else if (STREQ(Master_SSL_Cipher, name)) { + ASSIGN_STRING(ent, replMasterSSLCipher, value); + } else if (STREQ(Master_SSL_Key, name)) { + ASSIGN_STRING(ent, replMasterSSLKey, value); + } else if (STREQ(Seconds_Behind_Master, name)) { + ent->replSecondsBehindMaster = strtoul(value, NULL, 10) * 100; + } else if (STREQ(Master_SSL_Verify_Server_Cert, name)) { + ent->replMasterSSLVerifyServerCert = val_bool(value); } - free(oldtab); } -static void -hashtab_remove(struct hashtab *ht, char const *name) +int +replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic) { - uint32_t pos, i, j, r; + mysqlstat_connection_t conn; + MYSQL_RES *res; + MYSQL_ROW row; + MYSQL_FIELD *fields; + unsigned int num_fields, i; + netsnmp_tdata *table = (netsnmp_tdata *) vmagic; + struct replSlaveStatusTable_entry *ent; + netsnmp_tdata_row *data_row; - pos = hash_string(name, hash_size[ht->hc]); - for (i = pos; ht->tab[i].name;) { - if (syment_matches(&ht->tab[i], name)) - break; - i = (i + 1) % hash_size[ht->hc]; - if (i == pos) - return;// ENOENT - } + conn = mysqlstat_connect(); + if (!conn) + return SNMP_ERR_NOSUCHNAME; - syment_free(&ht->tab[i]); - - for (;;) { - ht->tab[i].name = ht->tab[i].value = NULL; - j = i; - - do { - i = (i + 1) % hash_size[ht->hc]; - if (!ht->tab[i].name) - return; - r = hash_string(ht->tab[i].name, hash_size[ht->hc]); - } while ((j < r && r <= i) - || (i < j && j < r) || (r <= i && i < j)); - ht->tab[j] = ht->tab[i]; + DEBUGMSGTL(("mysqlstat", "Getting slave status\n")); + if (mysql_query(&conn->mysql, "SHOW SLAVE STATUS")) { + snmp_log(LOG_ERR, "can't get slave status: %s\n", + mysql_error(&conn->mysql)); + mysqlstat_disconnect(conn); + return SNMP_ERR_NOSUCHNAME; } -} -static char const * -hashtab_lookup(struct hashtab *ht, char const *name) -{ - uint32_t pos, i; - - pos = hash_string(name, hash_size[ht->hc]); - for (i = pos; ht->tab[i].name;) { - if (syment_matches(&ht->tab[i], name)) - return ht->tab[i].value; - i = (i + 1) % hash_size[ht->hc]; - if (i == pos) - break; + res = mysql_store_result(&conn->mysql); + if (mysql_num_rows(res) < 1) { + snmp_log(LOG_INFO, "empty slave status\n"); + return 0; } - return NULL; -} -static void -hashtab_install(struct hashtab *ht, char const *name, char const *value) -{ - uint32_t i, pos; - struct syment *ent; - - if (!value) - value = ""; - DEBUGMSGTL(("mysqlstat", "%s = %s\n", name, value)); - pos = hash_string(name, hash_size[ht->hc]); - for (i = pos; ht->tab[i].name;) { - if (syment_matches(&ht->tab[i], name)) { - free(ht->tab[i].value); - ht->tab[i].value = xstrdup(value); - return; - } - i = (i + 1) % hash_size[ht->hc]; - if (i == pos) { - rehash(ht); - i = pos = hash_string(name, hash_size[ht->hc]); - } + num_fields = mysql_num_fields(res); + fields = mysql_fetch_fields(res); + row = mysql_fetch_row(res); + + ent = SNMP_MALLOC_TYPEDEF(struct replSlaveStatusTable_entry); + if (!ent) { + mysqlstat_disconnect(conn); + return SNMP_ERR_GENERR; } - ht->tab[i].name = xstrdup(name); - ht->tab[i].value = xstrdup(value); -} + data_row = netsnmp_tdata_create_row(); + if (!data_row) { + SNMP_FREE(ent); + mysqlstat_disconnect(conn); + return SNMP_ERR_GENERR; + } + data_row->data = ent; + ent->replSlaveIndex = 0; + netsnmp_tdata_row_add_index(data_row, ASN_INTEGER, + &ent->replSlaveIndex, + sizeof(ent->replSlaveIndex)); -void -hashtab_clear(struct hashtab *ht) -{ - unsigned i, hs; + netsnmp_tdata_add_row(table, data_row); + + for (i = 0; i < num_fields; i++) + store_slave_status_row (ent, fields[i].name, row[i]); - hs = hash_size[ht->hc]; - for (i = 0; i < hs; i++) { - syment_free(&ht->tab[i]); - } + mysql_free_result(res); + mysqlstat_disconnect(conn); + return 0; } -static struct hashtab * -hashtab_create(void) +void +replSlaveStatusTable_entry_free(void *data) { - struct hashtab *ht = xalloc(sizeof(*ht)); - ht->hc = 0; - ht->tab = xcalloc(hash_size[ht->hc], sizeof(ht->tab[0])); - return ht; + struct replSlaveStatusTable_entry *ent = data; + free(ent->replSlaveIOState); + free(ent->replMasterLogFile); + free(ent->replRelayLogFile); + free(ent->replRelayMasterLogFile); + free(ent->replLastSQLError); + free(ent->replLastIOError); + free(ent->replMasterHost); + free(ent->replMasterUser); + free(ent->replReplicateDoDB); + free(ent->replReplicateIgnoreDB); + free(ent->replReplicateDoTable); + free(ent->replReplicateIgnoreTable); + free(ent->replReplicateWildDoTable); + free(ent->replReplicateWildIgnoreTable); + free(ent->replUntilCondition); + free(ent->replUntilLogFile); + free(ent->replUntilLogPos); + free(ent->replMasterSSLAllowed); + free(ent->replMasterSSLCAFile); + free(ent->replMasterSSLCAPath); + free(ent->replMasterSSLCert); + free(ent->replMasterSSLCipher); + free(ent->replMasterSSLKey); } -struct mysqlstat_cache { - void (*populate) (struct hashtab *); - struct hashtab *ht; - time_t ts; -}; -static unsigned cache_timeout = CACHE_TIMEOUT; +enum { + FI_processID, + FI_processUser, + FI_processHost, + FI_processDatabase, + FI_processCommand, + FI_processTime, + FI_processState, + FI_processInfo +}; -static char const * -mysqlstat_cache_get(struct mysqlstat_cache *cache, char const *name) -{ - time_t now = time(NULL); - struct syment *ent; - - if (!cache->ht) - cache->ht = hashtab_create(); - if (now - cache->ts > cache_timeout) { - hashtab_clear(cache->ht); - cache->populate(cache->ht); - cache->ts = now; - } - return hashtab_lookup(cache->ht, name); -} - -static char const * -val_Slave_IO_Running(char const *val) +static void +process_list_add(netsnmp_tdata *table_data, long idx, MYSQL_ROW mysql_row) { - if (strcmp(val, "Yes") == 0) - return "1"; - else if (strcmp(val, "No") == 0) - return "2"; - else if (strcmp(val, "Connected") == 0) - return "3"; - return 4; -} + struct processListTable_entry *ent; + netsnmp_tdata_row *data_row; -static char const * -val_bool(char const *val) -{ - if (strcmp(val, "Yes") == 0) - return "1"; - return "2"; + ent = SNMP_MALLOC_TYPEDEF(struct processListTable_entry); + if (!ent) + return; + + data_row = netsnmp_tdata_create_row(); + if (!data_row) { + SNMP_FREE(ent); + return; + } + data_row->data = ent; + + ent->processIndex = idx; + if (mysql_row[FI_processID]) + ent->processID = strtol(mysql_row[FI_processID], NULL, 10); + ASSIGN_ROW(ent, processUser, mysql_row); + ASSIGN_ROW(ent, processHost, mysql_row); + ASSIGN_ROW(ent, processDatabase, mysql_row); + ASSIGN_ROW(ent, processCommand, mysql_row); + if (mysql_row[FI_processTime]) + ent->processTime = strtol(mysql_row[FI_processTime], NULL, 10) * 100; + ASSIGN_ROW(ent, processState, mysql_row); + ASSIGN_ROW(ent, processInfo, mysql_row); + + netsnmp_tdata_row_add_index(data_row, ASN_INTEGER, + &ent->processIndex, + sizeof(ent->processIndex)); + + netsnmp_tdata_add_row(table_data, data_row); } -static void -populate_repl(struct hashtab *ht) +int |