LCOV - code coverage report
Current view: top level - monetdb5/mal - mal_embedded.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 54 89 60.7 %
Date: 2024-04-25 20:03:45 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             :         {
      60             :                 /* unlock the vault, first see if we can find the file which
      61             :                  * holds the secret */
      62           1 :                 char secret[1024];
      63           1 :                 FILE *secretf;
      64           1 :                 size_t len;
      65             : 
      66           1 :                 if (GDKinmemory(0) || GDKgetenv("monet_vault_key") == NULL) {
      67             :                         /* use a default (hard coded, non safe) key */
      68           1 :                         snprintf(secret, sizeof(secret), "%s", "Xas632jsi2whjds8");
      69             :                 } else {
      70           0 :                         if ((secretf = MT_fopen(GDKgetenv("monet_vault_key"), "r")) == NULL) {
      71           0 :                                 throw(MAL, "malEmbeddedBoot",
      72             :                                           "unable to open vault_key_file %s: %s\n",
      73           0 :                                           GDKgetenv("monet_vault_key"), strerror(errno));
      74             :                         }
      75           0 :                         len = fread(secret, 1, sizeof(secret) - 1, secretf);
      76           0 :                         fclose(secretf);
      77           0 :                         secret[len] = '\0';
      78           0 :                         len = strlen(secret);   /* secret can contain null-bytes */
      79           0 :                         if (len == 0) {
      80           0 :                                 throw(MAL, "malEmbeddedBoot", "vault key has zero-length!\n");
      81           0 :                         } else if (len < 5) {
      82           0 :                                 throw(MAL, "malEmbeddedBoot",
      83             :                                           "#warning: your vault key is too short "
      84             :                                           "(%zu), enlarge your vault key!\n", len);
      85             :                         }
      86             :                 }
      87           1 :                 if ((msg = AUTHunlockVault(secret)) != MAL_SUCCEED) {
      88             :                         /* don't show this as a crash */
      89             :                         return msg;
      90             :                 }
      91             :         }
      92             : 
      93           1 :         if (!MCinit())
      94           0 :                 throw(MAL, "malEmbeddedBoot", "Failed to initialize clients structure");
      95             :         // monet_memory = MT_npages() * MT_pagesize();
      96           1 :         initNamespace();
      97           1 :         initHeartbeat();
      98             :         // initResource();
      99           1 :         qc_old = MT_thread_get_qry_ctx();
     100           1 :         c = MCinitClient((oid) 0, 0, 0);
     101           1 :         if (c == NULL)
     102           0 :                 throw(MAL, "malEmbeddedBoot", "Failed to initialize client");
     103           1 :         c->workerlimit = workerlimit;
     104           1 :         c->memorylimit = memorylimit;
     105           1 :         c->qryctx.querytimeout = querytimeout * 1000000;     // from sec to usec
     106           1 :         c->sessiontimeout = sessiontimeout * 1000000;
     107           1 :         c->curmodule = c->usermodule = userModule();
     108           1 :         if (c->usermodule == NULL) {
     109           0 :                 MCcloseClient(c);
     110           0 :                 MT_thread_set_qry_ctx(qc_old);
     111           0 :                 throw(MAL, "malEmbeddedBoot", "Failed to initialize client MAL module");
     112             :         }
     113           1 :         if ((msg = defaultScenario(c))) {
     114           0 :                 MCcloseClient(c);
     115           0 :                 MT_thread_set_qry_ctx(qc_old);
     116           0 :                 return msg;
     117             :         }
     118           1 :         if ((msg = MSinitClientPrg(c, "user", "main")) != MAL_SUCCEED) {
     119           0 :                 MCcloseClient(c);
     120           0 :                 MT_thread_set_qry_ctx(qc_old);
     121           0 :                 return msg;
     122             :         }
     123           1 :         char *modules[6] = { "embedded", "sql", "generator", "udf", "csv" };
     124           1 :         if ((msg = malIncludeModules(c, modules, 0, !with_mapi_server, NULL)) != MAL_SUCCEED) {
     125           0 :                 MCcloseClient(c);
     126           0 :                 MT_thread_set_qry_ctx(qc_old);
     127           0 :                 return msg;
     128             :         }
     129           1 :         pushEndInstruction(c->curprg->def);
     130             : #if 0
     131             :         msg = chkProgram(c->usermodule, c->curprg->def);
     132             :         if (msg != MAL_SUCCEED || (msg = c->curprg->def->errors) != MAL_SUCCEED) {
     133             :                 MCcloseClient(c);
     134             :                 MT_thread_set_qry_ctx(qc_old);
     135             :                 return msg;
     136             :         }
     137             :         msg = MALengine(c);
     138             : #endif
     139           1 :         if (msg == MAL_SUCCEED)
     140           1 :                 embeddedinitialized = true;
     141           1 :         MCcloseClient(c);
     142           1 :         MT_thread_set_qry_ctx(qc_old);
     143           1 :         initProfiler();
     144           1 :         return msg;
     145             : }
     146             : 
     147             : /*
     148             :  * Upon exit we should attempt to remove all allocated memory explicitly.
     149             :  * This seemingly superflous action is necessary to simplify analyis of
     150             :  * memory leakage problems later ons and to allow an embedded server to
     151             :  * restart the server properly.
     152             :  *
     153             :  * It is the responsibility of the enclosing application to finish/cease all
     154             :  * activity first.
     155             :  * This function should be called after you have issued sql_reset();
     156             :  */
     157             : 
     158             : void
     159           1 : malEmbeddedReset(void)                  //remove extra modules and set to non-initialized again
     160             : {
     161           1 :         if (!embeddedinitialized)
     162             :                 return;
     163             : 
     164           1 :         GDKprepareExit();
     165           1 :         MCstopClients(0);
     166           1 :         setHeartbeat(-1);
     167           1 :         stopProfiler(0);
     168           1 :         AUTHreset();
     169           1 :         if (!GDKinmemory(0) && !GDKembedded()) {
     170           0 :                 str err = 0;
     171             : 
     172           0 :                 if ((err = msab_wildRetreat()) !=NULL) {
     173           0 :                         TRC_ERROR(MAL_SERVER, "%s\n", err);
     174           0 :                         free(err);
     175             :                 }
     176           0 :                 if ((err = msab_registerStop()) !=NULL) {
     177           0 :                         TRC_ERROR(MAL_SERVER, "%s\n", err);
     178           0 :                         free(err);
     179             :                 }
     180             :         }
     181           1 :         mal_dataflow_reset();
     182           1 :         mal_client_reset();
     183           1 :         mal_linker_reset();
     184           1 :         mal_resource_reset();
     185           1 :         mal_runtime_reset();
     186           1 :         mal_module_reset();
     187           1 :         mal_atom_reset();
     188             : 
     189           1 :         memset((char *) monet_cwd, 0, sizeof(monet_cwd));
     190           1 :         memset((char *) monet_characteristics, 0, sizeof(monet_characteristics));
     191           1 :         mal_namespace_reset();
     192             :         /* No need to clean up the namespace, it will simply be extended
     193             :          * upon restart mal_namespace_reset(); */
     194           1 :         GDKreset(0);                            // terminate all other threads
     195           1 :         embeddedinitialized = false;
     196             : }
     197             : 
     198             : /* stopping clients should be done with care, as they may be in the mids of
     199             :  * transactions. One safe place is between MAL instructions, which would
     200             :  * abort the transaction by raising an exception. All sessions are
     201             :  * terminate this way.
     202             :  * We should also ensure that no new client enters the scene while shutting down.
     203             :  * For this we mark the client records as BLOCKCLIENT.
     204             :  */
     205             : 
     206             : void
     207           0 : malEmbeddedStop(int status)
     208             : {
     209           0 :         malEmbeddedReset();
     210           0 :         exit(status);                           /* properly end GDK */
     211             : }

Generated by: LCOV version 1.14