int malLibraryEnabled(str name) { if (strcmp(name, "pyapi") == 0) { const char *val = GDKgetenv("embedded_py"); return val && (strcmp(val, "2") == 0 || strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0); } else if (strcmp(name, "pyapi3") == 0) { const char *val = GDKgetenv("embedded_py"); return val && strcasecmp(val, "3") == 0; } return true; }
bool MCinit(void) { const char *max_clients = GDKgetenv("max_clients"); int maxclients = 0; if (max_clients != NULL) maxclients = atoi(max_clients); if (maxclients <= 0) { maxclients = 64; if (GDKsetenv("max_clients", "64") != GDK_SUCCEED) { fprintf(stderr,"#MCinit: GDKsetenv failed"); return false; } } MAL_MAXCLIENTS = /* console */ 1 + /* client connections */ maxclients; mal_clients = GDKzalloc(sizeof(ClientRec) * MAL_MAXCLIENTS); if( mal_clients == NULL){ fprintf(stderr,"#MCinit:" MAL_MALLOC_FAIL); return false; } for (int i = 0; i < MAL_MAXCLIENTS; i++) ATOMIC_INIT(&mal_clients[i].lastprint, 0); return true; }
static int BATlocation(str *fnme, int *bid) { /* this function was formerly ATTlocation in removed file * monetdb5/modules/mal/attach.c */ BAT *b = BBPquickdesc(*bid, FALSE); char path[BUFSIZ], *s; *fnme = NULL; if (b == NULL || (!b->T->heap.filename && !b->H->heap.filename)) return 0; s = GDKfilepath(b->T->heap.farmid, BATDIR, (b->T->heap.filename ? b->T->heap.filename : b->H->heap.filename), 0); if (!MT_path_absolute(s)) { snprintf(path, BUFSIZ, "%s%c%s", GDKgetenv("gdk_dbpath"), DIR_SEP, s); } else { snprintf(path, sizeof(path), "%s", s); } GDKfree(s); s = strrchr(path, '.'); if (s) *s = 0; *fnme = GDKstrdup(path); return 1; }
int GDKgetenv_int(const char *name, int def) { char *val = GDKgetenv(name); if (val) return atoi(val); return def; }
int GDKgetenv_istrue(const char *name) { char *val = GDKgetenv(name); if (val && strcasecmp(val, "true") == 0) { return 1; } return 0; }
Client MCinitClientRecord(Client c, oid user, bstream *fin, stream *fout) { str prompt; c->user = user; c->username = 0; c->scenario = NULL; c->oldscenario = NULL; c->srcFile = NULL; c->blkmode = 0; c->fdin = fin ? fin : bstream_create(GDKin, 0); c->yycur = 0; c->bak = NULL; c->listing = 0; c->fdout = fout ? fout : GDKstdout; c->mdb = 0; c->history = 0; c->curprg = c->backup = 0; c->glb = 0; /* remove garbage from previous connection */ if (c->nspace) { freeModule(c->nspace); c->nspace = 0; } c->father = NULL; c->login = c->lastcmd = time(0); //c->active = 0; c->session = GDKusec(); c->qtimeout = 0; c->stimeout = 0; c->stage = 0; c->itrace = 0; c->debugOptimizer = c->debugScheduler = 0; c->flags = MCdefault; c->errbuf = 0; prompt = !fin ? GDKgetenv("monet_prompt") : PROMPT1; c->prompt = GDKstrdup(prompt); c->promptlength = strlen(prompt); c->actions = 0; c->totaltime = 0; /* create a recycler cache */ c->exception_buf_initialized = 0; c->error_row = c->error_fld = c->error_msg = c->error_input = NULL; (void) AUTHgetUsername(&c->username, c); MT_sema_init(&c->s, 0, "Client->s"); return c; }
static void monet_hello(void) { #ifdef MONETDB_STATIC char *linkinfo = "statically"; #else char *linkinfo = "dynamically"; #endif dbl sz_mem_h; char *qc = " kMGTPE"; int qi = 0; monet_memory = MT_npages() * MT_pagesize(); sz_mem_h = (dbl) monet_memory; while (sz_mem_h >= 1000.0 && qi < 6) { sz_mem_h /= 1024.0; qi++; } printf("# MonetDB 5 server v" VERSION); if (strcmp(MONETDB_RELEASE, "unreleased") == 0) printf("\n# This is an unreleased version"); else printf(" \"%s\"", MONETDB_RELEASE); printf("\n# Serving database '%s', using %d thread%s\n", GDKgetenv("gdk_dbname"), GDKnr_threads, (GDKnr_threads != 1) ? "s" : ""); printf("# Compiled for %s/" SZFMT "bit with " SZFMT "bit OIDs %s linked\n", HOST, sizeof(ptr) * 8, sizeof(oid) * 8, linkinfo); printf("# Found %.3f %ciB available main-memory.\n", sz_mem_h, qc[qi]); #ifdef MONET_GLOBAL_DEBUG printf("# Database path:%s\n", GDKgetenv("gdk_dbpath")); printf("# Module path:%s\n", GDKgetenv("monet_mod_path")); #endif printf("# Copyright (c) 1993-July 2008 CWI.\n"); printf("# Copyright (c) August 2008-2013 MonetDB B.V., all rights reserved\n"); printf("# Visit http://www.monetdb.org/ for further information\n"); }
Client MCinitClientRecord(Client c, oid user, bstream *fin, stream *fout) { str prompt; c->user = user; c->scenario = NULL; c->oldscenario = NULL; c->srcFile = NULL; c->blkmode = 0; c->fdin = fin ? fin : bstream_create(GDKin, 0); c->yycur = 0; c->bak = NULL; c->listing = 0; c->fdout = fout ? fout : GDKstdout; c->mdb = 0; c->history = 0; c->curprg = c->backup = 0; c->glb = 0; /* remove garbage from previous connection */ if (c->nspace) { freeModule(c->nspace); c->nspace = 0; } c->father = NULL; c->login = c->lastcmd = time(0); c->qtimeout = 0; c->stimeout = 0; c->stage = 0; c->itrace = 0; c->debugOptimizer = c->debugScheduler = 0; c->flags = MCdefault; c->timer = 0; c->memory = 0; c->errbuf = 0; prompt = !fin ? GDKgetenv("monet_prompt") : PROMPT1; c->prompt = GDKstrdup(prompt); c->promptlength = strlen(prompt); c->actions = 0; c->totaltime = 0; c->rcc = (RecPtr) GDKzalloc(sizeof(RecStat)); c->rcc->curQ = -1; c->exception_buf_initialized = 0; MT_sema_init(&c->s, 0, "MCinitClient"); return c; }
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 char *RAPIinstalladdons(void) { int evalErr; ParseStatus status; char rlibs[FILENAME_MAX]; char rapiinclude[BUFSIZ]; SEXP librisexp; int len; // r library folder, create if not exists len = snprintf(rlibs, sizeof(rlibs), "%s%c%s", GDKgetenv("gdk_dbpath"), DIR_SEP, "rapi_packages"); if (len == -1 || len >= FILENAME_MAX) return "cannot create rapi_packages directory because the path is too large"; if (mkdir(rlibs, S_IRWXU) != 0 && errno != EEXIST) { return "cannot create rapi_packages directory"; } #ifdef _RAPI_DEBUG_ printf("# R libraries installed in %s\n",rlibs); #endif PROTECT(librisexp = allocVector(STRSXP, 1)); SET_STRING_ELT(librisexp, 0, mkChar(rlibs)); Rf_defineVar(Rf_install(".rapi.libdir"), librisexp, R_GlobalEnv); UNPROTECT(1); // run rapi.R environment setup script { char *f = locate_file("rapi", ".R", 0); snprintf(rapiinclude, sizeof(rapiinclude), "source(\"%s\")", f); GDKfree(f); } #if DIR_SEP != '/' { char *p; for (p = rapiinclude; *p; p++) if (*p == DIR_SEP) *p = '/'; } #endif R_tryEvalSilent( VECTOR_ELT( R_ParseVector(mkString(rapiinclude), 1, &status, R_NilValue), 0), R_GlobalEnv, &evalErr); // of course the script may contain errors as well if (evalErr != FALSE) { return "failure running R setup script"; } return NULL; }
str SQLprelude(void *ret) { str tmp; Scenario ms, s = getFreeScenario(); (void) ret; if (!s) throw(MAL, "sql.start", "out of scenario slots"); sqlinit = GDKgetenv("sqlinit"); s->name = "S_Q_L"; s->language = "sql"; s->initSystem = NULL; s->exitSystem = "SQLexit"; s->initClient = "SQLinitClient"; s->exitClient = "SQLexitClient"; s->reader = "SQLreader"; s->parser = "SQLparser"; s->engine = "SQLengine"; ms = getFreeScenario(); if (!ms) throw(MAL, "sql.start", "out of scenario slots"); ms->name = "M_S_Q_L"; ms->language = "msql"; ms->initSystem = NULL; ms->exitSystem = "SQLexit"; ms->initClient = "SQLinitClient"; ms->exitClient = "SQLexitClient"; ms->reader = "MALreader"; ms->parser = "MALparser"; ms->optimizer = "MALoptimizer"; /* ms->tactics = .. */ ms->engine = "MALengine"; tmp = SQLinit(); if (tmp != MAL_SUCCEED) return (tmp); fprintf(stdout, "# MonetDB/SQL module loaded\n"); fflush(stdout); /* make merovingian see this *now* */ /* only register availability of scenarios AFTER we are inited! */ s->name = "sql"; tmp = msab_marchScenario(s->name); if (tmp != MAL_SUCCEED) return (tmp); ms->name = "msql"; tmp = msab_marchScenario(ms->name); return tmp; }
void MCinit(void) { char *max_clients = GDKgetenv("max_clients"); int maxclients = 0; if (max_clients != NULL) maxclients = atoi(max_clients); if (maxclients <= 0) { maxclients = 64; GDKsetenv("max_clients", "64"); } MAL_MAXCLIENTS = /* console */ 1 + /* client connections */ maxclients; mal_clients = GDKzalloc(sizeof(ClientRec) * MAL_MAXCLIENTS); }
/* initialize the global variable, ie make mvc point to these */ static int global_variables(mvc *sql, char *user, char *schema) { sql_subtype ctype; char *typename; lng sec = 0; bit F = FALSE; ValRecord src; str opt; typename = "int"; sql_find_subtype(&ctype, typename, 0, 0); SQLglobal("debug", &sql->debug); SQLglobal("cache", &sql->cache); typename = "varchar"; sql_find_subtype(&ctype, typename, 1024, 0); SQLglobal("current_schema", schema); SQLglobal("current_user", user); SQLglobal("current_role", user); /* inherit the optimizer from the server */ opt = GDKgetenv("sql_optimizer"); if (!opt) opt = "default_pipe"; SQLglobal("optimizer", opt); typename = "sec_interval"; sql_find_subtype(&ctype, typename, inttype2digits(ihour, isec), 0); SQLglobal("current_timezone", &sec); typename = "boolean"; sql_find_subtype(&ctype, typename, 0, 0); SQLglobal("history", &F); typename = "bigint"; sql_find_subtype(&ctype, typename, 0, 0); SQLglobal("last_id", &sql->last_id); SQLglobal("rowcnt", &sql->rowcnt); return 0; }
str SQLsession(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { str msg = MAL_SUCCEED; str logmsg; int cnt=0; (void) mb; (void) stk; (void) pci; if (SQLinitialized == 0 && (msg = SQLprelude(NULL)) != MAL_SUCCEED) return msg; msg = setScenario(cntxt, "sql"); // Wait for any recovery process to be finished do { MT_sleep_ms(1000); logmsg = GDKgetenv("recovery"); if( logmsg== NULL && ++cnt == 5) throw(SQL,"SQLinit","#WARNING server not ready, recovery in progress\n"); }while (logmsg == NULL); return msg; }
void MCinit(void) { char *max_clients = GDKgetenv("max_clients"); int maxclients = 0; if (max_clients != NULL) maxclients = atoi(max_clients); if (maxclients <= 0) { maxclients = 64; GDKsetenv("max_clients", "64"); } MAL_MAXCLIENTS = /* console */ 1 + /* client connections */ maxclients; mal_clients = GDKzalloc(sizeof(ClientRec) * MAL_MAXCLIENTS); if( mal_clients == NULL){ showException(GDKout, MAL, "MCinit",MAL_MALLOC_FAIL); mal_exit(); } }
/* * Collect some global system properties to relate performance results later */ static void monet_hello(void) { dbl sz_mem_h; char *qc = " kMGTPE"; int qi = 0; monet_memory = MT_npages() * MT_pagesize(); sz_mem_h = (dbl) monet_memory; while (sz_mem_h >= 1000.0 && qi < 6) { sz_mem_h /= 1024.0; qi++; } printf("# MonetDB 5 server v%s", GDKversion()); { #ifdef MONETDB_RELEASE printf(" (%s)", MONETDB_RELEASE); #else const char *rev = mercurial_revision(); if (strcmp(rev, "Unknown") != 0) printf(" (hg id: %s)", rev); #endif } #ifndef MONETDB_RELEASE printf("\n# This is an unreleased version"); #endif printf("\n# Serving database '%s', using %d thread%s\n", GDKgetenv("gdk_dbname"), GDKnr_threads, (GDKnr_threads != 1) ? "s" : ""); printf("# Compiled for %s/%zubit%s\n", HOST, sizeof(ptr) * 8, #ifdef HAVE_HGE " with 128bit integers" #else "" #endif ); printf("# Found %.3f %ciB available main-memory.\n", sz_mem_h, qc[qi]); #ifdef MONET_GLOBAL_DEBUG printf("# Database path:%s\n", GDKgetenv("gdk_dbpath")); printf("# Module path:%s\n", GDKgetenv("monet_mod_path")); #endif printf("# Copyright (c) 1993 - July 2008 CWI.\n"); printf("# Copyright (c) August 2008 - 2019 MonetDB B.V., all rights reserved\n"); printf("# Visit https://www.monetdb.org/ for further information\n"); // The properties shipped through the performance profiler (void) snprintf(monet_characteristics, sizeof(monet_characteristics), "{\n" "\"version\":\"%s\",\n" "\"release\":\"%s\",\n" "\"host\":\"%s\",\n" "\"threads\":\"%d\",\n" "\"memory\":\"%.3f %cB\",\n" "\"oid\":\"%zu\",\n" "\"packages\":[" #ifdef HAVE_HGE "\"huge\"" #endif "]\n}", GDKversion(), #ifdef MONETDB_RELEASE MONETDB_RELEASE, #else "unreleased", #endif HOST, GDKnr_threads, sz_mem_h, qc[qi], sizeof(oid) * 8); }
void optimizerInit(void) { assert(batRef == NULL); abortRef = putName("abort",5); affectedRowsRef = putName("affectedRows",12); aggrRef = putName("aggr",4); alarmRef = putName("alarm",5); algebraRef = putName("algebra",7); appendidxRef = putName("append_idxbat",13); appendRef = putName("append",6); assertRef = putName("assert",6); attachRef = putName("attach",6); avgRef = putName("avg",3); arrayRef = putName("array",4); batcalcRef = putName("batcalc",7); basketRef = putName("basket",6); boxRef = putName("box",3); batstrRef = putName("batstr",6); batmtimeRef = putName("batmtime",8); batmmathRef = putName("batmmath",8); batxmlRef = putName("batxml",6); bbpRef = putName("bbp",3); tidRef = putName("tid",3); deltaRef = putName("delta",5); subdeltaRef = putName("subdelta",8); projectdeltaRef = putName("projectdelta",12); binddbatRef = putName("bind_dbat",9); bindidxRef = putName("bind_idxbat",11); bindRef = putName("bind",4); bpmRef = putName("bpm",3); bstreamRef = putName("bstream",7); calcRef = putName("calc",4); catalogRef = putName("catalog",7); centipedeRef = putName("centipede",9); clear_tableRef = putName("clear_table",11); closeRef = putName("close",5); columnRef = putName("column",6); columnBindRef = putName("columnBind",10); commitRef = putName("commit",6); connectRef = putName("connect",7); constraintsRef = putName("constraints",11); countRef = putName("count",5); subcountRef = putName("subcount",8); copyRef = putName("copy",4); copy_fromRef = putName("copy_from",9); count_no_nilRef = putName("count_no_nil",12); crossRef = putName("crossproduct",12); createRef = putName("create",6); dateRef = putName("date",4); datacellRef = putName("datacell",8); dataflowRef = putName("dataflow",8); datacyclotronRef = putName("datacyclotron",13); dblRef = putName("dbl",3); deleteRef = putName("delete",6); depositRef = putName("deposit",7); differenceRef= putName("difference",10); tdifferenceRef= putName("tdifference",11); tintersectRef= putName("tintersect",10); tdiffRef= putName("tdiff",5); tinterRef= putName("tinter",6); mergecandRef= putName("mergecand",9); mergepackRef= putName("mergepack",9); intersectcandRef= putName("intersectcand",13); eqRef = putName("==",2); disconnectRef= putName("disconnect",10); evalRef = putName("eval",4); execRef = putName("exec",4); expandRef = putName("expand",6); exportOperationRef = putName("exportOperation",15); finishRef = putName("finish",6); firstnRef = putName("firstn",6); getRef = putName("get",3); generatorRef = putName("generator",9); grabRef = putName("grab",4); groupRef = putName("group",5); subgroupRef = putName("subgroup",8); subgroupdoneRef= putName("subgroupdone",12); groupsRef = putName("groups",6); groupbyRef = putName("groupby",7); hashRef = putName("hash",4); identityRef = putName("identity",8); ifthenelseRef = putName("ifthenelse",10); inplaceRef = putName("inplace",7); insertRef = putName("insert",6); intRef = putName("int",3); ioRef = putName("io",2); iteratorRef = putName("iterator",8); joinPathRef = putName("joinPath",8); joinRef = putName("join",4); antijoinRef = putName("antijoin",8); bandjoinRef = putName("bandjoin",8); thetajoinRef = putName("thetajoin",9); subjoinRef = putName("subjoin",7); subantijoinRef = putName("subantijoin",11); subbandjoinRef = putName("subbandjoin",11); subthetajoinRef = putName("subthetajoin",12); jsonRef = putName("json",4); kdifferenceRef= putName("kdifference",11); kunionRef= putName("kunion",6); languageRef= putName("language",8); leftfetchjoinRef = putName("leftfetchjoin",13); leftfetchjoinPathRef = putName("leftfetchjoinPath",17); leftjoinRef = putName("leftjoin",8); leftjoinPathRef = putName("leftjoinPath",12); likeselectRef = putName("like_select",11); ilikeselectRef = putName("ilike_select",12); likeuselectRef = putName("like_uselect",12); ilikeuselectRef = putName("ilike_uselect",13); listRef = putName("list",4); likeRef = putName("like",4); ilikeRef = putName("ilike",5); not_likeRef = putName("not_like",8); not_ilikeRef = putName("not_ilike",9); lockRef = putName("lock",4); lookupRef = putName("lookup",6); malRef = putName("mal", 3); mapiRef = putName("mapi", 4); markHRef = putName("markH", 5); markTRef = putName("markT", 5); mark_grpRef = putName("mark_grp", 8); materializeRef = putName("materialize", 11); mtimeRef = putName("mtime", 5); multicolumnRef = putName("multicolumn", 11); dense_rank_grpRef = putName("dense_rank_grp", 14); matRef = putName("mat", 3); max_no_nilRef = putName("max_no_nil", 10); maxRef = putName("max", 3); submaxRef = putName("submax", 6); submedianRef = putName("submedian", 9); mdbRef = putName("mdb", 3); min_no_nilRef = putName("min_no_nil", 10); minRef = putName("min", 3); subminRef = putName("submin", 6); mirrorRef = putName("mirror", 6); mitosisRef = putName("mitosis", 7); mkeyRef = putName("mkey", 4); mmathRef = putName("mmath", 5); multiplexRef = putName("multiplex", 9); manifoldRef = putName("manifold", 8); mvcRef = putName("mvc", 3); newRef = putName("new",3); notRef = putName("not",3); nextRef = putName("next",4); oidRef = putName("oid",3); octopusRef = putName("octopus",7); optimizerRef = putName("optimizer",9); openRef = putName("open",4); parametersRef = putName("parameters",10); packRef = putName("pack",4); pack2Ref = putName("pack2",5); passRef = putName("pass",4); partitionRef = putName("partition",9); pcreRef = putName("pcre",4); pinRef = putName("pin",3); plusRef = putName("+",1); minusRef = putName("-",1); mulRef = putName("*",1); divRef = putName("/",1); printRef = putName("print",5); preludeRef = putName("prelude",7); prodRef = putName("prod",4); subprodRef = putName("subprod",7); profilerRef = putName("profiler",8); postludeRef = putName("postlude",8); projectRef = putName("project",7); putRef = putName("put",3); querylogRef = putName("querylog",8); queryRef = putName("query",5); rankRef = putName("rank", 4); rank_grpRef = putName("rank_grp", 8); rapiRef = putName("batrapi", 7); reconnectRef = putName("reconnect",9); recycleRef = putName("recycle",7); refineRef = putName("refine",6); refine_reverseRef = putName("refine_reverse",14); registerRef = putName("register",8); remapRef = putName("remap",5); remoteRef = putName("remote",6); replaceRef = putName("replace",7); replicatorRef = putName("replicator",10); resultSetRef = putName("resultSet",9); reuseRef = putName("reuse",5); reverseRef = putName("reverse",7); rpcRef = putName("rpc",3); rsColumnRef = putName("rsColumn",8); schedulerRef = putName("scheduler",9); selectNotNilRef = putName("selectNotNil",12); seriesRef = putName("series",6); semaRef = putName("sema",4); semijoinRef = putName("semijoin",8); semijoinPathRef = putName("semijoinPath",12); setAccessRef = putName("setAccess",9); setWriteModeRef= putName("setWriteMode",12); sinkRef = putName("sink",4); sliceRef = putName("slice",5); subsliceRef = putName("subslice",8); singleRef = putName("single",6); sortHRef = putName("sortH",5); sortHTRef = putName("sortHT",6); sortRef = putName("sort",4); sortReverseTailRef = putName("sortReverseTail",15); sortTailRef = putName("sortTail",8); sortTHRef = putName("sortTH",6); sqlRef = putName("sql",3); srvpoolRef = putName("srvpool",7); streamsRef = putName("streams",7); startRef = putName("start",5); stopRef = putName("stop",4); strRef = putName("str",3); sumRef = putName("sum",3); subsumRef = putName("subsum",6); subavgRef = putName("subavg",6); subsortRef = putName("subsort",7); takeRef= putName("take",5); timestampRef = putName("timestamp", 9); not_uniqueRef= putName("not_unique",10); unlockRef= putName("unlock",6); unpackRef = putName("unpack",6); unpinRef = putName("unpin",5); updateRef = putName("update",6); subselectRef = putName("subselect",9); thetasubselectRef = putName("thetasubselect",14); likesubselectRef = putName("likesubselect",13); ilikesubselectRef = putName("ilikesubselect",14); vectorRef = putName("vector",6); zero_or_oneRef = putName("zero_or_one",11); userRef = putName("user",4); canBeCrackedProp = PropertyIndex("canBeCracked"); canBeJoinselectProp = PropertyIndex("canBeJoinselect"); sidewaysSelectProp = PropertyIndex("sidewaysSelect"); headProp = PropertyIndex("head"); pivotProp = PropertyIndex("pivot"); pivotDisjunctiveProp = PropertyIndex("pivotDisjunctive"); removeProp = PropertyIndex("remove"); tableProp = PropertyIndex("table"); fileProp = PropertyIndex("file"); inlineProp = PropertyIndex("inline"); keepProp = PropertyIndex("keep"); notnilProp = PropertyIndex("notnil"); rowsProp = PropertyIndex("rows"); runonceProp = PropertyIndex("runonce"); unsafeProp = PropertyIndex("unsafe"); sqlfunctionProp = PropertyIndex("sqlfunction"); stableProp = PropertyIndex("stableProp"); insertionsProp = PropertyIndex("insertionsProp"); updatesProp = PropertyIndex("updatesProp"); deletesProp = PropertyIndex("deletesProp"); hlbProp = PropertyIndex("hlb"); hubProp = PropertyIndex("hub"); tlbProp = PropertyIndex("tlb"); tubProp = PropertyIndex("tub"); horiginProp = PropertyIndex("horigin"); toriginProp = PropertyIndex("torigin"); /* * @- * Set the optimizer debugging flag */ { int ret; str ref= GDKgetenv("opt_debug"); if ( ref) OPTsetDebugStr(&ret,&ref); } batRef = putName("bat",3); }
char * locate_file(const char *basename, const char *ext, bit recurse) { const char *mod_path = GDKgetenv("monet_mod_path"); char *fullname; size_t fullnamelen; size_t filelen = strlen(basename) + strlen(ext); str strs[MAXMULTISCRIPT]; /* hardwired limit */ int lasts = 0; if (mod_path == NULL) return NULL; while (*mod_path == PATH_SEP) mod_path++; if (*mod_path == 0) return NULL; fullnamelen = 512; fullname = GDKmalloc(fullnamelen); if (fullname == NULL) return NULL; while (*mod_path) { size_t i; const char *p; int fd; DIR *rdir; if ((p = strchr(mod_path, PATH_SEP)) != NULL) { i = p - mod_path; } else { i = strlen(mod_path); } while (i + filelen + 2 > fullnamelen) { char *tmp; fullnamelen += 512; tmp = GDKrealloc(fullname, fullnamelen); if (tmp == NULL) { GDKfree(fullname); return NULL; } fullname = tmp; } /* we are now sure the directory name, file base name, extension, and separator fit into fullname, so we don't need to do any extra checks */ strncpy(fullname, mod_path, i); fullname[i] = DIR_SEP; strcpy(fullname + i + 1, basename); /* see if this is a directory, if so, recurse */ if (recurse == 1 && (rdir = opendir(fullname)) != NULL) { struct dirent *e; /* list *ext, sort, return */ while ((e = readdir(rdir)) != NULL) { if (strcmp(e->d_name, "..") == 0 || strcmp(e->d_name, ".") == 0) continue; if (strcmp(e->d_name + strlen(e->d_name) - strlen(ext), ext) == 0) { int len; strs[lasts] = GDKmalloc(strlen(fullname) + sizeof(DIR_SEP) + strlen(e->d_name) + sizeof(PATH_SEP) + 1); if (strs[lasts] == NULL) { while (lasts >= 0) GDKfree(strs[lasts--]); GDKfree(fullname); (void)closedir(rdir); return NULL; } len = sprintf(strs[lasts], "%s%c%s%c", fullname, DIR_SEP, e->d_name, PATH_SEP); if (len == -1 || len >= FILENAME_MAX) { while (lasts >= 0) GDKfree(strs[lasts--]); GDKfree(fullname); (void)closedir(rdir); return NULL; } lasts++; } if (lasts >= MAXMULTISCRIPT) break; } (void)closedir(rdir); } else { strcat(fullname + i + 1, ext); if ((fd = open(fullname, O_RDONLY | O_CLOEXEC)) >= 0) { char *tmp; close(fd); tmp = GDKrealloc(fullname, strlen(fullname) + 1); if (tmp == NULL) GDKfree(fullname); return tmp; } } if ((mod_path = p) == NULL) break; while (*mod_path == PATH_SEP) mod_path++; } if (lasts > 0) { size_t i = 0; int c; char *tmp; /* assure that an ordering such as 10_first, 20_second works */ qsort(strs, lasts, sizeof(char *), cmpstr); for (c = 0; c < lasts; c++) i += strlen(strs[c]) + 1; /* PATH_SEP or \0 */ tmp = GDKrealloc(fullname, i); if( tmp == NULL){ GDKfree(fullname); return NULL; } fullname = tmp; i = 0; for (c = 0; c < lasts; c++) { if (strstr(fullname, strs[c]) == NULL) { strcpy(fullname + i, strs[c]); i += strlen(strs[c]); } GDKfree(strs[c]); } fullname[i - 1] = '\0'; return fullname; } /* not found */ GDKfree(fullname); return NULL; }
/* * CMDmodules * Obtains a list of modules by looking at what files are present in the * module directory. */ static BAT * TBL_getdir(void) { BAT *b = BATnew(TYPE_void, TYPE_str, 100, TRANSIENT); int i = 0; char *mod_path; size_t extlen = strlen(MAL_EXT); size_t len; struct dirent *dent; DIR *dirp = NULL; if ( b == 0) return 0; BATseqbase(b,0); mod_path = GDKgetenv("monet_mod_path"); if (mod_path == NULL) return b; while (*mod_path == PATH_SEP) mod_path++; if (*mod_path == 0) return b; while (mod_path || dirp) { if (dirp == NULL) { char *cur_dir; char *p; size_t l; if ((p = strchr(mod_path, PATH_SEP)) != NULL) { l = p - mod_path; } else { l = strlen(mod_path); } cur_dir = GDKmalloc(l + 1); if ( cur_dir == NULL){ GDKsyserror("mdb.modules"MAL_MALLOC_FAIL); return b; } strncpy(cur_dir, mod_path, l); cur_dir[l] = 0; if ((mod_path = p) != NULL) { while (*mod_path == PATH_SEP) mod_path++; } dirp = opendir(cur_dir); GDKfree(cur_dir); if (dirp == NULL) continue; } if ((dent = readdir(dirp)) == NULL) { closedir(dirp); dirp = NULL; continue; } len = strlen(dent->d_name); if (len < extlen || strcmp(dent->d_name + len - extlen, MAL_EXT) != 0) continue; dent->d_name[len - extlen] = 0; BUNappend(b, dent->d_name, FALSE); i++; } return b; }
static Client MCinitClientRecord(Client c, oid user, bstream *fin, stream *fout) { const char *prompt; c->user = user; c->username = 0; c->scenario = NULL; c->oldscenario = NULL; c->srcFile = NULL; c->blkmode = 0; c->fdin = fin ? fin : bstream_create(GDKin, 0); if ( c->fdin == NULL){ MT_lock_set(&mal_contextLock); c->mode = FREECLIENT; MT_lock_unset(&mal_contextLock); showException(GDKout, MAL, "initClientRecord", MAL_MALLOC_FAIL); return NULL; } c->yycur = 0; c->bak = NULL; c->listing = 0; c->fdout = fout ? fout : GDKstdout; c->mdb = 0; c->history = 0; c->curprg = c->backup = 0; c->glb = 0; /* remove garbage from previous connection * be aware, a user can introduce several modules * that should be freed to avoid memory leaks */ c->usermodule = c->curmodule = 0; c->father = NULL; c->login = c->lastcmd = time(0); //c->active = 0; c->session = GDKusec(); c->qtimeout = 0; c->stimeout = 0; c->itrace = 0; c->flags = 0; c->errbuf = 0; prompt = !fin ? GDKgetenv("monet_prompt") : PROMPT1; c->prompt = GDKstrdup(prompt); if ( c->prompt == NULL){ if (fin == NULL) { c->fdin->s = NULL; bstream_destroy(c->fdin); MT_lock_set(&mal_contextLock); c->mode = FREECLIENT; MT_lock_unset(&mal_contextLock); } showException(GDKout, MAL, "initClientRecord", MAL_MALLOC_FAIL); return NULL; } c->promptlength = strlen(prompt); c->actions = 0; c->exception_buf_initialized = 0; c->error_row = c->error_fld = c->error_msg = c->error_input = NULL; c->wlc_kind = 0; c->wlc = NULL; #ifndef HAVE_EMBEDDED /* no authentication in embedded mode */ { str msg = AUTHgetUsername(&c->username, c); if (msg) /* shouldn't happen */ freeException(msg); } #endif c->blocksize = BLOCK; c->protocol = PROTOCOL_9; c->filetrans = false; c->query = NULL; char name[16]; snprintf(name, sizeof(name), "Client%d->s", (int) (c - mal_clients)); MT_sema_init(&c->s, 0, name); return c; }
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); }
int main(int argc, char **av) { char *prog = *av; opt *set = NULL; int i, grpdebug = 0, debug = 0, setlen = 0, listing = 0; str err = MAL_SUCCEED; char prmodpath[FILENAME_MAX]; const char *modpath = NULL; char *binpath = NULL; str *monet_script; char *dbpath = NULL; char *dbextra = NULL; int verbosity = 0; static struct option long_options[] = { { "config", required_argument, NULL, 'c' }, { "dbpath", required_argument, NULL, 0 }, { "dbextra", required_argument, NULL, 0 }, { "daemon", required_argument, NULL, 0 }, { "debug", optional_argument, NULL, 'd' }, { "help", no_argument, NULL, '?' }, { "version", no_argument, NULL, 0 }, { "verbose", optional_argument, NULL, 'v' }, { "readonly", no_argument, NULL, 'r' }, { "single-user", no_argument, NULL, 0 }, { "set", required_argument, NULL, 's' }, { "threads", no_argument, NULL, 0 }, { "memory", no_argument, NULL, 0 }, { "properties", no_argument, NULL, 0 }, { "io", no_argument, NULL, 0 }, { "transactions", no_argument, NULL, 0 }, { "trace", optional_argument, NULL, 't' }, { "modules", no_argument, NULL, 0 }, { "algorithms", no_argument, NULL, 0 }, { "optimizers", no_argument, NULL, 0 }, { "performance", no_argument, NULL, 0 }, { "forcemito", no_argument, NULL, 0 }, { "heaps", no_argument, NULL, 0 }, { NULL, 0, NULL, 0 } }; #if defined(_MSC_VER) && defined(__cplusplus) set_terminate(mserver_abort); #endif #ifdef _MSC_VER _CrtSetReportMode(_CRT_ERROR, 0); _CrtSetReportMode(_CRT_ASSERT, 0); _set_invalid_parameter_handler(mserver_invalid_parameter_handler); #ifdef _TWO_DIGIT_EXPONENT _set_output_format(_TWO_DIGIT_EXPONENT); #endif #endif if (setlocale(LC_CTYPE, "") == NULL) { fprintf(stderr, "cannot set locale\n"); exit(1); } if (getcwd(monet_cwd, FILENAME_MAX - 1) == NULL) { perror("pwd"); fprintf(stderr,"monet_init: could not determine current directory\n"); exit(-1); } /* retrieve binpath early (before monet_init) because some * implementations require the working directory when the binary was * called */ binpath = get_bin_path(); if (!(setlen = mo_builtin_settings(&set))) usage(prog, -1); for (;;) { int option_index = 0; int c = getopt_long(argc, av, "c:d::rs:t::v::?", long_options, &option_index); if (c == -1) break; switch (c) { case 0: if (strcmp(long_options[option_index].name, "dbpath") == 0) { size_t optarglen = strlen(optarg); /* remove trailing directory separator */ while (optarglen > 0 && (optarg[optarglen - 1] == '/' || optarg[optarglen - 1] == '\\')) optarg[--optarglen] = '\0'; dbpath = absolute_path(optarg); if( dbpath == NULL) fprintf(stderr, "#error: can not allocate memory for dbpath\n"); else setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_dbpath", dbpath); break; } if (strcmp(long_options[option_index].name, "dbextra") == 0) { if (dbextra) fprintf(stderr, "#warning: ignoring multiple --dbextra arguments\n"); else dbextra = optarg; break; } #ifdef HAVE_CONSOLE if (strcmp(long_options[option_index].name, "daemon") == 0) { setlen = mo_add_option(&set, setlen, opt_cmdline, "monet_daemon", optarg); break; } #endif if (strcmp(long_options[option_index].name, "single-user") == 0) { setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_single_user", "yes"); break; } if (strcmp(long_options[option_index].name, "version") == 0) { monet_version(); exit(0); } /* debugging options */ if (strcmp(long_options[option_index].name, "properties") == 0) { grpdebug |= GRPproperties; break; } if (strcmp(long_options[option_index].name, "algorithms") == 0) { grpdebug |= GRPalgorithms; break; } if (strcmp(long_options[option_index].name, "optimizers") == 0) { grpdebug |= GRPoptimizers; break; } if (strcmp(long_options[option_index].name, "forcemito") == 0) { grpdebug |= GRPforcemito; break; } if (strcmp(long_options[option_index].name, "performance") == 0) { grpdebug |= GRPperformance; break; } if (strcmp(long_options[option_index].name, "io") == 0) { grpdebug |= GRPio; break; } if (strcmp(long_options[option_index].name, "memory") == 0) { grpdebug |= GRPmemory; break; } if (strcmp(long_options[option_index].name, "modules") == 0) { grpdebug |= GRPmodules; break; } if (strcmp(long_options[option_index].name, "transactions") == 0) { grpdebug |= GRPtransactions; break; } if (strcmp(long_options[option_index].name, "threads") == 0) { grpdebug |= GRPthreads; break; } if (strcmp(long_options[option_index].name, "trace") == 0) { mal_trace = 1; break; } if (strcmp(long_options[option_index].name, "heaps") == 0) { grpdebug |= GRPheaps; break; } usage(prog, -1); /* not reached */ case 'c': /* coverity[var_deref_model] */ setlen = mo_add_option(&set, setlen, opt_cmdline, "config", optarg); break; case 'd': if (optarg) { char *endarg; debug |= strtol(optarg, &endarg, 10); if (*endarg != '\0') { fprintf(stderr, "ERROR: wrong format for --debug=%s\n", optarg); usage(prog, -1); } } else { debug |= 1; } break; case 'r': setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_readonly", "yes"); break; case 's': { /* should add option to a list */ /* coverity[var_deref_model] */ char *tmp = strchr(optarg, '='); if (tmp) { *tmp = '\0'; setlen = mo_add_option(&set, setlen, opt_cmdline, optarg, tmp + 1); } else fprintf(stderr, "ERROR: wrong format %s\n", optarg); } break; case 't': mal_trace = 1; break; case 'v': if (optarg) { char *endarg; verbosity = (int) strtol(optarg, &endarg, 10); if (*endarg != '\0') { fprintf(stderr, "ERROR: wrong format for --verbose=%s\n", optarg); usage(prog, -1); } } else { verbosity++; } break; case '?': /* a bit of a hack: look at the option that the current `c' is based on and see if we recognize it: if -? or --help, exit with 0, else with -1 */ usage(prog, strcmp(av[optind - 1], "-?") == 0 || strcmp(av[optind - 1], "--help") == 0 ? 0 : -1); default: fprintf(stderr, "ERROR: getopt returned character " "code '%c' 0%o\n", c, (uint8_t) c); usage(prog, -1); } } if (!(setlen = mo_system_config(&set, setlen))) usage(prog, -1); GDKsetdebug(debug | grpdebug); /* add the algorithm tracers */ if (debug) mo_print_options(set, setlen); GDKsetverbose(verbosity); monet_script = (str *) malloc(sizeof(str) * (argc + 1)); if (monet_script == NULL) { fprintf(stderr, "!ERROR: cannot allocate memory for script \n"); exit(1); } i = 0; while (optind < argc) { monet_script[i] = absolute_path(av[optind]); if (monet_script[i] == NULL) { fprintf(stderr, "!ERROR: cannot allocate memory for script \n"); exit(1); } i++; optind++; } monet_script[i] = NULL; if (!dbpath) { dbpath = absolute_path(mo_find_option(set, setlen, "gdk_dbpath")); if (!dbpath) { fprintf(stderr, "!ERROR: cannot allocate memory for database directory \n"); exit(1); } } if (BBPaddfarm(dbpath, 1 << PERSISTENT) != GDK_SUCCEED || BBPaddfarm(dbextra ? dbextra : dbpath, 1 << TRANSIENT) != GDK_SUCCEED) { fprintf(stderr, "!ERROR: cannot add farm\n"); exit(1); } if (GDKcreatedir(dbpath) != GDK_SUCCEED) { fprintf(stderr, "!ERROR: cannot create directory for %s\n", dbpath); exit(1); } GDKfree(dbpath); if (monet_init(set, setlen) == 0) { mo_free_options(set, setlen); if (GDKerrbuf && *GDKerrbuf) fprintf(stderr, "%s\n", GDKerrbuf); exit(1); } mo_free_options(set, setlen); if (GDKsetenv("monet_version", GDKversion()) != GDK_SUCCEED || GDKsetenv("monet_release", #ifdef MONETDB_RELEASE MONETDB_RELEASE #else "unreleased" #endif ) != GDK_SUCCEED) { fprintf(stderr, "!ERROR: GDKsetenv failed\n"); exit(1); } if ((modpath = GDKgetenv("monet_mod_path")) == NULL) { /* start probing based on some heuristics given the binary * location: * bin/mserver5 -> ../ * libX/monetdb5/lib/ * probe libX = lib, lib32, lib64, lib/64 */ size_t pref; /* "remove" common prefix of configured BIN and LIB * directories from LIBDIR */ for (pref = 0; LIBDIR[pref] != 0 && BINDIR[pref] == LIBDIR[pref]; pref++) ; const char *libdirs[] = { &LIBDIR[pref], "lib", "lib64", "lib/64", "lib32", NULL, }; struct stat sb; if (binpath != NULL) { char *p = strrchr(binpath, DIR_SEP); if (p != NULL) *p = '\0'; p = strrchr(binpath, DIR_SEP); if (p != NULL) { *p = '\0'; for (i = 0; libdirs[i] != NULL; i++) { int len = snprintf(prmodpath, sizeof(prmodpath), "%s%c%s%cmonetdb5", binpath, DIR_SEP, libdirs[i], DIR_SEP); if (len == -1 || len >= FILENAME_MAX) continue; if (stat(prmodpath, &sb) == 0) { modpath = prmodpath; break; } } } else { printf("#warning: unusable binary location, " "please use --set monet_mod_path=/path/to/... to " "allow finding modules\n"); fflush(NULL); } } else { printf("#warning: unable to determine binary location, " "please use --set monet_mod_path=/path/to/... to " "allow finding modules\n"); fflush(NULL); } if (modpath != NULL && GDKsetenv("monet_mod_path", modpath) != GDK_SUCCEED) { fprintf(stderr, "!ERROR: GDKsetenv failed\n"); exit(1); } } /* configure sabaoth to use the right dbpath and active database */ msab_dbpathinit(GDKgetenv("gdk_dbpath")); /* wipe out all cruft, if left over */ if ((err = msab_wildRetreat()) != NULL) { /* just swallow the error */ free(err); } /* From this point, the server should exit cleanly. Discussion: * even earlier? Sabaoth here registers the server is starting up. */ if ((err = msab_registerStarting()) != NULL) { /* throw the error at the user, but don't die */ fprintf(stderr, "!%s\n", err); free(err); } #ifdef HAVE_SIGACTION { struct sigaction sa; (void) sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; if (sigaction(SIGINT, &sa, NULL) == -1 || sigaction(SIGQUIT, &sa, NULL) == -1 || sigaction(SIGTERM, &sa, NULL) == -1) { fprintf(stderr, "!unable to create signal handlers\n"); } } #else #ifdef _MSC_VER if (!SetConsoleCtrlHandler(winhandler, TRUE)) fprintf(stderr, "!unable to create console control handler\n"); #else if(signal(SIGINT, handler) == SIG_ERR) fprintf(stderr, "!unable to create signal handlers\n"); #ifdef SIGQUIT if(signal(SIGQUIT, handler) == SIG_ERR) fprintf(stderr, "!unable to create signal handlers\n"); #endif if(signal(SIGTERM, handler) == SIG_ERR) fprintf(stderr, "!unable to create signal handlers\n"); #endif #endif { str lang = "mal"; /* we inited mal before, so publish its existence */ if ((err = msab_marchScenario(lang)) != NULL) { /* throw the error at the user, but don't die */ fprintf(stderr, "!%s\n", err); free(err); } } { /* unlock the vault, first see if we can find the file which * holds the secret */ char secret[1024]; char *secretp = secret; FILE *secretf; size_t len; if (GDKgetenv("monet_vault_key") == NULL) { /* use a default (hard coded, non safe) key */ snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8"); } else { if ((secretf = fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) { fprintf(stderr, "unable to open vault_key_file %s: %s\n", GDKgetenv("monet_vault_key"), strerror(errno)); /* don't show this as a crash */ msab_registerStop(); exit(1); } len = fread(secret, 1, sizeof(secret), secretf); secret[len] = '\0'; len = strlen(secret); /* secret can contain null-bytes */ if (len == 0) { fprintf(stderr, "vault key has zero-length!\n"); /* don't show this as a crash */ msab_registerStop(); exit(1); } else if (len < 5) { fprintf(stderr, "#warning: your vault key is too short " "(%zu), enlarge your vault key!\n", len); } fclose(secretf); } if ((err = AUTHunlockVault(secretp)) != MAL_SUCCEED) { /* don't show this as a crash */ msab_registerStop(); fprintf(stderr, "%s\n", err); freeException(err); exit(1); } } /* make sure the authorisation BATs are loaded */ if ((err = AUTHinitTables(NULL)) != MAL_SUCCEED) { /* don't show this as a crash */ msab_registerStop(); fprintf(stderr, "%s\n", err); freeException(err); exit(1); } if (mal_init()) { /* don't show this as a crash */ msab_registerStop(); return 0; } if((err = MSinitClientPrg(mal_clients, "user", "main")) != MAL_SUCCEED) { msab_registerStop(); fprintf(stderr, "%s\n", err); freeException(err); exit(1); } emergencyBreakpoint(); for (i = 0; monet_script[i]; i++) { str msg = evalFile(monet_script[i], listing); /* check for internal exception message to terminate */ if (msg) { if (strcmp(msg, "MALException:client.quit:Server stopped.") == 0) mal_exit(0); fprintf(stderr, "#%s: %s\n", monet_script[i], msg); freeException(msg); } GDKfree(monet_script[i]); monet_script[i] = 0; } free(monet_script); if ((err = msab_registerStarted()) != NULL) { /* throw the error at the user, but don't die */ fprintf(stderr, "!%s\n", err); free(err); } #ifdef HAVE_CONSOLE if (!monet_daemon) { MSserveClient(mal_clients); } else #endif while (!interrupted && !GDKexiting()) { MT_sleep_ms(100); } /* mal_exit calls exit, so statements after this call will * never get reached */ mal_exit(0); return 0; }
int main(int argc, char **av) { char *prog = *av; opt *set = NULL; int idx = 0, grpdebug = 0, debug = 0, setlen = 0, listing = 0, i = 0; str dbinit = NULL; str err = MAL_SUCCEED; char prmodpath[1024]; char *modpath = NULL; char *binpath = NULL; str *monet_script; static struct option long_options[] = { { "config", 1, 0, 'c' }, { "dbpath", 1, 0, 0 }, { "dbinit", 1, 0, 0 }, { "debug", 2, 0, 'd' }, { "help", 0, 0, '?' }, { "version", 0, 0, 0 }, { "readonly", 0, 0, 'r' }, { "set", 1, 0, 's' }, { "threads", 0, 0, 0 }, { "memory", 0, 0, 0 }, { "properties", 0, 0, 0 }, { "io", 0, 0, 0 }, { "transactions", 0, 0, 0 }, { "trace", 2, 0, 't' }, { "modules", 0, 0, 0 }, { "algorithms", 0, 0, 0 }, { "optimizers", 0, 0, 0 }, { "performance", 0, 0, 0 }, #if 0 { "xproperties", 0, 0, 0 }, #endif { "forcemito", 0, 0, 0 }, { "heaps", 0, 0, 0 }, { 0, 0, 0, 0 } }; #if defined(_MSC_VER) && defined(__cplusplus) set_terminate(mserver_abort); #endif if (setlocale(LC_CTYPE, "") == NULL) { GDKfatal("cannot set locale\n"); } #ifdef HAVE_MALLOPT if (malloc_init) { /* for (Red Hat) Linux (6.2) unused and ignored at least as of glibc-2.1.3-15 */ /* for (Red Hat) Linux (8) used at least as of glibc-2.2.93-5 */ if (mallopt(M_MXFAST, 192)) { fprintf(stderr, "!monet: mallopt(M_MXFAST,192) fails.\n"); } #ifdef M_BLKSZ if (mallopt(M_BLKSZ, 8 * 1024)) { fprintf(stderr, "!monet: mallopt(M_BLKSZ,8*1024) fails.\n"); } #endif } malloc_init = 0; #else (void) malloc_init; /* still unused */ #endif if (getcwd(monet_cwd, PATHLENGTH - 1) == NULL) { perror("pwd"); GDKfatal("monet_init: could not determine current directory\n"); } /* retrieve binpath early (before monet_init) because some * implementations require the working directory when the binary was * called */ binpath = get_bin_path(); if (!(setlen = mo_builtin_settings(&set))) usage(prog, -1); setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_single_user", "yes"); for (;;) { int option_index = 0; int c = getopt_long(argc, av, "c:d::rs:t::?", long_options, &option_index); if (c == -1) break; switch (c) { case 0: if (strcmp(long_options[option_index].name, "dbpath") == 0) { size_t optarglen = strlen(optarg); /* remove trailing directory separator */ while (optarglen > 0 && (optarg[optarglen - 1] == '/' || optarg[optarglen - 1] == '\\')) optarg[--optarglen] = '\0'; setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_dbpath", optarg); break; } if (strcmp(long_options[option_index].name, "dbinit") == 0) { if (dbinit) fprintf(stderr, "#warning: ignoring multiple --dbinit argument\n"); else dbinit = optarg; break; } if (strcmp(long_options[option_index].name, "version") == 0) { monet_version(); exit(0); } /* debugging options */ if (strcmp(long_options[option_index].name, "properties") == 0) { grpdebug |= GRPproperties; break; } if (strcmp(long_options[option_index].name, "algorithms") == 0) { grpdebug |= GRPalgorithms; break; } if (strcmp(long_options[option_index].name, "optimizers") == 0) { grpdebug |= GRPoptimizers; break; } #if 0 if (strcmp(long_options[option_index].name, "xproperties") == 0) { grpdebug |= GRPxproperties; break; } #endif if (strcmp(long_options[option_index].name, "forcemito") == 0) { grpdebug |= GRPforcemito; break; } if (strcmp(long_options[option_index].name, "performance") == 0) { grpdebug |= GRPperformance; break; } if (strcmp(long_options[option_index].name, "io") == 0) { grpdebug |= GRPio; break; } if (strcmp(long_options[option_index].name, "memory") == 0) { grpdebug |= GRPmemory; break; } if (strcmp(long_options[option_index].name, "modules") == 0) { grpdebug |= GRPmodules; break; } if (strcmp(long_options[option_index].name, "transactions") == 0) { grpdebug |= GRPtransactions; break; } if (strcmp(long_options[option_index].name, "threads") == 0) { grpdebug |= GRPthreads; break; } if (strcmp(long_options[option_index].name, "trace") == 0) { mal_trace = optarg? optarg:"ISTest"; break; } if (strcmp(long_options[option_index].name, "heaps") == 0) { grpdebug |= GRPheaps; break; } usage(prog, -1); /* not reached */ case 'c': setlen = mo_add_option(&set, setlen, opt_cmdline, "config", optarg); break; case 'd': if (optarg) { debug |= strtol(optarg, NULL, 10); } else { debug |= 1; } break; case 'r': setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_readonly", "yes"); break; case 's': { /* should add option to a list */ char *tmp = strchr(optarg, '='); if (tmp) { *tmp = '\0'; setlen = mo_add_option(&set, setlen, opt_cmdline, optarg, tmp + 1); } else fprintf(stderr, "ERROR: wrong format %s\n", optarg); } break; case 't': mal_trace = optarg? optarg:"ISTest"; break; case '?': /* a bit of a hack: look at the option that the current `c' is based on and see if we recognize it: if -? or --help, exit with 0, else with -1 */ usage(prog, strcmp(av[optind - 1], "-?") == 0 || strcmp(av[optind - 1], "--help") == 0 ? 0 : -1); default: fprintf(stderr, "ERROR: getopt returned character " "code '%c' 0%o\n", c, c); usage(prog, -1); } } if (!(setlen = mo_system_config(&set, setlen))) usage(prog, -1); if (debug || grpdebug) { long_str buf; if (debug) mo_print_options(set, setlen); debug |= grpdebug; /* add the algorithm tracers */ snprintf(buf, sizeof(long_str) - 1, "%d", debug); setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_debug", buf); } #ifdef RDEBUG printf("parameter ok\n"); #endif monet_script = (str *) malloc(sizeof(str) * (argc + 1)); if (monet_script) { monet_script[idx] = NULL; while (optind < argc) { monet_script[idx] = absolute_path(av[optind]); monet_script[idx + 1] = NULL; optind++; idx++; } } if (monet_init(set, setlen) == 0) { mo_free_options(set, setlen); return 0; } mo_free_options(set, setlen); #ifdef RDEBUG printf("monet_init ok\n"); #endif GDKsetenv("monet_version", VERSION); GDKsetenv("monet_release", MONETDB_RELEASE); if ((modpath = GDKgetenv("monet_mod_path")) == NULL) { /* start probing based on some heuristics given the binary * location: * bin/mserver5 -> ../ * libX/monetdb5/lib/ * probe libX = lib, lib32, lib64, lib/64 */ char *libdirs[] = { "lib", "lib64", "lib/64", "lib32", NULL }; size_t i; struct stat sb; if (binpath != NULL) { char *p = strrchr(binpath, DIR_SEP); if (p != NULL) *p = '\0'; p = strrchr(binpath, DIR_SEP); if (p != NULL) { *p = '\0'; for (i = 0; libdirs[i] != NULL; i++) { snprintf(prmodpath, sizeof(prmodpath), "%s%c%s%cmonetdb5", binpath, DIR_SEP, libdirs[i], DIR_SEP); if (stat(prmodpath, &sb) == 0) { modpath = prmodpath; break; } } } else { printf("#warning: unusable binary location, " "please use --set monet_mod_path=/path/to/... to " "allow finding modules\n"); fflush(NULL); } } else { printf("#warning: unable to determine binary location, " "please use --set monet_mod_path=/path/to/... to " "allow finding modules\n"); fflush(NULL); } if (modpath != NULL) GDKsetenv("monet_mod_path", modpath); } #ifdef RDEBUG printf("modpath ok\n"); #endif /* configure sabaoth to use the right dbpath and active database */ msab_dbpathinit(GDKgetenv("gdk_dbpath")); /* wipe out all cruft, if left over */ if ((err = msab_wildRetreat()) != NULL) { /* just swallow the error */ free(err); } /* From this point, the server should exit cleanly. Discussion: * even earlier? Sabaoth here registers the server is starting up. */ if ((err = msab_registerStarting()) != NULL) { /* throw the error at the user, but don't die */ fprintf(stderr, "!%s\n", err); free(err); } #ifdef RDEBUG printf("some stuff\n"); #endif #ifdef HAVE_SIGACTION { struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; if ( sigaction(SIGINT, &sa, NULL) == -1 || sigaction(SIGQUIT, &sa, NULL) == -1 || sigaction(SIGTERM, &sa, NULL) == -1) { fprintf(stderr, "!unable to create signal handlers\n"); } } #else signal(SIGINT, handler); #ifdef SIGQUIT signal(SIGQUIT, handler); #endif signal(SIGTERM, handler); #endif { str lang = "mal"; /* we inited mal before, so publish its existence */ if ((err = msab_marchScenario(lang)) != NULL) { /* throw the error at the user, but don't die */ fprintf(stderr, "!%s\n", err); free(err); } } #ifdef RDEBUG printf("scenario ok\n"); #endif { /* unlock the vault, first see if we can find the file which * holds the secret */ char secret[1024]; char *secretp = secret; FILE *secretf; size_t len; if (GDKgetenv("monet_vault_key") == NULL) { /* use a default (hard coded, non safe) key */ snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8"); } else { if ((secretf = fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) { snprintf(secret, sizeof(secret), "unable to open vault_key_file %s: %s", GDKgetenv("monet_vault_key"), strerror(errno)); /* don't show this as a crash */ msab_registerStop(); GDKfatal("%s", secret); } len = fread(secret, 1, sizeof(secret), secretf); secret[len] = '\0'; len = strlen(secret); /* secret can contain null-bytes */ if (len == 0) { snprintf(secret, sizeof(secret), "vault key has zero-length!"); /* don't show this as a crash */ msab_registerStop(); GDKfatal("%s", secret); } else if (len < 5) { fprintf(stderr, "#warning: your vault key is too short " "(" SZFMT "), enlarge your vault key!\n", len); } fclose(secretf); } if ((err = AUTHunlockVault(&secretp)) != MAL_SUCCEED) { /* don't show this as a crash */ msab_registerStop(); GDKfatal("%s", err); } } /* make sure the authorisation BATs are loaded */ if ((err = AUTHinitTables()) != MAL_SUCCEED) { /* don't show this as a crash */ msab_registerStop(); GDKfatal("%s", err); } #ifdef RDEBUG printf("vaultkey ok\n"); #endif if (mal_init()) { /* don't show this as a crash */ msab_registerStop(); return 0; } #ifdef RDEBUG printf("mal_init ok\n"); #endif #if (0) if (!loadLibrary("lib_leaker", TRUE)) return 42; #endif #ifdef RDEBUG printf("lib_leaker ok\n"); #endif if (GDKgetenv("mal_listing")) sscanf(GDKgetenv("mal_listing"), "%d", &listing); MSinitClientPrg(mal_clients, "user", "main"); if (dbinit == NULL) dbinit = GDKgetenv("dbinit"); if (dbinit) callString(mal_clients, dbinit, listing); #ifdef RDEBUG printf("MSinitClientPrg ok\n"); #endif emergencyBreakpoint(); if ((err = compileOptimizer(mal_clients, "leaker_pipe")) != MAL_SUCCEED) mnstr_printf(mal_clients->fdout, "OPT_COMPILE: %s\n", err); //callString(mal_clients, "sql.start();\n", 0); if (monet_script) for (i = 0; monet_script[i]; i++) { str msg = evalFile(mal_clients, monet_script[i], listing); /* check for internal exception message to terminate */ if (msg) { if (strcmp(msg, "MALException:client.quit:Server stopped.") == 0) mal_exit(); fprintf(stderr, "#%s: %s\n", monet_script[i], msg); GDKfree(msg); } GDKfree(monet_script[i]); monet_script[i] = 0; } if ((err = msab_registerStarted()) != NULL) { /* throw the error at the user, but don't die */ fprintf(stderr, "!%s\n", err); free(err); } if (monet_script) free(monet_script); MSserveClient(mal_clients); /* mal_exit calls MT_global_exit, so statements after this call will * never get reached */ mal_exit(); return 0; }
int mvc_init(int debug, store_type store, int ro, int su, backend_stack stk) { int first = 0; logger_settings *log_settings = (struct logger_settings *) GDKmalloc(sizeof(struct logger_settings)); /* Set the default WAL directory. "sql_logs" by default */ log_settings->logdir = "sql_logs"; /* Get and pass on the WAL directory location, if set */ if (GDKgetenv("gdk_logdir") != NULL) { log_settings->logdir = GDKgetenv("gdk_logdir"); } /* Get and pass on the shared WAL directory location, if set */ log_settings->shared_logdir = GDKgetenv("gdk_shared_logdir"); /* Get and pass on the shared WAL drift threshold, if set. * -1 by default, meaning it should be ignored, since it is not set */ log_settings->shared_drift_threshold = GDKgetenv_int("gdk_shared_drift_threshold", -1); /* Get and pass on the flag how many WAL files should be preserved. * 0 by default - keeps only the current WAL file. */ log_settings->keep_persisted_log_files = GDKgetenv_int("gdk_keep_persisted_log_files", 0); mvc_debug = debug&4; if (mvc_debug) { fprintf(stderr, "#mvc_init logdir %s\n", log_settings->logdir); fprintf(stderr, "#mvc_init keep_persisted_log_files %d\n", log_settings->keep_persisted_log_files); if (log_settings->shared_logdir != NULL) { fprintf(stderr, "#mvc_init shared_logdir %s\n", log_settings->shared_logdir); } fprintf(stderr, "#mvc_init shared_drift_threshold %d\n", log_settings->shared_drift_threshold); } keyword_init(); scanner_init_keywords(); if ((first = store_init(debug, store, ro, su, log_settings, stk)) < 0) { fprintf(stderr, "!mvc_init: unable to create system tables\n"); return -1; } if (first || catalog_version) { sql_schema *s; sql_table *t; mvc *m = mvc_create(0, stk, 0, NULL, NULL); m->sa = sa_create(); /* disable caching */ m->caching = 0; /* disable history */ m->history = 0; /* disable size header */ m->sizeheader = 0; mvc_trans(m); s = m->session->schema = mvc_bind_schema(m, "sys"); assert(m->session->schema != NULL); if (!first) { t = mvc_bind_table(m, s, "tables"); mvc_drop_table(m, s, t, 0); t = mvc_bind_table(m, s, "columns"); mvc_drop_table(m, s, t, 0); } t = mvc_create_view(m, s, "tables", SQL_PERSIST, "SELECT \"id\", \"name\", \"schema_id\", \"query\", CAST(CASE WHEN \"system\" THEN \"type\" + 10 /* system table/view */ ELSE (CASE WHEN \"commit_action\" = 0 THEN \"type\" /* table/view */ ELSE \"type\" + 20 /* global temp table */ END) END AS SMALLINT) AS \"type\", \"system\", \"commit_action\", \"access\", CASE WHEN (NOT \"system\" AND \"commit_action\" > 0) THEN 1 ELSE 0 END AS \"temporary\" FROM \"sys\".\"_tables\" WHERE \"type\" <> 2 UNION ALL SELECT \"id\", \"name\", \"schema_id\", \"query\", CAST(\"type\" + 30 /* local temp table */ AS SMALLINT) AS \"type\", \"system\", \"commit_action\", \"access\", 1 AS \"temporary\" FROM \"tmp\".\"_tables\";", 1); mvc_create_column_(m, t, "id", "int", 32); mvc_create_column_(m, t, "name", "varchar", 1024); mvc_create_column_(m, t, "schema_id", "int", 32); mvc_create_column_(m, t, "query", "varchar", 2048); mvc_create_column_(m, t, "type", "smallint", 16); mvc_create_column_(m, t, "system", "boolean", 1); mvc_create_column_(m, t, "commit_action", "smallint", 16); mvc_create_column_(m, t, "access", "smallint", 16); mvc_create_column_(m, t, "temporary", "smallint", 16); if (!first) { int pub = ROLE_PUBLIC; int p = PRIV_SELECT; int zero = 0; sql_table *privs = find_sql_table(s, "privileges"); table_funcs.table_insert(m->session->tr, privs, &t->base.id, &pub, &p, &zero, &zero); } t = mvc_create_view(m, s, "columns", SQL_PERSIST, "SELECT * FROM (SELECT p.* FROM \"sys\".\"_columns\" AS p UNION ALL SELECT t.* FROM \"tmp\".\"_columns\" AS t) AS columns;", 1); mvc_create_column_(m, t, "id", "int", 32); mvc_create_column_(m, t, "name", "varchar", 1024); mvc_create_column_(m, t, "type", "varchar", 1024); mvc_create_column_(m, t, "type_digits", "int", 32); mvc_create_column_(m, t, "type_scale", "int", 32); mvc_create_column_(m, t, "table_id", "int", 32); mvc_create_column_(m, t, "default", "varchar", 2048); mvc_create_column_(m, t, "null", "boolean", 1); mvc_create_column_(m, t, "number", "int", 32); mvc_create_column_(m, t, "storage", "varchar", 2048); if (!first) { int pub = ROLE_PUBLIC; int p = PRIV_SELECT; int zero = 0; sql_table *privs = find_sql_table(s, "privileges"); table_funcs.table_insert(m->session->tr, privs, &t->base.id, &pub, &p, &zero, &zero); } else { sql_create_env(m, s); sql_create_privileges(m, s); } s = m->session->schema = mvc_bind_schema(m, "tmp"); assert(m->session->schema != NULL); if (mvc_commit(m, 0, NULL) < 0) { fprintf(stderr, "!mvc_init: unable to commit system tables\n"); return -1; } mvc_destroy(m); } return first; }
int GDKinit(opt *set, int setlen) { char *dbpath = mo_find_option(set, setlen, "gdk_dbpath"); char *p; opt *n; int i, j, nlen = 0; char buf[16]; /* some sanity checks (should also find if symbols are not defined) */ assert(sizeof(char) == SIZEOF_CHAR); assert(sizeof(short) == SIZEOF_SHORT); assert(sizeof(int) == SIZEOF_INT); assert(sizeof(long) == SIZEOF_LONG); assert(sizeof(lng) == SIZEOF_LNG); assert(sizeof(oid) == SIZEOF_OID); assert(sizeof(void *) == SIZEOF_VOID_P); assert(sizeof(wrd) == SIZEOF_WRD); assert(sizeof(size_t) == SIZEOF_SIZE_T); assert(sizeof(ptrdiff_t) == SIZEOF_PTRDIFF_T); assert(SIZEOF_OID == SIZEOF_INT || SIZEOF_OID == SIZEOF_LNG); #ifdef NEED_MT_LOCK_INIT MT_lock_init(&MT_system_lock,"MT_system_lock"); ATOMIC_INIT(GDKstoppedLock, "GDKstoppedLock"); ATOMIC_INIT(mbyteslock, "mbyteslock"); MT_lock_init(&GDKnameLock, "GDKnameLock"); MT_lock_init(&GDKthreadLock, "GDKthreadLock"); MT_lock_init(&GDKtmLock, "GDKtmLock"); #endif for (i = 0; i <= BBP_BATMASK; i++) { MT_lock_init(&GDKbatLock[i].swap, "GDKswapLock"); MT_lock_init(&GDKbatLock[i].hash, "GDKhashLock"); MT_lock_init(&GDKbatLock[i].imprints, "GDKimprintsLock"); } for (i = 0; i <= BBP_THREADMASK; i++) { MT_lock_init(&GDKbbpLock[i].alloc, "GDKcacheLock"); MT_lock_init(&GDKbbpLock[i].trim, "GDKtrimLock"); GDKbbpLock[i].free = 0; } errno = 0; if (!GDKenvironment(dbpath)) return 0; if ((p = mo_find_option(set, setlen, "gdk_debug"))) GDKdebug = strtol(p, NULL, 10); if ((p = mo_find_option(set, setlen, "gdk_mem_pagebits"))) GDK_mem_pagebits = (int) strtol(p, NULL, 10); mnstr_init(); MT_init_posix(); THRinit(); #ifndef NATIVE_WIN32 BATSIGinit(); #endif #ifdef WIN32 (void) signal(SIGABRT, BATSIGabort); _set_abort_behavior(0, _CALL_REPORTFAULT | _WRITE_ABORT_MSG); _set_error_mode(_OUT_TO_STDERR); #endif GDKlockHome(); /* Mserver by default takes 80% of all memory as a default */ GDK_mem_maxsize = GDK_mem_maxsize_max = (size_t) ((double) MT_npages() * (double) MT_pagesize() * 0.815); #ifdef NATIVE_WIN32 GDK_mmap_minsize = GDK_mem_maxsize_max; #else GDK_mmap_minsize = MIN( 1<<30 , GDK_mem_maxsize_max/6 ); /* per op: 2 args + 1 res, each with head & tail => (2+1)*2 = 6 ^ */ #endif GDK_mem_bigsize = 1024*1024; GDKremovedir(DELDIR); BBPinit(); HEAPcacheInit(); GDKkey = BATnew(TYPE_void, TYPE_str, 100); GDKval = BATnew(TYPE_void, TYPE_str, 100); if (GDKkey == NULL) GDKfatal("GDKinit: Could not create environment BAT"); if (GDKval == NULL) GDKfatal("GDKinit: Could not create environment BAT"); BATseqbase(GDKkey,0); BATkey(GDKkey, BOUND2BTRUE); BATrename(GDKkey, "environment_key"); BATmode(GDKkey, TRANSIENT); BATseqbase(GDKval,0); BATkey(GDKval, BOUND2BTRUE); BATrename(GDKval, "environment_val"); BATmode(GDKval, TRANSIENT); n = (opt *) malloc(setlen * sizeof(opt)); for (i = 0; i < setlen; i++) { int done = 0; for (j = 0; j < nlen; j++) { if (strcmp(n[j].name, set[i].name) == 0) { if (n[j].kind < set[i].kind) { n[j] = set[i]; } done = 1; break; } } if (!done) { n[nlen] = set[i]; nlen++; } } for (i = 0; i < nlen; i++) GDKsetenv(n[i].name, n[i].value); free(n); if ((p = GDKgetenv("gdk_dbpath")) != NULL && (p = strrchr(p, DIR_SEP)) != NULL) { GDKsetenv("gdk_dbname", p + 1); #if DIR_SEP != '/' /* on Windows look for different separator */ } else if ((p = GDKgetenv("gdk_dbpath")) != NULL && (p = strrchr(p, '/')) != NULL) { GDKsetenv("gdk_dbname", p + 1); #endif } if ((p = GDKgetenv("gdk_mem_maxsize"))) { GDK_mem_maxsize = MAX(1 << 26, (size_t) strtoll(p, NULL, 10)); } if ((p = GDKgetenv("gdk_vm_maxsize"))) { GDK_vm_maxsize = MAX(1 << 30, (size_t) strtoll(p, NULL, 10)); } if ((p = GDKgetenv("gdk_mem_bigsize"))) { /* when allocating >6% of all RAM; do so using * vmalloc() iso malloc() */ lng max_mem_bigsize = GDK_mem_maxsize_max / 16; /* sanity check to avoid memory fragmentation */ GDK_mem_bigsize = (size_t) MIN(max_mem_bigsize, strtoll(p, NULL, 10)); } if ((p = GDKgetenv("gdk_mmap_minsize"))) { GDK_mmap_minsize = MAX(REMAP_PAGE_MAXSIZE, (size_t) strtoll(p, NULL, 10)); } if (GDKgetenv("gdk_mem_pagebits") == NULL) { snprintf(buf, sizeof(buf), "%d", GDK_mem_pagebits); GDKsetenv("gdk_mem_pagebits", buf); } if (GDKgetenv("gdk_mem_bigsize") == NULL) { snprintf(buf, sizeof(buf), SZFMT, GDK_mem_bigsize); GDKsetenv("gdk_mem_bigsize", buf); } if (GDKgetenv("monet_pid") == NULL) { snprintf(buf, sizeof(buf), "%d", (int) getpid()); GDKsetenv("monet_pid", buf); } GDKnr_threads = GDKgetenv_int("gdk_nr_threads", 0); if (GDKnr_threads == 0) GDKnr_threads = MT_check_nr_cores(); #ifdef NATIVE_WIN32 GDK_mmap_minsize /= (GDKnr_threads ? GDKnr_threads : 1); #else /* WARNING: This unconditionally overwrites above settings, */ /* incl. setting via MonetDB env. var. "gdk_mmap_minsize" ! */ GDK_mmap_minsize = MIN( 1<<30 , (GDK_mem_maxsize_max/6) / (GDKnr_threads ? GDKnr_threads : 1) ); /* per op: 2 args + 1 res, each with head & tail => (2+1)*2 = 6 ^ */ #endif if ((p = mo_find_option(set, setlen, "gdk_vmtrim")) == NULL || strcasecmp(p, "yes") == 0) MT_create_thread(&GDKvmtrim_id, GDKvmtrim, &GDK_mem_maxsize, MT_THR_JOINABLE); return 1; }
str loadLibrary(str filename, int flag) { int mode = RTLD_NOW | RTLD_GLOBAL; char nme[FILENAME_MAX]; void *handle = NULL; str s; int idx; const char *mod_path = GDKgetenv("monet_mod_path"); /* AIX requires RTLD_MEMBER to load a module that is a member of an * archive. */ #ifdef RTLD_MEMBER mode |= RTLD_MEMBER; #endif for (idx = 0; idx < lastfile; idx++) if (filesLoaded[idx].modname && strcmp(filesLoaded[idx].modname, filename) == 0) /* already loaded */ return MAL_SUCCEED; /* ignore any path given */ if ((s = strrchr(filename, DIR_SEP)) == NULL) s = filename; if (mod_path != NULL) { while (*mod_path == PATH_SEP) mod_path++; if (*mod_path == 0) mod_path = NULL; } if (mod_path == NULL) { if (flag) throw(LOADER, "loadLibrary", RUNTIME_FILE_NOT_FOUND ":%s", s); return MAL_SUCCEED; } while (*mod_path) { int len; const char *p; for (p = mod_path; *p && *p != PATH_SEP; p++) ; /* try hardcoded SO_EXT if that is the same for modules */ #ifdef _AIX len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s%s(%s_%s.0)", (int) (p - mod_path), mod_path, DIR_SEP, SO_PREFIX, s, SO_EXT, SO_PREFIX, s); #else len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s%s", (int) (p - mod_path), mod_path, DIR_SEP, SO_PREFIX, s, SO_EXT); #endif if (len == -1 || len >= FILENAME_MAX) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR "Library filename path is too large"); handle = dlopen(nme, mode); if (handle == NULL && fileexists(nme)) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " failed to open library %s (from within file '%s'): %s", s, nme, dlerror()); if (handle == NULL && strcmp(SO_EXT, ".so") != /* DISABLES CODE */ (0)) { /* try .so */ len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s.so", (int) (p - mod_path), mod_path, DIR_SEP, SO_PREFIX, s); if (len == -1 || len >= FILENAME_MAX) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR "Library filename path is too large"); handle = dlopen(nme, mode); if (handle == NULL && fileexists(nme)) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " failed to open library %s (from within file '%s'): %s", s, nme, dlerror()); } #ifdef __APPLE__ if (handle == NULL && strcmp(SO_EXT, ".bundle") != 0) { /* try .bundle */ len = snprintf(nme, FILENAME_MAX, "%.*s%c%s_%s.bundle", (int) (p - mod_path), mod_path, DIR_SEP, SO_PREFIX, s); if (len == -1 || len >= FILENAME_MAX) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR "Library filename path is too large"); handle = dlopen(nme, mode); if (handle == NULL && fileexists(nme)) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " failed to open library %s (from within file '%s'): %s", s, nme, dlerror()); } #endif if (*p == 0 || handle != NULL) break; mod_path = p + 1; } if (handle == NULL) { if (flag) throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " could not locate library %s (from within file '%s'): %s", s, filename, dlerror()); } MT_lock_set(&mal_contextLock); if (lastfile == maxfiles) { MT_lock_unset(&mal_contextLock); if (handle) dlclose(handle); throw(MAL,"mal.linker", "loadModule internal error, too many modules loaded"); } else { filesLoaded[lastfile].modname = GDKstrdup(filename); if(filesLoaded[lastfile].modname == NULL) { MT_lock_unset(&mal_contextLock); if (handle) dlclose(handle); throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " could not allocate space"); } filesLoaded[lastfile].fullname = GDKstrdup(handle ? nme : ""); if(filesLoaded[lastfile].fullname == NULL) { GDKfree(filesLoaded[lastfile].modname); MT_lock_unset(&mal_contextLock); if (handle) dlclose(handle); throw(LOADER, "loadLibrary", RUNTIME_LOAD_ERROR " could not allocate space"); } filesLoaded[lastfile].handle = handle ? handle : filesLoaded[0].handle; lastfile ++; } MT_lock_unset(&mal_contextLock); return MAL_SUCCEED; }