X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fovsdb-error.c;h=eb9f1eee410552116e484a9fb47d55bc73c401a9;hb=HEAD;hp=c0eddf280e9d0b907ada166f49f8e4e523e0a837;hpb=f85f8ebbfac946c19b3c6eb0f4170f579d0a4d25;p=sliver-openvswitch.git diff --git a/lib/ovsdb-error.c b/lib/ovsdb-error.c index c0eddf280..eb9f1eee4 100644 --- a/lib/ovsdb-error.c +++ b/lib/ovsdb-error.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009 Nicira Networks +/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,9 @@ #include "dynamic-string.h" #include "json.h" #include "util.h" +#include "vlog.h" + +VLOG_DEFINE_THIS_MODULE(ovsdb_error); struct ovsdb_error { const char *tag; /* String for "error" member. */ @@ -83,7 +86,7 @@ ovsdb_syntax_error(const struct json *json, const char *tag, if (json) { /* XXX this is much too much information in some cases */ - error->syntax = json_to_string(json, 0); + error->syntax = json_to_string(json, JSSF_SORT); } return error; @@ -111,8 +114,16 @@ ovsdb_wrap_error(struct ovsdb_error *error, const char *details, ...) return error; } +/* Returns an ovsdb_error that represents an internal error for file name + * 'file' and line number 'line', with 'details' (formatted as with printf()) + * as the associated message. The caller is responsible for freeing the + * returned error. + * + * If 'inner_error' is nonnull then the returned error is wrapped around + * 'inner_error'. Takes ownership of 'inner_error'. */ 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; @@ -139,7 +150,15 @@ ovsdb_internal_error(const char *file, int line, const char *details, ...) ds_put_char(&ds, ')'); } - ds_put_format(&ds, " (%s %s%s)", program_name, VERSION, BUILDNR); + ds_put_format(&ds, " (%s %s)", program_name, VERSION); + + 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)); @@ -173,12 +192,6 @@ ovsdb_error_clone(const struct ovsdb_error *old) } } -static const char * -ovsdb_errno_string(int error) -{ - return error == EOF ? "unexpected end of file" : strerror(error); -} - struct json * ovsdb_error_to_json(const struct ovsdb_error *error) { @@ -192,7 +205,7 @@ ovsdb_error_to_json(const struct ovsdb_error *error) } if (error->errno_) { json_object_put_string(json, "io-error", - ovsdb_errno_string(error->errno_)); + ovs_retval_to_string(error->errno_)); } return json; } @@ -209,7 +222,7 @@ ovsdb_error_to_string(const struct ovsdb_error *error) ds_put_format(&ds, ": %s", error->details); } if (error->errno_) { - ds_put_format(&ds, " (%s)", ovsdb_errno_string(error->errno_)); + ds_put_format(&ds, " (%s)", ovs_retval_to_string(error->errno_)); } return ds_steal_cstr(&ds); } @@ -219,3 +232,18 @@ ovsdb_error_get_tag(const struct ovsdb_error *error) { return error->tag; } + +/* If 'error' is nonnull, logs it as an error and frees it. To be used in + * situations where an error should never occur, but an 'ovsdb_error *' gets + * passed back anyhow. */ +void +ovsdb_error_assert(struct ovsdb_error *error) +{ + if (error) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + char *s = ovsdb_error_to_string(error); + VLOG_ERR_RL(&rl, "unexpected ovsdb error: %s", s); + free(s); + ovsdb_error_destroy(error); + } +}