1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-18 04:29:09 +03:00

Add server support for "plugin" libraries that can be used for add-on tasks

such as debugging and performance measurement.  This consists of two features:
a table of "rendezvous variables" that allows separately-loaded shared
libraries to communicate, and a new GUC setting "local_preload_libraries"
that allows libraries to be loaded into specific sessions without explicit
cooperation from the client application.  To make local_preload_libraries
as flexible as possible, we do not restrict its use to superusers; instead,
it is restricted to load only libraries stored in $libdir/plugins/.  The
existing LOAD command has also been modified to allow non-superusers to
LOAD libraries stored in this directory.

This patch also renames the existing GUC variable preload_libraries to
shared_preload_libraries (after a suggestion by Simon Riggs) and does some
code refactoring in dfmgr.c to improve clarity.

Korry Douglas, with a little help from Tom Lane.
This commit is contained in:
Tom Lane
2006-08-15 18:26:59 +00:00
parent 66541c5aa5
commit abc3120e9b
11 changed files with 353 additions and 113 deletions

View File

@@ -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);
}