plugin_handle_t plugin_load_and_link(const char *type_name, int n_syms, const char *names[], void *ptrs[]) { plugin_handle_t plug = PLUGIN_INVALID_HANDLE; struct stat st; char *head = NULL, *dir_array = NULL, *so_name = NULL; char *file_name = NULL; int i = 0; plugin_err_t err = EPLUGIN_NOTFOUND; if (!type_name) return plug; so_name = xstrdup_printf("%s.so", type_name); while (so_name[i]) { if (so_name[i] == '/') so_name[i] = '_'; i++; } if (!(dir_array = slurm_get_plugin_dir())) { error("plugin_load_and_link: No plugin dir given"); xfree(so_name); return plug; } head = dir_array; for (i = 0; ; i++) { bool got_colon = 0; if (dir_array[i] == ':') { dir_array[i] = '\0'; got_colon = 1; } else if (dir_array[i] != '\0') continue; file_name = xstrdup_printf("%s/%s", head, so_name); debug3("Trying to load plugin %s", file_name); if ((stat(file_name, &st) < 0) || (!S_ISREG(st.st_mode))) { debug4("%s: Does not exist or not a regular file.", file_name); xfree(file_name); err = EPLUGIN_NOTFOUND; } else { if ((err = plugin_load_from_file(&plug, file_name)) == EPLUGIN_SUCCESS) { if (plugin_get_syms(plug, n_syms, names, ptrs) >= n_syms) { debug3("Success."); xfree(file_name); break; } else { (void) dlclose(plug); err = EPLUGIN_MISSING_SYMBOL; plug = PLUGIN_INVALID_HANDLE; } } else plug = PLUGIN_INVALID_HANDLE; xfree(file_name); } if (got_colon) { head = dir_array + i + 1; } else break; } xfree(dir_array); xfree(so_name); errno = err; return plug; }
/* * Create a priority context */ extern plugin_context_t *plugin_context_create( const char *plugin_type, const char *uler_type, void *ptrs[], const char *names[], size_t names_size) { plugin_context_t *c; int n_names; if (!uler_type) { debug3("plugin_context_create: no uler type"); return NULL; } else if (!plugin_type) { debug3("plugin_context_create: no plugin type"); return NULL; } else if (!names) { error("plugin_context_create: no symbols given for plugin %s", plugin_type); return NULL; } else if (!ptrs) { error("plugin_context_create: no ptrs given for plugin %s", plugin_type); return NULL; } c = xmalloc(sizeof(plugin_context_t)); c->type = xstrdup(uler_type); c->cur_plugin = PLUGIN_INVALID_HANDLE; n_names = names_size / sizeof(char *); /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->type, n_names, names, ptrs); if (c->cur_plugin != PLUGIN_INVALID_HANDLE) return c; if (errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->type, plugin_strerror(errno)); goto fail; } error("Couldn't find the specified plugin name for %s " "looking at all files", c->type); /* Get plugin list. */ if (!c->plugin_list) { char *plugin_dir; c->plugin_list = plugrack_create(); if (!c->plugin_list) { error("cannot create plugin manager"); goto fail; } plugrack_set_major_type(c->plugin_list, plugin_type); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir(c->plugin_list, plugin_dir); xfree(plugin_dir); } c->cur_plugin = plugrack_use_by_type(c->plugin_list, c->type); if (c->cur_plugin == PLUGIN_INVALID_HANDLE) { error("cannot find %s plugin for %s", plugin_type, c->type); goto fail; } /* Dereference the API. */ if (plugin_get_syms(c->cur_plugin, n_names, names, ptrs) < n_names) { error("incomplete %s plugin detected", plugin_type); goto fail; } return c; fail: plugin_context_destroy(c); return NULL; }
/* * Locate and load the appropriate plugin */ static int _select_get_ops(char *select_type, slurm_select_context_t *c) { /* * Must be synchronized with slurm_select_ops_t in node_select.h. * Also must be synchronized with the other_plugin.[c|h] in * the select/cray plugin. */ static const char *syms[] = { "plugin_id", "select_p_state_save", "select_p_state_restore", "select_p_job_init", "select_p_node_ranking", "select_p_node_init", "select_p_block_init", "select_p_job_test", "select_p_job_begin", "select_p_job_ready", "select_p_job_expand_allow", "select_p_job_expand", "select_p_job_resized", "select_p_job_signal", "select_p_job_fini", "select_p_job_suspend", "select_p_job_resume", "select_p_step_pick_nodes", "select_p_step_finish", "select_p_pack_select_info", "select_p_select_nodeinfo_pack", "select_p_select_nodeinfo_unpack", "select_p_select_nodeinfo_alloc", "select_p_select_nodeinfo_free", "select_p_select_nodeinfo_set_all", "select_p_select_nodeinfo_set", "select_p_select_nodeinfo_get", "select_p_select_jobinfo_alloc", "select_p_select_jobinfo_free", "select_p_select_jobinfo_set", "select_p_select_jobinfo_get", "select_p_select_jobinfo_copy", "select_p_select_jobinfo_pack", "select_p_select_jobinfo_unpack", "select_p_select_jobinfo_sprint", "select_p_select_jobinfo_xstrdup", "select_p_update_block", "select_p_update_sub_node", "select_p_get_info_from_plugin", "select_p_update_node_config", "select_p_update_node_state", "select_p_alter_node_cnt", "select_p_reconfigure", "select_p_resv_test", "select_p_ba_init", "select_p_ba_fini", "select_p_ba_get_dims", }; int n_syms = sizeof( syms ) / sizeof( char * ); c->select_type = xstrdup(select_type); c->plugin_list = NULL; c->cur_plugin = PLUGIN_INVALID_HANDLE; c->select_errno = SLURM_SUCCESS; /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->select_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return SLURM_SUCCESS; if(errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->select_type, plugin_strerror(errno)); return SLURM_ERROR; } error("Couldn't find the specified plugin name for %s " "looking at all files", c->select_type); /* Get plugin list. */ if ( c->plugin_list == NULL ) { char *plugin_dir; c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error( "cannot create plugin manager" ); return SLURM_ERROR; } plugrack_set_major_type( c->plugin_list, "select" ); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0 ); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir( c->plugin_list, plugin_dir ); xfree(plugin_dir); } c->cur_plugin = plugrack_use_by_type( c->plugin_list, c->select_type ); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error( "cannot find node selection plugin for %s", c->select_type ); return SLURM_ERROR; } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "incomplete node selection plugin detected" ); return SLURM_ERROR; } return SLURM_SUCCESS; }
static slurmd_task_ops_t * _slurmd_task_get_ops(slurmd_task_context_t *c) { /* * Must be synchronized with slurmd_task_ops_t above. */ static const char *syms[] = { "task_slurmd_batch_request", "task_slurmd_launch_request", "task_slurmd_reserve_resources", "task_slurmd_suspend_job", "task_slurmd_resume_job", "task_slurmd_release_resources", "task_pre_setuid", "task_pre_launch", "task_post_term", "task_post_step", }; int n_syms = sizeof( syms ) / sizeof( char * ); /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->task_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return &c->ops; if(errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->task_type, plugin_strerror(errno)); return NULL; } error("Couldn't find the specified plugin name for %s " "looking at all files", c->task_type); /* Get plugin list. */ if ( c->plugin_list == NULL ) { char *plugin_dir; c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error( "cannot create plugin manager" ); return NULL; } plugrack_set_major_type( c->plugin_list, "task" ); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0 ); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir( c->plugin_list, plugin_dir ); xfree(plugin_dir); } c->cur_plugin = plugrack_use_by_type( c->plugin_list, c->task_type ); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error( "cannot find task plugin for %s", c->task_type ); return NULL; } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "incomplete task plugin detected" ); return NULL; } return &c->ops; }
/* ************************************************************************ */ static slurm_sched_ops_t * slurm_sched_get_ops( slurm_sched_context_t *c ) { /* * Must be synchronized with slurm_sched_ops_t above. */ static const char *syms[] = { "slurm_sched_plugin_schedule", "slurm_sched_plugin_newalloc", "slurm_sched_plugin_freealloc", "slurm_sched_plugin_initial_priority", "slurm_sched_plugin_job_is_pending", "slurm_sched_plugin_reconfig", "slurm_sched_plugin_partition_change", "slurm_sched_get_errno", "slurm_sched_strerror", "slurm_sched_plugin_requeue", "slurm_sched_get_conf" }; int n_syms = sizeof( syms ) / sizeof( char * ); /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->sched_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return &c->ops; if(errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->sched_type, plugin_strerror(errno)); return NULL; } error("sched: Couldn't find the specified plugin name for %s " "looking at all files", c->sched_type); /* Get plugin list. */ if ( c->plugin_list == NULL ) { char *plugin_dir; c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error( "sched: cannot create plugin manager" ); return NULL; } plugrack_set_major_type( c->plugin_list, "sched" ); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0 ); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir( c->plugin_list, plugin_dir ); xfree(plugin_dir); } c->cur_plugin = plugrack_use_by_type( c->plugin_list, c->sched_type ); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error( "sched: cannot find scheduler plugin for %s", c->sched_type ); return NULL; } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "sched: incomplete scheduling plugin detected" ); return NULL; } return &c->ops; }
/* ************************************************************************ */ static slurm_topo_ops_t * slurm_topo_get_ops( slurm_topo_context_t *c ) { /* * Must be synchronized with slurm_topo_ops_t above. */ static const char *syms[] = { "topo_build_config", "topo_generate_node_ranking", "topo_get_node_addr", }; int n_syms = sizeof( syms ) / sizeof( char * ); /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->topo_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return &c->ops; if(errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->topo_type, plugin_strerror(errno)); return NULL; } error("Couldn't find the specified plugin name for %s " "looking at all files", c->topo_type); /* Get plugin list. */ if ( c->plugin_list == NULL ) { char *plugin_dir; c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error( "cannot create plugin manager" ); return NULL; } plugrack_set_major_type( c->plugin_list, "topo" ); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0 ); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir( c->plugin_list, plugin_dir ); xfree(plugin_dir); } c->cur_plugin = plugrack_use_by_type( c->plugin_list, c->topo_type ); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error( "cannot find topology plugin for %s", c->topo_type ); return NULL; } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "incomplete topology plugin detected" ); return NULL; } return &c->ops; }
/* * Resolve the operations from the plugin. */ static slurm_mpi_ops_t * _slurm_mpi_get_ops( slurm_mpi_context_t c ) { /* * These strings must be kept in the same order as the fields * declared for slurm_mpi_ops_t. */ static const char *syms[] = { "p_mpi_hook_slurmstepd_task", "p_mpi_hook_client_prelaunch", "p_mpi_hook_client_single_task_per_node", "p_mpi_hook_client_fini" }; int n_syms = sizeof( syms ) / sizeof( char * ); char *plugin_dir = NULL; /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->mpi_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return &c->ops; error("Couldn't find the specified plugin name for %s " "looking at all files", c->mpi_type); /* Get the plugin list, if needed. */ if ( c->plugin_list == NULL ) { c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error("Unable to create a plugin manager"); return NULL; } plugrack_set_major_type(c->plugin_list, "mpi"); plugrack_set_paranoia(c->plugin_list, PLUGRACK_PARANOIA_NONE, 0); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir(c->plugin_list, plugin_dir); xfree(plugin_dir); } if (strcasecmp (c->mpi_type, "mpi/list") == 0) { plugrack_print_all_plugin(c->plugin_list); exit(0); } else { /* Find the correct plugin. */ c->cur_plugin = plugrack_use_by_type(c->plugin_list, c->mpi_type); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error("can't find a valid plugin for type %s", c->mpi_type); return NULL; } } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "incomplete mpi plugin detected" ); return NULL; } return &c->ops; }
/* * Resolve the operations from the plugin. */ static slurm_checkpoint_ops_t * _slurm_checkpoint_get_ops( slurm_checkpoint_context_t c ) { /* * These strings must be kept in the same order as the fields * declared for slurm_checkpoint_ops_t. */ static const char *syms[] = { "slurm_ckpt_op", "slurm_ckpt_comp", "slurm_ckpt_task_comp", "slurm_ckpt_alloc_job", "slurm_ckpt_free_job", "slurm_ckpt_pack_job", "slurm_ckpt_unpack_job", "slurm_ckpt_stepd_prefork", "slurm_ckpt_signal_tasks", "slurm_ckpt_restart_task" }; int n_syms = sizeof( syms ) / sizeof( char * ); /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->checkpoint_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return &c->ops; if(errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->checkpoint_type, plugin_strerror(errno)); return NULL; } error("Couldn't find the specified plugin name for %s " "looking at all files", c->checkpoint_type); /* Get the plugin list, if needed. */ if ( c->plugin_list == NULL ) { char *plugin_dir; c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error( "Unable to create a plugin manager" ); return NULL; } plugrack_set_major_type( c->plugin_list, "checkpoint" ); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0 ); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir( c->plugin_list, plugin_dir ); xfree(plugin_dir); } /* Find the correct plugin. */ c->cur_plugin = plugrack_use_by_type( c->plugin_list, c->checkpoint_type ); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error( "can't find a plugin for type %s", c->checkpoint_type ); return NULL; } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "incomplete checkpoint plugin detected" ); return NULL; } return &c->ops; }
/* * Locate and load the appropriate plugin */ static slurm_acct_storage_ops_t * _acct_storage_get_ops( slurm_acct_storage_context_t *c) { /* * Must be synchronized with slurm_acct_storage_ops_t above. */ static const char *syms[] = { "acct_storage_p_get_connection", "acct_storage_p_close_connection", "acct_storage_p_commit", "acct_storage_p_add_users", "acct_storage_p_add_coord", "acct_storage_p_add_accts", "acct_storage_p_add_clusters", "acct_storage_p_add_associations", "acct_storage_p_add_qos", "acct_storage_p_add_wckeys", "acct_storage_p_add_reservation", "acct_storage_p_modify_users", "acct_storage_p_modify_accts", "acct_storage_p_modify_clusters", "acct_storage_p_modify_associations", "acct_storage_p_modify_job", "acct_storage_p_modify_qos", "acct_storage_p_modify_wckeys", "acct_storage_p_modify_reservation", "acct_storage_p_remove_users", "acct_storage_p_remove_coord", "acct_storage_p_remove_accts", "acct_storage_p_remove_clusters", "acct_storage_p_remove_associations", "acct_storage_p_remove_qos", "acct_storage_p_remove_wckeys", "acct_storage_p_remove_reservation", "acct_storage_p_get_users", "acct_storage_p_get_accts", "acct_storage_p_get_clusters", "acct_storage_p_get_config", "acct_storage_p_get_associations", "acct_storage_p_get_events", "acct_storage_p_get_problems", "acct_storage_p_get_qos", "acct_storage_p_get_wckeys", "acct_storage_p_get_reservations", "acct_storage_p_get_txn", "acct_storage_p_get_usage", "acct_storage_p_roll_usage", "clusteracct_storage_p_node_down", "clusteracct_storage_p_node_up", "clusteracct_storage_p_cluster_cpus", "clusteracct_storage_p_register_ctld", "clusteracct_storage_p_fini_ctld", "jobacct_storage_p_job_start", "jobacct_storage_p_job_complete", "jobacct_storage_p_step_start", "jobacct_storage_p_step_complete", "jobacct_storage_p_suspend", "jobacct_storage_p_get_jobs_cond", "jobacct_storage_p_archive", "jobacct_storage_p_archive_load", "acct_storage_p_update_shares_used", "acct_storage_p_flush_jobs_on_cluster" }; int n_syms = sizeof( syms ) / sizeof( char * ); /* Find the correct plugin. */ c->cur_plugin = plugin_load_and_link(c->acct_storage_type, n_syms, syms, (void **) &c->ops); if ( c->cur_plugin != PLUGIN_INVALID_HANDLE ) return &c->ops; if(errno != EPLUGIN_NOTFOUND) { error("Couldn't load specified plugin name for %s: %s", c->acct_storage_type, plugin_strerror(errno)); return NULL; } error("Couldn't find the specified plugin name for %s " "looking at all files", c->acct_storage_type); /* Get plugin list. */ if ( c->plugin_list == NULL ) { char *plugin_dir; c->plugin_list = plugrack_create(); if ( c->plugin_list == NULL ) { error( "cannot create plugin manager" ); return NULL; } plugrack_set_major_type( c->plugin_list, "accounting_storage" ); plugrack_set_paranoia( c->plugin_list, PLUGRACK_PARANOIA_NONE, 0 ); plugin_dir = slurm_get_plugin_dir(); plugrack_read_dir( c->plugin_list, plugin_dir ); xfree(plugin_dir); } c->cur_plugin = plugrack_use_by_type( c->plugin_list, c->acct_storage_type ); if ( c->cur_plugin == PLUGIN_INVALID_HANDLE ) { error( "cannot find accounting_storage plugin for %s", c->acct_storage_type ); return NULL; } /* Dereference the API. */ if ( plugin_get_syms( c->cur_plugin, n_syms, syms, (void **) &c->ops ) < n_syms ) { error( "incomplete acct_storage plugin detected" ); return NULL; } return &c->ops; }