#include "stats.h"
#include "db_calls.h"
#include "db_supp.h"
+#include "openserver.h"
#ifdef GLITE_LB_SERVER_WITH_WS
# if GSOAP_VERSION < 20700
#endif /* GLITE_LB_SERVER_WITH_WS */
extern int edg_wll_StoreProto(edg_wll_Context ctx);
-extern edg_wll_ErrorCode edg_wll_Open(edg_wll_Context ctx, char *cs);
-extern edg_wll_ErrorCode edg_wll_Close(edg_wll_Context);
extern int edg_wll_StoreProtoProxy(edg_wll_Context ctx);
extern char *lbproxy_ilog_socket_path;
,me);
}
-static void wait_for_open(edg_wll_Context,const char *);
+static int wait_for_open(edg_wll_Context,const char *);
static int decrement_timeout(struct timeval *, struct timeval, struct timeval);
static int add_root(char *);
static int read_roots(const char *);
/* Just check the database and let it be. The slaves do the job. */
edg_wll_InitContext(&ctx);
- glite_lbu_InitDBContext(&ctx->dbctx);
- wait_for_open(ctx, dbstring);
+ if (wait_for_open(ctx, dbstring)) return 1;
if ((ctx->dbcaps = glite_lbu_DBQueryCaps(ctx->dbctx)) == -1)
{
*/
break;
+ case EDG_WLL_ERROR_DB_INIT:
case EDG_WLL_ERROR_DB_CALL:
case EDG_WLL_ERROR_SERVER_RESPONSE:
default:
}
-static void wait_for_open(edg_wll_Context ctx, const char *dbstring)
+static int wait_for_open(edg_wll_Context ctx, const char *dbstring)
{
char *dbfail_string1, *dbfail_string2;
+ char *errt,*errd;
+ int err;
dbfail_string1 = dbfail_string2 = NULL;
- while (edg_wll_Open(ctx, (char *) dbstring)) {
- char *errt,*errd;
-
+ while (((err = edg_wll_Open(ctx, (char *) dbstring)) != EDG_WLL_ERROR_DB_INIT) && err) {
if (dbfail_string1) free(dbfail_string1);
- glite_lbu_DBError(ctx->dbctx,&errt,&errd);
+ edg_wll_Error(ctx,&errt,&errd);
asprintf(&dbfail_string1,"%s (%s)\n",errt,errd);
if (dbfail_string1 != NULL) {
if (dbfail_string2 == NULL || strcmp(dbfail_string1,dbfail_string2)) {
dprintf(("[%d]: DB connection established\n",getpid()));
if (!debug) syslog(LOG_INFO,"DB connection established\n");
}
+
+ if (err) {
+ edg_wll_Error(ctx,&errt,&errd);
+ asprintf(&dbfail_string1,"%s (%s)\n",errt,errd);
+ dprintf(("[%d]: %s\n", getpid(), dbfail_string1));
+ if (!debug) syslog(LOG_ERR,dbfail_string1);
+ free(dbfail_string1);
+ }
+
+ return err;
}
static void free_hostent(struct hostent *h){
#include <mysql.h>
#include <mysqld_error.h>
+#include <mysql_version.h>
#include <errmsg.h>
#include "glite/lbu/trio.h"
#define USE_TRANS(CTX) ((CTX->caps & GLITE_LBU_DB_CAP_TRANSACTIONS) != 0)
#define LOAD(SYM, SYM2) if ((*(void **)(&db_handle.SYM) = dlsym(db_handle.lib, SYM2)) == NULL) { \
- err = ERR(ctx, ENOENT, "can't load symbol %s from mysql library (%s)", SYM2, dlerror()); \
+ err = ERR(*ctx, ENOENT, "can't load symbol %s from mysql library (%s)", SYM2, dlerror()); \
break; \
}
pthread_mutex_t lock;
void *(*mysql_init)(void *);
+ unsigned long (*mysql_get_client_version)(void);
int (*mysql_options)(MYSQL *mysql, enum mysql_option option, const char *arg);
unsigned int (*mysql_errno)(MYSQL *mysql);
const char *(*mysql_error)(MYSQL *mysql);
static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results);
static int FetchRowPrepared(glite_lbu_DBContext ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results);
static void set_time(MYSQL_TIME *mtime, const time_t time);
+static void glite_lbu_DBCleanup(void);
/* ---- common ---- */
int glite_lbu_InitDBContext(glite_lbu_DBContext *ctx) {
- *ctx = calloc(1, sizeof **ctx);
- return *ctx == NULL ? ENOMEM : 0;
-}
-
-
-void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx) {
- if (ctx) {
- assert(ctx->mysql == NULL);
- free(ctx->err.desc);
- free(ctx);
- }
-}
-
-
-static void glite_lbu_DBCleanup(void) {
- pthread_mutex_lock(&db_handle.lock);
- if (db_handle.lib) {
- dlclose(db_handle.lib);
- db_handle.lib = NULL;
- }
- pthread_mutex_unlock(&db_handle.lock);
-}
-
-
-int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs) {
int err = 0;
+ unsigned int ver_u;
+
+ *ctx = calloc(1, sizeof **ctx);
+ if (!*ctx) return ENOMEM;
/* dynamic load the mysql library */
pthread_mutex_lock(&db_handle.lock);
if (!db_handle.lib) {
if ((!MYSQL_LIBPATH[0] || (db_handle.lib = dlopen(MYSQL_LIBPATH, RTLD_LAZY | RTLD_LOCAL)) == NULL) &&
(db_handle.lib = dlopen("libmysqlclient.so", RTLD_LAZY | RTLD_LOCAL)) == NULL)
- return ERR(ctx, ENOENT, "can't load '%s' or 'libmysqlclient.so' (%s)", MYSQL_LIBPATH, dlerror());
+ return ERR(*ctx, ENOENT, "can't load '%s' or 'libmysqlclient.so' (%s)", MYSQL_LIBPATH, dlerror());
do {
LOAD(mysql_init, "mysql_init");
+ LOAD(mysql_get_client_version, "mysql_get_client_version");
LOAD(mysql_options, "mysql_options");
LOAD(mysql_errno, "mysql_errno");
LOAD(mysql_error, "mysql_error");
LOAD(mysql_stmt_affected_rows, "mysql_stmt_affected_rows");
LOAD(mysql_stmt_result_metadata, "mysql_stmt_result_metadata");
LOAD(mysql_stmt_fetch_column, "mysql_stmt_fetch_column");
+
+ // check the runtime version
+ ver_u = db_handle.mysql_get_client_version();
+ if (ver_u != MYSQL_VERSION_ID) {
+ err = ERR(*ctx, EINVAL, "version mismatch (compiled '%lu', runtime '%lu')", MYSQL_VERSION_ID, ver_u);
+ break;
+ }
+
pthread_mutex_unlock(&db_handle.lock);
atexit(glite_lbu_DBCleanup);
} while(0);
+
if (err) {
dlclose(db_handle.lib);
db_handle.lib = NULL;
}
} else pthread_mutex_unlock(&db_handle.lock);
+ return 0;
+}
+
+
+void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx) {
+ if (ctx) {
+ assert(ctx->mysql == NULL);
+ free(ctx->err.desc);
+ free(ctx);
+ }
+}
+
+
+int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs) {
if (db_connect(ctx, cs, &ctx->mysql) != 0) return STATUS(ctx);
return 0;
}
mtime->minute = tm.tm_min;
mtime->second = tm.tm_sec;
}
+
+
+static void glite_lbu_DBCleanup(void) {
+ pthread_mutex_lock(&db_handle.lock);
+ if (db_handle.lib) {
+ dlclose(db_handle.lib);
+ db_handle.lib = NULL;
+ }
+ pthread_mutex_unlock(&db_handle.lock);
+}
+
+