Commit 55bfebe9 authored by Filip Siroky's avatar Filip Siroky Committed by Filip Široký

zone-status: add filtering + event timing

parent 245ae377
...@@ -89,9 +89,6 @@ in the configuration. (*) ...@@ -89,9 +89,6 @@ in the configuration. (*)
\fBzone\-memstats\fP [\fIzone\fP\&...] \fBzone\-memstats\fP [\fIzone\fP\&...]
Estimate memory use for the zone. (*) Estimate memory use for the zone. (*)
.TP .TP
\fBzone\-status\fP [\fIzone\fP\&...]
Show the zone status. (*)
.TP
\fBzone\-reload\fP [\fIzone\fP\&...] \fBzone\-reload\fP [\fIzone\fP\&...]
Trigger a zone reload from a disk without checking its modification time. For Trigger a zone reload from a disk without checking its modification time. For
slave zone, the refresh from a master server is scheduled; for master zone, slave zone, the refresh from a master server is scheduled; for master zone,
...@@ -145,6 +142,10 @@ Purge zone data, file, journal, and timers. ...@@ -145,6 +142,10 @@ Purge zone data, file, journal, and timers.
Show zone statistics counter(s). To print also counters with value 0, use Show zone statistics counter(s). To print also counters with value 0, use
force option. force option.
.TP .TP
\fBzone\-status\fP \fIzone\fP [\fIfilter\fP]
Show the zone status. (*)
Filters are type, serial, next\-event, auto\-dnssec, transaction, event\-timers.
.TP
\fBzone\-freeze\fP [\fIzone\fP\&...] \fBzone\-freeze\fP [\fIzone\fP\&...]
Temporarily postpone zone\-changing events (load, refresh, update, flush, and Temporarily postpone zone\-changing events (load, refresh, update, flush, and
DNSSEC signing). DNSSEC signing).
......
...@@ -66,9 +66,6 @@ Actions ...@@ -66,9 +66,6 @@ Actions
**zone-memstats** [*zone*...] **zone-memstats** [*zone*...]
Estimate memory use for the zone. (*) Estimate memory use for the zone. (*)
**zone-status** [*zone*...]
Show the zone status. (*)
**zone-reload** [*zone*...] **zone-reload** [*zone*...]
Trigger a zone reload from a disk without checking its modification time. For Trigger a zone reload from a disk without checking its modification time. For
slave zone, the refresh from a master server is scheduled; for master zone, slave zone, the refresh from a master server is scheduled; for master zone,
...@@ -122,6 +119,10 @@ Actions ...@@ -122,6 +119,10 @@ Actions
Show zone statistics counter(s). To print also counters with value 0, use Show zone statistics counter(s). To print also counters with value 0, use
force option. force option.
**zone-status** *zone* [*filter*]
Show the zone status. (*)
Filters are type, serial, next-event, auto-dnssec, transaction, event-timers.
**zone-freeze** [*zone*...] **zone-freeze** [*zone*...]
Temporarily postpone zone-changing events (load, refresh, update, flush, and Temporarily postpone zone-changing events (load, refresh, update, flush, and
DNSSEC signing). DNSSEC signing).
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h>
#include "knot/common/log.h" #include "knot/common/log.h"
#include "knot/common/stats.h" #include "knot/common/stats.h"
...@@ -137,6 +138,43 @@ static int zones_apply(ctl_args_t *args, int (*fcn)(zone_t *, ctl_args_t *)) ...@@ -137,6 +138,43 @@ static int zones_apply(ctl_args_t *args, int (*fcn)(zone_t *, ctl_args_t *))
return ret; return ret;
} }
typedef enum {
ZONE_STATUS_INVALID = -1,
ZONE_STATUS_NONE = 0,
ZONE_STATUS_TYPE = 1,
ZONE_STATUS_SERIAL,
ZONE_STATUS_NEXT_EVENT,
ZONE_STATUS_AUTO_DNSSEC,
ZONE_STATUS_TRANSACTION,
ZONE_STATUS_EVENT_TIMERS,
} zone_status_param ;
static zone_status_param zone_status_param_check(const char *param)
{
if (param == NULL) {
return ZONE_STATUS_NONE;
}
if (strcmp(param, "type") == 0) {
return ZONE_STATUS_TYPE;
}
if (strcmp(param, "serial") == 0) {
return ZONE_STATUS_SERIAL;
}
if (strcmp(param, "next-event") == 0) {
return ZONE_STATUS_NEXT_EVENT;
}
if (strcmp(param, "auto-dnssec") == 0) {
return ZONE_STATUS_AUTO_DNSSEC;
}
if (strcmp(param, "transaction") == 0) {
return ZONE_STATUS_TRANSACTION;
}
if (strcmp(param, "event-timers") == 0) {
return ZONE_STATUS_EVENT_TIMERS;
}
return ZONE_STATUS_INVALID;
}
static int zone_status(zone_t *zone, ctl_args_t *args) static int zone_status(zone_t *zone, ctl_args_t *args)
{ {
// Zone name. // Zone name.
...@@ -146,108 +184,166 @@ static int zone_status(zone_t *zone, ctl_args_t *args) ...@@ -146,108 +184,166 @@ static int zone_status(zone_t *zone, ctl_args_t *args)
} }
knot_ctl_data_t data = { knot_ctl_data_t data = {
[KNOT_CTL_IDX_ZONE] = name [KNOT_CTL_IDX_ZONE] = name
}; };
// Zone type. zone_status_param param = zone_status_param_check(args->data[KNOT_CTL_IDX_OWNER]);
data[KNOT_CTL_IDX_TYPE] = "type"; if (param == ZONE_STATUS_INVALID) {
data[KNOT_CTL_IDX_ERROR] = "Invalid parameters.";
if (zone_is_slave(conf(), zone)) { int ret = knot_ctl_send(args->ctl, KNOT_CTL_TYPE_DATA, &data);
data[KNOT_CTL_IDX_DATA] = "slave"; if (ret != KNOT_EOK) {
} else { return ret;
data[KNOT_CTL_IDX_DATA] = "master"; }
} return KNOT_EINVAL;
int ret = knot_ctl_send(args->ctl, KNOT_CTL_TYPE_DATA, &data);
if (ret != KNOT_EOK) {
return ret;
} }
// Zone serial. int ret;
data[KNOT_CTL_IDX_TYPE] = "serial";
char buff[128]; char buff[128];
if (zone->contents != NULL) { knot_ctl_type_t type = KNOT_CTL_TYPE_DATA;
knot_rdataset_t *soa = node_rdataset(zone->contents->apex, // Zone type.
KNOT_RRTYPE_SOA); if (param == ZONE_STATUS_TYPE || param == ZONE_STATUS_NONE) {
ret = snprintf(buff, sizeof(buff), "%u", knot_soa_serial(soa)); data[KNOT_CTL_IDX_TYPE] = "type";
} else {
ret = snprintf(buff, sizeof(buff), "none");
}
if (ret < 0 || ret >= sizeof(buff)) {
return KNOT_ESPACE;
}
data[KNOT_CTL_IDX_DATA] = buff; if (zone_is_slave(conf(), zone)) {
data[KNOT_CTL_IDX_DATA] = "slave";
} else {
data[KNOT_CTL_IDX_DATA] = "master";
}
ret = knot_ctl_send(args->ctl, KNOT_CTL_TYPE_EXTRA, &data); ret = knot_ctl_send(args->ctl, type, &data);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
return ret; return ret;
} else {
type = KNOT_CTL_TYPE_EXTRA;
}
} }
// Zone serial.
if (param == ZONE_STATUS_SERIAL || param == ZONE_STATUS_NONE) {
data[KNOT_CTL_IDX_TYPE] = "serial";
// Next event. if (zone->contents != NULL) {
data[KNOT_CTL_IDX_TYPE] = "next-event"; knot_rdataset_t *soa = node_rdataset(zone->contents->apex,
KNOT_RRTYPE_SOA);
zone_event_type_t next_type = ZONE_EVENT_INVALID; ret = snprintf(buff, sizeof(buff), "%u", knot_soa_serial(soa));
time_t next_time = zone_events_get_next(zone, &next_type);
if (next_type != ZONE_EVENT_INVALID) {
const char *next_name = zone_events_get_name(next_type);
next_time = next_time - time(NULL);
if (next_time < 0) {
ret = snprintf(buff, sizeof(buff), "%s pending",
next_name);
} else { } else {
ret = snprintf(buff, sizeof(buff), "%s in %lldh%lldm%llds", ret = snprintf(buff, sizeof(buff), "none");
next_name,
(long long)(next_time / 3600),
(long long)(next_time % 3600) / 60,
(long long)(next_time % 60));
} }
if (ret < 0 || ret >= sizeof(buff)) { if (ret < 0 || ret >= sizeof(buff)) {
return KNOT_ESPACE; return KNOT_ESPACE;
} }
data[KNOT_CTL_IDX_DATA] = buff; data[KNOT_CTL_IDX_DATA] = buff;
} else {
data[KNOT_CTL_IDX_DATA] = "idle";
}
ret = knot_ctl_send(args->ctl, KNOT_CTL_TYPE_EXTRA, &data); ret = knot_ctl_send(args->ctl, type, &data);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
return ret; return ret;
} else {
type = KNOT_CTL_TYPE_EXTRA;
}
} }
// Next event.
if (param == ZONE_STATUS_NEXT_EVENT || param == ZONE_STATUS_NONE) {
data[KNOT_CTL_IDX_TYPE] = "next-event";
zone_event_type_t next_type = ZONE_EVENT_INVALID;
time_t next_time = zone_events_get_next(zone, &next_type);
if (next_type != ZONE_EVENT_INVALID) {
const char *next_name = zone_events_get_name(next_type);
next_time = next_time - time(NULL);
if (next_time < 0) {
ret = snprintf(buff, sizeof(buff), "%s pending",
next_name);
} else {
ret = snprintf(buff, sizeof(buff), "%s in %lldh%lldm%llds",
next_name,
(long long)(next_time / 3600),
(long long)(next_time % 3600) / 60,
(long long)(next_time % 60));
}
if (ret < 0 || ret >= sizeof(buff)) {
return KNOT_ESPACE;
}
data[KNOT_CTL_IDX_DATA] = buff;
} else {
data[KNOT_CTL_IDX_DATA] = "idle";
}
ret = knot_ctl_send(args->ctl, type, &data);
if (ret != KNOT_EOK) {
return ret;
} else {
type = KNOT_CTL_TYPE_EXTRA;
}
}
// DNSSEC re-signing time. // DNSSEC re-signing time.
data[KNOT_CTL_IDX_TYPE] = "auto-dnssec"; if (param == ZONE_STATUS_AUTO_DNSSEC || param == ZONE_STATUS_NONE) {
data[KNOT_CTL_IDX_TYPE] = "auto-dnssec";
conf_val_t val = conf_zone_get(conf(), C_DNSSEC_SIGNING, zone->name);
if (conf_bool(&val)) {
struct tm time_gm = { 0 };
time_t refresh_at = zone_events_get_time(zone, ZONE_EVENT_DNSSEC);
gmtime_r(&refresh_at, &time_gm);
size_t written = strftime(buff, sizeof(buff), KNOT_LOG_TIME_FORMAT,
&time_gm);
if (written == 0) {
return KNOT_ESPACE;
}
conf_val_t val = conf_zone_get(conf(), C_DNSSEC_SIGNING, zone->name); data[KNOT_CTL_IDX_DATA] = buff;
if (conf_bool(&val)) { } else {
struct tm time_gm = { 0 }; data[KNOT_CTL_IDX_DATA] = "disabled";
time_t refresh_at = zone_events_get_time(zone, ZONE_EVENT_DNSSEC);
gmtime_r(&refresh_at, &time_gm);
size_t written = strftime(buff, sizeof(buff), KNOT_LOG_TIME_FORMAT,
&time_gm);
if (written == 0) {
return KNOT_ESPACE;
} }
data[KNOT_CTL_IDX_DATA] = buff; ret = knot_ctl_send(args->ctl, type, &data);
} else { if (ret != KNOT_EOK) {
data[KNOT_CTL_IDX_DATA] = "disabled"; return ret;
} else {
type = KNOT_CTL_TYPE_EXTRA;
}
} }
// Zone transaction.
ret = knot_ctl_send(args->ctl, KNOT_CTL_TYPE_EXTRA, &data); if (param == ZONE_STATUS_TRANSACTION || param == ZONE_STATUS_NONE) {
if (ret != KNOT_EOK) { data[KNOT_CTL_IDX_TYPE] = "transaction";
return ret; data[KNOT_CTL_IDX_DATA] = (zone->control_update != NULL) ? "open" : "none";
ret = knot_ctl_send(args->ctl, type, &data);
if (ret != KNOT_EOK) {
return ret;
}
} }
// list modules
if (param == ZONE_STATUS_EVENT_TIMERS || param == ZONE_STATUS_NONE) {
time_t ev_time;
for (zone_event_type_t i = 0; i < ZONE_EVENT_COUNT; i++) {
data[KNOT_CTL_IDX_TYPE] = zone_events_get_name(i);
// Zone transaction. ev_time = zone_events_get_time(zone, i);
data[KNOT_CTL_IDX_TYPE] = "transaction"; ev_time = ev_time - time(NULL);
data[KNOT_CTL_IDX_DATA] = (zone->control_update != NULL) ? "open" : "none"; if (ev_time < 0) {
ret = snprintf(buff, sizeof(buff), "pending");
} else {
ret = snprintf(buff, sizeof(buff), "in %lldh%lldm%llds",
(long long)(ev_time / 3600),
(long long)(ev_time % 3600) / 60,
(long long)(ev_time % 60));
}
if (ret < 0 || ret >= sizeof(buff)) {
return KNOT_ESPACE;
}
data[KNOT_CTL_IDX_DATA] = buff;
return knot_ctl_send(args->ctl, KNOT_CTL_TYPE_EXTRA, &data); ret = knot_ctl_send(args->ctl, !i? KNOT_CTL_TYPE_DATA : KNOT_CTL_TYPE_EXTRA, &data);
if (ret != KNOT_EOK) {
return ret;
}
type = KNOT_CTL_TYPE_EXTRA;
}
}
return KNOT_EOK;
} }
static int zone_reload(zone_t *zone, ctl_args_t *args) static int zone_reload(zone_t *zone, ctl_args_t *args)
......
...@@ -712,6 +712,7 @@ static int set_node_items(cmd_args_t *args, knot_ctl_data_t *data, char *rdata, ...@@ -712,6 +712,7 @@ static int set_node_items(cmd_args_t *args, knot_ctl_data_t *data, char *rdata,
switch (args->desc->cmd) { switch (args->desc->cmd) {
case CTL_ZONE_READ: case CTL_ZONE_READ:
case CTL_ZONE_GET: min_args = 1; max_args = 3; break; case CTL_ZONE_GET: min_args = 1; max_args = 3; break;
case CTL_ZONE_STATUS: min_args = 1; max_args = 2; break;
case CTL_ZONE_DIFF: min_args = 1; max_args = 1; break; case CTL_ZONE_DIFF: min_args = 1; max_args = 1; break;
case CTL_ZONE_SET: min_args = 3; max_args = -1; break; case CTL_ZONE_SET: min_args = 3; max_args = -1; break;
case CTL_ZONE_UNSET: min_args = 2; max_args = -1; break; case CTL_ZONE_UNSET: min_args = 2; max_args = -1; break;
...@@ -968,7 +969,6 @@ const cmd_desc_t cmd_table[] = { ...@@ -968,7 +969,6 @@ const cmd_desc_t cmd_table[] = {
{ CMD_ZONE_CHECK, cmd_zone_check, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD }, { CMD_ZONE_CHECK, cmd_zone_check, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD },
{ CMD_ZONE_MEMSTATS, cmd_zone_memstats, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD }, { CMD_ZONE_MEMSTATS, cmd_zone_memstats, CTL_NONE, CMD_FOPT_ZONE | CMD_FREAD },
{ CMD_ZONE_STATUS, cmd_zone_ctl, CTL_ZONE_STATUS, CMD_FOPT_ZONE },
{ CMD_ZONE_RELOAD, cmd_zone_ctl, CTL_ZONE_RELOAD, CMD_FOPT_ZONE }, { CMD_ZONE_RELOAD, cmd_zone_ctl, CTL_ZONE_RELOAD, CMD_FOPT_ZONE },
{ CMD_ZONE_REFRESH, cmd_zone_ctl, CTL_ZONE_REFRESH, CMD_FOPT_ZONE }, { CMD_ZONE_REFRESH, cmd_zone_ctl, CTL_ZONE_REFRESH, CMD_FOPT_ZONE },
{ CMD_ZONE_RETRANSFER, cmd_zone_ctl, CTL_ZONE_RETRANSFER, CMD_FOPT_ZONE }, { CMD_ZONE_RETRANSFER, cmd_zone_ctl, CTL_ZONE_RETRANSFER, CMD_FOPT_ZONE },
...@@ -987,6 +987,7 @@ const cmd_desc_t cmd_table[] = { ...@@ -987,6 +987,7 @@ const cmd_desc_t cmd_table[] = {
{ CMD_ZONE_UNSET, cmd_zone_node_ctl, CTL_ZONE_UNSET, CMD_FREQ_ZONE }, { CMD_ZONE_UNSET, cmd_zone_node_ctl, CTL_ZONE_UNSET, CMD_FREQ_ZONE },
{ CMD_ZONE_PURGE, cmd_zone_ctl, CTL_ZONE_PURGE, CMD_FREQ_ZONE }, { CMD_ZONE_PURGE, cmd_zone_ctl, CTL_ZONE_PURGE, CMD_FREQ_ZONE },
{ CMD_ZONE_STATS, cmd_stats_ctl, CTL_ZONE_STATS, CMD_FREQ_ZONE }, { CMD_ZONE_STATS, cmd_stats_ctl, CTL_ZONE_STATS, CMD_FREQ_ZONE },
{ CMD_ZONE_STATUS, cmd_zone_node_ctl, CTL_ZONE_STATUS, CMD_FREQ_ZONE },
{ CMD_CONF_INIT, cmd_conf_init, CTL_NONE, CMD_FWRITE }, { CMD_CONF_INIT, cmd_conf_init, CTL_NONE, CMD_FWRITE },
{ CMD_CONF_CHECK, cmd_conf_check, CTL_NONE, CMD_FREAD }, { CMD_CONF_CHECK, cmd_conf_check, CTL_NONE, CMD_FREAD },
...@@ -1014,7 +1015,6 @@ static const cmd_help_t cmd_help_table[] = { ...@@ -1014,7 +1015,6 @@ static const cmd_help_t cmd_help_table[] = {
{ "", "", "" }, { "", "", "" },
{ CMD_ZONE_CHECK, "[<zone>...]", "Check if the zone can be loaded. (*)" }, { CMD_ZONE_CHECK, "[<zone>...]", "Check if the zone can be loaded. (*)" },
{ CMD_ZONE_MEMSTATS, "[<zone>...]", "Estimate memory use for the zone. (*)" }, { CMD_ZONE_MEMSTATS, "[<zone>...]", "Estimate memory use for the zone. (*)" },
{ CMD_ZONE_STATUS, "[<zone>...]", "Show the zone status." },
{ CMD_ZONE_RELOAD, "[<zone>...]", "Reload a zone from a disk." }, { CMD_ZONE_RELOAD, "[<zone>...]", "Reload a zone from a disk." },
{ CMD_ZONE_REFRESH, "[<zone>...]", "Force slave zone refresh." }, { CMD_ZONE_REFRESH, "[<zone>...]", "Force slave zone refresh." },
{ CMD_ZONE_RETRANSFER, "[<zone>...]", "Force slave zone retransfer (no serial check)." }, { CMD_ZONE_RETRANSFER, "[<zone>...]", "Force slave zone retransfer (no serial check)." },
...@@ -1033,6 +1033,7 @@ static const cmd_help_t cmd_help_table[] = { ...@@ -1033,6 +1033,7 @@ static const cmd_help_t cmd_help_table[] = {
{ CMD_ZONE_UNSET, "<zone> <owner> [<type> [<rdata>]]", "Remove zone data within the transaction." }, { CMD_ZONE_UNSET, "<zone> <owner> [<type> [<rdata>]]", "Remove zone data within the transaction." },
{ CMD_ZONE_PURGE, "<zone>...", "Purge zone data, file, journal, and timers." }, { CMD_ZONE_PURGE, "<zone>...", "Purge zone data, file, journal, and timers." },
{ CMD_ZONE_STATS, "<zone> [<module>[.<counter>]]", "Show zone statistics counter(s)."}, { CMD_ZONE_STATS, "<zone> [<module>[.<counter>]]", "Show zone statistics counter(s)."},
{ CMD_ZONE_STATUS, "<zone> [filter]", "Show the zone status." },
{ "", "", "" }, { "", "", "" },
{ CMD_CONF_INIT, "", "Initialize the confdb. (*)" }, { CMD_CONF_INIT, "", "Initialize the confdb. (*)" },
{ CMD_CONF_CHECK, "", "Check the server configuration. (*)" }, { CMD_CONF_CHECK, "", "Check the server configuration. (*)" },
......
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