Fri Sep 24 19:51:52 PDT 2004
- Previous message: [Slony1-commit] By wieck: unsubscribeSet_int() must delete sl_sequence entries too, or
- Next message: [Slony1-commit] By darcyb: add syslog support, pid file writing and other bells
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Log Message: ----------- Ok it's finaly here, a slon config file. There are no command line argument chages, so this should be a transparent dropin. I'll be following this up with some documentation and the like RSN(tm). Modified Files: -------------- slony1-engine/src/slon: Makefile (r1.21 -> r1.22) misc.c (r1.11 -> r1.12) remote_worker.c (r1.60 -> r1.61) slon.c (r1.28 -> r1.29) slon.h (r1.37 -> r1.38) sync_thread.c (r1.11 -> r1.12) Added Files: ----------- slony1-engine/src/slon: conf-file.l (r1.1) confoptions.c (r1.1) confoptions.h (r1.1) misc.h (r1.1) -------------- next part -------------- --- /dev/null +++ src/slon/misc.h @@ -0,0 +1,26 @@ +#ifndef _MISC_H_ +#define _MISC_H_ +/* ---------- + * Functions in misc.c + * ---------- + */ +#include "config.h" +#include "c.h" + +typedef enum { + SLON_FATAL, + SLON_ERROR, + SLON_WARN, + SLON_CONFIG, + SLON_INFO, + SLON_DEBUG1, + SLON_DEBUG2, + SLON_DEBUG3, + SLON_DEBUG4 +} SlonLogLevel; + +extern void slon_log(SlonLogLevel level, char * fmt, ...); + +extern int slon_scanint64(char *str, int64 *result); + +#endif --- /dev/null +++ src/slon/confoptions.h @@ -0,0 +1,208 @@ +#ifndef _CONFOPTIONS_H_ +#define _CONFOPTIONS_H_ + +#include "c.h" + + +void InitializeConfOptions(void); + +bool set_config_option(const char *name, const char *value); + +extern double real_placeholder; +extern char *string_placeholder; + + +extern int vac_frequency; +extern int slon_log_level; +extern int sync_interval; +extern int sync_interval_timeout; + +extern int sync_group_maxsize; + +bool logpid; +bool logtimestamp; + + +enum config_type +{ + SLON_C_BOOL, + SLON_C_INT, + SLON_C_REAL, + SLON_C_STRING +}; + +struct config_generic +{ + /* constant fields, must be set correctly in initial value: */ + const char *name; + const char *short_desc; + const char *long_desc; + enum config_type vartype; /* type of variable (set only at startup) */ +}; + + +struct config_int +{ + struct config_generic gen; + /* these fields must be set correctly in initial value: */ + /* (all but reset_val are constants) */ + int *variable; + int default_val; + int min; + int max; +}; + +struct config_bool +{ + struct config_generic gen; + /* these fields must be set correctly in initial value: */ + /* (all but reset_val are constants) */ + bool *variable; + bool default_val; +}; + +struct config_real +{ + struct config_generic gen; + /* these fields must be set correctly in initial value: */ + /* (all but reset_val are constants) */ + double *variable; + double default_val; + double min; + double max; +}; + +struct config_string +{ + struct config_generic gen; + /* these fields must be set correctly in initial value: */ + /* (all are constants) */ + char **variable; + const char *default_val; +}; + + + +static struct config_int ConfigureNamesInt[] = +{ + { + { + (const char *)"vac_frequency", /* conf name */ + gettext_noop("Sets how many cleanup cyclse to run before a vacum is done"), /* short desc */ + gettext_noop("Sets how many cleanup cyclse to run before a vacum is done"), /* long desc */ + SLON_C_INT /* config type */ + }, + &vac_frequency, /* var name */ + 3, /* default val */ + 0, /* min val */ + 100 /* max val */ + }, + { + { + (const char *)"log_level", + gettext_noop("debug log level"), + gettext_noop("debug log level"), + SLON_C_INT + }, + &slon_log_level, + 4, + 0, + 4 + }, + { + { + (const char *)"sync_interval", + gettext_noop("sync even interval"), + gettext_noop("sync even interval in ms"), + SLON_C_INT + }, + &sync_interval, + 100, + 10, + 60000 + }, + { + { + (const char *)"sync_interval_timeout", + gettext_noop("sync interval time out"), + gettext_noop("sync interval time out"), + SLON_C_INT + }, + &sync_interval_timeout, + 1000, + 0, + 120000 + }, + { + { + (const char *)"sync_group_maxsize", + gettext_noop("sync group"), + gettext_noop("sync group"), + SLON_C_INT + }, + &sync_group_maxsize, + 6, + 0, + 100 + }, + + NULL +}; +static struct config_int ConfigureNamesBool[] = +{ + { + { + (const char *)"log_pid", /* conf name */ + gettext_noop("place holder"), /* short desc */ + gettext_noop("place holder"), /* long desc */ + SLON_C_BOOL /* config type */ + }, + &logpid, /* var_name */ + false /* default_value */ + }, + { + { + (const char *)"log_timestamp", + gettext_noop("place holder"), + gettext_noop("place holder"), + SLON_C_BOOL + }, + &logtimestamp, + true + }, + NULL +}; + +static struct config_int ConfigureNamesReal[] = +{ + { + { + (const char *)"real_placeholder", /* conf name */ + gettext_noop("place holder"), /* short desc */ + gettext_noop("place holder"), /* long desc */ + SLON_C_REAL /* config type */ + }, + &real_placeholder, /* var_name */ + 0.0, /* default val */ + 0.0, /* min_value */ + 1.0 /* max value */ + }, + NULL +}; + +static struct config_int ConfigureNamesString[] = +{ + { + { + (const char *)"string_placeholder", /* conf name */ + gettext_noop("place holder"), /* short desc */ + gettext_noop("place holder"), /* long desc */ + SLON_C_STRING /* config type */ + }, + &string_placeholder, /* var_name */ + "default" /* default value */ + }, + NULL +}; + +#endif Index: remote_worker.c =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v retrieving revision 1.60 retrieving revision 1.61 diff -Lsrc/slon/remote_worker.c -Lsrc/slon/remote_worker.c -u -w -r1.60 -r1.61 --- src/slon/remote_worker.c +++ src/slon/remote_worker.c @@ -199,7 +199,7 @@ static struct node_confirm_status *node_confirm_tail = NULL; pthread_mutex_t node_confirm_lock = PTHREAD_MUTEX_INITIALIZER; -int sync_group_maxsize = 6; +int sync_group_maxsize; /* ---------- Index: sync_thread.c =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/sync_thread.c,v retrieving revision 1.11 retrieving revision 1.12 diff -Lsrc/slon/sync_thread.c -Lsrc/slon/sync_thread.c -u -w -r1.11 -r1.12 --- src/slon/sync_thread.c +++ src/slon/sync_thread.c @@ -32,8 +32,8 @@ * Global variables * ---------- */ -int sync_interval = 10000; -int sync_interval_timeout = 60000; +int sync_interval; +int sync_interval_timeout; /* ---------- Index: slon.h =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.h,v retrieving revision 1.37 retrieving revision 1.38 diff -Lsrc/slon/slon.h -Lsrc/slon/slon.h -u -w -r1.37 -r1.38 --- src/slon/slon.h +++ src/slon/slon.h @@ -13,7 +13,9 @@ #ifndef SLON_H_INCLUDED #define SLON_H_INCLUDED + #include "config.h" +#include "misc.h" #define SLON_MEMDEBUG 1 @@ -52,6 +54,8 @@ } SlonThreadStatus; +extern bool logpid; + /* ---------- * In memory structures for cluster configuration * ---------- @@ -492,27 +496,5 @@ */ extern int slon_log_level; -/* ---------- - * Functions in misc.c - * ---------- - */ -typedef enum { - SLON_FATAL, - SLON_ERROR, - SLON_WARN, - SLON_CONFIG, - SLON_INFO, - SLON_DEBUG1, - SLON_DEBUG2, - SLON_DEBUG3, - SLON_DEBUG4 -} SlonLogLevel; - -extern void slon_log(SlonLogLevel level, char * fmt, ...); - -extern int slon_scanint64(char *str, int64 *result); - - - #endif /* SLON_H_INCLUDED */ Index: misc.c =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/misc.c,v retrieving revision 1.11 retrieving revision 1.12 diff -Lsrc/slon/misc.c -Lsrc/slon/misc.c -u -w -r1.11 -r1.12 --- src/slon/misc.c +++ src/slon/misc.c @@ -27,11 +27,14 @@ #include "libpq-fe.h" #include "c.h" +#include "confoptions.h" #include "slon.h" -int slon_log_level = SLON_INFO; +extern int slon_log_level; +extern bool logpid; +extern bool logtimestamp; static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -88,9 +91,20 @@ } } + sprintf(outbuf, ""); + + if (logtimestamp == true) + { strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S %Z", localtime(&stamp_time)); + sprintf(outbuf, "%s ", time_buf); + } + + if (logpid == true) + { + sprintf(outbuf, "%s[%d] ", outbuf, slon_pid); + } + sprintf(outbuf, "%s%-6.6s ",outbuf, level_c); - sprintf(outbuf, "%-6.6s [%s] ", level_c, time_buf); off = strlen(outbuf); while(vsnprintf(&outbuf[off], outsize - off, fmt, ap) >= outsize - off) --- /dev/null +++ src/slon/conf-file.l @@ -0,0 +1,338 @@ +/* Scanner for slon config file */ + +%{ +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <ctype.h> +#include <pthread.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#include "misc.h" +#include "confoptions.h" + + +#define CONFIG_FILENAME "./slon.conf" + +static unsigned ConfigFileLineno; + +enum { + SLON_ID = 1, + SLON_STRING = 2, + SLON_INTEGER = 3, + SLON_REAL = 4, + SLON_EQUALS = 5, + SLON_UNQUOTED_STRING = 6, + SLON_QUALIFIED_ID = 7, + SLON_EOL = 99, + SLON_FERROR = 100 +}; + +#define YY_USER_INIT (ConfigFileLineno = 1) + +/* prototype, so compiler is happy with our high warnings setting */ +int SLON_yylex(void); +char *SLON_scanstr(char *); +%} + +%option 8bit +%option never-interactive +%option nodefault +%option nounput +%option noyywrap + +SIGN ("-"|"+") +DIGIT [0-9] +HEXDIGIT [0-9a-fA-F] + +INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+) + +EXPONENT [Ee]{SIGN}?{DIGIT}+ +REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}? + +LETTER [A-Za-z_\200-\377] +LETTER_OR_DIGIT [A-Za-z_0-9\200-\377] + +ID {LETTER}{LETTER_OR_DIGIT}* +QUALIFIED_ID {ID}"."{ID} + +UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])* +STRING \'([^'\n]|\\.)*\' + +%% + +\n ConfigFileLineno++; return SLON_EOL; +[ \t\r]+ /* eat whitespace */ +#.*$ /* eat comment */ + +{ID} return SLON_ID; +{QUALIFIED_ID} return SLON_QUALIFIED_ID; +{STRING} return SLON_STRING; +{UNQUOTED_STRING} return SLON_UNQUOTED_STRING; +{INTEGER} return SLON_INTEGER; +{REAL} return SLON_REAL; += return SLON_EQUALS; + +. return SLON_FERROR; + +%% + +struct name_value_pair +{ + char *name; + char *value; + struct name_value_pair *next; +}; + +/* + * Free a list of name/value pairs, including the names and the values + */ +static void +free_name_value_list(struct name_value_pair * list) +{ + struct name_value_pair *item; + + item = list; + while (item) + { + struct name_value_pair *save; + + save = item->next; + free(item->name); + free(item->value); + free(item); + item = save; + } +} + +void ProcessConfigFile(const char *filename) +{ + int token, parse_state; + char *opt_name, *opt_value; + int elevel; + struct name_value_pair *item, *head, *tail; + FILE * fp; + + elevel = SLON_ERROR; + + /* + * Open the conf file + */ + if (filename == NULL) + { + fp = fopen(CONFIG_FILENAME, "r"); + } + else + { + fp = fopen(filename, "r"); + } + if (!fp) + { + /* File not found is fine */ + if (errno != ENOENT) + { + slon_log(elevel,"could not open configuration file \"%s\"\n", filename); + + } + return; + } + + /* Ok we have the file, lets parse it */ + + yyin = fp; + parse_state = 0; + head = NULL; + tail = head; + opt_name = NULL; + opt_value = opt_name; + + while (token = yylex()) + { + switch(parse_state) + { + case 0: + if (token == SLON_EOL) /* empty line */ + { + continue; + } + if (token != SLON_ID && token != SLON_QUALIFIED_ID) + { + goto parse_error; + } + opt_name = strdup(yytext); + parse_state = 1; + break; + case 1: + /* ignore equals sign */ + if (token == SLON_EQUALS) + { + token = yylex(); + } + if (token != SLON_ID && token != SLON_STRING && token != SLON_INTEGER && token != SLON_REAL && token != SLON_UNQUOTED_STRING) + { + goto parse_error; + } + opt_value = strdup(yytext); + if (token == SLON_STRING) + { + memmove(opt_value,opt_value+1,strlen(opt_value)-1); + opt_value[strlen(opt_value)-2]='\0'; + opt_value=SLON_scanstr(opt_value); + } + parse_state = 2; + break; + case 2: /* OEL ? */ + if (token != SLON_EOL) + { + goto parse_error; + } + item = malloc(sizeof *item); + item->name = opt_name; + item->value = opt_value; + + if (strcmp(opt_name, "custom_variable_classes") == 0) + { + item->next = head; + head = item; + if (!tail) + { + tail = item; + } + } + else + { + /* append to list */ + item->next = NULL; + if (!head) + { + head = item; + } + else + { + tail->next = item; + } + tail = item; + } + parse_state = 0; + break; + } + } + + fclose(fp); + + for (item = head; item; item=item->next) + { + if (!set_config_option(item->name, item->value)) + { + goto cleanup_exit; + } + } + for(item = head; item; item=item->next) + { + set_config_option(item->name, item->value); + } + + cleanup_exit: + free_name_value_list(head); + return; + + parse_error: + fclose(fp); + free_name_value_list(head); + if (token == SLON_EOL) + { + slon_log(elevel, "syntax error in file \"%s\" line %u, near end of line", filename, ConfigFileLineno - 1); + } + else + { + slon_log(elevel, "syntax error in file \"%s\" line %u, near end of line", filename, ConfigFileLineno - 1); + } +} + + + + + + + +char *SLON_scanstr(char *s) +{ + char *newStr; + int len, + i, + j; + + if (s == NULL || s[0] == '\0') + { + if (s != NULL) + free(s); + return strdup(""); + } + len = strlen(s); + + newStr = malloc(len + 1); /* string cannot get longer */ + if (newStr == NULL) + slon_log(SLON_FATAL, "out of memory"); + + for (i = 0, j = 0; i < len; i++) + { + if (s[i] == '\\') + { + i++; + switch (s[i]) + { + case 'b': + newStr[j] = '\b'; + break; + case 'f': + newStr[j] = '\f'; + break; + case 'n': + newStr[j] = '\n'; + break; + case 'r': + newStr[j] = '\r'; + break; + case 't': + newStr[j] = '\t'; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int k; + long octVal = 0; + + for (k = 0; + s[i + k] >= '0' && s[i ++ k] <= '7' && k < 3; + k++) + octVal = (octVal << 3) + + (s[i + k] - '0'); + i += k - 1; + newStr[j] = ((char) octVal); + } + break; + default: + newStr[j] = s[i]; + break; + } + } /* switch */ + else + newStr[j] = s[i]; + j++; + } + newStr[j] = '\0'; + free(s); + return newStr; +} + --- /dev/null +++ src/slon/confoptions.c @@ -0,0 +1,472 @@ +#include <pthread.h> +#include "libpq-fe.h" +#include "confoptions.h" +#include "postgres.h" +#include "misc.h" + + +static struct config_generic **conf_variables; +static int size_conf_variables; +static int num_conf_variables; + +static int conf_var_compare(const void *a, const void *b); +static int conf_name_compare(const char *namea, const char *nameb); + +bool set_config_option(const char *name, const char *value); + + +bool bool_placeholder; +double real_placeholder; +char *string_placeholder; + + + +void build_conf_variables(void) +{ + int size_vars; + int num_vars=0; + struct config_generic **conf_vars; + int i; + + for (i = 0; ConfigureNamesBool[i].gen.name; i++) + { + struct config_bool *conf = &ConfigureNamesBool[i]; + + /* Rather than requiring vartype to be filled in by hand, do this: */ + conf->gen.vartype = SLON_C_BOOL; + num_vars++; + } + + for (i = 0; ConfigureNamesInt[i].gen.name; i++) + { + struct config_int *conf = &ConfigureNamesInt[i]; + conf->gen.vartype = SLON_C_INT; + num_vars++; + } + + for (i = 0; ConfigureNamesReal[i].gen.name; i++) + { + struct config_real *conf = &ConfigureNamesReal[i]; + conf->gen.vartype = SLON_C_REAL; + num_vars++; + } + + for (i = 0; ConfigureNamesString[i].gen.name; i++) + { + struct config_string *conf = &ConfigureNamesString[i]; + conf->gen.vartype = SLON_C_STRING; + num_vars++; + } + + size_vars = num_vars + num_vars / 4; + + conf_vars = (struct config_generic **) malloc(size_vars * sizeof(struct config_generic *)); + if (conf_vars == NULL) + { + slon_log(FATAL, "malloc failed"); + return; + } + + num_vars = 0; + + for (i = 0; ConfigureNamesBool[i].gen.name; i++) + { + conf_vars[num_vars++] = &ConfigureNamesBool[i].gen; + } + for (i = 0; ConfigureNamesInt[i].gen.name; i++) + { + conf_vars[num_vars++] = &ConfigureNamesInt[i].gen; + } + for (i = 0; ConfigureNamesReal[i].gen.name; i++) + { + conf_vars[num_vars++] = &ConfigureNamesReal[i].gen; + } + for (i = 0; ConfigureNamesString[i].gen.name; i++) + { + conf_vars[num_vars++] = &ConfigureNamesString[i].gen; + } + + if (conf_variables) + { + free(conf_variables); + } + conf_variables = conf_vars; + num_conf_variables = num_vars; + size_conf_variables = size_vars; + qsort((void *) conf_variables, num_conf_variables, sizeof(struct config_generic *), conf_var_compare); +} + + +static bool +add_conf_variable(struct config_generic * var, int elevel) +{ + if (num_conf_variables + 1 >= size_conf_variables) + { + /* + * Increase the vector by 25% + */ + int size_vars = size_conf_variables + size_conf_variables / 4; + struct config_generic **conf_vars; + + if (size_vars == 0) + { + size_vars = 100; + conf_vars = (struct config_generic **) + malloc(size_vars * sizeof(struct config_generic *)); + } + else + { + conf_vars = (struct config_generic **) + realloc(conf_variables, size_vars * sizeof(struct config_generic *)); + } + + if (conf_vars == NULL) + { + slon_log(elevel,"malloc failed"); + return false; /* out of memory */ + } + + conf_variables = conf_vars; + size_conf_variables = size_vars; + } + conf_variables[num_conf_variables++] = var; + qsort((void *) conf_variables, num_conf_variables, + sizeof(struct config_generic *), conf_var_compare); + return true; +} + +void InitializeConfOptions(void) +{ + int i; + char *env; + + build_conf_variables(); + + for (i = 0; i < num_conf_variables; i++) + { + struct config_generic *gconf = conf_variables[i]; + + switch (gconf->vartype) + { + case SLON_C_BOOL: + { + struct config_bool *conf = (struct config_bool *) gconf; + *conf->variable = conf->default_val; + break; + } + case SLON_C_INT: + { + struct config_int *conf = (struct config_int *) gconf; + *conf->variable = conf->default_val; + break; + } + case SLON_C_REAL: + { + struct config_int *conf = (struct config_int *) gconf; + *conf->variable = conf->default_val; + break; + } + case SLON_C_STRING: + { + char *str; + struct config_int *conf = (struct config_int *) gconf; + *conf->variable = NULL; + str = strdup(conf->default_val); + *conf->variable = str; + break; + } + } + } + + env = getenv("CLUSTER"); + if (env != NULL) + { + set_config_option("cluster_name", env); + } +} + +static bool +parse_bool(const char *value, bool *result) +{ + size_t len = strlen(value); + + if (strncasecmp(value, "true", len) == 0) + { + if (result) + { + *result = true; + } + } + else if (strncasecmp(value, "false", len) == 0) + { + if (result) + { + *result = false; + } + } + else if (strncasecmp(value, "yes", len) == 0) + { + if (result) + { + *result = true; + } + } + else if (strncasecmp(value, "no", len) == 0) + { + if (result) + { + *result = false; + } + } + else if (strncasecmp(value, "on", len) == 0) + { + if (result) + { + *result = true; + } + } + else if (strncasecmp(value, "off", len) == 0) + { + if (result) + { + *result = false; + } + } + else if (strncasecmp(value, "1", len) == 0) + { + if (result) + { + *result = true; + } + } + else if (strncasecmp(value, "o", len) == 0) + { + if (result) + { + *result = false; + } + } + else + { + return false; + } + return true; +} + +/* + * Try to parse value as an integer. The accepted formats are the + * usual decimal, octal, or hexadecimal formats. If the string parses + * okay, return true, else false. If result is not NULL, return the + * value there. + */ +static bool +parse_int(const char *value, int *result) +{ + long val; + char *endptr; + + errno = 0; + val = strtol(value, &endptr, 0); + + if (endptr == value || *endptr != '\0' || errno == ERANGE +#ifdef HAVE_LONG_INT_64 + /* if long > 32 bits, check for overflow of int4 */ + || val != (long) ((int32) val) +#endif + ) + return false; + if (result) + *result = (int) val; + return true; +} + +/* + * Try to parse value as a floating point constant in the usual + * format. If the value parsed okay return true, else false. If + * result is not NULL, return the semantic value there. + */ +static bool +parse_real(const char *value, double *result) +{ + double val; + char *endptr; + + errno = 0; + val = strtod(value, &endptr); + if (endptr == value || *endptr != '\0' || errno == ERANGE) + return false; + if (result) + *result = val; + return true; +} + + +static struct config_generic *find_option(const char *name, int elevel) +{ + const char *dot; + const char **key = &name; + struct config_generic **res; + int i; + + res = (struct config_generic **) + bsearch((void *) &key, + (void *) conf_variables, + num_conf_variables, + sizeof(struct config_generic *), + conf_var_compare); + if (res) + return *res; +} + +static int +conf_var_compare(const void *a, const void *b) +{ + struct config_generic *confa = *(struct config_generic **) a; + struct config_generic *confb = *(struct config_generic **) b; + + return conf_name_compare(confa->name, confb->name); +} + +static int +conf_name_compare(const char *namea, const char *nameb) +{ + /* + * The temptation to use strcasecmp() here must be resisted, because + * the array ordering has to remain stable across setlocale() calls. + * So, build our own with a simple ASCII-only downcasing. + */ + while (*namea && *nameb) + { + char cha = *namea++; + char chb = *nameb++; + + if (cha >= 'A' && cha <= 'Z') + cha += 'a' - 'A'; + if (chb >= 'A' && chb <= 'Z') + chb += 'a' - 'A'; + if (cha != chb) + return cha - chb; + } + if (*namea) + return 1; /* a is longer */ + if (*nameb) + return -1; /* b is longer */ + return 0; +} + + +bool set_config_option(const char *name, const char *value) +{ + struct config_generic *record; + int elevel; + + elevel = SLON_WARN; + + record = find_option(name, elevel); + + if (record == NULL) + { + slon_log(elevel, "unrecognized configuration parameter \"%s\"\n", name); + return false; + } + + switch (record->vartype) + { + case SLON_C_BOOL: + { + struct config_bool *conf = (struct config_bool *) record; + bool newval; + if (value) + { + if (!parse_bool(value, &newval)) + { + slon_log(elevel, "parameter \"%s\" requires a Boolean value\n", name); + return false; + } + } + else + { + slon_log(elevel, "parameter \"%s\"\n", name ); + } + + *conf->variable = newval; + + break; + } + case SLON_C_INT: + { + struct config_int *conf = (struct config_int *) record; + int newval; + if (value) + { + if (!parse_int(value, &newval)) + { + slon_log(elevel, "parameter \"%s\" requires a integer value\n", name); + return false; + } + if (newval < conf->min || newval > conf->max) + { + slon_log(elevel, "%d is outside the valid range for parameter \"%s\" (%d .. %d)\n", + newval, name, conf->min, conf->max); + return false; + } + } + else + { + slon_log(elevel, "parameter \"%s\"\n", name ); + } + *conf->variable = newval; + break; + } + case SLON_C_REAL: + { + struct config_real *conf = (struct config_real *) record; + double newval; + + if (value) + { + if (!parse_real(value, &newval)) + { + slon_log(elevel, "parameter \"%s\" requires a numeric value\n", name); + return false; + } + if (newval < conf->min || newval > conf->max) + { + slon_log(elevel, "%g is outside the valid range for parameter \"%s\" (%g .. %g)\n", + newval, name, conf->min, conf->max); + return false; + } + } + else + { + slon_log(elevel, "parameter \"%s\"\n", name ); + } + *conf->variable = newval; + break; + } + case SLON_C_STRING: + { + struct config_string *conf = (struct config_string *) record; + char *newval; + + if (value) + { + newval = strdup(value); + if (newval == NULL) + { + return false; + } + + } + else + { + slon_log(elevel, "parameter \"%s\"\n", name ); + free(newval); + } + *conf->variable = newval; + break; + } + } + return true; +} + Index: slon.c =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.c,v retrieving revision 1.28 retrieving revision 1.29 diff -Lsrc/slon/slon.c -Lsrc/slon/slon.c -u -w -r1.28 -r1.29 --- src/slon/slon.c +++ src/slon/slon.c @@ -27,7 +27,7 @@ #include "c.h" #include "slon.h" - +#include "confoptions.h" /* ---------- * Global data @@ -52,6 +52,8 @@ static char *const *main_argv; static void sigalrmhandler(int signo); +int slon_log_level; + /* ---------- * main @@ -73,62 +75,39 @@ int group_size_set = 0; - while ((c = getopt(argc, argv, "d:s:t:g:c:h")) != EOF) + InitializeConfOptions(); + + + while ((c = getopt(argc, argv, "f:d:s:t:g:c:f:h")) != EOF) { switch(c) { - case 'd': slon_log_level = strtol(optarg, NULL, 10); - if (slon_log_level < 0 || slon_log_level > 4) - { - fprintf(stderr, "illegal debug level %d\n", - slon_log_level); - errors++; - } - slon_log_level += SLON_INFO; + case 'f': + ProcessConfigFile(optarg); break; - case 's': sync_interval = strtol(optarg, NULL, 10); - if (sync_interval < 100 || sync_interval > 60000) - { - fprintf(stderr, "sync interval must be between 100 and 60000 ms\n"); - errors++; - } - else if (!group_size_set) - { - sync_group_maxsize = 60000 / sync_interval; - if (sync_group_maxsize > 100) - sync_group_maxsize = 100; - } - + case 'd': + set_config_option("log_level", optarg); break; - case 't': sync_interval_timeout = strtol(optarg, NULL, 10); - if (sync_interval < 0) - { - fprintf(stderr, "sync interval must be >= 0\n"); - errors++; - } + case 's': + set_config_option("sync_group_maxsize", optarg); + break; + case 't': + set_config_option("sync_interval_timeout", optarg); break; - case 'g': sync_group_maxsize = strtol(optarg, NULL, 10); - if (sync_group_maxsize < 1 || sync_group_maxsize > 100) - { - fprintf(stderr, "sync group size must be between 1 and 100 ms\n"); - errors++; - } - group_size_set = 1; + case 'g': + set_config_option("sync_group_maxsize", optarg); break; - case 'c': vac_frequency = strtol(optarg, NULL, 10); - if (vac_frequency < 0 || vac_frequency > 10) - { - fprintf(stderr, "Vaccum frequency must be between 0 (disable) and 10\n"); - errors++; - } + case 'c': + set_config_option("vac_frequency", optarg); break; - case 'h': errors++; + case 'h': + errors++; break; default: fprintf(stderr, "unknown option '%c'\n", c); @@ -136,7 +115,18 @@ break; } } - +#if 0 +fprintf( stderr, "config: vac_frequency %d\n" + " sync_group_maxsize %d\n" + " sync_interval_timeout %d\n" + " sync_interval %d\n" + " slon_log_level %d\n" + " log_pid %d\n" + " log_timestamp %d\n", + vac_frequency, sync_group_maxsize, sync_interval_timeout, + sync_interval, slon_log_level, logpid, logtimestamp); +fflush(NULL); +#endif if (argc - optind != 2) errors++; @@ -150,6 +140,7 @@ fprintf(stderr, " -t <milliseconds> SYNC interval timeout (default 60000)\n"); fprintf(stderr, " -g <num> maximum SYNC group size (default 6)\n"); fprintf(stderr, " -c <num> how often to vaccum in cleanup cycles\n"); + fprintf(stderr, " -f <filename> slon configuration file\n"); return 1; } Index: Makefile =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/Makefile,v retrieving revision 1.21 retrieving revision 1.22 diff -Lsrc/slon/Makefile -Lsrc/slon/Makefile -u -w -r1.21 -r1.22 --- src/slon/Makefile +++ src/slon/Makefile @@ -36,6 +36,8 @@ cleanup_thread.o \ scheduler.o \ dbutils.o \ + conf-file.o \ + confoptions.o \ misc.o DISTFILES = Makefile README $(wildcard *.c) $(wildcard *.h) @@ -59,6 +61,11 @@ scheduler.o: scheduler.c slon.h slon.o: slon.c slon.h sync_thread.o: sync_thread.c slon.h +conf-file.o: conf-file.c slon.h confoptions.h +confoptions.o: confoptions.c slon.h confoptions.h + +conf-file.c: conf-file.l + $(FLEX) -o$(@) $< clean distclean maintainer-clean: rm -f $(ALL) $(OBJS)
- Previous message: [Slony1-commit] By wieck: unsubscribeSet_int() must delete sl_sequence entries too, or
- Next message: [Slony1-commit] By darcyb: add syslog support, pid file writing and other bells
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Slony1-commit mailing list