Skip to content

Commit

Permalink
postgetclean and presetcleanup hook
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-wa committed Apr 17, 2016
1 parent cfc717b commit 75c95b2
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 103 deletions.
53 changes: 27 additions & 26 deletions src/include/kdbprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#include <limits.h>

/** The minimal allocation size of a keyset inclusive
NULL byte. ksGetAlloc() will return one less because
it says how much can actually be stored.*/
NULL byte. ksGetAlloc() will return one less because
it says how much can actually be stored.*/
#define KEYSET_SIZE 16

/** How many plugins can exist in an backend. */
Expand Down Expand Up @@ -119,7 +119,7 @@ typedef enum {
If name, value or metadata
are changed this flag will be set, so that the backend will sync
the key to database.*/
KEY_FLAG_RO_NAME = 1 << 1, /*!<
KEY_FLAG_RO_NAME = 1 << 1, /*!<
Read only flag for name.
Key name is read only and not allowed
to be changed. All attempts to change the name
Expand All @@ -132,7 +132,7 @@ typedef enum {
to be changed. All attempts to change the value
will lead to an error.
Needed for meta keys*/
KEY_FLAG_RO_META = 1 << 3 /*!<
KEY_FLAG_RO_META = 1 << 3 /*!<
Read only flag for meta.
Key meta is read only and not allowed
to be changed. All attempts to change the value
Expand Down Expand Up @@ -248,7 +248,7 @@ struct _KeySet
size_t alloc; /**< Allocated size of array */

struct _Key * cursor; /**< Internal cursor */
size_t current; /**< Current position of cursor */
size_t current; /**< Current position of cursor */

/**
* Some control and internal flags.
Expand All @@ -268,6 +268,7 @@ typedef enum {
POSTGETSTORAGE,
POSTGETCLEANUP,
PRESETSTORAGE,
PRESETCLEANUP,
PRECOMMIT,
POSTCOMMIT,
NR_GLOBAL_PLUGINS
Expand Down Expand Up @@ -339,18 +340,18 @@ struct _Backend
Plugin * getplugins[NR_OF_PLUGINS];
Plugin * errorplugins[NR_OF_PLUGINS];

ssize_t specsize; /*!< The size of the spec key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
ssize_t dirsize; /*!< The size of the dir key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
ssize_t usersize; /*!< The size of the users key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
ssize_t specsize; /*!< The size of the spec key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
ssize_t dirsize; /*!< The size of the dir key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
ssize_t usersize; /*!< The size of the users key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
ssize_t systemsize; /*!< The size of the systems key from the previous get.
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */
-1 if still uninitialized.
Needed to know if a key was removed from a keyset. */

size_t refcounter; /*!< This refcounter shows how often the backend
is used. Not cascading or default backends have 1 in it.
Expand Down Expand Up @@ -383,8 +384,8 @@ struct _Plugin
kdbOpenPtr kdbOpen; /*!< The pointer to kdbOpen_template() of the backend. */
kdbClosePtr kdbClose; /*!< The pointer to kdbClose_template() of the backend. */

kdbGetPtr kdbGet; /*!< The pointer to kdbGet_template() of the backend. */
kdbSetPtr kdbSet; /*!< The pointer to kdbSet_template() of the backend. */
kdbGetPtr kdbGet; /*!< The pointer to kdbGet_template() of the backend. */
kdbSetPtr kdbSet; /*!< The pointer to kdbSet_template() of the backend. */
kdbErrorPtr kdbError; /*!< The pointer to kdbError_template() of the backend. */

const char * name; /*!< The name of the module responsible for that plugin. */
Expand All @@ -393,7 +394,7 @@ struct _Plugin
is used. Not shared plugins have 1 in it */

void * data; /*!< This handle can be used for a plugin to store
any data its want to. */
any data its want to. */
};


Expand All @@ -415,11 +416,11 @@ struct _Trie

typedef enum {
SPLIT_FLAG_SYNC = 1, /*!< KeySet in Split need sync.
Is there any key in there which need to be synced?
If keys were popped from the Keyset
this flag will be set, so that the backend will sync
the keys to database.
*/
Is there any key in there which need to be synced?
If keys were popped from the Keyset
this flag will be set, so that the backend will sync
the keys to database.
*/

SPLIT_FLAG_CASCADING = 1 << 1 /*!< Do we need relative checks?
Is this a cascading backend?
Expand All @@ -436,8 +437,8 @@ struct _Split
{
size_t size; /*!< Number of keysets */
size_t alloc; /*!< How large the arrays are allocated */
KeySet ** keysets; /*!< The keysets */
Backend ** handles; /*!< The KDB for the keyset */
KeySet ** keysets; /*!< The keysets */
Backend ** handles; /*!< The KDB for the keyset */
Key ** parents; /*!< The parentkey for the keyset.
Is either the mountpoint of the backend
or "user", "system", "spec" for the split root/cascading backends */
Expand Down
148 changes: 108 additions & 40 deletions src/libs/elektra/kdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ static int elektraGetDoUpdate (Split * split, Key * parentKey)
keySetName (parentKey, keyName (split->parents[i]));
keySetString (parentKey, keyString (split->parents[i]));

for (size_t p = 1; p < 6; ++p)
for (size_t p = 1; p < NR_OF_PLUGINS; ++p)
{
int ret = 0;
if (backend->getplugins[p])
Expand All @@ -527,7 +527,9 @@ static int elektraGetDoUpdate (Split * split, Key * parentKey)
return 0;
}

static int elektraGetDoUpdate2 (Split * split, KeySet * ks, Key * parentKey)
typedef enum { FIRST, LAST } UpdatePass;

static int elektraGetDoUpdateWithGlobalHooks (KDB * handle, Split * split, KeySet * ks, Key * parentKey, UpdatePass run)
{
const int bypassedSplits = 1;
for (size_t i = 0; i < split->size - bypassedSplits; i++)
Expand All @@ -541,13 +543,39 @@ static int elektraGetDoUpdate2 (Split * split, KeySet * ks, Key * parentKey)
ksRewind (split->keysets[i]);
keySetName (parentKey, keyName (split->parents[i]));
keySetString (parentKey, keyString (split->parents[i]));

for (size_t p = 6; p < NR_OF_PLUGINS; ++p)
int start, end;
if (run == FIRST)
{
start = 1;
end = STORAGE_PLUGIN + 1;
}
else
{
start = STORAGE_PLUGIN + 1;
end = NR_OF_PLUGINS;
}
for (int p = start; p < end; ++p)
{
int ret = 0;
if ((p == (STORAGE_PLUGIN + 1)) && handle->globalPlugins[POSTGETSTORAGE])
{
handle->globalPlugins[POSTGETSTORAGE]->kdbGet (handle->globalPlugins[POSTGETSTORAGE], ks, parentKey);
}
else if ((p == (NR_OF_PLUGINS - 1)) && handle->globalPlugins[POSTGETCLEANUP])
{
handle->globalPlugins[POSTGETCLEANUP]->kdbGet (handle->globalPlugins[POSTGETCLEANUP], ks, parentKey);
}

if (backend->getplugins[p])
{
ret = backend->getplugins[p]->kdbGet (backend->getplugins[p], ks, parentKey);
if (p <= STORAGE_PLUGIN)
{
ret = backend->getplugins[p]->kdbGet (backend->getplugins[p], split->keysets[i], parentKey);
}
else
{
ret = backend->getplugins[p]->kdbGet (backend->getplugins[p], ks, parentKey);
}
}

if (ret == -1)
Expand Down Expand Up @@ -699,43 +727,70 @@ int kdbGet (KDB * handle, KeySet * ks, Key * parentKey)
goto error;
}

/* Now do the real updating,
but not for bypassed keys in split->size-1 */
if (elektraGetDoUpdate (split, parentKey) == -1)
if (handle->globalPlugins[POSTGETSTORAGE] || handle->globalPlugins[POSTGETCLEANUP])
{
goto error;
}

/* Now postprocess the updated keysets */
if (elektraSplitGet (split, parentKey, handle) == -1)
{
ELEKTRA_ADD_WARNING (108, parentKey, keyName (ksCurrent (ks)));
// continue, because sizes are already updated
if (elektraGetDoUpdateWithGlobalHooks (NULL, split, NULL, parentKey, FIRST) == -1)
{
goto error;
}
ksClear (ks);
elektraSplitMerge (split, ks);
KeySet * dupKS = ksDup (ks);
if (elektraGetDoUpdateWithGlobalHooks (handle, split, ks, parentKey, LAST) == -1)
{
goto error;
}
Key * cur;
ksRewind (ks);
KeySet * newKeys = ksNew (0, KS_END);
while ((cur = ksNext (ks)) != NULL)
{
if (!ksLookup (dupKS, cur, KDB_O_NONE))
{
ksAppendKey (newKeys, cur);
}
}
ksDel (dupKS);
ksRewind (ks);
while ((cur = ksNext (ks)) != NULL)
fprintf (stderr, "%s:(%s)\n", keyName (cur), keyString (cur));
/* Now postprocess the updated keysets */
if (elektraSplitGet (split, parentKey, handle) == -1)
{
ELEKTRA_ADD_WARNING (108, parentKey, keyName (ksCurrent (ks)));
// continue, because sizes are already updated
}
ksClear (ks);
elektraSplitMerge (split, ks);
ksAppend (ks, newKeys);
ksDel (newKeys);
}
else
{

/* We are finished, now just merge everything to returned */
ksClear (ks);
elektraSplitMerge (split, ks);
ksRewind (ks);
/* Now do the real updating,
but not for bypassed keys in split->size-1 */
if (elektraGetDoUpdate (split, parentKey) == -1)
{
goto error;
}
/* Now postprocess the updated keysets */
if (elektraSplitGet (split, parentKey, handle) == -1)
{
ELEKTRA_ADD_WARNING (108, parentKey, keyName (ksCurrent (ks)));
// continue, because sizes are already updated
}
/* We are finished, now just merge everything to returned */
ksClear (ks);

keySetName (parentKey, keyName (initialParent));
if (handle->globalPlugins[POSTGETSTORAGE])
{
handle->globalPlugins[POSTGETSTORAGE]->kdbGet (handle->globalPlugins[POSTGETSTORAGE], ks, parentKey);
elektraSplitMerge (split, ks);
}

ksRewind (ks);

if (elektraGetDoUpdate2 (split, ks, parentKey) == -1)
{
goto error;
}
if (handle->globalPlugins[POSTGETCLEANUP])
{
handle->globalPlugins[POSTGETCLEANUP]->kdbGet (handle->globalPlugins[POSTGETCLEANUP], ks, parentKey);
}

keySetName (parentKey, keyName (initialParent));

elektraSplitUpdateFileName (split, handle, parentKey);
keyDel (initialParent);
elektraSplitDel (split);
Expand Down Expand Up @@ -768,7 +823,7 @@ int kdbGet (KDB * handle, KeySet * ks, Key * parentKey)
* @retval -1 on error
* @retval 0 on success
*/
static int elektraSetPrepare (Split * split, Key * parentKey, Key ** errorKey, Plugin * hook)
static int elektraSetPrepare (Split * split, Key * parentKey, Key ** errorKey, Plugin ** hooks)
{
int any_error = 0;
for (size_t i = 0; i < split->size; i++)
Expand Down Expand Up @@ -799,12 +854,6 @@ static int elektraSetPrepare (Split * split, Key * parentKey, Key ** errorKey, P

if (p == 0)
{
if (hook)
{
// the only place global presetstorage hooks can be executed
ksRewind (split->keysets[i]);
hook->kdbSet (hook, split->keysets[i], parentKey);
}
if (ret == 0)
{
// resolver says that sync is
Expand All @@ -816,6 +865,25 @@ static int elektraSetPrepare (Split * split, Key * parentKey, Key ** errorKey, P
keySetString (split->parents[i], keyString (parentKey));
}
}

if (p == 0)
{
if (hooks[PREGETSTORAGE])
{
// the only place global presetstorage hooks can be executed
ksRewind (split->keysets[i]);
hooks[PRESETSTORAGE]->kdbSet (hooks[PRESETSTORAGE], split->keysets[i], parentKey);
}
}
else if (p == 4)
{
if (hooks[PRESETCLEANUP])
{
ksRewind (split->keysets[i]);
hooks[PRESETCLEANUP]->kdbSet (hooks[PRESETCLEANUP], split->keysets[i], parentKey);
}
}

if (ret == -1)
{
// do not
Expand Down Expand Up @@ -1049,7 +1117,7 @@ int kdbSet (KDB * handle, KeySet * ks, Key * parentKey)

elektraSplitPrepare (split);

if (elektraSetPrepare (split, parentKey, &errorKey, handle->globalPlugins[PRESETSTORAGE]) == -1)
if (elektraSetPrepare (split, parentKey, &errorKey, handle->globalPlugins) == -1)
{
goto error;
}
Expand Down
6 changes: 4 additions & 2 deletions src/libs/elektra/mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,9 @@ int elektraMountGlobals (KDB * kdb, KeySet * keys, KeySet * modules, Key * error
continue;
const char * placement = keyBaseName (cur);
const char * pluginName = keyString (cur);
const char * globalPlacements[NR_GLOBAL_PLUGINS] = { "prerollback", "postrollback", "pregetstorage", "postgetstorage", "postgetcleanup",
"presetstorage", "precommit", "postcommit" };
const char * globalPlacements[NR_GLOBAL_PLUGINS] = { "prerollback", "postrollback", "pregetstorage",
"postgetstorage", "postgetcleanup", "presetstorage",
"presetcleanup", "precommit", "postcommit" };


if (!strcmp (pluginName, ""))
Expand All @@ -277,6 +278,7 @@ int elektraMountGlobals (KDB * kdb, KeySet * keys, KeySet * modules, Key * error
#if DEBUG && VERBOSE
printf ("mounting global plugin %s to %s\n", pluginName, placement);
#endif

Plugin * plugin;
Key * refKey;
Key * searchKey = keyNew ("/", KEY_END);
Expand Down
Loading

0 comments on commit 75c95b2

Please sign in to comment.