Skip to content

Commit 026d6b0

Browse files
lubennikovaavtristan957
authored andcommitted
Request extension files and libraries from compute_ctl
1 parent fcd0bde commit 026d6b0

File tree

3 files changed

+97
-5
lines changed

3 files changed

+97
-5
lines changed

src/backend/commands/extension.c

+18
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ get_extension_script_directory(ExtensionControlFile *control)
399399
{
400400
char sharepath[MAXPGPATH];
401401
char *result;
402+
struct stat fst;
402403

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

418+
// If directory does not exist, check remote extension storage
419+
if (stat(result, &fst) < 0)
420+
{
421+
// request download of extension files from for control->directory
422+
if (download_extension_file_hook != NULL)
423+
{
424+
download_extension_file_hook(control->directory, false);
425+
}
426+
}
427+
417428
return result;
418429
}
419430

@@ -1453,6 +1464,13 @@ CreateExtensionInternal(char *extensionName,
14531464
* will get us there.
14541465
*/
14551466
filename = get_extension_script_filename(pcontrol, NULL, versionName);
1467+
1468+
// request download of extension files from compute_ctl
1469+
if (download_extension_file_hook != NULL)
1470+
{
1471+
download_extension_file_hook(extensionName, false);
1472+
}
1473+
14561474
if (stat(filename, &fst) == 0)
14571475
{
14581476
/* Easy, no extra scripts */

src/backend/utils/fmgr/dfmgr.c

+73-5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "storage/shmem.h"
3737
#include "utils/hsearch.h"
3838

39+
download_extension_file_hook_type download_extension_file_hook = NULL;
3940

4041
/* signature for PostgreSQL-specific library init function */
4142
typedef void (*PG_init_t) (void);
@@ -79,11 +80,13 @@ static void *internal_load_library(const char *libname);
7980
static void incompatible_module_error(const char *libname,
8081
const Pg_magic_struct *module_magic_data) pg_attribute_noreturn();
8182
static bool file_exists(const char *name);
82-
static char *expand_dynamic_library_name(const char *name);
83+
static char *expand_dynamic_library_name(const char *name, bool *is_found);
8384
static void check_restricted_library_name(const char *name);
8485
static char *substitute_libpath_macro(const char *name);
8586
static char *find_in_dynamic_libpath(const char *basename);
8687

88+
static void neon_try_load(const char *name);
89+
8790
/* Magic structure that module needs to match to be accepted */
8891
static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA;
8992

@@ -108,9 +111,20 @@ load_external_function(const char *filename, const char *funcname,
108111
char *fullname;
109112
void *lib_handle;
110113
void *retval;
114+
bool is_found = true;
111115

112116
/* Expand the possibly-abbreviated filename to an exact path name */
113-
fullname = expand_dynamic_library_name(filename);
117+
fullname = expand_dynamic_library_name(filename, &is_found);
118+
119+
// if file is not found, try to download it from compute_ctl
120+
if (!is_found && download_extension_file_hook != NULL)
121+
{
122+
// try to download the file
123+
elog(DEBUG3, "load_external_function: try to download file: %s", fullname);
124+
neon_try_load(fullname);
125+
// try to find file locally once again
126+
fullname = expand_dynamic_library_name(filename, &is_found);
127+
}
114128

115129
/* Load the shared library, unless we already did */
116130
lib_handle = internal_load_library(fullname);
@@ -132,6 +146,47 @@ load_external_function(const char *filename, const char *funcname,
132146
return retval;
133147
}
134148

149+
void
150+
neon_try_load(const char *name)
151+
{
152+
bool have_slash;
153+
char *request_name;
154+
155+
// add .so suffix if it is not present
156+
if (strstr(name, DLSUFFIX) == NULL)
157+
{
158+
request_name = psprintf("%s%s", name, DLSUFFIX);
159+
elog(DEBUG3, "neon_try_load: add DLSUFFIX: %s", request_name);
160+
}
161+
else
162+
{
163+
request_name = pstrdup(name);
164+
elog(DEBUG3, "neon_try_load: DLSUFFIX already present: %s", request_name);
165+
}
166+
167+
have_slash = (first_dir_separator(request_name) != NULL);
168+
169+
if (strncmp(request_name, "$libdir/", strlen("$libdir/")) == 0)
170+
{
171+
char *new_request_name = psprintf("%s", request_name + strlen("$libdir/"));
172+
pfree(request_name);
173+
request_name = new_request_name;
174+
175+
elog(DEBUG3, "neon_try_load: omit $libdir/: %s", request_name);
176+
}
177+
else if (have_slash)
178+
{
179+
ereport(ERROR,
180+
(errcode(ERRCODE_INVALID_NAME),
181+
errmsg("unexpected path in dynamic library name: %s",
182+
name)));
183+
}
184+
185+
elog(DEBUG3, "neon_try_load: final request_name: %s", request_name);
186+
187+
download_extension_file_hook(request_name, true);
188+
}
189+
135190
/*
136191
* This function loads a shlib file without looking up any particular
137192
* function in it. If the same shlib has previously been loaded,
@@ -144,13 +199,24 @@ void
144199
load_file(const char *filename, bool restricted)
145200
{
146201
char *fullname;
202+
bool is_found = true;
147203

148204
/* Apply security restriction if requested */
149205
if (restricted)
150206
check_restricted_library_name(filename);
151207

152208
/* Expand the possibly-abbreviated filename to an exact path name */
153-
fullname = expand_dynamic_library_name(filename);
209+
fullname = expand_dynamic_library_name(filename, &is_found);
210+
211+
// if file is not found, try to download it from compute_ctl
212+
if (!is_found && download_extension_file_hook != NULL)
213+
{
214+
// try to download the file
215+
elog(DEBUG3, "load_file: try to download file: %s", fullname);
216+
neon_try_load(fullname);
217+
// try to find file locally once again
218+
fullname = expand_dynamic_library_name(filename, &is_found);
219+
}
154220

155221
/* Load the shared library */
156222
(void) internal_load_library(fullname);
@@ -168,7 +234,6 @@ lookup_external_function(void *filehandle, const char *funcname)
168234
return dlsym(filehandle, funcname);
169235
}
170236

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

277+
212278
for (file_scanner = file_list;
213279
file_scanner != NULL &&
214280
!SAME_INODE(stat_buf, *file_scanner);
@@ -428,7 +494,7 @@ file_exists(const char *name)
428494
* The result will always be freshly palloc'd.
429495
*/
430496
static char *
431-
expand_dynamic_library_name(const char *name)
497+
expand_dynamic_library_name(const char *name, bool *is_found)
432498
{
433499
bool have_slash;
434500
char *new;
@@ -474,9 +540,11 @@ expand_dynamic_library_name(const char *name)
474540
* If we can't find the file, just return the string as-is. The ensuing
475541
* load attempt will fail and report a suitable message.
476542
*/
543+
*is_found = false;
477544
return pstrdup(name);
478545
}
479546

547+
480548
/*
481549
* Check a restricted library name. It must begin with "$libdir/plugins/"
482550
* and there must not be any directory separators after that (this is

src/include/fmgr.h

+6
Original file line numberDiff line numberDiff line change
@@ -778,4 +778,10 @@ extern PGDLLIMPORT fmgr_hook_type fmgr_hook;
778778
#define FmgrHookIsNeeded(fn_oid) \
779779
(!needs_fmgr_hook ? false : (*needs_fmgr_hook)(fn_oid))
780780

781+
782+
783+
// download_extension_file_hook (filename, is_library)
784+
typedef bool (*download_extension_file_hook_type) (const char *, bool);
785+
extern PGDLLIMPORT download_extension_file_hook_type download_extension_file_hook;
786+
781787
#endif /* FMGR_H */

0 commit comments

Comments
 (0)