Sometimes internal errors are generated based on an originating error. In
these cases we were just throwing this information away. This commit adds
this information to the internal error report so that the error will be
easier to track down.
I haven't actually seen a situation like this come up.
---
lib/ovsdb-error.c | 13 +++++++++++--
lib/ovsdb-error.h | 12 ++++++++----
ovsdb/transaction.c | 8 +++-----
3 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/lib/ovsdb-error.c b/lib/ovsdb-error.c
index d6b4576..4a60d4f 100644
--- a/lib/ovsdb-error.c
+++ b/lib/ovsdb-error.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -115,7 +115,8 @@ ovsdb_wrap_error(struct ovsdb_error *error, const char
*details, ...)
}
struct ovsdb_error *
-ovsdb_internal_error(const char *file, int line, const char *details, ...)
+ovsdb_internal_error(struct ovsdb_error *inner_error,
+ const char *file, int line, const char *details, ...)
{
struct ds ds = DS_EMPTY_INITIALIZER;
struct backtrace backtrace;
@@ -144,6 +145,14 @@ ovsdb_internal_error(const char *file, int line, const
char *details, ...)
ds_put_format(&ds, " (%s %s%s)", program_name, VERSION, BUILDNR);
+ if (inner_error) {
+ char *s = ovsdb_error_to_string(inner_error);
+ ds_put_format(&ds, " (generated from: %s)", s);
+ free(s);
+
+ ovsdb_error_destroy(inner_error);
+ }
+
error = ovsdb_error("internal error", "%s", ds_cstr(&ds));
ds_destroy(&ds);
diff --git a/lib/ovsdb-error.h b/lib/ovsdb-error.h
index 2bff3ae..f4a5a69 100644
--- a/lib/ovsdb-error.h
+++ b/lib/ovsdb-error.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,11 +35,15 @@ struct ovsdb_error *ovsdb_wrap_error(struct ovsdb_error
*error,
const char *details, ...)
PRINTF_FORMAT(2, 3);
-struct ovsdb_error *ovsdb_internal_error(const char *file, int line,
+struct ovsdb_error *ovsdb_internal_error(struct ovsdb_error *error,
+ const char *file, int line,
const char *details, ...)
- PRINTF_FORMAT(3, 4)
+ PRINTF_FORMAT(4, 5)
WARN_UNUSED_RESULT;
-#define OVSDB_BUG(MSG) ovsdb_internal_error(__FILE__, __LINE__, "%s", MSG)
+#define OVSDB_BUG(MSG) \
+ ovsdb_internal_error(NULL, __FILE__, __LINE__, "%s", MSG)
+#define OVSDB_WRAP_BUG(MSG, ERROR) \
+ ovsdb_internal_error(ERROR, __FILE__, __LINE__, "%s", MSG)
void ovsdb_error_destroy(struct ovsdb_error *);
struct ovsdb_error *ovsdb_error_clone(const struct ovsdb_error *)
diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c
index b26705a..b7c57e5 100644
--- a/ovsdb/transaction.c
+++ b/ovsdb/transaction.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -218,8 +218,7 @@ update_row_ref_count(struct ovsdb_txn *txn, struct
ovsdb_txn_row *r)
if (r->old) {
error = ovsdb_txn_adjust_row_refs(txn, r->old, column, -1);
if (error) {
- ovsdb_error_destroy(error);
- return OVSDB_BUG("error decreasing refcount");
+ return OVSDB_WRAP_BUG("error decreasing refcount", error);
}
}
if (r->new) {
@@ -476,8 +475,7 @@ ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable)
* was really a no-op. */
error = for_each_txn_row(txn, determine_changes);
if (error) {
- ovsdb_error_destroy(error);
- return OVSDB_BUG("can't happen");
+ return OVSDB_WRAP_BUG("can't happen", error);
}
if (list_is_empty(&txn->txn_tables)) {
ovsdb_txn_abort(txn);
--
1.7.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev_openvswitch.org