Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2225718/?format=api
{ "id": 2225718, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2225718/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/2d2ee49b763ef6b195ccf627869d7538db8aac19.1776780072.git.felix.huettner@digits.schwarz/", "project": { "id": 47, "url": "http://patchwork.ozlabs.org/api/1.1/projects/47/?format=api", "name": "Open vSwitch", "link_name": "openvswitch", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "git@github.com:openvswitch/ovs.git", "webscm_url": "https://github.com/openvswitch/ovs" }, "msgid": "<2d2ee49b763ef6b195ccf627869d7538db8aac19.1776780072.git.felix.huettner@digits.schwarz>", "date": "2026-04-21T14:02:44", "name": "[ovs-dev,v3,1/2] ovsdb: Support custom transaction history size.", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "2e8ec0b0d262338ec15f6b7a649e128f7b146a6f", "submitter": { "id": 92762, "url": "http://patchwork.ozlabs.org/api/1.1/people/92762/?format=api", "name": "Felix Huettner", "email": "felix.huettner@digits.schwarz" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/2d2ee49b763ef6b195ccf627869d7538db8aac19.1776780072.git.felix.huettner@digits.schwarz/mbox/", "series": [ { "id": 500809, "url": "http://patchwork.ozlabs.org/api/1.1/series/500809/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=500809", "date": "2026-04-21T14:02:44", "name": "[ovs-dev,v3,1/2] ovsdb: Support custom transaction history size.", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/500809/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2225718/comments/", "check": "success", "checks": "http://patchwork.ozlabs.org/api/patches/2225718/checks/", "tags": {}, "headers": { "Return-Path": "<ovs-dev-bounces@openvswitch.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "dev@openvswitch.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "ovs-dev@lists.linuxfoundation.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=SNgbj5/Y;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)", "smtp2.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key,\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=SNgbj5/Y", "smtp3.osuosl.org; dmarc=pass (p=reject dis=none)\n header.from=digits.schwarz", "smtp3.osuosl.org; dkim=pass (2048-bit key,\n unprotected) header.d=digits.schwarz header.i=@digits.schwarz\n header.a=rsa-sha256 header.s=google header.b=SNgbj5/Y" ], "Received": [ "from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0PGS6xGrz1yGt\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 00:03:43 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby smtp2.osuosl.org (Postfix) with ESMTP id 710A541FDD;\n\tTue, 21 Apr 2026 14:03:38 +0000 (UTC)", "from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id kALUtAtwbFXO; Tue, 21 Apr 2026 14:03:36 +0000 (UTC)", "from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp2.osuosl.org (Postfix) with ESMTPS id 0943E40090;\n\tTue, 21 Apr 2026 14:03:36 +0000 (UTC)", "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id A5F7BC058E;\n\tTue, 21 Apr 2026 14:03:35 +0000 (UTC)", "from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n by lists.linuxfoundation.org (Postfix) with ESMTP id B2BF2C058D\n for <dev@openvswitch.org>; Tue, 21 Apr 2026 14:03:34 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp3.osuosl.org (Postfix) with ESMTP id 9250B6143D\n for <dev@openvswitch.org>; Tue, 21 Apr 2026 14:03:34 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id TVJ2WKpeYLhD for <dev@openvswitch.org>;\n Tue, 21 Apr 2026 14:03:33 +0000 (UTC)", "from mail-ej1-x662.google.com (mail-ej1-x662.google.com\n [IPv6:2a00:1450:4864:20::662])\n by smtp3.osuosl.org (Postfix) with ESMTPS id 8689B6141D\n for <dev@openvswitch.org>; Tue, 21 Apr 2026 14:03:31 +0000 (UTC)", "by mail-ej1-x662.google.com with SMTP id\n a640c23a62f3a-ba922426c5cso239931966b.3\n for <dev@openvswitch.org>; Tue, 21 Apr 2026 07:03:31 -0700 (PDT)", "from smtpproxy-deployment-574c6c876d-xch8m.de2.smtp.exclaimer.net\n ([20.113.217.23]) by smtp-relay.gmail.com with ESMTPS id\n a640c23a62f3a-ba454d23c82sm87550366b.74.2026.04.21.07.03.27\n for <dev@openvswitch.org>\n (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);\n Tue, 21 Apr 2026 07:03:28 -0700 (PDT)", "from mail-wm1-f71.google.com (209.85.128.71) by\n smtpproxy-deployment-574c6c876d-xch8m.de2.smtp.exclaimer.net\n (20.113.217.16/28) with Exclaimer Signature Manager ESMTP Proxy\n smtpproxy-deployment-574c6c876d-xch8m.de2.smtp.exclaimer.net\n (tlsversion=TLS12, tlscipher=TLS_DIFFIEHELLMAN_WITH_AES256_NONE); Tue, 21\n Apr 2026 14:03:28 +0000", "by mail-wm1-f71.google.com with SMTP id\n 5b1f17b1804b1-488c0fcc6deso24254815e9.2\n for <dev@openvswitch.org>; Tue, 21 Apr 2026 07:03:26 -0700 (PDT)", "from SDGDEU-G5041VBR ([185.124.194.86])\n by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-488fb74c789sm111696645e9.5.2026.04.21.07.03.18\n for <dev@openvswitch.org>\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 21 Apr 2026 07:03:19 -0700 (PDT)" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections -\n client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp2.osuosl.org 0943E40090", "OpenDKIM Filter v2.11.0 smtp3.osuosl.org 8689B6141D" ], "Received-SPF": "Pass (mailfrom) identity=mailfrom;\n client-ip=2a00:1450:4864:20::662; helo=mail-ej1-x662.google.com;\n envelope-from=felix.huettner@digits.schwarz; receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp3.osuosl.org 8689B6141D", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=digits.schwarz; s=google; t=1776780209; x=1777385009; darn=openvswitch.org;\n h=mime-version:mail-followup-to:message-id:subject:to:from:date:from\n :to:cc:subject:date:message-id:reply-to;\n bh=77n234TqH4mNF2Y4r/8G3HJcz9hsAXE6EZhLQozgaKg=;\n b=SNgbj5/YPxUv5aaiSbHForaDMeDOmgR0Cdy+W+7qIXnWOFRzQxz82AuhLRjoQkDEUH\n 19JeaLxljSv/yw3m6zI+tHf2Bi4wQWxh0ZfLy3u5MmOmtTHd3NjhxsfHV8EJ+va6WPyz\n 1ynPgDEygB3cSAyZ8IQn5PJswlx/TkpFP15D1ID8BMQi/18tn9mRMZo+mHu4M4XrPgxs\n iLNnvqRhaJEMrkOObv37as0inIoHSZqTzPGrh/XUFLFthqn/RouxYkxy4Y4ZKYN3EgXw\n rdAE30qlcsSg5bl1H62UcCICpjK6uSnjWkmDMNJqR+7wmVxLhUVKxHrSmGS+0C0RwSy7\n cQZQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776780209; x=1777385009;\n h=mime-version:mail-followup-to:message-id:subject:to:from:date\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=77n234TqH4mNF2Y4r/8G3HJcz9hsAXE6EZhLQozgaKg=;\n b=VKzeW6iRL5JteacLfNbAt/2+4bMnrSxQjVpCrBqRzKcwVztyI9u1zUN0ww9DKO9JZ9\n o5Brjz6yv22jxGlfsU2Ps+Cl4l+RFBUMUWDonrv522CLrDlrPMKSdwzZICnLpM8Wh7G0\n BVoK9uZcuD8QhWVhpj/2H6EHKtC2GnfCUmfa6Q6jc2qVBS43zT2+NiDrBQlcELW9SJPW\n xZSUqmVxX0tk1WIrA6zEc86ZRLHeDktRiJWkLjlzZk17eO9YBpTDM4IxIRNVZxEiqg78\n U7RqH50QakcwC4J8riwYwLUt/TcK0hfaHqdSgM0FGG9HsiPh1fGYzTaNF8463vRzwCNO\n 3uow==", "X-Gm-Message-State": "AOJu0YzMvYKuioNpxjUTESar1IvSs5mtUzT0rIDtU7y+vgnasr0yvq13\n 5EEJVnfTJaTPCrSwkv+Ju8ydqxMsDd/MYL71ArZxUvYzXvWn++HJE+iO9BHfEHQomE0EzBTNNeb\n UyzqYbmZ+F+XyFWHJR4T7wbvlKhEE5OermalSVLnJrXVIK4brR6BhSWHQ074BiO2rKwM5LUmXJ1\n rQunMn7k0A7O4zLhovJLb9nYehuusABLTquoZbt9JrSlfxbgppfcWy6XGc1A13XtQpHhc4rjofd\n tNAFN9GEoo/zs0Th9s=", "X-Gm-Gg": "AeBDiesc+5X7BQiqyIat/fJdmLOo1Dfb/RN/isvhehr5nWQ/NyqBprU1KApkezsStqE\n UIzgznyZrs5tHg1v/GtxJ5YqQEDOypIxhjX0a6D2uSHnj0e4Knsgt/bKHUoeZcjWWtTjSF/yuyE\n 6i/cS2z5ghZxOCFV+3sLQHUsV/QbqQ0GXyKgeD1OpN1xFG5Ze4nqHuO65Q3pFnnQDd+VESpQLy5\n Ox5tK5MNlALG87fwN9blGoSgkVCn6unfeBWoOCIUiIlUvoMbcCY+4mx+K7kkt7hElwvPUgsSLte\n 4AnbZXPLhtCkq3Kqk0g1YCDmJlpEd+SJwcAdmqUYD1BR5DqJMNmVqj+0FencZTUzofg98xwib1d\n d/mCUXZM7Lg6EMxvTOM1X98tVEBzKJsKZe+CnYp2/hPw9nZh0OMxqlMb01RYz9253x6P5UXUt4H\n GWSh8nikIiNWBd+dHxh6lV+e3UqR/01NBK", "X-Received": [ "by 2002:a17:907:9729:b0:b9c:30b7:770f with SMTP id\n a640c23a62f3a-ba41b5d2827mr809165966b.34.1776780208466;\n Tue, 21 Apr 2026 07:03:28 -0700 (PDT)", "by 2002:a05:600c:4707:b0:488:bfc3:efc with SMTP id\n 5b1f17b1804b1-488fb6e8eb5mr262183435e9.0.1776780205539;\n Tue, 21 Apr 2026 07:03:25 -0700 (PDT)", "by 2002:a05:600c:4707:b0:488:bfc3:efc with SMTP id\n 5b1f17b1804b1-488fb6e8eb5mr262176395e9.0.1776780200317;\n Tue, 21 Apr 2026 07:03:20 -0700 (PDT)" ], "X-Relaying-Domain": "digits.schwarz", "X-ExclaimerHostedSignatures-MessageProcessed": "true", "X-ExclaimerProxyLatency": "14826658", "X-ExclaimerImprintLatency": "12146274", "X-ExclaimerImprintAction": "cf245a513edc48ee983c85e3e9fbc895", "Date": "Tue, 21 Apr 2026 16:02:44 +0200", "To": "dev@openvswitch.org", "Message-ID": "\n <2d2ee49b763ef6b195ccf627869d7538db8aac19.1776780072.git.felix.huettner@digits.schwarz>", "Mail-Followup-To": "dev@openvswitch.org", "MIME-Version": "1.0", "X-please-dont-add-a-signature": "thanks", "X-Schwarz-Google-ToExclaimerByDomain": "1", "Content-Disposition": "inline", "X-Content-Filtered-By": "Mailman/MimeDel 2.1.30", "Subject": "[ovs-dev] [PATCH v3 1/2] ovsdb: Support custom transaction history\n size.", "X-BeenThere": "ovs-dev@openvswitch.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "<ovs-dev.openvswitch.org>", "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>", "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>", "List-Post": "<mailto:ovs-dev@openvswitch.org>", "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>", "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>", "From": "Felix Huettner via dev <ovs-dev@openvswitch.org>", "Reply-To": "Felix Huettner <felix.huettner@digits.schwarz>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "ovs-dev-bounces@openvswitch.org", "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>" }, "content": "Previously the transaction history was hard limited to 100 entries.\nHowever in fast changing environments (e.g. with 20 transactions/sec)\nthis means that transactions are only in the history for a few seconds.\nIf now a client reconnects and tries to use monitor_cond_since it has\nonly a short timeframe where this will reliably work.\n\nWe make the history limit configurable here so that use can choose the\nspeed vs memory tradeoff as needed.\nWe still keep the limit based on size of the history, as syncing a\nhistory larger than the actual database size does not make sense in any\nway.\n\nSigned-off-by: Felix Huettner <felix.huettner@digits.schwarz>\n---\nv2->v3: adressed docs and nits as requested by Ilja\nv1->v2: handle setting if the config does not specify the service-model.\n\n Documentation/ref/ovsdb.7.rst | 22 +++++++++++++++++++++\n NEWS | 3 +++\n ovsdb/ovsdb-server.1.in | 4 ++++\n ovsdb/ovsdb-server.c | 27 +++++++++++++++++++++++--\n ovsdb/ovsdb.h | 3 ++-\n ovsdb/relay.c | 4 ++--\n ovsdb/transaction.c | 37 +++++++++++++++++++++++++++++------\n ovsdb/transaction.h | 5 ++++-\n tests/ovsdb-server.at | 25 +++++++++++++++++++++--\n 9 files changed, 116 insertions(+), 14 deletions(-)\n\n\nbase-commit: 1159994824adcd7b45b0b3549c60a9e9a267298f", "diff": "diff --git a/Documentation/ref/ovsdb.7.rst b/Documentation/ref/ovsdb.7.rst\nindex cf1ef3736..1c88238c0 100644\n--- a/Documentation/ref/ovsdb.7.rst\n+++ b/Documentation/ref/ovsdb.7.rst\n@@ -624,6 +624,28 @@ above).\n \n Open vSwitch 2.16 introduced support for relay service model.\n \n+Client Monitors\n+===============\n+\n+Clients requesting monitors using ``\"monitor\"`` or ``\"monitor_cond\"`` will\n+generally receive an initial dump of all of their relevant data when the\n+montior is started. As changes are submitted to the ovsdb it will send updates\n+to the clients. If a client where to reconnect to a ovsdb it would receive a\n+full initial dump again.\n+\n+In case the client uses ``\"monitor_cond_since\"`` it can improve on this\n+reconnect behaviour by providing the ovsdb server with the last known update\n+ID. If the server still has this ID in its history it will respond only with\n+the changes that accumulated since this ID. This feature is only available if\n+the ovsdb server uses the **clustered** service model. It is also available on\n+the **relay** service model if the relay source is a **clustered** service\n+model.\n+\n+The transaction history used for this is limited to the same memory usage as\n+the database itself. In addition it has a limit of 100 entries per default.\n+This can be modified by using ``\"transaction-history-limit\": 1000`` in the\n+configuration of the database.\n+\n Database Replication\n ====================\n \ndiff --git a/NEWS b/NEWS\nindex 1a3044cbf..9b8fd7a54 100644\n--- a/NEWS\n+++ b/NEWS\n@@ -3,6 +3,9 @@ Post-v3.7.0\n - Userspace datapath:\n * ARP/ND lookups for native tunnel are now rate limited. The holdout\n timer can be configured with 'tnl/neigh/retrans_time'.\n+ - OVSDB:\n+ * The transaction history length is now configurable using the config\n+ `\"transaction-history-limit\": 1000`.\n \n \n v3.7.0 - 16 Feb 2026\ndiff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in\nindex 23b8e6e9c..bb4b9a938 100644\n--- a/ovsdb/ovsdb-server.1.in\n+++ b/ovsdb/ovsdb-server.1.in\n@@ -158,6 +158,10 @@ database otherwise.\n .IP \"\\fBexclude-tables\\fR (JSON array of strings; active-backup only)\"\n List of table names that should be excluded from replication in backup mode,\n e.g. \\fB\"exclude-tables\": [ \"Table_One\", \"Table_Two\" ]\\fR.\n+.IP \"\\fBtransaction-history-limit\\fR (integer)\"\n+Changes the transaction history length of the database. Only available for the\n+service-models \\fBclustered\\fR and \\fBrelay\\fR if the relay source is\n+\\fBclustered\\fR.\n .RE\n .RE\n .IP\ndiff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c\nindex 2af62071e..4a85ae575 100644\n--- a/ovsdb/ovsdb-server.c\n+++ b/ovsdb/ovsdb-server.c\n@@ -156,6 +156,10 @@ struct db_config {\n bool backup; /* If true, the database is read-only and receives\n * updates from the 'source'. */\n } ab;\n+\n+ /* Valid for SM_CLUSTERED or SM_RELAY. */\n+ unsigned int n_txn_history_max; /* The maximum amount of history entries\n+ * to keep. 0 means default. */\n };\n \n struct db {\n@@ -462,6 +466,7 @@ db_config_clone(const struct db_config *c)\n conf->options = ovsdb_jsonrpc_options_clone(c->options);\n }\n conf->ab.sync_exclude = nullable_xstrdup(c->ab.sync_exclude);\n+ conf->n_txn_history_max = c->n_txn_history_max;\n \n return conf;\n }\n@@ -572,6 +577,11 @@ database_update_config(struct server_config *server_config,\n replication_set_db(db->db, conf->source, conf->ab.sync_exclude,\n server_uuid, &conf->options->rpc);\n }\n+\n+ if ((conf->model == SM_CLUSTERED || conf->model == SM_RELAY) &&\n+ conf->n_txn_history_max) {\n+ ovsdb_txn_history_update(db->db, conf->n_txn_history_max);\n+ }\n }\n \n static bool\n@@ -1180,7 +1190,8 @@ open_db(struct server_config *server_config,\n /* Enable txn history for clustered and relay modes. It is not enabled for\n * other modes for now, since txn id is available for clustered and relay\n * modes only. */\n- ovsdb_txn_history_init(db->db, model == SM_RELAY || model == SM_CLUSTERED);\n+ ovsdb_txn_history_init(db->db, model == SM_RELAY || model == SM_CLUSTERED,\n+ conf->n_txn_history_max);\n \n read_db(server_config, db);\n \n@@ -2910,6 +2921,12 @@ db_config_to_json(const struct db_config *conf)\n }\n json_object_put(json, \"backup\", json_boolean_create(conf->ab.backup));\n }\n+\n+ if (conf->n_txn_history_max) {\n+ json_object_put(json, \"transaction-history-limit\",\n+ json_integer_create(conf->n_txn_history_max));\n+ }\n+\n return json;\n }\n \n@@ -3033,7 +3050,7 @@ remotes_from_json(struct shash *remotes, const struct json *json)\n static struct db_config *\n db_config_from_json(const char *name, const struct json *json)\n {\n- const struct json *model, *source, *sync_exclude, *backup;\n+ const struct json *model, *source, *sync_exclude, *backup, *txn_limit;\n struct db_config *conf = xzalloc(sizeof *conf);\n struct ovsdb_parser parser;\n struct ovsdb_error *error;\n@@ -3114,6 +3131,12 @@ db_config_from_json(const char *name, const struct json *json)\n }\n }\n \n+ txn_limit = ovsdb_parser_member(&parser, \"transaction-history-limit\",\n+ OP_INTEGER | OP_OPTIONAL);\n+ if (txn_limit) {\n+ conf->n_txn_history_max = json_integer(txn_limit);\n+ }\n+\n error = ovsdb_parser_finish(&parser);\n if (error) {\n char *s = ovsdb_error_to_string_free(error);\ndiff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h\nindex 325900bc6..04c52817d 100644\n--- a/ovsdb/ovsdb.h\n+++ b/ovsdb/ovsdb.h\n@@ -107,9 +107,10 @@ struct ovsdb {\n struct ovsdb_table *rbac_role;\n \n /* History trasanctions for incremental monitor transfer. */\n- bool need_txn_history; /* Need to maintain history of transactions. */\n unsigned int n_txn_history; /* Current number of history transactions. */\n unsigned int n_txn_history_atoms; /* Total number of atoms in history. */\n+ unsigned int n_txn_history_max; /* The maximum history length.\n+ If 0 there is no history. */\n struct ovs_list txn_history; /* Contains \"struct ovsdb_txn_history_node. */\n \n size_t n_atoms; /* Total number of ovsdb atoms in the database. */\ndiff --git a/ovsdb/relay.c b/ovsdb/relay.c\nindex a5e1a5f3a..7691e0b73 100644\n--- a/ovsdb/relay.c\n+++ b/ovsdb/relay.c\n@@ -274,7 +274,7 @@ exit:\n /* The relay source doesn't support unique transaction ids,\n * disabling transaction history for relay. */\n ovsdb_txn_history_destroy(db);\n- ovsdb_txn_history_init(db, false);\n+ ovsdb_txn_history_init(db, false, 0);\n } else {\n ovsdb_txn_set_txnid(last_id, txn);\n }\n@@ -307,7 +307,7 @@ ovsdb_relay_clear(struct ovsdb *db)\n \n /* Clearing the transaction history, and re-enabling it. */\n ovsdb_txn_history_destroy(db);\n- ovsdb_txn_history_init(db, true);\n+ ovsdb_txn_history_init(db, true, db->n_txn_history_max);\n \n return error;\n }\ndiff --git a/ovsdb/transaction.c b/ovsdb/transaction.c\nindex 0d0d27b61..210030e62 100644\n--- a/ovsdb/transaction.c\n+++ b/ovsdb/transaction.c\n@@ -18,6 +18,7 @@\n #include \"transaction.h\"\n \n #include \"bitmap.h\"\n+#include \"coverage.h\"\n #include \"openvswitch/dynamic-string.h\"\n #include \"file.h\"\n #include \"hash.h\"\n@@ -38,6 +39,10 @@\n \n VLOG_DEFINE_THIS_MODULE(transaction);\n \n+COVERAGE_DEFINE(txn_history_add);\n+\n+#define TRANSACTION_HISTORY_LIMIT_DEFAULT 100\n+\n struct ovsdb_txn {\n struct ovsdb *db;\n struct ovs_list txn_tables; /* Contains \"struct ovsdb_txn_table\"s. */\n@@ -1186,12 +1191,13 @@ ovsdb_txn_destroy_cloned(struct ovsdb_txn *txn)\n static void\n ovsdb_txn_add_to_history(struct ovsdb_txn *txn)\n {\n- if (txn->db->need_txn_history) {\n+ if (txn->db->n_txn_history_max) {\n struct ovsdb_txn_history_node *node = xzalloc(sizeof *node);\n node->txn = ovsdb_txn_clone_for_history(txn);\n ovs_list_push_back(&txn->db->txn_history, &node->node);\n txn->db->n_txn_history++;\n txn->db->n_txn_history_atoms += txn->n_atoms;\n+ COVERAGE_INC(txn_history_add);\n }\n }\n \n@@ -1676,7 +1682,7 @@ for_each_txn_row(struct ovsdb_txn *txn,\n void\n ovsdb_txn_history_run(struct ovsdb *db)\n {\n- if (!db->need_txn_history) {\n+ if (!db->n_txn_history_max) {\n return;\n }\n /* Remove old histories to limit the size of the history. Removing until\n@@ -1686,7 +1692,7 @@ ovsdb_txn_history_run(struct ovsdb *db)\n * Keeping at least one transaction to avoid sending UUID_ZERO as a last id\n * if all entries got removed due to the size limit. */\n while (db->n_txn_history > 1 &&\n- (db->n_txn_history > 100 ||\n+ (db->n_txn_history > db->n_txn_history_max ||\n db->n_txn_history_atoms > db->n_atoms)) {\n struct ovsdb_txn_history_node *txn_h_node = CONTAINER_OF(\n ovs_list_pop_front(&db->txn_history),\n@@ -1700,11 +1706,17 @@ ovsdb_txn_history_run(struct ovsdb *db)\n }\n \n void\n-ovsdb_txn_history_init(struct ovsdb *db, bool need_txn_history)\n+ovsdb_txn_history_init(struct ovsdb *db, bool need_txn_history,\n+ unsigned int n_txn_history_max)\n {\n- db->need_txn_history = need_txn_history;\n db->n_txn_history = 0;\n db->n_txn_history_atoms = 0;\n+ if (need_txn_history) {\n+ db->n_txn_history_max = MAX(n_txn_history_max,\n+ TRANSACTION_HISTORY_LIMIT_DEFAULT);\n+ } else {\n+ db->n_txn_history_max = 0;\n+ }\n ovs_list_init(&db->txn_history);\n }\n \n@@ -1712,7 +1724,7 @@ void\n ovsdb_txn_history_destroy(struct ovsdb *db)\n {\n \n- if (!db->need_txn_history) {\n+ if (!db->n_txn_history_max) {\n return;\n }\n \n@@ -1725,3 +1737,16 @@ ovsdb_txn_history_destroy(struct ovsdb *db)\n db->n_txn_history = 0;\n db->n_txn_history_atoms = 0;\n }\n+\n+void\n+ovsdb_txn_history_update(struct ovsdb *db, unsigned int n_txn_history_max)\n+{\n+ if (!db->n_txn_history_max) {\n+ return;\n+ }\n+\n+ db->n_txn_history_max = MAX(n_txn_history_max,\n+ TRANSACTION_HISTORY_LIMIT_DEFAULT);\n+\n+ ovsdb_txn_history_run(db);\n+}\ndiff --git a/ovsdb/transaction.h b/ovsdb/transaction.h\nindex d94205414..04f96f079 100644\n--- a/ovsdb/transaction.h\n+++ b/ovsdb/transaction.h\n@@ -75,7 +75,10 @@ struct ovsdb_row *ovsdb_index_search(struct hmap *index,\n void ovsdb_txn_add_comment(struct ovsdb_txn *, const char *);\n const char *ovsdb_txn_get_comment(const struct ovsdb_txn *);\n void ovsdb_txn_history_run(struct ovsdb *);\n-void ovsdb_txn_history_init(struct ovsdb *, bool need_txn_history);\n+void ovsdb_txn_history_init(struct ovsdb *, bool need_txn_history,\n+ unsigned int n_txn_history_max);\n void ovsdb_txn_history_destroy(struct ovsdb *);\n+void ovsdb_txn_history_update(struct ovsdb *db,\n+ unsigned int n_txn_history_max);\n \n #endif /* ovsdb/transaction.h */\ndiff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at\nindex d9389e12f..ad1028e2b 100644\n--- a/tests/ovsdb-server.at\n+++ b/tests/ovsdb-server.at\n@@ -3108,6 +3108,25 @@ WARN|syntax \"{\"dscp\":42,\"inactivity-probe\":10000,\"max-backoff\":8000,\"role\":\"My-R\n syntax error: Parsing JSON-RPC options failed: Member 'role' is present but not allowed here.\n ])\n \n+TEST_CONFIG_FILE([relay with transaction-history-limit], [\n+{\n+ \"remotes\": { \"punix:db.sock\": {} },\n+ \"databases\": {\n+ \"RelaySchema\": {\n+ \"service-model\": \"relay\",\n+ \"source\": {\n+ \"punix:db2.sock\": {\n+ \"inactivity-probe\": 10000,\n+ \"max-backoff\": 8000,\n+ \"dscp\": 42\n+ }\n+ },\n+ \"transaction-history-limit\": 1000\n+ }\n+ }\n+}\n+], [0])\n+\n TEST_CONFIG_FILE([unknown config], [\n {\n \"remotes\": { \"punix:db.sock\": {} },\n@@ -3192,7 +3211,8 @@ TEST_CONFIG_FILE([complex config], [\n },\n \"databases\": {\n \"db_cluster\": {\n- \"service-model\": \"clustered\"\n+ \"service-model\": \"clustered\",\n+ \"transaction-history-limit\": 5432\n },\n \"OVN_Northbound\": {\n \"service-model\": \"relay\",\n@@ -3201,7 +3221,8 @@ TEST_CONFIG_FILE([complex config], [\n \"max-backoff\": 3000,\n \"inactivity-probe\": 16000\n }\n- }\n+ },\n+ \"transaction-history-limit\": 1000\n },\n \"db\": {\n \"service-model\": \"active-backup\",\n", "prefixes": [ "ovs-dev", "v3", "1/2" ] }