[master] merge dyndb
4224. [func] Added support for "dyndb", a new interface for loading zone data from an external database, developed by Red Hat for the FreeIPA project. DynDB drivers fully implement the BIND database API, and are capable of significantly better performance and functionality than DLZ drivers, while taking advantage of advanced database features not available in BIND such as multi-master replication. Thanks to Adam Tkac and Petr Spacek of Red Hat. [RT #35271]
This commit is contained in:
138
bin/tests/system/dyndb/driver/driver.c
Normal file
138
bin/tests/system/dyndb/driver/driver.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Driver API implementation and main entry point for BIND.
|
||||
*
|
||||
* BIND calls dyndb_version() before loading, dyndb_init() during startup
|
||||
* and dyndb_destroy() during shutdown.
|
||||
*
|
||||
* It is completely up to implementation what to do.
|
||||
*
|
||||
* dyndb <name> <driver> {} sections in named.conf are independent so
|
||||
* driver init() and destroy() functions are called independently for
|
||||
* each section even if they reference the same driver/library. It is
|
||||
* up to driver implementation to detect and catch this situation if
|
||||
* it is undesirable.
|
||||
*
|
||||
* Copyright (C) 2009-2015 Red Hat ; see COPYRIGHT for license
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/commandline.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/lib.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/db.h>
|
||||
#include <dns/dyndb.h>
|
||||
#include <dns/lib.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#include "db.h"
|
||||
#include "log.h"
|
||||
#include "instance.h"
|
||||
#include "util.h"
|
||||
|
||||
dns_dyndb_destroy_t dyndb_destroy;
|
||||
dns_dyndb_register_t dyndb_init;
|
||||
dns_dyndb_version_t dyndb_version;
|
||||
|
||||
/*
|
||||
* Driver init is called for each dyndb section in named.conf
|
||||
* once during startup and then again on every reload.
|
||||
*
|
||||
* @code
|
||||
* dyndb example-name "sample.so" { param1 param2 };
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] name User-defined string from dyndb "name" {}; definition
|
||||
* in named.conf.
|
||||
* The example above will have name = "example-name".
|
||||
* @param[in] argc Number of arg parameters
|
||||
* definition. The example above will have
|
||||
* argc = 2;
|
||||
* @param[in] argv User-defined strings from arg parameters in dyndb
|
||||
* definition. The example above will have
|
||||
* argv[0] = "param1";
|
||||
* argv[1] = "param2";
|
||||
* @param[out] instp Pointer to instance-specific data (for one dyndb section).
|
||||
*/
|
||||
isc_result_t
|
||||
dyndb_init(isc_mem_t *mctx, const char *name, const char *parameters,
|
||||
const dns_dyndbctx_t *dctx, void **instp)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned int argc;
|
||||
char **argv = NULL;
|
||||
char *s = NULL;
|
||||
sample_instance_t *sample_inst = NULL;
|
||||
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(dctx != NULL);
|
||||
|
||||
/*
|
||||
* Depending on how dlopen() was called, we may not have
|
||||
* access to named's global namespace, in which case we need
|
||||
* to initialize libisc/libdns
|
||||
*/
|
||||
if (dctx->refvar != &isc_bind9) {
|
||||
isc_lib_register();
|
||||
isc_log_setcontext(dctx->lctx);
|
||||
dns_log_setcontext(dctx->lctx);
|
||||
}
|
||||
|
||||
if (isc_hashctx != NULL && isc_hashctx != dctx->hctx)
|
||||
isc_hash_ctxdetach(&isc_hashctx);
|
||||
isc_hashctx = dctx->hctx;
|
||||
|
||||
s = isc_mem_strdup(mctx, parameters);
|
||||
if (s == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = isc_commandline_strtoargv(mctx, s, &argc, &argv, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
/* Finally, create the instance. */
|
||||
CHECK(new_sample_instance(mctx, name, argc, argv, dctx, &sample_inst));
|
||||
|
||||
/*
|
||||
* This is an example so we create and load zones
|
||||
* right now. This step can be arbitrarily postponed.
|
||||
*/
|
||||
CHECK(load_sample_instance_zones(sample_inst));
|
||||
|
||||
*instp = sample_inst;
|
||||
|
||||
cleanup:
|
||||
if (s != NULL)
|
||||
isc_mem_free(mctx, s);
|
||||
if (argv != NULL)
|
||||
isc_mem_put(mctx, argv, argc * sizeof(*argv));
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Driver destroy is called for every instance on every reload and then once
|
||||
* during shutdown.
|
||||
*
|
||||
* @param[out] instp Pointer to instance-specific data (for one dyndb section).
|
||||
*/
|
||||
void
|
||||
dyndb_destroy(void **instp) {
|
||||
destroy_sample_instance((sample_instance_t **)instp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Driver version is called when loading the driver to ensure there
|
||||
* is no API mismatch betwen the driver and the caller.
|
||||
*/
|
||||
int
|
||||
dyndb_version(unsigned int *flags) {
|
||||
UNUSED(flags);
|
||||
|
||||
return (DNS_DYNDB_VERSION);
|
||||
}
|
||||
Reference in New Issue
Block a user