Commit 808d007a authored by Jan Včelák's avatar Jan Včelák 🚀

logging: clean and consistent messages for zones

parent fd3993e1
......@@ -207,7 +207,7 @@ int xfr_process_list(knot_pkt_t *pkt, xfr_put_cb process_item,
/* AXFR-specific logging (internal, expects 'qdata' variable set). */
#define AXFROUT_LOG(severity, msg...) \
QUERY_LOG(severity, qdata, "Outgoing AXFR", msg)
QUERY_LOG(severity, qdata, "AXFR, outgoing", msg)
int axfr_query_process(knot_pkt_t *pkt, struct query_data *qdata)
{
......@@ -229,11 +229,11 @@ int axfr_query_process(knot_pkt_t *pkt, struct query_data *qdata)
ret = axfr_query_init(qdata);
if (ret != KNOT_EOK) {
AXFROUT_LOG(LOG_ERR, "Failed to start (%s).",
AXFROUT_LOG(LOG_ERR, "failed to start (%s)",
knot_strerror(ret));
return NS_PROC_FAIL;
} else {
AXFROUT_LOG(LOG_INFO, "Started (serial %u).",
AXFROUT_LOG(LOG_INFO, "started, serial %u",
zone_contents_serial(qdata->zone->contents));
}
}
......@@ -249,14 +249,13 @@ int axfr_query_process(knot_pkt_t *pkt, struct query_data *qdata)
return NS_PROC_FULL; /* Check for more. */
case KNOT_EOK: /* Last response. */
gettimeofday(&now, NULL);
AXFROUT_LOG(LOG_INFO, "Finished in %.02fs (%u messages, "
"%s%.*f %s).",
AXFROUT_LOG(LOG_INFO, "finished, %.02fs, %u messages, " SIZE_FORMAT,
time_diff(&axfr->proc.tstamp, &now) / 1000.0,
axfr->proc.npkts, SIZE_PARAMS(axfr->proc.nbytes));
return NS_PROC_DONE;
break;
default: /* Generic error. */
AXFROUT_LOG(LOG_ERR, "%s", knot_strerror(ret));
AXFROUT_LOG(LOG_ERR, "failed (%s)", knot_strerror(ret));
return NS_PROC_FAIL;
}
}
......@@ -305,7 +304,7 @@ static int axfr_answer_init(struct answer_data *data)
/* AXFR-specific logging (internal, expects 'adata' variable set). */
#define AXFRIN_LOG(priority, msg...) \
ANSWER_LOG(priority, adata, "Incoming AXFR", msg)
ANSWER_LOG(priority, adata, "AXFR, incoming", msg)
static int axfr_answer_finalize(struct answer_data *adata)
{
......@@ -327,11 +326,11 @@ static int axfr_answer_finalize(struct answer_data *adata)
zone_contents_t *old_contents =
zone_switch_contents(zone, proc->contents);
synchronize_rcu();
AXFRIN_LOG(LOG_INFO, "Serial %u -> %u",
zone_contents_serial(old_contents),
zone_contents_serial(proc->contents));
AXFRIN_LOG(LOG_INFO, "Finished in %.02fs (%u messages, %s%.*f %s)",
AXFRIN_LOG(LOG_INFO, "finished, "
"serial %u -> %u, %.02fs, %u messages, " SIZE_FORMAT,
zone_contents_serial(old_contents),
zone_contents_serial(proc->contents),
time_diff(&proc->tstamp, &now) / 1000.0,
proc->npkts, SIZE_PARAMS(proc->nbytes));
......@@ -382,7 +381,7 @@ int axfr_answer_process(knot_pkt_t *pkt, struct answer_data *adata)
if (rcode != KNOT_RCODE_NOERROR) {
knot_lookup_table_t *lut = knot_lookup_by_id(knot_rcode_names, rcode);
if (lut != NULL) {
AXFRIN_LOG(LOG_ERR, "Server responded with %s.", lut->name);
AXFRIN_LOG(LOG_ERR, "server responded with %s", lut->name);
}
return NS_PROC_FAIL;
}
......@@ -391,14 +390,14 @@ int axfr_answer_process(knot_pkt_t *pkt, struct answer_data *adata)
if (adata->ext == NULL) {
NS_NEED_TSIG_SIGNED(&adata->param->tsig_ctx, 0);
if (!zone_transfer_needed(adata->param->zone, pkt)) {
AXFRIN_LOG(LOG_INFO, "Zone is up-to-date.");
AXFRIN_LOG(LOG_INFO, "zone is up-to-date");
return NS_PROC_DONE;
}
AXFRIN_LOG(LOG_INFO, "Starting.");
AXFRIN_LOG(LOG_INFO, "starting");
int ret = axfr_answer_init(adata);
if (ret != KNOT_EOK) {
AXFRIN_LOG(LOG_ERR, "%s", knot_strerror(ret));
AXFRIN_LOG(LOG_ERR, "failed (%s)", knot_strerror(ret));
return NS_PROC_FAIL;
}
} else {
......
......@@ -33,6 +33,7 @@ struct query_data;
struct answer_data;
/*! \brief This macro helps with data size formatting during xfr logging. */
#define SIZE_FORMAT "%s%.*f %s"
#define SIZE_PARAMS(value) (value) < 1024 ? "" : "~", \
(value) < 1024 ? 0 : 1, \
(value) < 1024 ? (float)(value) : (value) / 1024.0, \
......
......@@ -935,12 +935,12 @@ static int process_soa_answer(knot_pkt_t *pkt, struct answer_data *data)
uint32_t our_serial = knot_soa_serial(soa);
uint32_t their_serial = knot_soa_serial(&answer->rr[0].rrs);
if (knot_serial_compare(our_serial, their_serial) >= 0) {
ANSWER_LOG(LOG_INFO, data, "Refresh", "Zone is up-to-date.");
ANSWER_LOG(LOG_INFO, data, "refresh, outgoing", "zone is up-to-date");
return NS_PROC_DONE; /* Our zone is up to date. */
}
/* Our zone is outdated, schedule zone transfer. */
ANSWER_LOG(LOG_INFO, data, "Refresh", "master has newer serial %u -> %u.",
ANSWER_LOG(LOG_INFO, data, "refresh, outgoing", "master has newer serial %u -> %u",
our_serial, their_serial);
zone_events_schedule(zone, ZONE_EVENT_XFER, ZONE_EVENT_NOW);
return NS_PROC_DONE;
......
......@@ -36,7 +36,7 @@ struct ixfr_proc {
/* IXFR-out-specific logging (internal, expects 'qdata' variable set). */
#define IXFROUT_LOG(severity, msg...) \
QUERY_LOG(severity, qdata, "Outgoing IXFR", msg)
QUERY_LOG(severity, qdata, "IXFR, outgoing", msg)
/*! \brief Helper macro for putting RRs into packet. */
#define IXFR_SAFE_PUT(pkt, rr) \
......@@ -126,7 +126,7 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item,
struct query_data *qdata = ixfr->qdata; /*< Required for IXFROUT_LOG() */
const uint32_t serial_from = knot_soa_serial(&chgset->soa_from->rrs);
const uint32_t serial_to = knot_soa_serial(&chgset->soa_to->rrs);
IXFROUT_LOG(LOG_INFO, "Serial %u -> %u.", serial_from, serial_to);
IXFROUT_LOG(LOG_INFO, "serial %u -> %u", serial_from, serial_to);
return ret;
}
......@@ -290,7 +290,7 @@ static int ixfr_answer_soa(knot_pkt_t *pkt, struct query_data *qdata)
/* IXFR-in-specific logging (internal, expects 'adata' variable set). */
#define IXFRIN_LOG(severity, msg...) \
ANSWER_LOG(severity, adata, "Incoming IXFR", msg)
ANSWER_LOG(severity, adata, "IXFR, incoming", msg)
/*! \brief Cleans up data allocated by IXFR-in processing. */
static void ixfrin_cleanup(struct answer_data *data)
......@@ -337,14 +337,14 @@ static int ixfrin_finalize(struct answer_data *adata)
int ret = zone_change_apply_and_store(&ixfr->changesets,
ixfr->zone, "IXFR", adata->mm);
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_ERR, "Failed to apply changes to zone - %s",
IXFRIN_LOG(LOG_ERR, "failed to apply changes to zone (%s)",
knot_strerror(ret));
return ret;
}
struct timeval now = {0};
gettimeofday(&now, NULL);
IXFRIN_LOG(LOG_INFO, "Finished in %.02fs (%u messages, %s%.*f %s).",
IXFRIN_LOG(LOG_INFO, "finished, %.02fs, %u messages, " SIZE_FORMAT,
time_diff(&ixfr->proc.tstamp, &now) / 1000.0,
ixfr->proc.npkts, SIZE_PARAMS(ixfr->proc.nbytes));
......@@ -533,7 +533,7 @@ static int process_ixfrin_packet(knot_pkt_t *pkt, struct answer_data *adata)
const knot_pktsection_t *answer = knot_pkt_section(pkt, KNOT_ANSWER);
for (uint16_t i = 0; i < answer->count; ++i) {
if (journal_limit_exceeded(ixfr)) {
IXFRIN_LOG(LOG_WARNING, "Journal is full.");
IXFRIN_LOG(LOG_WARNING, "journal is full");
return NS_PROC_FAIL;
}
......@@ -544,7 +544,7 @@ static int process_ixfrin_packet(knot_pkt_t *pkt, struct answer_data *adata)
int ret = ixfrin_step(rr, ixfr);
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_ERR, "Failed - %s", knot_strerror(ret));
IXFRIN_LOG(LOG_ERR, "failed (%s)", knot_strerror(ret));
return NS_PROC_FAIL;
}
......@@ -581,16 +581,16 @@ int ixfr_query(knot_pkt_t *pkt, struct query_data *qdata)
switch(ret) {
case KNOT_EOK: /* OK */
ixfr = (struct ixfr_proc*)qdata->ext;
IXFROUT_LOG(LOG_INFO, "Started (serial %u -> %u).",
IXFROUT_LOG(LOG_INFO, "started, serial %u -> %u",
knot_soa_serial(&ixfr->soa_from->rrs),
knot_soa_serial(&ixfr->soa_to->rrs));
break;
case KNOT_EUPTODATE: /* Our zone is same age/older, send SOA. */
IXFROUT_LOG(LOG_INFO, "Zone is up-to-date.");
IXFROUT_LOG(LOG_INFO, "zone is up-to-date");
return ixfr_answer_soa(pkt, qdata);
case KNOT_ERANGE: /* No history -> AXFR. */
case KNOT_ENOENT:
IXFROUT_LOG(LOG_INFO, "Incomplete history, fallback to AXFR.");
IXFROUT_LOG(LOG_INFO, "incomplete history, fallback to AXFR");
knot_pkt_clear(pkt);
knot_pkt_put_question(pkt, knot_pkt_qname(query),
knot_pkt_qclass(query),
......@@ -598,7 +598,7 @@ int ixfr_query(knot_pkt_t *pkt, struct query_data *qdata)
qdata->packet_type = KNOT_QUERY_AXFR; /* Solve as AXFR. */
return axfr_query_process(pkt, qdata);
default: /* Server errors. */
IXFROUT_LOG(LOG_ERR, "Failed to start (%s).", knot_strerror(ret));
IXFROUT_LOG(LOG_ERR, "failed to start (%s)", knot_strerror(ret));
return NS_PROC_FAIL;
}
}
......@@ -613,14 +613,13 @@ int ixfr_query(knot_pkt_t *pkt, struct query_data *qdata)
return NS_PROC_FULL; /* Check for more. */
case KNOT_EOK: /* Last response. */
gettimeofday(&now, NULL);
IXFROUT_LOG(LOG_INFO, "Finished in %.02fs (%u messages, "
"%s%.*f %s).",
IXFROUT_LOG(LOG_INFO, "finished, %.02fs, %u messages, " SIZE_FORMAT,
time_diff(&ixfr->proc.tstamp, &now) / 1000.0,
ixfr->proc.npkts, SIZE_PARAMS(ixfr->proc.nbytes));
ret = NS_PROC_DONE;
break;
default: /* Generic error. */
IXFROUT_LOG(LOG_ERR, "%s", knot_strerror(ret));
IXFROUT_LOG(LOG_ERR, "failed (%s)", knot_strerror(ret));
ret = NS_PROC_FAIL;
break;
}
......@@ -639,7 +638,7 @@ int ixfr_process_answer(knot_pkt_t *pkt, struct answer_data *adata)
if (rcode != KNOT_RCODE_NOERROR) {
knot_lookup_table_t *lut = knot_lookup_by_id(knot_rcode_names, rcode);
if (lut != NULL) {
IXFRIN_LOG(LOG_ERR, "Server responded with %s.", lut->name);
IXFRIN_LOG(LOG_ERR, "server responded with %s", lut->name);
}
return NS_PROC_FAIL;
}
......@@ -648,15 +647,15 @@ int ixfr_process_answer(knot_pkt_t *pkt, struct answer_data *adata)
if (adata->ext == NULL) {
NS_NEED_TSIG_SIGNED(&adata->param->tsig_ctx, 0);
if (!zone_transfer_needed(adata->param->zone, pkt)) {
IXFRIN_LOG(LOG_INFO, "Server has newer zone.");
IXFRIN_LOG(LOG_INFO, "server has newer zone");
return NS_PROC_DONE;
}
IXFRIN_LOG(LOG_INFO, "Starting.");
IXFRIN_LOG(LOG_INFO, "starting");
// First packet with IXFR, init context
int ret = ixfrin_answer_init(adata);
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_ERR, "%s", knot_strerror(ret));
IXFRIN_LOG(LOG_ERR, "failed (%s)", knot_strerror(ret));
return NS_PROC_FAIL;
}
} else {
......
......@@ -44,7 +44,7 @@
/* NOTIFY-specific logging (internal, expects 'qdata' variable set). */
#define NOTIFY_QLOG(severity, msg...) \
QUERY_LOG(severity, qdata, "NOTIFY", msg)
QUERY_LOG(severity, qdata, "notify, incoming", msg)
static int notify_check_query(struct query_data *qdata)
{
......@@ -70,7 +70,7 @@ int notify_process_query(knot_pkt_t *pkt, struct query_data *qdata)
if (state == NS_PROC_FAIL) {
switch (qdata->rcode) {
case KNOT_RCODE_NOTAUTH: /* Not authoritative or ACL check failed. */
NOTIFY_QLOG(LOG_NOTICE, "unauthorized request.");
NOTIFY_QLOG(LOG_NOTICE, "unauthorized request");
break;
case KNOT_RCODE_FORMERR: /* Silently ignore bad queries. */
default:
......@@ -88,12 +88,12 @@ int notify_process_query(knot_pkt_t *pkt, struct query_data *qdata)
const knot_rrset_t *soa = &answer->rr[0];
if (soa->type == KNOT_RRTYPE_SOA) {
uint32_t serial = knot_soa_serial(&soa->rrs);
NOTIFY_QLOG(LOG_INFO, "received serial %u.", serial);
NOTIFY_QLOG(LOG_INFO, "received serial %u", serial);
} else { /* Complain, but accept N/A record. */
NOTIFY_QLOG(LOG_NOTICE, "received, bad record in answer section.");
NOTIFY_QLOG(LOG_NOTICE, "received, bad record in answer section");
}
} else {
NOTIFY_QLOG(LOG_INFO, "received, doesn't have SOA.");
NOTIFY_QLOG(LOG_INFO, "received, doesn't have SOA");
}
/* Incoming NOTIFY expires REFRESH timer and renews EXPIRE timer. */
......@@ -107,7 +107,7 @@ int notify_process_query(knot_pkt_t *pkt, struct query_data *qdata)
/* NOTIFY-specific logging (internal, expects 'adata' variable set). */
#define NOTIFY_RLOG(severity, msg...) \
ANSWER_LOG(severity, adata, "NOTIFY", msg)
ANSWER_LOG(severity, adata, "notify, incoming", msg)
int notify_process_answer(knot_pkt_t *pkt, struct answer_data *adata)
{
......@@ -120,7 +120,7 @@ int notify_process_answer(knot_pkt_t *pkt, struct answer_data *adata)
if (rcode != KNOT_RCODE_NOERROR) {
knot_lookup_table_t *lut = knot_lookup_by_id(knot_rcode_names, rcode);
if (lut != NULL) {
NOTIFY_RLOG(LOG_ERR, "Server responded with %s.", lut->name);
NOTIFY_RLOG(LOG_ERR, "server responded with %s", lut->name);
}
return NS_PROC_FAIL;
}
......
......@@ -39,7 +39,7 @@ const knot_process_module_t *process_query_get_module(void);
#define NS_PROC_LOG(priority, remote, zone_name, operation, msg, ...) do { \
char addr_str[SOCKADDR_STRLEN] = {0}; \
sockaddr_tostr(remote, addr_str, sizeof(addr_str)); \
log_msg_zone(priority, zone_name, operation ", remote %s: " msg "\n", \
log_msg_zone(priority, zone_name, operation ", %s: " msg "\n", \
addr_str, ##__VA_ARGS__); \
} while (0)
......
......@@ -164,9 +164,9 @@ fail:
/* @note Module specific, expects some variables set. */
#define ZONE_XFER_LOG(priority, pkt_type, msg...) \
if (pkt_type == KNOT_QUERY_AXFR) { \
ZONE_QUERY_LOG(priority, zone, master, "AXFR", msg); \
ZONE_QUERY_LOG(priority, zone, master, "AXFR, incoming", msg); \
} else { \
ZONE_QUERY_LOG(priority, zone, master, "IXFR", msg); \
ZONE_QUERY_LOG(priority, zone, master, "IXFR, incoming", msg); \
}
/*! \brief Execute zone transfer request. */
......@@ -179,12 +179,12 @@ static int zone_query_transfer(zone_t *zone, const conf_iface_t *master, uint16_
if (ret != KNOT_EOK) {
/* IXFR failed, revert to AXFR. */
if (pkt_type == KNOT_QUERY_IXFR) {
ZONE_XFER_LOG(LOG_NOTICE, pkt_type, "Fallback to AXFR.");
ZONE_XFER_LOG(LOG_NOTICE, pkt_type, "fallback to AXFR");
return zone_query_transfer(zone, master, KNOT_QUERY_AXFR);
}
/* Log connection errors. */
ZONE_XFER_LOG(LOG_ERR, pkt_type, "%s", knot_strerror(ret));
ZONE_XFER_LOG(LOG_ERR, pkt_type, "failed (%s)", knot_strerror(ret));
}
return ret;
......@@ -211,7 +211,7 @@ static void schedule_dnssec(zone_t *zone, time_t refresh_at)
struct tm time_gm = { 0 };
localtime_r(&refresh_at, &time_gm);
strftime(time_str, sizeof(time_str), KNOT_LOG_TIME_FORMAT, &time_gm);
log_zone_info(zone->name, "DNSSEC: Next event on %s\n", time_str);
log_zone_info(zone->name, "DNSSEC, next event on %s\n", time_str);
// schedule
......@@ -255,10 +255,10 @@ static int event_reload(zone_t *zone)
result = zone_load_post(contents, zone, &dnssec_refresh);
if (result != KNOT_EOK) {
if (result == KNOT_ESPACE) {
log_zone_error(zone->name, "Journal size is too small "
log_zone_error(zone->name, "journal size is too small "
"to fit the changes\n");
} else {
log_zone_error(zone->name, "Failed to store changes into "
log_zone_error(zone->name, "failed to store changes into "
"journal: %s\n", knot_strerror(result));
}
goto fail;
......@@ -297,7 +297,7 @@ static int event_reload(zone_t *zone)
zone_events_schedule(zone, ZONE_EVENT_FLUSH, zone_config->dbsync_timeout);
uint32_t current_serial = zone_contents_serial(zone->contents);
log_zone_info(zone->name, "Loaded, serial %u -> %u\n",
log_zone_info(zone->name, "loaded, serial %u -> %u\n",
old_serial, current_serial);
return KNOT_EOK;
......@@ -325,7 +325,8 @@ static int event_refresh(zone_t *zone)
const knot_rdataset_t *soa = node_rdataset(contents->apex, KNOT_RRTYPE_SOA);
if (ret != KNOT_EOK) {
/* Log connection errors. */
ZONE_QUERY_LOG(LOG_WARNING, zone, master, "SOA query", "%s", knot_strerror(ret));
ZONE_QUERY_LOG(LOG_WARNING, zone, master, "SOA query, outgoing",
"failed (%s)", knot_strerror(ret));
/* Rotate masters if current failed. */
zone_master_rotate(zone);
/* Schedule next retry. */
......@@ -435,7 +436,7 @@ static int event_expire(zone_t *zone)
zone->zonefile_serial = 0;
zone_contents_deep_free(&expired);
log_zone_info(zone->name, "Zone expired\n");
log_zone_info(zone->name, "zone expired\n");
/* Trim extra heap. */
mem_trim();
......@@ -477,10 +478,12 @@ static int event_notify(zone_t *zone)
int ret = zone_query_execute(zone, KNOT_QUERY_NOTIFY, iface);
if (ret == KNOT_EOK) {
ZONE_QUERY_LOG(LOG_INFO, zone, iface, "NOTIFY", "sent (serial %u).",
ZONE_QUERY_LOG(LOG_INFO, zone, iface, "notify, outgoing",
"serial %u",
zone_contents_serial(zone->contents));
} else {
ZONE_QUERY_LOG(LOG_WARNING, zone, iface, "NOTIFY", "%s", knot_strerror(ret));
ZONE_QUERY_LOG(LOG_WARNING, zone, iface, "notify, outgoing",
"failed (%s)", knot_strerror(ret));
}
}
......@@ -503,14 +506,14 @@ static int event_dnssec(zone_t *zone)
uint32_t refresh_at = time(NULL);
if (zone->flags & ZONE_FORCE_RESIGN) {
log_zone_info(zone->name, "DNSSEC: Dropping previous "
log_zone_info(zone->name, "DNSSEC, dropping previous "
"signatures, resigning zone\n");
zone->flags &= ~ZONE_FORCE_RESIGN;
ret = knot_dnssec_zone_sign_force(zone->contents, zone->conf,
ch, &refresh_at);
} else {
log_zone_info(zone->name, "DNSSEC: Signing zone\n");
log_zone_info(zone->name, "DNSSEC, signing zone\n");
ret = knot_dnssec_zone_sign(zone->contents, zone->conf,
ch, KNOT_SOA_SERIAL_UPDATE,
&refresh_at);
......@@ -522,7 +525,7 @@ static int event_dnssec(zone_t *zone)
if (!changesets_empty(chs)) {
ret = zone_change_apply_and_store(&chs, zone, "DNSSEC", NULL);
if (ret != KNOT_EOK) {
log_zone_error(zone->name, "DNSSEC: Could not sign zone: %s\n",
log_zone_error(zone->name, "DNSSEC, could not sign zone (%s)\n",
knot_strerror(ret));
goto done;
}
......@@ -803,7 +806,7 @@ static void event_wrap(task_t *task)
const event_info_t *info = get_event_info(type);
int result = info->callback(zone);
if (result != KNOT_EOK) {
log_zone_error(zone->name, "Zone %s failed: %s\n", info->name,
log_zone_error(zone->name, "zone %s failed (%s)\n", info->name,
knot_strerror(result));
}
......@@ -1033,4 +1036,3 @@ void zone_events_replan_ddns(struct zone_t *zone, const struct zone_t *old_zone)
replan_update(zone, (zone_t *)old_zone);
}
}
......@@ -127,7 +127,7 @@ int zone_change_store(zone_t *zone, changesets_t *chset)
int ret = journal_store_changesets(chset, conf->ixfr_db, conf->ixfr_fslimit);
if (ret == KNOT_EBUSY) {
log_zone_notice(zone->name, "Zone journal is full, flushing\n");
log_zone_notice(zone->name, "zone journal is full, flushing\n");
/* Transaction rolled back, journal released, we may flush. */
ret = zone_flush_journal(zone);
......@@ -245,10 +245,10 @@ int zone_flush_journal(zone_t *zone)
conf_zone_t *conf = zone->conf;
int ret = zonefile_write(conf->file, contents, from);
if (ret == KNOT_EOK) {
log_zone_info(zone->name, "Zone file updated, serial %u -> %u\n",
log_zone_info(zone->name, "zone file updated, serial %u -> %u\n",
zone->zonefile_serial, serial_to);
} else {
log_zone_warning(zone->name, "Failed to update zone file: %s\n",
log_zone_warning(zone->name, "failed to update zone file: %s\n",
knot_strerror(ret));
return ret;
}
......@@ -256,7 +256,7 @@ int zone_flush_journal(zone_t *zone)
/* Update zone version. */
struct stat st;
if (stat(zone->conf->file, &st) < 0) {
log_zone_warning(zone->name, "Failed to update zone file: %s\n",
log_zone_warning(zone->name, "failed to update zone file: %s\n",
knot_strerror(KNOT_EACCES));
return KNOT_EACCES;
}
......
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