diff options
-rw-r--r-- | doc/src/sgml/runtime.sgml | 31 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 11 | ||||
-rw-r--r-- | src/backend/utils/init/miscinit.c | 91 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 9 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 1 | ||||
-rw-r--r-- | src/include/miscadmin.h | 3 |
6 files changed, 141 insertions, 5 deletions
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 408c81e2ee5..0f53895fdcd 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.171 2003/03/20 03:34:55 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.172 2003/03/20 04:51:44 momjian Exp $ --> <Chapter Id="runtime"> @@ -1800,6 +1800,35 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' </varlistentry> <varlistentry> + <term><varname>PRELOAD_LIBRARIES</varname> (<type>string</type>)</term> + <indexterm><primary>preload_libraries</></> + <listitem> + <para> + This variable specifies one or more shared libraries that are to be + preloaded at Postmaster start. An initialization function can also be + optionally specified by adding a colon followed by the name of the + initialization function after the library name. For example + <literal>'$libdir/mylib:init_mylib'</literal> would cause <literal>mylib</> + to be preloaded and <literal>init_mylib</> to be executed. If more than + one library is to be loaded, they must be delimited with a comma. + </para> + + <para> + If <literal>mylib</> is not found, the postmaster will fail to start. + However, if <literal>init_mylib</> is not found, <literal>mylib</> will + still be preloaded without executing the initialization function. + </para> + + <para> + By preloading a shared library (and initializing it if applicable), + the library startup time is avoided when the library is used later in a + specific backend. However there is a cost in terms of memory duplication + as every backend is forked, whether or not the library is used. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>REGEX_FLAVOR</varname> (<type>string</type>)</term> <indexterm><primary>regular expressions</></> <listitem> diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 3ce63e05d63..13cc86e98c7 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.307 2003/02/23 04:48:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.308 2003/03/20 04:51:44 momjian Exp $ * * NOTES * @@ -205,6 +205,8 @@ bool LogSourcePort; bool Log_connections = false; bool Db_user_namespace = false; +/* list of library:init-function to be preloaded */ +char *preload_libraries_string = NULL; /* Startup/shutdown state */ static pid_t StartupPID = 0, @@ -646,6 +648,13 @@ PostmasterMain(int argc, char *argv[]) #endif /* + * process any libraries that should be preloaded and + * optionally pre-initialized + */ + if (preload_libraries_string) + process_preload_libraries(preload_libraries_string); + + /* * Fork away from controlling terminal, if -S specified. * * Must do this before we grab any interlock files, else the interlocks diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 12154396193..8b49ca2e584 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.100 2003/01/27 00:51:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.101 2003/03/20 04:51:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1044,3 +1044,92 @@ ValidatePgVersion(const char *path) "which is not compatible with this version %s.", file_major, file_minor, version_string); } + +/*------------------------------------------------------------------------- + * Library preload support + *------------------------------------------------------------------------- + */ + +#if defined(__mc68000__) && defined(__ELF__) +typedef int32 ((*func_ptr) ()); +#else +typedef char *((*func_ptr) ()); +#endif + +/* + * process any libraries that should be preloaded and + * optionally pre-initialized + */ +void +process_preload_libraries(char *preload_libraries_string) +{ + char *rawstring; + List *elemlist; + List *l; + + if (preload_libraries_string == NULL) + return; + + /* Need a modifiable copy of string */ + rawstring = pstrdup(preload_libraries_string); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawstring, ',', &elemlist)) + { + /* syntax error in list */ + pfree(rawstring); + freeList(elemlist); + elog(LOG, "invalid list syntax for preload_libraries configuration option"); + } + + foreach(l, elemlist) + { + char *tok = (char *) lfirst(l); + char *sep = strstr(tok, ":"); + char *filename = NULL; + char *funcname = NULL; + func_ptr initfunc; + + if (sep) + { + /* + * a colon separator implies there is an initialization function + * that we need to run in addition to loading the library + */ + size_t filename_len = sep - tok; + size_t funcname_len = strlen(tok) - filename_len - 1; + + filename = (char *) palloc(filename_len + 1); + memset(filename, '\0', filename_len + 1); + snprintf(filename, filename_len + 1, "%s", tok); + + funcname = (char *) palloc(funcname_len + 1); + memset(funcname, '\0', funcname_len + 1); + snprintf(funcname, funcname_len + 1, "%s", sep + 1); + } + else + { + /* + * no separator -- just load the library + */ + filename = pstrdup(tok); + funcname = NULL; + } + + initfunc = (func_ptr) load_external_function(filename, funcname, false, NULL); + if (initfunc) + (*initfunc)(); + + elog(LOG, "preloaded library %s with initialization function %s", filename, funcname); + + if (filename != NULL) + pfree(filename); + + if (funcname != NULL) + pfree(funcname); + } + + pfree(rawstring); + freeList(elemlist); +} + diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 37e1192b6d0..7c5d6d18849 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -5,7 +5,7 @@ * command, configuration file, and command line options. * See src/backend/utils/misc/README for more information. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.116 2003/03/04 21:51:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.117 2003/03/20 04:51:44 momjian Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -60,6 +60,7 @@ extern int CheckPointTimeout; extern bool autocommit; extern int CommitDelay; extern int CommitSiblings; +extern char *preload_libraries_string; #ifdef HAVE_SYSLOG extern char *Syslog_facility; @@ -815,6 +816,12 @@ static struct config_string }, { + {"preload_libraries", PGC_POSTMASTER, GUC_LIST_INPUT | GUC_LIST_QUOTE}, + &preload_libraries_string, + "", NULL, NULL + }, + + { {"regex_flavor", PGC_USERSET}, ®ex_flavor_string, "advanced", assign_regex_flavor, NULL }, diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 40b143c7cab..c290df19d99 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -214,4 +214,5 @@ #transform_null_equals = false #statement_timeout = 0 # 0 is disabled, in milliseconds #db_user_namespace = false +#preload_libraries = '' diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index f8321325f6c..e44d0fbad30 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: miscadmin.h,v 1.116 2003/02/22 05:57:45 tgl Exp $ + * $Id: miscadmin.h,v 1.117 2003/03/20 04:51:44 momjian Exp $ * * NOTES * some of the information in this file should be moved to @@ -288,6 +288,7 @@ extern void RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2); extern void ValidatePgVersion(const char *path); +extern void process_preload_libraries(char *preload_libraries_string); /* these externs do not belong here... */ extern void IgnoreSystemIndexes(bool mode); |