From patchwork Fri Aug 23 00:53:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: aginwala aginwala X-Patchwork-Id: 1151901 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="SVjGAH0K"; 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 46F2vM18Gfz9sND for ; Fri, 23 Aug 2019 10:53:17 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id B78CB101D; Fri, 23 Aug 2019 00:53:14 +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 F356E101B for ; Fri, 23 Aug 2019 00:53:13 +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 723E07FB for ; Fri, 23 Aug 2019 00:53:13 +0000 (UTC) Received: by mail-pf1-f195.google.com with SMTP id i30so5162062pfk.9 for ; Thu, 22 Aug 2019 17:53:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=cDnUDdRwVsaP/xonWbt9Kmni0DEYyiaZgFSG+15r0t0=; b=SVjGAH0KZFzpRYlirFm8rPOcxWYqvb10A7PzQXYBnjj2mEUXub/EUGHvE0uOFcd+oV waHEs1/mPKpyRWg/lm9ubkA66TpztUwhEfFHIThrh6sPXvy034JO6igjxdar2dwtMKbh yLOGMpVX3ZuSMgQoz/qtVnwQuyRW24R7IUq1CLqJvQ8C980IDezITonrLwVkHiwq1nEp ilylhdg3+pzOnxItJVCQyS5zqZXCHeSMDWTTOdTyoV9tOITOBx5GhRrYAzoqCz0FKQtH 96DGB0B/z9rgbu7q0B7B1BABLhq7a/2MOgVLx7c6ipvkZB1i+ulpBa2bcGfd9SipdSZH mjNA== 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:mime-version :content-transfer-encoding; bh=cDnUDdRwVsaP/xonWbt9Kmni0DEYyiaZgFSG+15r0t0=; b=XJLBFgJ1nf4w/YmvOzN+pjNxbutCwyDG3rpsxriQDKmuNTSTZqqaphNW3HeihDYKRN VmmMPkTCHxv2XBxUYUbkVdcCYKWno8zpOptZWSiY+UD5pF1vSCKX9UvlMx6llghjBT0w oLJqvRXgf3d99zjEXJLIMvzdcjWago3E2XlNuck9AZTlzd4qVv3qdY65zO0kph8Dwwbe oDdOw7/fJQkIulCNELx1zEi2ZU9GNt9iGS2RfyfSwJTEeAUhYS5cDc+OCrv9ax8LL56Q DnkUr5HyufmDT3vjfbYChFcoTiaML28N84iTilBaZaGPk/4MrF9MlTUVyg2gk3wn0JmY oi+w== X-Gm-Message-State: APjAAAU5e4PfTB/J1c4VG7TU6KyBa58AfIU1oskdv76/UpRlI2Vw+wJ0 ggnMgroJo7zbhjwLg/N+w3oT0RGe X-Google-Smtp-Source: APXvYqwv3GzI+3R0KDXhF2I2l58JiHr2iXymGE4ZkfP4p5fTTFK/5dW8r6SsDUDf9F6KzLT8kDIqYQ== X-Received: by 2002:a63:3046:: with SMTP id w67mr1657440pgw.37.1566521592754; Thu, 22 Aug 2019 17:53:12 -0700 (PDT) Received: from LM-SJC-11015761.corp.ebay.com ([216.113.160.77]) by smtp.gmail.com with ESMTPSA id v21sm582145pfe.131.2019.08.22.17.53.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 22 Aug 2019 17:53:12 -0700 (PDT) From: amginwal@gmail.com To: dev@openvswitch.org Date: Thu, 22 Aug 2019 17:53:10 -0700 Message-Id: <20190823005310.99329-1-amginwal@gmail.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) MIME-Version: 1.0 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 Cc: Aliasgar Ginwala Subject: [ovs-dev] [PATCH v2] ovsdb-tool: Convert clustered db to standalone db. 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: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Aliasgar Ginwala Add support in ovsdb-tool for migrating clustered dbs to standalone dbs. E.g. usage to migrate nb/sb db to standalone db from raft: ovsdb-tool migrate-cluster-db ovnnb_db.db ovnnb_db_cluster.db Signed-off-by: Aliasgar Ginwala --- ovsdb/ovsdb-tool.c | 154 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c index 438f97590..4aa1d4b3f 100644 --- a/ovsdb/ovsdb-tool.c +++ b/ovsdb/ovsdb-tool.c @@ -173,6 +173,8 @@ usage(void) " compare-versions A OP B compare OVSDB schema version numbers\n" " query [DB] TRNS execute read-only transaction on DB\n" " transact [DB] TRNS execute read/write transaction on DB\n" + " migrate-cluster-db [DB [DB]] Migrate clustered DB to\n" + "standalone DB\n " " [-m]... show-log [DB] print DB's log entries\n" "The default DB is %s.\n" "The default SCHEMA is %s.\n", @@ -206,7 +208,7 @@ default_schema(void) } return schema; } - + static struct json * parse_json(const char *s) { @@ -244,7 +246,7 @@ read_standalone_schema(const char *filename) ovsdb_storage_close(storage); return schema; } - + static void do_create(struct ovs_cmdl_context *ctx) { @@ -942,6 +944,94 @@ print_raft_record(const struct raft_record *r, } } +static struct ovsdb_log * +write_raft_header_to_file(const struct json *data, const char *db_file_name) +{ + if (!data) { + return NULL; + } + + if (json_array(data)->n != 2) { + printf(" ***invalid data***\n"); + return NULL; + } + + struct ovsdb_log *log; + struct json *schema_json = json_array(data)->elems[0]; + if (schema_json->type != JSON_NULL) { + struct ovsdb_schema *schema; + check_ovsdb_error(ovsdb_schema_from_json(schema_json, &schema)); + check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_MAGIC, + OVSDB_LOG_CREATE_EXCL, -1, &log)); + check_ovsdb_error(ovsdb_log_write_and_free(log, schema_json)); + check_ovsdb_error(ovsdb_log_commit_block(log)); + } + + struct json *data_json = json_array(data)->elems[1]; + if (!data_json || data_json->type != JSON_OBJECT) { + return NULL; + } + if (data_json->type != JSON_NULL) { + check_ovsdb_error(ovsdb_log_write_and_free(log, data_json)); + check_ovsdb_error(ovsdb_log_commit_block(log)); + } + return log; +} + +static struct ovsdb_log * +write_raft_header(const struct raft_header *h, const char *db_file_name) +{ + if (h->snap_index) { + return write_raft_header_to_file(h->snap.data, db_file_name); + } + return NULL; +} + +static void +write_raft_records_to_file(const struct json *data, struct ovsdb_log *log_data) +{ + if (json_array(data)->n != 2) { + printf(" ***invalid data***\n"); + return; + } + + struct json *data_json = json_array(data)->elems[1]; + if (data_json->type != JSON_NULL) { + check_ovsdb_error(ovsdb_log_write_and_free(log_data, data_json)); + check_ovsdb_error(ovsdb_log_commit_block(log_data)); + } +} + +static void +write_raft_records(const struct raft_record *r, struct ovsdb_log *log_data) +{ + switch (r->type) { + case RAFT_REC_ENTRY: + if (!r->entry.data) { + return; + } + write_raft_records_to_file(r->entry.data, log_data); + break; + + case RAFT_REC_TERM: + break; + + case RAFT_REC_VOTE: + break; + + case RAFT_REC_NOTE: + break; + + case RAFT_REC_COMMIT_INDEX: + break; + + case RAFT_REC_LEADER: + break; + default: + OVS_NOT_REACHED(); + } +} + static void do_show_log_cluster(struct ovsdb_log *log) { @@ -1511,6 +1601,65 @@ do_compare_versions(struct ovs_cmdl_context *ctx) exit(result ? 0 : 2); } +static void +do_migrate_cluster(struct ovsdb_log *log, const char *db_file_name) +{ + struct ovsdb_log *log_data = NULL; + for (unsigned int i = 0; ; i++) { + struct json *json; + check_ovsdb_error(ovsdb_log_read(log, &json)); + if (!json) { + break; + } + + printf("record %u:\n", i); + struct ovsdb_error *error; + if (i == 0) { + struct raft_header h; + error = raft_header_from_json(&h, json); + if (!error) { + log_data = write_raft_header(&h, db_file_name); + raft_header_uninit(&h); + if (!log_data) { + return; + } + } + } else { + struct raft_record r; + error = raft_record_from_json(&r, json); + if (!error) { + write_raft_records(&r, log_data); + raft_record_uninit(&r); + } + } + if (error) { + char *s = ovsdb_error_to_string_free(error); + puts(s); + free(s); + } + + putchar('\n'); + } + ovsdb_log_close(log_data); +} + +static void +do_migrate(struct ovs_cmdl_context *ctx) +{ + const char *db_file_name = ctx->argv[1]; + const char *cluster_db_file_name = ctx->argv[2]; + struct ovsdb_log *log; + + check_ovsdb_error(ovsdb_log_open(cluster_db_file_name, + OVSDB_MAGIC"|"RAFT_MAGIC, + OVSDB_LOG_READ_ONLY, -1, &log)); + if (!strcmp(ovsdb_log_get_magic(log), OVSDB_MAGIC)) { + printf("Data base is not clustered db."); + } else { + do_migrate_cluster(log, db_file_name); + } + ovsdb_log_close(log); +} static void do_help(struct ovs_cmdl_context *ctx OVS_UNUSED) @@ -1550,6 +1699,7 @@ static const struct ovs_cmdl_command all_commands[] = { { "compare-versions", "a op b", 3, 3, do_compare_versions, OVS_RO }, { "help", NULL, 0, INT_MAX, do_help, OVS_RO }, { "list-commands", NULL, 0, INT_MAX, do_list_commands, OVS_RO }, + { "migrate-cluster-db", "[db [clusterdb]]", 0, 2, do_migrate, OVS_RW }, { NULL, NULL, 0, 0, NULL, OVS_RO }, };