Example #1
0
/*
 * The emergency flag can be set to force a fatal error if needed.
 * Otherwise, the caller is able to deal with the lack of memory.
 */
void *
GDKmallocmax(size_t size, size_t *maxsize, int emergency)
{
	ssize_t *s = NULL;

	if (size == 0) {
#ifdef GDK_MEM_NULLALLOWED
		return NULL;
#else
		GDKfatal("GDKmallocmax: called with size " SZFMT "", size);
#endif
	}
	size = (size + 7) & ~7;	/* round up to a multiple of eight */
	GDKmalloc_prefixsize(s, size);
	if (s == NULL) {
		GDKmemfail("GDKmalloc", size);
		GDKmalloc_prefixsize(s, size);
		if (s == NULL) {
			if (emergency == 0) {
				GDKerror("GDKmallocmax: failed for " SZFMT " bytes", size);
				return NULL;
			}
			GDKfatal("GDKmallocmax: failed for " SZFMT " bytes", size);
		} else {
			THRprintf(GDKstdout, "#GDKmallocmax: recovery ok. Continuing..\n");
		}
	}
	*maxsize = size;
	heapinc(size + MALLOC_EXTRA_SPACE);
	return (void *) s;
}
Example #2
0
ptr
GDKreallocmax(void *blk, size_t size, size_t *maxsize, int emergency)
{
	void *oldblk = blk;
	ssize_t oldsize = 0;
	size_t newsize;

	if (blk == NULL) {
		return GDKmallocmax(size, maxsize, emergency);
	}
	if (size == 0) {
#ifdef GDK_MEM_NULLALLOWED
		GDKfree_(blk);
		*maxsize = 0;
		return NULL;
#else
		GDKfatal("GDKreallocmax: called with size 0");
#endif
	}
	size = (size + 7) & ~7;	/* round up to a multiple of eight */
	oldsize = GDK_MEM_BLKSIZE(blk);

	/* check against duplicate free */
	assert((oldsize & 2) == 0);

	newsize = size + MALLOC_EXTRA_SPACE;

	blk = realloc(((char *) blk) - MALLOC_EXTRA_SPACE,
		      newsize + GLIBC_BUG);
	if (blk == NULL) {
		GDKmemfail("GDKrealloc", newsize);
		blk = realloc(((char *) oldblk) - MALLOC_EXTRA_SPACE,
			      newsize);
		if (blk == NULL) {
			if (emergency == 0) {
				GDKerror("GDKreallocmax: failed for "
					 SZFMT " bytes", newsize);
				return NULL;
			}
			GDKfatal("GDKreallocmax: failed for "
				 SZFMT " bytes", newsize);
		} else {
			THRprintf(GDKstdout, "#GDKremallocmax: "
				  "recovery ok. Continuing..\n");
		}
	}
	/* place MALLOC_EXTRA_SPACE bytes before it */
	assert((((size_t) blk) & 4) == 0);
	blk = ((char *) blk) + MALLOC_EXTRA_SPACE;
	((ssize_t *) blk)[-1] = (ssize_t) newsize;

	/* adapt statistics */
	heapinc(newsize);
	heapdec(oldsize);
	*maxsize = size;
	return blk;
}
Example #3
0
/*
 * @+ Concurrency control
 * Concurrency control requires actions at several levels of the
 * system.  First, it should be ensured that each database is
 * controlled by a single server process (group). Subsequent attempts
 * should be stopped.  This is regulated through file locking against
 * ".gdk_lock".  Furthermore, the server process is moved to the
 * database directory for improved speed.
 *
 * Before the locks and threads are initiated, we cannot use the
 * normal routines yet. So we have a local fatal here instead of
 * GDKfatal.
 */
static void
GDKlockHome(void)
{
	char *p = 0, buf[1024], host[PATHLENGTH];

	/*
	 * Go there and obtain the global database lock.
	 */
	if (chdir(GDKdbpathStr) < 0) {
		char GDKdirStr[PATHLENGTH];

		/* The DIR_SEP at the end of the path is needed for a
		 * successful call to GDKcreatedir */
		snprintf(GDKdirStr, PATHLENGTH, "%s%c", GDKdbpathStr, DIR_SEP);
		if (!GDKcreatedir(GDKdirStr))
			GDKfatal("GDKlockHome: could not create %s\n", GDKdbpathStr);
		if (chdir(GDKdbpathStr) < 0)
			GDKfatal("GDKlockHome: could not move to %s\n", GDKdbpathStr);
		IODEBUG THRprintf(GDKstdout, "#GDKlockHome: created directory %s\n", GDKdbpathStr);
	}
	if (MT_lockf(GDKLOCK, F_TLOCK, 4, 1) < 0) {
		GDKlockFile = 0;
		GDKfatal("GDKlockHome: Database lock '%s' denied\n", GDKLOCK);
	}
	if ((GDKlockFile = fopen(GDKLOCK, "rb+")) == NULL) {
		GDKfatal("GDKlockHome: Could not open %s\n", GDKLOCK);
	}
	if (fgets(buf, 1024, GDKlockFile) && (p = strchr(buf, ':')))
		*p = 0;
	if (p) {
		sprintf(host, " from '%s'", buf);
	} else {
		IODEBUG THRprintf(GDKstdout, "#GDKlockHome: ignoring empty or invalid %s.\n", GDKLOCK);
		host[0] = 0;
	}
	/*
	 * We have the lock, are the only process currently allowed in
	 * this section.
	 */
	MT_init();
	OIDinit();
	/*
	 * Print the new process list in the global lock file.
	 */
	fseek(GDKlockFile, 0, SEEK_SET);
	if (ftruncate(fileno(GDKlockFile), 0) < 0)
		GDKfatal("GDKlockHome: Could not truncate %s\n", GDKLOCK);
	fflush(GDKlockFile);
	GDKlog(GDKLOGON);
	/*
	 * In shared mode, we allow more parties to join. Release the lock.
	 * No need yet to use GDKstoppedLock: there are no other threads.
	 */
	ATOMIC_SET_int(GDKstopped, 0, GDKstoppedLock, "");
}
Example #4
0
static
void tstAligned(void)
{
#ifdef STRUCT_ALIGNED
	int allAligned=0;
	ValRecord v;
	ptr val, base;
	base = (ptr) & v.val.ival;
	val= (ptr) & v.val.bval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.btval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.shval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.bval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.ival; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.oval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.pval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.fval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.dval; if(val != base){ allAligned = -1; }
	val= (ptr) & v.val.lval; if(val != base){ allAligned = -1; }
#ifdef HAVE_HGE
	val= (ptr) & v.val.hval; if(val != base){ allAligned = -1; }
#endif
	val= (ptr) & v.val.sval; if(val != base){ allAligned = -1; }
	if(allAligned<0)
	    GDKfatal("Recompile with STRUCT_ALIGNED flag disabled\n");
#endif
}
Example #5
0
MalStkPtr
newGlobalStack(int size)
{
	MalStkPtr s;

	s = (MalStkPtr) GDKzalloc(stackSize(size) + offsetof(MalStack, stk));
	if (s == NULL)
		GDKfatal("newGlobalStack:can not obtain memory\n");
	s->stksize = size;
	return s;
}
Example #6
0
void
THRdel(Thread t)
{
	if (t < GDKthreads || t > GDKthreads + THREADS) {
		GDKfatal("THRdel: illegal call\n");
	}
	MT_lock_set(&GDKthreadLock, "THRdel");
/*	The stream may haven been closed (e.g. in freeClient)  causing an abort
	PARDEBUG THRprintf(GDKstdout, "#pid = " SZFMT ", disconnected, %d left\n", (size_t) t->pid, GDKnrofthreads);
*/

	t->pid = 0;
	GDKnrofthreads--;
	MT_lock_unset(&GDKthreadLock, "THRdel");
}
Example #7
0
/* release all savepoints up including the given named savepoint 
 * but keep the current changes.
 * */
int
mvc_release(mvc *m, const char *name)
{
	int ok = SQL_OK;
	int res = Q_TRANS;
	sql_trans *tr = m->session->tr;

	assert(tr);
	assert(m->session->active);	/* only release active transactions */

	if (mvc_debug)
		fprintf(stderr, "#mvc_release %s\n", (name) ? name : "");

	if (!name)
		mvc_rollback(m, 0, name);

	while (tr && (!tr->name || strcmp(tr->name, name) != 0))
		tr = tr->parent;
	if (!tr || !tr->name || strcmp(tr->name, name) != 0) {
		(void)sql_error(m, 010, "release savepoint %s doesn't exists", name);
		m->session->status = -1;
		return -1;
	}
	tr = m->session->tr;
	store_lock();
	while (ok == SQL_OK && (!tr->name || strcmp(tr->name, name) != 0)) {
		/* commit all intermediate savepoints */
		if (sql_trans_commit(tr) != SQL_OK)
			GDKfatal("release savepoints should not fail");
		tr = sql_trans_destroy(tr);
	}
	tr->name = NULL;
	store_unlock();
	m->session->tr = tr;
	m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name);

	m->type = res;
	return res;
}
Example #8
0
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;
}
Example #9
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;
}
Example #10
0
int
mvc_commit(mvc *m, int chain, const char *name)
{
	sql_trans *cur, *tr = m->session->tr;
	int ok = SQL_OK;//, wait = 0;

	assert(tr);
	assert(m->session->active);	/* only commit an active transaction */
	
	if (mvc_debug)
		fprintf(stderr, "#mvc_commit %s\n", (name) ? name : "");

	if (m->session->status < 0) {
		(void)sql_error(m, 010, "40000!COMMIT: transaction is aborted, will ROLLBACK instead");
		mvc_rollback(m, chain, name);
		return -1;
	}

	/* savepoint then simply make a copy of the current transaction */
	if (name && name[0] != '\0') {
		sql_trans *tr = m->session->tr;
		if (mvc_debug)
			fprintf(stderr, "#mvc_savepoint\n");
		store_lock();
		m->session->tr = sql_trans_create(m->session->stk, tr, name);
		store_unlock();
		m->type = Q_TRANS;
		if (m->qc) /* clean query cache, protect against concurrent access on the hash tables (when functions already exists, concurrent mal will
build up the hash (not copied in the trans dup)) */
			qc_clean(m->qc);
		m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name);
		if (mvc_debug)
			fprintf(stderr, "#mvc_commit %s done\n", name);
		return 0;
	}

	/* first release all intermediate savepoints */
	cur = tr;
	tr = tr->parent;
	if (tr->parent) {
		store_lock();
		while (tr->parent != NULL && ok == SQL_OK) {
			tr = sql_trans_destroy(tr);
		}
		store_unlock();
	}
	cur -> parent = tr;
	tr = cur;

	store_lock();
	/* if there is nothing to commit reuse the current transaction */
	if (tr->wtime == 0) {
		if (!chain) 
			sql_trans_end(m->session);
		m->type = Q_TRANS;
		if (mvc_debug)
			fprintf(stderr, "#mvc_commit %s done\n", (name) ? name : "");
		store_unlock();
		return 0;
	}

	/*
	while (tr->schema_updates && store_nr_active > 1) {
		store_unlock();
		MT_sleep_ms(100);
		wait += 100;
		if (wait > 1000) {
			(void)sql_error(m, 010, "40000!COMMIT: transaction is aborted because of DDL concurrency conflicts, will ROLLBACK instead");
			mvc_rollback(m, chain, name);
			return -1;
		}
		store_lock();
	}
	 * */
	/* validation phase */
	if (sql_trans_validate(tr)) {
		if ((ok = sql_trans_commit(tr)) != SQL_OK) {
			char *msg = sql_message("40000!COMMIT: transaction commit failed (perhaps your disk is full?) exiting (kernel error: %s)", GDKerrbuf);
			GDKfatal("%s", msg);
			_DELETE(msg);
		}
	} else {
		store_unlock();
		(void)sql_error(m, 010, "40000!COMMIT: transaction is aborted because of concurrency conflicts, will ROLLBACK instead");
		mvc_rollback(m, chain, name);
		return -1;
	}
	sql_trans_end(m->session);
	if (chain) 
		sql_trans_begin(m->session);
	store_unlock();
	m->type = Q_TRANS;
	if (mvc_debug)
		fprintf(stderr, "#mvc_commit %s done\n", (name) ? name : "");
	return ok;
}
Example #11
0
str
instruction2str(MalBlkPtr mb, MalStkPtr stk,  InstrPtr p, int flg)
{
	int i, tab = 4;
	str base, s, t;
	size_t len=  (mb->stop < 1000? 1000: mb->stop) * 128 /* max realistic line length estimate */;
	str arg;

	base = s = GDKmalloc(len);
	if ( s == NULL)
		return s;
	if (flg) {
		s[0] = 0;
		t = s;
	} else {
		s[0] = '#';
		if (p->typechk == TYPE_UNKNOWN) {
			s[1] = '!';	/* error */
			s[2] = 0;
			t = s + 2;
		} else {
			s[1] = 0;
			t = s + 1;
		}
	}
	advance(t,base,len);
	if (p->token == REMsymbol) {
		/* do nothing */
	} else if (p->barrier) {
		if (p->barrier == LEAVEsymbol || 
			p->barrier == REDOsymbol || 
			p->barrier == RETURNsymbol || 
			p->barrier == YIELDsymbol || 
			p->barrier == RAISEsymbol) {
    			for(;tab>0;tab--) 
				*t++= ' ';
    			*t= 0;
    			advance(t,base,len);
		}
		snprintf(t,(len-(t-base)), "%s ", operatorName(p->barrier));
		advance(t,base,len);
	} else
	if( functionStart(p) && flg != LIST_MAL_CALL ){
		return fcnDefinition(mb, p, s, flg, base, len);
	} else if (!functionExit(p) && flg!=LIST_MAL_CALL) {
			// beautify with tabs
    		for(;tab>0;tab--) 
			*t++= ' ';
    		*t= 0;
    		advance(t,base,len);
	}
	switch (p->token<0?-p->token:p->token) {
	case FCNcall:
	case FACcall:
	case PATcall:
	case CMDcall:
	case ASSIGNsymbol :
		// is any variable explicit or used
		for (i = 0; i < p->retc; i++)
			if (!getVarTmp(mb, getArg(p, i)) || isVarUsed(mb, getArg(p, i)) || isVarUDFtype(mb,getArg(p,i)))
				break;

		if (i == p->retc)
			break;

		/* display multi-assignment list */
		if (p->retc > 1)
			*t++ = '(';

		for (i = 0; i < p->retc; i++) {
			arg= renderTerm(mb, stk, p, i, flg);
			snprintf(t,(len-(t-base)), "%s", arg);
			GDKfree(arg);
			advance(t,base,len);
			if (i < p->retc - 1)
				*t++ = ',';
		}
		if (p->retc > 1)
			*t++ = ')';

		if (p->argc > p->retc || getFunctionId(p)) {
			sprintf(t, " := ");
			t += 4;
		}
		*t = 0;
		break;
	case ENDsymbol:
		snprintf(t,(len-(t-base)), "end %s.%s", getModuleId(getInstrPtr(mb,0)), getFunctionId(getInstrPtr(mb, 0)));
		advance(t,base,len);
		break;
	case COMMANDsymbol:
	case FUNCTIONsymbol:
	case FACTORYsymbol:
	case PATTERNsymbol:
		if (flg & LIST_MAL_VALUE) {
			snprintf(t,(len-(t-base)), "%s ", operatorName(p->token));
			advance(t,base,len);
			break;
		}
		return fcnDefinition(mb, p, s, flg, base, len);
	case REMsymbol:
	case NOOPsymbol:
		if(getVar(mb, getArg(p, 0))->value.val.sval) 
			snprintf(t,(len-(t-base)), "#%s ", getVar(mb, getArg(p, 0))->value.val.sval);
		else
			snprintf(t, (len-(t-base)), "# ");
		break;
	default:
		snprintf(t,  (len-(t-base))," unknown symbol ?%d? ", p->token);
	}

	advance(t,base,len);
	if (getModuleId(p))
		snprintf(t,  (len-(t-base)),"%s.", getModuleId(p));
	advance(t,base,len);
	if (getFunctionId(p)) {
		snprintf(t, (len-(t-base)), "%s(", getFunctionId(p));
	} else if (p->argc > p->retc + 1)
		snprintf(t, (len-(t-base)), "(");
	advance(t,base,len);

	for (i = p->retc; i < p->argc; i++) {
		arg= renderTerm(mb, stk, p, i, flg);
		snprintf(t,(len-(t-base)), "%s", arg);
		GDKfree(arg);
		advance(t,base,len);

		if (i < p->argc -1){
			snprintf(t, (len-(t-base)), ",");
			advance(t,base,len);
		}
	} 
	if (getFunctionId(p) || p->argc > p->retc + 1)
		snprintf(t,(len-(t-base)), ")");
	advance(t,base,len);
	if (p->token != REMsymbol){
		snprintf(t,(len-(t-base)), ";");
		advance(t,base,len);
	}
	/* we may accidentally overwrite */
	if (t > s + len)
		GDKfatal("instruction2str:");
	return base;
}