]>
git.proxmox.com Git - mirror_ovs.git/blob - lib/ovsdb-error.c
1 /* Copyright (c) 2009, 2010, 2011, 2012, 2016 Nicira, Inc.
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 "openvswitch/dynamic-string.h"
24 #include "openvswitch/json.h"
26 #include "openvswitch/vlog.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
;
117 /* Returns an ovsdb_error that represents an internal error for file name
118 * 'file' and line number 'line', with 'details' (formatted as with printf())
119 * as the associated message. The caller is responsible for freeing the
122 * If 'inner_error' is nonnull then the returned error is wrapped around
123 * 'inner_error'. Takes ownership of 'inner_error'. */
125 ovsdb_internal_error(struct ovsdb_error
*inner_error
,
126 const char *file
, int line
, const char *details
, ...)
128 struct ds ds
= DS_EMPTY_INITIALIZER
;
129 struct backtrace backtrace
;
130 struct ovsdb_error
*error
;
133 ds_put_format(&ds
, "%s:%d:", file
, line
);
136 ds_put_char(&ds
, ' ');
137 va_start(args
, details
);
138 ds_put_format_valist(&ds
, details
, args
);
142 backtrace_capture(&backtrace
);
143 if (backtrace
.n_frames
) {
146 ds_put_cstr(&ds
, " (backtrace:");
147 for (i
= 0; i
< backtrace
.n_frames
; i
++) {
148 ds_put_format(&ds
, " 0x%08"PRIxPTR
, backtrace
.frames
[i
]);
150 ds_put_char(&ds
, ')');
153 ds_put_format(&ds
, " (%s %s)", program_name
, VERSION
);
156 char *s
= ovsdb_error_to_string(inner_error
);
157 ds_put_format(&ds
, " (generated from: %s)", s
);
160 ovsdb_error_destroy(inner_error
);
163 error
= ovsdb_error("internal error", "%s", ds_cstr(&ds
));
171 ovsdb_error_destroy(struct ovsdb_error
*error
)
174 free(error
->details
);
181 ovsdb_error_clone(const struct ovsdb_error
*old
)
184 struct ovsdb_error
*new = xmalloc(sizeof *new);
186 new->details
= nullable_xstrdup(old
->details
);
187 new->syntax
= nullable_xstrdup(old
->syntax
);
188 new->errno_
= old
->errno_
;
196 ovsdb_error_to_json(const struct ovsdb_error
*error
)
198 struct json
*json
= json_object_create();
199 json_object_put_string(json
, "error", error
->tag
);
200 if (error
->details
) {
201 json_object_put_string(json
, "details", error
->details
);
204 json_object_put_string(json
, "syntax", error
->syntax
);
207 json_object_put_string(json
, "io-error",
208 ovs_retval_to_string(error
->errno_
));
214 ovsdb_error_to_string(const struct ovsdb_error
*error
)
216 struct ds ds
= DS_EMPTY_INITIALIZER
;
218 ds_put_format(&ds
, "syntax \"%s\": ", error
->syntax
);
220 ds_put_cstr(&ds
, error
->tag
);
221 if (error
->details
) {
222 ds_put_format(&ds
, ": %s", error
->details
);
225 ds_put_format(&ds
, " (%s)", ovs_retval_to_string(error
->errno_
));
227 return ds_steal_cstr(&ds
);
231 ovsdb_error_get_tag(const struct ovsdb_error
*error
)
236 /* If 'error' is nonnull, logs it as an error and frees it. To be used in
237 * situations where an error should never occur, but an 'ovsdb_error *' gets
238 * passed back anyhow. */
240 ovsdb_error_assert(struct ovsdb_error
*error
)
243 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 1);
244 char *s
= ovsdb_error_to_string(error
);
245 VLOG_ERR_RL(&rl
, "unexpected ovsdb error: %s", s
);
247 ovsdb_error_destroy(error
);