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 #define THIS_MODULE VLM_ovsdb_error
32 const char *tag; /* String for "error" member. */
33 char *details; /* String for "details" member. */
34 char *syntax; /* String for "syntax" member. */
35 int errno_; /* Unix errno value, 0 if none. */
38 static struct ovsdb_error *
39 ovsdb_error_valist(const char *tag, const char *details, va_list args)
41 struct ovsdb_error *error = xmalloc(sizeof *error);
42 error->tag = tag ? tag : "ovsdb error";
43 error->details = details ? xvasprintf(details, args) : NULL;
50 ovsdb_error(const char *tag, const char *details, ...)
52 struct ovsdb_error *error;
55 va_start(args, details);
56 error = ovsdb_error_valist(tag, details, args);
63 ovsdb_io_error(int errno_, const char *details, ...)
65 struct ovsdb_error *error;
68 va_start(args, details);
69 error = ovsdb_error_valist("I/O error", details, args);
72 error->errno_ = errno_;
78 ovsdb_syntax_error(const struct json *json, const char *tag,
79 const char *details, ...)
81 struct ovsdb_error *error;
84 va_start(args, details);
85 error = ovsdb_error_valist(tag ? tag : "syntax error", details, args);
89 /* XXX this is much too much information in some cases */
90 error->syntax = json_to_string(json, JSSF_SORT);
97 ovsdb_wrap_error(struct ovsdb_error *error, const char *details, ...)
102 va_start(args, details);
103 msg = xvasprintf(details, args);
106 if (error->details) {
107 char *new = xasprintf("%s: %s", msg, error->details);
108 free(error->details);
109 error->details = new;
112 error->details = msg;
119 ovsdb_internal_error(const char *file, int line, const char *details, ...)
121 struct ds ds = DS_EMPTY_INITIALIZER;
122 struct backtrace backtrace;
123 struct ovsdb_error *error;
126 ds_put_format(&ds, "%s:%d:", file, line);
129 ds_put_char(&ds, ' ');
130 va_start(args, details);
131 ds_put_format_valist(&ds, details, args);
135 backtrace_capture(&backtrace);
136 if (backtrace.n_frames) {
139 ds_put_cstr(&ds, " (backtrace:");
140 for (i = 0; i < backtrace.n_frames; i++) {
141 ds_put_format(&ds, " 0x%08"PRIxPTR, backtrace.frames[i]);
143 ds_put_char(&ds, ')');
146 ds_put_format(&ds, " (%s %s%s)", program_name, VERSION, BUILDNR);
148 error = ovsdb_error("internal error", "%s", ds_cstr(&ds));
156 ovsdb_error_destroy(struct ovsdb_error *error)
159 free(error->details);
166 ovsdb_error_clone(const struct ovsdb_error *old)
169 struct ovsdb_error *new = xmalloc(sizeof *new);
171 new->details = old->details ? xstrdup(old->details) : NULL;
172 new->syntax = old->syntax ? xstrdup(old->syntax) : NULL;
173 new->errno_ = old->errno_;
181 ovsdb_errno_string(int error)
183 return error == EOF ? "unexpected end of file" : strerror(error);
187 ovsdb_error_to_json(const struct ovsdb_error *error)
189 struct json *json = json_object_create();
190 json_object_put_string(json, "error", error->tag);
191 if (error->details) {
192 json_object_put_string(json, "details", error->details);
195 json_object_put_string(json, "syntax", error->syntax);
198 json_object_put_string(json, "io-error",
199 ovsdb_errno_string(error->errno_));
205 ovsdb_error_to_string(const struct ovsdb_error *error)
207 struct ds ds = DS_EMPTY_INITIALIZER;
209 ds_put_format(&ds, "syntax \"%s\": ", error->syntax);
211 ds_put_cstr(&ds, error->tag);
212 if (error->details) {
213 ds_put_format(&ds, ": %s", error->details);
216 ds_put_format(&ds, " (%s)", ovsdb_errno_string(error->errno_));
218 return ds_steal_cstr(&ds);
222 ovsdb_error_get_tag(const struct ovsdb_error *error)
227 /* If 'error' is nonnull, logs it as an error and frees it. To be used in
228 * situations where an error should never occur, but an 'ovsdb_error *' gets
229 * passed back anyhow. */
231 ovsdb_error_assert(struct ovsdb_error *error)
234 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
235 char *s = ovsdb_error_to_string(error);
236 VLOG_ERR_RL(&rl, "unexpected ovsdb error: %s", s);
238 ovsdb_error_destroy(error);