Using env vars
authorJeroen van der Heijden <jeroen@transceptor.technology>
Wed, 22 Apr 2020 07:59:09 +0000 (09:59 +0200)
committerJeroen van der Heijden <jeroen@transceptor.technology>
Wed, 22 Apr 2020 07:59:09 +0000 (09:59 +0200)
12 files changed:
Debug/src/siri/subdir.mk
Release/src/siri/subdir.mk
include/siri/cfg/cfg.h
include/siri/net/tcp.h
include/siri/siri.h
include/siri/version.h
main.c
src/siri/cfg/cfg.c
src/siri/evars.c
src/siri/net/tcp.c
src/siri/service/account.c
src/siri/siri.c

index 0ee94fb2e54fac593334380a13da9026786b5779..bcbba4998ecff50df426791bbecccfbf4103e340 100644 (file)
@@ -5,6 +5,7 @@ C_SRCS += \
 ../src/siri/backup.c \
 ../src/siri/buffersync.c \
 ../src/siri/err.c \
+../src/siri/evars.c \
 ../src/siri/health.c \
 ../src/siri/heartbeat.c \
 ../src/siri/optimize.c \
@@ -17,6 +18,7 @@ OBJS += \
 ./src/siri/backup.o \
 ./src/siri/buffersync.o \
 ./src/siri/err.o \
+./src/siri/evars.o \
 ./src/siri/health.o \
 ./src/siri/heartbeat.o \
 ./src/siri/optimize.o \
@@ -29,6 +31,7 @@ C_DEPS += \
 ./src/siri/backup.d \
 ./src/siri/buffersync.d \
 ./src/siri/err.d \
+./src/siri/evars.d \
 ./src/siri/health.d \
 ./src/siri/heartbeat.d \
 ./src/siri/optimize.d \
index d22d9d8aa64069db7e6637a50eca6aa0ec6d7182..7effb5cb943e8916b7fa96ff916baa34c8587007 100644 (file)
@@ -5,6 +5,7 @@ C_SRCS += \
 ../src/siri/backup.c \
 ../src/siri/buffersync.c \
 ../src/siri/err.c \
+../src/siri/evars.c \
 ../src/siri/health.c \
 ../src/siri/heartbeat.c \
 ../src/siri/optimize.c \
@@ -17,6 +18,7 @@ OBJS += \
 ./src/siri/backup.o \
 ./src/siri/buffersync.o \
 ./src/siri/err.o \
+./src/siri/evars.o \
 ./src/siri/health.o \
 ./src/siri/heartbeat.o \
 ./src/siri/optimize.o \
@@ -29,6 +31,7 @@ C_DEPS += \
 ./src/siri/backup.d \
 ./src/siri/buffersync.d \
 ./src/siri/err.d \
+./src/siri/evars.d \
 ./src/siri/health.d \
 ./src/siri/heartbeat.d \
 ./src/siri/optimize.d \
index d6215401cbb047f814689ffc021b4cda3a185445..49d197c9fa3fe970d8489d0c506c669384e95453 100644 (file)
@@ -8,6 +8,13 @@ typedef struct siri_cfg_s siri_cfg_t;
 
 #define SIRI_CFG_MAX_LEN_ADDRESS 256
 
+/* do not use more than x percent for the max limit for open sharding files */
+#define RLIMIT_PERC_FOR_SHARDING 0.5
+
+#define MAX_OPEN_FILES_LIMIT 32768
+#define MIN_OPEN_FILES_LIMIT 3
+#define DEFAULT_OPEN_FILES_LIMIT MAX_OPEN_FILES_LIMIT
+
 #include <inttypes.h>
 #include <limits.h>
 #include <siri/siri.h>
index 4612c9734e657662f4d3e87e061554ba6dc954c5..ce13dcfd0d12609ede3429ff49fadb03670c9c1a 100644 (file)
@@ -17,5 +17,9 @@ enum
 int dns_req_family_map[3];
 const char * sirinet_tcp_ip_support_str(uint8_t ip_support);
 char * sirinet_tcp_name(uv_tcp_t * client);
+int sirinet_extract_addr_port(
+        char * s,
+        char * addr,
+        uint16_t * port);
 
 #endif  /* SIRINET_TCP_H_ */
index a029c279930b16559c993d5a7a887c2d885cfc5a..b780de82523c5b149510a1b5e8eebccd08c8d626 100644 (file)
@@ -54,6 +54,8 @@ extern siri_t siri;
 void siri_setup_logger(void);
 int siri_start(void);
 void siri_free(void);
+int make_database_directory(void);
+void set_max_open_files_limit(void);
 
 struct siri_s
 {
index b3e532ec705eccb20b4556e8a64b7eea8a7a643e..96b8ffc4c89848a3d618df6408bc066744963438 100644 (file)
@@ -15,7 +15,7 @@
  * Note that debian alpha packages should use versions like this:
  *   2.0.34-0alpha0
  */
-#define SIRIDB_VERSION_PRE_RELEASE "-alpha-1"
+#define SIRIDB_VERSION_PRE_RELEASE "-alpha-2"
 
 #ifndef NDEBUG
 #define SIRIDB_VERSION_BUILD_RELEASE "+debug"
diff --git a/main.c b/main.c
index 0ee8e7468d221d8b47b28f6e8239355c5cd10994..5ab27cef8f1fdf44cd7cbe82e4a828cbcdf2835d 100644 (file)
--- a/main.c
+++ b/main.c
@@ -59,6 +59,13 @@ int main(int argc, char * argv[])
 
     siri_evars_parse(&siri);
 
+    if (make_database_directory())
+    {
+        exit(1);
+    }
+
+    set_max_open_files_limit();
+
     /* start SiriDB. (this start the event loop etc.) */
     if (siri_start() && !siri_err)
     {
index 8bb840b5886ec4132ea6f420dc0d8d6a5bffbc46..3af712f468e4aea15df030a699d78d3719b4d3dd 100644 (file)
 #include <sys/resource.h>
 #include <siri/net/tcp.h>
 
-/* do not use more than x percent for the max limit for open sharding files */
-#define RLIMIT_PERC_FOR_SHARDING 0.5
-
-#define MAX_OPEN_FILES_LIMIT 32768
-#define MIN_OPEN_FILES_LIMIT 3
-#define DEFAULT_OPEN_FILES_LIMIT MAX_OPEN_FILES_LIMIT
-
 static siri_cfg_t siri_cfg = {
         .http_status_port=0,    /* 0=disabled, 1-16535=enabled */
         .http_api_port=0,       /* 0=disabled, 1-16535=enabled */
@@ -34,7 +27,7 @@ static siri_cfg_t siri_cfg = {
         .ip_support=IP_SUPPORT_ALL,
         .shard_compression=0,
         .server_address="localhost",
-        .default_db_path="/var/lib/siridb/",
+        .default_db_path="",
         .pipe_support=0,
         .pipe_client_name="siridb_client.sock",
         .buffer_sync_interval=0,
@@ -75,12 +68,12 @@ void siri_cfg_init(siri_t * siri)
         /* we could choose to continue with defaults but this is probably
          * not what users want so lets quit.
          */
-        log_critical(
-                "Cannot read '%s' (%s)\n",
+        log_debug(
+                "Not using configuration file '%s' (%s)\n",
                 siri->args->config,
                 cfgparser_errmsg(rc));
         cfgparser_free(cfgparser);
-        exit(EXIT_FAILURE);
+        return;
     }
 
     SIRI_CFG_read_address_port(
@@ -90,6 +83,7 @@ void siri_cfg_init(siri_t * siri)
             &siri_cfg.listen_backend_port);
 
     tmp = siri_cfg.listen_client_port;
+
     SIRI_CFG_read_uint(
             cfgparser,
             "listen_client_port",
@@ -190,40 +184,36 @@ static void SIRI_CFG_read_uint(
     if (rc != CFGPARSER_SUCCESS)
     {
         log_warning(
-                "Missing '%s' in '%s' (%s). "
-                "Using default value: %u",
+                "Missing '%s' in '%s' (%s). ",
                 option_name,
                 siri.args->config,
-                cfgparser_errmsg(rc),
-                *value);
+                cfgparser_errmsg(rc));
+        return;
     }
-    else if (option->tp != CFGPARSER_TP_INTEGER)
+
+    if (option->tp != CFGPARSER_TP_INTEGER)
     {
         log_warning(
-                "Error reading '%s' in '%s': %s. "
-                "Using default value: %u",
+                "Error reading '%s' in '%s': %s.",
                 option_name,
                 siri.args->config,
-                "error: expecting an integer value",
-                *value);
+                "error: expecting an integer value");
+        return;
     }
-    else if (option->val->integer < min || option->val->integer > max)
+
+    if (option->val->integer < min || option->val->integer > max)
     {
         log_warning(
                 "Error reading '%s' in '%s': "
-                "error: value should be between %d and %d but got %d. "
-                "Using default value: %u",
+                "error: value should be between %d and %d but got %d.",
                 option_name,
                 siri.args->config,
                 min,
                 max,
-                option->val->integer,
-                *value);
-    }
-    else
-    {
-        *value = option->val->integer;
+                option->val->integer);
+        return;
     }
+    *value = option->val->integer;
 }
 
 static void SIRI_CFG_read_ip_support(cfgparser_t * cfgparser)
@@ -238,22 +228,16 @@ static void SIRI_CFG_read_ip_support(cfgparser_t * cfgparser)
     if (rc != CFGPARSER_SUCCESS)
     {
         log_warning(
-                "Missing '%s' in '%s' (%s). "
-                "Using default value: '%s'",
-                "ip_support",
+                "Missing 'ip_support' in '%s' (%s).",
                 siri.args->config,
-                cfgparser_errmsg(rc),
-                sirinet_tcp_ip_support_str(siri_cfg.ip_support));
+                cfgparser_errmsg(rc));
     }
     else if (option->tp != CFGPARSER_TP_STRING)
     {
         log_warning(
-                "Error reading '%s' in '%s': %s. "
-                "Using default value: '%s'",
-                "ip_support",
+                "Error reading 'ip_support' in '%s': %s.",
                 siri.args->config,
-                "error: expecting a string value",
-                sirinet_tcp_ip_support_str(siri_cfg.ip_support));
+                "error: expecting a string value");
     }
     else
     {
@@ -272,13 +256,10 @@ static void SIRI_CFG_read_ip_support(cfgparser_t * cfgparser)
         else
         {
             log_warning(
-                    "Error reading '%s' in '%s': "
-                    "error: expecting ALL, IPV4ONLY or IPV6ONLY but got '%s'. "
-                    "Using default value: '%s'",
-                    "ip_support",
+                    "Error reading 'ip_support' in '%s': "
+                    "error: expecting ALL, IPV4ONLY or IPV6ONLY but got '%s'.",
                     siri.args->config,
-                    option->val->string,
-                    sirinet_tcp_ip_support_str(siri_cfg.ip_support));
+                    option->val->string);
         }
     }
 }
@@ -406,127 +387,85 @@ static void SIRI_CFG_read_pipe_client_name(cfgparser_t * cfgparser)
     if (rc != CFGPARSER_SUCCESS)
     {
         log_warning(
-                "Missing '%s' in '%s' (%s). "
-                "Using default value: '%s'",
-                "pipe_client_name",
+                "Missing 'pipe_client_name' in '%s' (%s).",
                 siri.args->config,
-                cfgparser_errmsg(rc),
-                siri_cfg.pipe_client_name);
+                cfgparser_errmsg(rc));
+        return;
     }
-    else if (option->tp != CFGPARSER_TP_STRING)
+
+    if (option->tp != CFGPARSER_TP_STRING)
     {
         log_warning(
-                "Error reading '%s' in '%s': %s. "
-                "Using default value: '%s'",
-                "pipe_client_name",
+                "Error reading 'pipe_client_name' in '%s': %s.",
                 siri.args->config,
-                "error: expecting a string value",
-                siri_cfg.pipe_client_name);
+                "error: expecting a string value");
+        return;
     }
-    else
+
+    len = strlen(option->val->string);
+    if (len > XPATH_MAX-2)
     {
-        len = strlen(option->val->string);
-        if (len > XPATH_MAX-2)
-        {
-            log_warning(
-                    "Pipe client name exceeds %d characters, please "
-                    "check your configuration file: %s. "
-                    "Using default value: '%s'",
-                    XPATH_MAX-2,
-                    siri.args->config,
-                    siri_cfg.pipe_client_name);
-        }
-        else if (len == 0)
-        {
-            log_warning(
-                    "Pipe client should not be an empty string, please "
-                    "check your configuration file: %s. "
-                    "Using default value: '%s'",
-                    siri.args->config,
-                    siri_cfg.pipe_client_name);
-        }
-        else
-        {
-            strcpy(siri_cfg.pipe_client_name, option->val->string);
-        }
+        log_warning(
+                "Pipe client name exceeds %d characters, please "
+                "check your configuration file: %s.",
+                XPATH_MAX-2,
+                siri.args->config);
+        return;
+    }
+
+    if (len == 0)
+    {
+        log_warning(
+                "Pipe client should not be an empty string, please "
+                "check your configuration file: %s.",
+                siri.args->config);
+        return;
     }
+
+    strcpy(siri_cfg.pipe_client_name, option->val->string);
 }
 
 static void SIRI_CFG_read_default_db_path(cfgparser_t * cfgparser)
 {
     cfgparser_option_t * option;
     cfgparser_return_t rc;
-    size_t len;
     rc = cfgparser_get_option(
                 &option,
                 cfgparser,
                 "siridb",
                 "default_db_path");
+
     if (rc != CFGPARSER_SUCCESS)
+    {
+        return;
+    }
+
+    if (option->tp != CFGPARSER_TP_STRING)
     {
         log_warning(
-                "Missing '%s' in '%s' (%s). "
-                "Using default value: '%s'",
-                "default_db_path",
+                "Error reading 'default_db_path' in '%s': %s.",
                 siri.args->config,
-                cfgparser_errmsg(rc),
-                siri_cfg.default_db_path);
+                "error: expecting a string value");
+        return;
     }
-    else if (option->tp != CFGPARSER_TP_STRING)
+
+    if (strlen(option->val->string) >= XPATH_MAX)
     {
         log_warning(
-                "Error reading '%s' in '%s': %s. "
-                "Using default value: '%s'",
-                "default_db_path",
+                "Error reading 'default_db_path' in '%s': %s.",
                 siri.args->config,
-                "error: expecting a string value",
-                siri_cfg.default_db_path);
+                "error: path too long");
+        return;
     }
-    else
-    {
-        memset(siri_cfg.default_db_path, 0, XPATH_MAX);
-
-        if (strlen(option->val->string) >= XPATH_MAX -2 ||
-            realpath(
-                option->val->string,
-                siri_cfg.default_db_path) == NULL)
-        {
-            log_warning(
-                    "Could not resolve default database path: %s, please "
-                    "check your configuration file: %s",
-                    option->val->string,
-                    siri.args->config);
-
-            /* keep space left for a trailing slash and a terminator char */
-            strncpy(siri_cfg.default_db_path,
-                    option->val->string,
-                    XPATH_MAX - 2);
-        }
 
-        len = strlen(siri_cfg.default_db_path);
-
-        if (len == XPATH_MAX - 2)
-        {
-            log_warning(
-                    "Default database path exceeds %d characters, please "
-                    "check your configuration file: %s",
-                    XPATH_MAX - 3,
-                    siri.args->config);
-        }
-
-        /* add trailing slash (/) if its not already there */
-        if (siri_cfg.default_db_path[len - 1] != '/')
-        {
-            siri_cfg.default_db_path[len] = '/';
-        }
-    }
+    strncpy(siri_cfg.default_db_path, option->val->string, XPATH_MAX);
 }
 
 static void SIRI_CFG_read_max_open_files(cfgparser_t * cfgparser)
 {
     cfgparser_option_t * option;
     cfgparser_return_t rc;
-    struct rlimit rlim;
+
     rc = cfgparser_get_option(
                 &option,
                 cfgparser,
@@ -534,65 +473,10 @@ static void SIRI_CFG_read_max_open_files(cfgparser_t * cfgparser)
                 "max_open_files");
     if (rc != CFGPARSER_SUCCESS || option->tp != CFGPARSER_TP_INTEGER)
     {
-        log_info(
-                "Using default value for max_open_files: %d",
-                siri_cfg.max_open_files);
-    }
-    else
-    {
-        siri_cfg.max_open_files = (uint16_t) option->val->integer;
-    }
-
-    if (siri_cfg.max_open_files < MIN_OPEN_FILES_LIMIT ||
-            siri_cfg.max_open_files > MAX_OPEN_FILES_LIMIT)
-    {
-        log_warning(
-                "Value max_open_files must be a value between %d and %d "
-                "but we found %d. Using default value instead: %d",
-                MIN_OPEN_FILES_LIMIT, MAX_OPEN_FILES_LIMIT,
-                siri_cfg.max_open_files, DEFAULT_OPEN_FILES_LIMIT);
-        siri_cfg.max_open_files = DEFAULT_OPEN_FILES_LIMIT;
-    }
-
-    getrlimit(RLIMIT_NOFILE, &rlim);
-
-    uint16_t min_limit = (uint16_t)
-            ((double) siri_cfg.max_open_files / RLIMIT_PERC_FOR_SHARDING) -1;
-
-    if (min_limit > (uint64_t) rlim.rlim_max)
-    {
-        siri_cfg.max_open_files =
-                (uint16_t) ((double) rlim.rlim_max * RLIMIT_PERC_FOR_SHARDING);
-        log_warning(
-                "We want to set a max-open-files value which "
-                "exceeds %d%% of the current hard limit.\n\nWe "
-                "will use %d as max_open_files for now.\n"
-                "Please increase the hard-limit using:\n"
-                "ulimit -Hn %d",
-                (uint8_t) (RLIMIT_PERC_FOR_SHARDING * 100),
-                siri_cfg.max_open_files,
-                min_limit);
-        min_limit = siri_cfg.max_open_files * 2;
+        return;
     }
 
-    if (min_limit > (uint64_t) rlim.rlim_cur)
-    {
-        rlim_t prev = rlim.rlim_cur;
-        log_info(
-                "Increasing soft-limit from %d to %d since we want "
-                "to use only %d%% from the soft-limit for shard files",
-                (uint64_t) rlim.rlim_cur,
-                min_limit,
-                (uint8_t) (RLIMIT_PERC_FOR_SHARDING * 100));
-        rlim.rlim_cur = min_limit;
-        if (setrlimit(RLIMIT_NOFILE, &rlim))
-        {
-            siri_cfg.max_open_files = (uint16_t) (prev / 2);
-            log_warning("Could not set the soft-limit to %d, "
-                    "changing max open files to: %u",
-                    min_limit, siri_cfg.max_open_files);
-        }
-    }
+    siri_cfg.max_open_files = (uint16_t) option->val->integer;
 }
 
 /*
@@ -604,21 +488,8 @@ static void SIRI_CFG_read_address_port(
         char * address_pt,
         uint16_t * port_pt)
 {
-    char * port;
-    char * address;
-    char hostname[SIRI_CFG_MAX_LEN_ADDRESS];
     cfgparser_option_t * option;
     cfgparser_return_t rc;
-    int test_port;
-
-    if (gethostname(hostname, SIRI_CFG_MAX_LEN_ADDRESS))
-    {
-        log_debug(
-                "Unable to read the systems host name. Since its only purpose "
-                "is to apply this in the configuration file this might not be "
-                "any problem. (using 'localhost' as fallback)");
-        strcpy(hostname, "localhost");
-    }
 
     rc = cfgparser_get_option(
                 &option,
@@ -627,12 +498,6 @@ static void SIRI_CFG_read_address_port(
                 option_name);
     if (rc != CFGPARSER_SUCCESS)
     {
-        log_critical(
-                "Missing '%s' in '%s' (%s).",
-                option_name,
-                siri.args->config,
-                cfgparser_errmsg(rc));
-        exit(EXIT_FAILURE);
         return;
     }
 
@@ -647,75 +512,9 @@ static void SIRI_CFG_read_address_port(
         return;
     }
 
-    if (*option->val->string == '[')
-    {
-        /* an IPv6 address... */
-        for (port = address = option->val->string + 1; *port; port++)
-        {
-            if (*port == ']')
-            {
-                *port = 0;
-                port++;
-                break;
-            }
-        }
-    }
-    else
-    {
-        port = address = option->val->string;
-    }
-
-    for (; *port; port++)
-    {
-        if (*port == ':')
-        {
-            *port = 0;
-            port++;
-            break;
-        }
-    }
-
-    if (    !strlen(address) ||
-            strlen(address) >= SIRI_CFG_MAX_LEN_ADDRESS ||
-            !xstr_is_int(port) ||
-            strcpy(address_pt, address) == NULL ||
-            xstr_replace_str(
-                    address_pt,
-                    "%HOSTNAME",
-                    hostname,
-                    SIRI_CFG_MAX_LEN_ADDRESS))
+    if (sirinet_extract_addr_port(option->val->string, address_pt, port_pt))
     {
-        log_critical(
-                "Error reading '%s' in '%s': "
-                "error: got an unexpected value '%s:%s'.",
-                option_name,
-                siri.args->config,
-                address,
-                port);
         exit(EXIT_FAILURE);
-    }
-    else
-    {
-        test_port = atoi(port);
-
-        if (test_port < 1 || test_port > 65535)
-        {
-            log_critical(
-                    "Error reading '%s' in '%s': "
-                    "error: port should be between 1 and 65535, got '%d'.",
-                    option_name,
-                    siri.args->config,
-                    test_port);
-            exit(EXIT_FAILURE);
-        }
-        else
-        {
-            *port_pt = (uint16_t) test_port;
-        }
-
-        log_debug("Read '%s' from config: %s:%d",
-                option_name,
-                address_pt,
-                *port_pt);
+        return;
     }
 }
index 480939f882ae716b1612868bad8ef52fa1afd239..9f645ecbfc7629fcb3b3a13ea621277666407932 100644 (file)
@@ -3,14 +3,15 @@
  */
 
 #include <siri/evars.h>
+#include <siri/net/tcp.h>
 
-static void evars__u8(const char * evar, uint8_t * u8)
+static void evars__bool(const char * evar, uint8_t * b)
 {
     char * u8str = getenv(evar);
     if (!u8str)
         return;
 
-    *u8 = (uint8_t) strtoul(u8str, NULL, 10);
+    *b = (_Bool) strtoul(u8str, NULL, 10);
 }
 
 static void evars__u16(const char * evar, uint16_t * u16)
@@ -22,36 +23,154 @@ static void evars__u16(const char * evar, uint16_t * u16)
     *u16 = (uint16_t) strtoul(u16str, NULL, 10);
 }
 
-static void evars__sizet(const char * evar, size_t * sz)
+static void evars__u16_mm(
+        const char * evar,
+        uint16_t * u16,
+        uint16_t mi,
+        uint16_t ma)
 {
-    char * sizetstr = getenv(evar);
-    if (!sizetstr)
+    uint16_t val;
+    char * u16str = getenv(evar);
+    if (!u16str)
+        return;
+
+    val = (uint16_t) strtoul(u16str, NULL, 10);
+    if (val < mi || val > ma)
+        return;
+
+    *u16 = val;
+}
+
+static void evars__u32_mm(
+        const char * evar,
+        uint32_t * u32,
+        uint32_t mi,
+        uint32_t ma)
+{
+    uint32_t val;
+    char * u32str = getenv(evar);
+    if (!u32str)
+        return;
+
+    val = (uint32_t) strtoull(u32str, NULL, 10);
+    if (val < mi || val > ma)
         return;
 
-    *sz = (size_t) strtoull(sizetstr, NULL, 10);
+    *u32 = val;
 }
 
-static void evars__double(const char * evar, double * d)
+static void evars__to_strn(const char * evar, char * s, size_t n)
 {
-    char * doublestr = getenv(evar);
-    if (!doublestr)
+    char * str = getenv(evar);
+    if (!str || strlen(str) >= n)
         return;
 
-    *d = strtod(doublestr, NULL);
+    strncpy(s, str, n);
 }
 
-static void evars__str(const char * evar, char ** straddr)
+static void evars__ip_support(const char * evar, uint8_t * ip_support)
 {
     char * str = getenv(evar);
-    if (!str || !(str = strdup(str)))
+    if (!str)
         return;
 
-    free(*straddr);
-    *straddr = str;
+    if (strcasecmp(str, "ALL") == 0)
+    {
+        *ip_support = IP_SUPPORT_ALL;
+    }
+    else if (strcasecmp(str, "IPV4ONLY") == 0)
+    {
+        *ip_support = IP_SUPPORT_IPV4ONLY;
+    }
+    else if (strcasecmp(str, "IPV6ONLY") == 0)
+    {
+        *ip_support = IP_SUPPORT_IPV6ONLY;
+    }
 }
 
+static void evars__to_addr(const char * evar, char ** addr)
+{
+    struct in_addr sa;
+    struct in6_addr sa6;
 
-void siri_evars_parse(siri_t * siri)
+    char * str = getenv(evar);
+    if (!str || (
+            !inet_pton(AF_INET, str, &sa) &&
+            !inet_pton(AF_INET6, str, &sa6)))
+        return;
+
+    str = strdup(str);
+    if (!str)
+        return;
+
+    free(*addr);
+    *addr = str;
+}
+
+static void evars__to_addr_port(
+        const char * evar,
+        char * addr,
+        uint16_t * port)
 {
+    char * str = getenv(evar);
+    if (!str)
+        return;
+
+    (void) sirinet_extract_addr_port(str, addr, port);
+}
 
+
+void siri_evars_parse(siri_t * siri)
+{
+    evars__u16(
+            "SIRIDB_LISTEN_CLIENT_PORT",
+            &siri->cfg->listen_client_port);
+    evars__u16(
+            "SIRIDB_HTTP_STATUS_PORT",
+            &siri->cfg->http_status_port);
+    evars__u16(
+            "SIRIDB_HTTP_API_PORT",
+            &siri->cfg->http_api_port);
+    evars__u16(
+            "SIRIDB_MAX_OPEN_FILES",
+            &siri->cfg->max_open_files);
+    evars__bool(
+            "SIRIDB_ENABLE_PIPE_SUPPORT",
+            &siri->cfg->pipe_support);
+    evars__bool(
+            "SIRIDB_ENABLE_SHARD_COMPRESSION",
+            &siri->cfg->shard_compression);
+    evars__to_strn(
+            "SIRIDB_DEFAULT_DB_PATH",
+            siri->cfg->default_db_path,
+            sizeof(siri->cfg->default_db_path));
+    evars__u32_mm(
+            "SIRIDB_BUFFER_SYNC_INTERVAL",
+            &siri->cfg->buffer_sync_interval,
+            0, 300000);
+    evars__u16_mm(
+            "SIRIDB_HEARTBEAT_INTERVAL",
+            &siri->cfg->heartbeat_interval,
+            3, 300);
+    evars__u32_mm(
+            "SIRIDB_OPTIMIZING_INTERVAL",
+            &siri->cfg->optimize_interval,
+            0, 2419200);
+    evars__ip_support(
+            "SIRIDB_IP_SUPPORT",
+            &siri->cfg->ip_support);
+    evars__to_addr(
+            "SIRIDB_BIND_CLIENT_ADDRESS",
+            &siri->cfg->bind_client_addr);
+    evars__to_addr(
+            "SIRIDB_BIND_SERVER_ADDRESS",
+            &siri->cfg->bind_backend_addr);
+    evars__to_strn(
+            "SIRIDB_PIPE_CLIENT_NAME",
+            siri->cfg->pipe_client_name,
+            sizeof(siri->cfg->pipe_client_name)-2);
+    evars__to_addr_port(
+            "SIRIDB_SERVER_NAME",
+            siri->cfg->server_address,
+            &siri->cfg->listen_backend_port);
 }
index 2cdcc070de58574499a9a301897e59d7c744d93b..b09afe449b64a4b6aaeba9e21ac620927cb0943f 100644 (file)
@@ -3,8 +3,12 @@
  */
 #include <siri/net/tcp.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <string.h>
 #include <uv.h>
+#include <xstr/xstr.h>
+#include <siri/cfg/cfg.h>
+#include <logger/logger.h>
 
 #define TCP_NAME_BUF_SZ 54
 
@@ -84,83 +88,87 @@ failed:
     return NULL;
 }
 
-
 int sirinet_extract_addr_port(
-        const char * s,
+        char * s,
         char * addr,
-        uint16_t * port)
+        uint16_t * addrport)
 {
-    if (*option->val->string == '[')
+    int test_port;
+    char * strport;
+    char * address;
+    char hostname[SIRI_CFG_MAX_LEN_ADDRESS];
+    if (gethostname(hostname, SIRI_CFG_MAX_LEN_ADDRESS))
+    {
+        log_debug(
+                "Unable to read the systems host name. Since its only purpose "
+                "is to apply this in the configuration file this might not be "
+                "any problem. (using 'localhost' as fallback)");
+        strcpy(hostname, "localhost");
+    }
+
+
+    if (*s == '[')
     {
         /* an IPv6 address... */
-        for (port = address = option->val->string + 1; *port; port++)
+        for (strport = address = s + 1; *strport; strport++)
         {
-            if (*port == ']')
+            if (*strport == ']')
             {
-                *port = 0;
-                port++;
+                *strport = 0;
+                strport++;
                 break;
             }
         }
     }
     else
     {
-        port = address = option->val->string;
+        strport = address = s;
     }
 
-    for (; *port; port++)
+    for (; *strport; strport++)
     {
-        if (*port == ':')
+        if (*strport == ':')
         {
-            *port = 0;
-            port++;
+            *strport = 0;
+            strport++;
             break;
         }
     }
 
     if (    !strlen(address) ||
             strlen(address) >= SIRI_CFG_MAX_LEN_ADDRESS ||
-            !xstr_is_int(port) ||
-            strcpy(address_pt, address) == NULL ||
+            !xstr_is_int(strport) ||
+            strcpy(addr, address) == NULL ||
             xstr_replace_str(
-                    address_pt,
+                    addr,
                     "%HOSTNAME",
                     hostname,
                     SIRI_CFG_MAX_LEN_ADDRESS))
     {
         log_critical(
-                "Error reading '%s' in '%s': "
                 "error: got an unexpected value '%s:%s'.",
-                option_name,
-                siri.args->config,
                 address,
-                port);
-        exit(EXIT_FAILURE);
+                strport);
+        return -1;
     }
-    else
-    {
-        test_port = atoi(port);
 
-        if (test_port < 1 || test_port > 65535)
-        {
-            log_critical(
-                    "Error reading '%s' in '%s': "
-                    "error: port should be between 1 and 65535, got '%d'.",
-                    option_name,
-                    siri.args->config,
-                    test_port);
-            exit(EXIT_FAILURE);
-        }
-        else
-        {
-            *port_pt = (uint16_t) test_port;
-        }
+    test_port = atoi(strport);
 
-        log_debug("Read '%s' from config: %s:%d",
-                option_name,
-                address_pt,
-                *port_pt);
+    if (test_port < 1 || test_port > 65535)
+    {
+        log_critical(
+                "error: port should be between 1 and 65535, got '%d'.",
+                test_port);
+        return -1;
     }
+
+    *addrport = (uint16_t) test_port;
+
+    log_debug("Read '%s': %s:%d",
+            s,
+            addr,
+            *addrport);
+    return 0;
 }
 
 
index b0a43a5121d735691c908f08ff69c9c1facfb8ad..8a136a11365fbdad40ff12279a056016b890ba29 100644 (file)
@@ -407,7 +407,14 @@ int siri_service_account_save(siri_t * siri, char * err_msg)
         /* close file pointer */
         qp_close(fpacker))
     {
-        ACCOUNT_msg(err_msg, "error saving service accounts");
+        if (err_msg)
+        {
+            ACCOUNT_msg(err_msg, "error saving service accounts");
+        }
+        else
+        {
+            log_error("error saving service accounts: `%s`", fn);
+        }
         return EOF;
     }
     return 0;
index 242d8ea3f8b2b50b6794e293b623808447656ebc..20c6160c795deeee24d0cee5348266f4579484cd 100644 (file)
@@ -48,6 +48,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <time.h>
+#include <sys/resource.h>
 #include <unistd.h>
 #include <xpath/xpath.h>
 
@@ -125,6 +126,130 @@ void siri_setup_logger(void)
     logger_init(stdout, 0);
 }
 
+int make_database_directory(void)
+{
+    char tmppath[XPATH_MAX];
+    char * sysuser = getenv("USER");
+    char * homedir = getenv("HOME");
+    size_t len;
+
+    memset(tmppath, 0, XPATH_MAX);
+
+    if (*siri.cfg->default_db_path == '\0')
+    {
+        if (!homedir || !sysuser || strcmp(sysuser, "root") == 0)
+        {
+            strcpy(siri.cfg->default_db_path, "/var/lib/siridb/");
+        }
+        else
+        {
+            snprintf(siri.cfg->default_db_path, XPATH_MAX, "%s%s.siridb/",
+                    homedir,
+                    homedir[strlen(homedir)-1] == '/' ? "" : "/");
+        }
+    }
+
+    if (!xpath_is_dir(siri.cfg->default_db_path))
+    {
+        log_warning("Database directory not found, creating directory '%s'.",
+                siri.cfg->default_db_path);
+        if (mkdir(siri.cfg->default_db_path, 0700) == -1)
+        {
+            log_error("Cannot create directory '%s'.",
+                    siri.cfg->default_db_path);
+            return -1;
+        }
+    }
+
+    if (realpath(siri.cfg->default_db_path, tmppath) == NULL)
+    {
+        log_warning(
+                "Could not resolve default database path: %s",
+                siri.cfg->default_db_path);
+    }
+    else
+    {
+        memcpy(siri.cfg->default_db_path, tmppath, sizeof(tmppath));
+    }
+
+    len = strlen(siri.cfg->default_db_path);
+
+    if (len >= XPATH_MAX - 2)
+    {
+        log_warning(
+                "Default database path exceeds %d characters, please "
+                "check your configuration file: %s",
+                XPATH_MAX - 3,
+                siri.args->config);
+        return -1;
+    }
+
+    /* add trailing slash (/) if its not already there */
+    if (siri.cfg->default_db_path[len - 1] != '/')
+    {
+        siri.cfg->default_db_path[len] = '/';
+        siri.cfg->default_db_path[len+1] = '\0';
+    }
+
+    return 0;
+}
+
+void set_max_open_files_limit(void)
+{
+    struct rlimit rlim;
+
+    if (siri.cfg->max_open_files < MIN_OPEN_FILES_LIMIT ||
+            siri.cfg->max_open_files > MAX_OPEN_FILES_LIMIT)
+    {
+        log_warning(
+                "Value max_open_files must be a value between %d and %d "
+                "but we found %d. Using default value instead: %d",
+                MIN_OPEN_FILES_LIMIT, MAX_OPEN_FILES_LIMIT,
+                siri.cfg->max_open_files, DEFAULT_OPEN_FILES_LIMIT);
+        siri.cfg->max_open_files = DEFAULT_OPEN_FILES_LIMIT;
+    }
+
+    getrlimit(RLIMIT_NOFILE, &rlim);
+
+    uint16_t min_limit = (uint16_t)
+            ((double) siri.cfg->max_open_files / RLIMIT_PERC_FOR_SHARDING) -1;
+
+    if (min_limit > (uint64_t) rlim.rlim_max)
+    {
+        siri.cfg->max_open_files =
+                (uint16_t) ((double) rlim.rlim_max * RLIMIT_PERC_FOR_SHARDING);
+        log_warning(
+                "We want to set a max-open-files value which "
+                "exceeds %d%% of the current hard limit.\n\nWe "
+                "will use %d as max_open_files for now.\n"
+                "Please increase the hard-limit using:\n"
+                "ulimit -Hn %d",
+                (uint8_t) (RLIMIT_PERC_FOR_SHARDING * 100),
+                siri.cfg->max_open_files,
+                min_limit);
+        min_limit = siri.cfg->max_open_files * 2;
+    }
+
+    if (min_limit > (uint64_t) rlim.rlim_cur)
+    {
+        rlim_t prev = rlim.rlim_cur;
+        log_info(
+                "Increasing soft-limit from %d to %d since we want "
+                "to use only %d%% from the soft-limit for shard files",
+                (uint64_t) rlim.rlim_cur,
+                min_limit,
+                (uint8_t) (RLIMIT_PERC_FOR_SHARDING * 100));
+        rlim.rlim_cur = min_limit;
+        if (setrlimit(RLIMIT_NOFILE, &rlim))
+        {
+            siri.cfg->max_open_files = (uint16_t) (prev / 2);
+            log_warning("Could not set the soft-limit to %d, "
+                    "changing max open files to: %u",
+                    min_limit, siri.cfg->max_open_files);
+        }
+    }
+}
+
 int siri_start(void)
 {
     int rc;