From patchwork Tue Jan 29 20:01:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032988 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TVXIcYln"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyJl1sQPz9sBQ for ; Wed, 30 Jan 2019 07:09:42 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id CDDD73269; Tue, 29 Jan 2019 20:09:34 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 9DA5D2E4E for ; Tue, 29 Jan 2019 20:01:52 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 612B4827 for ; Tue, 29 Jan 2019 20:01:52 +0000 (UTC) Received: by mail-pf1-f170.google.com with SMTP id g62so10155177pfd.12 for ; Tue, 29 Jan 2019 12:01:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MVSAruA0G5/16Yko5CpWPJDr0qEFnx0t99BT1obvaXA=; b=TVXIcYlniuUrikFs9WLyjNeinTr91+aeIfpdo7ZEFrOpTb6fV+laHUthnykyPsH9i0 k5gdSDIbtmwaSKrWWR1ZWkpJZuDfPWX4GkjlWsLCc+NBuYu9pEhrTQewQbaERXDTkBBb ga+Y8YFID+gXa8HYln5H+3TB5uYhEgx2+c0cr/hQiwYDri2b4lyaXCbcZAkQeQf66gzl 4cy76LVzdJ0yEWJvpfYDwpnFoV2JgaYkQtgwrD9kpbynG2cA34urs2PwRsTD6WoFNzvK Zo+PssJkVgfOpkxXFzJOr7f7oEpATUYbmKIl4BNdBb+77ofnjR0R1EvdZruGonf7Zi81 DMRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MVSAruA0G5/16Yko5CpWPJDr0qEFnx0t99BT1obvaXA=; b=KFmtdq4m+MddWaGpPK+/28gyo9H2KVQUUjVZwVMS9PCss9TBGXc/F0xksxwsy3n29/ Ot+5nKH7o678a/at7tdmUEHHgdihLdrvC/Nynck6fLT3SXnodlWj8QpoDrEvPfRTuIdN Yib/DpvgU7hobxqpgODfhLso6BYjXOAaTVTUnnm5tRJei71VE3zmiqeO6R596zYZdrVN CL27b9GG/ox01cK6UHymcrRVMelmdfYLLLDJQNic5bHwnWuTqP7T+KQ0d4HZF9l2Yo1b Me5AAZauu+s3yJCS7NesJ+ODyIFsN44R80q3DqjVKcsrwfz9KaNlVzO0s+BIHKHOIg0O AwOA== X-Gm-Message-State: AJcUukchQOO0a6t9xD9AEon1VwGF1omAghPPlVkCDvBPlau4z6Az8Tu+ MsOPrerWKNOCh0SR35MetDRmPEmj X-Google-Smtp-Source: ALg8bN5vzSA/atobZ+RGJJzpISWdlhx0YI9wrKDWpZFGu8uhNp2H+Kz3cEPBMcaNVfd0cl+6Kizk9w== X-Received: by 2002:a62:37c3:: with SMTP id e186mr28198163pfa.251.1548792111690; Tue, 29 Jan 2019 12:01:51 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:51 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:43 -0800 Message-Id: <1548792109-111156-2-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 1/7] ovsdb-client.c: fix typo X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Signed-off-by: Han Zhou --- ovsdb/ovsdb-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 83c3c12..0215357 100644 --- a/ovsdb/ovsdb-client.c +++ b/ovsdb/ovsdb-client.c @@ -1267,7 +1267,7 @@ ovsdb_client_cond_change(struct unixctl_conn *conn, int argc OVS_UNUSED, jsonrpc_send(rpc, request); VLOG_DBG("cond change %s %s", argv[1], argv[2]); - unixctl_command_reply(conn, "condiiton changed"); + unixctl_command_reply(conn, "condition changed"); } static void From patchwork Tue Jan 29 20:01:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032989 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="K4Uqmtqd"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyKZ4JFYz9sBQ for ; Wed, 30 Jan 2019 07:10:26 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A484D326C; Tue, 29 Jan 2019 20:09:35 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id DE06C2E4E for ; Tue, 29 Jan 2019 20:01:53 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 5AEFE827 for ; Tue, 29 Jan 2019 20:01:53 +0000 (UTC) Received: by mail-pf1-f194.google.com with SMTP id c73so10153754pfe.13 for ; Tue, 29 Jan 2019 12:01:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+QdqDTdxSg0xYB6PM4BzOR5RraeKPO61i5N2bWK7HiQ=; b=K4Uqmtqdqnxm7FDJTvnGkwH1jZnKb0N97lGDofHb8gyFPDyNPmvrRVkPlKwkCA+Oey EobU7Nt9zIzmGwT2w/HwJH+DoYnxE6sicXKhSj8syxhmjzt0yUz3oGsJ7STBNv5E3pYd NAlsnLXFtKhqlSAe2XJc7PxDW/855VVF/mzwEtzUEacCUObRjFZIqsUm5aKDOtndFncv 9OVlUKEwr020tOWl5ksEsezjo0t6jwPYCfb/yIq6HMP6/3syj4qquDgEKEml6UpPemEF k8BqlUaCnYVyWBtXmllg1vGrNm5ciDt9kTEAazxxSv8B9I3mrYLul3OKQFpBhH+ch2+X bjmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+QdqDTdxSg0xYB6PM4BzOR5RraeKPO61i5N2bWK7HiQ=; b=QCgUy3BLabkx0a8euTYwlsKrD/s/RFHX3YPQOB2p5Wb9FJPz2M5SkKp9X7AZOKMytw uvxfpD3Kt70A2Jv46vT8WcTrhvVW7PiORYIA0JHFWN502t87Q5yBS6e6zUFuE503aHJ/ wzn9jnoCpSfh/oXZ5Ui2Ahg0W2ZzcQ2UgdAuu9rkXuGg+5DpwcA5VbNwUEo8gFhd3t04 vhMJZnMA7KQAfy5AndJX9bDbqntieoiZTpjLEjLu8YtbDaovL8iKqq74UE8Jud2lbC9O 5oK7Syuty+WJ2tItiRsPWlSIU/j88rGHgLqf+4V0LEn16axtoNGvdUo8L4BAFs5NvOZn G87Q== X-Gm-Message-State: AJcUukeyYEz+E9XiWI1Aa18OefXIXZBPmMDY4z0FzePauvf2WQIuzHQn MKKvIeSXw7Yim440mM2x5hXFhuXT X-Google-Smtp-Source: ALg8bN4zaRvrfRBC6Xe/tNv7uLEbXW6dp+MtqSmW7mmwlL9KXtDnbV3nnY+ipFIfV6ntm3X13MdRsQ== X-Received: by 2002:a62:d148:: with SMTP id t8mr28229226pfl.52.1548792112715; Tue, 29 Jan 2019 12:01:52 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:51 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:44 -0800 Message-Id: <1548792109-111156-3-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 2/7] ovsdb_monitor: Fix style of prototypes. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Ommiting the parameter names in prototypes, as suggested by coding style: Omit parameter names from function prototypes when the names do not give useful information. Adjust orders of parameters as suggested by coding style. Signed-off-by: Han Zhou --- ovsdb/jsonrpc-server.c | 4 +-- ovsdb/monitor.c | 14 +++++------ ovsdb/monitor.h | 66 +++++++++++++++++++++++++------------------------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index 7c7a277..77f15d9 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -1578,7 +1578,7 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, struct json *update_json; update_json = ovsdb_monitor_get_update(m->dbmon, false, true, - &m->unflushed, m->condition, m->version); + m->condition, m->version, &m->unflushed); if (update_json) { struct jsonrpc_msg *msg; struct json *p; @@ -1653,7 +1653,7 @@ ovsdb_jsonrpc_monitor_compose_update(struct ovsdb_jsonrpc_monitor *m, } return ovsdb_monitor_get_update(m->dbmon, initial, false, - &m->unflushed, m->condition, m->version); + m->condition, m->version, &m->unflushed); } static bool diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index dd06e26..bf130ad 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -158,14 +158,14 @@ typedef struct json * const void *, bool initial, unsigned long int *changed); -static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon); +static void ovsdb_monitor_destroy(struct ovsdb_monitor *); static struct ovsdb_monitor_changes * ovsdb_monitor_table_add_changes( - struct ovsdb_monitor_table *mt, uint64_t next_txn); + struct ovsdb_monitor_table *, uint64_t next_txn); static struct ovsdb_monitor_changes *ovsdb_monitor_table_find_changes( - struct ovsdb_monitor_table *mt, uint64_t unflushed); + struct ovsdb_monitor_table *, uint64_t unflushed); static void ovsdb_monitor_changes_destroy( - struct ovsdb_monitor_changes *changes); -static void ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *mt, + struct ovsdb_monitor_changes *); +static void ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *, uint64_t unflushed); static uint32_t @@ -1103,9 +1103,9 @@ struct json * ovsdb_monitor_get_update( struct ovsdb_monitor *dbmon, bool initial, bool cond_updated, - uint64_t *unflushed_, struct ovsdb_monitor_session_condition *condition, - enum ovsdb_monitor_version version) + enum ovsdb_monitor_version version, + uint64_t *unflushed_) { struct ovsdb_monitor_json_cache_node *cache_node = NULL; struct shash_node *node; diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h index eb3ff27..9bc0613 100644 --- a/ovsdb/monitor.h +++ b/ovsdb/monitor.h @@ -44,73 +44,73 @@ enum ovsdb_monitor_version { OVSDB_MONITOR_VERSION_MAX }; -struct ovsdb_monitor *ovsdb_monitor_create(struct ovsdb *db, - struct ovsdb_jsonrpc_monitor *jsonrpc_monitor); +struct ovsdb_monitor *ovsdb_monitor_create(struct ovsdb *, + struct ovsdb_jsonrpc_monitor *); void ovsdb_monitors_remove(struct ovsdb *); void ovsdb_monitors_commit(struct ovsdb *, const struct ovsdb_txn *); void ovsdb_monitor_prereplace_db(struct ovsdb *); -struct ovsdb_monitor *ovsdb_monitor_add(struct ovsdb_monitor *dbmon); +struct ovsdb_monitor *ovsdb_monitor_add(struct ovsdb_monitor *); -void ovsdb_monitor_add_jsonrpc_monitor(struct ovsdb_monitor *dbmon, - struct ovsdb_jsonrpc_monitor *jsonrpc_monitor); +void ovsdb_monitor_add_jsonrpc_monitor(struct ovsdb_monitor *, + struct ovsdb_jsonrpc_monitor *); -void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon, - struct ovsdb_jsonrpc_monitor *jsonrpc_monitor, +void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *, + struct ovsdb_jsonrpc_monitor *, uint64_t unflushed); -void ovsdb_monitor_add_table(struct ovsdb_monitor *m, - const struct ovsdb_table *table); +void ovsdb_monitor_add_table(struct ovsdb_monitor *, + const struct ovsdb_table *); -const char * ovsdb_monitor_add_column(struct ovsdb_monitor *dbmon, - const struct ovsdb_table *table, - const struct ovsdb_column *column, - enum ovsdb_monitor_selection select, +const char * ovsdb_monitor_add_column(struct ovsdb_monitor *, + const struct ovsdb_table *, + const struct ovsdb_column *, + enum ovsdb_monitor_selection, bool monitored); bool -ovsdb_monitor_table_exists(struct ovsdb_monitor *m, - const struct ovsdb_table *table); +ovsdb_monitor_table_exists(struct ovsdb_monitor *, + const struct ovsdb_table *); -struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, +struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *, bool initial, bool cond_updated, - uint64_t *unflushed_transaction, - struct ovsdb_monitor_session_condition *condition, - enum ovsdb_monitor_version version); + struct ovsdb_monitor_session_condition *, + enum ovsdb_monitor_version, + uint64_t *unflushed_transaction); -void ovsdb_monitor_table_add_select(struct ovsdb_monitor *dbmon, - const struct ovsdb_table *table, - enum ovsdb_monitor_selection select); +void ovsdb_monitor_table_add_select(struct ovsdb_monitor *, + const struct ovsdb_table *, + enum ovsdb_monitor_selection); -bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon, +bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *, uint64_t next_transaction); -void ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon); +void ovsdb_monitor_get_initial(const struct ovsdb_monitor *); -void ovsdb_monitor_get_memory_usage(struct simap *usage); +void ovsdb_monitor_get_memory_usage(struct simap *); struct ovsdb_monitor_session_condition * ovsdb_monitor_session_condition_create(void); void ovsdb_monitor_session_condition_destroy( - struct ovsdb_monitor_session_condition *condition); + struct ovsdb_monitor_session_condition *); struct ovsdb_error * ovsdb_monitor_table_condition_create( - struct ovsdb_monitor_session_condition *condition, - const struct ovsdb_table *table, + struct ovsdb_monitor_session_condition *, + const struct ovsdb_table *, const struct json *json_cnd); void -ovsdb_monitor_condition_bind(struct ovsdb_monitor *dbmon, - struct ovsdb_monitor_session_condition *cond); +ovsdb_monitor_condition_bind(struct ovsdb_monitor *, + struct ovsdb_monitor_session_condition *); struct ovsdb_error * ovsdb_monitor_table_condition_update( - struct ovsdb_monitor *dbmon, - struct ovsdb_monitor_session_condition *condition, - const struct ovsdb_table *table, + struct ovsdb_monitor *, + struct ovsdb_monitor_session_condition *, + const struct ovsdb_table *, const struct json *cond_json); #endif From patchwork Tue Jan 29 20:01:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032991 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="M8PGi9ZD"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyLw03PBz9sBn for ; Wed, 30 Jan 2019 07:11:35 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2719A3275; Tue, 29 Jan 2019 20:09:37 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 38E112E4E for ; Tue, 29 Jan 2019 20:01:56 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl1-f196.google.com (mail-pl1-f196.google.com [209.85.214.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 82CC1827 for ; Tue, 29 Jan 2019 20:01:54 +0000 (UTC) Received: by mail-pl1-f196.google.com with SMTP id p8so9839806plo.2 for ; Tue, 29 Jan 2019 12:01:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SZJgB+EqD+3Kz9Jle1LYZ0iqJxOJKm6ocVJqTYMo7/0=; b=M8PGi9ZDsjSi9FDbYxFUsWTp2zAJnU21dykZOdUSNDLrOK9enNKRFmF20NzNb2K+f0 83dqajJd8XikQAUrrT6GCEjKXqMiJz9kkPZ1nxS0mFD8ZAs7d/psgvXSH2UYnneRmfWZ ENTDvCrdWls8azsNgKL9Lec+diw1pON5EOjVrugUeAf/Xb7EBXvpl3OHzfRJGm9iOMOG mMqvmCoH64Uodgp6hTmJ2Anw+ng2XkRsrLWQlpopAzjtOMLWeUQGzxOliyn4uYImDrkz VI4Rw0rF36CJTtEAylE1oDRFS5w3RPub7Tn513WjEXA4mqo86UKhXqDdNL8EirpbOe8u aitw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SZJgB+EqD+3Kz9Jle1LYZ0iqJxOJKm6ocVJqTYMo7/0=; b=C+fPhn+WKtvYKz00hlIuqRzuSTRWgXSlua9bzwC9clxrSdkfzqFu/KMykxUOyktI8s CaNz8lj6ryZpZvsC50vCYRqAsStFd9iX2VZCFIiTVkyeEntLexWEIAYaPn+zrXXhbHRw JBO7LY4BmfgIiU6NoauvcbDd86EJPTfQLq9iE6vGFt2ea1GnOAb3OV1r1IOLyYmLyB59 B2bb9xBenwuNQ4d4o7u6EcxqOic1e/sJWp78AS+/GgczoT6R7HD29DroPrfm5dUTW0v3 5TLZxQg3JznvSoZq9sNovc3nJC0U5uCFuT95AFfmCnXZN/T9f+VhC42eluqetOp4z4BK gh6g== X-Gm-Message-State: AJcUukd6brh0XrNOoIN55eKATDPQ13I7AMUmEfz0uv2EWKfVlzcfuWgA UYkN9gu76IvldGfe1rVOwsKuy9En X-Google-Smtp-Source: ALg8bN7sJFk0AhG8z6wkzlmXmw2avFLErMg+5bhVSvihOy2PWLtkuVrgJT9Ih+HCxyeIGRJGoEeoHQ== X-Received: by 2002:a17:902:59c8:: with SMTP id d8mr27442561plj.116.1548792113607; Tue, 29 Jan 2019 12:01:53 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:52 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:45 -0800 Message-Id: <1548792109-111156-4-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 3/7] ovsdb-monitor: Refactor ovsdb monitor implementation. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Current ovsdb monitor maintains pending changes through an incremental integer to figure out if the set of changes should be flushed. And it uses number 0 to represent that the change set contains all data for initial client population. It is a smart way but it prevents further extension of the monitoring mechanism to support future use case of monitoring starting from an arbitory history point. This patch refactors the structures so that change sets are tracked directly, instead of through calculated version numbers based on implicite rules. Signed-off-by: Han Zhou --- ovsdb/jsonrpc-server.c | 18 ++- ovsdb/monitor.c | 378 +++++++++++++++++++++++++------------------------ ovsdb/monitor.h | 10 +- 3 files changed, 207 insertions(+), 199 deletions(-) diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index 77f15d9..f9b7c27 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -1216,8 +1216,7 @@ struct ovsdb_jsonrpc_monitor { struct ovsdb *db; struct json *monitor_id; struct ovsdb_monitor *dbmon; - uint64_t unflushed; /* The first transaction that has not been - flushed to the jsonrpc remote client. */ + struct ovsdb_monitor_change_set *change_set; enum ovsdb_monitor_version version; struct ovsdb_monitor_session_condition *condition;/* Session's condition */ }; @@ -1389,7 +1388,6 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, if (version == OVSDB_MONITOR_V2) { m->condition = ovsdb_monitor_session_condition_create(); } - m->unflushed = 0; m->version = version; hmap_insert(&s->monitors, &m->node, json_hash(monitor_id, 0)); m->monitor_id = json_clone(monitor_id); @@ -1436,7 +1434,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, dbmon = ovsdb_monitor_add(m->dbmon); if (dbmon != m->dbmon) { /* Found an exisiting dbmon, reuse the current one. */ - ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m, m->unflushed); + ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m, NULL); ovsdb_monitor_add_jsonrpc_monitor(dbmon, m); m->dbmon = dbmon; } @@ -1446,7 +1444,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, ovsdb_monitor_condition_bind(m->dbmon, m->condition); } - ovsdb_monitor_get_initial(m->dbmon); + ovsdb_monitor_get_initial(m->dbmon, &m->change_set); json = ovsdb_jsonrpc_monitor_compose_update(m, true); json = json ? json : json_object_create(); return jsonrpc_create_reply(json, request_id); @@ -1578,7 +1576,7 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, struct json *update_json; update_json = ovsdb_monitor_get_update(m->dbmon, false, true, - m->condition, m->version, &m->unflushed); + m->condition, m->version, &m->change_set); if (update_json) { struct jsonrpc_msg *msg; struct json *p; @@ -1648,12 +1646,12 @@ ovsdb_jsonrpc_monitor_compose_update(struct ovsdb_jsonrpc_monitor *m, bool initial) { - if (!ovsdb_monitor_needs_flush(m->dbmon, m->unflushed)) { + if (!ovsdb_monitor_needs_flush(m->dbmon, m->change_set)) { return NULL; } return ovsdb_monitor_get_update(m->dbmon, initial, false, - m->condition, m->version, &m->unflushed); + m->condition, m->version, &m->change_set); } static bool @@ -1662,7 +1660,7 @@ ovsdb_jsonrpc_monitor_needs_flush(struct ovsdb_jsonrpc_session *s) struct ovsdb_jsonrpc_monitor *m; HMAP_FOR_EACH (m, node, &s->monitors) { - if (ovsdb_monitor_needs_flush(m->dbmon, m->unflushed)) { + if (ovsdb_monitor_needs_flush(m->dbmon, m->change_set)) { return true; } } @@ -1686,7 +1684,7 @@ ovsdb_jsonrpc_monitor_destroy(struct ovsdb_jsonrpc_monitor *m, json_destroy(m->monitor_id); hmap_remove(&m->session->monitors, &m->node); - ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m, m->unflushed); + ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m, m->change_set); ovsdb_monitor_session_condition_destroy(m->condition); free(m); } diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index bf130ad..b41054d 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -69,17 +69,31 @@ struct ovsdb_monitor { struct shash tables; /* Holds "struct ovsdb_monitor_table"s. */ struct ovs_list jsonrpc_monitors; /* Contains "jsonrpc_monitor_node"s. */ struct ovsdb *db; - uint64_t n_transactions; /* Count number of committed transactions. */ - struct hmap_node hmap_node; /* Elements within ovsdb_monitors. */ - struct hmap json_cache; /* Contains "ovsdb_monitor_json_cache_node"s.*/ + + /* Contains "ovsdb_monitor_change_set". Each change set contains changes + * from some start point up to the latest committed transaction. There can + * be different change sets for the same struct ovsdb_monitor because there + * are different clients pending on changes starting from different points. + * The different change sets are maintained as a list. */ + struct ovs_list change_sets; + + /* The new change set that is to be populated for future transactions. */ + struct ovsdb_monitor_change_set *new_change_set; + + /* The change set that starts from the first transaction of the DB, which + * is used for populating the initial data for new clients. */ + struct ovsdb_monitor_change_set *init_change_set; + + struct hmap_node hmap_node; /* Elements within ovsdb_monitors. */ + struct hmap json_cache; /* Contains "ovsdb_monitor_json_cache_node"s.*/ }; -/* A json object of updates between 'from_txn' and 'dbmon->n_transactions' - * inclusive. */ +/* A json object of updates for the ovsdb_monitor_change_set and the given + * monitor version. */ struct ovsdb_monitor_json_cache_node { struct hmap_node hmap_node; /* Elements in json cache. */ enum ovsdb_monitor_version version; - uint64_t from_txn; + struct uuid change_set_uuid; struct json *json; /* Null, or a cloned of json */ }; @@ -97,29 +111,48 @@ struct ovsdb_monitor_column { /* A row that has changed in a monitored table. */ struct ovsdb_monitor_row { - struct hmap_node hmap_node; /* In ovsdb_jsonrpc_monitor_table.changes. */ + struct hmap_node hmap_node; /* In ovsdb_monitor_change_set_for_table. */ struct uuid uuid; /* UUID of row that changed. */ struct ovsdb_datum *old; /* Old data, NULL for an inserted row. */ struct ovsdb_datum *new; /* New data, NULL for a deleted row. */ }; -/* Contains 'struct ovsdb_monitor_row's for rows that have been - * updated but not yet flushed to all the jsonrpc connection. +/* Contains a set of changes that are not yet flushed to all the jsonrpc + * connections. * - * 'n_refs' represent the number of jsonrpc connections that have - * not received updates. Generate the update for the last jsonprc - * connection will also destroy the whole "struct ovsdb_monitor_changes" - * object. - * - * 'transaction' stores the first update's transaction id. - * */ -struct ovsdb_monitor_changes { - struct hmap_node hmap_node; /* Element in ovsdb_monitor_tables' changes - hmap. */ + * 'n_refs' represent the number of jsonrpc connections that depend on this + * change set (have not received updates). Generate the update for the last + * jsonprc connection will also destroy the whole "struct + * ovsdb_monitor_change_set" object. + */ +struct ovsdb_monitor_change_set { + /* Element in change_sets of ovsdb_monitor. */ + struct ovs_list list_node; + + /* Internally generated uuid that identifies this data structure. */ + struct uuid uuid; + + /* Contains struct ovsdb_monitor_change_set_for_table. */ + struct ovs_list change_set_for_tables; + + int n_refs; +}; + +/* Contains 'struct ovsdb_monitor_row's for rows in a specific table + * of struct ovsdb_monitor_change_set. It can also be searched from + * member 'change_sets' of struct ovsdb_monitor_table. */ +struct ovsdb_monitor_change_set_for_table { + /* Element in ovsdb_monitor_tables' change_sets list. */ + struct ovs_list list_in_mt; + + /* Element in ovsdb_monitor_change_sets' change_set_for_tables list. */ + struct ovs_list list_in_change_set; + struct ovsdb_monitor_table *mt; + struct ovsdb_monitor_change_set *mcs; + + /* Contains struct ovsdb_monitor_row. */ struct hmap rows; - int n_refs; - uint64_t transaction; }; /* A particular table being monitored. */ @@ -141,8 +174,8 @@ struct ovsdb_monitor_table { * ovsdb_monitor_row. It is used for condition evaluation. */ unsigned int *columns_index_map; - /* Contains 'ovsdb_monitor_changes' indexed by 'transaction'. */ - struct hmap changes; + /* Contains 'ovsdb_monitor_change_set_for_table'. */ + struct ovs_list change_sets; }; enum ovsdb_monitor_row_type { @@ -159,36 +192,23 @@ typedef struct json * bool initial, unsigned long int *changed); static void ovsdb_monitor_destroy(struct ovsdb_monitor *); -static struct ovsdb_monitor_changes * ovsdb_monitor_table_add_changes( - struct ovsdb_monitor_table *, uint64_t next_txn); -static struct ovsdb_monitor_changes *ovsdb_monitor_table_find_changes( - struct ovsdb_monitor_table *, uint64_t unflushed); -static void ovsdb_monitor_changes_destroy( - struct ovsdb_monitor_changes *); -static void ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *, - uint64_t unflushed); - -static uint32_t -json_cache_hash(enum ovsdb_monitor_version version, uint64_t from_txn) -{ - uint32_t hash; - - hash = hash_uint64(version); - hash = hash_uint64_basis(from_txn, hash); - - return hash; -} +static struct ovsdb_monitor_change_set * ovsdb_monitor_add_change_set( + struct ovsdb_monitor *, bool init_only); +static void ovsdb_monitor_change_set_destroy( + struct ovsdb_monitor_change_set *); +static void ovsdb_monitor_track_new_change_set(struct ovsdb_monitor *); static struct ovsdb_monitor_json_cache_node * ovsdb_monitor_json_cache_search(const struct ovsdb_monitor *dbmon, enum ovsdb_monitor_version version, - uint64_t from_txn) + struct ovsdb_monitor_change_set *change_set) { struct ovsdb_monitor_json_cache_node *node; - uint32_t hash = json_cache_hash(version, from_txn); + uint32_t hash = uuid_hash(&change_set->uuid); HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash, &dbmon->json_cache) { - if (node->from_txn == from_txn && node->version == version) { + if (uuid_equals(&node->change_set_uuid, &change_set->uuid) && + node->version == version) { return node; } } @@ -199,15 +219,16 @@ ovsdb_monitor_json_cache_search(const struct ovsdb_monitor *dbmon, static void ovsdb_monitor_json_cache_insert(struct ovsdb_monitor *dbmon, enum ovsdb_monitor_version version, - uint64_t from_txn, struct json *json) + struct ovsdb_monitor_change_set *change_set, + struct json *json) { struct ovsdb_monitor_json_cache_node *node; - uint32_t hash = json_cache_hash(version, from_txn); + uint32_t hash = uuid_hash(&change_set->uuid); node = xmalloc(sizeof *node); node->version = version; - node->from_txn = from_txn; + node->change_set_uuid = change_set->uuid; node->json = json ? json_clone(json) : NULL; hmap_insert(&dbmon->json_cache, &node->hmap_node, hash); @@ -241,8 +262,9 @@ compare_ovsdb_monitor_column(const void *a_, const void *b_) /* Finds and returns the ovsdb_monitor_row in 'mt->changes->rows' for the * given 'uuid', or NULL if there is no such row. */ static struct ovsdb_monitor_row * -ovsdb_monitor_changes_row_find(const struct ovsdb_monitor_changes *changes, - const struct uuid *uuid) +ovsdb_monitor_changes_row_find( + const struct ovsdb_monitor_change_set_for_table *changes, + const struct uuid *uuid) { struct ovsdb_monitor_row *row; @@ -375,7 +397,7 @@ ovsdb_monitor_create(struct ovsdb *db, ovs_list_push_back(&db->monitors, &dbmon->list_node); ovs_list_init(&dbmon->jsonrpc_monitors); dbmon->db = db; - dbmon->n_transactions = 0; + ovs_list_init(&dbmon->change_sets); shash_init(&dbmon->tables); hmap_node_nullify(&dbmon->hmap_node); hmap_init(&dbmon->json_cache); @@ -395,7 +417,7 @@ ovsdb_monitor_add_table(struct ovsdb_monitor *m, mt = xzalloc(sizeof *mt); mt->table = table; shash_add(&m->tables, table->schema->name, mt); - hmap_init(&mt->changes); + ovs_list_init(&mt->change_sets); mt->columns_index_map = xmalloc(sizeof *mt->columns_index_map * n_columns); for (i = 0; i < n_columns; i++) { @@ -481,81 +503,87 @@ ovsdb_monitor_table_exists(struct ovsdb_monitor *m, return shash_find_data(&m->tables, table->schema->name); } -static struct ovsdb_monitor_changes * -ovsdb_monitor_table_add_changes(struct ovsdb_monitor_table *mt, - uint64_t next_txn) +static struct ovsdb_monitor_change_set * +ovsdb_monitor_add_change_set(struct ovsdb_monitor *dbmon, + bool init_only) { - struct ovsdb_monitor_changes *changes; - - changes = xzalloc(sizeof *changes); - - changes->transaction = next_txn; - changes->mt = mt; - changes->n_refs = 1; - hmap_init(&changes->rows); - hmap_insert(&mt->changes, &changes->hmap_node, hash_uint64(next_txn)); - - return changes; -}; + struct ovsdb_monitor_change_set *change_set = xzalloc(sizeof *change_set); + change_set->uuid = uuid_random(); + ovs_list_push_back(&(dbmon->change_sets), &change_set->list_node); + ovs_list_init(&change_set->change_set_for_tables); + change_set->n_refs = 1; -static struct ovsdb_monitor_changes * -ovsdb_monitor_table_find_changes(struct ovsdb_monitor_table *mt, - uint64_t transaction) -{ - struct ovsdb_monitor_changes *changes; - size_t hash = hash_uint64(transaction); - - HMAP_FOR_EACH_WITH_HASH(changes, hmap_node, hash, &mt->changes) { - if (changes->transaction == transaction) { - return changes; + struct shash_node *node; + SHASH_FOR_EACH (node, &dbmon->tables) { + struct ovsdb_monitor_table *mt = node->data; + if (!init_only || (mt->select & OJMS_INITIAL)) { + struct ovsdb_monitor_change_set_for_table *mcst = + xzalloc(sizeof *mcst); + mcst->mt = mt; + mcst->mcs = change_set; + hmap_init(&mcst->rows); + ovs_list_push_back(&mt->change_sets, &mcst->list_in_mt); + ovs_list_push_back(&change_set->change_set_for_tables, + &mcst->list_in_change_set); } } - return NULL; -} + return change_set; +}; /* Stop currently tracking changes to table 'mt' since 'transaction'. */ static void -ovsdb_monitor_table_untrack_changes(struct ovsdb_monitor_table *mt, - uint64_t transaction) +ovsdb_monitor_untrack_change_set(struct ovsdb_monitor *dbmon, + struct ovsdb_monitor_change_set *mcs) { - struct ovsdb_monitor_changes *changes = - ovsdb_monitor_table_find_changes(mt, transaction); - if (changes) { - if (--changes->n_refs == 0) { - hmap_remove(&mt->changes, &changes->hmap_node); - ovsdb_monitor_changes_destroy(changes); + ovs_assert(mcs); + if (--mcs->n_refs == 0) { + ovs_list_remove(&mcs->list_node); + if (mcs == dbmon->init_change_set) { + dbmon->init_change_set = NULL; + } else if (mcs == dbmon->new_change_set) { + dbmon->new_change_set = NULL; } + ovsdb_monitor_change_set_destroy(mcs); } } /* Start tracking changes to table 'mt' begins from 'transaction' inclusive. */ static void -ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *mt, - uint64_t transaction) +ovsdb_monitor_track_new_change_set(struct ovsdb_monitor *dbmon) { - struct ovsdb_monitor_changes *changes; + struct ovsdb_monitor_change_set *change_set = dbmon->new_change_set; - changes = ovsdb_monitor_table_find_changes(mt, transaction); - if (changes) { - changes->n_refs++; + if (change_set) { + change_set->n_refs++; } else { - ovsdb_monitor_table_add_changes(mt, transaction); + change_set = ovsdb_monitor_add_change_set(dbmon, false); + dbmon->new_change_set = change_set; } } static void -ovsdb_monitor_changes_destroy(struct ovsdb_monitor_changes *changes) +ovsdb_monitor_change_set_destroy(struct ovsdb_monitor_change_set *mcs) { - struct ovsdb_monitor_row *row, *next; + ovs_list_remove(&mcs->list_node); + + struct ovsdb_monitor_change_set_for_table *mcst, *next_mcst; + LIST_FOR_EACH_SAFE (mcst, next_mcst, list_in_change_set, + &mcs->change_set_for_tables) { + ovs_list_remove(&mcst->list_in_change_set); + ovs_list_remove(&mcst->list_in_mt); + + struct ovsdb_monitor_row *row, *next; + HMAP_FOR_EACH_SAFE (row, next, hmap_node, &mcst->rows) { + hmap_remove(&mcst->rows, &row->hmap_node); + ovsdb_monitor_row_destroy(mcst->mt, row); + } + hmap_destroy(&mcst->rows); - HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { - hmap_remove(&changes->rows, &row->hmap_node); - ovsdb_monitor_row_destroy(changes->mt, row); + free(mcst); } - hmap_destroy(&changes->rows); - free(changes); + free(mcs); } static enum ovsdb_monitor_selection @@ -1008,28 +1036,22 @@ ovsdb_monitor_add_json_row(struct json **json, const char *table_name, static struct json* ovsdb_monitor_compose_update( struct ovsdb_monitor *dbmon, - bool initial, uint64_t transaction, + bool initial, struct ovsdb_monitor_change_set *mcs, const struct ovsdb_monitor_session_condition *condition, compose_row_update_cb_func row_update) { - struct shash_node *node; struct json *json; size_t max_columns = ovsdb_monitor_max_columns(dbmon); unsigned long int *changed = xmalloc(bitmap_n_bytes(max_columns)); json = NULL; - SHASH_FOR_EACH (node, &dbmon->tables) { - struct ovsdb_monitor_table *mt = node->data; + struct ovsdb_monitor_change_set_for_table *mcst; + LIST_FOR_EACH (mcst, list_in_change_set, &mcs->change_set_for_tables) { struct ovsdb_monitor_row *row, *next; - struct ovsdb_monitor_changes *changes; struct json *table_json = NULL; + struct ovsdb_monitor_table *mt = mcst->mt; - changes = ovsdb_monitor_table_find_changes(mt, transaction); - if (!changes) { - continue; - } - - HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { + HMAP_FOR_EACH_SAFE (row, next, hmap_node, &mcst->rows) { struct json *row_json; row_json = (*row_update)(mt, condition, OVSDB_MONITOR_ROW, row, initial, changed); @@ -1105,39 +1127,37 @@ ovsdb_monitor_get_update( bool initial, bool cond_updated, struct ovsdb_monitor_session_condition *condition, enum ovsdb_monitor_version version, - uint64_t *unflushed_) + struct ovsdb_monitor_change_set **p_mcs) { struct ovsdb_monitor_json_cache_node *cache_node = NULL; - struct shash_node *node; struct json *json; - const uint64_t unflushed = *unflushed_; - const uint64_t next_unflushed = dbmon->n_transactions + 1; + struct ovsdb_monitor_change_set *mcs = *p_mcs; - ovs_assert(cond_updated ? unflushed == next_unflushed : true); + ovs_assert(cond_updated ? mcs == dbmon->new_change_set : true); /* Return a clone of cached json if one exists. Otherwise, * generate a new one and add it to the cache. */ if (!condition || (!condition->conditional && !cond_updated)) { cache_node = ovsdb_monitor_json_cache_search(dbmon, version, - unflushed); + mcs); } if (cache_node) { json = cache_node->json ? json_clone(cache_node->json) : NULL; } else { if (version == OVSDB_MONITOR_V1) { json = - ovsdb_monitor_compose_update(dbmon, initial, unflushed, + ovsdb_monitor_compose_update(dbmon, initial, mcs, condition, ovsdb_monitor_compose_row_update); } else { ovs_assert(version == OVSDB_MONITOR_V2); if (!cond_updated) { - json = ovsdb_monitor_compose_update(dbmon, initial, unflushed, + json = ovsdb_monitor_compose_update(dbmon, initial, mcs, condition, ovsdb_monitor_compose_row_update2); if (!condition || !condition->conditional) { - ovsdb_monitor_json_cache_insert(dbmon, version, unflushed, + ovsdb_monitor_json_cache_insert(dbmon, version, mcs, json); } } else { @@ -1149,24 +1169,20 @@ ovsdb_monitor_get_update( } } - /* Maintain transaction id of 'changes'. */ - SHASH_FOR_EACH (node, &dbmon->tables) { - struct ovsdb_monitor_table *mt = node->data; - - ovsdb_monitor_table_untrack_changes(mt, unflushed); - ovsdb_monitor_table_track_changes(mt, next_unflushed); - } - *unflushed_ = next_unflushed; + /* Maintain tracking change set. */ + ovsdb_monitor_untrack_change_set(dbmon, mcs); + ovsdb_monitor_track_new_change_set(dbmon); + *p_mcs = dbmon->new_change_set; return json; } bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon, - uint64_t next_transaction) + struct ovsdb_monitor_change_set *change_set) { - ovs_assert(next_transaction <= dbmon->n_transactions + 1); - return (next_transaction <= dbmon->n_transactions); + ovs_assert(change_set); + return (change_set != dbmon->new_change_set); } void @@ -1225,15 +1241,15 @@ static void ovsdb_monitor_changes_update(const struct ovsdb_row *old, const struct ovsdb_row *new, const struct ovsdb_monitor_table *mt, - struct ovsdb_monitor_changes *changes) + struct ovsdb_monitor_change_set_for_table *mcst) { const struct uuid *uuid = ovsdb_row_get_uuid(new ? new : old); struct ovsdb_monitor_row *change; - change = ovsdb_monitor_changes_row_find(changes, uuid); + change = ovsdb_monitor_changes_row_find(mcst, uuid); if (!change) { change = xzalloc(sizeof *change); - hmap_insert(&changes->rows, &change->hmap_node, uuid_hash(uuid)); + hmap_insert(&mcst->rows, &change->hmap_node, uuid_hash(uuid)); change->uuid = *uuid; change->old = clone_monitor_row_data(mt, old); change->new = clone_monitor_row_data(mt, new); @@ -1285,7 +1301,7 @@ ovsdb_monitor_changes_update(const struct ovsdb_row *old, if (!change->old) { /* This row was added then deleted. Forget about it. */ - hmap_remove(&changes->rows, &change->hmap_node); + hmap_remove(&mcst->rows, &change->hmap_node); free(change); } } @@ -1343,7 +1359,7 @@ ovsdb_monitor_change_cb(const struct ovsdb_row *old, const struct ovsdb_monitor *m = aux->monitor; struct ovsdb_table *table = new ? new->table : old->table; struct ovsdb_monitor_table *mt; - struct ovsdb_monitor_changes *changes; + struct ovsdb_monitor_change_set_for_table *mcst; if (!aux->mt || table != aux->mt->table) { aux->mt = shash_find_data(&m->tables, table->schema->name); @@ -1360,9 +1376,9 @@ ovsdb_monitor_change_cb(const struct ovsdb_row *old, enum ovsdb_monitor_changes_efficacy efficacy = ovsdb_monitor_changes_classify(type, mt, changed); - HMAP_FOR_EACH(changes, hmap_node, &mt->changes) { - if (efficacy > OVSDB_CHANGES_NO_EFFECT) { - ovsdb_monitor_changes_update(old, new, mt, changes); + if (efficacy > OVSDB_CHANGES_NO_EFFECT) { + LIST_FOR_EACH (mcst, list_in_mt, &mt->change_sets) { + ovsdb_monitor_changes_update(old, new, mt, mcst); } } if (aux->efficacy < efficacy) { @@ -1373,34 +1389,34 @@ ovsdb_monitor_change_cb(const struct ovsdb_row *old, } void -ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon) +ovsdb_monitor_get_initial(struct ovsdb_monitor *dbmon, + struct ovsdb_monitor_change_set **p_mcs) { - struct shash_node *node; - - SHASH_FOR_EACH (node, &dbmon->tables) { - struct ovsdb_monitor_table *mt = node->data; - - if (mt->select & OJMS_INITIAL) { - struct ovsdb_row *row; - struct ovsdb_monitor_changes *changes; - - changes = ovsdb_monitor_table_find_changes(mt, 0); - if (!changes) { - changes = ovsdb_monitor_table_add_changes(mt, 0); - HMAP_FOR_EACH (row, hmap_node, &mt->table->rows) { - ovsdb_monitor_changes_update(NULL, row, mt, changes); + if (!dbmon->init_change_set) { + struct ovsdb_monitor_change_set *change_set = + ovsdb_monitor_add_change_set(dbmon, true); + dbmon->init_change_set = change_set; + + struct ovsdb_monitor_change_set_for_table *mcst; + LIST_FOR_EACH (mcst, list_in_change_set, + &change_set->change_set_for_tables) { + if (mcst->mt->select & OJMS_INITIAL) { + struct ovsdb_row *row; + HMAP_FOR_EACH (row, hmap_node, &mcst->mt->table->rows) { + ovsdb_monitor_changes_update(NULL, row, mcst->mt, mcst); } - } else { - changes->n_refs++; } } + } else { + dbmon->init_change_set->n_refs++; } + *p_mcs = dbmon->init_change_set; } void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon, struct ovsdb_jsonrpc_monitor *jsonrpc_monitor, - uint64_t unflushed) + struct ovsdb_monitor_change_set *change_set) { struct jsonrpc_monitor_node *jm; @@ -1413,10 +1429,8 @@ ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon, LIST_FOR_EACH(jm, node, &dbmon->jsonrpc_monitors) { if (jm->jsonrpc_monitor == jsonrpc_monitor) { /* Release the tracked changes. */ - struct shash_node *node; - SHASH_FOR_EACH (node, &dbmon->tables) { - struct ovsdb_monitor_table *mt = node->data; - ovsdb_monitor_table_untrack_changes(mt, unflushed); + if (change_set) { + ovsdb_monitor_untrack_change_set(dbmon, change_set); } ovs_list_remove(&jm->node); free(jm); @@ -1547,15 +1561,16 @@ ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon) ovsdb_monitor_json_cache_flush(dbmon); hmap_destroy(&dbmon->json_cache); + struct ovsdb_monitor_change_set *cs, *cs_next; + LIST_FOR_EACH_SAFE (cs, cs_next, list_node, &dbmon->change_sets) { + ovs_list_remove(&cs->list_node); + ovsdb_monitor_change_set_destroy(cs); + free(cs); + } + SHASH_FOR_EACH (node, &dbmon->tables) { struct ovsdb_monitor_table *mt = node->data; - struct ovsdb_monitor_changes *changes, *next; - - HMAP_FOR_EACH_SAFE (changes, next, hmap_node, &mt->changes) { - hmap_remove(&mt->changes, &changes->hmap_node); - ovsdb_monitor_changes_destroy(changes); - } - hmap_destroy(&mt->changes); + ovs_assert(ovs_list_is_empty(&mt->change_sets)); free(mt->columns); free(mt->columns_index_map); free(mt); @@ -1570,24 +1585,17 @@ ovsdb_monitor_commit(struct ovsdb_monitor *m, const struct ovsdb_txn *txn) struct ovsdb_monitor_aux aux; ovsdb_monitor_init_aux(&aux, m); - /* Update ovsdb_monitor's transaction number for - * each transaction, before calling ovsdb_monitor_change_cb(). */ - m->n_transactions++; ovsdb_txn_for_each_change(txn, ovsdb_monitor_change_cb, &aux); - switch(aux.efficacy) { - case OVSDB_CHANGES_NO_EFFECT: - /* The transaction is ignored by the monitor. - * Roll back the 'n_transactions' as if the transaction - * has never happened. */ - m->n_transactions--; - break; - case OVSDB_CHANGES_REQUIRE_INTERNAL_UPDATE: - /* Nothing. */ - break; - case OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE: - ovsdb_monitor_json_cache_flush(m); - break; + if (aux.efficacy > OVSDB_CHANGES_NO_EFFECT) { + /* The transaction is has impact to the monitor. + * Reset new_change_set, so that a new change set will be + * created for future trackings. */ + m->new_change_set = NULL; + + if (aux.efficacy == OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE) { + ovsdb_monitor_json_cache_flush(m); + } } } diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h index 9bc0613..112c672 100644 --- a/ovsdb/monitor.h +++ b/ovsdb/monitor.h @@ -56,9 +56,10 @@ struct ovsdb_monitor *ovsdb_monitor_add(struct ovsdb_monitor *); void ovsdb_monitor_add_jsonrpc_monitor(struct ovsdb_monitor *, struct ovsdb_jsonrpc_monitor *); +struct ovsdb_monitor_change_set; void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *, struct ovsdb_jsonrpc_monitor *, - uint64_t unflushed); + struct ovsdb_monitor_change_set *); void ovsdb_monitor_add_table(struct ovsdb_monitor *, const struct ovsdb_table *); @@ -77,16 +78,17 @@ struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *, bool cond_updated, struct ovsdb_monitor_session_condition *, enum ovsdb_monitor_version, - uint64_t *unflushed_transaction); + struct ovsdb_monitor_change_set **p_mcs); void ovsdb_monitor_table_add_select(struct ovsdb_monitor *, const struct ovsdb_table *, enum ovsdb_monitor_selection); bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *, - uint64_t next_transaction); + struct ovsdb_monitor_change_set *); -void ovsdb_monitor_get_initial(const struct ovsdb_monitor *); +void ovsdb_monitor_get_initial(struct ovsdb_monitor *, + struct ovsdb_monitor_change_set **); void ovsdb_monitor_get_memory_usage(struct simap *); From patchwork Tue Jan 29 20:01:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032990 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="gqGRrD/f"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyLH2DcHz9sBQ for ; Wed, 30 Jan 2019 07:11:03 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 676573270; Tue, 29 Jan 2019 20:09:36 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id B27732E4E for ; Tue, 29 Jan 2019 20:01:55 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f177.google.com (mail-pg1-f177.google.com [209.85.215.177]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 0B01A834 for ; Tue, 29 Jan 2019 20:01:54 +0000 (UTC) Received: by mail-pg1-f177.google.com with SMTP id d72so9202597pga.9 for ; Tue, 29 Jan 2019 12:01:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uCX/tA+uaYQC25gJQ9/kD/BYQrjXh5P5eId6P2Jx/wc=; b=gqGRrD/f9iF0UDkcxbOWE+1+4lfpgLiiFRvw7F3R9XJ1FznFoBfFh9+v/giOBWFI6u CrZkbASNYGOCZiPJ6jFZyXW1koplqEkobMka0N1piZLZ+4OX1XZ+zBHy1jadcnh0Grkg UPrZUcXl5MGL2pa9+5orCVGemDmY7zeGaMKj4Qk2D0BQ+1R0j35RBPKNiBw7sWYcXYqo 1jEvne7pYeDIuhx0JeVYBnyz0uv1mWvRbfXSpxG1o/T14i10LcT+1pWiTLC0E/+BNJlO dnmVVTDvuPb5JnUbSFOBdWyI6KiwOsK6WfCgmGnvcO40GclH0Iz/zh/neV7Ps0fkSQ4x k6bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uCX/tA+uaYQC25gJQ9/kD/BYQrjXh5P5eId6P2Jx/wc=; b=RLDYwFR6rGOzGDdHsxRalG9W9WR70k8PLFdaAnqUwjDB39HXqRP4IPkSaOilLVfx0e WiOfiEQsVEaZeiDG/gNjVaNTjHOYu5W2s2EjmDQ9VXTBYZ4jgGhii33G4Dsh4+MZIdx5 8z4T6pKxo7FPlvpR0CW47/h77U94aV99XaqI0+gjLMLEFto5cZ15E4EsYSyX3fViek8U 46p1VcaWt31agnKRRuBYo1M0fDB6G2Ve6oLLNiYKZaIaKVgLVcCPPe4rWR4xBbHJl8Mp bDPVSbIxKHbt7M8PQ2I4BPg2mOGnBdYNwBDQJOcgMuL8wJ0JXjIHvVthK1mxsvXigdtF bURw== X-Gm-Message-State: AJcUukeKMGX20ZhnR+5fjbo9r0htYh30iS27koDN7Szj+UFFfFV9ktDO z0yoBk0U0MR+2uZA/ZnMnctasJ+o X-Google-Smtp-Source: ALg8bN6/s8dgijfJOCQtu4q5NHQC+VUNWaH707hldqUF0QMn97HNZfWbEQHuHt+cQvcPXkuGTBLgvw== X-Received: by 2002:a62:11c7:: with SMTP id 68mr27468167pfr.21.1548792114333; Tue, 29 Jan 2019 12:01:54 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:53 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:46 -0800 Message-Id: <1548792109-111156-5-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 4/7] ovsdb-server: Transaction history tracking. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Maintaining last N (n = 100) transactions in memory, which will be used for future patches for generating monitor data from any point in this N transactions. Signed-off-by: Han Zhou --- ovsdb/ovsdb-server.c | 11 +++++ ovsdb/ovsdb.c | 3 ++ ovsdb/ovsdb.h | 10 +++++ ovsdb/transaction.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++- ovsdb/transaction.h | 3 ++ 5 files changed, 137 insertions(+), 1 deletion(-) diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 65a47a4..321381e 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -219,6 +219,7 @@ main_loop(struct server_config *config, struct shash_node *next; SHASH_FOR_EACH_SAFE (node, next, all_dbs) { struct db *db = node->data; + ovsdb_txn_history_run(db->db); if (ovsdb_trigger_run(db->db, time_msec())) { /* The message below is currently the only reason to disconnect * all clients. */ @@ -568,6 +569,7 @@ parse_txn(struct server_config *config, struct db *db, error = ovsdb_file_txn_from_json(db->db, txn_json, false, &txn); if (!error) { + ovsdb_txn_set_txnid(txnid, txn); log_and_free_error(ovsdb_txn_replay_commit(txn)); } if (!error && !uuid_is_zero(txnid)) { @@ -658,6 +660,13 @@ open_db(struct server_config *config, const char *filename) db->db = ovsdb_create(schema, storage); ovsdb_jsonrpc_server_add_db(config->jsonrpc, db->db); + /* Enable txn history for clustered mode. It is not enabled for other mode + * for now, since txn id is available for clustered mode only. */ + if (ovsdb_storage_is_clustered(storage)) { + db->db->need_txn_history = true; + db->db->n_txn_history = 0; + ovs_list_init(&db->db->txn_history); + } read_db(config, db); error = (db->db->name[0] == '_' @@ -695,6 +704,8 @@ add_server_db(struct server_config *config) json_destroy(schema_json); struct db *db = xzalloc(sizeof *db); + /* We don't need txn_history for server_db. */ + db->filename = xstrdup(""); db->db = ovsdb_create(schema, ovsdb_storage_create_unbacked()); bool ok OVS_UNUSED = ovsdb_jsonrpc_server_add_db(config->jsonrpc, db->db); diff --git a/ovsdb/ovsdb.c b/ovsdb/ovsdb.c index da8db82..ea7dd23 100644 --- a/ovsdb/ovsdb.c +++ b/ovsdb/ovsdb.c @@ -455,6 +455,9 @@ ovsdb_destroy(struct ovsdb *db) /* Remove all the monitors. */ ovsdb_monitors_remove(db); + /* Destroy txn history. */ + ovsdb_txn_history_destroy(db); + /* The caller must ensure that no triggers remain. */ ovs_assert(ovs_list_is_empty(&db->triggers)); diff --git a/ovsdb/ovsdb.h b/ovsdb/ovsdb.h index d96b1c2..32e5333 100644 --- a/ovsdb/ovsdb.h +++ b/ovsdb/ovsdb.h @@ -67,6 +67,11 @@ bool ovsdb_parse_version(const char *, struct ovsdb_version *); bool ovsdb_is_valid_version(const char *); /* Database. */ +struct ovsdb_txn_history_node { + struct ovs_list node; /* Element in struct ovsdb's txn_history list */ + struct ovsdb_txn *txn; +}; + struct ovsdb { char *name; struct ovsdb_schema *schema; @@ -80,6 +85,11 @@ struct ovsdb { bool run_triggers; struct ovsdb_table *rbac_role; + + /* History trasanctions for incremental monitor transfer. */ + bool need_txn_history; /* Need to maintain history of transactions. */ + unsigned int n_txn_history; /* Current number of history transactions. */ + struct ovs_list txn_history; /* Contains "struct ovsdb_txn_history_node. */ }; struct ovsdb *ovsdb_create(struct ovsdb_schema *, struct ovsdb_storage *); diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index 5a43132..3485383 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -40,6 +40,7 @@ struct ovsdb_txn { struct ovsdb *db; struct ovs_list txn_tables; /* Contains "struct ovsdb_txn_table"s. */ struct ds comment; + struct uuid txnid; /* For clustered mode only. It is the eid. */ }; /* A table modified by a transaction. */ @@ -106,13 +107,19 @@ static unsigned int serial; struct ovsdb_txn * ovsdb_txn_create(struct ovsdb *db) { - struct ovsdb_txn *txn = xmalloc(sizeof *txn); + struct ovsdb_txn *txn = xzalloc(sizeof *txn); txn->db = db; ovs_list_init(&txn->txn_tables); ds_init(&txn->comment); return txn; } +void +ovsdb_txn_set_txnid(const struct uuid *txnid, struct ovsdb_txn *txn) +{ + txn->txnid = *txnid; +} + static void ovsdb_txn_free(struct ovsdb_txn *txn) { @@ -881,11 +888,79 @@ ovsdb_txn_precommit(struct ovsdb_txn *txn) return error; } +static struct ovsdb_txn* +ovsdb_txn_clone(const struct ovsdb_txn *txn) +{ + struct ovsdb_txn *txn_cloned = xzalloc(sizeof *txn_cloned); + ovs_list_init(&txn_cloned->txn_tables); + txn_cloned->txnid = txn->txnid; + + struct ovsdb_txn_table *t; + LIST_FOR_EACH (t, node, &txn->txn_tables) { + struct ovsdb_txn_table *t_cloned = xmalloc(sizeof *t_cloned); + ovs_list_push_back(&txn_cloned->txn_tables, &t_cloned->node); + hmap_init(&t_cloned->txn_rows); + + struct ovsdb_txn_row *r; + HMAP_FOR_EACH (r, hmap_node, &t->txn_rows) { + size_t n_columns = shash_count(&t->table->schema->columns); + struct ovsdb_txn_row *r_cloned = + xzalloc(offsetof(struct ovsdb_txn_row, changed) + + bitmap_n_bytes(n_columns)); + + r_cloned->uuid = r->uuid; + r_cloned->table = r->table; + r_cloned->old = r->old ? ovsdb_row_clone(r->old) : NULL; + r_cloned->new = r->new ? ovsdb_row_clone(r->new) : NULL; + memcpy(&r_cloned->changed, &r->changed, bitmap_n_bytes(n_columns)); + hmap_insert(&t_cloned->txn_rows, &r_cloned->hmap_node, + uuid_hash(&r_cloned->uuid)); + } + } + return txn_cloned; +} + +static void +ovsdb_txn_destroy_cloned(struct ovsdb_txn *txn) +{ + ovs_assert(!txn->db); + struct ovsdb_txn_table *t, *next_txn_table; + LIST_FOR_EACH_SAFE (t, next_txn_table, node, &txn->txn_tables) { + struct ovsdb_txn_row *r, *next_txn_row; + HMAP_FOR_EACH_SAFE (r, next_txn_row, hmap_node, &t->txn_rows) { + if (r->old) { + ovsdb_row_destroy(r->old); + } + if (r->new) { + ovsdb_row_destroy(r->new); + } + hmap_remove(&t->txn_rows, &r->hmap_node); + free(r); + } + hmap_destroy(&t->txn_rows); + ovs_list_remove(&t->node); + free(t); + } + free(txn); +} + +static void +ovsdb_txn_add_to_history(struct ovsdb_txn *txn) +{ + if (txn->db->need_txn_history) { + struct ovsdb_txn_history_node *node = xzalloc(sizeof *node); + node->txn = ovsdb_txn_clone(txn); + ovs_list_push_back(&txn->db->txn_history, &node->node); + txn->db->n_txn_history++; + } +} + /* Finalize commit. */ void ovsdb_txn_complete(struct ovsdb_txn *txn) { if (!ovsdb_txn_is_empty(txn)) { + txn->db->run_triggers = true; ovsdb_monitors_commit(txn->db, txn); ovsdb_error_assert(for_each_txn_row(txn, ovsdb_txn_update_weak_refs)); @@ -906,6 +981,7 @@ ovsdb_txn_replay_commit(struct ovsdb_txn *txn) if (error) { ovsdb_txn_abort(txn); } else { + ovsdb_txn_add_to_history(txn); ovsdb_txn_complete(txn); } return error; @@ -1304,3 +1380,36 @@ for_each_txn_row(struct ovsdb_txn *txn, return NULL; } + +void +ovsdb_txn_history_run(struct ovsdb *db) +{ + if (!db->need_txn_history) { + return; + } + /* Remove old histories to limit the size of the history */ + while (db->n_txn_history > 100) { + struct ovsdb_txn_history_node *txn_h_node = CONTAINER_OF( + ovs_list_pop_front(&db->txn_history), + struct ovsdb_txn_history_node, node); + + ovsdb_txn_destroy_cloned(txn_h_node->txn); + free(txn_h_node); + db->n_txn_history--; + } +} + +void +ovsdb_txn_history_destroy(struct ovsdb *db) +{ + + if (!db->need_txn_history) { + return; + } + + struct ovsdb_txn_history_node *txn_h_node, *next; + LIST_FOR_EACH_SAFE (txn_h_node, next, node, &db->txn_history) { + ovsdb_txn_destroy_cloned(txn_h_node->txn); + free(txn_h_node); + } +} diff --git a/ovsdb/transaction.h b/ovsdb/transaction.h index 32384fc..c601d47 100644 --- a/ovsdb/transaction.h +++ b/ovsdb/transaction.h @@ -25,6 +25,7 @@ struct ovsdb_table; struct uuid; struct ovsdb_txn *ovsdb_txn_create(struct ovsdb *); +void ovsdb_txn_set_txnid(const struct uuid *, struct ovsdb_txn *); void ovsdb_txn_abort(struct ovsdb_txn *); struct ovsdb_error *ovsdb_txn_replay_commit(struct ovsdb_txn *) @@ -59,5 +60,7 @@ void ovsdb_txn_for_each_change(const struct ovsdb_txn *, void ovsdb_txn_add_comment(struct ovsdb_txn *, const char *); const char *ovsdb_txn_get_comment(const struct ovsdb_txn *); +void ovsdb_txn_history_run(struct ovsdb *); +void ovsdb_txn_history_destroy(struct ovsdb *); #endif /* ovsdb/transaction.h */ From patchwork Tue Jan 29 20:01:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Qv1tsy63"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyNY6YSbz9sBQ for ; Wed, 30 Jan 2019 07:13:01 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 571C83281; Tue, 29 Jan 2019 20:09:39 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 0BED62E4E for ; Tue, 29 Jan 2019 20:01:59 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 9579E827 for ; Tue, 29 Jan 2019 20:01:56 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id j10so9226000pga.1 for ; Tue, 29 Jan 2019 12:01:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+/I2Z8vG7JwBHK37w1SDTE1I34Qwx6aSV+lOqNQBUdU=; b=Qv1tsy630xExoiND7UTdWYt4RpI5iZFvsNmW/LpmPOhTF3uceq0WwrPErxfaewOpXi JORAHGMg/Zj5mSdhIzZn4+CkIX9eGoOOHvS65ETtNbLWY+Ar9hY3LADRaeeI9jVdhAm6 459ho5uT9FhGL+FRA4caican7Q0nu/FyJvuSyZ4qQo5dhbrxCrgS42Zz0/180sCWujJD WgULW7aM18kI0izrT/W49HKQYcO2K18eMjhRVW3Hk47w/wNucDJnbEyyVRlA/ZNeXtYs jmKgzkmPZU5hJohvs0qDFDaOLkdvYFNZ5gCBKjIvDHAZhEY7U5/h/UI5dqN0Rr8k1o+d 4ZXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+/I2Z8vG7JwBHK37w1SDTE1I34Qwx6aSV+lOqNQBUdU=; b=inVNhYXn7qWs0rb3ARisLU0rRtKGyrIPWh0FoSVvcysQUCTyU/TkKM4ZFCeEWjAU9L H8rTwAV5vZAn6Q8pePHwBLinVr2X/q/DJg1paKpisCoRIzwi4LEvNd3gy5qMAGDTJ7km RZypS/wAaC81RAjZY5HEoXfs+JMbrq+ZlBycUYU8FHsOzuT4zWaoqGg7vdvDjhgeaRs5 0Zrck+oA+JksxobmyxAkgMzdhqiiyRQBKTFhhWPs+TadW0lOmXFYeZc78bSkScod74mg 5op+81sjI6fVvmwxjqNJphLWJpF+deF1ixnHlmaYCS6D2ub6to8FdT3tzh935RT24cwO KY2w== X-Gm-Message-State: AJcUuke2HoCVgGXMPATQt/j88d3WGwBIyYGplFQOAEaqejlPfCBAqtyv 1//i96i9ZY8mi38w09zqtjNgJesb X-Google-Smtp-Source: ALg8bN7NmGecvcXD5rKJtUVku4INrOyk4yGo25HUr7hyKzj5I9YBUDsA4VkR8z3F8tUX3od2592zfA== X-Received: by 2002:a62:f51a:: with SMTP id n26mr17497070pfh.245.1548792115190; Tue, 29 Jan 2019 12:01:55 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:54 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:47 -0800 Message-Id: <1548792109-111156-6-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, WEIRD_QUOTING autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 5/7] ovsdb-monitor: Support monitor_cond_since. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Support the new monitor method monitor_cond_since so that a client can request monitoring start from a specific point instead of always from beginning. This will reduce the cost at scenarios when server is restarted/failed-over but client still has all existing data. In these scenarios only new changes (and in most cases no change) needed to be transfered to client. This change includes both server side and ovsdb-client side changes with the new protocol. IDLs using this capability will be added in future patches. Note: the feature takes effect only for cluster mode of ovsdb-server, because cluster mode is the only mode that supports unique transcation uuid today. For other modes, the monitor_cond_since always fall back to transfer all data with found = false. For more details of the protocol change, see Documentation/ref/ovsdb-server.7.rst. Signed-off-by: Han Zhou --- Documentation/ref/ovsdb-server.7.rst | 78 +++++++++- ovsdb/jsonrpc-server.c | 85 ++++++++-- ovsdb/monitor.c | 109 ++++++++++++- ovsdb/monitor.h | 6 + ovsdb/ovsdb-client.c | 104 ++++++++++++- ovsdb/transaction.c | 6 + ovsdb/transaction.h | 1 + tests/ovsdb-monitor.at | 294 +++++++++++++++++++++++++++++++++++ 8 files changed, 655 insertions(+), 28 deletions(-) diff --git a/Documentation/ref/ovsdb-server.7.rst b/Documentation/ref/ovsdb-server.7.rst index 14c7da8..4bbe232 100644 --- a/Documentation/ref/ovsdb-server.7.rst +++ b/Documentation/ref/ovsdb-server.7.rst @@ -364,7 +364,79 @@ Initial views of rows are not presented in update2 notifications, but in the response object to the ``monitor_cond`` request. The formatting of the object, however, is the same in either case. -4.1.15 Get Server ID +4.1.15 Monitor_cond_since +------------------------- + +A new monitor method added in Open vSwitch version 2.12. The +``monitor_cond_since`` request enables a client to request changes that +happened after a specific transaction id. A client can use this feature to +request only latest changes after a server connection reset instead of +re-transfer all data from the server again. + +The ``monitor_cond`` method described in Section 4.1.12 also applies to +``monitor_cond_since``, with the following exceptions: + +* RPC request method becomes ``monitor_cond_since``. + +* Reply result includes extra parameters. + +* Subsequent changes are sent to the client using the ``update3`` monitor + notification, described in Section 4.1.16 + +The request object has the following members:: + + "method": "monitor_cond_since" + "params": [, , , ] + "id": + +The parameter is the transaction id that identifies the latest +data the client already has, and it requests server to send changes AFTER this +transaction (exclusive). + +All other parameters are the same as ``monitor_cond`` method. + +The response object has the following members:: + + "result": [, , ] + "error": null + "id": same "id" as request + +The is a boolean value that tells if the requested by +client is found in server's history or not. If true, the changes after that +version up to current is sent. Otherwise, all data is sent. + +The is the transaction id that identifies the latest transaction +included in the changes in of this response, so that client +can keep tracking. If there is no change involved in this response, it is the +same as the in the request if is true, or zero uuid if + is false. If the server does not support transaction uuid, it will +be zero uuid as well. + +All other parameters are the same as in response object of ``monitor_cond`` +method. + +Like in ``monitor_cond``, subsequent changes that match conditions in + are automatically sent to the client, but using +``update3`` monitor notification (see Section 4.1.16), instead of ``update2``. + +4.1.16 Update3 notification +--------------------------- + +The ``update3`` notification is sent by the server to the client to report +changes in tables that are being monitored following a ``monitor_cond_since`` +request as described above. The notification has the following members:: + + "method": "update3" + "params": [, , ] + "id": null + +The is the same as described in the response object of +``monitor_cond_since``. + +All other parameters are the same as in ``update2`` monitor notification (see +Section 4.1.14). + +4.1.17 Get Server ID -------------------- A new RPC method added in Open vSwitch version 2.7. The request contains the @@ -384,7 +456,7 @@ The response object contains the following members:: running OVSDB server process. A fresh UUID is generated when the process restarts. -4.1.16 Database Change Awareness +4.1.18 Database Change Awareness -------------------------------- RFC 7047 does not provide a way for a client to find out about some kinds of @@ -414,7 +486,7 @@ The reply is always the same:: "error": null "id": same "id" as request -4.1.17 Schema Conversion +4.1.19 Schema Conversion ------------------------ Open vSwitch 2.9 adds a new JSON-RPC request to convert an online database from diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index f9b7c27..0f8024c 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -986,13 +986,19 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s, ovsdb_jsonrpc_trigger_create(s, db, request); } } else if (!strcmp(request->method, "monitor") || - (monitor_cond_enable__ && !strcmp(request->method, - "monitor_cond"))) { + (monitor_cond_enable__ && + (!strcmp(request->method, "monitor_cond") || + !strcmp(request->method, "monitor_cond_since")))) { struct ovsdb *db = ovsdb_jsonrpc_lookup_db(s, request, &reply); if (!reply) { - int l = strlen(request->method) - strlen("monitor"); - enum ovsdb_monitor_version version = l ? OVSDB_MONITOR_V2 - : OVSDB_MONITOR_V1; + enum ovsdb_monitor_version version; + if (!strcmp(request->method, "monitor")) { + version = OVSDB_MONITOR_V1; + } else if (!strcmp(request->method, "monitor_cond")) { + version = OVSDB_MONITOR_V2; + } else { + version = OVSDB_MONITOR_V3; + } reply = ovsdb_jsonrpc_monitor_create(s, db, request->params, version, request->id); } @@ -1364,7 +1370,8 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, struct shash_node *node; struct json *json; - if (json_array(params)->n != 3) { + if ((version == OVSDB_MONITOR_V2 && json_array(params)->n != 3) || + (version == OVSDB_MONITOR_V3 && json_array(params)->n != 4)) { error = ovsdb_syntax_error(params, NULL, "invalid parameters"); goto error; } @@ -1385,7 +1392,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, m->session = s; m->db = db; m->dbmon = ovsdb_monitor_create(db, m); - if (version == OVSDB_MONITOR_V2) { + if (version == OVSDB_MONITOR_V2 || version == OVSDB_MONITOR_V3) { m->condition = ovsdb_monitor_session_condition_create(); } m->version = version; @@ -1444,9 +1451,42 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, ovsdb_monitor_condition_bind(m->dbmon, m->condition); } - ovsdb_monitor_get_initial(m->dbmon, &m->change_set); - json = ovsdb_jsonrpc_monitor_compose_update(m, true); + bool initial = false; + if (version == OVSDB_MONITOR_V3) { + struct json *last_id = params->array.elems[3]; + if (last_id->type != JSON_STRING) { + error = ovsdb_syntax_error(last_id, NULL, + "last_version_id must be string"); + goto error; + } + struct uuid txn_uuid; + if (!uuid_from_string(&txn_uuid, last_id->string)) { + error = ovsdb_syntax_error(last_id, NULL, + "last_version_id must be UUID format."); + goto error; + } + if (!uuid_is_zero(&txn_uuid)) { + ovsdb_monitor_get_changes_after(&txn_uuid, m->dbmon, + &m->change_set); + } + } + if (!m->change_set) { + ovsdb_monitor_get_initial(m->dbmon, &m->change_set); + initial = true; + } + json = ovsdb_jsonrpc_monitor_compose_update(m, initial); json = json ? json : json_object_create(); + + if (m->version == OVSDB_MONITOR_V3) { + struct json *json_last_id = json_string_create_nocopy( + xasprintf(UUID_FMT, + UUID_ARGS(ovsdb_monitor_get_last_txnid( + m->dbmon)))); + + struct json *json_found = json_boolean_create(!initial); + json = json_array_create_3(json_found, json_last_id, json); + } + return jsonrpc_create_reply(json, request_id); error: @@ -1580,8 +1620,17 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, if (update_json) { struct jsonrpc_msg *msg; struct json *p; - - p = json_array_create_2(json_clone(m->monitor_id), update_json); + if (m->version == OVSDB_MONITOR_V3) { + struct json *json_last_id = json_string_create_nocopy( + xasprintf(UUID_FMT, + UUID_ARGS(ovsdb_monitor_get_last_txnid( + m->dbmon)))); + + p = json_array_create_3(json_clone(m->monitor_id), json_last_id, + update_json); + } else { + p = json_array_create_2(json_clone(m->monitor_id), update_json); + } msg = ovsdb_jsonrpc_create_notify(m, p); jsonrpc_session_send(s->js, msg); } @@ -1702,6 +1751,9 @@ ovsdb_jsonrpc_create_notify(const struct ovsdb_jsonrpc_monitor *m, case OVSDB_MONITOR_V2: method = "update2"; break; + case OVSDB_MONITOR_V3: + method = "update3"; + break; case OVSDB_MONITOR_VERSION_MAX: default: OVS_NOT_REACHED(); @@ -1728,8 +1780,17 @@ ovsdb_jsonrpc_monitor_flush_all(struct ovsdb_jsonrpc_session *s) if (json) { struct jsonrpc_msg *msg; struct json *params; + if (m->version == OVSDB_MONITOR_V3) { + struct json *json_last_id = json_string_create_nocopy( + xasprintf(UUID_FMT, + UUID_ARGS(ovsdb_monitor_get_last_txnid( + m->dbmon)))); + params = json_array_create_3(json_clone(m->monitor_id), + json_last_id, json); + } else { + params = json_array_create_2(json_clone(m->monitor_id), json); + } - params = json_array_create_2(json_clone(m->monitor_id), json); msg = ovsdb_jsonrpc_create_notify(m, params); jsonrpc_session_send(s->js, msg); } diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index b41054d..6936dc1 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -136,6 +136,9 @@ struct ovsdb_monitor_change_set { struct ovs_list change_set_for_tables; int n_refs; + + /* The previous txn id before this change set's start point. */ + struct uuid prev_txn; }; /* Contains 'struct ovsdb_monitor_row's for rows in a specific table @@ -193,7 +196,9 @@ typedef struct json * static void ovsdb_monitor_destroy(struct ovsdb_monitor *); static struct ovsdb_monitor_change_set * ovsdb_monitor_add_change_set( - struct ovsdb_monitor *, bool init_only); + struct ovsdb_monitor *, bool init_only, const struct uuid *prev_txn); +static struct ovsdb_monitor_change_set * ovsdb_monitor_find_change_set( + const struct ovsdb_monitor *, const struct uuid *prev_txn); static void ovsdb_monitor_change_set_destroy( struct ovsdb_monitor_change_set *); static void ovsdb_monitor_track_new_change_set(struct ovsdb_monitor *); @@ -505,13 +510,14 @@ ovsdb_monitor_table_exists(struct ovsdb_monitor *m, static struct ovsdb_monitor_change_set * ovsdb_monitor_add_change_set(struct ovsdb_monitor *dbmon, - bool init_only) + bool init_only, const struct uuid *prev_txn) { struct ovsdb_monitor_change_set *change_set = xzalloc(sizeof *change_set); change_set->uuid = uuid_random(); ovs_list_push_back(&(dbmon->change_sets), &change_set->list_node); ovs_list_init(&change_set->change_set_for_tables); change_set->n_refs = 1; + change_set->prev_txn = prev_txn ? *prev_txn : UUID_ZERO; struct shash_node *node; SHASH_FOR_EACH (node, &dbmon->tables) { @@ -531,6 +537,19 @@ ovsdb_monitor_add_change_set(struct ovsdb_monitor *dbmon, return change_set; }; +static struct ovsdb_monitor_change_set * +ovsdb_monitor_find_change_set(const struct ovsdb_monitor *dbmon, + const struct uuid *prev_txn) +{ + struct ovsdb_monitor_change_set *cs; + LIST_FOR_EACH (cs, list_node, &dbmon->change_sets) { + if (uuid_equals(&cs->prev_txn, prev_txn)) { + return cs; + } + } + return NULL; +} + /* Stop currently tracking changes to table 'mt' since 'transaction'. */ static void ovsdb_monitor_untrack_change_set(struct ovsdb_monitor *dbmon, @@ -558,7 +577,8 @@ ovsdb_monitor_track_new_change_set(struct ovsdb_monitor *dbmon) if (change_set) { change_set->n_refs++; } else { - change_set = ovsdb_monitor_add_change_set(dbmon, false); + change_set = ovsdb_monitor_add_change_set(dbmon, false, + ovsdb_monitor_get_last_txnid(dbmon)); dbmon->new_change_set = change_set; } } @@ -1150,12 +1170,13 @@ ovsdb_monitor_get_update( condition, ovsdb_monitor_compose_row_update); } else { - ovs_assert(version == OVSDB_MONITOR_V2); + ovs_assert(version == OVSDB_MONITOR_V2 || + version == OVSDB_MONITOR_V3); + if (!cond_updated) { json = ovsdb_monitor_compose_update(dbmon, initial, mcs, condition, ovsdb_monitor_compose_row_update2); - if (!condition || !condition->conditional) { ovsdb_monitor_json_cache_insert(dbmon, version, mcs, json); @@ -1394,7 +1415,7 @@ ovsdb_monitor_get_initial(struct ovsdb_monitor *dbmon, { if (!dbmon->init_change_set) { struct ovsdb_monitor_change_set *change_set = - ovsdb_monitor_add_change_set(dbmon, true); + ovsdb_monitor_add_change_set(dbmon, true, NULL); dbmon->init_change_set = change_set; struct ovsdb_monitor_change_set_for_table *mcst; @@ -1413,6 +1434,70 @@ ovsdb_monitor_get_initial(struct ovsdb_monitor *dbmon, *p_mcs = dbmon->init_change_set; } +static bool +ovsdb_monitor_history_change_cb(const struct ovsdb_row *old, + const struct ovsdb_row *new, + const unsigned long int *changed, + void *aux) +{ + struct ovsdb_monitor_change_set *change_set = aux; + struct ovsdb_table *table = new ? new->table : old->table; + struct ovsdb_monitor_change_set_for_table *mcst; + + enum ovsdb_monitor_selection type = + ovsdb_monitor_row_update_type(false, old, new); + LIST_FOR_EACH (mcst, list_in_change_set, + &change_set->change_set_for_tables) { + if (mcst->mt->table == table) { + enum ovsdb_monitor_changes_efficacy efficacy = + ovsdb_monitor_changes_classify(type, mcst->mt, changed); + if (efficacy > OVSDB_CHANGES_NO_EFFECT) { + ovsdb_monitor_changes_update(old, new, mcst->mt, mcst); + } + return true; + } + } + return false; +} + +void +ovsdb_monitor_get_changes_after(const struct uuid *txn_uuid, + struct ovsdb_monitor *dbmon, + struct ovsdb_monitor_change_set **p_mcs) +{ + ovs_assert(*p_mcs == NULL); + ovs_assert(!uuid_is_zero(txn_uuid)); + struct ovsdb_monitor_change_set *change_set = + ovsdb_monitor_find_change_set(dbmon, txn_uuid); + if (change_set) { + change_set->n_refs++; + *p_mcs = change_set; + return; + } + + struct ovsdb_txn_history_node *h_node; + bool found = false; + LIST_FOR_EACH (h_node, node, &dbmon->db->txn_history) { + struct ovsdb_txn *txn = h_node->txn; + if (!found) { + /* find the txn with last_id in history */ + if (uuid_equals(ovsdb_txn_get_txnid(txn), txn_uuid)) { + found = true; + if (!change_set) { + change_set = ovsdb_monitor_add_change_set(dbmon, false, + txn_uuid); + *p_mcs = change_set; + } + } + } else { + /* Already found. Add changes in each follow up transaction to + * the new change_set. */ + ovsdb_txn_for_each_change(txn, ovsdb_monitor_history_change_cb, + change_set); + } + } +} + void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon, struct ovsdb_jsonrpc_monitor *jsonrpc_monitor, @@ -1653,3 +1738,15 @@ ovsdb_monitor_prereplace_db(struct ovsdb *db) } } } + +const struct uuid * +ovsdb_monitor_get_last_txnid(struct ovsdb_monitor *dbmon) { + static struct uuid dummy = { .parts = { 0, 0, 0, 0 } }; + if (dbmon->db->n_txn_history) { + struct ovsdb_txn_history_node *thn = CONTAINER_OF( + ovs_list_back(&dbmon->db->txn_history), + struct ovsdb_txn_history_node, node); + return ovsdb_txn_get_txnid(thn->txn); + } + return &dummy; +} diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h index 112c672..1ac9aaf 100644 --- a/ovsdb/monitor.h +++ b/ovsdb/monitor.h @@ -39,6 +39,8 @@ enum ovsdb_monitor_version { OVSDB_MONITOR_V1, /* RFC 7047 "monitor" method. */ OVSDB_MONITOR_V2, /* Extension to RFC 7047, see ovsdb-server man page for details. */ + OVSDB_MONITOR_V3, /* Extension to V2, see ovsdb-server man + page for details. */ /* Last entry. */ OVSDB_MONITOR_VERSION_MAX @@ -80,6 +82,8 @@ struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *, enum ovsdb_monitor_version, struct ovsdb_monitor_change_set **p_mcs); +const struct uuid *ovsdb_monitor_get_last_txnid(struct ovsdb_monitor *); + void ovsdb_monitor_table_add_select(struct ovsdb_monitor *, const struct ovsdb_table *, enum ovsdb_monitor_selection); @@ -89,6 +93,8 @@ bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *, void ovsdb_monitor_get_initial(struct ovsdb_monitor *, struct ovsdb_monitor_change_set **); +void ovsdb_monitor_get_changes_after(const struct uuid *txn_uuid, + struct ovsdb_monitor *, struct ovsdb_monitor_change_set **); void ovsdb_monitor_get_memory_usage(struct simap *); diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 0215357..9ae15e5 100644 --- a/ovsdb/ovsdb-client.c +++ b/ovsdb/ovsdb-client.c @@ -430,6 +430,13 @@ usage(void) " DATABASE on SERVER.\n" " COLUMNs may include !initial, !insert, !delete, !modify\n" " to avoid seeing the specified kinds of changes.\n" + "\n monitor-cond-since [SERVER] [DATABASE] [LASTID] CONDITION TABLE [COLUMN,...]...\n" + " monitor contents that match CONDITION of COLUMNs in TABLE in\n" + " DATABASE on SERVER, since change after LASTID.\n" + " LASTID specifies transaction ID after which the monitoring\n" + " starts, which works only for cluster mode. If ignored, it\n" + " defaults to an all-zero uuid.\n" + " Other arguments are the same as in monitor-cond.\n" "\n convert [SERVER] SCHEMA\n" " convert database on SERVER named in SCHEMA to SCHEMA.\n" "\n needs-conversion [SERVER] SCHEMA\n" @@ -1127,6 +1134,35 @@ monitor2_print(struct json *table_updates2, } static void +monitor3_print(struct json *result, + const struct monitored_table *mts, size_t n_mts) +{ + if (result->type != JSON_ARRAY) { + ovs_error(0, " is not array"); + } + + if (result->array.n != 3) { + ovs_error(0, " should have 3 elements, but has %"PRIuSIZE".", + result->array.n); + } + + bool found = json_boolean(result->array.elems[0]); + const char *last_id = json_string(result->array.elems[1]); + printf("found: %s, last_id: %s\n", found ? "true" : "false", last_id); + + struct json *table_updates2 = result->array.elems[2]; + monitor2_print(table_updates2, mts, n_mts); +} + +static void +monitor3_notify_print(const char *last_id, struct json *table_updates2, + const struct monitored_table *mts, size_t n_mts) +{ + printf("\nlast_id: %s", last_id); + monitor2_print(table_updates2, mts, n_mts); +} + +static void add_column(const char *server, const struct ovsdb_column *column, struct ovsdb_column_set *columns, struct json *columns_json) { @@ -1333,7 +1369,8 @@ destroy_monitored_table(struct monitored_table *mts, size_t n) static void do_monitor__(struct jsonrpc *rpc, const char *database, enum ovsdb_monitor_version version, - int argc, char *argv[], struct json *condition) + int argc, char *argv[], struct json *condition, + const struct uuid *last_id) { const char *server = jsonrpc_get_name(rpc); const char *table_name = argv[0]; @@ -1411,8 +1448,24 @@ do_monitor__(struct jsonrpc *rpc, const char *database, monitor = json_array_create_3(json_string_create(database), json_null_create(), monitor_requests); - const char *method = version == OVSDB_MONITOR_V2 ? "monitor_cond" - : "monitor"; + const char *method; + switch (version) { + case OVSDB_MONITOR_V1: + method = "monitor"; + break; + case OVSDB_MONITOR_V2: + method = "monitor_cond"; + break; + case OVSDB_MONITOR_V3: + method = "monitor_cond_since"; + struct json *json_last_id = json_string_create_nocopy( + xasprintf(UUID_FMT, UUID_ARGS(last_id))); + json_array_add(monitor, json_last_id); + break; + case OVSDB_MONITOR_VERSION_MAX: + default: + OVS_NOT_REACHED(); + } struct jsonrpc_msg *request; request = jsonrpc_create_request(method, monitor, NULL); @@ -1444,6 +1497,9 @@ do_monitor__(struct jsonrpc *rpc, const char *database, case OVSDB_MONITOR_V2: monitor2_print(msg->result, mts, n_mts); break; + case OVSDB_MONITOR_V3: + monitor3_print(msg->result, mts, n_mts); + break; case OVSDB_MONITOR_VERSION_MAX: default: OVS_NOT_REACHED(); @@ -1470,6 +1526,17 @@ do_monitor__(struct jsonrpc *rpc, const char *database, fflush(stdout); } } else if (msg->type == JSONRPC_NOTIFY + && version == OVSDB_MONITOR_V3 + && !strcmp(msg->method, "update3")) { + struct json *params = msg->params; + if (params->type == JSON_ARRAY + && params->array.n == 3 + && params->array.elems[0]->type == JSON_NULL) { + monitor3_notify_print(json_string(params->array.elems[1]), + params->array.elems[2], mts, n_mts); + fflush(stdout); + } + } else if (msg->type == JSONRPC_NOTIFY && !strcmp(msg->method, "monitor_canceled")) { ovs_fatal(0, "%s: %s database was removed", server, database); @@ -1500,12 +1567,13 @@ static void do_monitor(struct jsonrpc *rpc, const char *database, int argc, char *argv[]) { - do_monitor__(rpc, database, OVSDB_MONITOR_V1, argc, argv, NULL); + do_monitor__(rpc, database, OVSDB_MONITOR_V1, argc, argv, NULL, NULL); } static void -do_monitor_cond(struct jsonrpc *rpc, const char *database, - int argc, char *argv[]) +do_monitor_cond__(struct jsonrpc *rpc, const char *database, + enum ovsdb_monitor_version version, + struct uuid *last_id, int argc, char *argv[]) { struct ovsdb_condition cnd; struct json *condition = NULL; @@ -1524,10 +1592,31 @@ do_monitor_cond(struct jsonrpc *rpc, const char *database, check_ovsdb_error(ovsdb_condition_from_json(table, condition, NULL, &cnd)); ovsdb_condition_destroy(&cnd); - do_monitor__(rpc, database, OVSDB_MONITOR_V2, --argc, ++argv, condition); + do_monitor__(rpc, database, version, --argc, ++argv, condition, + last_id); ovsdb_schema_destroy(schema); } +static void +do_monitor_cond(struct jsonrpc *rpc, const char *database, + int argc, char *argv[]) +{ + do_monitor_cond__(rpc, database, OVSDB_MONITOR_V2, NULL, argc, argv); +} + +static void +do_monitor_cond_since(struct jsonrpc *rpc, const char *database, + int argc, char *argv[]) +{ + ovs_assert(argc > 1); + struct uuid last_id; + if (uuid_from_string(&last_id, argv[0])) { + argc--; + argv++; + } + do_monitor_cond__(rpc, database, OVSDB_MONITOR_V3, &last_id, argc, argv); +} + static bool is_database_clustered(struct jsonrpc *rpc, const char *database) { @@ -2409,6 +2498,7 @@ static const struct ovsdb_client_command all_commands[] = { { "query", NEED_NONE, 1, 2, do_query }, { "monitor", NEED_DATABASE, 1, INT_MAX, do_monitor }, { "monitor-cond", NEED_DATABASE, 2, 3, do_monitor_cond }, + { "monitor-cond-since", NEED_DATABASE, 2, 4, do_monitor_cond_since }, { "wait", NEED_NONE, 2, 3, do_wait }, { "convert", NEED_NONE, 1, 2, do_convert }, { "needs-conversion", NEED_NONE, 1, 2, do_needs_conversion }, diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index 3485383..0081840 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -120,6 +120,12 @@ ovsdb_txn_set_txnid(const struct uuid *txnid, struct ovsdb_txn *txn) txn->txnid = *txnid; } +const struct uuid * +ovsdb_txn_get_txnid(const struct ovsdb_txn *txn) +{ + return &txn->txnid; +} + static void ovsdb_txn_free(struct ovsdb_txn *txn) { diff --git a/ovsdb/transaction.h b/ovsdb/transaction.h index c601d47..929520e 100644 --- a/ovsdb/transaction.h +++ b/ovsdb/transaction.h @@ -26,6 +26,7 @@ struct uuid; struct ovsdb_txn *ovsdb_txn_create(struct ovsdb *); void ovsdb_txn_set_txnid(const struct uuid *, struct ovsdb_txn *); +const struct uuid *ovsdb_txn_get_txnid(const struct ovsdb_txn *); void ovsdb_txn_abort(struct ovsdb_txn *); struct ovsdb_error *ovsdb_txn_replay_commit(struct ovsdb_txn *) diff --git a/tests/ovsdb-monitor.at b/tests/ovsdb-monitor.at index dca7cad..657858b 100644 --- a/tests/ovsdb-monitor.at +++ b/tests/ovsdb-monitor.at @@ -83,6 +83,7 @@ m4_define([OVSDB_CHECK_MONITOR], m4_define([OVSDB_CHECK_MONITOR_COND], [AT_SETUP([$1]) AT_KEYWORDS([ovsdb server monitor monitor-cond positive $10]) + echo $10 $2 > schema AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore]) for txn in m4_foreach([txn], [$3], ['txn' ]); do @@ -589,3 +590,296 @@ row,action,name,number,_version [[[["name","==","one"]]]], [[[false]]], [[[true]]]]) + +# Test monitor-cond-since with zero uuid, which shouldn't +# be found in server and server should send all rows +# as initial. +AT_SETUP([monitor-cond-since not found]) +AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive]) +ordinal_schema > schema +AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore]) +AT_CAPTURE_FILE([ovsdb-server-log]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) +on_exit 'kill `cat ovsdb-server.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore]) +done + +# Omitting the last_id parameter in ovsdb-client monitor-cond-since command +# will by default using all zero uuid, which doesn't exist in any history txn. +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) +on_exit 'kill `cat ovsdb-client.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 10, "name": "ten"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], + [ignore], [ignore], [kill `cat server-pid client-pid`]) +done +AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0], + [ignore], [ignore]) +AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore]) +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) +AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], + [[found: false, last_id: <0> +row,action,name,number,_version +<1>,initial,"""one""",1,"[""uuid"",""<2>""]" + +last_id: <3> +row,action,name,number,_version +<4>,insert,"""ten""",10,"[""uuid"",""<5>""]" +]], [ignore]) +AT_CLEANUP + +# Test monitor-cond-since in ovsdb server restart scenario. +# ovsdb-client should receive only new changes after the +# specific transaction id. +AT_SETUP([monitor-cond-since db restart]) +AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive]) +ordinal_schema > schema +AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore]) +AT_CAPTURE_FILE([ovsdb-server-log]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) +on_exit 'kill `cat ovsdb-server.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore]) +done + +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) +on_exit 'kill `cat ovsdb-client.pid`' +OVS_WAIT_UNTIL([grep last_id output]) + +kill `cat ovsdb-client.pid` +kill `cat ovsdb-server.pid` +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) + +# Remember the last_id, which will be used for monitor-cond-since later. +last_id=`grep last_id output | awk '{print $4}'` + +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) + +# Some new changes made to db after restarting the server. +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 10, "name": "ten"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], + [ignore], [ignore], [kill `cat server-pid client-pid`]) +done + +# Use last_id to monitor and get only the new changes. +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals $last_id '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) + +AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0], + [ignore], [ignore]) +AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore]) +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) +AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], + [[found: true, last_id: <0> +row,action,name,number,_version +<1>,insert,"""ten""",10,"[""uuid"",""<2>""]" +]], [ignore]) +AT_CLEANUP + +# Test monitor-cond-since with last_id found in server +# but there is no new change after that transaction. +AT_SETUP([monitor-cond-since found but no new rows]) +AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive]) +ordinal_schema > schema +AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore]) +AT_CAPTURE_FILE([ovsdb-server-log]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) +on_exit 'kill `cat ovsdb-server.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore]) +done +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) +on_exit 'kill `cat ovsdb-client.pid`' +OVS_WAIT_UNTIL([grep last_id output]) + +kill `cat ovsdb-client.pid` +OVS_WAIT_UNTIL([test ! -e ovsdb-client.pid]) +last_id=`grep last_id output | awk '{print $4}'` +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals $last_id '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) + +AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0], + [ignore], [ignore]) +AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore]) +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) +AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], + [[found: true, last_id: <0> +]], [ignore]) +AT_CLEANUP + +# Test monitor-cond-since against empty DB +AT_SETUP([monitor-cond-since empty db]) +AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive]) +ordinal_schema > schema +AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore]) +AT_CAPTURE_FILE([ovsdb-server-log]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) +on_exit 'kill `cat ovsdb-server.pid`' +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) +on_exit 'kill `cat ovsdb-client.pid`' +OVS_WAIT_UNTIL([grep last_id output]) + +AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0], + [ignore], [ignore]) +AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore]) +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) +AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], + [[found: false, last_id: <0> +]], [ignore]) +AT_CLEANUP + +# Test monitor-cond-since with cond-change followed. +AT_SETUP([monitor-cond-since condition change]) +AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive]) +ordinal_schema > schema +AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore]) +AT_CAPTURE_FILE([ovsdb-server-log]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) +on_exit 'kill `cat ovsdb-server.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore]) +done +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[]]' ordinals > output], [0], [ignore], [ignore]) +on_exit 'kill `cat ovsdb-client.pid`' +for cond in m4_foreach([cond], + [[[[["name","==","one"],["name","==","two"]]]], + [[[["name","==","one"]]]], + [[[false]]], + [[[true]]]], ['cond' ]); do + AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/cond_change ordinals "$cond"], [0], [ignore], [ignore]) +done +AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0], + [ignore], [ignore]) +AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore]) +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) +AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], + [[found: false, last_id: <0> +row,action,name,number,_version +<1>,initial,"""one""",1,"[""uuid"",""<2>""]" +<3>,initial,"""two""",2,"[""uuid"",""<4>""]" +<5>,initial,"""zero""",,"[""uuid"",""<6>""]" + +last_id: <0> +row,action,name,number,_version +<5>,delete,,, + +last_id: <0> +row,action,name,number,_version +<3>,delete,,, + +last_id: <0> +row,action,name,number,_version +<1>,delete,,, + +last_id: <0> +row,action,name,number,_version +<1>,insert,"""one""",1,"[""uuid"",""<2>""]" +<3>,insert,"""two""",2,"[""uuid"",""<4>""]" +<5>,insert,"""zero""",,"[""uuid"",""<6>""]" +]], [ignore]) +AT_CLEANUP + +# Test monitor-cond-since with non-cluster mode server +AT_SETUP([monitor-cond-since non-cluster]) +AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive]) +ordinal_schema > schema +AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore]) +AT_CAPTURE_FILE([ovsdb-server-log]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1]) +on_exit 'kill `cat ovsdb-server.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore]) +done + +AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output], + [0], [ignore], [ignore]) +on_exit 'kill `cat ovsdb-client.pid`' +for txn in m4_foreach([txn], [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 10, "name": "ten"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do + AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], + [ignore], [ignore], [kill `cat server-pid client-pid`]) +done +AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0], + [ignore], [ignore]) +AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore]) +OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid]) + +# Transaction shouldn't be found, and last_id returned should always +# be the same (all zero uuid) +AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], + [[found: false, last_id: <0> +row,action,name,number,_version +<1>,initial,"""one""",1,"[""uuid"",""<2>""]" + +last_id: <0> +row,action,name,number,_version +<3>,insert,"""ten""",10,"[""uuid"",""<4>""]" +]], [ignore]) +AT_CLEANUP + From patchwork Tue Jan 29 20:01:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032992 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Q8AI8cp8"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyMV59Zlz9sBQ for ; Wed, 30 Jan 2019 07:12:06 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D76023279; Tue, 29 Jan 2019 20:09:37 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id EE9D02E4E for ; Tue, 29 Jan 2019 20:01:57 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl1-f194.google.com (mail-pl1-f194.google.com [209.85.214.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id DE630834 for ; Tue, 29 Jan 2019 20:01:56 +0000 (UTC) Received: by mail-pl1-f194.google.com with SMTP id a14so9818831plm.12 for ; Tue, 29 Jan 2019 12:01:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=V/8grDfq2dR/559uULr/FMR2eiedjvtWcrzuX8MRazw=; b=Q8AI8cp8OUtpTDl50USdMz1NFsAZu5j60VAiI0Hv38yx/kqDLIVSm7DDQRDjjrLkJG bPpvE3/eNg6yiCUug8HU+nd93DyDc4tlgheFGLBOS1i8zof8LGjlNoMvXla9WcnxobZZ acGWIjP0CEhTRkXqRxsmxou+X61DG29KewWlKB6SkbxZ8XYgX2Q/mcPQpqDlNaob1YdT of9t9DFM/1h4aEKGfqcoCbRcmzShrBQSFhaXMK1/+Fy2QqEtdWSEaZIjHfiI9qtYrZtm uRBWX+cst/m6cIBQCyrLNvNbl6iIMRLOAYV0OqKWWO1h3jastA7Fo3ZvOWteUcrneQtf QMng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=V/8grDfq2dR/559uULr/FMR2eiedjvtWcrzuX8MRazw=; b=toYaWq+xertgbMSui5qOFsHmI3vMxDu2k3K25dZXSivRvJP9FYM6ZL6ILGqJuBT6RY lTyYjWxskwmz9FzE3N0kqkjeCaPXauOy2Qt6WQ1CtvBTcnzoikMm6XMkNOJmE+iPqvMa sys1mIzcJClx5zk2xixUg8TQyX6AqGqA3f1y5pZtc3kd/sTSk7R8Sa7O4PS8Rlvz0br+ Qfwe96LtRbaGoD0FJTwYsgpbiN0t621pxl/XOl9D7hFJZRS9AiABvrREji7MS7nYmrSQ GwjYuQQHgV7s78mXkMPSb6U5bCHLjki5DQy7A5vvzZtJBwGWrwzO/4SzE+6sZiw2IO7s VJuA== X-Gm-Message-State: AJcUukf+SpwbJKO+ftPczg3VrAResP2OLsQbrDIaN+DNLlBf6MjW6/dA EXab4N6okT/eSPlx8a4PCZ9zG+/V X-Google-Smtp-Source: ALg8bN5AXNJmyl1hxX2bmQDMFIvpiZmyCzTlJyh9KH+UzaWpou5rKOiTQ2n/uEawrPAF+71YtNWsWA== X-Received: by 2002:a17:902:aa82:: with SMTP id d2mr27476712plr.153.1548792116089; Tue, 29 Jan 2019 12:01:56 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:55 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:48 -0800 Message-Id: <1548792109-111156-7-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 6/7] ovsdb-idl.c: Support monitor_cond_since method in C IDL. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Use monitor_cond_since in C IDL. If it is not supported by server, fall back to old method (monitor_cond, or monitor). Signed-off-by: Han Zhou --- lib/ovsdb-idl.c | 206 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 158 insertions(+), 48 deletions(-) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index a7274de..7ef4ed0 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -106,10 +106,10 @@ struct ovsdb_idl_arc { * connection. The next connection attempt has a chance at \ * picking a connected server. \ * \ - * * Otherwise, sends a "monitor_cond" request for the IDL \ + * * Otherwise, sends a "monitor_cond_since" request for the IDL \ * database whose details are informed by the schema \ * (obtained from the row), and transitions to \ - * IDL_S_DATA_MONITOR_COND_REQUESTED. \ + * IDL_S_DATA_MONITOR_COND_SINCE_REQUESTED. \ * \ * - If the reply indicates success, but the Database table does \ * not have a row for the IDL database, transitions to \ @@ -125,6 +125,13 @@ struct ovsdb_idl_arc { * transitions to IDL_S_DATA_MONITOR_COND_REQUESTED. */ \ OVSDB_IDL_STATE(DATA_SCHEMA_REQUESTED) \ \ + /* Waits for "monitor_cond_since" reply. If successful, replaces \ + * the IDL contents by the data carried in the reply and \ + * transitions to IDL_S_MONITORING. On failure, sends a \ + * "monitor_cond" request and transitions to \ + * IDL_S_DATA_MONITOR_COND_REQUESTED. */ \ + OVSDB_IDL_STATE(DATA_MONITOR_COND_SINCE_REQUESTED) \ + \ /* Waits for "monitor_cond" reply. If successful, replaces the \ * IDL contents by the data carried in the reply and transitions \ * to IDL_S_MONITORING. On failure, sends a "monitor" request \ @@ -136,9 +143,9 @@ struct ovsdb_idl_arc { * IDL_S_MONITORING. On failure, transitions to IDL_S_ERROR. */ \ OVSDB_IDL_STATE(DATA_MONITOR_REQUESTED) \ \ - /* State that processes "update" or "update2" notifications for \ - * the main database (and the Database table in _Server if \ - * available). \ + /* State that processes "update", "update2" or "update3" \ + * notifications for the main database (and the Database table \ + * in _Server if available). \ * \ * If we're monitoring the Database table and we get notified \ * that the IDL database has been deleted, we close the \ @@ -167,10 +174,18 @@ enum ovsdb_idl_state { static const char *ovsdb_idl_state_to_string(enum ovsdb_idl_state); +enum ovsdb_idl_monitor_method { + OVSDB_IDL_MM_MONITOR, + OVSDB_IDL_MM_MONITOR_COND, + OVSDB_IDL_MM_MONITOR_COND_SINCE +}; + enum ovsdb_idl_monitoring { OVSDB_IDL_NOT_MONITORING, /* Database is not being monitored. */ OVSDB_IDL_MONITORING, /* Database has "monitor" outstanding. */ OVSDB_IDL_MONITORING_COND, /* Database has "monitor_cond" outstanding. */ + OVSDB_IDL_MONITORING_COND_SINCE, /* Database has "monitor_cond_since" + outstanding. */ }; struct ovsdb_idl_db { @@ -220,7 +235,7 @@ static void ovsdb_idl_send_db_change_aware(struct ovsdb_idl *); static bool ovsdb_idl_check_server_db(struct ovsdb_idl *); static void ovsdb_idl_send_monitor_request(struct ovsdb_idl *, struct ovsdb_idl_db *, - bool use_monitor_cond); + enum ovsdb_idl_monitor_method); struct ovsdb_idl { struct ovsdb_idl_db server; @@ -287,8 +302,8 @@ static struct vlog_rate_limit other_rl = VLOG_RATE_LIMIT_INIT(1, 5); static void ovsdb_idl_clear(struct ovsdb_idl *); static void ovsdb_idl_db_parse_monitor_reply(struct ovsdb_idl_db *, - const struct json *result, - bool is_monitor_cond); + const struct json *result, + enum ovsdb_idl_monitor_method method); static bool ovsdb_idl_db_parse_update_rpc(struct ovsdb_idl_db *, const struct jsonrpc_msg *); static bool ovsdb_idl_handle_monitor_canceled(struct ovsdb_idl *, @@ -296,7 +311,7 @@ static bool ovsdb_idl_handle_monitor_canceled(struct ovsdb_idl *, const struct jsonrpc_msg *); static void ovsdb_idl_db_parse_update(struct ovsdb_idl_db *, const struct json *table_updates, - bool is_monitor_cond); + enum ovsdb_idl_monitor_method method); static bool ovsdb_idl_process_update(struct ovsdb_idl_table *, const struct uuid *, const struct json *old, @@ -674,7 +689,8 @@ ovsdb_idl_process_response(struct ovsdb_idl *idl, struct jsonrpc_msg *msg) if (!ok && idl->state != IDL_S_SERVER_SCHEMA_REQUESTED && idl->state != IDL_S_SERVER_MONITOR_COND_REQUESTED - && idl->state != IDL_S_DATA_MONITOR_COND_REQUESTED) { + && idl->state != IDL_S_DATA_MONITOR_COND_REQUESTED + && idl->state != IDL_S_DATA_MONITOR_COND_SINCE_REQUESTED) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); char *s = jsonrpc_msg_to_string(msg); VLOG_INFO_RL(&rl, "%s: received unexpected %s response in " @@ -692,7 +708,8 @@ ovsdb_idl_process_response(struct ovsdb_idl *idl, struct jsonrpc_msg *msg) if (ok) { json_destroy(idl->server.schema); idl->server.schema = json_clone(msg->result); - ovsdb_idl_send_monitor_request(idl, &idl->server, true); + ovsdb_idl_send_monitor_request(idl, &idl->server, + OVSDB_IDL_MM_MONITOR_COND); ovsdb_idl_transition(idl, IDL_S_SERVER_MONITOR_COND_REQUESTED); } else { ovsdb_idl_send_schema_request(idl, &idl->data); @@ -703,7 +720,8 @@ ovsdb_idl_process_response(struct ovsdb_idl *idl, struct jsonrpc_msg *msg) case IDL_S_SERVER_MONITOR_COND_REQUESTED: if (ok) { idl->server.monitoring = OVSDB_IDL_MONITORING_COND; - ovsdb_idl_db_parse_monitor_reply(&idl->server, msg->result, true); + ovsdb_idl_db_parse_monitor_reply(&idl->server, msg->result, + OVSDB_IDL_MM_MONITOR_COND); if (ovsdb_idl_check_server_db(idl)) { ovsdb_idl_send_db_change_aware(idl); } @@ -716,29 +734,48 @@ ovsdb_idl_process_response(struct ovsdb_idl *idl, struct jsonrpc_msg *msg) case IDL_S_DATA_SCHEMA_REQUESTED: json_destroy(idl->data.schema); idl->data.schema = json_clone(msg->result); - ovsdb_idl_send_monitor_request(idl, &idl->data, true); + ovsdb_idl_send_monitor_request(idl, &idl->data, + OVSDB_IDL_MM_MONITOR_COND); ovsdb_idl_transition(idl, IDL_S_DATA_MONITOR_COND_REQUESTED); break; + case IDL_S_DATA_MONITOR_COND_SINCE_REQUESTED: + if (!ok) { + /* "monitor_cond_since" not supported. Try "monitor_cond". */ + ovsdb_idl_send_monitor_request(idl, &idl->data, + OVSDB_IDL_MM_MONITOR_COND); + ovsdb_idl_transition(idl, IDL_S_DATA_MONITOR_COND_REQUESTED); + } else { + idl->data.monitoring = OVSDB_IDL_MONITORING_COND_SINCE; + ovsdb_idl_transition(idl, IDL_S_MONITORING); + ovsdb_idl_db_parse_monitor_reply(&idl->data, msg->result, + OVSDB_IDL_MM_MONITOR_COND_SINCE); + } + break; + case IDL_S_DATA_MONITOR_COND_REQUESTED: if (!ok) { /* "monitor_cond" not supported. Try "monitor". */ - ovsdb_idl_send_monitor_request(idl, &idl->data, false); + ovsdb_idl_send_monitor_request(idl, &idl->data, + OVSDB_IDL_MM_MONITOR); ovsdb_idl_transition(idl, IDL_S_DATA_MONITOR_REQUESTED); } else { idl->data.monitoring = OVSDB_IDL_MONITORING_COND; ovsdb_idl_transition(idl, IDL_S_MONITORING); - ovsdb_idl_db_parse_monitor_reply(&idl->data, msg->result, true); + ovsdb_idl_db_parse_monitor_reply(&idl->data, msg->result, + OVSDB_IDL_MM_MONITOR_COND); } break; case IDL_S_DATA_MONITOR_REQUESTED: idl->data.monitoring = OVSDB_IDL_MONITORING; ovsdb_idl_transition(idl, IDL_S_MONITORING); - ovsdb_idl_db_parse_monitor_reply(&idl->data, msg->result, false); + ovsdb_idl_db_parse_monitor_reply(&idl->data, msg->result, + OVSDB_IDL_MM_MONITOR); idl->data.change_seqno++; ovsdb_idl_clear(idl); - ovsdb_idl_db_parse_update(&idl->data, msg->result, false); + ovsdb_idl_db_parse_update(&idl->data, msg->result, + OVSDB_IDL_MM_MONITOR); break; case IDL_S_MONITORING: @@ -1564,7 +1601,7 @@ ovsdb_idl_send_cond_change(struct ovsdb_idl *idl) * conditional monitoring update request that we have not heard * from the server yet. Don't generate another request in this case. */ if (!jsonrpc_session_is_connected(idl->session) - || idl->data.monitoring != OVSDB_IDL_MONITORING_COND + || idl->data.monitoring == OVSDB_IDL_MONITORING || idl->request_id) { return; } @@ -1860,8 +1897,9 @@ ovsdb_idl_check_server_db(struct ovsdb_idl *idl) if (idl->state == IDL_S_SERVER_MONITOR_COND_REQUESTED) { json_destroy(idl->data.schema); idl->data.schema = json_from_string(database->schema); - ovsdb_idl_send_monitor_request(idl, &idl->data, true); - ovsdb_idl_transition(idl, IDL_S_DATA_MONITOR_COND_REQUESTED); + ovsdb_idl_send_monitor_request(idl, &idl->data, + OVSDB_IDL_MM_MONITOR_COND_SINCE); + ovsdb_idl_transition(idl, IDL_S_DATA_MONITOR_COND_SINCE_REQUESTED); } return true; } @@ -1951,7 +1989,7 @@ parse_schema(const struct json *schema_json) static void ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl, struct ovsdb_idl_db *db, - bool use_monitor_cond) + enum ovsdb_idl_monitor_method monitor_method) { struct shash *schema = parse_schema(db->schema); struct json *monitor_requests = json_object_create(); @@ -2003,7 +2041,9 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl, struct ovsdb_idl_db *db, json_object_put(monitor_request, "columns", columns); const struct ovsdb_idl_condition *cond = &table->condition; - if (use_monitor_cond && !ovsdb_idl_condition_is_true(cond)) { + if ((monitor_method == OVSDB_IDL_MM_MONITOR_COND || + monitor_method == OVSDB_IDL_MM_MONITOR_COND_SINCE) && + !ovsdb_idl_condition_is_true(cond)) { json_object_put(monitor_request, "where", ovsdb_idl_condition_to_json(cond)); table->cond_changed = false; @@ -2016,13 +2056,30 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl, struct ovsdb_idl_db *db, db->cond_changed = false; - ovsdb_idl_send_request( - idl, - jsonrpc_create_request( - use_monitor_cond ? "monitor_cond" : "monitor", - json_array_create_3(json_string_create(db->class_->database), - json_clone(db->monitor_id), monitor_requests), - NULL)); + struct json *params = json_array_create_3( + json_string_create(db->class_->database), + json_clone(db->monitor_id), + monitor_requests); + const char *method; + switch (monitor_method) { + case OVSDB_IDL_MM_MONITOR: + method = "monitor"; + break; + case OVSDB_IDL_MM_MONITOR_COND: + method = "monitor_cond"; + break; + case OVSDB_IDL_MM_MONITOR_COND_SINCE: + method = "monitor_cond_since"; + struct uuid last_id = UUID_ZERO; + struct json *json_last_id = json_string_create_nocopy( + xasprintf(UUID_FMT, UUID_ARGS(&last_id))); + json_array_add(params, json_last_id); + break; + default: + OVS_NOT_REACHED(); + } + + ovsdb_idl_send_request(idl, jsonrpc_create_request(method, params, NULL)); } static void @@ -2039,30 +2096,71 @@ log_parse_update_error(struct ovsdb_error *error) static void ovsdb_idl_db_parse_monitor_reply(struct ovsdb_idl_db *db, const struct json *result, - bool is_monitor_cond) + enum ovsdb_idl_monitor_method method) { db->change_seqno++; + const struct json *table_updates = result; + if (method == OVSDB_IDL_MM_MONITOR_COND_SINCE) { + if (result->type != JSON_ARRAY || result->array.n != 3) { + struct ovsdb_error *error = ovsdb_syntax_error(result, NULL, + "Response of monitor_cond_since must " + "be an array with 3 elements."); + log_parse_update_error(error); + return; + } + + bool found = json_boolean(result->array.elems[0]); + const char *last_id = json_string(result->array.elems[1]); + + table_updates = result->array.elems[2]; + + } ovsdb_idl_db_clear(db); - ovsdb_idl_db_parse_update(db, result, is_monitor_cond); + ovsdb_idl_db_parse_update(db, table_updates, method); } static bool ovsdb_idl_db_parse_update_rpc(struct ovsdb_idl_db *db, const struct jsonrpc_msg *msg) { - if (msg->type == JSONRPC_NOTIFY) { - bool is_update = !strcmp(msg->method, "update"); - bool is_update2 = !strcmp(msg->method, "update2"); - if ((is_update || is_update2) - && msg->params->type == JSON_ARRAY - && msg->params->array.n == 2 - && json_equal(msg->params->array.elems[0], db->monitor_id)) { - ovsdb_idl_db_parse_update(db, msg->params->array.elems[1], - is_update2); - return true; - } + if (msg->type != JSONRPC_NOTIFY) { + return false; } - return false; + + enum ovsdb_idl_monitor_method mm; + uint8_t n; + if (!strcmp(msg->method, "update")) { + mm = OVSDB_IDL_MM_MONITOR; + n = 2; + } else if (!strcmp(msg->method, "update2")) { + mm = OVSDB_IDL_MM_MONITOR_COND; + n = 2; + } else if (!strcmp(msg->method, "update3")) { + mm = OVSDB_IDL_MM_MONITOR_COND_SINCE; + n = 3; + } else { + return false; + } + + struct json *params = msg->params; + if (params->type != JSON_ARRAY || params->array.n != n) { + struct ovsdb_error *error = ovsdb_syntax_error(params, NULL, + "%s must be an array with %u elements.", + msg->method, n); + log_parse_update_error(error); + return false; + } + + if (!json_equal(params->array.elems[0], db->monitor_id)) { + return false; + } + + struct json *table_updates = params->array.elems[1]; + if (!strcmp(msg->method, "update3")) { + table_updates = params->array.elems[2]; + } + ovsdb_idl_db_parse_update(db, table_updates, mm); + return true; } static bool @@ -2103,10 +2201,21 @@ ovsdb_idl_handle_monitor_canceled(struct ovsdb_idl *idl, static struct ovsdb_error * ovsdb_idl_db_parse_update__(struct ovsdb_idl_db *db, const struct json *table_updates, - bool is_monitor_cond) + enum ovsdb_idl_monitor_method method) { const struct shash_node *tables_node; - const char *version_suffix = is_monitor_cond ? "2" : ""; + const char *version_suffix; + switch (method) { + case OVSDB_IDL_MM_MONITOR: + version_suffix = ""; + break; + case OVSDB_IDL_MM_MONITOR_COND: + case OVSDB_IDL_MM_MONITOR_COND_SINCE: + version_suffix = "2"; + break; + default: + OVS_NOT_REACHED(); + } if (table_updates->type != JSON_OBJECT) { return ovsdb_syntax_error(table_updates, NULL, @@ -2155,7 +2264,8 @@ ovsdb_idl_db_parse_update__(struct ovsdb_idl_db *db, version_suffix, table_node->name); } - if (is_monitor_cond) { + if (method == OVSDB_IDL_MM_MONITOR_COND || + method == OVSDB_IDL_MM_MONITOR_COND_SINCE) { const char *ops[] = {"modify", "insert", "delete", "initial"}; const char *operation; const struct json *row; @@ -2216,10 +2326,10 @@ ovsdb_idl_db_parse_update__(struct ovsdb_idl_db *db, static void ovsdb_idl_db_parse_update(struct ovsdb_idl_db *db, const struct json *table_updates, - bool is_monitor_cond) + enum ovsdb_idl_monitor_method method) { struct ovsdb_error *error = ovsdb_idl_db_parse_update__(db, table_updates, - is_monitor_cond); + method); if (error) { log_parse_update_error(error); } From patchwork Tue Jan 29 20:01:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Han Zhou X-Patchwork-Id: 1032993 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="BH3jXOfC"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43pyN42yhNz9sBQ for ; Wed, 30 Jan 2019 07:12:36 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9D30E327D; Tue, 29 Jan 2019 20:09:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 6682F2E4E for ; Tue, 29 Jan 2019 20:01:58 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 5E24A85C for ; Tue, 29 Jan 2019 20:01:57 +0000 (UTC) Received: by mail-pf1-f195.google.com with SMTP id z9so10179098pfi.2 for ; Tue, 29 Jan 2019 12:01:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kBBG8mydFaETrW9erofiKy0Glcn/4FOfJZ9y3PWaHu0=; b=BH3jXOfCHXUZ0aD5Zjk9C2LZlWZma2XMLcQWuH8tK1A29xMx876y6VkCghICG4Cl/6 coaR1hWtB2FQjC8IbLPtzDu1svNuQ1gRi2g3KB4WyYymbQ50VXSWej4PNh6YHNKFaj2o 2/ZueXa/iFGsLZivDCATzvhm7uBM8AJ0YQv0mhFhdcpulLNKtCjvg2WfmrcjeHp/DqP5 cnaHOtAKfSsrs4nfOLff48C8uCs/ARznJvqHEFJMWFObpky2o0H6bLX4ahlafKNZ7dpc GSsmTan04WOu5tBKdF/rfl+zkSe9E7o2LO4rclqd0eSy/sqAo5muszsqfrUv2KA/Yzqp usVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kBBG8mydFaETrW9erofiKy0Glcn/4FOfJZ9y3PWaHu0=; b=OHCxcOLjDJ9bKvE/UjpmtUK27d4BkaYXhS3eOR/Ft9o00qehJ25j5eqSpIURPQVe0H NDQV/EVR75FV1iqygjxF/QStESXb4b00SiX/o4m/DKBZabD0Wy+XpAShhqjjetFIoPer wPQT8RZaUbgf/yfv7IV6b4K4UPQt40NAM1otwGwKqpMglFIGa+eE6G310+KP0H8kW1ME Yzyh4HRZwpPbjKjPKruGwm8sUVaQKqt+ehY8z3XFgO4bCjvjqxOTENsNfS48pnyS0aQw xAaSqGva1KRgcr24eRgIeyhmjQYJjxbFFzYNVeiSxqGidWJYkoyptXR5xAbXLlpgtB1Y DfFA== X-Gm-Message-State: AJcUukeI5BAsvN+loQIygsn1ll9KZTnLJE9bh0lumfIETscvYMWDXasY O5vpa6tTNv/MMQjRbe55XlH25QsW X-Google-Smtp-Source: ALg8bN5lbgU9yYXgZ1yTGvSo5+KX+w0B3O2TQtsiMWuWpreiWFMBED9atI7PCH/tXFk2/Elid0Wdzg== X-Received: by 2002:a63:ff16:: with SMTP id k22mr25145062pgi.244.1548792116745; Tue, 29 Jan 2019 12:01:56 -0800 (PST) Received: from localhost.localdomain.localdomain ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id c23sm43097565pfi.83.2019.01.29.12.01.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Jan 2019 12:01:56 -0800 (PST) From: Han Zhou X-Google-Original-From: Han Zhou To: dev@openvswitch.org Date: Tue, 29 Jan 2019 12:01:49 -0800 Message-Id: <1548792109-111156-8-git-send-email-hzhou8@ebay.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> References: <1548792109-111156-1-git-send-email-hzhou8@ebay.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC v2 7/7] ovsdb-idl.c: Fast resync from server when connection reset. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Han Zhou Use monitor_cond_since to request changes after last version of local data when connection to server is reset, without clearing the local data. It falls back to clearing and repopulate all the data when the requested id cannot be fulfilled by the server. Signed-off-by: Han Zhou --- lib/ovsdb-idl.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 7ef4ed0..8cfb201 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -216,6 +216,9 @@ struct ovsdb_idl_db { bool has_lock; /* Has db server told us we have the lock? */ bool is_lock_contended; /* Has db server told us we can't get lock? */ struct json *lock_request_id; /* JSON-RPC ID of in-flight lock request. */ + + /* Last db txn id, used for fast resync through monitor_cond_since */ + struct uuid last_id; }; static void ovsdb_idl_db_track_clear(struct ovsdb_idl_db *); @@ -2070,9 +2073,8 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl, struct ovsdb_idl_db *db, break; case OVSDB_IDL_MM_MONITOR_COND_SINCE: method = "monitor_cond_since"; - struct uuid last_id = UUID_ZERO; struct json *json_last_id = json_string_create_nocopy( - xasprintf(UUID_FMT, UUID_ARGS(&last_id))); + xasprintf(UUID_FMT, UUID_ARGS(&db->last_id))); json_array_add(params, json_last_id); break; default: @@ -2100,6 +2102,7 @@ ovsdb_idl_db_parse_monitor_reply(struct ovsdb_idl_db *db, { db->change_seqno++; const struct json *table_updates = result; + bool clear_db = true; if (method == OVSDB_IDL_MM_MONITOR_COND_SINCE) { if (result->type != JSON_ARRAY || result->array.n != 3) { struct ovsdb_error *error = ovsdb_syntax_error(result, NULL, @@ -2110,12 +2113,24 @@ ovsdb_idl_db_parse_monitor_reply(struct ovsdb_idl_db *db, } bool found = json_boolean(result->array.elems[0]); + if (found) { + clear_db = false; + } + const char *last_id = json_string(result->array.elems[1]); + if (!uuid_from_string(&db->last_id, last_id)) { + struct ovsdb_error *error = ovsdb_syntax_error(result, NULL, + "Last-id %s is not in UUID format.", + last_id); + log_parse_update_error(error); + return; + } table_updates = result->array.elems[2]; - } - ovsdb_idl_db_clear(db); + if (clear_db) { + ovsdb_idl_db_clear(db); + } ovsdb_idl_db_parse_update(db, table_updates, method); } @@ -2158,6 +2173,14 @@ ovsdb_idl_db_parse_update_rpc(struct ovsdb_idl_db *db, struct json *table_updates = params->array.elems[1]; if (!strcmp(msg->method, "update3")) { table_updates = params->array.elems[2]; + const char *last_id = json_string(params->array.elems[1]); + if (!uuid_from_string(&db->last_id, last_id)) { + struct ovsdb_error *error = ovsdb_syntax_error(params, NULL, + "Last-id %s is not in UUID format.", + last_id); + log_parse_update_error(error); + return false; + } } ovsdb_idl_db_parse_update(db, table_updates, mm); return true;