]>
git.proxmox.com Git - mirror_ovs.git/blob - lib/ovsdb-error.c
1 /* Copyright (c) 2009, 2010, 2011, 2012, 2016, 2017 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_free(inner_error
);
157 ds_put_format(&ds
, " (generated from: %s)", s
);
161 error
= ovsdb_error("internal error", "%s", ds_cstr(&ds
));
169 ovsdb_perm_error(const char *details
, ...)
171 struct ovsdb_error
*error
;
174 va_start(args
, details
);
175 error
= ovsdb_error_valist("permission error", details
, args
);
182 ovsdb_error_destroy(struct ovsdb_error
*error
)
185 free(error
->details
);
192 ovsdb_error_clone(const struct ovsdb_error
*old
)
195 struct ovsdb_error
*new = xmalloc(sizeof *new);
197 new->details
= nullable_xstrdup(old
->details
);
198 new->syntax
= nullable_xstrdup(old
->syntax
);
199 new->errno_
= old
->errno_
;
206 /* Returns 'error' converted to the <error> JSON object format described in RFC
207 * 7047. The caller must free the returned json (with json_destroy()). */
209 ovsdb_error_to_json(const struct ovsdb_error
*error
)
211 struct json
*json
= json_object_create();
212 json_object_put_string(json
, "error", error
->tag
);
213 if (error
->details
) {
214 json_object_put_string(json
, "details", error
->details
);
217 /* These are RFC 7047-compliant extensions. */
219 json_object_put_string(json
, "syntax", error
->syntax
);
222 json_object_put_string(json
, "io-error",
223 ovs_retval_to_string(error
->errno_
));
229 /* Returns 'error' converted to the <error> JSON object format described in RFC
230 * 7047. The caller must free the returned json (with json_destroy()).
232 * Also, frees 'error'. */
234 ovsdb_error_to_json_free(struct ovsdb_error
*error
)
236 struct json
*json
= ovsdb_error_to_json(error
);
237 ovsdb_error_destroy(error
);
241 /* Returns 'error' converted to a string suitable for use as an error message.
242 * The caller must free the returned string (with free()). */
244 ovsdb_error_to_string(const struct ovsdb_error
*error
)
246 struct ds ds
= DS_EMPTY_INITIALIZER
;
248 ds_put_format(&ds
, "syntax \"%s\": ", error
->syntax
);
250 ds_put_cstr(&ds
, error
->tag
);
251 if (error
->details
) {
252 ds_put_format(&ds
, ": %s", error
->details
);
255 ds_put_format(&ds
, " (%s)", ovs_retval_to_string(error
->errno_
));
257 return ds_steal_cstr(&ds
);
260 /* Returns 'error' converted to a string suitable for use as an error message.
261 * The caller must free the returned string (with free()).
263 * If 'error' is NULL, returns NULL.
265 * Also, frees 'error'. */
267 ovsdb_error_to_string_free(struct ovsdb_error
*error
)
270 char *s
= ovsdb_error_to_string(error
);
271 ovsdb_error_destroy(error
);
279 ovsdb_error_get_tag(const struct ovsdb_error
*error
)
284 /* If 'error' is nonnull, logs it as an error and frees it. To be used in
285 * situations where an error should never occur, but an 'ovsdb_error *' gets
286 * passed back anyhow. */
288 ovsdb_error_assert(struct ovsdb_error
*error
)
291 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 1);
292 char *s
= ovsdb_error_to_string_free(error
);
293 VLOG_ERR_RL(&rl
, "unexpected ovsdb error: %s", s
);