Changeset: e76e18625d74 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e76e18625d74 Added Files: tools/mserver/shutdowntest.c Modified Files: monetdb5/mal/mal_stack.c tools/mserver/Makefile.ag Branch: default Log Message:
Add shutdowntest.c program for testing in-process shutdown. diffs (truncated from 331 to 300 lines): diff --git a/monetdb5/mal/mal_stack.c b/monetdb5/mal/mal_stack.c --- a/monetdb5/mal/mal_stack.c +++ b/monetdb5/mal/mal_stack.c @@ -98,7 +98,11 @@ void clearStack(MalStkPtr s) { ValPtr v; - int i = s->stktop; + int i; + + if (!s) return; + + i = s->stktop; for (v = s->stk; i >= 0; i--, v++) if (ATOMextern(v->vtype) && v->val.pval) { diff --git a/tools/mserver/Makefile.ag b/tools/mserver/Makefile.ag --- a/tools/mserver/Makefile.ag +++ b/tools/mserver/Makefile.ag @@ -15,6 +15,13 @@ INCLUDES = ../../monetdb5/mal \ ../../common/stream \ ../../common/utils \ ../../common/options \ + ../../monetdb5/modules/atoms \ + ../../monetdb5/modules/mal \ + ../../sql/backends/monet5 \ + ../../sql/common \ + ../../sql/include \ + ../../sql/server \ + ../../sql/storage \ $(openssl_CFLAGS) $(pcre_CFLAGS) $(libxml2_CFLAGS) headers_docx = { @@ -44,3 +51,11 @@ bin_mserver5 = { $(curl_LIBS) $(pcre_LIBS) $(openssl_LIBS) $(PSAPILIB) \ $(SOCKET_LIBS) $(MALLOC_LIBS) $(DL_LIBS) $(PTHREAD_LIBS) } + +bin_shutdowntest = { + SOURCES = shutdowntest.c + LIBS = ../../monetdb5/tools/libmonetdb5 \ + ../../gdk/libbat ../../common/stream/libstream \ + $(curl_LIBS) $(pcre_LIBS) $(openssl_LIBS) $(PSAPILIB) \ + $(SOCKET_LIBS) $(MALLOC_LIBS) $(DL_LIBS) $(PTHREAD_LIBS) +} diff --git a/tools/mserver/shutdowntest.c b/tools/mserver/shutdowntest.c new file mode 100644 --- /dev/null +++ b/tools/mserver/shutdowntest.c @@ -0,0 +1,281 @@ + +#include "monetdb_config.h" +#include <stdio.h> +#include <errno.h> +#include <string.h> /* strerror */ +#include <locale.h> +#include "monet_options.h" +#include "mal.h" +#include "mal_session.h" +#include "mal_import.h" +#include "mal_client.h" +#include "mal_function.h" +#include "monet_version.h" +#include "mal_authorize.h" +#include "msabaoth.h" +#include "mutils.h" +#include "mal_linker.h" +#include "sql_execute.h" +#include "sql_scenario.h" + +#define CREATE_SQL_FUNCTION_PTR(retval, fcnname) \ + typedef retval (*fcnname##_ptr_tpe)(); \ + fcnname##_ptr_tpe fcnname##_ptr = NULL; + +#define LOAD_SQL_FUNCTION_PTR(fcnname) \ + fcnname##_ptr = (fcnname##_ptr_tpe) getAddress(NULL, "lib_sql.so", #fcnname, 0); \ + if (fcnname##_ptr == NULL) { \ + retval = GDKstrdup(#fcnname); \ + } + +CREATE_SQL_FUNCTION_PTR(int,SQLautocommit); +CREATE_SQL_FUNCTION_PTR(str,SQLexitClient); +CREATE_SQL_FUNCTION_PTR(str,SQLinitClient); +CREATE_SQL_FUNCTION_PTR(str,SQLstatementIntern); + + +static int monetdb_initialized = 0; + +static void* monetdb_connect(void) { + Client conn = NULL; + if (!monetdb_initialized) { + return NULL; + } + conn = MCforkClient(&mal_clients[0]); + if (!MCvalid((Client) conn)) { + return NULL; + } + if ((SQLinitClient_ptr)(conn) != MAL_SUCCEED) { + return NULL; + } + ((backend *) conn->sqlcontext)->mvc->session->auto_commit = 1; + return conn; +} + +static void monetdb_disconnect(void* conn) { + if (!MCvalid((Client) conn)) { + return; + } + (SQLexitClient_ptr)((Client) conn); + MCcloseClient((Client) conn); +} + +static str monetdb_initialize() { + opt *set = NULL; + volatile int setlen = 0; + str retval = MAL_SUCCEED; + char* sqres = NULL; + void* res = NULL; + void* c; + char* dbdir = "/tmp/dbfarm"; // FIXME + char prmodpath[1024]; + char *modpath = NULL; + char *binpath = NULL; + + if (monetdb_initialized) return MAL_SUCCEED; + monetdb_initialized = 1; + + if (setlocale(LC_CTYPE, "") == NULL) { + retval = GDKstrdup("setlocale() failed"); + goto cleanup; + } + + GDKfataljumpenable = 1; + if(setjmp(GDKfataljump) != 0) { + retval = GDKfatalmsg; + // we will get here if GDKfatal was called. + if (retval == NULL) { + retval = GDKstrdup("GDKfatal() with unspecified error?"); + } + goto cleanup; + } + + binpath = get_bin_path(); + + setlen = mo_builtin_settings(&set); + setlen = mo_add_option(&set, setlen, opt_cmdline, "gdk_dbpath", dbdir); + + BBPaddfarm(dbdir, (1 << PERSISTENT) | (1 << TRANSIENT)); + if (GDKinit(set, setlen) == 0) { + retval = GDKstrdup("GDKinit() failed"); + goto cleanup; + } + + GDKsetenv("mapi_disable", "true"); + + 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); + } + + /* configure sabaoth to use the right dbpath and active database */ + msab_dbpathinit(GDKgetenv("gdk_dbpath")); + /* wipe out all cruft, if left over */ + if ((retval = msab_wildRetreat()) != NULL) { + /* just swallow the error */ + free(retval); + } + /* From this point, the server should exit cleanly. Discussion: + * even earlier? Sabaoth here registers the server is starting up. */ + if ((retval = msab_registerStarting()) != NULL) { + /* throw the error at the user, but don't die */ + fprintf(stderr, "!%s\n", retval); + free(retval); + } + + { + str lang = "mal"; + /* we inited mal before, so publish its existence */ + if ((retval = msab_marchScenario(lang)) != NULL) { + /* throw the error at the user, but don't die */ + fprintf(stderr, "!%s\n", retval); + free(retval); + } + } + + { + /* 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 ((retval = AUTHunlockVault(&secretp)) != MAL_SUCCEED) { + /* don't show this as a crash */ + msab_registerStop(); + GDKfatal("%s", retval); + } + } + /* make sure the authorisation BATs are loaded */ + if ((retval = AUTHinitTables(NULL)) != MAL_SUCCEED) { + /* don't show this as a crash */ + msab_registerStop(); + GDKfatal("%s", retval); + } + + if (mal_init() != 0) { // mal_init() does not return meaningful codes on failure + retval = GDKstrdup("mal_init() failed"); + goto cleanup; + } + GDKfataljumpenable = 0; + + LOAD_SQL_FUNCTION_PTR(SQLautocommit); + LOAD_SQL_FUNCTION_PTR(SQLexitClient); + LOAD_SQL_FUNCTION_PTR(SQLinitClient); + LOAD_SQL_FUNCTION_PTR(SQLstatementIntern); + + if (retval != MAL_SUCCEED) { + printf("Failed to load SQL function: %s\n", retval); + goto cleanup; + } + + { + Client c = (Client) monetdb_connect(); + char* query = "SELECT * FROM tables;"; + mvc* m = ((backend *) c->sqlcontext)->mvc; + res_table* res; + retval = (SQLstatementIntern_ptr)(c, + &query, + "name", + 1, 0, &res); + (SQLautocommit_ptr)(c, m); + if (retval != MAL_SUCCEED) { + retval = GDKstrdup("Failed to execute SQL query.\n"); + goto cleanup; + } + + + monetdb_disconnect(c); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list