By being able to start up ovn-northd-ddlog in a paused state, we can produce a recording for use in debugging without having to restart one of the real ovn-northd-ddlog processes or disturbing the system.
Signed-off-by: Ben Pfaff <[email protected]> CC: Ihar Hrachyshka <[email protected]> --- NEWS | 2 +- northd/ovn-northd-ddlog.c | 43 ++++++++++++++++++++++++--------------- northd/ovn-northd.8.xml | 25 ++++++++++++++++++++--- northd/ovn-northd.c | 19 ++++++++++++----- tests/ovn-macros.at | 22 ++++++++++++++------ tests/ovn-northd.at | 16 +++++++-------- 6 files changed, 88 insertions(+), 39 deletions(-) diff --git a/NEWS b/NEWS index f96ed73f0823..96c9397361a2 100644 --- a/NEWS +++ b/NEWS @@ -18,7 +18,7 @@ Post-v21.03.0 datapath flows with this field used. - Introduce a new "allow-stateless" ACL verb to always bypass connection tracking. The existing "allow" verb behavior is left intact. - - Added support in native DNS to respond to PTR request types. + - New --dry-run option for ovn-northd and ovn-northd-ddlog. OVN v21.03.0 - 12 Mar 2021 ------------------------- diff --git a/northd/ovn-northd-ddlog.c b/northd/ovn-northd-ddlog.c index c79e15312b64..73bf5290eb35 100644 --- a/northd/ovn-northd-ddlog.c +++ b/northd/ovn-northd-ddlog.c @@ -159,7 +159,8 @@ northd_ctx_create(const char *server, const char *database, ddlog_prog ddlog, ddlog_delta *delta, const char **input_relations, const char **output_relations, - const char **output_only_relations) + const char **output_only_relations, + bool paused) { struct northd_ctx *ctx = xmalloc(sizeof *ctx); *ctx = (struct northd_ctx) { @@ -175,7 +176,7 @@ northd_ctx_create(const char *server, const char *database, .db_name = database, /* 'output_only_relations' will get filled in later. */ .lock_name = lock_name, - .paused = false, + .paused = paused, }; ovsdb_cs_set_remote(ctx->cs, server, true); @@ -1041,7 +1042,7 @@ static void usage(void) { printf("\ -%s: OVN northbound management daemon\n\ +%s: OVN northbound management daemon (DDlog version)\n\ usage: %s [OPTIONS]\n\ \n\ Options:\n\ @@ -1049,6 +1050,7 @@ Options:\n\ (default: %s)\n\ --ovnsb-db=DATABASE connect to ovn-sb database at DATABASE\n\ (default: %s)\n\ + --dry-run start in paused state (do not commit db changes)\n\ --ddlog-record=FILE.TXT record db changes to replay later for debugging\n\ --unixctl=SOCKET override default control socket name\n\ -h, --help display this help message\n\ @@ -1061,22 +1063,25 @@ Options:\n\ } static void -parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED, + bool *pause) { enum { OVN_DAEMON_OPTION_ENUMS, VLOG_OPTION_ENUMS, SSL_OPTION_ENUMS, + OPT_DRY_RUN, OPT_DDLOG_RECORD }; static const struct option long_options[] = { - {"ddlog-record", required_argument, NULL, OPT_DDLOG_RECORD}, {"ovnsb-db", required_argument, NULL, 'd'}, {"ovnnb-db", required_argument, NULL, 'D'}, {"unixctl", required_argument, NULL, 'u'}, {"help", no_argument, NULL, 'h'}, {"options", no_argument, NULL, 'o'}, {"version", no_argument, NULL, 'V'}, + {"dry-run", no_argument, NULL, OPT_DRY_RUN}, + {"ddlog-record", required_argument, NULL, OPT_DDLOG_RECORD}, OVN_DAEMON_LONG_OPTIONS, VLOG_LONG_OPTIONS, STREAM_SSL_LONG_OPTIONS, @@ -1097,10 +1102,6 @@ parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) VLOG_OPTION_HANDLERS; STREAM_SSL_OPTION_HANDLERS; - case OPT_DDLOG_RECORD: - record_file = optarg; - break; - case 'd': ovnsb_db = optarg; break; @@ -1125,6 +1126,14 @@ parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) ovs_print_version(0, 0); exit(EXIT_SUCCESS); + case OPT_DRY_RUN: + *pause = true; + break; + + case OPT_DDLOG_RECORD: + record_file = optarg; + break; + default: break; } @@ -1148,6 +1157,10 @@ main(int argc, char *argv[]) struct unixctl_server *unixctl; int retval; bool exiting; + struct northd_status status = { + .locked = false, + .pause = false, + }; init_table_ids(); @@ -1155,7 +1168,7 @@ main(int argc, char *argv[]) ovs_cmdl_proctitle_init(argc, argv); set_program_name(argv[0]); service_start(&argc, &argv); - parse_options(argc, argv); + parse_options(argc, argv, &status.pause); daemonize_start(false); @@ -1167,10 +1180,6 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } - struct northd_status status = { - .locked = false, - .pause = false, - }; unixctl_command_register("exit", "", 0, 0, ovn_northd_exit, &exiting); unixctl_command_register("status", "", 0, 0, ovn_northd_status, &status); @@ -1202,10 +1211,12 @@ main(int argc, char *argv[]) struct northd_ctx *nb_ctx = northd_ctx_create( ovnnb_db, "OVN_Northbound", "nb", NULL, ddlog, delta, - nb_input_relations, nb_output_relations, nb_output_only_relations); + nb_input_relations, nb_output_relations, nb_output_only_relations, + status.pause); struct northd_ctx *sb_ctx = northd_ctx_create( ovnsb_db, "OVN_Southbound", "sb", "ovn_northd", ddlog, delta, - sb_input_relations, sb_output_relations, sb_output_only_relations); + sb_input_relations, sb_output_relations, sb_output_only_relations, + status.pause); unixctl_command_register("pause", "", 0, 0, ovn_northd_pause, sb_ctx); unixctl_command_register("resume", "", 0, 0, ovn_northd_resume, sb_ctx); diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index b7214b05e7ed..0c75d0795817 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -52,6 +52,22 @@ <code>debugging-ddlog.rst</code> in the OVN documentation for more details. </dd> + <dt><code>--dry-run</code></dt> + <dd> + <p> + Causes <code>ovn-northd</code> to start paused. In the paused state, + <code>ovn-northd</code> does not apply any changes to the databases, + although it continues to monitor them. For more information, see the + <code>pause</code> command, under <code>Runtime Management + Commands</code> below. + </p> + + <p> + For <code>ovn-northd-ddlog</code>, one could use this option with + <code>--ddlog-record</code> to generate a replay log without + restarting a process or disturbing a running system. + </p> + </dd> </dl> <p> <var>database</var> in the above options must be an OVSDB active or @@ -91,9 +107,12 @@ <dt><code>pause</code></dt> <dd> - Pauses the ovn-northd operation from processing any Northbound and - Southbound database changes. This will also instruct ovn-northd to - drop any lock on SB DB. + Pauses <code>ovn-northd</code>. When it is paused, + <code>ovn-northd</code> receives changes from the Northbound and + Southbound database changes as usual, but it does not send any updates. + A paused <code>ovn-northd</code> also drops database locks, which + allows any other non-paused instance of <code>ovn-northd</code> to take + over. </dd> <dt><code>resume</code></dt> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 0e5092a875ff..f97b23dec0b2 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -401,6 +401,7 @@ Options:\n\ (default: %s)\n\ --ovnsb-db=DATABASE connect to ovn-sb database at DATABASE\n\ (default: %s)\n\ + --dry-run start in paused state (do not commit db changes)\n\ --unixctl=SOCKET override default control socket name\n\ -h, --help display this help message\n\ -o, --options list available options\n\ @@ -13977,12 +13978,14 @@ ovn_db_run(struct northd_context *ctx, } static void -parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED, + bool *paused) { enum { OVN_DAEMON_OPTION_ENUMS, VLOG_OPTION_ENUMS, SSL_OPTION_ENUMS, + OPT_DRY_RUN, }; static const struct option long_options[] = { {"ovnsb-db", required_argument, NULL, 'd'}, @@ -13991,6 +13994,7 @@ parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) {"help", no_argument, NULL, 'h'}, {"options", no_argument, NULL, 'o'}, {"version", no_argument, NULL, 'V'}, + {"dry-run", no_argument, NULL, OPT_DRY_RUN}, OVN_DAEMON_LONG_OPTIONS, VLOG_LONG_OPTIONS, STREAM_SSL_LONG_OPTIONS, @@ -14035,6 +14039,10 @@ parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) ovn_print_version(0, 0); exit(EXIT_SUCCESS); + case OPT_DRY_RUN: + *paused = true; + break; + default: break; } @@ -14066,13 +14074,16 @@ main(int argc, char *argv[]) struct unixctl_server *unixctl; int retval; bool exiting; - struct northd_state state; + struct northd_state state = { + .had_lock = false, + .paused = false + }; fatal_ignore_sigpipe(); ovs_cmdl_proctitle_init(argc, argv); ovn_set_program_name(argv[0]); service_start(&argc, &argv); - parse_options(argc, argv); + parse_options(argc, argv, &state.paused); daemonize_start(false); @@ -14371,8 +14382,6 @@ main(int argc, char *argv[]) /* Main loop. */ exiting = false; - state.had_lock = false; - state.paused = false; while (!exiting) { memory_run(); diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at index 94fba405ea33..2217131ab234 100644 --- a/tests/ovn-macros.at +++ b/tests/ovn-macros.at @@ -149,8 +149,12 @@ ovn_init_ic_db () { ovn_init_db ovn-ic-sb } -# ovn_start_northd (primary|backup) [AZ] +# ovn_start_northd [--paused] (primary|backup) [AZ] ovn_start_northd() { + local northd_args= + case $1 in + --paused) northd_args=--dry-run; shift ;; + esac local priority=$1 local AZ=$2 local msg_prefix=${AZ:+$AZ: } @@ -161,10 +165,9 @@ ovn_start_northd() { backup) suffix=-backup ;; esac - local northd_args= case ${NORTHD_TYPE:=ovn-northd} in ovn-northd) ;; - ovn-northd-ddlog) northd_args="--ddlog-record=${AZ:+$AZ/}northd$suffix/replay.dat -v" ;; + ovn-northd-ddlog) northd_args="$northd_args --ddlog-record=${AZ:+$AZ/}northd$suffix/replay.dat -v" ;; esac local name=${d_prefix}northd${suffix} @@ -174,16 +177,23 @@ ovn_start_northd() { --ovnnb-db=$OVN_NB_DB --ovnsb-db=$OVN_SB_DB } -# ovn_start [--no-backup-northd] [AZ] +# ovn_start [--backup-northd=none|paused] [AZ] # # Creates and initializes ovn-sb and ovn-nb databases and starts their # ovsdb-server instance, sets appropriate environment variables so that # ovn-sbctl and ovn-nbctl use them by default, and starts ovn-northd running # against them. +# +# Normally this starts an active northd and a backup norhtd. The following +# options are accepted to adjust that: +# --backup-northd=none Don't start a backup northd. +# --backup-northd=paused Start the backup northd in the paused state. ovn_start () { local backup_northd=: + local backup_northd_options= case $1 in - --no-backup-northd) backup_northd=false; shift ;; + --backup-northd=none) backup_northd=false; shift ;; + --backup-northd=paused) backup_northd_options=--paused; shift ;; esac local AZ=$1 local msg_prefix=${AZ:+$AZ: } @@ -201,7 +211,7 @@ ovn_start () { ovn_start_northd primary $AZ if $backup_northd; then - ovn_start_northd backup $AZ + ovn_start_northd $backup_northd_options backup $AZ fi if test X$HAVE_OPENSSL = Xyes; then diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index bff2ade43b4d..28a46702cf48 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -641,7 +641,10 @@ AT_CLEANUP OVN_FOR_EACH_NORTHD([ AT_SETUP([ovn -- ovn-northd pause and resume]) -ovn_start +# By starting the backup northd paused, we ensure that the primary +# northd is active; otherwise, there's a race. (We also test that +# the ovn-northd --dry-run option works.) +ovn_start --backup-northd=paused get_northd_status() { as northd ovn-appctl -t NORTHD_TYPE is-paused @@ -650,10 +653,7 @@ get_northd_status() { as northd-backup ovn-appctl -t NORTHD_TYPE status } -AS_BOX([Pause the backup]) -# This forces the main northd to become active (otherwise there's no -# guarantee, ovn_start is racy). -check as northd-backup ovs-appctl -t NORTHD_TYPE pause +AS_BOX([Check that the backup is paused]) OVS_WAIT_FOR_OUTPUT([get_northd_status], [0], [false Status: active true @@ -709,7 +709,7 @@ AT_CLEANUP OVN_FOR_EACH_NORTHD([ AT_SETUP([ovn -- ovn-northd restart]) -ovn_start --no-backup-northd +ovn_start --backup-northd=none # Check that ovn-northd is active, by verifying that it creates and # destroys southbound datapaths as one would expect. @@ -741,7 +741,7 @@ dnl This test doesn't take into account flows that are shared between dnl datapaths when datapath groups are enabled. AT_SKIP_IF([test NORTHD_USE_DP_GROUPS = yes]) -ovn_start --no-backup-northd +ovn_start --backup-northd=none # Check that ovn-northd is active, by verifying that it creates and # destroys southbound datapaths as one would expect. @@ -781,7 +781,7 @@ dnl This test doesn't take into account flows that are shared between dnl datapaths when datapath groups are enabled. AT_SKIP_IF([test NORTHD_USE_DP_GROUPS = yes]) -ovn_start --no-backup-northd +ovn_start --backup-northd=none # Check that ovn-northd is active, by verifying that it creates and # destroys southbound datapaths as one would expect. -- 2.31.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
