/** * res_mem_init_node() - call region specific reserved memory init code */ static int __init __reserved_mem_init_node(struct reserved_mem *rmem) { extern const struct of_device_id __reservedmem_of_table[]; const struct of_device_id *i; for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) { reservedmem_of_init_fn initfn = i->data; const char *compat = i->compatible; if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) continue; if (initfn(rmem) == 0) { pr_info("Reserved memory: initialized node %s, compatible id %s\n", rmem->name, compat); return 0; } } return -ENOENT; }
/* * Load a dynamic plugin object and call it's init-function * Note 'file' may be destructively modified */ static plghndl_t plugin_load (clicon_handle h, char *file, int dlflags, const char *cnklbl) { char *error; void *handle = NULL; plginit_t *initfn; dlerror(); /* Clear any existing error */ if ((handle = dlopen (file, dlflags)) == NULL) { error = (char*)dlerror(); clicon_err(OE_PLUGIN, errno, "dlopen: %s\n", error ? error : "Unknown error"); goto quit; } /* call plugin_init() if defined */ if ((initfn = dlsym(handle, "plugin_init")) != NULL) { if (initfn(h) != 0) { clicon_err(OE_PLUGIN, errno, "Failed to initiate %s\n", strrchr(file,'/')?strchr(file, '/'):file); goto quit; } } quit: return handle; }
/*! Load a dynamic plugin object and call its init-function * @param[in] h Clicon handle * @param[in] file Which plugin to load * @param[in] function Which function symbol to load and call * @param[in] dlflags See man(3) dlopen * @param[out] cpp Clixon plugin structure (if retval is 1) * @retval 1 OK * @retval 0 Failed load, log, skip and continue with other plugins * @retval -1 Error * @see clixon_plugins_load Load all plugins */ static int plugin_load_one(clicon_handle h, char *file, char *function, int dlflags, clixon_plugin **cpp) { int retval = -1; char *error; void *handle = NULL; plginit2_t *initfn; clixon_plugin_api *api = NULL; clixon_plugin *cp = NULL; char *name; char *p; clicon_debug(1, "%s file:%s function:%s", __FUNCTION__, file, function); dlerror(); /* Clear any existing error */ if ((handle = dlopen(file, dlflags)) == NULL) { error = (char*)dlerror(); clicon_err(OE_PLUGIN, errno, "dlopen: %s", error ? error : "Unknown error"); goto done; } /* call plugin_init() if defined, eg CLIXON_PLUGIN_INIT or CLIXON_BACKEND_INIT */ if ((initfn = dlsym(handle, function)) == NULL){ clicon_err(OE_PLUGIN, errno, "Failed to find %s when loading clixon plugin %s", CLIXON_PLUGIN_INIT, file); goto done; } if ((error = (char*)dlerror()) != NULL) { clicon_err(OE_UNIX, 0, "dlsym: %s: %s", file, error); goto done; } clicon_err_reset(); if ((api = initfn(h)) == NULL) { if (!clicon_errno){ /* if clicon_err() is not called then log and continue */ clicon_log(LOG_DEBUG, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file); retval = 0; goto done; } else{ clicon_err(OE_PLUGIN, errno, "Failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file); goto done; } } /* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */ if ((cp = (clixon_plugin *)malloc(sizeof(struct clixon_plugin))) == NULL){ clicon_err(OE_UNIX, errno, "malloc"); goto done; } memset(cp, 0, sizeof(struct clixon_plugin)); cp->cp_handle = handle; /* Extract string after last '/' in filename, if any */ name = strrchr(file, '/') ? strrchr(file, '/')+1 : file; /* strip extension, eg .so from name */ if ((p=strrchr(name, '.')) != NULL) *p = '\0'; /* Copy name to struct */ memcpy(cp->cp_name, name, strlen(name)+1); snprintf(cp->cp_name, sizeof(cp->cp_name), "%*s", (int)strlen(name), name); cp->cp_api = *api; clicon_debug(1, "%s", __FUNCTION__); if (cp){ *cpp = cp; cp = NULL; } retval = 1; done: if (retval != 1 && handle) dlclose(handle); if (cp) free(cp); return retval; }