From: Jan Hák Date: Fri, 24 May 2019 12:03:50 +0000 (+0200) Subject: knotc: add blocking mode for zone event triggers X-Git-Tag: v2.9.0~257^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bf87eaf06ae20ed2308ef4eee4b7bbf2ecdb050;p=thirdparty%2Fknot-dns.git knotc: add blocking mode for zone event triggers --- diff --git a/doc/man/knotc.8in b/doc/man/knotc.8in index ea00e393fa..8a3a2aa4db 100644 --- a/doc/man/knotc.8in +++ b/doc/man/knotc.8in @@ -56,6 +56,9 @@ Use a control UNIX socket path (default is \fB@run_dir@/knot.sock\fP). \fB\-t\fP, \fB\-\-timeout\fP \fIseconds\fP Use a control timeout in seconds. Set 0 for infinity (default is 10). .TP +\fB\-b\fP, \fB\-\-blocking\fP +Zone event trigger commands wait until the event is finished. +.TP \fB\-f\fP, \fB\-\-force\fP Forced operation. Overrides some checks. .TP @@ -102,46 +105,47 @@ Estimate memory use for the zone. (*) 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, the notification of slave servers is scheduled. An open zone transaction -will be aborted! +will be aborted! (#) .TP \fBzone\-refresh\fP [\fIzone\fP\&...] Trigger a check for the zone serial on the zone\(aqs master. If the master has a -newer zone, a transfer is scheduled. This command is valid for slave zones. +newer zone, a transfer is scheduled. This command is valid for slave zones. (#) .TP \fBzone\-retransfer\fP [\fIzone\fP\&...] Trigger a zone transfer from the zone\(aqs master. The server doesn\(aqt check the -serial of the master\(aqs zone. This command is valid for slave zones. +serial of the master\(aqs zone. This command is valid for slave zones. (#) .TP \fBzone\-notify\fP [\fIzone\fP\&...] Trigger a NOTIFY message to all configured remotes. This can help in cases -when previous NOTIFY had been lost or the slaves offline. +when previous NOTIFY had been lost or the slaves offline. (#) .TP \fBzone\-flush\fP [\fIzone\fP\&...] [\fB+outdir\fP \fIdirectory\fP] Trigger a zone journal flush into the zone file. If output dir is specified, instead of flushing the zonefile, the zone is dumped to a file in the specified -directory. +directory. (#) .TP \fBzone\-sign\fP [\fIzone\fP\&...] Trigger a DNSSEC re\-sign of the zone. Existing signatures will be dropped. -This command is valid for zones with DNSSEC signing enabled. +This command is valid for zones with DNSSEC signing enabled. (#) .TP \fBzone\-key\-rollover\fP \fIzone\fP \fIkey_type\fP Trigger immediate key rollover. Publish new key and start a key rollover, even when the key has a lifetime to go. Key type can be \fBksk\fP (also for CSK) or \fBzsk\fP\&. This command is valid for zones with DNSSEC signing and automatic -key management enabled. +key management enabled. Note that complete key rollover consists of several steps +and the blocking mode relates to the initial one only! (#) .TP \fBzone\-ksk\-submitted\fP \fIzone\fP\&... Use when the zone\(aqs KSK rollover is in submittion phase. By calling this command the user confirms manually that the parent zone contains DS record for the new -KSK in submission phase and the old KSK can be retired. +KSK in submission phase and the old KSK can be retired. (#) .TP \fBzone\-freeze\fP [\fIzone\fP\&...] Temporarily postpone zone\-changing events (load, refresh, update, flush, and -DNSSEC signing). +DNSSEC signing). (#) .TP \fBzone\-thaw\fP [\fIzone\fP\&...] -Dismiss zone freeze. +Dismiss zone freeze. (#) .TP \fBzone\-read\fP \fIzone\fP [\fIowner\fP [\fItype\fP]] Get zone data that are currently being presented. @@ -173,7 +177,7 @@ Purge zone data, zone file, journal, timers, and/or KASP data of specified zones Available filters are \fB+expire\fP, \fB+zonefile\fP, \fB+journal\fP, \fB+timers\fP, and \fB+kaspdb\fP\&. If no filter is specified, all filters are enabled. If the zone is no longer configured, add \fB+orphan\fP filter (zone file cannot -be purged in this case). +be purged in this case). (#) .TP \fBzone\-stats\fP \fIzone\fP [\fImodule\fP[\fB\&.\fP\fIcounter\fP]] Show zone statistics counter(s). To print also counters with value 0, use @@ -230,7 +234,9 @@ Type \fIitem\fP parameter in the form of \fIsection\fP[\fB[\fP\fIid\fP\fB]\fP][\ .sp (*) indicates a local operation which requires a configuration. .sp -Use \fB\-\-force\fP or \fB\-f\fP as the first parameter of any command to force it. +(#) indicates an optionally blocking operation. +.sp +The \fI\-b\fP and \fI\-f\fP options can be placed right after the command name. .SS Interactive mode .sp The utility provides interactive mode with basic line editing functionality, diff --git a/doc/man_knotc.rst b/doc/man_knotc.rst index e4fd7d5b20..919ec99b87 100644 --- a/doc/man_knotc.rst +++ b/doc/man_knotc.rst @@ -33,6 +33,9 @@ Parameters **-t**, **--timeout** *seconds* Use a control timeout in seconds. Set 0 for infinity (default is 10). +**-b**, **--blocking** + Zone event trigger commands wait until the event is finished. + **-f**, **--force** Forced operation. Overrides some checks. @@ -79,46 +82,47 @@ Actions 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, the notification of slave servers is scheduled. An open zone transaction - will be aborted! + will be aborted! (#) **zone-refresh** [*zone*...] Trigger a check for the zone serial on the zone's master. If the master has a - newer zone, a transfer is scheduled. This command is valid for slave zones. + newer zone, a transfer is scheduled. This command is valid for slave zones. (#) **zone-retransfer** [*zone*...] Trigger a zone transfer from the zone's master. The server doesn't check the - serial of the master's zone. This command is valid for slave zones. + serial of the master's zone. This command is valid for slave zones. (#) **zone-notify** [*zone*...] Trigger a NOTIFY message to all configured remotes. This can help in cases - when previous NOTIFY had been lost or the slaves offline. + when previous NOTIFY had been lost or the slaves offline. (#) **zone-flush** [*zone*...] [**+outdir** *directory*] Trigger a zone journal flush into the zone file. If output dir is specified, instead of flushing the zonefile, the zone is dumped to a file in the specified - directory. + directory. (#) **zone-sign** [*zone*...] Trigger a DNSSEC re-sign of the zone. Existing signatures will be dropped. - This command is valid for zones with DNSSEC signing enabled. + This command is valid for zones with DNSSEC signing enabled. (#) **zone-key-rollover** *zone* *key_type* Trigger immediate key rollover. Publish new key and start a key rollover, even when the key has a lifetime to go. Key type can be **ksk** (also for CSK) or **zsk**. This command is valid for zones with DNSSEC signing and automatic - key management enabled. + key management enabled. Note that complete key rollover consists of several steps + and the blocking mode relates to the initial one only! (#) **zone-ksk-submitted** *zone*... Use when the zone's KSK rollover is in submittion phase. By calling this command the user confirms manually that the parent zone contains DS record for the new - KSK in submission phase and the old KSK can be retired. + KSK in submission phase and the old KSK can be retired. (#) **zone-freeze** [*zone*...] Temporarily postpone zone-changing events (load, refresh, update, flush, and - DNSSEC signing). + DNSSEC signing). (#) **zone-thaw** [*zone*...] - Dismiss zone freeze. + Dismiss zone freeze. (#) **zone-read** *zone* [*owner* [*type*]] Get zone data that are currently being presented. @@ -150,7 +154,7 @@ Actions Available filters are **+expire**, **+zonefile**, **+journal**, **+timers**, and **+kaspdb**. If no filter is specified, all filters are enabled. If the zone is no longer configured, add **+orphan** filter (zone file cannot - be purged in this case). + be purged in this case). (#) **zone-stats** *zone* [*module*\ [\ **.**\ *counter*\ ]] Show zone statistics counter(s). To print also counters with value 0, use @@ -208,7 +212,9 @@ Type *item* parameter in the form of *section*\ [**[**\ *id*\ **]**\ ][**.**\ *n (*) indicates a local operation which requires a configuration. -Use **--force** or **-f** as the first parameter of any command to force it. +(\#) indicates an optionally blocking operation. + +The *-b* and *-f* options can be placed right after the command name. Interactive mode ................ diff --git a/src/knot/ctl/commands.c b/src/knot/ctl/commands.c index 67de1ac23f..ee6f894787 100644 --- a/src/knot/ctl/commands.c +++ b/src/knot/ctl/commands.c @@ -45,6 +45,18 @@ #define MATCH_AND_FILTER(args, code) ((args)->data[KNOT_CTL_IDX_FILTER] != NULL && \ strchr((args)->data[KNOT_CTL_IDX_FILTER], (code)) != NULL) +static void schedule_trigger(zone_t *zone, ctl_args_t *args, zone_event_type_t event, + bool user) +{ + if (ctl_has_flag(args->data[KNOT_CTL_IDX_FLAGS], CTL_FLAG_BLOCKING)) { + zone_events_schedule_blocking(zone, event, user); + } else if (user) { + zone_events_schedule_user(zone, event); + } else { + zone_events_schedule_now(zone, event); + } +} + void ctl_log_data(knot_ctl_data_t *data) { if (data == NULL) { @@ -281,7 +293,7 @@ static int zone_reload(zone_t *zone, ctl_args_t *args) return KNOT_ENOTSUP; } - zone_events_schedule_user(zone, ZONE_EVENT_LOAD); + schedule_trigger(zone, args, ZONE_EVENT_LOAD, true); return KNOT_EOK; } @@ -294,7 +306,7 @@ static int zone_refresh(zone_t *zone, ctl_args_t *args) return KNOT_ENOTSUP; } - zone_events_schedule_user(zone, ZONE_EVENT_REFRESH); + schedule_trigger(zone, args, ZONE_EVENT_REFRESH, true); return KNOT_EOK; } @@ -308,7 +320,7 @@ static int zone_retransfer(zone_t *zone, ctl_args_t *args) } zone->flags |= ZONE_FORCE_AXFR; - zone_events_schedule_user(zone, ZONE_EVENT_REFRESH); + schedule_trigger(zone, args, ZONE_EVENT_REFRESH, true); return KNOT_EOK; } @@ -317,7 +329,7 @@ static int zone_notify(zone_t *zone, ctl_args_t *args) { UNUSED(args); - zone_events_schedule_user(zone, ZONE_EVENT_NOTIFY); + schedule_trigger(zone, args, ZONE_EVENT_NOTIFY, true); return KNOT_EOK; } @@ -332,7 +344,7 @@ static int zone_flush(zone_t *zone, ctl_args_t *args) zone->flags |= ZONE_FORCE_FLUSH; } - zone_events_schedule_user(zone, ZONE_EVENT_FLUSH); + schedule_trigger(zone, args, ZONE_EVENT_FLUSH, true); return KNOT_EOK; } @@ -347,7 +359,7 @@ static int zone_sign(zone_t *zone, ctl_args_t *args) } zone->flags |= ZONE_FORCE_RESIGN; - zone_events_schedule_user(zone, ZONE_EVENT_DNSSEC); + schedule_trigger(zone, args, ZONE_EVENT_DNSSEC, true); return KNOT_EOK; } @@ -368,7 +380,7 @@ static int zone_key_roll(zone_t *zone, ctl_args_t *args) return KNOT_EINVAL; } - zone_events_schedule_user(zone, ZONE_EVENT_DNSSEC); + schedule_trigger(zone, args, ZONE_EVENT_DNSSEC, true); return KNOT_EOK; } @@ -390,7 +402,7 @@ static int zone_ksk_sbm_confirm(zone_t *zone, ctl_args_t *args) conf_val_t val = conf_zone_get(conf(), C_DNSSEC_SIGNING, zone->name); if (ret == KNOT_EOK && conf_bool(&val)) { // NOT zone_events_schedule_user(), intentionally! - zone_events_schedule_now(zone, ZONE_EVENT_DNSSEC); + schedule_trigger(zone, args, ZONE_EVENT_DNSSEC, false); } return ret; @@ -400,7 +412,7 @@ static int zone_freeze(zone_t *zone, ctl_args_t *args) { UNUSED(args); - zone_events_schedule_now(zone, ZONE_EVENT_UFREEZE); + schedule_trigger(zone, args, ZONE_EVENT_UFREEZE, false); return KNOT_EOK; } @@ -409,7 +421,7 @@ static int zone_thaw(zone_t *zone, ctl_args_t *args) { UNUSED(args); - zone_events_schedule_now(zone, ZONE_EVENT_UTHAW); + schedule_trigger(zone, args, ZONE_EVENT_UTHAW, false); return KNOT_EOK; } @@ -1144,7 +1156,7 @@ static int zone_purge(zone_t *zone, ctl_args_t *args) // Expire the zone. if (MATCH_OR_FILTER(args, CTL_FILTER_PURGE_EXPIRE)) { - zone_events_schedule_user(zone, ZONE_EVENT_EXPIRE); + schedule_trigger(zone, args, ZONE_EVENT_EXPIRE, true); } // Purge the zone file. diff --git a/src/knot/ctl/commands.h b/src/knot/ctl/commands.h index 8ff1a0d39d..1356da1deb 100644 --- a/src/knot/ctl/commands.h +++ b/src/knot/ctl/commands.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 CZ.NIC, z.s.p.o. +/* Copyright (C) 2019 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,9 +19,10 @@ #include "libknot/libknot.h" #include "knot/server/server.h" -#define CTL_FLAG_FORCE "F" -#define CTL_FLAG_ADD "+" -#define CTL_FLAG_REM "-" +#define CTL_FLAG_FORCE "F" +#define CTL_FLAG_BLOCKING "B" +#define CTL_FLAG_ADD "+" +#define CTL_FLAG_REM "-" #define CTL_FILTER_FLUSH_OUTDIR 'd' diff --git a/src/utils/knotc/commands.c b/src/utils/knotc/commands.c index 0bf99f74c7..ef495a61aa 100644 --- a/src/utils/knotc/commands.c +++ b/src/utils/knotc/commands.c @@ -442,7 +442,7 @@ static int cmd_ctl(cmd_args_t *args) knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL, + [KNOT_CTL_IDX_FLAGS] = args->flags, [KNOT_CTL_IDX_TYPE] = args->argc > 0 ? args->argv[0] : NULL }; @@ -497,7 +497,7 @@ static int cmd_stats_ctl(cmd_args_t *args) { knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL + [KNOT_CTL_IDX_FLAGS] = args->flags, }; int ret = set_stats_items(args, &data); @@ -656,7 +656,7 @@ static int cmd_zone_key_roll_ctl(cmd_args_t *args) knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL, + [KNOT_CTL_IDX_FLAGS] = args->flags, [KNOT_CTL_IDX_ZONE] = args->argv[0], [KNOT_CTL_IDX_TYPE] = args->argv[1], }; @@ -671,7 +671,7 @@ static int cmd_zone_ctl(cmd_args_t *args) { knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL + [KNOT_CTL_IDX_FLAGS] = args->flags, }; // Check the number of arguments. @@ -763,7 +763,7 @@ static int cmd_zone_filter_ctl(cmd_args_t *args) { knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL + [KNOT_CTL_IDX_FLAGS] = args->flags, }; if (args->desc->cmd == CTL_ZONE_PURGE && !args->force) { @@ -919,7 +919,7 @@ static int cmd_zone_node_ctl(cmd_args_t *args) { knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL + [KNOT_CTL_IDX_FLAGS] = args->flags, }; char rdata[65536]; // Maximum item size in libknot control interface. @@ -1040,7 +1040,7 @@ static int cmd_conf_ctl(cmd_args_t *args) knot_ctl_data_t data = { [KNOT_CTL_IDX_CMD] = ctl_cmd_to_str(args->desc->cmd), - [KNOT_CTL_IDX_FLAGS] = args->force ? CTL_FLAG_FORCE : NULL + [KNOT_CTL_IDX_FLAGS] = args->flags, }; // Send the command without parameters. @@ -1137,16 +1137,16 @@ static const cmd_help_t cmd_help_table[] = { { "", "", "" }, { CMD_ZONE_CHECK, "[...]", "Check if the zone can be loaded. (*)" }, { CMD_ZONE_MEMSTATS, "[...]", "Estimate memory use for the zone. (*)" }, - { CMD_ZONE_RELOAD, "[...]", "Reload a zone from a disk." }, - { CMD_ZONE_REFRESH, "[...]", "Force slave zone refresh." }, - { CMD_ZONE_NOTIFY, "[...]", "Send a NOTIFY message to all configured remotes." }, - { CMD_ZONE_RETRANSFER, "[...]", "Force slave zone retransfer (no serial check)." }, - { CMD_ZONE_FLUSH, "[...] [...]", "Flush zone journal into the zone file." }, - { CMD_ZONE_SIGN, "[...]", "Re-sign the automatically signed zone." }, - { CMD_ZONE_KEY_ROLL, " ksk|zsk", "Trigger immediate key rollover." }, - { CMD_ZONE_KSK_SBM, " ...", "When KSK submission, confirm parent's DS presence." }, - { CMD_ZONE_FREEZE, "[...]", "Temporarily postpone automatic zone-changing events." }, - { CMD_ZONE_THAW, "[...]", "Dismiss zone freeze." }, + { CMD_ZONE_RELOAD, "[...]", "Reload a zone from a disk. (#)" }, + { CMD_ZONE_REFRESH, "[...]", "Force slave zone refresh. (#)" }, + { CMD_ZONE_NOTIFY, "[...]", "Send a NOTIFY message to all configured remotes. (#)" }, + { CMD_ZONE_RETRANSFER, "[...]", "Force slave zone retransfer (no serial check). (#)" }, + { CMD_ZONE_FLUSH, "[...] [...]", "Flush zone journal into the zone file. (#)" }, + { CMD_ZONE_SIGN, "[...]", "Re-sign the automatically signed zone. (#)" }, + { CMD_ZONE_KEY_ROLL, " ksk|zsk", "Trigger immediate key rollover. (#)" }, + { CMD_ZONE_KSK_SBM, " ...", "When KSK submission, confirm parent's DS presence. (#)" }, + { CMD_ZONE_FREEZE, "[...]", "Temporarily postpone automatic zone-changing events. (#)" }, + { CMD_ZONE_THAW, "[...]", "Dismiss zone freeze. (#)" }, { "", "", "" }, { CMD_ZONE_READ, " [ []]", "Get zone data that are currently being presented." }, { CMD_ZONE_BEGIN, "...", "Begin a zone transaction." }, @@ -1156,7 +1156,7 @@ static const cmd_help_t cmd_help_table[] = { { CMD_ZONE_GET, " [ []]", "Get zone data within the transaction." }, { CMD_ZONE_SET, " [] ", "Add zone record within the transaction." }, { CMD_ZONE_UNSET, " [ []]", "Remove zone data within the transaction." }, - { CMD_ZONE_PURGE, "... [...]", "Purge zone data, zone file, journal, timers, and KASP data." }, + { CMD_ZONE_PURGE, "... [...]", "Purge zone data, zone file, journal, timers, and KASP data. (#)" }, { CMD_ZONE_STATS, " [[.]]", "Show zone statistics counter(s)."}, { CMD_ZONE_STATUS, " [...]", "Show the zone status." }, { "", "", "" }, @@ -1190,5 +1190,6 @@ void print_commands(void) " Empty or '--' parameter means all zones or all zones with a transaction.\n" " Type parameter in the form of
[]..\n" " (*) indicates a local operation which requires a configuration.\n" - " Use '--force' or '-f' as the first parameter of any command to force it.\n"); + " (#) indicates an optionally blocking operation.\n" + " The '-b' and '-f' options can be placed right after the command name.\n"); } diff --git a/src/utils/knotc/commands.h b/src/utils/knotc/commands.h index 8e2fd5cdd3..efbd474872 100644 --- a/src/utils/knotc/commands.h +++ b/src/utils/knotc/commands.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 CZ.NIC, z.s.p.o. +/* Copyright (C) 2019 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,7 +43,9 @@ typedef struct { knot_ctl_t *ctl; int argc; const char **argv; + char flags[4]; bool force; + bool blocking; } cmd_args_t; /*! \brief Command callback description. */ diff --git a/src/utils/knotc/main.c b/src/utils/knotc/main.c index 81780ac75e..7ad4d4c9c3 100644 --- a/src/utils/knotc/main.c +++ b/src/utils/knotc/main.c @@ -43,6 +43,7 @@ static void print_help(void) " "SPACE" (default %s)\n" " -t, --timeout "SPACE"Use a control socket timeout (max 7200 seconds).\n" " "SPACE" (default %u seconds)\n" + " -b, --blocking "SPACE"Zone event trigger commands wait until the event is finished.\n" " -f, --force "SPACE"Forced operation. Overrides some checks.\n" " -v, --verbose "SPACE"Enable debug output.\n" " -h, --help "SPACE"Print the program help.\n" @@ -67,6 +68,7 @@ int main(int argc, char **argv) { "max-conf-size", required_argument, NULL, 'm' }, { "socket", required_argument, NULL, 's' }, { "timeout", required_argument, NULL, 't' }, + { "blocking", no_argument, NULL, 'b' }, { "force", no_argument, NULL, 'f' }, { "verbose", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, @@ -76,7 +78,7 @@ int main(int argc, char **argv) /* Parse command line arguments */ int opt = 0; - while ((opt = getopt_long(argc, argv, "+c:C:m:s:t:fvhV", opts, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+c:C:m:s:t:bfvhV", opts, NULL)) != -1) { switch (opt) { case 'c': params.config = optarg; @@ -103,6 +105,9 @@ int main(int argc, char **argv) /* Convert to milliseconds. */ params.timeout *= 1000; break; + case 'b': + params.blocking = true; + break; case 'f': params.force = true; break; diff --git a/src/utils/knotc/process.c b/src/utils/knotc/process.c index b53f7bb1ab..8666c02ca8 100644 --- a/src/utils/knotc/process.c +++ b/src/utils/knotc/process.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 CZ.NIC, z.s.p.o. +/* Copyright (C) 2019 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,8 +14,10 @@ along with this program. If not, see . */ +#include #include +#include "contrib/openbsd/strlcat.h" #include "knot/conf/conf.h" #include "knot/common/log.h" #include "utils/knotc/commands.h" @@ -47,6 +49,14 @@ static bool get_cmd_force_flag(const char *arg) return false; } +static bool get_cmd_blocking_flag(const char *arg) +{ + if (strcmp(arg, "-b") == 0 || strcmp(arg, "--blocking") == 0) { + return true; + } + return false; +} + int set_config(const cmd_desc_t *desc, params_t *params) { if (params->config != NULL && params->confdb != NULL) { @@ -225,14 +235,31 @@ int process_cmd(int argc, const char **argv, params_t *params) .desc = desc, .argc = argc - 1, .argv = argv + 1, - .force = params->force + .force = params->force, + .blocking = params->blocking }; - /* Check for --force flag after command. */ - if (args.argc > 0 && get_cmd_force_flag(args.argv[0])) { - args.force = true; - args.argc--; - args.argv++; + /* Check for special flags after command. */ + while (args.argc > 0) { + if (get_cmd_force_flag(args.argv[0])) { + args.force = true; + args.argc--; + args.argv++; + } else if (get_cmd_blocking_flag(args.argv[0])) { + args.blocking = true; + args.argc--; + args.argv++; + } else { + break; + } + } + + /* Prepare flags parameter. */ + if (args.force) { + strlcat(args.flags, CTL_FLAG_FORCE, sizeof(args.flags)); + } + if (args.blocking) { + strlcat(args.flags, CTL_FLAG_BLOCKING, sizeof(args.flags)); } /* Set control interface if necessary. */ diff --git a/src/utils/knotc/process.h b/src/utils/knotc/process.h index 29f61dd61c..d4dd2450e5 100644 --- a/src/utils/knotc/process.h +++ b/src/utils/knotc/process.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 CZ.NIC, z.s.p.o. +/* Copyright (C) 2019 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ typedef struct { const char *socket; bool verbose; bool force; + bool blocking; int timeout; } params_t;