1 /* Copyright (c) 2009, 2010 Nicira Networks
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include "ovsdb-error.h"
22 #include "backtrace.h"
23 #include "dynamic-string.h"
28 VLOG_DEFINE_THIS_MODULE(ovsdb_error)
31 const char *tag; /* String for "error" member. */
32 char *details; /* String for "details" member. */
33 char *syntax; /* String for "syntax" member. */
34 int errno_; /* Unix errno value, 0 if none. */
37 static struct ovsdb_error *
38 ovsdb_error_valist(const char *tag, const char *details, va_list args)
40 struct ovsdb_error *error = xmalloc(sizeof *error);
41 error->tag = tag ? tag : "ovsdb error";
42 error->details = details ? xvasprintf(details, args) : NULL;
49 ovsdb_error(const char *tag, const char *details, ...)
51 struct ovsdb_error *error;
54 va_start(args, details);
55 error = ovsdb_error_valist(tag, details, args);
62 ovsdb_io_error(int errno_, const char *details, ...)
64 struct ovsdb_error *error;
67 va_start(args, details);
68 error = ovsdb_error_valist("I/O error", details, args);
71 error->errno_ = errno_;
77 ovsdb_syntax_error(const struct json *json, const char *tag,
78 const char *details, ...)
80 struct ovsdb_error *error;
83 va_start(args, details);
84 error = ovsdb_error_valist(tag ? tag : "syntax error", details, args);
88 /* XXX this is much too much information in some cases */
89 error->syntax = json_to_string(json, JSSF_SORT);
96 ovsdb_wrap_error(struct ovsdb_error *error, const char *details, ...)
101 va_start(args, details);
102 msg = xvasprintf(details, args);
105 if (error->details) {
106 char *new = xasprintf("%s: %s", msg, error->details);
107 free(error->details);
108 error->details = new;
111 error->details = msg;
118 ovsdb_internal_error(const char *file, int line, const char *details, ...)
120 struct ds ds = DS_EMPTY_INITIALIZER;
121 struct backtrace backtrace;
122 struct ovsdb_error *error;
125 ds_put_format(&ds, "%s:%d:", file, line);
128 ds_put_char(&ds, ' ');
129 va_start(args, details);
130 ds_put_format_valist(&ds, details, args);
134 backtrace_capture(&backtrace);
135 if (backtrace.n_frames) {
138 ds_put_cstr(&ds, " (backtrace:");
139 for (i = 0; i < backtrace.n_frames; i++) {
140 ds_put_format(&ds, " 0x%08"PRIxPTR, backtrace.frames[i]);
142 ds_put_char(&ds, ')');
145 ds_put_format(&ds, " (%s %s%s)", program_name, VERSION, BUILDNR);
147 error = ovsdb_error("internal error", "%s", ds_cstr(&ds));
155 ovsdb_error_destroy(struct ovsdb_error *error)
158 free(error->details);
165 ovsdb_error_clone(const struct ovsdb_error *old)
168 struct ovsdb_error *new = xmalloc(sizeof *new);
170 new->details = old->details ? xstrdup(old->details) : NULL;
171 new->syntax = old->syntax ? xstrdup(old->syntax) : NULL;
172 new->errno_ = old->errno_;
180 ovsdb_errno_string(int error)
182 return error == EOF ? "unexpected end of file" : strerror(error);
186 ovsdb_error_to_json(const struct ovsdb_error *error)
188 struct json *json = json_object_create();
189 json_object_put_string(json, "error", error->tag);
190 if (error->details) {
191 json_object_put_string(json, "details", error->details);
194 json_object_put_string(json, "syntax", error->syntax);
197 json_object_put_string(json, "io-error",
198 ovsdb_errno_string(error->errno_));
204 ovsdb_error_to_string(const struct ovsdb_error *error)
206 struct ds ds = DS_EMPTY_INITIALIZER;
208 ds_put_format(&ds, "syntax \"%s\": ", error->syntax);
210 ds_put_cstr(&ds, error->tag);
211 if (error->details) {
212 ds_put_format(&ds, ": %s", error->details);
215 ds_put_format(&ds, " (%s)", ovsdb_errno_string(error->errno_));
217 return ds_steal_cstr(&ds);
221 ovsdb_error_get_tag(const struct ovsdb_error *error)
226 /* If 'error' is nonnull, logs it as an error and frees it. To be used in
227 * situations where an error should never occur, but an 'ovsdb_error *' gets
228 * passed back anyhow. */
230 ovsdb_error_assert(struct ovsdb_error *error)
233 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
234 char *s = ovsdb_error_to_string(error);
235 VLOG_ERR_RL(&rl, "unexpected ovsdb error: %s", s);
237 ovsdb_error_destroy(error);