Elektra
0.9.3
|
Private declarations. More...
#include <elektra.h>
#include <elektra/error.h>
#include <kdb.h>
#include <kdbextension.h>
#include <kdbhelper.h>
#include <kdbio.h>
#include <kdbmacros.h>
#include <kdbnotificationinternal.h>
#include <kdbplugin.h>
#include <kdbproposal.h>
#include <kdbtypes.h>
#include <kdbglobal.h>
#include <limits.h>
Macros | |
#define | KEYSET_SIZE 16 |
The minimal allocation size of a keyset inclusive NULL byte. More... | |
#define | NR_OF_PLUGINS 10 |
How many plugins can exist in an backend. More... | |
#define | COMMIT_PLUGIN 7 |
The index of the commit plugin. | |
#define | STORAGE_PLUGIN 5 |
The index of the storage plugin. | |
#define | RESOLVER_PLUGIN 0 |
The index of the resolver plugin. | |
#define | APPROXIMATE_NR_OF_BACKENDS 16 |
Trie optimization. | |
#define | KDB_MAX_UCHAR (UCHAR_MAX + 1) |
The maximum value of unsigned char+1, needed for iteration over trie children/values: More... | |
#define | MAX_LEN_INT 31 |
The maximum of how many characters an integer needs as decimal number. More... | |
#define | KDB_SYSTEM_ELEKTRA "system/elektra" |
Backend mounting information. More... | |
#define | KDB_CACHE_PREFIX "system/elektra/cache" |
All keys below this are used for cache metadata in the global keyset. | |
#define | test_bit(var, bit) ((var) & (bit)) |
Test a bit. More... | |
#define | set_bit(var, bit) ((var) |= (bit)) |
Set a bit. More... | |
#define | clear_bit(var, bit) ((var) &= ~(bit)) |
Clear a bit. More... | |
Enumerations | |
enum | keyflag_t { KEY_FLAG_SYNC = 1, KEY_FLAG_RO_NAME = 1 << 1, KEY_FLAG_RO_VALUE = 1 << 2, KEY_FLAG_RO_META = 1 << 3, KEY_FLAG_MMAP_STRUCT = 1 << 4, KEY_FLAG_MMAP_KEY = 1 << 5, KEY_FLAG_MMAP_DATA = 1 << 6 } |
Key Flags. More... | |
enum | ksflag_t { KS_FLAG_SYNC = 1, KS_FLAG_MMAP_STRUCT = 1 << 2, KS_FLAG_MMAP_ARRAY = 1 << 3 } |
Advanced KS Flags. More... | |
enum | splitflag_t { SPLIT_FLAG_SYNC = 1, SPLIT_FLAG_CASCADING = 1 << 1 } |
Functions | |
Split * | splitNew (void) |
Allocates a new split object. More... | |
void | splitDel (Split *keysets) |
Delete a split object. More... | |
void | splitRemove (Split *split, size_t where) |
Remove one part of split. More... | |
ssize_t | splitAppend (Split *split, Backend *backend, Key *parentKey, int syncbits) |
Increases the size of split and appends a new empty keyset. More... | |
int | splitBuildup (Split *split, KDB *handle, Key *parentKey) |
Walks through kdb->split and adds all backends below parentKey to split. More... | |
void | splitUpdateFileName (Split *split, KDB *handle, Key *key) |
Update the (configuration) file name for the parent key. More... | |
int | splitAppoint (Split *split, KDB *handle, KeySet *ks) |
Appoints all keys from ks to yet unsynced splits. More... | |
int | splitGet (Split *split, Key *warningKey, KDB *handle) |
Does some work after getting of backends is finished. More... | |
int | splitMergeBackends (Split *split, KeySet *dest) |
Merges together the backend based parts of split into dest, but bypasses the default split. More... | |
int | splitMergeDefault (Split *split, KeySet *dest) |
Merges the default split into dest. More... | |
int | splitDivide (Split *split, KDB *handle, KeySet *ks) |
Splits up the keysets and search for a sync bit in every key. More... | |
int | splitSync (Split *split) |
Add sync bits everywhere keys were removed/added. More... | |
void | splitPrepare (Split *split) |
Prepares for kdbSet() mainloop afterwards. More... | |
int | splitUpdateSize (Split *split) |
Also update sizes after kdbSet() to recognize multiple kdbSet() attempts. More... | |
Backend * | backendOpen (KeySet *elektra_config, KeySet *modules, KeySet *global, Key *errorKey) |
Builds a backend out of the configuration supplied from: More... | |
Backend * | backendOpenDefault (KeySet *modules, KeySet *global, const char *file, Key *errorKey) |
Opens a default backend using the plugin named KDB_RESOLVER and KDB_STORAGE. More... | |
Backend * | backendOpenModules (KeySet *modules, KeySet *global, Key *errorKey) |
Backend * | backendOpenVersion (KeySet *global, Key *errorKey) |
Opens the internal version backend. More... | |
int | backendUpdateSize (Backend *backend, Key *parent, int size) |
Update internal size in backend. More... | |
Plugin * | elektraPluginOpen (const char *backendname, KeySet *modules, KeySet *config, Key *errorKey) |
Opens a plugin. More... | |
int | elektraProcessPlugin (Key *cur, int *pluginNumber, char **pluginName, char **referenceName, Key *errorKey) |
int | elektraProcessPlugins (Plugin **plugins, KeySet *modules, KeySet *referencePlugins, KeySet *config, KeySet *systemConfig, KeySet *global, Key *errorKey) |
Load a plugin. More... | |
size_t | elektraPluginGetFunction (Plugin *plugin, const char *name) |
Retrieves a function exported by a plugin. More... | |
Plugin * | elektraPluginFindGlobal (KDB *handle, const char *pluginName) |
Searches the global plugins for a given plugin name. More... | |
int | trieClose (Trie *trie, Key *errorKey) |
Closes the trie and all opened backends within. More... | |
Backend * | trieLookup (Trie *trie, const Key *key) |
The Trie structure. More... | |
Trie * | trieInsert (Trie *trie, const char *name, Backend *value) |
Insert into trie. More... | |
int | mountOpen (KDB *kdb, KeySet *config, KeySet *modules, Key *errorKey) |
Creates a trie from a given configuration. More... | |
int | mountDefault (KDB *kdb, KeySet *modules, int inFallback, Key *errorKey) |
Reopens the default backend and mounts the default backend if needed. More... | |
int | mountModules (KDB *kdb, KeySet *modules, Key *errorKey) |
Mount all module configurations. More... | |
int | mountVersion (KDB *kdb, Key *errorKey) |
Mount the version backend. More... | |
int | mountBackend (KDB *kdb, Backend *backend, Key *errorKey) |
Mounts a backend into the trie. More... | |
Key * | mountGetMountpoint (KDB *handle, const Key *where) |
Lookup a mountpoint in a handle for a specific key. More... | |
Backend * | mountGetBackend (KDB *handle, const Key *key) |
Lookup a backend handle for a specific key. More... | |
Key * | elektraKsPopAtCursor (KeySet *ks, elektraCursor pos) |
Pop key at given cursor position. More... | |
ssize_t | elektraMemcpy (Key **array1, Key **array2, size_t size) |
Internal Methods for Elektra. More... | |
ssize_t | elektraMemmove (Key **array1, Key **array2, size_t size) |
Copies the key array2 into where array1 points. More... | |
int | elektraValidateKeyName (const char *name, size_t size) |
Validates whether the supplied keyname is valid. More... | |
KeySet * | ksRenameKeys (KeySet *config, const char *name) |
Takes the first key and cuts off this common part for all other keys, instead name will be prepended. More... | |
ElektraError * | elektraErrorCreate (const char *code, const char *description, const char *module, const char *file, kdb_long_t line) |
Creates a new ElektraError using the provided values. More... | |
void | elektraErrorAddWarning (ElektraError *error, ElektraError *warning) |
Adds a warning to an existing ElektraError struct. More... | |
ElektraError * | elektraErrorFromKey (Key *key) |
Extracts the error and all warnings from the given key. More... | |
ElektraError * | elektraErrorKeyNotFound (const char *keyname) |
Creates a "Key not found" error. More... | |
ElektraError * | elektraErrorWrongType (const char *keyname, KDBType expectedType, KDBType actualType) |
Creates a "Wrong type" error. More... | |
ElektraError * | elektraErrorNullError (const char *function) |
Creates a "Null error argument" error. More... | |
ElektraError * | elektraErrorEnsureFailed (const char *reason) |
Creates a "kdbEnsure failed" error. More... | |
ElektraError * | elektraErrorMinimalValidationFailed (const char *function) |
Creates a "minimal validation failed" error. More... | |
Private declarations.
#define clear_bit | ( | var, | |
bit | |||
) | ((var) &= ~(bit)) |
Clear a bit.
#define KDB_MAX_UCHAR (UCHAR_MAX + 1) |
The maximum value of unsigned char+1, needed for iteration over trie children/values:
for (i=0; i<KDB_MAX_UCHAR; ++i)
#define KDB_SYSTEM_ELEKTRA "system/elektra" |
Backend mounting information.
This key directory tells you where each backend is mounted to which mountpoint.
#define KEYSET_SIZE 16 |
The minimal allocation size of a keyset inclusive NULL byte.
ksGetAlloc() will return one less because it says how much can actually be stored.
#define MAX_LEN_INT 31 |
The maximum of how many characters an integer needs as decimal number.
#define NR_OF_PLUGINS 10 |
How many plugins can exist in an backend.
#define set_bit | ( | var, | |
bit | |||
) | ((var) |= (bit)) |
Set a bit.
#define test_bit | ( | var, | |
bit | |||
) | ((var) & (bit)) |
Test a bit.
enum keyflag_t |
Key Flags.
Store a synchronizer state so that the Elektra knows if something has changed or not.
enum ksflag_t |
Advanced KS Flags.
Store a synchronizer state so that the Elektra knows if something has changed or not.
enum splitflag_t |
Backend* backendOpen | ( | KeySet * | elektraConfig, |
KeySet * | modules, | ||
KeySet * | global, | ||
Key * | errorKey | ||
) |
Builds a backend out of the configuration supplied from:
system/elektra/mountpoints/<name>
The root key must be like the above example. You do not need to rewind the keyset. But every key must be below the root key.
The internal consistency will be checked in this function. If necessary parts are missing, like no plugins, they cant be loaded or similar 0 will be returned.
ksCut() is perfectly suitable for cutting out the configuration like needed.
elektraConfig | the configuration to work with. It is used to build up this backend. |
modules | used to load new modules or get references to existing one |
global | the global keyset of the KDB instance |
errorKey | the key where an error and warnings are added |
0 | if out of memory |
Backend* backendOpenDefault | ( | KeySet * | modules, |
KeySet * | global, | ||
const char * | file, | ||
Key * | errorKey | ||
) |
Opens a default backend using the plugin named KDB_RESOLVER and KDB_STORAGE.
modules | the modules to work with |
global | the global keyset of the KDB instance |
errorKey | the key to issue warnings and errors to |
Backend* backendOpenModules | ( | KeySet * | modules, |
KeySet * | global, | ||
Key * | errorKey | ||
) |
modules | the modules to work with |
global | the global keyset of the KDB instance |
errorKey | the key to issue warnings and errors to |
Backend* backendOpenVersion | ( | KeySet * | global, |
Key * | errorKey | ||
) |
Opens the internal version backend.
global | the global keyset of the KDB instance |
errorKey | the key to issue warnings and errors to |
int backendUpdateSize | ( | Backend * | backend, |
Key * | parent, | ||
int | size | ||
) |
Update internal size in backend.
backend | the backend to update |
parent | for parent |
size | to update (-1 default, 0 empty, >0 otherwise) |
-1 | if invalid parent (assert) |
0 | on success |
void elektraErrorAddWarning | ( | ElektraError * | error, |
ElektraError * | warning | ||
) |
Adds a warning to an existing ElektraError struct.
If you want to report a warning without an error, create a dummy error with elektraErrorPureWarning() and then add a warning to it.
error | The error to which warning shall be added. |
warning | The warning to add. Once added it is owned by error . DO NOT call elektraErrorReset() on it afterwards. |
ElektraError* elektraErrorCreate | ( | const char * | code, |
const char * | description, | ||
const char * | module, | ||
const char * | file, | ||
kdb_long_t | line | ||
) |
Creates a new ElektraError using the provided values.
The returned value will be allocated with elektraCalloc().
code | The error code of the error. Must be compile-time constant. |
description | The description of the error. Will be copied and stored in the struct. |
module | The module that raised the error. Must be compile-time constant. |
file | The file that raised the error. Must be compile-time constant. |
line | The line in which the error was raised. |
ElektraError* elektraErrorEnsureFailed | ( | const char * | reason | ) |
Creates a "kdbEnsure failed" error.
This intended for the case when kdbEnsure() returns 1.
reason | The error/reason metadata returned by kdbEnsure(). |
ElektraError* elektraErrorFromKey | ( | Key * | key | ) |
Extracts the error and all warnings from the given key.
If no error exists, a pure warning error will be used.
key | The to extract error and warnings from. |
ElektraError* elektraErrorKeyNotFound | ( | const char * | keyname | ) |
Creates a "Key not found" error.
keyname | The name of the key that wasn't found. |
ElektraError* elektraErrorMinimalValidationFailed | ( | const char * | application | ) |
Creates a "minimal validation failed" error.
application | parent key as passed to elektraOpen() |
ElektraError* elektraErrorNullError | ( | const char * | function | ) |
Creates a "Null error argument" error.
function | The name of the function that was called with a null pointer error argument. |
ElektraError* elektraErrorWrongType | ( | const char * | keyname, |
KDBType | expectedType, | ||
KDBType | actualType | ||
) |
Creates a "Wrong type" error.
keyname | The name of the key that had the wrong type. |
expectedType | The type that was expected. |
actualType | The type that was actually found. |
Key* elektraKsPopAtCursor | ( | KeySet * | ks, |
elektraCursor | pos | ||
) |
Pop key at given cursor position.
ks | the keyset to pop key from |
c | where to pop |
The internal cursor will be rewinded using ksRewind(). You can use ksGetCursor() and ksSetCursor() jump back to the previous position. e.g. to pop at current position within ksNext() loop:
0 | if ks is 0 |
ssize_t elektraMemcpy | ( | Key ** | array1, |
Key ** | array2, | ||
size_t | size | ||
) |
Internal Methods for Elektra.
To use them:
There are some areas where libraries have to reimplement some basic functions to archive support for non-standard systems, for testing purposes or to provide a little more convenience. Copies the key array2 into where array1 points. It copies size elements.
Overlapping is prohibited, use elektraMemmove() instead.
array1 | the destination |
array2 | the source |
size | how many pointer to Keys to copy |
-1 | on null pointers |
0 | if nothing was done |
ssize_t elektraMemmove | ( | Key ** | array1, |
Key ** | array2, | ||
size_t | size | ||
) |
Copies the key array2 into where array1 points.
It copies size elements.
Overlapping is ok. If they do not overlap consider elektraMemcpy() instead.
array1 | the destination |
array2 | the source |
size | how many pointer to Keys to copy |
-1 | on null pointers |
0 | if nothing was done |
Plugin* elektraPluginFindGlobal | ( | KDB * | handle, |
const char * | pluginName | ||
) |
Searches the global plugins for a given plugin name.
NOTE: if the list plugin occupies the prerollback position, this queries the list plugin first, and only if we don't find anything there, we look directly in the global plugins array
handle | The KDB handle to search |
pluginName | The plugin name to look for |
size_t elektraPluginGetFunction | ( | Plugin * | plugin, |
const char * | name | ||
) |
Retrieves a function exported by a plugin.
plugin | Plugin handle |
name | Function name |
Plugin* elektraPluginOpen | ( | const char * | name, |
KeySet * | modules, | ||
KeySet * | config, | ||
Key * | errorKey | ||
) |
Opens a plugin.
The config will be used as is. So be sure to transfer ownership of the config to it, with e.g. ksDup(). elektraPluginClose() will delete the config.
int elektraProcessPlugin | ( | Key * | cur, |
int * | pluginNumber, | ||
char ** | pluginName, | ||
char ** | referenceName, | ||
Key * | errorKey | ||
) |
1 | and an allocated string of the pluginName if a new plugins should be created. |
2 | and an allocated string of the referenceName if an old plugin should be used |
3 | and both if a new plugin should be created and made available for later back referencing. |
-1 | on error |
int elektraProcessPlugins | ( | Plugin ** | plugins, |
KeySet * | modules, | ||
KeySet * | referencePlugins, | ||
KeySet * | config, | ||
KeySet * | systemConfig, | ||
KeySet * | global, | ||
Key * | errorKey | ||
) |
Load a plugin.
The array of plugins must be set to 0. Its length is NR_OF_PLUGINS.
systemConfig will only be used, not deleted.
config | the config with the information how the plugins should be put together |
systemConfig | the shared (system) config for the plugins. Every plugin additional get this config. |
global | the global keyset of the KDB instance |
-1 | on failure |
int elektraValidateKeyName | ( | const char * | name, |
size_t | size | ||
) |
Validates whether the supplied keyname is valid.
The function looks for tangling escape characters in the end and for a minimum length.
Does not check for valid namespaces
name | the key name that is to be checked |
size | a elektraStrLen of the key name |
true | if the supplied keyname part is valid |
false | if its invalid |
int mountBackend | ( | KDB * | kdb, |
Backend * | backend, | ||
Key * | errorKey | ||
) |
Mounts a backend into the trie.
kdb | the handle to work with |
backend | the backend to mount |
errorKey | the key used to report warnings |
-1 | on failure |
1 | on success |
int mountDefault | ( | KDB * | kdb, |
KeySet * | modules, | ||
int | inFallback, | ||
Key * | errorKey | ||
) |
Reopens the default backend and mounts the default backend if needed.
kdb | the handle to work with |
modules | the current list of loaded modules |
errorKey | the key used to report warnings |
-1 | on error |
0 | on success |
Backend* mountGetBackend | ( | KDB * | handle, |
const Key * | key | ||
) |
Lookup a backend handle for a specific key.
The required canonical name is ensured by using a key as parameter, which will transform the key to canonical representation.
Will return handle when no more specific KDB could be found.
If key is 0 or invalid the default backend will be returned.
handle | is the data structure, where the mounted directories are saved. |
key | the key, that should be looked up. |
Key* mountGetMountpoint | ( | KDB * | handle, |
const Key * | where | ||
) |
Lookup a mountpoint in a handle for a specific key.
Will return a key representing the mountpoint or null if there is no appropriate mountpoint e.g. its the root mountpoint.
handle | is the data structure, where the mounted directories are saved. |
where | the key, that should be looked up. |
int mountModules | ( | KDB * | kdb, |
KeySet * | modules, | ||
Key * | errorKey | ||
) |
Mount all module configurations.
kdb | the handle to work with |
modules | the current list of loaded modules |
errorKey | the key used to report warnings |
-1 | if not rootkey was found |
0 | otherwise |
int mountOpen | ( | KDB * | kdb, |
KeySet * | config, | ||
KeySet * | modules, | ||
Key * | errorKey | ||
) |
Creates a trie from a given configuration.
The config will be deleted within this function.
kdb | the handle to work with |
modules | the current list of loaded modules |
config | the configuration which should be used to build up the trie. |
errorKey | the key used to report warnings |
-1 | on failure |
0 | on success |
int mountVersion | ( | KDB * | kdb, |
Key * | errorKey | ||
) |
Mount the version backend.
kdb | the handle to work with |
errorKey | the key used to report warnings |
0 | on success |
ssize_t splitAppend | ( | Split * | split, |
Backend * | backend, | ||
Key * | parentKey, | ||
int | syncbits | ||
) |
Increases the size of split and appends a new empty keyset.
Initializes the element with the given parameters at size-1 to be used.
Will automatically resize split if needed.
split | the split object to work with |
backend | the backend which should be appended |
parentKey | the parentKey which should be appended |
syncbits | the initial syncstate which should be appended |
-1 | if no split is found |
int splitAppoint | ( | Split * | split, |
KDB * | handle, | ||
KeySet * | ks | ||
) |
Appoints all keys from ks to yet unsynced splits.
split | the split object to work with |
handle | to determine to which backend a key belongs |
ks | the keyset to appoint to split |
1 | on success |
-1 | if no backend was found for a key |
int splitBuildup | ( | Split * | split, |
KDB * | kdb, | ||
Key * | parentKey | ||
) |
Walks through kdb->split and adds all backends below parentKey to split.
Sets syncbits to 2 if it is a default or root backend (which needs splitting). The information is copied from kdb->split.
split | will get all backends appended |
kdb | the handle to get information about backends |
parentKey | the information below which key the backends are from interest |
1 | always |
void splitDel | ( | Split * | keysets | ) |
Delete a split object.
Will free all allocated resources of a split keyset.
keysets | the split object to work with |
int splitDivide | ( | Split * | split, |
KDB * | handle, | ||
KeySet * | ks | ||
) |
Splits up the keysets and search for a sync bit in every key.
It does not check if there were removed keys, see splitSync() for the next step.
It does not create new backends, this has to be done by buildup before.
split | the split object to work with |
handle | to get information where the individual keys belong |
ks | the keyset to divide |
0 | if there were no sync bits |
1 | if there were sync bits |
-1 | if no backend was found for any key |
int splitGet | ( | Split * | split, |
Key * | warningKey, | ||
KDB * | handle | ||
) |
Does some work after getting of backends is finished.
split | the split object to work with |
warningKey | postcondition violations are reported here |
handle | the handle to preprocess the keys |
1 | on success |
-1 | if no backend was found for a key or split->parents has invalid namespace |
int splitMergeBackends | ( | Split * | split, |
KeySet * | dest | ||
) |
Merges together the backend based parts of split into dest, but bypasses the default split.
split | the split object to work with |
dest | the destination keyset where all keysets are appended. |
1 | on success |
int splitMergeDefault | ( | Split * | split, |
KeySet * | dest | ||
) |
Merges the default split into dest.
split | the split object to work with |
dest | the destination keyset where all keysets are appended. |
1 | on success |
Split* splitNew | ( | void | ) |
Allocates a new split object.
Splits up a keyset into multiple keysets where each of them will passed to the correct kdbSet().
Initially the size is 0 and alloc is APPROXIMATE_NR_OF_BACKENDS.
void splitPrepare | ( | Split * | split | ) |
Prepares for kdbSet() mainloop afterwards.
All splits which do not need sync are removed and a deep copy of the remaining keysets is done.
split | the split object to work with |
void splitRemove | ( | Split * | split, |
size_t | where | ||
) |
Remove one part of split.
split | the split object to work with |
where | the position to cut away |
int splitSync | ( | Split * | split | ) |
Add sync bits everywhere keys were removed/added.
Only splitDivide() together with this function can really decide if sync is needed or not.
0 | if kdbSet() is not needed |
1 | if kdbSet() is needed |
-1 | on wrong keys (also has assert, should not happen) |
-2 | wrong spec state: kdbGet() was not executed before |
-3 | wrong dir state: kdbGet() was not executed before |
-4 | wrong user state: kdbGet() was not executed before |
-5 | wrong system state: kdbGet() was not executed before |
split | the split object to work with |
void splitUpdateFileName | ( | Split * | split, |
KDB * | handle, | ||
Key * | key | ||
) |
Update the (configuration) file name for the parent key.
split | the split to work with |
handle | the handle to work with |
key | the parentKey that should be updated (name must be correct) |
int splitUpdateSize | ( | Split * | split | ) |
int trieClose | ( | Trie * | trie, |
Key * | errorKey | ||
) |
Closes the trie and all opened backends within.
trie | the trie to close |
errorKey | the key used to report warnings |
0 | on success |
Trie* trieInsert | ( | Trie * | trie, |
const char * | name, | ||
Backend * | value | ||
) |
Insert into trie.
trie | the trie to insert to (0 to create a new trie) |
name | the key's name to insert |
value | the value to insert |
trie | on success |
Backend* trieLookup | ( | Trie * | trie, |
const Key * | key | ||
) |
The Trie structure.
Lookups a backend inside the trie.
trie | the trie object to work with |
key | the name of this key will be looked up |