static str SQLinit(void) { char *debug_str = GDKgetenv("sql_debug"), *msg = MAL_SUCCEED; int readonly = GDKgetenv_isyes("gdk_readonly"); int single_user = GDKgetenv_isyes("gdk_single_user"); const char *gmt = "GMT"; tzone tz; #ifdef _SQL_SCENARIO_DEBUG mnstr_printf(GDKout, "#SQLinit Monet 5\n"); #endif if (SQLinitialized) return MAL_SUCCEED; #ifdef NEED_MT_LOCK_INIT MT_lock_init(&sql_contextLock, "sql_contextLock"); #endif MT_lock_set(&sql_contextLock); memset((char *) &be_funcs, 0, sizeof(backend_functions)); be_funcs.fstack = &monet5_freestack; be_funcs.fcode = &monet5_freecode; be_funcs.fresolve_function = &monet5_resolve_function; monet5_user_init(&be_funcs); msg = MTIMEtimezone(&tz, &gmt); if (msg) return msg; (void) tz; if (debug_str) SQLdebug = strtol(debug_str, NULL, 10); if (single_user) SQLdebug |= 64; if (readonly) SQLdebug |= 32; if ((SQLnewcatalog = mvc_init(SQLdebug, store_bat, readonly, single_user, 0)) < 0) throw(SQL, "SQLinit", "Catalogue initialization failed"); SQLinitialized = TRUE; MT_lock_unset(&sql_contextLock); if (MT_create_thread(&sqllogthread, (void (*)(void *)) mvc_logmanager, NULL, MT_THR_DETACHED) != 0) { throw(SQL, "SQLinit", "Starting log manager failed"); } #if 0 if (MT_create_thread(&minmaxthread, (void (*)(void *)) mvc_minmaxmanager, NULL, MT_THR_DETACHED) != 0) { throw(SQL, "SQLinit", "Starting minmax manager failed"); } #endif return MAL_SUCCEED; }
static int monet_init(opt *set, int setlen) { /* determine Monet's kernel settings */ if (GDKinit(set, setlen) != GDK_SUCCEED) return 0; #ifdef HAVE_CONSOLE monet_daemon = false; if (GDKgetenv_isyes("monet_daemon")) { monet_daemon = true; #ifdef HAVE_SETSID setsid(); #endif } #endif monet_hello(); return 1; }
static bool RAPIEnabled(void) { return (GDKgetenv_istrue(rapi_enableflag) || GDKgetenv_isyes(rapi_enableflag)); }
void MSscheduleClient(str command, str challenge, bstream *fin, stream *fout) { char *user = command, *algo = NULL, *passwd = NULL, *lang = NULL; char *database = NULL, *s, *dbname; Client c; /* decode BIG/LIT:user:{cypher}passwordchal:lang:database: line */ /* byte order */ s = strchr(user, ':'); if (s) { *s = 0; mnstr_set_byteorder(fin->s, strcmp(user, "BIG") == 0); user = s + 1; } else { mnstr_printf(fout, "!incomplete challenge '%s'\n", user); exit_streams(fin, fout); GDKfree(command); return; } /* passwd */ s = strchr(user, ':'); if (s) { *s = 0; passwd = s + 1; /* decode algorithm, i.e. {plain}mypasswordchallenge */ if (*passwd != '{') { mnstr_printf(fout, "!invalid password entry\n"); exit_streams(fin, fout); GDKfree(command); return; } algo = passwd + 1; s = strchr(algo, '}'); if (!s) { mnstr_printf(fout, "!invalid password entry\n"); exit_streams(fin, fout); GDKfree(command); return; } *s = 0; passwd = s + 1; } else { mnstr_printf(fout, "!incomplete challenge '%s'\n", user); exit_streams(fin, fout); GDKfree(command); return; } /* lang */ s = strchr(passwd, ':'); if (s) { *s = 0; lang = s + 1; } else { mnstr_printf(fout, "!incomplete challenge, missing language\n"); exit_streams(fin, fout); GDKfree(command); return; } /* database */ s = strchr(lang, ':'); if (s) { *s = 0; database = s + 1; /* we can have stuff following, make it void */ s = strchr(database, ':'); if (s) *s = 0; } dbname = GDKgetenv("gdk_dbname"); if (database != NULL && database[0] != '\0' && strcmp(database, dbname) != 0) { mnstr_printf(fout, "!request for database '%s', " "but this is database '%s', " "did you mean to connect to monetdbd instead?\n", database, dbname); /* flush the error to the client, and abort further execution */ exit_streams(fin, fout); GDKfree(command); return; } else { str err; oid uid; sabdb *stats = NULL; Client root = &mal_clients[0]; /* access control: verify the credentials supplied by the user, * no need to check for database stuff, because that is done per * database itself (one gets a redirect) */ err = AUTHcheckCredentials(&uid, root, &user, &passwd, &challenge, &algo); if (err != MAL_SUCCEED) { mnstr_printf(fout, "!%s\n", err); exit_streams(fin, fout); GDKfree(err); GDKfree(command); return; } err = SABAOTHgetMyStatus(&stats); if (err != MAL_SUCCEED) { /* this is kind of awful, but we need to get rid of this * message */ fprintf(stderr, "!SABAOTHgetMyStatus: %s\n", err); if (err != M5OutOfMemory) GDKfree(err); mnstr_printf(fout, "!internal server error, " "please try again later\n"); exit_streams(fin, fout); GDKfree(command); return; } if (stats->locked == 1) { if (uid == 0) { mnstr_printf(fout, "#server is running in " "maintenance mode\n"); } else { mnstr_printf(fout, "!server is running in " "maintenance mode, please try again later\n"); exit_streams(fin, fout); SABAOTHfreeStatus(&stats); GDKfree(command); return; } } SABAOTHfreeStatus(&stats); c = MCinitClient(uid, fin, fout); if (c == NULL) { if ( MCshutdowninprogress()) mnstr_printf(fout, "!system shutdown in progress, please try again later\n"); else mnstr_printf(fout, "!maximum concurrent client limit reached " "(%d), please try again later\n", MAL_MAXCLIENTS); exit_streams(fin, fout); GDKfree(command); return; } /* move this back !! */ if (c->nspace == 0) { c->nspace = newModule(NULL, putName("user", 4)); c->nspace->outer = mal_clients[0].nspace->outer; } if ((s = setScenario(c, lang)) != NULL) { mnstr_printf(c->fdout, "!%s\n", s); mnstr_flush(c->fdout); GDKfree(s); c->mode = FINISHCLIENT; } if (!GDKgetenv_isyes(mal_enableflag) && (strncasecmp("sql", lang, 3) != 0 && uid != 0)) { mnstr_printf(fout, "!only the 'monetdb' user can use non-sql languages. " "run mserver5 with --set %s=yes to change this.\n", mal_enableflag); exit_streams(fin, fout); GDKfree(command); return; } } MSinitClientPrg(c, "user", "main"); GDKfree(command); /* NOTE ABOUT STARTING NEW THREADS * At this point we have conducted experiments (Jun 2012) with * reusing threads. The implementation used was a lockless array of * semaphores to wake up threads to do work. Experimentation on * Linux, Solaris and Darwin showed no significant improvements, in * most cases no improvements at all. Hence the following * conclusion: thread reuse doesn't save up on the costs of just * forking new threads. Since the latter means no difficulties of * properly maintaining a pool of threads and picking the workers * out of them, it is favourable just to start new threads on * demand. */ /* fork a new thread to handle this client */ mnstr_settimeout(c->fdin->s, 50, GDKexiting); MSserveClient(c); }