diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 706ccba56c..b35fa9c1cc 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ - + Server Configuration @@ -949,10 +949,10 @@ SET ENABLE_SEQSCAN TO OFF; - - preload_libraries (string) + + shared_preload_libraries (string) - preload_libraries configuration parameter + shared_preload_libraries configuration parameter @@ -963,6 +963,7 @@ SET ENABLE_SEQSCAN TO OFF; mylib.so (or on some platforms, mylib.sl) to be preloaded from the installation's standard library directory. + This parameter can only be set at server start. @@ -3642,6 +3643,60 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + + local_preload_libraries (string) + + local_preload_libraries configuration parameter + + + $libdir/plugins + + + + This variable specifies one or more shared libraries that are + to be preloaded at connection start. If more than one library + is to be loaded, separate their names with commas. + This parameter cannot be changed after the start of a particular + session. + + + + Because this is not a superuser-only option, the libraries + that can be loaded are restricted to those appearing in the + plugins subdirectory of the installation's + standard library directory. (It is the database administrator's + responsibility to ensure that only safe libraries + are installed there.) Entries in local_preload_libraries + can specify this directory explicitly, for example + $libdir/plugins/mylib, or just specify + the library name — mylib would have + the same effect as $libdir/plugins/mylib. + + + + There is no performance advantage to loading a library at session + start rather than when it is first used. Rather, the intent of + this feature is to allow debugging or performance-measurement + libraries to be loaded into specific sessions without an explicit + LOAD command being given. For example, debugging could + be enabled for all sessions under a given user name by setting + this parameter with ALTER USER SET. + + + + If a specified library is not found, + the connection attempt will fail. + + + + Every PostgreSQL-supported library has a magic + block that is checked to guarantee compatibility. + For this reason, non-PostgreSQL libraries cannot be + loaded in this way. + + + diff --git a/doc/src/sgml/ref/load.sgml b/doc/src/sgml/ref/load.sgml index b29dfd4ed4..6a6e9d9098 100644 --- a/doc/src/sgml/ref/load.sgml +++ b/doc/src/sgml/ref/load.sgml @@ -1,5 +1,5 @@ @@ -44,6 +44,19 @@ LOAD 'filename' shared library file name extension. See for more information on this topic. + + + $libdir/plugins + + + + Non-superusers may only apply LOAD to library files + located in $libdir/plugins/ — the specified + filename must begin + with exactly that string. (It is the database administrator's + responsibility to ensure that only safe libraries + are installed there.) + diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index eefa974dee..130415c74c 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.498 2006/08/08 19:15:07 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.499 2006/08/15 18:26:58 tgl Exp $ * * NOTES * @@ -709,7 +709,7 @@ PostmasterMain(int argc, char *argv[]) /* * process any libraries that should be preloaded at postmaster start */ - process_preload_libraries(); + process_shared_preload_libraries(); /* * Remove old temporary files. At this point there can be no other diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 9cb61c16cb..af9578b15a 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.498 2006/08/13 22:18:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.499 2006/08/15 18:26:58 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -3000,6 +3000,12 @@ PostgresMain(int argc, char *argv[], const char *username) if (IsUnderPostmaster && Log_disconnections) on_proc_exit(log_disconnections, 0); + /* + * process any libraries that should be preloaded at backend start + * (this likewise can't be done until GUC settings are complete) + */ + process_local_preload_libraries(); + /* * Send this backend's cancellation info to the frontend. */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 7d6941ddce..ce86a90ba3 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.265 2006/08/12 20:05:56 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.266 2006/08/15 18:26:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -886,12 +886,9 @@ ProcessUtility(Node *parsetree, { LoadStmt *stmt = (LoadStmt *) parsetree; - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to do LOAD"))); closeAllVfds(); /* probably not necessary... */ - load_file(stmt->filename); + /* Allowed names are restricted if you're not superuser */ + load_file(stmt->filename, !superuser()); } break; diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index fd2c54c211..3c2b34e3e6 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.87 2006/08/08 19:15:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.88 2006/08/15 18:26:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,12 +23,20 @@ #endif #include "miscadmin.h" #include "utils/dynamic_loader.h" +#include "utils/hsearch.h" /* signatures for PostgreSQL-specific library init/fini functions */ typedef void (*PG_init_t)(void); typedef void (*PG_fini_t)(void); +/* hashtable entry for rendezvous variables */ +typedef struct +{ + char varName[NAMEDATALEN]; /* hash key (must be first) */ + void *varValue; +} rendezvousHashEntry; + /* * List of dynamically loaded files (kept in malloc'd memory). */ @@ -62,10 +70,13 @@ static DynamicFileList *file_tail = NULL; char *Dynamic_library_path; +static void *internal_load_library(const char *libname); +static void internal_unload_library(const char *libname); static bool file_exists(const char *name); -static char *find_in_dynamic_libpath(const char *basename); static char *expand_dynamic_library_name(const char *name); +static void check_restricted_library_name(const char *name); static char *substitute_libpath_macro(const char *name); +static char *find_in_dynamic_libpath(const char *basename); /* Magic structure that module needs to match to be accepted */ static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA; @@ -73,7 +84,7 @@ static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA; /* * Load the specified dynamic-link library file, and look for a function - * named funcname in it. (funcname can be NULL to just load the file.) + * named funcname in it. * * If the function is not found, we raise an error if signalNotFound is true, * else return (PGFunction) NULL. Note that errors in loading the library @@ -88,37 +99,107 @@ PGFunction load_external_function(char *filename, char *funcname, bool signalNotFound, void **filehandle) { - DynamicFileList *file_scanner; + char *fullname; + void *lib_handle; PGFunction retval; + + /* Expand the possibly-abbreviated filename to an exact path name */ + fullname = expand_dynamic_library_name(filename); + + /* Load the shared library, unless we already did */ + lib_handle = internal_load_library(fullname); + + /* Return handle if caller wants it */ + if (filehandle) + *filehandle = lib_handle; + + /* Look up the function within the library */ + retval = pg_dlsym(lib_handle, funcname); + + if (retval == NULL && signalNotFound) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not find function \"%s\" in file \"%s\"", + funcname, fullname))); + + pfree(fullname); + return retval; +} + +/* + * This function loads a shlib file without looking up any particular + * function in it. If the same shlib has previously been loaded, + * unload and reload it. + * + * When 'restrict' is true, only libraries in the presumed-secure + * directory $libdir/plugins may be referenced. + */ +void +load_file(const char *filename, bool restrict) +{ + char *fullname; + + /* Apply security restriction if requested */ + if (restrict) + check_restricted_library_name(filename); + + /* Expand the possibly-abbreviated filename to an exact path name */ + fullname = expand_dynamic_library_name(filename); + + /* Unload the library if currently loaded */ + internal_unload_library(fullname); + + /* Load the shared library */ + (void) internal_load_library(fullname); + + pfree(fullname); +} + +/* + * Lookup a function whose library file is already loaded. + * Return (PGFunction) NULL if not found. + */ +PGFunction +lookup_external_function(void *filehandle, char *funcname) +{ + return pg_dlsym(filehandle, funcname); +} + + +/* + * Load the specified dynamic-link library file, unless it already is + * loaded. Return the pg_dl* handle for the file. + * + * Note: libname is expected to be an exact name for the library file. + */ +static void * +internal_load_library(const char *libname) +{ + DynamicFileList *file_scanner; PGModuleMagicFunction magic_func; char *load_error; struct stat stat_buf; - char *fullname; PG_init_t PG_init; - fullname = expand_dynamic_library_name(filename); - if (!fullname) - fullname = pstrdup(filename); - /* at this point fullname is always freshly palloc'd */ - /* * Scan the list of loaded FILES to see if the file has been loaded. */ for (file_scanner = file_list; file_scanner != NULL && - strcmp(fullname, file_scanner->filename) != 0; + strcmp(libname, file_scanner->filename) != 0; file_scanner = file_scanner->next) ; + if (file_scanner == NULL) { /* * Check for same files - different paths (ie, symlink or link) */ - if (stat(fullname, &stat_buf) == -1) + if (stat(libname, &stat_buf) == -1) ereport(ERROR, (errcode_for_file_access(), errmsg("could not access file \"%s\": %m", - fullname))); + libname))); for (file_scanner = file_list; file_scanner != NULL && @@ -133,21 +214,21 @@ load_external_function(char *filename, char *funcname, * File not loaded yet. */ file_scanner = (DynamicFileList *) - malloc(sizeof(DynamicFileList) + strlen(fullname)); + malloc(sizeof(DynamicFileList) + strlen(libname)); if (file_scanner == NULL) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); MemSet(file_scanner, 0, sizeof(DynamicFileList)); - strcpy(file_scanner->filename, fullname); + strcpy(file_scanner->filename, libname); file_scanner->device = stat_buf.st_dev; #ifndef WIN32 file_scanner->inode = stat_buf.st_ino; #endif file_scanner->next = NULL; - file_scanner->handle = pg_dlopen(fullname); + file_scanner->handle = pg_dlopen(file_scanner->filename); if (file_scanner->handle == NULL) { load_error = (char *) pg_dlerror(); @@ -156,7 +237,7 @@ load_external_function(char *filename, char *funcname, ereport(ERROR, (errcode_for_file_access(), errmsg("could not load library \"%s\": %s", - fullname, load_error))); + libname, load_error))); } /* Check the magic function to determine compatibility */ @@ -184,7 +265,7 @@ load_external_function(char *filename, char *funcname, if (module_magic_data.version != magic_data.version) ereport(ERROR, (errmsg("incompatible library \"%s\": version mismatch", - fullname), + libname), errdetail("Server is version %d.%d, library is version %d.%d.", magic_data.version/100, magic_data.version % 100, @@ -192,7 +273,7 @@ load_external_function(char *filename, char *funcname, module_magic_data.version % 100))); ereport(ERROR, (errmsg("incompatible library \"%s\": magic block mismatch", - fullname))); + libname))); } } else @@ -203,7 +284,7 @@ load_external_function(char *filename, char *funcname, /* complain */ ereport(ERROR, (errmsg("incompatible library \"%s\": missing magic block", - fullname), + libname), errhint("Extension libraries are now required to use the PG_MODULE_MAGIC macro."))); } @@ -222,77 +303,48 @@ load_external_function(char *filename, char *funcname, file_tail = file_scanner; } - /* Return handle if caller wants it. */ - if (filehandle) - *filehandle = file_scanner->handle; - - /* - * If funcname is NULL, we only wanted to load the file. - */ - if (funcname == NULL) - { - pfree(fullname); - return NULL; - } - - retval = pg_dlsym(file_scanner->handle, funcname); - - if (retval == NULL && signalNotFound) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("could not find function \"%s\" in file \"%s\"", - funcname, fullname))); - - pfree(fullname); - return retval; + return file_scanner->handle; } /* - * This function loads a shlib file without looking up any particular - * function in it. If the same shlib has previously been loaded, - * unload and reload it. + * Unload the specified dynamic-link library file, if it is loaded. + * + * Note: libname is expected to be an exact name for the library file. */ -void -load_file(char *filename) +static void +internal_unload_library(const char *libname) { DynamicFileList *file_scanner, *prv, *nxt; struct stat stat_buf; - char *fullname; PG_fini_t PG_fini; - fullname = expand_dynamic_library_name(filename); - if (!fullname) - fullname = pstrdup(filename); - /* at this point fullname is always freshly palloc'd */ - /* * We need to do stat() in order to determine whether this is the same * file as a previously loaded file; it's also handy so as to give a good * error message if bogus file name given. */ - if (stat(fullname, &stat_buf) == -1) + if (stat(libname, &stat_buf) == -1) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not access file \"%s\": %m", fullname))); + errmsg("could not access file \"%s\": %m", libname))); /* * We have to zap all entries in the list that match on either filename or - * inode, else load_external_function() won't do anything. + * inode, else internal_load_library() will still think it's present. */ prv = NULL; for (file_scanner = file_list; file_scanner != NULL; file_scanner = nxt) { nxt = file_scanner->next; - if (strcmp(fullname, file_scanner->filename) == 0 || + if (strcmp(libname, file_scanner->filename) == 0 || SAME_INODE(stat_buf, *file_scanner)) { if (prv) prv->next = nxt; else file_list = nxt; - clear_external_function_hash(file_scanner->handle); /* * If the library has a _PG_fini() function, call it. @@ -301,6 +353,7 @@ load_file(char *filename) if (PG_fini) (*PG_fini)(); + clear_external_function_hash(file_scanner->handle); pg_dlclose(file_scanner->handle); free((char *) file_scanner); /* prv does not change */ @@ -308,23 +361,8 @@ load_file(char *filename) else prv = file_scanner; } - - load_external_function(fullname, NULL, false, NULL); - - pfree(fullname); } -/* - * Lookup a function whose library file is already loaded. - * Return (PGFunction) NULL if not found. - */ -PGFunction -lookup_external_function(void *filehandle, char *funcname) -{ - return pg_dlsym(filehandle, funcname); -} - - static bool file_exists(const char *name) { @@ -353,9 +391,9 @@ file_exists(const char *name) * the name. Else (no slash) try to expand using search path (see * find_in_dynamic_libpath below); if that works, return the fully * expanded file name. If the previous failed, append DLSUFFIX and - * try again. If all fails, return NULL. + * try again. If all fails, just return the original name. * - * A non-NULL result will always be freshly palloc'd. + * The result will always be freshly palloc'd. */ static char * expand_dynamic_library_name(const char *name) @@ -402,9 +440,28 @@ expand_dynamic_library_name(const char *name) pfree(full); } - return NULL; + /* + * If we can't find the file, just return the string as-is. + * The ensuing load attempt will fail and report a suitable message. + */ + return pstrdup(name); } +/* + * Check a restricted library name. It must begin with "$libdir/plugins/" + * and there must not be any directory separators after that (this is + * sufficient to prevent ".." style attacks). + */ +static void +check_restricted_library_name(const char *name) +{ + if (strncmp(name, "$libdir/plugins/", 16) != 0 || + first_dir_separator(name + 16) != NULL) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("access to library \"%s\" is not allowed", + name))); +} /* * Substitute for any macros appearing in the given string. @@ -418,6 +475,7 @@ substitute_libpath_macro(const char *name) AssertArg(name != NULL); + /* Currently, we only recognize $libdir at the start of the string */ if (name[0] != '$') return pstrdup(name); @@ -428,7 +486,8 @@ substitute_libpath_macro(const char *name) strncmp(name, "$libdir", strlen("$libdir")) != 0) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), - errmsg("invalid macro name in dynamic library path: %s", name))); + errmsg("invalid macro name in dynamic library path: %s", + name))); ret = palloc(strlen(pkglib_path) + strlen(sep_ptr) + 1); @@ -513,3 +572,58 @@ find_in_dynamic_libpath(const char *basename) return NULL; } + + +/* + * Find (or create) a rendezvous variable that one dynamically + * loaded library can use to meet up with another. + * + * On the first call of this function for a particular varName, + * a "rendezvous variable" is created with the given name. + * The value of the variable is a void pointer (initially set to NULL). + * Subsequent calls with the same varName just return the address of + * the existing variable. Once created, a rendezvous variable lasts + * for the life of the process. + * + * Dynamically loaded libraries can use rendezvous variables + * to find each other and share information: they just need to agree + * on the variable name and the data it will point to. + */ +void ** +find_rendezvous_variable(const char *varName) +{ + static HTAB *rendezvousHash = NULL; + + char key[NAMEDATALEN]; + rendezvousHashEntry *hentry; + bool found; + + /* Create a hashtable if we haven't already done so in this process */ + if (rendezvousHash == NULL) + { + HASHCTL ctl; + + MemSet(&ctl, 0, sizeof(ctl)); + ctl.keysize = NAMEDATALEN; + ctl.entrysize = sizeof(rendezvousHashEntry); + rendezvousHash = hash_create("Rendezvous variable hash", + 16, + &ctl, + HASH_ELEM); + } + + /* Turn the varName into a fixed-size string */ + StrNCpy(key, varName, sizeof(key)); + + /* Find or create the hashtable entry for this varName */ + hentry = (rendezvousHashEntry *) hash_search(rendezvousHash, + key, + HASH_ENTER, + &found); + + /* Initialize to NULL if first time */ + if (!found) + hentry->varValue = NULL; + + return &hentry->varValue; +} diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index b238aaec5c..3b2cb2f9c8 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.156 2006/08/08 19:15:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.157 2006/08/15 18:26:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1097,24 +1097,31 @@ ValidatePgVersion(const char *path) *------------------------------------------------------------------------- */ -/* GUC variable: list of library names to be preloaded */ -char *preload_libraries_string = NULL; +/* + * GUC variables: lists of library names to be preloaded at postmaster + * start and at backend start + */ +char *shared_preload_libraries_string = NULL; +char *local_preload_libraries_string = NULL; /* - * process any libraries that should be preloaded at postmaster start + * load the shared libraries listed in 'libraries' + * + * 'gucname': name of GUC variable, for error reports + * 'restrict': if true, force libraries to be in $libdir/plugins/ */ -void -process_preload_libraries(void) +static void +load_libraries(const char *libraries, const char *gucname, bool restrict) { char *rawstring; List *elemlist; ListCell *l; - if (preload_libraries_string == NULL) - return; + if (libraries == NULL || libraries[0] == '\0') + return; /* nothing to do */ /* Need a modifiable copy of string */ - rawstring = pstrdup(preload_libraries_string); + rawstring = pstrdup(libraries); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawstring, ',', &elemlist)) @@ -1124,7 +1131,8 @@ process_preload_libraries(void) list_free(elemlist); ereport(LOG, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("invalid list syntax for parameter \"preload_libraries\""))); + errmsg("invalid list syntax in parameter \"%s\"", + gucname))); return; } @@ -1135,12 +1143,45 @@ process_preload_libraries(void) filename = pstrdup(tok); canonicalize_path(filename); - (void) load_external_function(filename, NULL, true, NULL); + /* If restricting, insert $libdir/plugins if not mentioned already */ + if (restrict && first_dir_separator(filename) == NULL) + { + char *expanded; + + expanded = palloc(strlen("$libdir/plugins/") + strlen(filename) + 1); + strcpy(expanded, "$libdir/plugins/"); + strcat(expanded, filename); + pfree(filename); + filename = expanded; + } + load_file(filename, restrict); ereport(LOG, - (errmsg("preloaded library \"%s\"", filename))); + (errmsg("loaded library \"%s\"", filename))); pfree(filename); } pfree(rawstring); list_free(elemlist); } + +/* + * process any libraries that should be preloaded at postmaster start + */ +void +process_shared_preload_libraries(void) +{ + load_libraries(shared_preload_libraries_string, + "shared_preload_libraries", + false); +} + +/* + * process any libraries that should be preloaded at backend start + */ +void +process_local_preload_libraries(void) +{ + load_libraries(local_preload_libraries_string, + "local_preload_libraries", + true); +} diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0e16035ef6..69c67471fc 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.341 2006/08/14 02:27:26 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.342 2006/08/15 18:26:59 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -1964,12 +1964,22 @@ static struct config_string ConfigureNamesString[] = }, { - {"preload_libraries", PGC_POSTMASTER, RESOURCES_KERNEL, + {"shared_preload_libraries", PGC_POSTMASTER, RESOURCES_KERNEL, gettext_noop("Lists shared libraries to preload into server."), NULL, GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY }, - &preload_libraries_string, + &shared_preload_libraries_string, + "", NULL, NULL + }, + + { + {"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_OTHER, + gettext_noop("Lists shared libraries to preload into each backend."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE + }, + &local_preload_libraries_string, "", NULL, NULL }, diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index edecda549e..b0c6cdf763 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -120,7 +120,7 @@ #max_files_per_process = 1000 # min 25 # (change requires restart) -#preload_libraries = '' # (change requires restart) +#shared_preload_libraries = '' # (change requires restart) # - Cost-Based Vacuum Delay - @@ -419,6 +419,7 @@ #explain_pretty_print = on #dynamic_library_path = '$libdir' +#local_preload_libraries = '' #--------------------------------------------------------------------------- diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 5b904cbad4..2e9e3f7182 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -11,7 +11,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.45 2006/05/31 20:58:09 tgl Exp $ + * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.46 2006/08/15 18:26:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -488,7 +488,8 @@ extern char *Dynamic_library_path; extern PGFunction load_external_function(char *filename, char *funcname, bool signalNotFound, void **filehandle); extern PGFunction lookup_external_function(void *filehandle, char *funcname); -extern void load_file(char *filename); +extern void load_file(const char *filename, bool restrict); +extern void **find_rendezvous_variable(const char *varName); /* diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 07590c9294..8a050f5b7d 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.187 2006/08/08 19:15:08 tgl Exp $ + * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.188 2006/08/15 18:26:59 tgl Exp $ * * NOTES * some of the information in this file should be moved to other files. @@ -307,7 +307,8 @@ extern void BaseInit(void); /* in utils/init/miscinit.c */ extern bool IgnoreSystemIndexes; -extern char *preload_libraries_string; +extern char *shared_preload_libraries_string; +extern char *local_preload_libraries_string; extern void SetReindexProcessing(Oid heapOid, Oid indexOid); extern void ResetReindexProcessing(void); @@ -319,6 +320,7 @@ extern void TouchSocketLockFile(void); extern void RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2); extern void ValidatePgVersion(const char *path); -extern void process_preload_libraries(void); +extern void process_shared_preload_libraries(void); +extern void process_local_preload_libraries(void); #endif /* MISCADMIN_H */