LCOV - code coverage report
Current view: top level - monetdb5/mal - mal_embedded.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 56 91 61.5 %
Date: 2024-04-26 00:35:57 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * (author) M.L. Kersten
      15             :  * These routines assume that the signatures for all MAL files are defined as text in mal_embedded.h
      16             :  * They are parsed upon system restart without access to their source files.
      17             :  * This way the definitions are part of the library upon compilation.
      18             :  * It assumes that all necessary libraries are already loaded.
      19             :  * A failure to bind the address in the context of an embedded version is not considered an error.
      20             :  */
      21             : 
      22             : #include "monetdb_config.h"
      23             : 
      24             : #include "mal_embedded.h"
      25             : #include "mal_builder.h"
      26             : #include "mal_stack.h"
      27             : #include "mal_linker.h"
      28             : #include "mal_session.h"
      29             : #include "mal_scenario.h"
      30             : #include "mal_parser.h"
      31             : #include "mal_interpreter.h"
      32             : #include "mal_namespace.h"            /* for initNamespace() */
      33             : #include "mal_client.h"
      34             : #include "mal_dataflow.h"
      35             : #include "mal_private.h"
      36             : #include "mal_internal.h"
      37             : #include "mal_runtime.h"
      38             : #include "mal_atom.h"
      39             : #include "mal_resource.h"
      40             : #include "mal_atom.h"
      41             : #include "msabaoth.h"
      42             : #include "mal_authorize.h"
      43             : #include "mal_profiler.h"
      44             : #include "mutils.h"
      45             : 
      46             : static bool embeddedinitialized = false;
      47             : 
      48             : str
      49           1 : malEmbeddedBoot(int workerlimit, int memorylimit, int querytimeout,
      50             :                                 int sessiontimeout, bool with_mapi_server)
      51             : {
      52           1 :         Client c;
      53           1 :         QryCtx *qc_old;
      54           1 :         str msg = MAL_SUCCEED;
      55             : 
      56           1 :         if (embeddedinitialized)
      57             :                 return MAL_SUCCEED;
      58             : 
      59           1 :         mal_startup();
      60             :         {
      61             :                 /* unlock the vault, first see if we can find the file which
      62             :                  * holds the secret */
      63           1 :                 char secret[1024];
      64           1 :                 FILE *secretf;
      65           1 :                 size_t len;
      66             : 
      67           1 :                 if (GDKinmemory(0) || GDKgetenv("monet_vault_key") == NULL) {
      68             :                         /* use a default (hard coded, non safe) key */
      69           1 :                         snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8");
      70             :                 } else {
      71           0 :                         if ((secretf = MT_fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) {
      72           0 :                                 throw(MAL, "malEmbeddedBoot",
      73             :                                           "unable to open vault_key_file %s: %s\n",
      74           0 :                                           GDKgetenv("monet_vault_key"), strerror(errno));
      75             :                         }
      76           0 :                         len = fread(secret, 1, sizeof(secret) - 1, secretf);
      77           0 :                         fclose(secretf);
      78           0 :                         secret[len] = '\0';
      79           0 :                         len = strlen(secret);   /* secret can contain null-bytes */
      80           0 :                         if (len == 0) {
      81           0 :                                 throw(MAL, "malEmbeddedBoot", "vault key has zero-length!\n");
      82           0 :                         } else if (len < 5) {
      83           0 :                                 throw(MAL, "malEmbeddedBoot",
      84             :                                           "#warning: your vault key is too short "
      85             :                                           "(%zu), enlarge your vault key!\n", len);
      86             :                         }
      87             :                 }
      88           1 :                 if ((msg = AUTHunlockVault(secret)) != MAL_SUCCEED) {
      89             :                         /* don't show this as a crash */
      90             :                         return msg;
      91             :                 }
      92             :         }
      93             : 
      94           1 :         if (!MCinit())
      95           0 :                 throw(MAL, "malEmbeddedBoot", "Failed to initialize clients structure");
      96             :         // monet_memory = MT_npages() * MT_pagesize();
      97           1 :         initNamespace();
      98           1 :         initHeartbeat();
      99             :         // initResource();
     100           1 :         qc_old = MT_thread_get_qry_ctx();
     101           1 :         c = MCinitClient((oid) 0, 0, 0);
     102           1 :         if (c == NULL)
     103           0 :                 throw(MAL, "malEmbeddedBoot", "Failed to initialize client");
     104           1 :         c->workerlimit = workerlimit;
     105           1 :         c->memorylimit = memorylimit;
     106           1 :         c->querytimeout = querytimeout * 1000000;    // from sec to usec
     107           1 :         c->qryctx.endtime = c->qryctx.starttime && c->querytimeout ? c->qryctx.starttime + c->querytimeout : 0;
     108           1 :         c->sessiontimeout = sessiontimeout * 1000000;
     109           1 :         c->curmodule = c->usermodule = userModule();
     110           1 :         if (c->usermodule == NULL) {
     111           0 :                 MCcloseClient(c);
     112           0 :                 MT_thread_set_qry_ctx(qc_old);
     113           0 :                 throw(MAL, "malEmbeddedBoot", "Failed to initialize client MAL module");
     114             :         }
     115           1 :         if ((msg = defaultScenario(c))) {
     116           0 :                 MCcloseClient(c);
     117           0 :                 MT_thread_set_qry_ctx(qc_old);
     118           0 :                 return msg;
     119             :         }
     120           1 :         if ((msg = MSinitClientPrg(c, "user", "main")) != MAL_SUCCEED) {
     121           0 :                 MCcloseClient(c);
     122           0 :                 MT_thread_set_qry_ctx(qc_old);
     123           0 :                 return msg;
     124             :         }
     125           1 :         char *modules[6] = { "embedded", "sql", "generator", "udf", "csv" };
     126           1 :         if ((msg = malIncludeModules(c, modules, 0, !with_mapi_server, NULL)) != MAL_SUCCEED) {
     127           0 :                 MCcloseClient(c);
     128           0 :                 MT_thread_set_qry_ctx(qc_old);
     129           0 :                 return msg;
     130             :         }
     131           1 :         pushEndInstruction(c->curprg->def);
     132             : #if 0
     133             :         msg = chkProgram(c->usermodule, c->curprg->def);
     134             :         if (msg != MAL_SUCCEED || (msg = c->curprg->def->errors) != MAL_SUCCEED) {
     135             :                 MCcloseClient(c);
     136             :                 MT_thread_set_qry_ctx(qc_old);
     137             :                 return msg;
     138             :         }
     139             :         msg = MALengine(c);
     140             : #endif
     141           1 :         if (msg == MAL_SUCCEED)
     142           1 :                 embeddedinitialized = true;
     143           1 :         MCcloseClient(c);
     144           1 :         MT_thread_set_qry_ctx(qc_old);
     145           1 :         initProfiler();
     146           1 :         return msg;
     147             : }
     148             : 
     149             : /*
     150             :  * Upon exit we should attempt to remove all allocated memory explicitly.
     151             :  * This seemingly superflous action is necessary to simplify analyis of
     152             :  * memory leakage problems later ons and to allow an embedded server to
     153             :  * restart the server properly.
     154             :  *
     155             :  * It is the responsibility of the enclosing application to finish/cease all
     156             :  * activity first.
     157             :  * This function should be called after you have issued sql_reset();
     158             :  */
     159             : 
     160             : void
     161           1 : malEmbeddedReset(void)                  //remove extra modules and set to non-initialized again
     162             : {
     163           1 :         if (!embeddedinitialized)
     164             :                 return;
     165             : 
     166           1 :         GDKprepareExit();
     167           1 :         MCstopClients(0);
     168           1 :         setHeartbeat(-1);
     169           1 :         stopProfiler(0);
     170           1 :         AUTHreset();
     171           1 :         if (!GDKinmemory(0) && !GDKembedded()) {
     172           0 :                 str err = 0;
     173             : 
     174           0 :                 if ((err = msab_wildRetreat()) !=NULL) {
     175           0 :                         TRC_ERROR(MAL_SERVER, "%s\n", err);
     176           0 :                         free(err);
     177             :                 }
     178           0 :                 if ((err = msab_registerStop()) !=NULL) {
     179           0 :                         TRC_ERROR(MAL_SERVER, "%s\n", err);
     180           0 :                         free(err);
     181             :                 }
     182             :         }
     183           1 :         mal_dataflow_reset();
     184           1 :         mal_client_reset();
     185           1 :         mal_linker_reset();
     186           1 :         mal_resource_reset();
     187           1 :         mal_runtime_reset();
     188           1 :         mal_module_reset();
     189           1 :         mal_atom_reset();
     190             : 
     191           1 :         memset((char *) monet_cwd, 0, sizeof(monet_cwd));
     192           1 :         memset((char *) monet_characteristics, 0, sizeof(monet_characteristics));
     193           1 :         mal_namespace_reset();
     194             :         /* No need to clean up the namespace, it will simply be extended
     195             :          * upon restart mal_namespace_reset(); */
     196           1 :         GDKreset(0);                            // terminate all other threads
     197           1 :         embeddedinitialized = false;
     198             : }
     199             : 
     200             : /* stopping clients should be done with care, as they may be in the mids of
     201             :  * transactions. One safe place is between MAL instructions, which would
     202             :  * abort the transaction by raising an exception. All sessions are
     203             :  * terminate this way.
     204             :  * We should also ensure that no new client enters the scene while shutting down.
     205             :  * For this we mark the client records as BLOCKCLIENT.
     206             :  */
     207             : 
     208             : void
     209           0 : malEmbeddedStop(int status)
     210             : {
     211           0 :         malEmbeddedReset();
     212           0 :         exit(status);                           /* properly end GDK */
     213             : }

Generated by: LCOV version 1.14