1
1

Updates the documentation on a few things. Adds the preliminary registry documentation. The functionality in registry.c should be ignored for now as it is just in test mode - I will be converting it to something more solid shortly. Main desire was to get the prototype functions out there along with their documentation.

This commit was SVN r1181.
Этот коммит содержится в:
Ralph Castain 2004-06-01 18:40:16 +00:00
родитель a82fc3ff5a
Коммит 4cf0df541e
7 изменённых файлов: 531 добавлений и 46 удалений

Просмотреть файл

@ -21,7 +21,9 @@ libs = $(top_builddir)/src/libmpi.la
bin_PROGRAMS = openmpi
openmpi_SOURCES = \
openmpi.h \
ompi_init.h \
os_session_dir.c \
ompi_init.c \
openmpi.c
openmpi_LDADD = \

Просмотреть файл

@ -9,15 +9,17 @@ openmpi.c - main program for spawning persistent universe.
*/
#include "lam_config.h"
#include <stdio.h>
#include <string.h>
#include <pwd.h>
#include "lam_config.h"
#include "util/sys_info.h"
#include "util/cmd_line.h"
#include "rte/universe/os_session_dir.h"
#include "rte/universe/ompi_init.h"
#include "rte/universe/openmpi.h"
/**
@ -29,12 +31,18 @@ openmpi.c - main program for spawning persistent universe.
* will be reported to user but will not terminate processing.
*/
ompi_universe_t universe = {.name = NULL,
.pid = -1,
.session_file = NULL,
.persistence = false,
.web_server = false,
.console_connected = false
ompi_universe_t universe = {
/* .name = */ NULL,
/* .host = */ NULL,
/* .user_name = */ NULL,
/* .user_id = */ -1,
/* .pid = */ -1,
/* .session_file = */ NULL,
/* .persistence = */ false,
/* .silent_mode = */ false,
/* .script_mode = */ false,
/* .web_server = */ false,
/* .console_connected = */ false
};
@ -42,6 +50,11 @@ int main(int argc, char *argv[])
{
lam_cmd_line_t *cmd_line = NULL;
char *tmpdir_option = NULL;
char *universe_option = NULL;
char *tmp, *universe_name, *remote_host, *remote_uid;
struct passwd *pwdent;
tmp = universe_name = remote_host = remote_uid = NULL;
cmd_line = lam_cmd_line_create();
if (NULL == cmd_line) {
@ -57,6 +70,10 @@ int main(int argc, char *argv[])
"Temp directory to be used by universe");
lam_cmd_line_make_opt(cmd_line, 'w', "webserver", 1,
"Web server available");
lam_cmd_line_make_opt(cmd_line, 's', "silent", 1,
"No console prompt - operate silently");
lam_cmd_line_make_opt(cmd_line, 'f', "script", 1,
"Read commands from script file");
if ((LAM_SUCCESS != lam_cmd_line_parse(cmd_line, false, argc, argv)) ||
lam_cmd_line_is_taken(cmd_line, "help") ||
@ -72,9 +89,23 @@ int main(int argc, char *argv[])
fprintf(stderr, "error retrieving universe name - please report error to bugs@open-mpi.org\n");
exit(1);
}
universe.name = strdup(lam_cmd_line_get_param(cmd_line, "universe", 0, 0));
universe_option = strdup(lam_cmd_line_get_param(cmd_line, "universe", 0, 0));
if (NULL != (tmp = strchr(universe_option, ':'))) { /* name contains remote host */
/* get the host name, and the universe name separated */
/* could be in form remote-uid@remote-host:universe */
*tmp = '\0';
tmp++;
universe_name = strdup(tmp);
if (NULL != (tmp = strchr(universe_option, '@'))) { /* remote name includes remote uid */
*tmp = '\0';
tmp++;
remote_host = strdup(tmp);
remote_uid = strdup(universe_option);
}
}
} else {
universe.name = strdup("ompi-default-universe");
universe_name = strdup("default");
}
/* get the pid and store it for later use */
@ -87,25 +118,39 @@ int main(int argc, char *argv[])
exit(1);
}
tmpdir_option = strdup(lam_cmd_line_get_param(cmd_line, "tmpdir", 0, 0));
} else {
tmpdir_option = NULL;
}
/* get the system information */
ompi_system_info.init = false;
ompi_sys_info();
if (!ompi_system_info.init) {
fprintf(stderr, "Couldn't get system information\n");
/* Store all the information in the Universe structure for later use */
universe.name = strdup(universe_name);
if (NULL != remote_host) {
universe.host = strdup(remote_host);
} else {
universe.host = (char *)malloc(OMPI_RIDICULOUS_NAMELEN);
if (NULL == universe.host) {
fprintf(stderr, "openmpi(error): unable to get memory allocation - please report error to bugs@open-mpi.org\n");
exit(1);
}
gethostname(universe.host, OMPI_RIDICULOUS_NAMELEN);
}
if (NULL != remote_uid) {
universe.user_name = strdup(remote_uid);
} else { /* get the name of the user */
if ((pwdent = getpwuid(getuid())) != 0) {
universe.user_name = strdup(pwdent->pw_name);
} else {
universe.user_name = strdup("unknown");
}
}
/* initialize the Open MPI system */
if (LAM_ERROR == ompi_init(universe_name, tmpdir_option)) {
fprintf(stderr, "Unable to initialize system - please report error to bugs@open-mpi.org\n");
exit(1);
}
/* create the session directory */
if (LAM_ERROR == ompi_session_dir_init(tmpdir_option, "test-universe")) {
fprintf(stderr, "error creating session directory - please report error to bugs@open-mpi.org");
exit(1);
}
/* store this session information */
/* first, check to see if we are rejoining an existing session */
/* yes, so read info from file */
/* no existing session, so create the file */
return(0);
}

Просмотреть файл

@ -10,9 +10,14 @@
struct ompi_universe_t {
char *name;
char *host;
char *user_name;
uid_t user_id;
pid_t pid;
char *session_file;
bool persistence;
bool silent_mode;
bool script_mode;
bool web_server;
bool console_connected;
};

Просмотреть файл

@ -34,12 +34,11 @@
#include "util/os_path.h"
#include "util/os_create_dirpath.h"
static char *ompi_get_prefix(char *prefix);
static int ompi_check_dir(char *directory);
static int ompi_check_dir(bool create, char *directory);
#define OMPI_DEFAULT_TMPDIR "tmp"
static int ompi_check_dir(char *directory)
static int ompi_check_dir(bool create, char *directory)
{
struct stat buf;
mode_t my_mode = S_IRWXU; /* at the least, I need to be able to do anything */
@ -50,10 +49,13 @@ static int ompi_check_dir(char *directory)
return(LAM_SUCCESS);
}
}
if (create) {
return(ompi_os_create_dirpath(directory, mode_all)); /* try to create it, but ensure open to all */
}
return(LAM_ERROR); /* couldn't find it, or don't have access rights, and not asked to create it */
}
static char *ompi_get_prefix(char *prefix)
char *ompi_find_session_dir(bool create, char *prefix)
{
char *tmpprefix=NULL, *tmp=NULL;
char *sessions=NULL;
@ -62,7 +64,7 @@ static char *ompi_get_prefix(char *prefix)
if (NULL != prefix) {
tmpprefix = strdup(ompi_os_path(false, prefix, sessions, NULL)); /* make sure it's an absolute pathname */
if (LAM_SUCCESS == ompi_check_dir(tmpprefix)) { /* check for existence and access, or create it */
if (LAM_SUCCESS == ompi_check_dir(create, tmpprefix)) { /* check for existence and access, or create it */
free(sessions);
return(tmpprefix);
}
@ -74,7 +76,7 @@ static char *ompi_get_prefix(char *prefix)
if (NULL != getenv("LAM_PREFIX_ENV")) {
tmp = strdup(getenv("LAM_PREFIX_ENV"));
tmpprefix = strdup(ompi_os_path(false, tmp, sessions, NULL));
if (LAM_SUCCESS == ompi_check_dir(tmpprefix)) { /* check for existence and access, or create it */
if (LAM_SUCCESS == ompi_check_dir(create, tmpprefix)) { /* check for existence and access, or create it */
free(tmp);
free(sessions);
return(tmpprefix);
@ -90,7 +92,7 @@ static char *ompi_get_prefix(char *prefix)
if (NULL != getenv("TMPDIR")) {
tmp = strdup(getenv("TMPDIR"));
tmpprefix = strdup(ompi_os_path(false, tmp, sessions, NULL));
if (LAM_SUCCESS == ompi_check_dir(tmpprefix)) { /* check for existence and access, or create it */
if (LAM_SUCCESS == ompi_check_dir(create, tmpprefix)) { /* check for existence and access, or create it */
free(tmp);
free(sessions);
return(tmpprefix);
@ -106,7 +108,7 @@ static char *ompi_get_prefix(char *prefix)
if (NULL != getenv("TMP")) {
tmp = strdup(getenv("TMP"));
tmpprefix = strdup(ompi_os_path(false, tmp, sessions, NULL));
if (LAM_SUCCESS == ompi_check_dir(tmpprefix)) { /* check for existence and access, or create it */
if (LAM_SUCCESS == ompi_check_dir(create, tmpprefix)) { /* check for existence and access, or create it */
free(tmp);
free(sessions);
return(tmpprefix);
@ -122,7 +124,7 @@ static char *ompi_get_prefix(char *prefix)
if (NULL != getenv("HOME")) {
tmp = strdup(getenv("HOME"));
tmpprefix = strdup(ompi_os_path(false, tmp, sessions, NULL));
if (LAM_SUCCESS == ompi_check_dir(tmpprefix)) { /* check for existence and access, or create it */
if (LAM_SUCCESS == ompi_check_dir(create, tmpprefix)) { /* check for existence and access, or create it */
free(tmp);
free(sessions);
return(tmpprefix);
@ -137,7 +139,7 @@ static char *ompi_get_prefix(char *prefix)
tmp = strdup(OMPI_DEFAULT_TMPDIR);
tmpprefix = strdup(ompi_os_path(false, tmp, sessions, NULL));
if (LAM_SUCCESS == ompi_check_dir(tmpprefix)) { /* check for existence and access, or create it */
if (LAM_SUCCESS == ompi_check_dir(create, tmpprefix)) { /* check for existence and access, or create it */
free(tmp);
free(sessions);
return(tmpprefix);
@ -159,14 +161,8 @@ static char *ompi_get_prefix(char *prefix)
/*
* ompi_session_dir_init
*
* Function: - set up tmpdir for Open MPI to store stuff
* - creates directory, with "good" perms
* Accepts: - prefix to use, if provided by user
* Returns: - LAM_SUCCESS or LAM_ERROR
* Notes: - directory in form of:
* <prefix>/openmpi-sessions/uid
*/
*/
int ompi_session_dir_init(char *prefix, char *universe)
{
@ -180,7 +176,7 @@ int ompi_session_dir_init(char *prefix, char *universe)
}
/* locate the ompi-sessions directory - create it if it doesn't exist */
if (NULL == (tmpprefix = ompi_get_prefix(prefix))) { /* couldn't find nor create the sessions directory */
if (NULL == (tmpprefix = ompi_find_session_dir(true, prefix))) { /* couldn't find nor create the sessions directory */
return (LAM_ERROR);
}

Просмотреть файл

@ -3,7 +3,7 @@
*/
/** @file:
*
* Creates Open MPI session directory.
* Find and/or create Open MPI session directory.
*
* The ompi_session_dir_init() function creates a temporary directory that is
* used by the Open MPI system for storing system-critical information. For a given
@ -83,3 +83,25 @@
*/
int ompi_session_dir_init(char *prefix, char *universe);
/** The ompi_find_session_dir() function searches either a user-specified location, or a
* set of standard locations that might contain the "openmpi-sessions" directory. Once
* found, the function returns the pathname of that directory. The function calls the
* ompi_check_dir() function.
*/
/** @param create A boolean variable that indicates whether or not to create the "openmpi-sessions"
* directory. If set to "false", the function only checks to see if an existing directory
* can be found. This is typically used to locate an already existing universe for reconnection
* purposes. If set to "true", then the function creates the "openmpi-sessions" directory, if possible.
* @param prefix A string variable indicating where the user stipulated the "openmpi-sessions" directory
* should be placed. A value of "NULL" indicates that the user specified no location - hence, the
* function explores a range of "standard" locations.
*
* @retval *path A pointer to a string containing the pathname of the "openmpi-sessions" directory.
* A "NULL" value is returned if the directory cannot be found (if create is "false") or created (if
* create is "true").
*/
char *ompi_find_session_dir(bool create, char *prefix);

52
src/rte/universe/registry.c Обычный файл
Просмотреть файл

@ -0,0 +1,52 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "rte/universe/registry.h"
ompi_registry_core *registry;
ompi_keytable *keytable;
int main(int argc, char *argv)
{
ompi_keytable *nextkey;
ompi_registry_core *nextreg;
keytable = (ompi_keytable *)malloc(sizeof(ompi_keytable));
keytable->token = strdup("universe");
keytable->key = 1;
keytable->next = NULL;
nextkey = (ompi_keytable *)malloc(sizeof(ompi_keytable));
nextkey->token = strdup("commworld-1");
nextkey->key = 1;
keytable->next = nextkey;
nextkey->next = NULL;
registry = (ompi_registry_core *)malloc(sizeof(ompi_registry_core));
registry->primary_key = ompi_getkey("universe");
registry->keys = (ompi_keylist *)malloc(sizeof(ompi_keylist));
registry->keys->key = ompi_getkey("commworld-1");
registry->keys->next = NULL;
registry->object_size = 100;
registry->object = (uint8_t *)malloc(100);
registry->subscriber = (ompi_subscribe_list *)malloc(sizeof(ompi_subscribe_list));
registry->subscriber->id = 1;
registry->subscriber->action = OMPI_REGISTRY_NOTIFY_MODIFICATION | OMPI_REGISTRY_NOTIFY_DELETE;
printf("universe key = %d\n", registry->primary_key);
}
int ompi_getkey(char *token)
{
ompi_keytable *ptr;
ptr = keytable;
while ((ptr != NULL) && (0 != strcmp(token, ptr->token))) {
ptr = ptr->next;
}
if (NULL == ptr) {
return(-1);
}
return(ptr->key);
}

363
src/rte/universe/registry.h Обычный файл
Просмотреть файл

@ -0,0 +1,363 @@
/*
* $HEADER$
*/
/** @file:
*
* The Open MPI general purpose registry.
*
* The Open MPI system contains a general purpose registry for use by both
* applications and internal systems to dynamically share information. For
* speed purposes, the registry is divided into "segments", each labelled
* with an appropriate "token" string that describes its contents. Segments
* are automatically provided for the "universe" and for each MPI CommWorld.
* At this time, all segments may be accessed by any application within the universe, thus
* providing a mechanism for cross-CommWorld communications (with the requirement
* that all participating CommWorlds must reside within the same universe). In the future,
* some form of security may be provided to limit access privileges between
* segments.
*
* Within each registry segment, there exists a list of objects that have
* been "put" onto the registry. Each object must be tagged with at least
* one token, but may be tagged with as many tokens as the creator desires.
* Retrieval requests must specify the segment and at least one token, but
* can specify an arbitrary number of tokens to describe the search. The registry
* will return a list of all objects that meet the search criteria.
*
* Tokens are defined as character strings, thus allowing for clarity in
* the program. However, for speed purposes, tokens are translated into
* integer keys prior to storing an object. A table of token-key pairs
* is independetly maintained for each registry segment. Users can obtain
* an index of token-key values by requesting it through the ompi_registry_index()
* function, and can define/delete token-key values using the ompi_registry_definekey()
* and ompi_registry_deletekey() functions, respectively.
*
* The registry also provides a subscription capability whereby a caller
* can subscribe to a stored object and receive notification when various actions
* are performed on that object. Currently supported actions include modification,
* the addition of another subscriber, and deletion. Notifications are sent via
* the OOB communication channel.
*
*
*/
/** Define the notification actions for the subscription system
*/
/** Notifies subscriber when object is modified */
#define OMPI_REGISTRY_NOTIFY_MODIFICATION 0x01
/** Notifies subscriber when another subscriber is added */
#define OMPI_REGISTRY_NOTIFY_ADD_SUBSCRIBER 0x02
/** Notifies subscriber when object is removed from registry */
#define OMPI_REGISTRY_NOTIFY_DELETE 0x04
/** Notifies subscriber upon any action - effectively an OR of all other flags */
#define OMPI_REGISTRY_NOTIFY_ALL 0xff
/** Dictionary of token-key pairs.
* This structure is used to create a linked list of token-key pairs. All calls to
* registry functions pass char string tokens for programming clarity - the ompi_keytable
* structure is used to translate those strings into an integer key value, thus allowing
* for faster searches of the registry.
*/
struct ompi_keytable_t {
char *token; /**< Char string that defines the key */
int key; /**< Numerical value assigned by registry to represent token string */
struct ompi_keytable_t *next;
};
typedef struct ompi_keytable_t ompi_keytable_t;
/** List of keys that describe a stored object.
* Each object stored in the registry may have as many keys describing it as the
* creator desires. This structure is used to create a linked list of keys
* associated with each object.
*/
struct ompi_keylist_t {
int key; /**< Numerical key that defines stored object */
struct ompi_keylist_t *next;
};
typedef struct ompi_keylist_t ompi_keylist_t;
/** List of subscribers to a stored object.
* Each object can have an arbitrary number of subscribers desiring notification
* upon specified actions being performed against the object. This structure is
* used to create a linked list of subscribers for objects.
*/
struct ompi_subscribe_list_t {
int id; /**< ID of the subscriber */
uint8_t action; /**< Bit-mask of actions that trigger notification */
struct ompi_subscribe_list_t *next;
};
typedef struct ompi_subscribe_list_t ompi_subscribe_list_t;
/** The core registry structure.
* Each segment of the registry contains a linked list of registry entries. This structure
* represents a link in that list. The structure contains a linked list of the keys that
* define this particular object, the size of the object, a pointer to the object, and a linked
* list of subscribers to this object. Objects are stored as unsigned bytes - knowledge of any
* structure within the objects is the responsibility of the calling functions. The repository
* has no knowledge of what is in the structure, nor any way of determining such structure.
*
* At this time, no security is provided on an object-level basis. Thus, all requests for an
* object are automatically granted. This may be changed at some future time by adding an
* "authorization" linked list of ID's and their access rights to this structure.
*/
struct ompi_registry_core_t {
ompi_keylist_t *keys; /**< Linked list of keys that define stored object */
int object_size; /**< Size of stored object, in bytes */
uint8_t *object; /**< Pointer to stored object */
ompi_subscribe_list_t *subscriber; /**< Linked list of subscribers to this object */
struct ompi_registry_core_t *next;
};
typedef struct ompi_registry_core_t ompi_registry_core_t;
/** Registry segment definition.
* The registry is subdivided into segments, each defining a unique domain. The "universe" segment
* is automatically created to allow the exchange of information supporting universe-level functions.
* Similarly, a segment is automatically created for each MPI CommWorld within the universe - the
* name for that segment is stored in each CommWorld's ompi_system_info structure so program
* elements within that CommWorld can access it. The segment structure serves as the "head" of a linked
* list of registry elements for that segment. Each segment also holds its own token-key dictionary
* to avoid naming conflicts between tokens from CommWorlds sharing a given universe.
*/
struct ompi_registry_segment_t {
int segment; /**< ID of registry segment */
ompi_registry_core_t *reg_list; /**< Linked list of stored objects within this segment */
ompi_keytable_t *keytable; /**< Token-key dictionary for this segment */
struct ompi_registry_segment_t *next;
};
typedef struct ompi_registry_segment_t ompi_registry_segment_t;
/** Return value structure for registry requests.
* A request for information stored within the registry returns a linked list of values that
* correspond to the provided tokens. The linked list is terminated by a "next" value of NULL.
* Each link in the list contains a pointer to a copy of the registry object, and the size
* of that object in bytes. Note that the pointer is to a \em copy of the object, and not
* to the registry object itself. This prevents inadvertent modification of the registry, but
* may require the recipient to release the structure's memory when done.
*/
struct ompi_registry_value_t {
uint8_t *object; /**< Pointer to object being returned */
int object_size; /**< Size of returned object, in bytes */
struct ompi_registry_value_t *next;
};
typedef struct ompi_registry_value_t ompi_registry_value_t;
/** Retrieve a registry key value for a given token string.
* The ompi_registry_getkey() function is used to translate a token string for a particular
* segment of the registry into its associated (integer) key value.
*
* @param segment Pointer to a character string defining the segment of the registry being queried.
* @param token Pointer to a character string containing the token to be translated.
*
* @retval key Integer value corresponding to the specified token within the specified segment.
* @retval -1 Indicates that the segment and/or token could not be found.
*/
int ompi_registry_getkey(char *segment, char *token);
/** Add a token to a segment's dictionary.
* The ompi_registry_definekey() function allows the addition of a new definition to
* the registry's token-key dictionaries. The specified token is assigned an integer
* value within the specified segment, and the entry is added to the segment's token-key
* dictionary.
*
* @param segment Pointer to a character string defining the segment of the registry being queried.
* @param token Pointer to a character string containing the token to be translated.
*
* @retval key Integer value corresponding to the specified token within the specified segment.
* @retval -1 Indicates that the entry could not be created.
*/
int ompi_registry_definekey(char *segment, char *token);
/** Delete a token from a segment's dictionary.
* The ompi_registry_deletekey() function allows the removal of a definition from the
* registry's token-key dictionaries. This should be used with caution! Deletion of
* a token-key pair causes the registry to search through all entries within that segment
* for objects that include the specified token-key pair in their description. The reference
* is subsequently removed, and any object for which this was the SOLE key will also
* be removed from the registry!
*
* @param segment Pointer to a character string defining the segment of the registry.
* @param token Pointer to a character string containing the token to be deleted.
*
* @retval LAM_SUCCESS Indicating that the operation was successful.
* @retval LAM_ERROR Indicates that the operation failed - most likely caused by specifying
* a token that did not exist within the specified segment, or a non-existent segment.
*/
int ompi_registry_deletekey(char *segment, char *token);
/** Define a new registry segment.
* The ompi_registry_definesegment() function allows the caller to create a new registry
* segment with the specified name. Each segment is given its own token-key dictionary and
* object storage list. There is no limit nor restrictions on the number of segments
* that can be created and who can create them, or for what they can be used. Attempts to
* define a segment with a name that already exists will return an error.
*
* @param segment A pointer to a character string containing the name of the segment
* to be created.
*
* @retval LAM_SUCCESS Indicates that the operation was successfully completed.
* @retval LAM_ERROR Indicates that the operation failed - most likely due to the
* prior existence of a segment with an identical name.
*/
int ompi_registry_definesegment(char *segment);
/** Place an object on the registry.
* The ompi_registry_put() function places an object on the registry within the specified
* registry segment. At least one token describing the object must be provided - an unlimited
* number of additional tokens may also be provided. Note that placing an object on the
* registry where another object with all tokens identical already exists will cause the
* prior object to be replaced with the new object.
*
* CAUTION: The ompi_registry_put() function call MUST end with a NULL parameter! The C variable
* argument system does not provide for a mechanism by which we can determine the number of
* arguments that were passed. Failure to terminate the argument list with a NULL will result
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
*
* @param object A pointer to the object to be stored on the registry. The registry will create
* a copy of the object. Since the registry has no knowledge of the object's internal structure,
* the object is stored as an object of uint8_t (unsigned 8-bit int) type. The pointer must be cast
* into the uint8_t type when passed.
* @param size Integer value of the size of the object being passed, in bytes.
* @param segment A pointer to a character string stating the registry segment to be used.
* @param token A pointer to a character string containing a token that defines the object
* being stored. This token can later be used to retrieve the object. The registry uses the
* ompi_registry_getkey() function to translate the token to an integer key prior to storing
* the object. If the token is not currently defined in the segment's dictionary, a new
* dictionary entry will automatically be created.
* @param tokens... Additional tokens (provided as pointers to character strings) can be
* provided to further identify the object being stored.
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
* variable list of arguments.
*
* @retval LAM_SUCCESS Indicates that the operation was successful.
* @retval LAM_ERROR Indicates that the registry was unable to store the object - most
* likely due to specifying a non-existent segment or lack of available memory.
*/
int ompi_registry_put(uint8_t *object, int size, char *segment, char *token, ...);
/** Retrieve an object from the registry.
* The ompi_registry_get() function retrieves a copy of an object previously stored on
* the registry. The caller must provide the registry segment containing the object, and at
* least one token that describes it. An unlimited number of additional tokens describing the
* object may be provided. The function will return a linked list of all objects that match
* the search criteria.
*
* CAUTION: The ompi_registry_get() function call MUST end with a NULL parameter! The C variable
* argument system does not provide for a mechanism by which we can determine the number of
* arguments that were passed. Failure to terminate the argument list with a NULL will result
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
*
* @param segment Pointer to a character string defining the segment of the registry.
* @param token Pointer to a character string containing the token to be retrieved.
* @param tokens... Additional tokens (provided as pointers to character strings) can be
* provided to further identify the object being retrieved.
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
* variable list of arguments.
*
* @retval object Pointer to a linked list of ompi_registry_value structures, each containing
* a pointer to a copy of the object retrieved from the registry, the size of the object in bytes,
* and a pointer to the next link in the list (which is NULL for the last link). The object
* is returned as a *uint8_t since the object's internal structure is unknown to the registry.
* @retval NULL Indicates that the specified object could not be found.
*/
ompi_registry_value_t *ompi_registry_get(char *segment, char *token, ...);
/** Delete an object from the registry.
* The ompi_registry_del() function removes an object that was previously stored on the registry.
* The caller must provide the registry segment containing the object, and at
* least one token that describes it. An unlimited number of additional tokens describing the
* object may be provided.
*
* CAUTION: The function will delete ALL objects that match the search criteria.
*
* CAUTION: The ompi_registry_del() function call MUST end with a NULL parameter! The C variable
* argument system does not provide for a mechanism by which we can determine the number of
* arguments that were passed. Failure to terminate the argument list with a NULL will result
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
*
* @param segment Pointer to a character string defining the segment of the registry.
* @param token Pointer to a character string containing the token to be deleted.
* @param tokens... Additional tokens (provided as pointers to character strings) can be
* provided to further identify the object being deleted.
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
* variable list of arguments.
* @retval LAM_SUCCESS Indicates that the operation was successful.
* @retval LAM_ERROR Indicates that the registry was unable to delete the object - most
* likely due to specifying a non-existent segment or object.
*/
int ompi_registry_del(char *segment, char *token, ...);
/** Obtain an index of the registry token-key dictionary.
* The ompi_registry_index() function provides a list of the token-key pairs within
* a specified dictionary. The caller must provide the name of the segment being
* queried - this will return a linked list of all token-key pairs within that segment's
* dictionary. Alternatively, the caller may also provide an unlimited number of tokens
* which the caller would like to have translated - the function will then return a
* linked list of token-key pairs. Any tokens not found will be ignored.
*
* CAUTION: The ompi_registry_index() function call MUST end with a NULL parameter! The C variable
* argument system does not provide for a mechanism by which we can determine the number of
* arguments that were passed. Failure to terminate the argument list with a NULL will result
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
*
* @param segment Pointer to a character string defining the segment of the registry.
* @param tokens... Additional tokens (provided as pointers to character strings) can be
* provided that the caller would like to have translated.
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
* variable list of arguments.
*
* @retval keyvalues A pointer to a linked list of token-key pairs. Any tokens not found
* will be ignored and will, therefore, not be included in the returned list.
* @retval NULL Indicates that the operation failed - most likely caused by failing to specify
* any token that exists within the specified segment, or a non-existent segment.
*/
ompi_keytable_t *ompi_registry_index(char *segment, ...);
/** Subscribe to a registry object.
* The ompi_registry_subscribe() function allows the caller to be notified when specific actions
* are taken on the specified object. Notification will be sent via the OOB communication channel.
* The caller must provide an ID that allows the OOB to properly route the notification message.
*
* CAUTION: The ompi_registry_subscribe() function call MUST end with a NULL parameter! The C variable
* argument system does not provide for a mechanism by which we can determine the number of
* arguments that were passed. Failure to terminate the argument list with a NULL will result
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
*
* @param caller The ID of the caller - used to route any subsequent notifications.
* @param action A bit-mask value formed using the OMPI_REGISTRY_NOTIFY flags that indicates
* the action that shall trigger notification of the caller.
* @param segment Pointer to a character string defining the segment of the registry.
* @param token Pointer to a character string containing the token of the object to which
* the caller is subscribing.
* @param tokens... Additional tokens (provided as pointers to character strings) can be
* provided to further identify the object to which the caller is subscribing.
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
* variable list of arguments.
*
* @retval LAM_SUCCESS Indicating that the operation was successful.
* @retval LAM_ERROR Indicates that the operation failed - most likely caused by specifying
* an object that did not exist within the specified segment, or a non-existent segment.
*/
int ompi_registry_subscribe(int caller, uint8_t action, char *segment, char *token, ...);
/** Unsubscribe from a registry object.
*
* CAUTION: The ompi_registry_put() function call MUST end with a NULL parameter! The C variable
* argument system does not provide for a mechanism by which we can determine the number of
* arguments that were passed. Failure to terminate the argument list with a NULL will result
* in segmentation violations or bus errors, thus causing the program to catastrophically fail.
*
* @param caller The ID of the caller wishing to remove its subscription to the object.
* @param segment Pointer to a character string defining the segment of the registry.
* @param token Pointer to a character string containing the token of the object to which
* the caller is subscribed.
* @param tokens... Additional tokens (provided as pointers to character strings) can be
* provided to further identify the object to which the caller is subscribed.
* @param NULL The last parameter in the function call MUST be a NULL to terminate the
* variable list of arguments.
*
* @retval LAM_SUCCESS Indicating that the operation was successful. Note that this value will
* also be returned if the caller was not previously subscribed to the specified object since an
* unsubscribe request would have resulted in the same end condition.
* @retval LAM_ERROR Indicates that the operation failed - most likely caused by specifying
* an object that did not exist within the specified segment, or a non-existent segment.
*/
int ompi_registry_unsubscribe(int caller, uint8_t action, char *segment, char *token, ...);