Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4495 from atmaxinger/nb-hooks-spec
Browse files Browse the repository at this point in the history
[new-backend] spec hook
  • Loading branch information
atmaxinger authored Sep 30, 2022
2 parents fac8496 + 48f21e0 commit 9a830e5
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 181 deletions.
2 changes: 1 addition & 1 deletion doc/help/kdb-get.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ kdb get -n /tests/get/examples/kdb-get/key

# To explain why a specific key was used (for cascading keys):
kdb get -v /tests/get/examples/kdb-get/key
#> got 2 keys
#> got 3 keys
#> searching spec:/tests/get/examples/kdb-get/key, found: <nothing>, options: KDB_O_CALLBACK
#> searching proc:/tests/get/examples/kdb-get/key, found: <nothing>
#> searching dir:/tests/get/examples/kdb-get/key, found: <nothing>
Expand Down
9 changes: 2 additions & 7 deletions doc/help/kdb-global-umount.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,14 @@ if [ -f "$(kdb file system:/elektra/globalplugins)" ]; then mv "$(kdb file syste
sudo kdb global-mount tracer

sudo kdb global-mount
# STDOUT-REGEX: .*spec⏎tracer.*
# STDOUT-REGEX: .*tracer.*

sudo kdb global-umount tracer

# spec is always mounted by default
sudo kdb global-mount
#> spec

sudo kdb global-umount spec

sudo kdb global-mount
#>


if [ -f "globalplugins.rm" ]; then rm "$(kdb file system:/elektra/globalplugins)" "globalplugins.rm"; else mv "globalplugins.bak" "$(kdb file system:/elektra/globalplugins)"; fi
```

Expand Down
5 changes: 5 additions & 0 deletions doc/news/_preparation_next_release.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ The following section lists news about the [plugins](https://www.libelektra.org/
- <<TODO>>
- <<TODO>>

### spec

- Partial rewrite for spec hook _(Maximilian Irlinger @atmaxinger)_
- <<TODO>>

### <<Plugin3>>

- <<TODO>>
Expand Down
16 changes: 12 additions & 4 deletions src/include/kdbprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ typedef int (*kdbCommitPtr) (Plugin * handle, KeySet * returned, Key * parentKey

typedef int (*kdbHookGoptsGetPtr) (Plugin * handle, KeySet * returned, Key * parentKey);

typedef int (*kdbHookSpecCopyPtr) (Plugin * handle, KeySet * returned, Key * parentKey, bool isKdbGet);
typedef int (*kdbHookSpecRemovePtr) (Plugin * handle, KeySet * returned, Key * parentKey);

typedef Plugin * (*OpenMapper) (const char *, const char *, KeySet *);
typedef int (*CloseMapper) (Plugin *);

Expand Down Expand Up @@ -321,8 +324,6 @@ struct _KeySet
#endif
};

typedef struct _Hooks Hooks;

/**
* The access point to the key database.
*
Expand Down Expand Up @@ -371,9 +372,16 @@ struct _KDB
{
struct
{
struct _Plugin* plugin;
kdbHookGoptsGetPtr kdbHookGoptsGet;
struct _Plugin * plugin;
kdbHookGoptsGetPtr get;
} gopts;

struct
{
struct _Plugin * plugin;
kdbHookSpecCopyPtr copy;
kdbHookSpecRemovePtr remove;
} spec;
} hooks;
};

Expand Down
45 changes: 44 additions & 1 deletion src/libs/elektra/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ void freeHooks (KDB * kdb, Key * errorKey)
if (kdb->hooks.gopts.plugin != NULL)
{
elektraPluginClose (kdb->hooks.gopts.plugin, errorKey);
kdb->hooks.gopts.plugin = NULL;
kdb->hooks.gopts.get = NULL;
}

if (kdb->hooks.spec.plugin != NULL)
{
elektraPluginClose (kdb->hooks.spec.plugin, errorKey);
kdb->hooks.spec.plugin = NULL;
kdb->hooks.spec.copy = NULL;
kdb->hooks.spec.remove = NULL;
}
}

Expand All @@ -43,7 +53,27 @@ static int initHooksGopts (KDB * kdb, Plugin * plugin, Key * errorKey)

kdb->hooks.gopts.plugin = plugin;

if ((kdb->hooks.gopts.kdbHookGoptsGet = (kdbHookGoptsGetPtr) getFunction (plugin, "hook/gopts/get", errorKey)) == NULL)
if ((kdb->hooks.gopts.get = (kdbHookGoptsGetPtr) getFunction (plugin, "hook/gopts/get", errorKey)) == NULL)
{
return -1;
}

return 0;
}

static int initHooksSpec (KDB * kdb, Plugin * plugin, Key * errorKey)
{
if (!plugin)
{
return -1;
}

kdb->hooks.spec.plugin = plugin;

kdb->hooks.spec.copy = (kdbHookSpecCopyPtr) getFunction (plugin, "hook/spec/copy", errorKey);
kdb->hooks.spec.remove = (kdbHookSpecRemovePtr) getFunction (plugin, "hook/spec/remove", errorKey);

if (kdb->hooks.spec.copy == NULL || kdb->hooks.spec.remove == NULL)
{
return -1;
}
Expand Down Expand Up @@ -138,6 +168,13 @@ static bool isGoptsEnabledByContract (const KeySet * contract)
return isEnabled;
}

static bool isSpecEnabledByConfig (const KeySet * config)
{
// TODO: check for system:/elektra/hook/spec/enabled or system:/elektra/hook/spec/disabled or something else ... TBD
// See this discussion: https://github.com/ElektraInitiative/libelektra/issues/4499
return true;
}

/**
* Initializes the hooks stored in the passed KDB handle.
* If the handle already contains initialized hooks, they will be reinitialized, including unloading and loading of their plugins.
Expand Down Expand Up @@ -169,6 +206,12 @@ int initHooks (KDB * kdb, const KeySet * config, KeySet * modules, const KeySet
goto error;
}

if (isSpecEnabledByConfig (config) &&
initHooksSpec (kdb, loadPlugin ("spec", kdb->global, modules, contract, errorKey), errorKey) != 0)
{
goto error;
}

if (!existingError)
{
// remove dummy error again
Expand Down
53 changes: 42 additions & 11 deletions src/libs/elektra/kdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1865,28 +1865,30 @@ int kdbGet (KDB * handle, KeySet * ks, Key * parentKey)
goto error;
}

/* TODO (kodebach): implement actual steps with new global plugins
// Step 14: run spec plugin
if (!specGet (dataKs, cascadingParent))
{
clear_bit (parentKey->flags, KEY_LOCK_NAME | KEY_LOCK_VALUE);
goto error;
}
clear_bit (parentKey->flags, KEY_LOCK_NAME | KEY_LOCK_VALUE);
*/

// Step 13: run gopts (if enabled)
keyCopy (parentKey, initialParent, KEY_CP_NAME);
keySetNamespace (parentKey, KEY_NS_CASCADING);

if (goptsActive && !handle->hooks.gopts.kdbHookGoptsGet (handle->hooks.gopts.plugin, dataKs, parentKey))
if (goptsActive && !handle->hooks.gopts.get (handle->hooks.gopts.plugin, dataKs, parentKey))
{
clear_bit (parentKey->flags, KEY_LOCK_NAME | KEY_LOCK_VALUE);
goto error;
}

keySetNamespace (parentKey, keyGetNamespace (initialParent));

// Step 14: run spec plugin
if (handle->hooks.spec.plugin && handle->hooks.spec.copy (handle->hooks.spec.plugin, dataKs, parentKey, true) == -1)
{
clear_bit (parentKey->flags, KEY_LOCK_NAME | KEY_LOCK_VALUE);
goto error;
}
clear_bit (parentKey->flags, KEY_LOCK_NAME | KEY_LOCK_VALUE);

// TODO (atmaxinger): should we have a default:/ backend?
Key * defaultCutpoint = keyNew ("default:/", KEY_END);
KeySet * defaults = ksCut (dataKs, defaultCutpoint);

// Step 15: split dataKs for poststorage phase
// FIXME (kodebach): handle proc:/ keys
if (!backendsDivide (backends, dataKs))
Expand Down Expand Up @@ -1917,6 +1919,11 @@ int kdbGet (KDB * handle, KeySet * ks, Key * parentKey)
// Step 18: merge data into ks and return
backendsMerge (backends, ks);

// TODO (atmaxinger): should we have a default:/ backend?
ksAppend (ks, defaults);
ksDel (defaults);
keyDel (defaultCutpoint);

// Step 19: update cache
// FIXME (kodebach): implement cache

Expand Down Expand Up @@ -2320,6 +2327,11 @@ int kdbSet (KDB * handle, KeySet * ks, Key * parentKey)
goto error;
}

if (handle->hooks.spec.plugin && handle->hooks.spec.copy (handle->hooks.spec.plugin, ks, parentKey, false) == -1)
{
goto error;
}

// TODO (kodebach) [opt]: merge steps 4-6
// By merging steps 4-6, we MAY be able to avoid copying keys from unchanged and read-only backends.

Expand Down Expand Up @@ -2407,6 +2419,25 @@ int kdbSet (KDB * handle, KeySet * ks, Key * parentKey)
}
*/

// Step 8: merge data from all backends (for spec removal)
ksClear (setKs);
backendsMerge (backends, setKs);

// Step 9: run the spec plugin to remove copied metadata
if (handle->hooks.spec.plugin && handle->hooks.spec.remove (handle->hooks.spec.plugin, setKs, parentKey) == -1)
{
goto rollback;
}

// Step 10: split setKs for remaining phases
if (!backendsDivide (backends, setKs))
{
ELEKTRA_SET_INTERNAL_ERROR (parentKey,
"Couldn't divide keys into mountpoints after spec removal. Please report this bug at "
"https://issues.libelektra.org.");
goto rollback;
}

// Step 11a: run storage phase
if (!runSetPhase (backends, parentKey, KDB_SET_PHASE_STORAGE, false, KDB_SET_FN_SET))
{
Expand Down
1 change: 0 additions & 1 deletion src/plugins/spec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
- infos/licence = BSD
- infos/needs =
- infos/provides = check apply
- infos/placements = postgetstorage presetstorage
- infos/status = recommended productive nodep configurable global unfinished
- infos/description = allows to give specifications for keys

Expand Down
Loading

0 comments on commit 9a830e5

Please sign in to comment.