MXS-2558: Reuse loaded users
When users are loaded, they can be reused across all routing workers.
This commit is contained in:
		@ -33,6 +33,7 @@
 | 
				
			|||||||
#include <maxscale/service.hh>
 | 
					#include <maxscale/service.hh>
 | 
				
			||||||
#include <maxscale/users.h>
 | 
					#include <maxscale/users.h>
 | 
				
			||||||
#include <maxscale/utils.h>
 | 
					#include <maxscale/utils.h>
 | 
				
			||||||
 | 
					#include <maxscale/routingworker.hh>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Don't include the root user */
 | 
					/** Don't include the root user */
 | 
				
			||||||
#define USERS_QUERY_NO_ROOT " AND user.user NOT IN ('root')"
 | 
					#define USERS_QUERY_NO_ROOT " AND user.user NOT IN ('root')"
 | 
				
			||||||
@ -1087,12 +1088,18 @@ static bool have_mdev13453_problem(MYSQL* con, SERVER* server)
 | 
				
			|||||||
    return rval;
 | 
					    return rval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool query_and_process_users(const char* query,
 | 
					// Contains loaded user definitions, only used temporarily
 | 
				
			||||||
                             MYSQL* con,
 | 
					struct User
 | 
				
			||||||
                             sqlite3* handle,
 | 
					{
 | 
				
			||||||
                             SERVICE* service,
 | 
					    std::string user;
 | 
				
			||||||
                             int* users,
 | 
					    std::string host;
 | 
				
			||||||
                             server_category_t category)
 | 
					    std::string db;
 | 
				
			||||||
 | 
					    bool        anydb;
 | 
				
			||||||
 | 
					    std::string pw;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool query_and_process_users(const char* query, MYSQL* con, SERVICE* service, int* users,
 | 
				
			||||||
 | 
					                             std::vector<User>* userlist, server_category_t category)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Clustrix does not have a mysql database. If non-clustrix we set the
 | 
					    // Clustrix does not have a mysql database. If non-clustrix we set the
 | 
				
			||||||
    // default database in case CTEs are used.
 | 
					    // default database in case CTEs are used.
 | 
				
			||||||
@ -1118,8 +1125,9 @@ bool query_and_process_users(const char* query,
 | 
				
			|||||||
                    merge_netmask(row[1]);
 | 
					                    merge_netmask(row[1]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                add_mysql_user(handle, row[0], row[1], row[2],
 | 
					                userlist->push_back({row[0], row[1], row[2] ? row[2] : "",
 | 
				
			||||||
                               row[3] && strcmp(row[3], "Y") == 0, row[4]);
 | 
					                                     row[3] && strcmp(row[3], "Y") == 0,
 | 
				
			||||||
 | 
					                                     row[4] ? row[4] : ""});
 | 
				
			||||||
                (*users)++;
 | 
					                (*users)++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1158,10 +1166,11 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service,
 | 
				
			|||||||
    char* query = get_users_query(server_version, service->enable_root, category);
 | 
					    char* query = get_users_query(server_version, service->enable_root, category);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MYSQL_AUTH* instance = (MYSQL_AUTH*)listener->auth_instance();
 | 
					    MYSQL_AUTH* instance = (MYSQL_AUTH*)listener->auth_instance();
 | 
				
			||||||
    sqlite3* handle = get_handle(instance);
 | 
					 | 
				
			||||||
    int users = 0;
 | 
					    int users = 0;
 | 
				
			||||||
 | 
					    std::vector<User> userlist;
 | 
				
			||||||
 | 
					    std::vector<std::string> dblist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool rv = query_and_process_users(query, con, handle, service, &users, category);
 | 
					    bool rv = query_and_process_users(query, con, service, &users, &userlist, category);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!rv && have_mdev13453_problem(con, server))
 | 
					    if (!rv && have_mdev13453_problem(con, server))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -1171,7 +1180,7 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service,
 | 
				
			|||||||
         */
 | 
					         */
 | 
				
			||||||
        MXS_FREE(query);
 | 
					        MXS_FREE(query);
 | 
				
			||||||
        query = get_users_query(server_version, service->enable_root, SERVER_ROLES);
 | 
					        query = get_users_query(server_version, service->enable_root, SERVER_ROLES);
 | 
				
			||||||
        rv = query_and_process_users(query, con, handle, service, &users, SERVER_ROLES);
 | 
					        rv = query_and_process_users(query, con, service, &users, &userlist, SERVER_ROLES);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!rv)
 | 
					    if (!rv)
 | 
				
			||||||
@ -1190,7 +1199,7 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service,
 | 
				
			|||||||
            MYSQL_ROW row;
 | 
					            MYSQL_ROW row;
 | 
				
			||||||
            while ((row = mysql_fetch_row(result)))
 | 
					            while ((row = mysql_fetch_row(result)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                add_database(handle, row[0]);
 | 
					                dblist.push_back(row[0]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mysql_free_result(result);
 | 
					            mysql_free_result(result);
 | 
				
			||||||
@ -1198,9 +1207,30 @@ int get_users_from_server(MYSQL* con, SERVER_REF* server_ref, SERVICE* service,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        rv = false;
 | 
				
			||||||
        MXS_ERROR("Failed to load list of databases: %s", mysql_error(con));
 | 
					        MXS_ERROR("Failed to load list of databases: %s", mysql_error(con));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rv)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        auto func = [instance, userlist, dblist]() {
 | 
				
			||||||
 | 
					                sqlite3* handle = get_handle(instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (const auto& user : userlist)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add_mysql_user(handle, user.user.c_str(), user.host.c_str(),
 | 
				
			||||||
 | 
					                                   user.db.c_str(), user.anydb, user.pw.c_str());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (const auto& db : dblist)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add_database(handle, db.c_str());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mxs::RoutingWorker::broadcast(func, mxs::RoutingWorker::EXECUTE_AUTO);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return users;
 | 
					    return users;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user