]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
knotc: add blocking mode for zone event triggers
authorJan Hák <jan.hak@nic.cz>
Fri, 24 May 2019 12:03:50 +0000 (14:03 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Wed, 29 May 2019 18:51:24 +0000 (20:51 +0200)
doc/man/knotc.8in
doc/man_knotc.rst
src/knot/ctl/commands.c
src/knot/ctl/commands.h
src/utils/knotc/commands.c
src/utils/knotc/commands.h
src/utils/knotc/main.c
src/utils/knotc/process.c
src/utils/knotc/process.h

index ea00e393fa9cbd9e79d2e8a6d6fd0a5d25b7ed83..8a3a2aa4dbdc72c9f1087dab30e7d8be57f9b271 100644 (file)
@@ -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,
index e4fd7d5b20e88b3f6bec3dabbc1c7afc2fa72a56..919ec99b8706fada4eeb391a6c21e9ebe79d6c88 100644 (file)
@@ -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
 ................
index 67de1ac23f0c4ae2b9b46c451a8aa0c67025e137..ee6f894787012a79cfe91a261e7aaa50c1f435b7 100644 (file)
 #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.
index 8ff1a0d39dd98064099214b3d139b5fe25cfbdc4..1356da1deb8ebe0995c6b9ea00ada9583c2cec57 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     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
 #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'
 
index 0bf99f74c7830a0650d51ccd02fb29440723e174..ef495a61aa658c5f89796be009ac28ee8a13761a 100644 (file)
@@ -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,      "[<zone>...]",                            "Check if the zone can be loaded. (*)" },
        { CMD_ZONE_MEMSTATS,   "[<zone>...]",                            "Estimate memory use for the zone. (*)" },
-       { CMD_ZONE_RELOAD,     "[<zone>...]",                            "Reload a zone from a disk." },
-       { CMD_ZONE_REFRESH,    "[<zone>...]",                            "Force slave zone refresh." },
-       { CMD_ZONE_NOTIFY,     "[<zone>...]",                            "Send a NOTIFY message to all configured remotes." },
-       { CMD_ZONE_RETRANSFER, "[<zone>...]",                            "Force slave zone retransfer (no serial check)." },
-       { CMD_ZONE_FLUSH,      "[<zone>...] [<filter>...]",              "Flush zone journal into the zone file." },
-       { CMD_ZONE_SIGN,       "[<zone>...]",                            "Re-sign the automatically signed zone." },
-       { CMD_ZONE_KEY_ROLL,   " <zone> ksk|zsk",                        "Trigger immediate key rollover." },
-       { CMD_ZONE_KSK_SBM,    " <zone>...",                             "When KSK submission, confirm parent's DS presence." },
-       { CMD_ZONE_FREEZE,     "[<zone>...]",                            "Temporarily postpone automatic zone-changing events." },
-       { CMD_ZONE_THAW,       "[<zone>...]",                            "Dismiss zone freeze." },
+       { CMD_ZONE_RELOAD,     "[<zone>...]",                            "Reload a zone from a disk. (#)" },
+       { CMD_ZONE_REFRESH,    "[<zone>...]",                            "Force slave zone refresh. (#)" },
+       { CMD_ZONE_NOTIFY,     "[<zone>...]",                            "Send a NOTIFY message to all configured remotes. (#)" },
+       { CMD_ZONE_RETRANSFER, "[<zone>...]",                            "Force slave zone retransfer (no serial check). (#)" },
+       { CMD_ZONE_FLUSH,      "[<zone>...] [<filter>...]",              "Flush zone journal into the zone file. (#)" },
+       { CMD_ZONE_SIGN,       "[<zone>...]",                            "Re-sign the automatically signed zone. (#)" },
+       { CMD_ZONE_KEY_ROLL,   " <zone> ksk|zsk",                        "Trigger immediate key rollover. (#)" },
+       { CMD_ZONE_KSK_SBM,    " <zone>...",                             "When KSK submission, confirm parent's DS presence. (#)" },
+       { CMD_ZONE_FREEZE,     "[<zone>...]",                            "Temporarily postpone automatic zone-changing events. (#)" },
+       { CMD_ZONE_THAW,       "[<zone>...]",                            "Dismiss zone freeze. (#)" },
        { "",                  "",                                       "" },
        { CMD_ZONE_READ,       "<zone> [<owner> [<type>]]",              "Get zone data that are currently being presented." },
        { CMD_ZONE_BEGIN,      "<zone>...",                              "Begin a zone transaction." },
@@ -1156,7 +1156,7 @@ static const cmd_help_t cmd_help_table[] = {
        { CMD_ZONE_GET,        "<zone> [<owner> [<type>]]",              "Get zone data within the transaction." },
        { CMD_ZONE_SET,        "<zone>  <owner> [<ttl>] <type> <rdata>", "Add zone record within the transaction." },
        { CMD_ZONE_UNSET,      "<zone>  <owner> [<type> [<rdata>]]",     "Remove zone data within the transaction." },
-       { CMD_ZONE_PURGE,      "<zone>... [<filter>...]",                "Purge zone data, zone file, journal, timers, and KASP data." },
+       { CMD_ZONE_PURGE,      "<zone>... [<filter>...]",                "Purge zone data, zone file, journal, timers, and KASP data. (#)" },
        { CMD_ZONE_STATS,      "<zone> [<module>[.<counter>]]",          "Show zone statistics counter(s)."},
        { CMD_ZONE_STATUS,     "<zone> [<filter>...]",                   "Show the zone status." },
        { "",                  "",                                       "" },
@@ -1190,5 +1190,6 @@ void print_commands(void)
               " Empty or '--' <zone> parameter means all zones or all zones with a transaction.\n"
               " Type <item> parameter in the form of <section>[<identifier>].<name>.\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");
 }
index 8e2fd5cdd31e2badea0e09277d9c04bcc20b2ed4..efbd4748729e767a63ee6c9b02fd8896cbcf1c03 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     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. */
index 81780ac75e020814aebcc5d384fff404e0d4acab..7ad4d4c9c3b0a72d92ac1cc6b980d2b38788dc45 100644 (file)
@@ -43,6 +43,7 @@ static void print_help(void)
               "                          "SPACE" (default %s)\n"
               " -t, --timeout <sec>      "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;
index b53f7bb1ab3659b17b32afeb8a5ada37e435fc75..8666c02ca867a6e0b410be16135dc1753207650e 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     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
     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
+#include <stddef.h>
 #include <sys/stat.h>
 
+#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. */
index 29f61dd61c0f0b637bf71b648d5a0799dfb5b229..d4dd2450e51c8b56bee0b667bd4f9dcfcda18076 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     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;