diff options
| author | Bruce Momjian <bruce@momjian.us> | 2006-05-30 14:09:32 +0000 |
|---|---|---|
| committer | Bruce Momjian <bruce@momjian.us> | 2006-05-30 14:09:32 +0000 |
| commit | 01b2168c90f121b5be7da72786c051588c43c128 (patch) | |
| tree | f6509f08f087f762892f1d47bde60456c34f53df /src/backend | |
| parent | 87bd07d97989bafe63a029931a65512aca4ba531 (diff) | |
| download | postgresql-01b2168c90f121b5be7da72786c051588c43c128.tar.gz | |
Add pgmagic header block to store compile-time constants:
It now only checks four things:
Major version number (7.4 or 8.1 for example)
NAMEDATALEN
FUNC_MAX_ARGS
INDEX_MAX_KEYS
The three constants were chosen because:
1. We document them in the config page in the docs
2. We mark them as changable in pg_config_manual.h
3. Changing any of these will break some of the more popular modules:
FUNC_MAX_ARGS changes fmgr interface, every module uses this NAMEDATALEN
changes syscache interface, every PL as well as tsearch uses this
INDEX_MAX_KEYS breaks tsearch and anything using GiST.
Martijn van Oosterhout
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/utils/fmgr/dfmgr.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index 582c1b0565..5379b89902 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.82 2006/03/05 15:58:46 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.83 2006/05/30 14:09:32 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ #include "dynloader.h" #include "miscadmin.h" #include "utils/dynamic_loader.h" - +#include "pgmagic.h" /* * List of dynamically loaded files (kept in malloc'd memory). @@ -60,6 +60,9 @@ static char *find_in_dynamic_libpath(const char *basename); static char *expand_dynamic_library_name(const char *name); static char *substitute_libpath_macro(const char *name); +/* Magic structure that module needs to match to be accepted */ +static 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.) @@ -116,6 +119,7 @@ load_external_function(char *filename, char *funcname, if (file_scanner == NULL) { + PGModuleMagicFunction magic_func; /* * File not loaded yet. */ @@ -146,6 +150,45 @@ load_external_function(char *filename, char *funcname, fullname, load_error))); } + /* Check the magic function to determine compatability */ + magic_func = pg_dlsym( file_scanner->handle, PG_MAGIC_FUNCTION_NAME_STRING ); + if( magic_func ) + { + Pg_magic_struct *module_magic_data = magic_func(); + if( module_magic_data->len != magic_data.len || + memcmp( module_magic_data, &magic_data, magic_data.len ) != 0 ) + { + pg_dlclose( file_scanner->handle ); + + if( module_magic_data->len != magic_data.len ) + ereport(ERROR, + (errmsg("incompatible library \"%s\": Magic block length mismatch", + fullname))); + if( module_magic_data->version != magic_data.version ) + ereport(ERROR, + (errmsg("incompatible library \"%s\": Version mismatch", + fullname), + errdetail("Expected %d.%d, got %d.%d", + magic_data.version/100, magic_data.version % 100, + module_magic_data->version/100, module_magic_data->version % 100))); + + if( module_magic_data->magic != magic_data.magic ) + ereport(ERROR, + (errmsg("incompatible library \"%s\": Magic constant mismatch", + fullname), + errdetail("Expected 0x%08X, got 0x%08X", + magic_data.magic, magic_data.magic))); + /* Should never get here */ + ereport(ERROR,(errmsg("incompatible library \"%s\": Reason unknown", + fullname))); + } + } + else + /* Currently we do not penalize modules for not having a + magic block, it would break every external module in + existance. At some point though... */ + ereport(LOG, (errmsg("external library \"%s\" did not have magic block", fullname ))); + /* OK to link it into list */ if (file_list == NULL) file_list = file_scanner; |
