[shibboleth-sp2] 11/18: Added real-time repair, cleaned up some error handling
Ferenc Wágner
wferi-guest at moszumanska.debian.org
Tue Jan 26 21:29:31 UTC 2016
This is an automated email from the git hooks/post-receive script.
wferi-guest pushed a commit to annotated tag 1.2.1b
in repository shibboleth-sp2.
commit f1911f2b79beaf442d70b61f329d3e5d73f60a22
Author: Scott Cantor <cantor.2 at osu.edu>
Date: Sun Feb 27 19:11:33 2005 +0000
Added real-time repair, cleaned up some error handling
---
shib-mysql-ccache/shib-mysql-ccache.cpp | 129 +++++++++++++++++++++++---------
1 file changed, 92 insertions(+), 37 deletions(-)
diff --git a/shib-mysql-ccache/shib-mysql-ccache.cpp b/shib-mysql-ccache/shib-mysql-ccache.cpp
index 945005f..77ca6ee 100644
--- a/shib-mysql-ccache/shib-mysql-ccache.cpp
+++ b/shib-mysql-ccache/shib-mysql-ccache.cpp
@@ -44,6 +44,9 @@
#include <mysql.h>
+// wanted to use MySQL codes for this, but can't seem to get back a 145
+#define isCorrupt(s) strstr(s,"(errno: 145)")
+
#ifdef HAVE_LIBDMALLOCXX
#include <dmalloc.h>
#endif
@@ -130,6 +133,7 @@ private:
void createDatabase(MYSQL*, int major, int minor);
void upgradeDatabase(MYSQL*);
void getVersion(MYSQL*, int* major_p, int* minor_p);
+ bool repairTable(MYSQL*&, const char* table);
void mysqlInit(void);
};
@@ -145,8 +149,7 @@ extern "C" void shib_mysql_destroy_handle(void* data);
MYSQL* ShibMySQLCCache::getMYSQL() const
{
- void* data = m_mysql->getData();
- return (MYSQL*)data;
+ return (MYSQL*)m_mysql->getData();
}
void ShibMySQLCCache::thread_init()
@@ -158,19 +161,18 @@ void ShibMySQLCCache::thread_init()
if (!mysql) {
log->error("mysql_init failed");
mysql_close(mysql);
- throw runtime_error("mysql_init()");
+ throw SAMLException("ShibMySQLCCache::thread_init(): mysql_init() failed");
}
if (!mysql_real_connect(mysql, NULL, NULL, NULL, "shar", 0, NULL, 0)) {
if (initialized) {
log->crit("mysql_real_connect failed: %s", mysql_error(mysql));
- throw runtime_error("mysql_real_connect");
-
+ mysql_close(mysql);
+ throw SAMLException("ShibMySQLCCache::thread_init(): mysql_real_connect() failed");
} else {
- log->info("mysql_real_connect failed: %s. Trying to create",
- mysql_error(mysql));
+ log->info("mysql_real_connect failed: %s. Trying to create", mysql_error(mysql));
- // This will throw a runtime error if it fails.
+ // This will throw an exception if it fails.
createDatabase(mysql, PLUGIN_VER_MAJOR, PLUGIN_VER_MINOR);
}
}
@@ -186,13 +188,14 @@ void ShibMySQLCCache::thread_init()
upgradeDatabase(mysql);
}
else {
+ mysql_close(mysql);
log->crit("Invalid database version: %d.%d", major, minor);
- throw runtime_error("Invalid Database version");
+ throw SAMLException("ShibMySQLCCache::thread_init(): Invalid database version");
}
}
// We're all set.. Save off the handle for this thread.
- m_mysql->setData((void*)mysql);
+ m_mysql->setData(mysql);
}
ShibMySQLCCache::ShibMySQLCCache(const DOMElement* e)
@@ -226,6 +229,7 @@ ShibMySQLCCache::~ShibMySQLCCache()
shutdown_wait->signal();
cleanup_thread->join(NULL);
+ thread_end();
delete m_cache;
delete m_mysql;
@@ -235,7 +239,7 @@ ShibMySQLCCache::~ShibMySQLCCache()
ISessionCacheEntry* ShibMySQLCCache::find(const char* key)
{
- saml::NDC ndc("mysql::find");
+ saml::NDC ndc("ShibMySQLCCache::find");
ISessionCacheEntry* res = m_cache->find(key);
if (!res) {
@@ -246,8 +250,14 @@ ISessionCacheEntry* ShibMySQLCCache::find(const char* key)
MYSQL_RES* rows;
MYSQL* mysql = getMYSQL();
- if (mysql_query(mysql, q.c_str()))
- log->error("Error searching for %s: %s", key, mysql_error(mysql));
+ if (mysql_query(mysql, q.c_str())) {
+ const char* err=mysql_error(mysql);
+ log->error("Error searching for %s: %s", key, err);
+ if (isCorrupt(err) && repairTable(mysql,"state")) {
+ if (mysql_query(mysql, q.c_str()))
+ log->error("Error retrying search for %s: %s", key, mysql_error(mysql));
+ }
+ }
rows = mysql_store_result(mysql);
@@ -306,7 +316,7 @@ void ShibMySQLCCache::insert(
const char *client_addr,
saml::SAMLResponse* r)
{
- saml::NDC ndc("mysql::insert");
+ saml::NDC ndc("ShibMySQLCCache::insert");
ostringstream os;
os << *s;
@@ -319,13 +329,21 @@ void ShibMySQLCCache::insert(
// then add it to the database
MYSQL* mysql = getMYSQL();
- if (mysql_query(mysql, q.c_str()))
- log->error("Error inserting %s: %s", key, mysql_error(mysql));
+ if (mysql_query(mysql, q.c_str())) {
+ const char* err=mysql_error(mysql);
+ log->error("Error inserting %s: %s", key, err);
+ if (isCorrupt(err) && repairTable(mysql,"state")) {
+ // Try again...
+ if (mysql_query(mysql, q.c_str()))
+ log->error("Error inserting %s: %s", key, mysql_error(mysql));
+ // TODO: throw exception
+ }
+ }
}
void ShibMySQLCCache::remove(const char* key)
{
- saml::NDC ndc("mysql::remove");
+ saml::NDC ndc("ShibMySQLCCache::remove");
// Remove the cached version
m_cache->remove(key);
@@ -333,14 +351,21 @@ void ShibMySQLCCache::remove(const char* key)
// Remove from the database
string q = string("DELETE FROM state WHERE cookie='") + key + "'";
MYSQL* mysql = getMYSQL();
- if (mysql_query(mysql, q.c_str()))
- log->info("Error deleting entry %s: %s", key, mysql_error(mysql));
+ if (mysql_query(mysql, q.c_str())) {
+ const char* err=mysql_error(mysql);
+ log->error("Error deleting entry %s: %s", key, err);
+ if (isCorrupt(err) && repairTable(mysql,"state")) {
+ // Try again...
+ if (mysql_query(mysql, q.c_str()))
+ log->error("Error deleting entry %s: %s", key, mysql_error(mysql));
+ }
+ }
}
void ShibMySQLCCache::cleanup()
{
Mutex* mutex = Mutex::create();
- saml::NDC ndc("mysql::cleanup");
+ saml::NDC ndc("ShibMySQLCCache::cleanup");
thread_init();
@@ -386,8 +411,14 @@ void ShibMySQLCCache::cleanup()
"UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(atime) >= " << timeout_life;
MYSQL_RES *rows;
- if (mysql_query(mysql, q.str().c_str()))
- log->error("Error searching for old items: %s", mysql_error(mysql));
+ if (mysql_query(mysql, q.str().c_str())) {
+ const char* err=mysql_error(mysql);
+ log->error("Error searching for old items: %s", err);
+ if (isCorrupt(err) && repairTable(mysql,"state")) {
+ if (mysql_query(mysql, q.str().c_str()))
+ log->error("Error re-searching for old items: %s", mysql_error(mysql));
+ }
+ }
rows = mysql_store_result(mysql);
if (!rows)
@@ -427,6 +458,23 @@ void* ShibMySQLCCache::cleanup_fcn(void* cache_p)
return NULL;
}
+bool ShibMySQLCCache::repairTable(MYSQL*& mysql, const char* table)
+{
+ string q = string("REPAIR TABLE ") + table;
+ if (mysql_query(mysql, q.c_str())) {
+ log->error("Error repairing table %s: %s", table, mysql_error(mysql));
+ return false;
+ }
+
+ // seems we have to recycle the connection to get the thread to keep working
+ // other threads seem to be ok, but we should monitor that
+ mysql_close(mysql);
+ m_mysql->setData(NULL);
+ thread_init();
+ mysql=getMYSQL();
+ return true;
+}
+
void ShibMySQLCCache::createDatabase(MYSQL* mysql, int major, int minor)
{
log->info("Creating database.");
@@ -436,48 +484,55 @@ void ShibMySQLCCache::createDatabase(MYSQL* mysql, int major, int minor)
ms = mysql_init(NULL);
if (!ms) {
log->crit("mysql_init failed");
- throw ShibTargetException();
+ throw SAMLException("ShibMySQLCCache::createDatabase(): mysql_init failed");
}
if (!mysql_real_connect(ms, NULL, NULL, NULL, NULL, 0, NULL, 0)) {
log->crit("cannot open DB file to create DB: %s", mysql_error(ms));
- throw ShibTargetException();
+ throw SAMLException("ShibMySQLCCache::createDatabase(): mysql_real_connect failed");
}
if (mysql_query(ms, "CREATE DATABASE shar")) {
log->crit("cannot create shar database: %s", mysql_error(ms));
- throw ShibTargetException();
+ throw SAMLException("ShibMySQLCCache::createDatabase(): create db cmd failed");
}
if (!mysql_real_connect(mysql, NULL, NULL, NULL, "shar", 0, NULL, 0)) {
log->crit("cannot open SHAR database");
- throw ShibTargetException();
+ throw SAMLException("ShibMySQLCCache::createDatabase(): mysql_real_connect to shar db failed");
}
mysql_close(ms);
- } catch (ShibTargetException&) {
+ }
+ catch (SAMLException&) {
if (ms)
mysql_close(ms);
mysql_close(mysql);
- throw runtime_error("mysql_real_connect");
+ throw;
}
// Now create the tables if they don't exist
- log->info("Creating database tables.");
+ log->info("Creating database tables");
- if (mysql_query(mysql, "CREATE TABLE version (major INT, minor INT)"))
+ if (mysql_query(mysql, "CREATE TABLE version (major INT, minor INT)")) {
log->error ("Error creating version: %s", mysql_error(mysql));
+ throw SAMLException("ShibMySQLCCache::createDatabase(): create table cmd failed");
+ }
if (mysql_query(mysql,
"CREATE TABLE state (cookie VARCHAR(64) PRIMARY KEY, application_id VARCHAR(255),"
- "atime DATETIME, addr VARCHAR(128), statement TEXT)"))
+ "atime DATETIME, addr VARCHAR(128), statement TEXT)")) {
log->error ("Error creating state: %s", mysql_error(mysql));
+ throw SAMLException("ShibMySQLCCache::createDatabase(): create table cmd failed");
+ }
ostringstream q;
q << "INSERT INTO version VALUES(" << major << "," << minor << ")";
- if (mysql_query(mysql, q.str().c_str()))
+ if (mysql_query(mysql, q.str().c_str())) {
log->error ("Error setting version: %s", mysql_error(mysql));
+ throw SAMLException("ShibMySQLCCache::createDatabase(): version insert failed");
+ }
}
void ShibMySQLCCache::upgradeDatabase(MYSQL* mysql)
@@ -490,14 +545,14 @@ void ShibMySQLCCache::upgradeDatabase(MYSQL* mysql)
"CREATE TABLE state (cookie VARCHAR(64) PRIMARY KEY, application_id VARCHAR(255),"
"atime DATETIME, addr VARCHAR(128), statement TEXT)")) {
log->error ("Error creating state table: %s", mysql_error(mysql));
- throw runtime_error("error creating table");
+ throw SAMLException("ShibMySQLCCache::upgradeDatabase(): error creating state table");
}
ostringstream q;
q << "UPDATE version SET major = " << PLUGIN_VER_MAJOR;
if (mysql_query(mysql, q.str().c_str())) {
log->error ("Error updating version: %s", mysql_error(mysql));
- throw runtime_error("error updating table");
+ throw SAMLException("ShibMySQLCCache::upgradeDatabase(): error updating version");
}
}
@@ -525,13 +580,13 @@ void ShibMySQLCCache::getVersion(MYSQL* mysql, int* major_p, int* minor_p)
} else {
// Wrong number of rows or wrong number of fields...
- log->crit("Houston, we've got a problem with the database..");
+ log->crit("Houston, we've got a problem with the database...");
mysql_free_result (rows);
- throw runtime_error("Database version verification failed");
+ throw SAMLException("ShibMySQLCCache::getVersion(): version verification failed");
}
}
log->crit("MySQL Read Failed in version verificatoin");
- throw runtime_error("MySQL Read Failed");
+ throw SAMLException("ShibMySQLCCache::getVersion(): error reading version");
}
void ShibMySQLCCache::mysqlInit(void)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/shibboleth-sp2.git
More information about the Pkg-shibboleth-devel
mailing list