Commit b37a6f24 authored by Vitezslav Kriz's avatar Vitezslav Kriz

semcheck: error handler callback

parent e62d73c6
......@@ -323,11 +323,9 @@ static int axfr_answer_finalize(struct answer_data *adata)
return rc;
}
err_handler_t handler;
err_handler_init(&handler);
rc = zone_do_sem_checks(proc->contents, false, &handler);
err_handler_log_errors(&handler);
err_handler_deinit(&handler);
err_handler_logger_t handler;
handler._cb.cb = err_handler_logger;
rc = zone_do_sem_checks(proc->contents, false, &handler._cb);
if (rc != KNOT_EOK) {
return rc;
......
......@@ -23,6 +23,7 @@
#include "knot/updates/apply.h"
#include "knot/zone/serial.h"
#include "knot/zone/semantic-check.h"
#include "knot/zone/zonefile.h"
#include "libknot/libknot.h"
#include "contrib/mempattern.h"
#include "contrib/print.h"
......@@ -389,11 +390,9 @@ static int ixfrin_finalize(struct answer_data *adata)
return ret;
}
err_handler_t handler;
err_handler_init(&handler);
ret = zone_do_sem_checks(new_contents, false, &handler);
err_handler_log_errors(&handler);
err_handler_deinit(&handler);
err_handler_logger_t handler;
handler._cb.cb = err_handler_logger;
ret = zone_do_sem_checks(new_contents, false, &handler._cb);
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_WARNING, "failed to apply changes to zone (%s)",
......
This diff is collapsed.
......@@ -86,78 +86,31 @@ enum zonechecks_errors {
ZC_ERR_GLUE_RECORD,
ZC_ERR_GLUE_GENERAL_ERROR, /* GLUE error delimiter. */
ZC_ERR_LAST = ZC_ERR_GLUE_GENERAL_ERROR,
ZC_ERR_LAST,
};
extern const char *zonechecks_error_messages[];
const char *semantic_check_error_msg(int ecode);
/*!
* \brief Structure for handling semantic errors.
*/
struct err_handler {
/* Consider moving error messages here */
unsigned errors[(-ZC_ERR_UNKNOWN) + 1]; /*!< Counting errors by type */
unsigned error_count; /*!< Total error count */
list_t error_list; /*!< List of all errors */
};
typedef struct err_handler err_handler_t;
typedef struct err_node {
node_t node; ///< must be first
int error;
char *zone_name;
char *name;
char *data;
} err_node_t;
/*!
* \brief Inits semantic error handler. No optional events will be logged.
*
* \param handler Variable to be initialized.
*/
void err_handler_init(err_handler_t *err_handler);
/*!
* \brief Free all allocated memory and deinit error handler.
* \brief Callback for handle error.
*
* \param handler Handler to be freed
* Return KNOT_EOK to continue in semantic checks.
* Return other KNOT_E* to stop semantic check with error.
*/
void err_handler_deinit(err_handler_t *h);
typedef int (*error_cb) (err_handler_t *ctx, const zone_contents_t *zone,
const zone_node_t *node, int error, const char *data);
/*!
* \brief Called when error has been encountered in node. Will save error to
* list for future possibility to log it.
*
* \param handler Error handler.
* \param zone Zone content which is being checked.
* \param node Node with semantic error in it.
* \param error Type of error.
* \param data Additional info in string.
*
* \retval KNOT_EOK on success.
* \retval KNOT_ENOMEM if memory error.
*/
int err_handler_node_error(err_handler_t *handler,
const zone_contents_t *zone,
const zone_node_t *node,
int error, const char *data);
struct err_handler {
error_cb cb;
};
/*!
* \brief Called when error has been encountered for entire zone.
*
* Will save error to list for future possibility to log it.
*
* \param handler Error handler.
* \param zname Zone name
* \param error Type of error.
*
* \retval KNOT_EOK on success.
* \retval KNOT_ENOMEM if memory error.
*/
int err_handler_zone_error(err_handler_t *handler, const knot_dname_t *zname,
int error);
/*!
* \brief Check zone for semantic errors.
......@@ -174,11 +127,4 @@ int err_handler_zone_error(err_handler_t *handler, const knot_dname_t *zname,
int zone_do_sem_checks(zone_contents_t *zone, bool optional,
err_handler_t *handler);
/*!
* \brief Log all found errors using standard knot log.
*
* \param handler Error handler
*/
void err_handler_log_errors(err_handler_t *handler);
/*! @} */
......@@ -34,6 +34,12 @@ int zone_load_contents(conf_t *conf, const knot_dname_t *zone_name,
char *zonefile = conf_zonefile(conf, zone_name);
conf_val_t val = conf_zone_get(conf, C_SEM_CHECKS, zone_name);
int ret = zonefile_open(&zl, zonefile, zone_name, conf_bool(&val));
err_handler_logger_t handler;
memset(&handler, 0, sizeof(handler));
handler._cb.cb = err_handler_logger;
zl.err_handler = (err_handler_t *) &handler;
free(zonefile);
if (ret != KNOT_EOK) {
return ret;
......@@ -46,8 +52,6 @@ int zone_load_contents(conf_t *conf, const knot_dname_t *zone_name,
*contents = zonefile_load(&zl);
err_handler_log_errors(&zl.err_handler);
zonefile_close(&zl);
if (*contents == NULL) {
return KNOT_ERROR;
......
......@@ -173,7 +173,6 @@ int zonefile_open(zloader_t *loader, const char *source,
}
memset(loader, 0, sizeof(zloader_t));
err_handler_init(&loader->err_handler);
/* Check zone file. */
if (access(source, F_OK | R_OK) != 0) {
......@@ -254,7 +253,7 @@ zone_contents_t *zonefile_load(zloader_t *loader)
}
if (!node_rrtype_exists(loader->creator->z->apex, KNOT_RRTYPE_SOA)) {
err_handler_zone_error(&loader->err_handler, zname, ZC_ERR_MISSING_SOA);
loader->err_handler->cb(loader->err_handler, zc->z, NULL, ZC_ERR_MISSING_SOA, NULL);
goto fail;
}
......@@ -266,7 +265,7 @@ zone_contents_t *zonefile_load(zloader_t *loader)
}
ret = zone_do_sem_checks(zc->z, loader->semantic_checks,
&loader->err_handler);
loader->err_handler);
INFO(zname, "semantic check, completed");
if (ret != KNOT_EOK) {
......@@ -397,7 +396,31 @@ void zonefile_close(zloader_t *loader)
zs_deinit(&loader->scanner);
free(loader->source);
free(loader->creator);
err_handler_deinit(&loader->err_handler);
}
int err_handler_logger(err_handler_t *handler, const zone_contents_t *zone,
const zone_node_t *node, int error, const char *data)
{
assert(handler != NULL);
assert(zone != NULL);
err_handler_logger_t *h = (err_handler_logger_t *) handler;
const char *errmsg = semantic_check_error_msg(error);
if (node == NULL) { // zone error
log_zone_warning(zone->apex->owner, "semantic check, (%s%s%s)",
errmsg, data ? " " : "", data ? data : "");
} else {
char buff[KNOT_DNAME_TXT_MAXLEN + 1];
char *name = knot_dname_to_str(buff, node->owner, sizeof(buff));
log_zone_warning(zone->apex->owner,
"semantic check, node '%s' (%s%s%s)",
name ? name : "", errmsg, data ? " " : "",
data ? data : "");
}
h->error_count++;
return KNOT_EOK;
}
#undef ERROR
......
......@@ -43,11 +43,20 @@ typedef struct zcreator {
typedef struct zloader {
char *source; /*!< Zone source file. */
bool semantic_checks; /*!< Do semantic checks. */
err_handler_t err_handler; /*!< Semantic checks error handler. */
err_handler_t *err_handler; /*!< Semantic checks error handler. */
zcreator_t *creator; /*!< Loader context. */
zs_scanner_t scanner; /*!< Zone scanner. */
} zloader_t;
typedef struct {
err_handler_t _cb;
unsigned error_count; /*!< Error count for limitng output. */
} err_handler_logger_t;
int err_handler_logger(err_handler_t *handler, const zone_contents_t *zone,
const zone_node_t *node, int error, const char *data);
/*!
* \brief Open zone file for loading.
*
......
......@@ -15,38 +15,55 @@
*/
#include <stdio.h>
#include <assert.h>
#include "knot/zone/contents.h"
#include "knot/zone/zonefile.h"
#include "contrib/ucw/lists.h"
#include "utils/kzonecheck/zone_check.h"
static void print_errors(err_handler_t *handler, FILE *outfile)
typedef struct {
err_handler_t _cb;
FILE *outfile;
unsigned errors[(-ZC_ERR_UNKNOWN) + 1]; /*!< Counting errors by type */
unsigned error_count; /*!< Total error count */
} err_handler_stats_t;
int err_handler_printf(err_handler_t *handler, const zone_contents_t *zone,
const zone_node_t *node, int error, const char *data)
{
err_node_t *n;
WALK_LIST(n, handler->error_list) {
if (n->error > (int)ZC_ERR_GLUE_RECORD) {
fprintf(outfile, "zone: [%s], semantic check, unknown error\n",
n->zone_name ? n->zone_name : "?");
return;
}
assert(handler != NULL);
assert(zone != NULL);
err_handler_stats_t *h = (err_handler_stats_t *)handler;
char buff[KNOT_DNAME_TXT_MAXLEN + 1];
const char *errmsg = semantic_check_error_msg(error);
if (node == NULL) { // zone error
char *zone_name = knot_dname_to_str(buff, zone->apex->owner, sizeof(buff));
fprintf(h->outfile, "zone: [%s], semantic check, (%s%s%s)\n",
zone_name ? zone_name : "?", errmsg,
data ? " " : "", data ? data : "");
} else {
char *name = knot_dname_to_str(buff, node->owner, sizeof(buff));
fprintf(h->outfile, "node: '%s' (%s%s%s)\n", name ? name : "",
errmsg, data ? " " : "", data ? data : "");
}
const char *errmsg = zonechecks_error_messages[-n->error];
h->errors[-error]++;
h->error_count++;
fprintf(outfile ,"node: '%s' (%s%s%s)\n",
n->name ? n->name : "?",
errmsg ? errmsg : "unknown error",
n->data ? " " : "",
n->data ? n->data : "");
}
return KNOT_EOK;
}
static void print_statistics(err_handler_t *handler, FILE *outfile)
static void print_statistics(err_handler_stats_t *handler)
{
fprintf(outfile, "\nERRORS SUMMARY:\n\tCount\tError\n");
err_handler_stats_t *h = (err_handler_stats_t *)handler;
fprintf(h->outfile, "\nERRORS SUMMARY:\n\tCount\tError\n");
for(int i = ZC_ERR_UNKNOWN; i < ZC_ERR_LAST; ++i) {
if (handler->errors[-i] > 0) {
fprintf(outfile, "\t%u\t%s\n", handler->errors[-i], zonechecks_error_messages[-i]);
if (h->errors[-i] > 0) {
fprintf(h->outfile, "\t%u\t%s\n", h->errors[-i],
semantic_check_error_msg(i));
}
}
}
......@@ -60,15 +77,20 @@ int zone_check(const char *zone_file, const knot_dname_t *zone_name,
return ret;
}
err_handler_stats_t handler;
memset(&handler, 0, sizeof(handler));
handler._cb.cb = err_handler_printf;
handler.outfile = outfile;
zl.err_handler = (err_handler_t *)&handler;
zl.creator->master = true;
zone_contents_t *contents;
contents = zonefile_load(&zl);
if (zl.err_handler.error_count > 0) {
if (handler.error_count > 0) {
ret = KNOT_ESEMCHECK;
print_errors(&zl.err_handler, outfile);
print_statistics(&zl.err_handler, outfile);
print_statistics(&handler);
}
zonefile_close(&zl);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment