diff --git a/src/common/plugin.c b/src/common/plugin.c index 74bc1e8ba880a17dd337a411f5bfaa76d8dde6d1..87b93fe0d8abacbda6b551957c3bfbc798f71fa2 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -140,12 +140,25 @@ plugin_peek( const char *fq_path, return SLURM_SUCCESS; } -plugin_handle_t -plugin_load_from_file(const char *fq_path) +plugin_err_t +plugin_load_from_file(plugin_handle_t *p, const char *fq_path) { + struct stat st; plugin_handle_t plug; int (*init)(void); + *p = PLUGIN_INVALID_HANDLE; + + /* + * Check for file existence and access permissions + */ + if (access(fq_path, R_OK) < 0) { + if (errno == ENOENT) + return EPLUGIN_NOTFOUND; + else + return EPLUGIN_ACCESS_ERROR; + } + /* * Try to open the shared object. * @@ -161,16 +174,15 @@ plugin_load_from_file(const char *fq_path) error("plugin_load_from_file: dlopen(%s): %s", fq_path, _dlerror()); - return PLUGIN_INVALID_HANDLE; + return EPLUGIN_DLOPEN_FAILED; } /* Now see if our required symbols are defined. */ if ((dlsym(plug, PLUGIN_NAME) == NULL) || (dlsym(plug, PLUGIN_TYPE) == NULL) || (dlsym(plug, PLUGIN_VERSION) == NULL)) { - debug("plugin_load_from_file: invalid symbol"); - /* slurm_seterrno( SLURM_PLUGIN_SYMBOLS ); */ - return PLUGIN_INVALID_HANDLE; + dlclose (plug); + return EPLUGIN_MISSING_SYMBOL; } /* @@ -179,14 +191,13 @@ plugin_load_from_file(const char *fq_path) */ if ((init = dlsym(plug, "init")) != NULL) { if ((*init)() != 0) { - error("plugin_load_from_file(%s): init() returned SLURM_ERROR", - fq_path); - (void) dlclose(plug); - return PLUGIN_INVALID_HANDLE; + dlclose(plug); + return EPLUGIN_INIT_FAILED; } } - return plug; + *p = plug; + return EPLUGIN_SUCCESS; } plugin_handle_t @@ -230,7 +241,7 @@ plugin_load_and_link(const char *type_name, int n_syms, debug4("No Good."); xfree(file_name); } else { - plug = plugin_load_from_file(file_name); + plugin_load_from_file(&plug, file_name); xfree(file_name); if (plugin_get_syms(plug, n_syms, names, ptrs) >= n_syms) { diff --git a/src/common/plugin.h b/src/common/plugin.h index ee346e01e73370d016f310254c41f89291eb7919..1e5c3fbc8e601bf47db5ba5157d114796b7463c1 100644 --- a/src/common/plugin.h +++ b/src/common/plugin.h @@ -119,15 +119,17 @@ int plugin_peek( const char *fq_path, /* * Simplest way to get a plugin -- load it from a file. * + * pph - Pointer to a plugin handle * fq_path - the fully-qualified pathname (i.e., from root) to * the plugin to load. * - * Returns a handle if successful, or NULL if not. + * Returns EPLUGIN_SUCCESS on success, and an plugin_err_t error + * code on failure. * * The plugin's initialization code will be executed prior * to this function's return. */ -plugin_handle_t plugin_load_from_file( const char *fq_path ); +plugin_err_t plugin_load_from_file(plugin_handle_t *pph, const char *fq_path); /* * load plugin and link hooks. diff --git a/src/common/plugrack.c b/src/common/plugrack.c index 27256a3e8c51f66919dc497deefa1a10b02e66b9..18e5c490bb4efb8541cda489802e986d48899bde 100644 --- a/src/common/plugrack.c +++ b/src/common/plugrack.c @@ -548,7 +548,7 @@ plugrack_load_all( plugrack_t rack ) it = list_iterator_create( rack->entries ); while ( ( e = list_next( it ) ) != NULL ) { if ( e->plug == PLUGIN_INVALID_HANDLE ) { - e->plug = plugin_load_from_file( e->fq_path ); + plugin_load_from_file(&e->plug, e->fq_path); } } @@ -585,7 +585,7 @@ plugrack_use_by_type( plugrack_t rack, /* See if plugin is loaded. */ if ( e->plug == PLUGIN_INVALID_HANDLE ) - e->plug = plugin_load_from_file( e->fq_path ); + plugin_load_from_file(&e->plug, e->fq_path); /* If load was successful, increment the reference count. */ if ( e->plug == PLUGIN_INVALID_HANDLE ) diff --git a/src/common/plugstack.c b/src/common/plugstack.c index 543e56f0c06b20c5873eebef2df9d0a1adc877c7..fa8beeb2ad4ef6efc4b9ecb97aa2e0d495b78198 100644 --- a/src/common/plugstack.c +++ b/src/common/plugstack.c @@ -260,10 +260,13 @@ static struct spank_plugin *_spank_plugin_create(char *path, int ac, { struct spank_plugin *plugin; plugin_handle_t p; + plugin_err_t e; struct spank_plugin_operations ops; - if (!(p = plugin_load_from_file(path))) + if ((e = plugin_load_from_file(&p, path)) != EPLUGIN_SUCCESS) { + error ("spank: %s: %s\n", path, plugin_strerror(e)); return NULL; + } if (plugin_get_syms(p, n_spank_syms, spank_syms, (void **)&ops) == 0) { error("spank: \"%s\" exports 0 symbols\n", path);