X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fcats%2Fmysql.c;h=a8cd052bbd89dcded1e2ee4d802da5a407e16770;hb=27c6094b93454811a6e966558ec187f8ad5a229c;hp=fff10ba24da79854e3297649bc978942f1b854cd;hpb=71025c877b28da7326d650dd3598b9bd64d00e23;p=bacula%2Fbacula diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index fff10ba24d..a8cd052bbd 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -9,7 +9,7 @@ */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -56,19 +56,26 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; * never have errors, or it is really fatal. */ B_DB * -db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password, - char *db_address, int db_port, char *db_socket) +db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password, + const char *db_address, int db_port, const char *db_socket, + int mult_db_connections) { B_DB *mdb; + if (!db_user) { + Jmsg(jcr, M_FATAL, 0, _("A user name for MySQL must be supplied.\n")); + return NULL; + } P(mutex); /* lock DB queue */ /* Look to see if DB already open */ - for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) { - if (strcmp(mdb->db_name, db_name) == 0) { - Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name); - mdb->ref_count++; - V(mutex); - return mdb; /* already open */ + if (!mult_db_connections) { + for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) { + if (strcmp(mdb->db_name, db_name) == 0) { + Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name); + mdb->ref_count++; + V(mutex); + return mdb; /* already open */ + } } } Dmsg0(100, "db_open first time\n"); @@ -76,7 +83,9 @@ db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password, memset(mdb, 0, sizeof(B_DB)); mdb->db_name = bstrdup(db_name); mdb->db_user = bstrdup(db_user); - mdb->db_password = bstrdup(db_password); + if (db_password) { + mdb->db_password = bstrdup(db_password); + } if (db_address) { mdb->db_address = bstrdup(db_address); } @@ -101,7 +110,9 @@ db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password, /* * Now actually open the database. This can generate errors, - * which are returned in the errmsg + * which are returned in the errmsg + * + * DO NOT close the database or free(mdb) here !!!! */ int db_open_database(JCR *jcr, B_DB *mdb) @@ -116,7 +127,7 @@ db_open_database(JCR *jcr, B_DB *mdb) mdb->connected = FALSE; if ((errstat=rwl_init(&mdb->lock)) != 0) { - Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), + Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), strerror(errstat)); V(mutex); return 0; @@ -128,18 +139,8 @@ db_open_database(JCR *jcr, B_DB *mdb) #endif mysql_init(&(mdb->mysql)); Dmsg0(50, "mysql_init done\n"); - mdb->db = mysql_real_connect( - &(mdb->mysql), /* db */ - mdb->db_address, /* default = localhost */ - mdb->db_user, /* login name */ - mdb->db_password, /* password */ - mdb->db_name, /* database name */ - mdb->db_port, /* default port */ - mdb->db_socket, /* default = socket */ - CLIENT_FOUND_ROWS); /* flags */ - - /* If no connect, try once more incase it is a timing problem */ - if (mdb->db == NULL) { + /* If connection fails, try at 5 sec intervals for 30 seconds. */ + for (int retry=0; retry < 6; retry++) { mdb->db = mysql_real_connect( &(mdb->mysql), /* db */ mdb->db_address, /* default = localhost */ @@ -148,17 +149,23 @@ db_open_database(JCR *jcr, B_DB *mdb) mdb->db_name, /* database name */ mdb->db_port, /* default port */ mdb->db_socket, /* default = socket */ - 0); /* flags = none */ + CLIENT_FOUND_ROWS); /* flags */ + + /* If no connect, try once more in case it is a timing problem */ + if (mdb->db != NULL) { + break; + } + bmicrosleep(5,0); } - + Dmsg0(50, "mysql_real_connect done\n"); - Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", mdb->db_user, mdb->db_name, - mdb->db_password==NULL?"(NULL)":mdb->db_password); - + Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", mdb->db_user, mdb->db_name, + mdb->db_password==NULL?"(NULL)":mdb->db_password); + if (mdb->db == NULL) { - Mmsg2(&mdb->errmsg, _("Unable to connect to MySQL server. \n\ -Database=%s User=%s\n\ -It is probably not running or your password is incorrect.\n"), + Mmsg2(&mdb->errmsg, _("Unable to connect to MySQL server. \n" +"Database=%s User=%s\n" +"It is probably not running or your password is incorrect.\n"), mdb->db_name, mdb->db_user); V(mutex); return 0; @@ -166,11 +173,12 @@ It is probably not running or your password is incorrect.\n"), if (!check_tables_version(jcr, mdb)) { V(mutex); - db_close_database(jcr, mdb); return 0; } +#ifdef HAVE_THREAD_SAFE_MYSQL my_thread_init(); +#endif mdb->connected = TRUE; V(mutex); @@ -180,9 +188,14 @@ It is probably not running or your password is incorrect.\n"), void db_close_database(JCR *jcr, B_DB *mdb) { + if (!mdb) { + return; + } P(mutex); mdb->ref_count--; +#ifdef HAVE_TREAD_SAFE_MYSQL my_thread_end(); +#endif if (mdb->ref_count == 0) { qdchain(&mdb->bq); if (mdb->connected && mdb->db) { @@ -191,7 +204,7 @@ db_close_database(JCR *jcr, B_DB *mdb) mysql_server_end(); #endif } - rwl_destroy(&mdb->lock); + rwl_destroy(&mdb->lock); free_pool_memory(mdb->errmsg); free_pool_memory(mdb->cmd); free_pool_memory(mdb->cached_path); @@ -221,7 +234,7 @@ db_close_database(JCR *jcr, B_DB *mdb) /* * Return the next unique index (auto-increment) for * the given table. Return NULL on error. - * + * * For MySQL, NULL causes the auto-increment value * to be updated. */ @@ -229,14 +242,14 @@ int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index) { strcpy(index, "NULL"); return 1; -} +} /* * Escape strings so that MySQL is happy * * NOTE! len is the length of the old string. Your new - * string must be long enough (max 2*old) to hold + * string must be long enough (max 2*old+1) to hold * the escaped output. */ void @@ -256,38 +269,38 @@ unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, while (len--) { switch (*o) { case 0: - *n++= '\\'; - *n++= '0'; + *n++= '\\'; + *n++= '0'; o++; break; case '\n': - *n++= '\\'; - *n++= 'n'; + *n++= '\\'; + *n++= 'n'; o++; break; case '\r': - *n++= '\\'; - *n++= 'r'; + *n++= '\\'; + *n++= 'r'; o++; break; case '\\': - *n++= '\\'; - *n++= '\\'; + *n++= '\\'; + *n++= '\\'; o++; break; case '\'': - *n++= '\\'; - *n++= '\''; + *n++= '\\'; + *n++= '\''; o++; break; case '"': - *n++= '\\'; - *n++= '"'; + *n++= '\\'; + *n++= '"'; o++; break; case '\032': - *n++= '\\'; - *n++= 'Z'; + *n++= '\\'; + *n++= 'Z'; o++; break; default: @@ -302,13 +315,13 @@ unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, * Submit a general SQL command (cmd), and for each row returned, * the sqlite_handler is called with the ctx. */ -int db_sql_query(B_DB *mdb, char *query, DB_RESULT_HANDLER *result_handler, void *ctx) +int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) { SQL_ROW row; - + db_lock(mdb); if (sql_query(mdb, query) != 0) { - Mmsg(&mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb)); + Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb)); db_unlock(mdb); return 0; } @@ -329,118 +342,4 @@ int db_sql_query(B_DB *mdb, char *query, DB_RESULT_HANDLER *result_handler, void } - -static void -list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx) -{ - SQL_FIELD *field; - unsigned int i, j; - - sql_field_seek(mdb, 0); - send(ctx, "+"); - for (i = 0; i < sql_num_fields(mdb); i++) { - field = sql_fetch_field(mdb); - for (j = 0; j < field->max_length + 2; j++) - send(ctx, "-"); - send(ctx, "+"); - } - send(ctx, "\n"); -} - -/* - * If full_list is set, we list vertically, otherwise, we - * list on one line horizontally. - */ -void -list_result(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type) -{ - SQL_FIELD *field; - SQL_ROW row; - unsigned int i, col_len, max_len = 0; - char buf[2000], ewc[30]; - - if (mdb->result == NULL) { - send(ctx, _("No results to list.\n")); - return; - } - /* determine column display widths */ - sql_field_seek(mdb, 0); - for (i = 0; i < sql_num_fields(mdb); i++) { - field = sql_fetch_field(mdb); - col_len = strlen(field->name); - if (type == VERT_LIST) { - if (col_len > max_len) { - max_len = col_len; - } - } else { - if (IS_NUM(field->type) && field->max_length > 0) { /* fixup for commas */ - field->max_length += (field->max_length - 1) / 3; - } - if (col_len < field->max_length) { - col_len = field->max_length; - } - if (col_len < 4 && !IS_NOT_NULL(field->flags)) { - col_len = 4; /* 4 = length of the word "NULL" */ - } - field->max_length = col_len; /* reset column info */ - } - } - - if (type == VERT_LIST) { - goto vertical_list; - } - - list_dashes(mdb, send, ctx); - send(ctx, "|"); - sql_field_seek(mdb, 0); - for (i = 0; i < sql_num_fields(mdb); i++) { - field = sql_fetch_field(mdb); - bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, field->name); - send(ctx, buf); - } - send(ctx, "\n"); - list_dashes(mdb, send, ctx); - - while ((row = sql_fetch_row(mdb)) != NULL) { - sql_field_seek(mdb, 0); - send(ctx, "|"); - for (i = 0; i < sql_num_fields(mdb); i++) { - field = sql_fetch_field(mdb); - if (row[i] == NULL) { - bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL"); - } else if (IS_NUM(field->type)) { - bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length, - add_commas(row[i], ewc)); - } else { - bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]); - } - send(ctx, buf); - } - send(ctx, "\n"); - } - list_dashes(mdb, send, ctx); - return; - -vertical_list: - - while ((row = sql_fetch_row(mdb)) != NULL) { - sql_field_seek(mdb, 0); - for (i = 0; i < sql_num_fields(mdb); i++) { - field = sql_fetch_field(mdb); - if (row[i] == NULL) { - bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL"); - } else if (IS_NUM(field->type)) { - bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, - add_commas(row[i], ewc)); - } else { - bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]); - } - send(ctx, buf); - } - send(ctx, "\n"); - } - return; -} - - #endif /* HAVE_MYSQL */