From patchwork Wed Apr 19 19:06:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Richardson X-Patchwork-Id: 752426 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3w7WjY4Cgyz9s7B for ; Thu, 20 Apr 2017 05:08:01 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 19DFABF2; Wed, 19 Apr 2017 19:06:56 +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 25787B6B for ; Wed, 19 Apr 2017 19:06:55 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id CFB7E8D for ; Wed, 19 Apr 2017 19:06:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 461BC7E9FB; Wed, 19 Apr 2017 19:06:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 461BC7E9FB Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=lrichard@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 461BC7E9FB Received: from thinkcentre.localdomain.com (ovpn-120-23.rdu2.redhat.com [10.10.120.23]) by smtp.corp.redhat.com (Postfix) with ESMTP id BB35E7F8ED; Wed, 19 Apr 2017 19:06:52 +0000 (UTC) From: Lance Richardson To: dev@openvswitch.org, blp@ovn.org, russell@ovn.org, mickeys.dev@gmail.com Date: Wed, 19 Apr 2017 15:06:51 -0400 Message-Id: <20170419190651.4190-1-lrichard@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 19 Apr 2017 19:06:53 +0000 (UTC) X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD 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 v3 2/6] ovsdb: refactor utility functions into separate file 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 Move local db access functions to a new file and make give them global scope so they can be included in the ovsdb library and used by other ovsdb library functions. Signed-off-by: Lance Richardson --- v2: - Renamed functions in ovsdb-util.c to have "ovsdb_util_" prefix. - Included in ovsdb-util.c. v3: No changes. ovsdb/automake.mk | 4 +- ovsdb/ovsdb-server.c | 187 +++--------------------------------------------- ovsdb/ovsdb-util.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++ ovsdb/ovsdb-util.h | 48 +++++++++++++ 4 files changed, 258 insertions(+), 177 deletions(-) create mode 100644 ovsdb/ovsdb-util.c create mode 100644 ovsdb/ovsdb-util.h diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk index 33d04f8..c218bf5 100644 --- a/ovsdb/automake.mk +++ b/ovsdb/automake.mk @@ -35,7 +35,9 @@ ovsdb_libovsdb_la_SOURCES = \ ovsdb/trigger.c \ ovsdb/trigger.h \ ovsdb/transaction.c \ - ovsdb/transaction.h + ovsdb/transaction.h \ + ovsdb/ovsdb-util.c \ + ovsdb/ovsdb-util.h ovsdb_libovsdb_la_CFLAGS = $(AM_CFLAGS) ovsdb_libovsdb_la_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 8e3bdaf..50c3555 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -56,6 +56,7 @@ #include "util.h" #include "unixctl.h" #include "perf-counter.h" +#include "ovsdb-util.h" #include "openvswitch/vlog.h" VLOG_DEFINE_THIS_MODULE(ovsdb_server); @@ -673,174 +674,6 @@ add_remote(struct shash *remotes, const char *target) return options; } -static struct ovsdb_datum * -get_datum(struct ovsdb_row *row, const char *column_name, - const enum ovsdb_atomic_type key_type, - const enum ovsdb_atomic_type value_type, - const size_t n_max) -{ - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - const struct ovsdb_table_schema *schema = row->table->schema; - const struct ovsdb_column *column; - - column = ovsdb_table_schema_get_column(schema, column_name); - if (!column) { - VLOG_DBG_RL(&rl, "Table `%s' has no `%s' column", - schema->name, column_name); - return NULL; - } - - if (column->type.key.type != key_type - || column->type.value.type != value_type - || column->type.n_max != n_max) { - if (!VLOG_DROP_DBG(&rl)) { - char *type_name = ovsdb_type_to_english(&column->type); - VLOG_DBG("Table `%s' column `%s' has type %s, not expected " - "key type %s, value type %s, max elements %"PRIuSIZE".", - schema->name, column_name, type_name, - ovsdb_atomic_type_to_string(key_type), - ovsdb_atomic_type_to_string(value_type), - n_max); - free(type_name); - } - return NULL; - } - - return &row->fields[column->index]; -} - -/* Read string-string key-values from a map. Returns the value associated with - * 'key', if found, or NULL */ -static const char * -read_map_string_column(const struct ovsdb_row *row, const char *column_name, - const char *key) -{ - const struct ovsdb_datum *datum; - union ovsdb_atom *atom_key = NULL, *atom_value = NULL; - size_t i; - - datum = get_datum(CONST_CAST(struct ovsdb_row *, row), column_name, - OVSDB_TYPE_STRING, OVSDB_TYPE_STRING, UINT_MAX); - - if (!datum) { - return NULL; - } - - for (i = 0; i < datum->n; i++) { - atom_key = &datum->keys[i]; - if (!strcmp(atom_key->string, key)){ - atom_value = &datum->values[i]; - break; - } - } - - return atom_value ? atom_value->string : NULL; -} - -static const union ovsdb_atom * -read_column(const struct ovsdb_row *row, const char *column_name, - enum ovsdb_atomic_type type) -{ - const struct ovsdb_datum *datum; - - datum = get_datum(CONST_CAST(struct ovsdb_row *, row), column_name, type, - OVSDB_TYPE_VOID, 1); - return datum && datum->n ? datum->keys : NULL; -} - -static bool -read_integer_column(const struct ovsdb_row *row, const char *column_name, - long long int *integerp) -{ - const union ovsdb_atom *atom; - - atom = read_column(row, column_name, OVSDB_TYPE_INTEGER); - *integerp = atom ? atom->integer : 0; - return atom != NULL; -} - -static bool -read_string_column(const struct ovsdb_row *row, const char *column_name, - const char **stringp) -{ - const union ovsdb_atom *atom; - - atom = read_column(row, column_name, OVSDB_TYPE_STRING); - *stringp = atom ? atom->string : NULL; - return atom != NULL; -} - -static bool -read_bool_column(const struct ovsdb_row *row, const char *column_name, - bool *boolp) -{ - const union ovsdb_atom *atom; - - atom = read_column(row, column_name, OVSDB_TYPE_BOOLEAN); - *boolp = atom ? atom->boolean : false; - return atom != NULL; -} - -static void -write_bool_column(struct ovsdb_row *row, const char *column_name, bool value) -{ - const struct ovsdb_column *column; - struct ovsdb_datum *datum; - - column = ovsdb_table_schema_get_column(row->table->schema, column_name); - datum = get_datum(row, column_name, OVSDB_TYPE_BOOLEAN, - OVSDB_TYPE_VOID, 1); - if (!datum) { - return; - } - - if (datum->n != 1) { - ovsdb_datum_destroy(datum, &column->type); - - datum->n = 1; - datum->keys = xmalloc(sizeof *datum->keys); - datum->values = NULL; - } - - datum->keys[0].boolean = value; -} - -static void -write_string_string_column(struct ovsdb_row *row, const char *column_name, - char **keys, char **values, size_t n) -{ - const struct ovsdb_column *column; - struct ovsdb_datum *datum; - size_t i; - - column = ovsdb_table_schema_get_column(row->table->schema, column_name); - datum = get_datum(row, column_name, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING, - UINT_MAX); - if (!datum) { - for (i = 0; i < n; i++) { - free(keys[i]); - free(values[i]); - } - return; - } - - /* Free existing data. */ - ovsdb_datum_destroy(datum, &column->type); - - /* Allocate space for new values. */ - datum->n = n; - datum->keys = xmalloc(n * sizeof *datum->keys); - datum->values = xmalloc(n * sizeof *datum->values); - - for (i = 0; i < n; ++i) { - datum->keys[i].string = keys[i]; - datum->values[i].string = values[i]; - } - - /* Sort and check constraints. */ - ovsdb_datum_sort_assert(datum, column->type.key.type); -} - /* Adds a remote and options to 'remotes', based on the Manager table row in * 'row'. */ static void @@ -852,25 +685,27 @@ add_manager_options(struct shash *remotes, const struct ovsdb_row *row) bool read_only; const char *target, *dscp_string; - if (!read_string_column(row, "target", &target) || !target) { + if (!ovsdb_util_read_string_column(row, "target", &target) || !target) { VLOG_INFO_RL(&rl, "Table `%s' has missing or invalid `target' column", row->table->schema->name); return; } options = add_remote(remotes, target); - if (read_integer_column(row, "max_backoff", &max_backoff)) { + if (ovsdb_util_read_integer_column(row, "max_backoff", &max_backoff)) { options->max_backoff = max_backoff; } - if (read_integer_column(row, "inactivity_probe", &probe_interval)) { + if (ovsdb_util_read_integer_column(row, "inactivity_probe", + &probe_interval)) { options->probe_interval = probe_interval; } - if (read_bool_column(row, "read_only", &read_only)) { + if (ovsdb_util_read_bool_column(row, "read_only", &read_only)) { options->read_only = read_only; } options->dscp = DSCP_DEFAULT; - dscp_string = read_map_string_column(row, "other_config", "dscp"); + dscp_string = ovsdb_util_read_map_string_column(row, "other_config", + "dscp"); if (dscp_string) { int dscp = atoi(dscp_string); if (dscp >= 0 && dscp <= 63) { @@ -939,7 +774,7 @@ update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn, size_t n = 0; /* Get the "target" (protocol/host/port) spec. */ - if (!read_string_column(row, "target", &target)) { + if (!ovsdb_util_read_string_column(row, "target", &target)) { /* Bad remote spec or incorrect schema. */ return; } @@ -947,7 +782,7 @@ update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn, ovsdb_jsonrpc_server_get_remote_status(jsonrpc, target, &status); /* Update status information columns. */ - write_bool_column(rw_row, "is_connected", status.is_connected); + ovsdb_util_write_bool_column(rw_row, "is_connected", status.is_connected); if (status.state) { keys[n] = xstrdup("state"); @@ -986,7 +821,7 @@ update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn, keys[n] = xstrdup("bound_port"); values[n++] = xasprintf("%"PRIu16, ntohs(status.bound_port)); } - write_string_string_column(rw_row, "status", keys, values, n); + ovsdb_util_write_string_string_column(rw_row, "status", keys, values, n); ovsdb_jsonrpc_server_free_remote_status(&status); } diff --git a/ovsdb/ovsdb-util.c b/ovsdb/ovsdb-util.c new file mode 100644 index 0000000..647f5df --- /dev/null +++ b/ovsdb/ovsdb-util.c @@ -0,0 +1,196 @@ +/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "row.h" +#include "sset.h" +#include "table.h" +#include "ovsdb-util.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(ovsdb_util); + +struct ovsdb_datum * +ovsdb_util_get_datum(struct ovsdb_row *row, const char *column_name, + const enum ovsdb_atomic_type key_type, + const enum ovsdb_atomic_type value_type, + const size_t n_max) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + const struct ovsdb_table_schema *schema = row->table->schema; + const struct ovsdb_column *column; + + column = ovsdb_table_schema_get_column(schema, column_name); + if (!column) { + VLOG_DBG_RL(&rl, "Table `%s' has no `%s' column", + schema->name, column_name); + return NULL; + } + + if (column->type.key.type != key_type + || column->type.value.type != value_type + || column->type.n_max != n_max) { + if (!VLOG_DROP_DBG(&rl)) { + char *type_name = ovsdb_type_to_english(&column->type); + VLOG_DBG("Table `%s' column `%s' has type %s, not expected " + "key type %s, value type %s, max elements %"PRIuSIZE".", + schema->name, column_name, type_name, + ovsdb_atomic_type_to_string(key_type), + ovsdb_atomic_type_to_string(value_type), + n_max); + free(type_name); + } + return NULL; + } + + return &row->fields[column->index]; +} + +/* Read string-string key-values from a map. Returns the value associated with + * 'key', if found, or NULL */ +const char * +ovsdb_util_read_map_string_column(const struct ovsdb_row *row, + const char *column_name, + const char *key) +{ + const struct ovsdb_datum *datum; + union ovsdb_atom *atom_key = NULL, *atom_value = NULL; + size_t i; + + datum = ovsdb_util_get_datum(CONST_CAST(struct ovsdb_row *, row), + column_name, OVSDB_TYPE_STRING, + OVSDB_TYPE_STRING, UINT_MAX); + + if (!datum) { + return NULL; + } + + for (i = 0; i < datum->n; i++) { + atom_key = &datum->keys[i]; + if (!strcmp(atom_key->string, key)) { + atom_value = &datum->values[i]; + break; + } + } + + return atom_value ? atom_value->string : NULL; +} + +const union ovsdb_atom * +ovsdb_util_read_column(const struct ovsdb_row *row, const char *column_name, + enum ovsdb_atomic_type type) +{ + const struct ovsdb_datum *datum; + + datum = ovsdb_util_get_datum(CONST_CAST(struct ovsdb_row *, row), + column_name, type, OVSDB_TYPE_VOID, 1); + return datum && datum->n ? datum->keys : NULL; +} + +bool +ovsdb_util_read_integer_column(const struct ovsdb_row *row, + const char *column_name, + long long int *integerp) +{ + const union ovsdb_atom *atom; + + atom = ovsdb_util_read_column(row, column_name, OVSDB_TYPE_INTEGER); + *integerp = atom ? atom->integer : 0; + return atom != NULL; +} + +bool +ovsdb_util_read_string_column(const struct ovsdb_row *row, + const char *column_name, const char **stringp) +{ + const union ovsdb_atom *atom; + + atom = ovsdb_util_read_column(row, column_name, OVSDB_TYPE_STRING); + *stringp = atom ? atom->string : NULL; + return atom != NULL; +} + +bool +ovsdb_util_read_bool_column(const struct ovsdb_row *row, + const char *column_name, bool *boolp) +{ + const union ovsdb_atom *atom; + + atom = ovsdb_util_read_column(row, column_name, OVSDB_TYPE_BOOLEAN); + *boolp = atom ? atom->boolean : false; + return atom != NULL; +} + +void +ovsdb_util_write_bool_column(struct ovsdb_row *row, const char *column_name, + bool value) +{ + const struct ovsdb_column *column; + struct ovsdb_datum *datum; + + column = ovsdb_table_schema_get_column(row->table->schema, column_name); + datum = ovsdb_util_get_datum(row, column_name, OVSDB_TYPE_BOOLEAN, + OVSDB_TYPE_VOID, 1); + if (!datum) { + return; + } + + if (datum->n != 1) { + ovsdb_datum_destroy(datum, &column->type); + + datum->n = 1; + datum->keys = xmalloc(sizeof *datum->keys); + datum->values = NULL; + } + + datum->keys[0].boolean = value; +} + +void +ovsdb_util_write_string_string_column(struct ovsdb_row *row, + const char *column_name, + char **keys, char **values, size_t n) +{ + const struct ovsdb_column *column; + struct ovsdb_datum *datum; + size_t i; + + column = ovsdb_table_schema_get_column(row->table->schema, column_name); + datum = ovsdb_util_get_datum(row, column_name, OVSDB_TYPE_STRING, + OVSDB_TYPE_STRING, UINT_MAX); + if (!datum) { + for (i = 0; i < n; i++) { + free(keys[i]); + free(values[i]); + } + return; + } + + /* Free existing data. */ + ovsdb_datum_destroy(datum, &column->type); + + /* Allocate space for new values. */ + datum->n = n; + datum->keys = xmalloc(n * sizeof *datum->keys); + datum->values = xmalloc(n * sizeof *datum->values); + + for (i = 0; i < n; ++i) { + datum->keys[i].string = keys[i]; + datum->values[i].string = values[i]; + } + + /* Sort and check constraints. */ + ovsdb_datum_sort_assert(datum, column->type.key.type); +} diff --git a/ovsdb/ovsdb-util.h b/ovsdb/ovsdb-util.h new file mode 100644 index 0000000..effbec8 --- /dev/null +++ b/ovsdb/ovsdb-util.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OVSDB_UTIL_H +#define OVSDB_UTIL_H 1 + +/* Database access utility functions. */ +struct ovsdb_datum *ovsdb_util_get_datum(struct ovsdb_row *row, + const char *column_name, + const enum ovsdb_atomic_type keytype, + const enum ovsdb_atomic_type valtype, + const size_t n_max); +const char *ovsdb_util_read_map_string_column(const struct ovsdb_row *row, + const char *column_name, + const char *key); +const union ovsdb_atom *ovsdb_util_read_column(const struct ovsdb_row *row, + const char *column_name, + enum ovsdb_atomic_type type); +bool ovsdb_util_read_integer_column(const struct ovsdb_row *row, + const char *column_name, + long long int *integerp); +bool ovsdb_util_read_string_column(const struct ovsdb_row *row, + const char *column_name, + const char **stringp); +void ovsdb_util_write_string_string_column(struct ovsdb_row *row, + const char *column_name, + char **keys, char **values, + size_t n); +bool ovsdb_util_read_bool_column(const struct ovsdb_row *row, + const char *column_name, + bool *boolp); +void ovsdb_util_write_bool_column(struct ovsdb_row *row, + const char *column_name, + bool value); + +#endif /* ovsdb/util.h */