/** * Allocate a new service for the gateway to support * * * @param servname The service name * @param router Name of the router module this service uses * * @return The newly created service or NULL if an error occured */ SERVICE * service_alloc(char *servname, char *router) { SERVICE *service; if ((service = (SERVICE *)malloc(sizeof(SERVICE))) == NULL) return NULL; if ((service->router = load_module(router, MODULE_ROUTER)) == NULL) { char* home = get_maxscale_home(); char* ldpath = getenv("LD_LIBRARY_PATH"); LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Unable to load %s module \"%s\".\n\t\t\t" " Ensure that lib%s.so exists in one of the " "following directories :\n\t\t\t " "- %s/modules\n\t\t\t - %s", MODULE_ROUTER, router, router, home, ldpath))); free(service); return NULL; } service->name = strdup(servname); service->routerModule = strdup(router); service->version_string = NULL; memset(&service->stats, 0, sizeof(SERVICE_STATS)); service->ports = NULL; service->stats.started = time(0); service->state = SERVICE_STATE_ALLOC; service->credentials.name = NULL; service->credentials.authdata = NULL; service->enable_root = 0; service->routerOptions = NULL; service->databases = NULL; service->svc_config_param = NULL; service->svc_config_version = 0; service->filters = NULL; service->n_filters = 0; service->weightby = 0; spinlock_init(&service->spin); spinlock_init(&service->users_table_spin); memset(&service->rate_limit, 0, sizeof(SERVICE_REFRESH_RATE)); spinlock_acquire(&service_spin); service->next = allServices; allServices = service; spinlock_release(&service_spin); return service; }
/** * Allocate a new service for the gateway to support * * * @param servname The service name * @param router Name of the router module this service uses * * @return The newly created service or NULL if an error occurred */ SERVICE * service_alloc(const char *servname, const char *router) { SERVICE *service; if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) return NULL; if ((service->router = load_module(router, MODULE_ROUTER)) == NULL) { char* home = get_maxscale_home(); char* ldpath = getenv("LD_LIBRARY_PATH"); LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Unable to load %s module \"%s\".\n\t\t\t" " Ensure that lib%s.so exists in one of the " "following directories :\n\t\t\t " "- %s/modules\n\t\t\t - %s", MODULE_ROUTER, router, router, home, ldpath))); free(service); return NULL; } service->name = strdup(servname); service->routerModule = strdup(router); service->users_from_all = false; service->resources = NULL; if (service->name == NULL || service->routerModule == NULL) { if (service->name) free(service->name); free(service); return NULL; } service->stats.started = time(0); service->state = SERVICE_STATE_ALLOC; spinlock_init(&service->spin); spinlock_init(&service->users_table_spin); spinlock_acquire(&service_spin); service->next = allServices; allServices = service; spinlock_release(&service_spin); return service; }
/** * Load the dynamic library related to a gateway module. The routine * will look for library files in the current directory, * $MAXSCALE_HOME/modules and /usr/local/skysql/MaxScale/modules. * * @param module Name of the module to load * @param type Type of module, used purely for registration * @return The module specific entry point structure or NULL */ void * load_module(const char *module, const char *type) { char *home, *version; char fname[MAXPATHLEN]; void *dlhandle, *sym; char *(*ver)(); void *(*ep)(), *modobj; MODULES *mod; MODULE_INFO *mod_info = NULL; if ((mod = find_module(module)) == NULL) { /*< * The module is not already loaded * * Search of the shared object. */ sprintf(fname, "./lib%s.so", module); if (access(fname, F_OK) == -1) { home = get_maxscale_home (); sprintf(fname, "%s/modules/lib%s.so", home, module); if (access(fname, F_OK) == -1) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Unable to find library for " "module: %s.", module))); return NULL; } } if ((dlhandle = dlopen(fname, RTLD_NOW|RTLD_LOCAL)) == NULL) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Unable to load library for module: " "%s\n\n\t\t %s." "\n\n", module, dlerror()))); return NULL; } if ((sym = dlsym(dlhandle, "version")) == NULL) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Version interface not supported by " "module: %s\n\t\t\t %s.", module, dlerror()))); dlclose(dlhandle); return NULL; } ver = sym; version = ver(); /* * If the module has a ModuleInit function cal it now. */ if ((sym = dlsym(dlhandle, "ModuleInit")) != NULL) { void (*ModuleInit)() = sym; ModuleInit(); } if ((sym = dlsym(dlhandle, "info")) != NULL) { int fatal = 0; mod_info = sym; if (strcmp(type, MODULE_PROTOCOL) == 0 && mod_info->modapi != MODULE_API_PROTOCOL) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Module '%s' does not implement " "the protocol API.\n", module))); fatal = 1; } if (strcmp(type, MODULE_ROUTER) == 0 && mod_info->modapi != MODULE_API_ROUTER) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Module '%s' does not implement " "the router API.\n", module))); fatal = 1; } if (strcmp(type, MODULE_MONITOR) == 0 && mod_info->modapi != MODULE_API_MONITOR) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Module '%s' does not implement " "the monitor API.\n", module))); fatal = 1; } if (strcmp(type, MODULE_FILTER) == 0 && mod_info->modapi != MODULE_API_FILTER) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Module '%s' does not implement " "the filter API.\n", module))); fatal = 1; } if (fatal) { dlclose(dlhandle); return NULL; } } if ((sym = dlsym(dlhandle, "GetModuleObject")) == NULL) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Expected entry point interface missing " "from module: %s\n\t\t\t %s.", module, dlerror()))); dlclose(dlhandle); return NULL; } ep = sym; modobj = ep(); LOGIF(LM, (skygw_log_write_flush( LOGFILE_MESSAGE, "Loaded module %s: %s from %s", module, version, fname))); register_module(module, type, dlhandle, version, modobj, mod_info); } else { /* * The module is already loaded, get the entry points again and * return a reference to the already loaded module. */ modobj = mod->modobj; } return modobj; }