1 /*
2  * virerror.h: error handling and reporting code for libvirt
3  *
4  * Copyright (C) 2006-2014 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #pragma once
23 
24 #include "internal.h"
25 
26 extern virErrorFunc virErrorHandler;
27 extern void *virUserData;
28 
29 int virErrorInitialize(void);
30 void virRaiseErrorFull(const char *filename,
31                        const char *funcname,
32                        size_t linenr,
33                        int domain,
34                        int code,
35                        virErrorLevel level,
36                        const char *str1,
37                        const char *str2,
38                        const char *str3,
39                        int int1,
40                        int int2,
41                        const char *fmt, ...)
42     G_GNUC_PRINTF(12, 13);
43 
44 void virRaiseErrorObject(const char *filename,
45                          const char *funcname,
46                          size_t linenr,
47                          virErrorPtr err);
48 
49 void virReportErrorHelper(int domcode, int errcode,
50                           const char *filename,
51                           const char *funcname,
52                           size_t linenr,
53                           const char *fmt, ...)
54   G_GNUC_PRINTF(6, 7);
55 
56 void virReportSystemErrorFull(int domcode,
57                               int theerrno,
58                               const char *filename,
59                               const char *funcname,
60                               size_t linenr,
61                               const char *fmt, ...)
62     G_GNUC_PRINTF(6, 7);
63 
64 #define virReportSystemError(theerrno, fmt,...) \
65     virReportSystemErrorFull(VIR_FROM_THIS, \
66                              (theerrno), \
67                              __FILE__, __FUNCTION__, __LINE__, \
68                              (fmt), __VA_ARGS__)
69 
70 #define virReportInvalidNullArg(argname) \
71     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
72                       VIR_FROM_THIS, \
73                       VIR_ERR_INVALID_ARG, \
74                       VIR_ERR_ERROR, \
75                       __FUNCTION__, \
76                       #argname, \
77                       NULL, \
78                       0, 0, \
79                       _("%s in %s must be NULL"), \
80                       #argname, __FUNCTION__)
81 #define virReportInvalidNonNullArg(argname) \
82     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
83                       VIR_FROM_THIS, \
84                       VIR_ERR_INVALID_ARG, \
85                       VIR_ERR_ERROR, \
86                       __FUNCTION__, \
87                       #argname, \
88                       NULL, \
89                       0, 0, \
90                       _("%s in %s must not be NULL"), \
91                       #argname, __FUNCTION__)
92 #define virReportInvalidEmptyStringArg(argname) \
93     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
94                       VIR_FROM_THIS, \
95                       VIR_ERR_INVALID_ARG, \
96                       VIR_ERR_ERROR, \
97                       __FUNCTION__, \
98                       #argname, \
99                       NULL, \
100                       0, 0, \
101                       _("string %s in %s must not be empty"), \
102                       #argname, __FUNCTION__)
103 #define virReportInvalidPositiveArg(argname) \
104     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
105                       VIR_FROM_THIS, \
106                       VIR_ERR_INVALID_ARG, \
107                       VIR_ERR_ERROR, \
108                       __FUNCTION__, \
109                       #argname, \
110                       NULL, \
111                       0, 0, \
112                       _("%s in %s must be greater than zero"), \
113                       #argname, __FUNCTION__)
114 #define virReportInvalidNonZeroArg(argname) \
115     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
116                       VIR_FROM_THIS, \
117                       VIR_ERR_INVALID_ARG, \
118                       VIR_ERR_ERROR, \
119                       __FUNCTION__, \
120                       #argname, \
121                       NULL, \
122                       0, 0, \
123                       _("%s in %s must not be zero"), \
124                       #argname, __FUNCTION__)
125 #define virReportInvalidZeroArg(argname) \
126     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
127                       VIR_FROM_THIS, \
128                       VIR_ERR_INVALID_ARG, \
129                       VIR_ERR_ERROR, \
130                       __FUNCTION__, \
131                       #argname, \
132                       NULL, \
133                       0, 0, \
134                       _("%s in %s must be zero"), \
135                       #argname, __FUNCTION__)
136 #define virReportInvalidNonNegativeArg(argname) \
137     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
138                       VIR_FROM_THIS, \
139                       VIR_ERR_INVALID_ARG, \
140                       VIR_ERR_ERROR, \
141                       __FUNCTION__, \
142                       #argname, \
143                       NULL, \
144                       0, 0, \
145                       _("%s in %s must be zero or greater"), \
146                       #argname, __FUNCTION__)
147 #define virReportInvalidArg(argname, fmt, ...) \
148     virRaiseErrorFull(__FILE__, __FUNCTION__, __LINE__, \
149                       VIR_FROM_THIS, \
150                       VIR_ERR_INVALID_ARG, \
151                       VIR_ERR_ERROR, \
152                       __FUNCTION__, \
153                       #argname, \
154                       NULL, \
155                       0, 0, \
156                       (fmt), __VA_ARGS__)
157 
158 #define virReportUnsupportedError() \
159     virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_NO_SUPPORT, \
160                          __FILE__, __FUNCTION__, __LINE__, __FUNCTION__)
161 #define virReportRestrictedError(...) \
162     virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_OPERATION_DENIED, \
163                          __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
164 /* The sizeof(...) comparison here is a hack to catch typos
165  * in the name of the enum by triggering a compile error, as well
166  * as detecting if you passed a typename that refers to a function
167  * or struct type, instead of an enum. It should get optimized away
168  * since sizeof() is known at compile time  */
169 #define virReportEnumRangeError(typname, value) \
170     virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_INTERNAL_ERROR, \
171                          __FILE__, __FUNCTION__, __LINE__, \
172                          "Unexpected enum value %d for %s", \
173                          value, sizeof((typname)1) != 0 ? #typname : #typname);
174 
175 #define virReportError(code, ...) \
176     virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
177                          __FUNCTION__, __LINE__, __VA_ARGS__)
178 
179 #define virReportErrorObject(obj) \
180     virRaiseErrorObject(__FILE__, __FUNCTION__, __LINE__, obj)
181 
182 int virSetError(virErrorPtr newerr);
183 virErrorPtr virErrorCopyNew(virErrorPtr err);
184 void virDispatchError(virConnectPtr conn);
185 
186 typedef int (*virErrorLogPriorityFunc)(virErrorPtr, int);
187 void virSetErrorLogPriorityFunc(virErrorLogPriorityFunc func);
188 
189 void virErrorSetErrnoFromLastError(void);
190 
191 bool virLastErrorIsSystemErrno(int errnum);
192 
193 void virErrorPreserveLast(virErrorPtr *saveerr);
194 void virErrorRestore(virErrorPtr *savederr);
195 
196 void virLastErrorPrefixMessage(const char *fmt, ...)
197     G_GNUC_PRINTF(1, 2);
198 
199 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virError, virFreeError);
200