Skip to content

Commit

Permalink
Request extension files and libraries from compute_ctl
Browse files Browse the repository at this point in the history
  • Loading branch information
lubennikovaav authored and tristan957 committed Aug 9, 2023
1 parent 07873a7 commit 5d5cfee
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
18 changes: 18 additions & 0 deletions src/backend/commands/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ get_extension_script_directory(ExtensionControlFile *control)
{
char sharepath[MAXPGPATH];
char *result;
struct stat fst;

/*
* The directory parameter can be omitted, absolute, or relative to the
Expand All @@ -414,6 +415,16 @@ get_extension_script_directory(ExtensionControlFile *control)
result = (char *) palloc(MAXPGPATH);
snprintf(result, MAXPGPATH, "%s/%s", sharepath, control->directory);

// If directory does not exist, check remote extension storage
if (stat(result, &fst) < 0)
{
// request download of extension files from for control->directory
if (download_extension_file_hook != NULL)
{
download_extension_file_hook(control->directory, false);
}
}

return result;
}

Expand Down Expand Up @@ -1438,6 +1449,13 @@ CreateExtensionInternal(char *extensionName,
* will get us there.
*/
filename = get_extension_script_filename(pcontrol, NULL, versionName);

// request download of extension files from compute_ctl
if (download_extension_file_hook != NULL)
{
download_extension_file_hook(extensionName, false);
}

if (stat(filename, &fst) == 0)
{
/* Easy, no extra scripts */
Expand Down
78 changes: 73 additions & 5 deletions src/backend/utils/fmgr/dfmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "storage/shmem.h"
#include "utils/hsearch.h"

download_extension_file_hook_type download_extension_file_hook = NULL;

/* signatures for PostgreSQL-specific library init/fini functions */
typedef void (*PG_init_t) (void);
Expand Down Expand Up @@ -81,11 +82,13 @@ static void incompatible_module_error(const char *libname,
const Pg_magic_struct *module_magic_data) pg_attribute_noreturn();
static void internal_unload_library(const char *libname);
static bool file_exists(const char *name);
static char *expand_dynamic_library_name(const char *name);
static char *expand_dynamic_library_name(const char *name, bool *is_found);
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);

static void neon_try_load(const char *name);

/* Magic structure that module needs to match to be accepted */
static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA;

Expand All @@ -110,9 +113,20 @@ load_external_function(const char *filename, const char *funcname,
char *fullname;
void *lib_handle;
void *retval;
bool is_found = true;

/* Expand the possibly-abbreviated filename to an exact path name */
fullname = expand_dynamic_library_name(filename);
fullname = expand_dynamic_library_name(filename, &is_found);

// if file is not found, try to download it from compute_ctl
if (!is_found && download_extension_file_hook != NULL)
{
// try to download the file
elog(DEBUG3, "load_external_function: try to download file: %s", fullname);
neon_try_load(fullname);
// try to find file locally once again
fullname = expand_dynamic_library_name(filename, &is_found);
}

/* Load the shared library, unless we already did */
lib_handle = internal_load_library(fullname);
Expand All @@ -134,6 +148,47 @@ load_external_function(const char *filename, const char *funcname,
return retval;
}

void
neon_try_load(const char *name)
{
bool have_slash;
char *request_name;

// add .so suffix if it is not present
if (strstr(name, DLSUFFIX) == NULL)
{
request_name = psprintf("%s%s", name, DLSUFFIX);
elog(DEBUG3, "neon_try_load: add DLSUFFIX: %s", request_name);
}
else
{
request_name = pstrdup(name);
elog(DEBUG3, "neon_try_load: DLSUFFIX already present: %s", request_name);
}

have_slash = (first_dir_separator(request_name) != NULL);

if (strncmp(request_name, "$libdir/", strlen("$libdir/")) == 0)
{
char *new_request_name = psprintf("%s", request_name + strlen("$libdir/"));
pfree(request_name);
request_name = new_request_name;

elog(DEBUG3, "neon_try_load: omit $libdir/: %s", request_name);
}
else if (have_slash)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("unexpected path in dynamic library name: %s",
name)));
}

elog(DEBUG3, "neon_try_load: final request_name: %s", request_name);

download_extension_file_hook(request_name, true);
}

/*
* This function loads a shlib file without looking up any particular
* function in it. If the same shlib has previously been loaded,
Expand All @@ -146,13 +201,24 @@ void
load_file(const char *filename, bool restricted)
{
char *fullname;
bool is_found = true;

/* Apply security restriction if requested */
if (restricted)
check_restricted_library_name(filename);

/* Expand the possibly-abbreviated filename to an exact path name */
fullname = expand_dynamic_library_name(filename);
fullname = expand_dynamic_library_name(filename, &is_found);

// if file is not found, try to download it from compute_ctl
if (!is_found && download_extension_file_hook != NULL)
{
// try to download the file
elog(DEBUG3, "load_file: try to download file: %s", fullname);
neon_try_load(fullname);
// try to find file locally once again
fullname = expand_dynamic_library_name(filename, &is_found);
}

/* Unload the library if currently loaded */
internal_unload_library(fullname);
Expand All @@ -173,7 +239,6 @@ lookup_external_function(void *filehandle, const char *funcname)
return dlsym(filehandle, funcname);
}


/*
* Load the specified dynamic-link library file, unless it already is
* loaded. Return the pg_dl* handle for the file.
Expand Down Expand Up @@ -209,6 +274,7 @@ internal_load_library(const char *libname)
errmsg("could not access file \"%s\": %m",
libname)));


for (file_scanner = file_list;
file_scanner != NULL &&
!SAME_INODE(stat_buf, *file_scanner);
Expand Down Expand Up @@ -483,7 +549,7 @@ file_exists(const char *name)
* The result will always be freshly palloc'd.
*/
static char *
expand_dynamic_library_name(const char *name)
expand_dynamic_library_name(const char *name, bool *is_found)
{
bool have_slash;
char *new;
Expand Down Expand Up @@ -529,9 +595,11 @@ expand_dynamic_library_name(const char *name)
* If we can't find the file, just return the string as-is. The ensuing
* load attempt will fail and report a suitable message.
*/
*is_found = false;
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
Expand Down
6 changes: 6 additions & 0 deletions src/include/fmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -774,4 +774,10 @@ extern PGDLLIMPORT fmgr_hook_type fmgr_hook;
#define FmgrHookIsNeeded(fn_oid) \
(!needs_fmgr_hook ? false : (*needs_fmgr_hook)(fn_oid))



// download_extension_file_hook (filename, is_library)
typedef bool (*download_extension_file_hook_type) (const char *, bool);
extern PGDLLIMPORT download_extension_file_hook_type download_extension_file_hook;

#endif /* FMGR_H */

0 comments on commit 5d5cfee

Please sign in to comment.