static void test_mount()
{
	printf ("test mount backend\n");

	KDB *kdb = kdb_new();
	elektraMountBackend (kdb, b_new("user", "user"), 0);
	succeed_if (kdb->trie, "there should be a trie");

	Key *mp = keyNew ("user", KEY_VALUE, "user", KEY_END);
	Key *sk = keyNew ("user", KEY_VALUE, "user", KEY_END);

	succeed_if (kdb->split->size == 1, "size of split not correct");
	compare_key(mp, kdb->split->parents[0]);

	compare_key(elektraMountGetBackend (kdb, sk)->mountpoint, mp);
	compare_key(elektraMountGetMountpoint (kdb, sk), mp);

	keySetName (sk, "user/below");
	compare_key(elektraMountGetBackend (kdb, sk)->mountpoint, mp);
	compare_key(elektraMountGetMountpoint (kdb, sk), mp);

	keySetName (sk, "system");
	kdb->defaultBackend = b_new("", "default");
	succeed_if (elektraMountGetBackend (kdb, sk) == kdb->defaultBackend, "did not return default backend");

	keySetName (mp, "");
	keySetString (mp, "default");
	compare_key(elektraMountGetBackend (kdb, sk)->mountpoint, mp);
	compare_key(elektraMountGetMountpoint (kdb, sk), mp);

	keyDel (sk);
	keyDel (mp);

	kdb_del (kdb);
}
Example #2
0
/**
 * Appoints all keys from ks to yet unsynced splits.
 *
 * @pre elektraSplitBuildup() need to be executed before.
 *
 * @param split the split object to work with
 * @param handle to determine to which backend a key belongs
 * @param ks the keyset to appoint to split
 *
 * @retval 1 on success
 * @retval -1 if no backend was found for a key
 * @ingroup split
 */
int elektraSplitAppoint (Split * split, KDB * handle, KeySet * ks)
{
	ssize_t curFound = 0; /* If key could be appended to any of the existing split keysets */
	Key * curKey = 0;
	Backend * curHandle = 0;
	ssize_t defFound = elektraSplitAppend (split, 0, 0, 0);

	ksRewind (ks);
	while ((curKey = ksNext (ks)) != 0)
	{
		curHandle = elektraMountGetBackend (handle, curKey);
		if (!curHandle) return -1;

		curFound = elektraSplitSearchBackend (split, curHandle, curKey);

		if (curFound == -1) curFound = defFound;

		if (split->syncbits[curFound] & SPLIT_FLAG_SYNC)
		{
			continue;
		}

		ksAppendKey (split->keysets[curFound], curKey);
	}

	return 1;
}
Example #3
0
/**
 * Splits up the keysets and search for a sync bit in every key.
 *
 * It does not check if there were removed keys,
 * see elektraSplitSync() for the next step.
 *
 * It does not create new backends, this has to be
 * done by buildup before.
 *
 * @pre elektraSplitBuildup() need to be executed before.
 *
 * @param split the split object to work with
 * @param handle to get information where the individual keys belong
 * @param ks the keyset to divide
 *
 * @retval 0 if there were no sync bits
 * @retval 1 if there were sync bits
 * @retval -1 if no backend was found for any key
 * @ingroup split
 */
int elektraSplitDivide (Split * split, KDB * handle, KeySet * ks)
{
	ssize_t curFound = 0; /* If key could be appended to any of the existing split keysets */
	int needsSync = 0;
	Key * curKey = 0;
	Backend * curHandle = 0;

	ksRewind (ks);
	while ((curKey = ksNext (ks)) != 0)
	{
		// TODO: handle keys in wrong namespaces
		curHandle = elektraMountGetBackend (handle, curKey);
		if (!curHandle) return -1;

		curFound = elektraSplitSearchBackend (split, curHandle, curKey);

		if (curFound == -1) continue; // key not relevant in this kdbSet

		ksAppendKey (split->keysets[curFound], curKey);
		if (keyNeedSync (curKey) == 1)
		{
			split->syncbits[curFound] |= 1;
			needsSync = 1;
		}
	}

	return needsSync;
}
Example #4
0
/**
 * @brief Filter out keys not in the correct keyset
 *
 * @param split the split where to do it
 * @param i for which split
 * @param warningKey the key
 * @param handle where to do backend lookups
 *
 * @retval -1 on error (no backend, wrong namespace)
 * @retval 0 otherwise
 */
static int elektraSplitPostprocess (Split * split, int i, Key * warningKey, KDB * handle)
{
	Key * cur = 0;
	Backend * curHandle = 0;
	ksRewind (split->keysets[i]);
	while ((cur = ksNext (split->keysets[i])) != 0)
	{
		curHandle = elektraMountGetBackend (handle, cur);
		if (!curHandle) return -1;

		keyClearSync (cur);

		if (curHandle != split->handles[i])
		{
			elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is hidden by other mountpoint");
		}
		else
			switch (keyGetNamespace (cur))
			{
			case KEY_NS_SPEC:
				if (!keyIsSpec (split->parents[i]))
					elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not spec");
				break;
			case KEY_NS_DIR:
				if (!keyIsDir (split->parents[i]))
					elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not dir");
				break;
			case KEY_NS_USER:
				if (!keyIsUser (split->parents[i]))
					elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not user");
				break;
			case KEY_NS_SYSTEM:
				if (!keyIsSystem (split->parents[i]))
					elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not system");
				break;
			case KEY_NS_PROC:
				elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has a proc key name");
				break;
			case KEY_NS_EMPTY:
				elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has an empty name");
				break;
			case KEY_NS_META:
				elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has a meta name");
				break;
			case KEY_NS_CASCADING:
				elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has a cascading name");
				break;
			case KEY_NS_NONE:
				ELEKTRA_ASSERT (0 && "wrong key namespace, should not be none");
				return -1;
			}
	}
	return 0;
}
Example #5
0
/**
 * @brief Update the (configuration) file name for the parent key
 *
 * @param split the split to work with
 * @param handle the handle to work with
 * @param key the parentKey that should be updated (name must be
 * correct)
 */
void elektraSplitUpdateFileName (Split * split, KDB * handle, Key * key)
{
	Backend * curHandle = elektraMountGetBackend (handle, key);
	if (!curHandle) return;
	ssize_t curFound = elektraSplitSearchBackend (split, curHandle, key);
	if (curFound == -1) return;
#if DEBUG && VERBOSE
	printf ("Update string from %s to %s\n", keyString (key), keyString (split->parents[curFound]));
	printf ("Names are: %s and %s\n\n", keyName (key), keyName (split->parents[curFound]));
#endif
	keySetString (key, keyString (split->parents[curFound]));
}
Example #6
0
/**
 * 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.
 *
 * @pre split needs to be empty, directly after creation with elektraSplitNew().
 *
 * @pre there needs to be a valid defaultBackend
 *      but its ok not to have a trie inside KDB.
 *
 * @pre parentKey must be a valid key! (could be implemented more generally,
 *      but that would require splitting up of keysets of the same backend)
 *
 * @param split will get all backends appended
 * @param kdb the handle to get information about backends
 * @param parentKey the information below which key the backends are from interest
 * @ingroup split
 * @retval 1 always
 */
int elektraSplitBuildup (Split * split, KDB * kdb, Key * parentKey)
{
	/* For compatibility reasons invalid names are accepted, too.
	 * This solution is faster than checking the name of parentKey
	 * every time in loop.
	 * The parentKey might be null in some unit tests, so also check
	 * for this. */
	const char * name = keyName (parentKey);
	if (!parentKey || !name || !strcmp (name, "") || !strcmp (name, "/"))
	{
		parentKey = 0;
	}
	else if (name[0] == '/')
	{
		Key * key = keyNew (0, KEY_END);
		for (elektraNamespace ins = KEY_NS_FIRST; ins <= KEY_NS_LAST; ++ins)
		{
			if (!elektraKeySetNameByNamespace (key, ins)) continue;
			keyAddName (key, keyName (parentKey));
			elektraSplitBuildup (split, kdb, key);
		}
		keyDel (key);
		return 1;
	}

	/* Returns the backend the key is in or the default backend
	   otherwise */
	Backend * backend = elektraMountGetBackend (kdb, parentKey);

#if DEBUG && VERBOSE
	printf (" with parent %s\n", keyName (parentKey));
#endif
	for (size_t i = 0; i < kdb->split->size; ++i)
	{
#if DEBUG && VERBOSE
		printf ("  %zu with parent %s\n", i, keyName (kdb->split->parents[i]));
#endif
		if (!parentKey)
		{
#if DEBUG && VERBOSE
			printf ("   def add %s\n", keyName (kdb->split->parents[i]));
#endif
			/* Catch all: add all mountpoints */
			elektraSplitAppend (split, kdb->split->handles[i], keyDup (kdb->split->parents[i]), kdb->split->syncbits[i]);
		}
		else if (backend == kdb->split->handles[i] && keyRel (kdb->split->parents[i], parentKey) >= 0)
		{
#if DEBUG && VERBOSE
			printf ("   exa add %s\n", keyName (kdb->split->parents[i]));
#endif
			/* parentKey is exactly in this backend, so add it! */
			elektraSplitAppend (split, kdb->split->handles[i], keyDup (kdb->split->parents[i]), kdb->split->syncbits[i]);
		}
		else if (keyRel (parentKey, kdb->split->parents[i]) >= 0)
		{
#if DEBUG && VERBOSE
			printf ("   rel add %s\n", keyName (kdb->split->parents[i]));
#endif
			/* this backend is completely below the parentKey, so lets add it. */
			elektraSplitAppend (split, kdb->split->handles[i], keyDup (kdb->split->parents[i]), kdb->split->syncbits[i]);
		}
	}

	return 1;
}