summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHan Zhou <hzhou8@ebay.com>2019-05-17 12:56:33 -0700
committerBen Pfaff <blp@ovn.org>2019-05-24 11:37:29 -0700
commit72aeb243a52a08e3888ef445083668a3305caa27 (patch)
tree305b9d6b3fd623fd2516868fb74a2f9a8c6040b1 /lib
parentc4af630718309f253ce7c809d85965bc8d00cb1d (diff)
downloadopenvswitch-72aeb243a52a08e3888ef445083668a3305caa27.tar.gz
ovsdb-idl: Tracking - preserve data for deleted rows.
OVSDB IDL can track changes, but for deleted rows, the data is destroyed and only uuid is tracked. In some cases we need to check the data of the deleted rows. This patch preserves data for deleted rows until track clear is called. Signed-off-by: Han Zhou <hzhou8@ebay.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/ovsdb-idl-provider.h2
-rw-r--r--lib/ovsdb-idl.c36
2 files changed, 31 insertions, 7 deletions
diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h
index 2eee4fd01..30d1d08eb 100644
--- a/lib/ovsdb-idl-provider.h
+++ b/lib/ovsdb-idl-provider.h
@@ -73,6 +73,7 @@ struct ovsdb_idl_row {
struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */
struct ovsdb_idl_table *table; /* Containing table. */
struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */
+ bool parsed; /* Whether the row is parsed. */
/* Transactional data. */
struct ovsdb_datum *new_datum; /* Modified data (null to delete row). */
@@ -88,6 +89,7 @@ struct ovsdb_idl_row {
unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX];
struct ovs_list track_node; /* Rows modified/added/deleted by IDL */
unsigned long int *updated; /* Bitmap of columns updated by IDL */
+ struct ovsdb_datum *tracked_old_datum; /* Old deleted data. */
};
struct ovsdb_idl_column {
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index 370781b45..d27e205d2 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -1828,7 +1828,16 @@ ovsdb_idl_db_track_clear(struct ovsdb_idl_db *db)
}
ovs_list_remove(&row->track_node);
ovs_list_init(&row->track_node);
- if (ovsdb_idl_row_is_orphan(row)) {
+ if (ovsdb_idl_row_is_orphan(row) && row->tracked_old_datum) {
+ ovsdb_idl_row_unparse(row);
+ const struct ovsdb_idl_table_class *class =
+ row->table->class_;
+ for (size_t c = 0; c < class->n_columns; c++) {
+ ovsdb_datum_destroy(&row->tracked_old_datum[c],
+ &class->columns[c].type);
+ }
+ free(row->tracked_old_datum);
+ row->tracked_old_datum = NULL;
free(row);
}
}
@@ -2665,10 +2674,14 @@ ovsdb_idl_row_parse(struct ovsdb_idl_row *row)
const struct ovsdb_idl_table_class *class = row->table->class_;
size_t i;
+ if (row->parsed) {
+ ovsdb_idl_row_unparse(row);
+ }
for (i = 0; i < class->n_columns; i++) {
const struct ovsdb_idl_column *c = &class->columns[i];
(c->parse)(row, &row->old_datum[i]);
}
+ row->parsed = true;
}
static void
@@ -2677,10 +2690,14 @@ ovsdb_idl_row_unparse(struct ovsdb_idl_row *row)
const struct ovsdb_idl_table_class *class = row->table->class_;
size_t i;
+ if (!row->parsed) {
+ return;
+ }
for (i = 0; i < class->n_columns; i++) {
const struct ovsdb_idl_column *c = &class->columns[i];
(c->unparse)(row);
}
+ row->parsed = false;
}
/* The OVSDB-IDL Compound Indexes feature allows for the creation of custom
@@ -3008,13 +3025,18 @@ ovsdb_idl_row_clear_old(struct ovsdb_idl_row *row)
{
ovs_assert(row->old_datum == row->new_datum);
if (!ovsdb_idl_row_is_orphan(row)) {
- const struct ovsdb_idl_table_class *class = row->table->class_;
- size_t i;
+ if (ovsdb_idl_track_is_set(row->table)) {
+ row->tracked_old_datum = row->old_datum;
+ } else {
+ const struct ovsdb_idl_table_class *class = row->table->class_;
+ size_t i;
- for (i = 0; i < class->n_columns; i++) {
- ovsdb_datum_destroy(&row->old_datum[i], &class->columns[i].type);
+ for (i = 0; i < class->n_columns; i++) {
+ ovsdb_datum_destroy(&row->old_datum[i],
+ &class->columns[i].type);
+ }
+ free(row->old_datum);
}
- free(row->old_datum);
row->old_datum = row->new_datum = NULL;
}
}
@@ -3187,6 +3209,7 @@ ovsdb_idl_row_destroy_postprocess(struct ovsdb_idl_db *db)
LIST_FOR_EACH_SAFE(row, next, track_node, &table->track_list) {
if (!ovsdb_idl_track_is_set(row->table)) {
ovs_list_remove(&row->track_node);
+ ovsdb_idl_row_unparse(row);
free(row);
}
}
@@ -3217,7 +3240,6 @@ static void
ovsdb_idl_delete_row(struct ovsdb_idl_row *row)
{
ovsdb_idl_remove_from_indexes(row);
- ovsdb_idl_row_unparse(row);
ovsdb_idl_row_clear_arcs(row, true);
ovsdb_idl_row_clear_old(row);
if (ovs_list_is_empty(&row->dst_arcs)) {