diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:40:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:40:13 +0000 |
commit | e9be59e1502a41bab9891d96d753102a7dafef0b (patch) | |
tree | c3b2da87c414881f4b53d0964f407c83492d813e /lib/plugins/InterfaceMgr | |
parent | Initial commit. (diff) | |
download | cluster-glue-upstream.tar.xz cluster-glue-upstream.zip |
Adding upstream version 1.0.12.upstream/1.0.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/plugins/InterfaceMgr')
-rw-r--r-- | lib/plugins/InterfaceMgr/HBauth.c | 171 | ||||
-rw-r--r-- | lib/plugins/InterfaceMgr/Makefile.am | 33 | ||||
-rw-r--r-- | lib/plugins/InterfaceMgr/generic.c | 452 |
3 files changed, 656 insertions, 0 deletions
diff --git a/lib/plugins/InterfaceMgr/HBauth.c b/lib/plugins/InterfaceMgr/HBauth.c new file mode 100644 index 0000000..eae22cf --- /dev/null +++ b/lib/plugins/InterfaceMgr/HBauth.c @@ -0,0 +1,171 @@ +/* + * Heartbeat authentication interface manager + * + * Copyright 2001 Alan Robertson <alanr@unix.sh> + * Licensed under the GNU Lesser General Public License + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + */ +#define PIL_PLUGINTYPE InterfaceMgr +#define PIL_PLUGIN HBauth + +#define PIN(f) #f +#define PIN2(f) PIN(f) +#define PIN3 PIN2(PIL_PLUGIN) +#define PIT PIN2(PIL_PLUGINTYPE) + +/* We are a interface manager... */ +#define ENABLE_PLUGIN_MANAGER_PRIVATE + +#include <lha_internal.h> +#include <pils/interface.h> +#include <stdio.h> + +PIL_PLUGIN_BOILERPLATE2("1.0", AuthDebugFlag) + + +/* + * Places to store information gotten during registration. + */ +static const PILPluginImports* AuthPIImports; /* Imported plugin fcns */ +static PILPlugin* AuthPlugin; /* Our plugin info */ +static PILInterfaceImports* AuthIfImports; /* Interface imported fcns */ +static PILInterface* AuthIf; /* Our Auth Interface info */ + +/* Our exported auth interface management functions */ +static PIL_rc RegisterAuthIF(PILInterface* ifenv, void** imports); + +static PIL_rc UnregisterAuthIF(PILInterface*iifinfo); + +/* + * Our Interface Manager interfaces - exported to the universe! + * + * (or at least to the interface management universe ;-). + * + * These are the interfaces which are used to manage our + * client authentication interfaces + * + */ +static PILInterfaceOps AuthIfOps = +{ RegisterAuthIF +, UnregisterAuthIF +}; + + +PIL_rc PIL_PLUGIN_INIT(PILPlugin*us, PILPluginImports* imports, void*); + +/* + * Our user_ptr is presumed to point at a GHashTable for us + * to put plugin into when they show up, and drop from when + * they disappear. + * + * We need to think more carefully about the way for us to get + * the user_ptr from the global environment. + * + * We need to think more carefully about how interface registration + * etc. interact with plugin loading, reference counts, etc. and how + * the application that uses us (i.e., heartbeat) interacts with us. + * + * Issues include: + * - freeing all memory, + * - making sure things are all cleaned up correctly + * - Thread-safety? + * + * I think the global system should handle thread-safety. + */ + +PIL_rc +PIL_PLUGIN_INIT(PILPlugin*us, PILPluginImports* imports, void *user_ptr) +{ + PIL_rc ret; + /* + * Force compiler to check our parameters... + */ + PILPluginInitFun fun = &PIL_PLUGIN_INIT; (void)fun; + + + if (user_ptr == NULL) { + imports->log(PIL_CRIT + , "Interface Manager %s requires non-NULL " + " user pointer (to GHashTable) at initialization" + , PIN3); + return PIL_INVAL; + } + + AuthPIImports = imports; + AuthPlugin = us; + + /* Register as a plugin */ + imports->register_plugin(us, &OurPIExports); + + + /* Register our interfaces */ + ret = imports->register_interface(us + , PIT + , PIN3 + , &AuthIfOps + , NULL + , &AuthIf /* Our interface object pointer */ + , (void**)&AuthIfImports /* Interface-imported functions */ + , user_ptr); + return ret; +} + +/* + * We get called for every authentication interface that gets registered. + * + * It's our job to make the authentication interface that's + * registering with us available to the system. + * + * We do that by adding it to a g_hash_table of authentication + * plugin. The rest of the system takes it from there... + * The key is the authentication method, and the data + * is a pointer to the functions the method exports. + * It's a piece of cake ;-) + */ +static PIL_rc +RegisterAuthIF(PILInterface* intf, void** imports) +{ + GHashTable* authtbl = intf->ifmanager->ud_interface; + + g_assert(authtbl != NULL); + + /* Reference count should now be one */ + g_assert(intf->refcnt == 1); + g_hash_table_insert(authtbl, intf->interfacename, intf->exports); + + return PIL_OK; +} + +/* Unregister a client authentication interface - + * We get called from the interface mgmt sys when someone requests that + * a interface be unregistered. + */ +static PIL_rc +UnregisterAuthIF(PILInterface*intf) +{ + GHashTable* authtbl = intf->ifmanager->ud_interface; + g_assert(authtbl != NULL); + + intf->refcnt--; + g_assert(intf->refcnt >= 0); + if (intf->refcnt <= 0) { + g_hash_table_remove(authtbl, intf->interfacetype); + } + return PIL_OK; +} + diff --git a/lib/plugins/InterfaceMgr/Makefile.am b/lib/plugins/InterfaceMgr/Makefile.am new file mode 100644 index 0000000..86b88d1 --- /dev/null +++ b/lib/plugins/InterfaceMgr/Makefile.am @@ -0,0 +1,33 @@ +# +# InterfaceMgr: Interface manager plugins for Linux-HA +# +# Copyright (C) 2001 Alan Robertson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ + -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ + -I$(top_builddir)/lib/upmls -I$(top_srcdir)/lib/upmls + +## libraries + +plugindir = $(libdir)/@HB_PKG@/plugins/InterfaceMgr +plugin_LTLIBRARIES = generic.la + +generic_la_SOURCES = generic.c +generic_la_LDFLAGS = -export-dynamic -module -avoid-version diff --git a/lib/plugins/InterfaceMgr/generic.c b/lib/plugins/InterfaceMgr/generic.c new file mode 100644 index 0000000..6ddad3b --- /dev/null +++ b/lib/plugins/InterfaceMgr/generic.c @@ -0,0 +1,452 @@ +/* + * + * Generic interface (implementation) manager + * + * Copyright 2001 Alan Robertson <alanr@unix.sh> + * Licensed under the GNU Lesser General Public License + * + * This manager will manage any number of types of interfaces. + * + * This means that when any implementations of our client interfaces register + * or unregister, it is us that makes their interfaces show up in the outside + * world. + * + * And, of course, we have to do this in a very generic way, since we have + * no idea about the client programs or interface types, or anything else. + * + * We do that by getting a parameter passed to us which tell us the names + * of the interface types we want to manage, and the address of a GHashTable + * for each type that we put the implementation in when they register + * themselves. + * + * So, each type of interface that we manage gets its own private + * GHashTable of the implementations of that type that are currently + * registered. + * + * For example, if we manage communication modules, their exported + * interfaces will be registered in a hash table. If we manage + * authentication modules, they'll have their (separate) hash table that + * their exported interfaces are registered in. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define PIL_PLUGINTYPE InterfaceMgr +#define PIL_PLUGINTYPE_S "InterfaceMgr" +#define PIL_PLUGIN generic +#define PIL_PLUGIN_S "generic" +#define PIL_PLUGINLICENSE LICENSE_LGPL +#define PIL_PLUGINLICENSEURL URL_LGPL + +/* We are an interface manager... */ +#define ENABLE_PLUGIN_MANAGER_PRIVATE +#define ENABLE_PIL_DEFS_PRIVATE + +#include <lha_internal.h> +#include <pils/generic.h> + +#include <stdio.h> + +PIL_PLUGIN_BOILERPLATE("1.0", GenDebugFlag, CloseGeneralPluginManager) + +/* + * Key is interface type, value is a PILGenericIfMgmtRqst. + * The key is g_strdup()ed, but the struct is not copied. + */ + +static gboolean FreeAKey(gpointer key, gpointer value, gpointer data); + +/* + * Places to store information gotten during registration. + */ +static const PILPluginImports* GenPIImports; /* Imported plugin fcns */ +static PILPlugin* GenPlugin; /* Our plugin info */ +static PILInterfaceImports* GenIfImports; /* Interface imported fcns */ + +/* Our exported generic interface management functions */ +static PIL_rc RegisterGenIF(PILInterface* ifenv, void** imports); + +static PIL_rc UnregisterGenIF(PILInterface*iifinfo); + +static PIL_rc CloseGenInterfaceManager(PILInterface*, void* info); + +/* + * Our Interface Manager interfaces - exported to the universe! + * + * (or at least to the interface management universe ;-). + * + * These are the interfaces which are used to manage our + * client implementations + */ +static PILInterfaceOps GenIfOps = +{ RegisterGenIF +, UnregisterGenIF +}; + + +PIL_rc PIL_PLUGIN_INIT(PILPlugin*us, PILPluginImports* imports, void*); + +/* + * Our user_ptr is presumed to point to NULL-terminated array of + * PILGenericIfMgmtRqst structs. + * + * These requests have pointers to GHashTables for us + * to put plugins into when they show up, and drop from when + * they disappear. + * + * Issues include: + * - freeing all memory, + * - making sure things are all cleaned up correctly + * - Thread-safety? + * + * IMHO the global system should handle thread-safety. + */ +static PIL_rc AddAnInterfaceType(PILPlugin*us, GHashTable* MasterTable, PILGenericIfMgmtRqst* req); + +PIL_rc +PIL_PLUGIN_INIT(PILPlugin*us, PILPluginImports* imports, void *user_ptr) +{ + PIL_rc ret; + PILGenericIfMgmtRqst* user_req; + PILGenericIfMgmtRqst* curreq; + GHashTable* MasterTable = NULL; + /* + * Force the compiler to check our parameters... + */ + PILPluginInitFun fun = &PIL_PLUGIN_INIT; (void)fun; + + + GenPIImports = imports; + + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "IF manager %s: initializing.", PIL_PLUGIN_S); + } + + if (user_ptr == NULL) { + PILCallLog(GenPIImports->log, PIL_CRIT + , "%s Interface Manager requires non-NULL " + " PILGenericIfMgmtRqst user pointer at initialization." + , PIL_PLUGIN_S); + return PIL_INVAL; + } + + GenPlugin = us; + + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "IF manager %s: registering as a plugin." + , PIL_PLUGIN_S); + } + + user_req = user_ptr; + MasterTable = g_hash_table_new(g_str_hash, g_str_equal); + us->ud_plugin = MasterTable; /* Override passed value */ + + /* Register ourselves as a plugin */ + + if ((ret = imports->register_plugin(us, &OurPIExports)) != PIL_OK) { + PILCallLog(imports->log, PIL_CRIT + , "IF manager %s unable to register as plugin (%s)" + , PIL_PLUGIN_S, PIL_strerror(ret)); + + return ret; + } + + /* + * Register to manage implementations + * for all the interface types we've been asked to manage. + */ + + for(curreq = user_req; curreq->iftype != NULL; ++curreq) { + PIL_rc newret; + + newret = AddAnInterfaceType(us, MasterTable, curreq); + + if (newret != PIL_OK) { + ret = newret; + } + } + + /* + * Our plugin and all our registered plugin types + * have ud_plugin pointing at MasterTable. + */ + + return ret; +} + +static PIL_rc +AddAnInterfaceType(PILPlugin*us, GHashTable* MasterTable, PILGenericIfMgmtRqst* req) +{ + PIL_rc rc; + PILInterface* GenIf; /* Our Generic Interface info*/ + + g_assert(MasterTable != NULL); + g_hash_table_insert(MasterTable, g_strdup(req->iftype), req); + + if (req->ifmap == NULL) { + PILCallLog(GenPIImports->log, PIL_CRIT + , "IF manager %s: iftype %s has NULL" + " ifmap pointer address." + , PIL_PLUGIN_S, req->iftype); + return PIL_INVAL; + } + if ((*req->ifmap) != NULL) { + PILCallLog(GenPIImports->log, PIL_CRIT + , "IF manager %s: iftype %s GHashTable pointer" + " was not initialized to NULL" + , PIL_PLUGIN_S, req->iftype); + return PIL_INVAL; + } + + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "IF manager %s: registering ourselves" + " to manage interface type %s" + , PIL_PLUGIN_S, req->iftype); + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: ifmap: 0x%lx callback: 0x%lx" + " imports: 0x%lx" + , PIL_PLUGIN_S + , (unsigned long)req->ifmap + , (unsigned long)req->callback + , (unsigned long)req->importfuns); + } + + /* Create the hash table to communicate with this client */ + *(req->ifmap) = g_hash_table_new(g_str_hash, g_str_equal); + + rc = GenPIImports->register_interface(us + , PIL_PLUGINTYPE_S + , req->iftype /* the iftype we're managing here */ + , &GenIfOps + , CloseGenInterfaceManager + , &GenIf + , (void*)&GenIfImports + , MasterTable); /* Point ud_interface to MasterTable */ + + /* We don't ever want to be unloaded... */ + GenIfImports->ModRefCount(GenIf, +100); + + if (rc != PIL_OK) { + PILCallLog(GenPIImports->log, PIL_CRIT + , "Generic interface manager %s: unable to register" + " to manage interface type %s: %s" + , PIL_PLUGIN_S, req->iftype + , PIL_strerror(rc)); + } + return rc; +} + +static void +CloseGeneralPluginManager(PILPlugin* us) +{ + + GHashTable* MasterTable = us->ud_plugin; + int count; + + g_assert(MasterTable != NULL); + + /* + * All our clients have already been shut down automatically + * This is the final shutdown for us... + */ + + + /* There *shouldn't* be any keys in there ;-) */ + + if ((count=g_hash_table_size(MasterTable)) > 0) { + + /* But just in case there are... */ + g_hash_table_foreach_remove(MasterTable, FreeAKey, NULL); + } + g_hash_table_destroy(MasterTable); + us->ud_plugin = NULL; + return; +} + +/* + * We get called for every time an implementation registers itself as + * implementing one of the kinds of interfaces we manage. + * + * It's our job to make the implementation that's + * registering with us available to the system. + * + * We do that by adding it to a GHashTable for its interface type + * Our users in the rest of the system takes it from there... + * + * The key to the GHashTable is the implementation name, and the data is + * a pointer to the information the implementation exports. + * + * It's a piece of cake ;-) + */ +static PIL_rc +RegisterGenIF(PILInterface* intf, void** imports) +{ + PILGenericIfMgmtRqst* ifinfo; + GHashTable* MasterTable = intf->ifmanager->ud_interface; + + g_assert(MasterTable != NULL); + + /* Reference count should now be one */ + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: interface %s/%s registering." + , PIL_PLUGIN_S, intf->interfacetype->typename + , intf->interfacename); + } + g_assert(intf->refcnt == 1); + /* + * We need to add it to the table that goes with this particular + * type of interface. + */ + if ((ifinfo = g_hash_table_lookup(MasterTable + , intf->interfacetype->typename)) != NULL) { + GHashTable* ifmap = *(ifinfo->ifmap); + + g_hash_table_insert(ifmap, intf->interfacename,intf->exports); + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: Inserted interface [%s] in hash" + " table @ 0x%08lx" + , PIL_PLUGIN_S, intf->interfacename + , (unsigned long)ifmap); + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: Exports are here: 0x%08x" + , PIL_PLUGIN_S + , GPOINTER_TO_UINT(intf->exports)); + } + + if (ifinfo->callback != NULL) { + PILInterfaceType* t = intf->interfacetype; + + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: callback 0x%lx" + , PIL_PLUGIN_S + , (unsigned long)ifinfo->callback); + } + ifinfo->callback(PIL_REGISTER + , t->universe->piuniv, intf->interfacename + , t->typename, ifinfo->userptr); + } + + *imports = ifinfo->importfuns; + + return PIL_OK; + + }else{ + PILCallLog(GenPIImports->log, PIL_WARN + , "RegisterGenIF: interface type %s not found" + , intf->interfacename); + } + return PIL_INVAL; +} + +/* Unregister an implementation - + * We get called from the interface management system when someone + * has requested that an implementation of a client interface be + * unregistered. + */ +static PIL_rc +UnregisterGenIF(PILInterface*intf) +{ + GHashTable* MasterTable = intf->ifmanager->ud_interface; + PILGenericIfMgmtRqst* ifinfo; + + g_assert(MasterTable != NULL); + g_assert(intf->refcnt >= 0); + /* + * Go through the "master table" and find client table, + * notify client we're about to remove this entry, then + * then remove this entry from it. + */ + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: unregistering interface %s/%s." + , PIL_PLUGIN_S, intf->interfacetype->typename + , intf->interfacename); + } + if ((ifinfo = g_hash_table_lookup(MasterTable + , intf->interfacetype->typename)) != NULL) { + + GHashTable* ifmap = *(ifinfo->ifmap); + + if (ifinfo->callback != NULL) { + PILInterfaceType* t = intf->interfacetype; + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_DEBUG + , "%s IF manager: callback 0x%lx" + , PIL_PLUGIN_S + , (unsigned long)ifinfo->callback); + } + ifinfo->callback(PIL_UNREGISTER + , t->universe->piuniv, intf->interfacename + , t->typename, ifinfo->userptr); + } + + /* Remove the client entry from master table */ + g_hash_table_remove(ifmap, intf->interfacename); + + }else{ + PILCallLog(GenPIImports->log, PIL_WARN + , "UnregisterGenIF: interface type %s not found" + , intf->interfacename); + return PIL_INVAL; + } + return PIL_OK; +} + +/* + * Close down the generic interface manager. + */ +static PIL_rc +CloseGenInterfaceManager(PILInterface*intf, void* info) +{ + void* key; + void* data; + GHashTable* MasterTable = intf->ud_interface; + + if (GenDebugFlag) { + PILCallLog(GenPIImports->log, PIL_INFO + , "In CloseGenInterFaceManager on %s/%s (MasterTable: 0x%08lx)" + , intf->interfacetype->typename, intf->interfacename + , (unsigned long)MasterTable); + } + + + g_assert(MasterTable != NULL); + if (g_hash_table_lookup_extended(MasterTable + , intf->interfacename, &key, &data)) { + PILGenericIfMgmtRqst* ifinfo = data; + g_hash_table_destroy(*(ifinfo->ifmap)); + *(ifinfo->ifmap) = NULL; + g_hash_table_remove(MasterTable, key); + g_free(key); + }else{ + g_assert_not_reached(); + } + return PIL_OK; +} + +static gboolean +FreeAKey(gpointer key, gpointer value, gpointer data) +{ + g_free(key); + return TRUE; +} |