00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <eyedbconfig.h>
00025
00026 #include <string.h>
00027
00028 #include <eyedbsm/eyedbsm.h>
00029 #include <eyedblib/log.h>
00030 #include <pthread.h>
00031 #include <eyedblib/butils.h>
00032 #include <stdlib.h>
00033 #include <stdarg.h>
00034 #include <eyedblib/m_mem.h>
00035 #include "lib/m_mem_p.h"
00036
00037
00038
00039 #define NSTATUS 8
00040
00041 namespace eyedbsm {
00042
00043 static int w_status;
00044
00045 struct StatusContext {
00046 StatusRec status;
00047 char *err_msg;
00048 int err_msg_len;
00049 };
00050
00051 static StatusContext statusCtx[NSTATUS];
00052
00053 static StatusContext *
00054 getStatusContext(int *pnstatus)
00055 {
00056 if (w_status >= NSTATUS)
00057 w_status = 0;
00058 if (pnstatus)
00059 *pnstatus = w_status;
00060 return &statusCtx[w_status++];
00061 }
00062
00063 Status
00064 statusMake(Error err, const char *fmt, ...)
00065 {
00066 va_list ap;
00067 StatusContext *s;
00068 int nstatus;
00069 char *buf;
00070
00071 va_start(ap, fmt);
00072 buf = eyedblib::getFBuffer(fmt, ap);
00073 va_end(ap);
00074
00075 va_start(ap, fmt);
00076 vsprintf(buf, fmt, ap);
00077 va_end(ap);
00078
00079 IDB_LOG(IDB_LOG_EXCEPTION, ("%s\n", buf));
00080
00081 s = getStatusContext(&nstatus);
00082
00083 if (strlen(buf) >= s->err_msg_len) {
00084 s->err_msg_len = strlen(buf)+10;
00085 s->err_msg = (char *)m_realloc(s->err_msg, s->err_msg_len);
00086 }
00087
00088 s->status.err = err;
00089 s->status.err_msg = s->err_msg;
00090 strcpy(s->status.err_msg, buf);
00091
00092 nstatus++;
00093
00094 return &s->status;
00095 }
00096
00097 Status
00098 statusMake_s(Error err)
00099 {
00100 StatusContext *s;
00101
00102 s = getStatusContext(0);
00103
00104 s->status.err = err;
00105 s->status.err_msg = "";
00106
00107 return &s->status;
00108 }
00109
00110 static char *_seError[N_ERROR];
00111
00112 #define PREFIX "storage manager: "
00113
00114 void
00115 errorInit(void)
00116 {
00117 if (!_seError[SUCCESS]) {
00118 _seError[SUCCESS] =
00119 PREFIX "success";
00120 _seError[ERROR] =
00121 PREFIX "error";
00122 _seError[SYS_ERROR] =
00123 PREFIX "system error";
00124 _seError[CONNECTION_FAILURE] =
00125 PREFIX "connection failure";
00126 _seError[SERVER_FAILURE] =
00127 PREFIX "server failure";
00128 _seError[CANNOT_LOCK_SHMFILE] =
00129 PREFIX "cannot lock shm file";
00130 _seError[DB_ALREADY_LOCK_BY_A_SERVER] =
00131 PREFIX "db already lock by a server";
00132 _seError[INVALID_DBID] =
00133 PREFIX "invalid dbid";
00134 _seError[INVALID_MAXSIZE] =
00135 PREFIX "invalid maxsize";
00136 _seError[INVALID_SIZESLOT] =
00137 PREFIX "invalid sizeslot";
00138 _seError[INVALID_NBSLOTS] =
00139 PREFIX "invalid slot number";
00140 _seError[INVALID_NBOBJS] =
00141 PREFIX "invalid object number";
00142 _seError[DATABASE_CREATION_ERROR] =
00143 PREFIX "database creation error";
00144 _seError[DATABASE_ACCESS_DENIED] =
00145 PREFIX "database access denied";
00146 _seError[DATABASE_OPEN_FAILED] =
00147 PREFIX "database open failed";
00148 _seError[INVALID_DATAFILE_CNT] =
00149 PREFIX "invalid datafile count";
00150 _seError[INVALID_DATASPACE_CNT] =
00151 PREFIX "invalid dataspace count";
00152 _seError[INVALID_DATAFILE_CNT_IN_DATASPACE] =
00153 PREFIX "invalid datafile count in a dataspace";
00154 _seError[INVALID_DBFILE] =
00155 PREFIX "invalid database file";
00156 _seError[INVALID_DBFILE_ACCESS] =
00157 PREFIX "invalid database file access";
00158 _seError[INVALID_SHMFILE] =
00159 PREFIX "invalid shm file";
00160 _seError[INVALID_SHMFILE_ACCESS] =
00161 PREFIX "invalid shm file access";
00162 _seError[INVALID_OBJMAP_ACCESS] =
00163 PREFIX "invalid oid map file access";
00164 _seError[INVALID_DATAFILE] =
00165 PREFIX "invalid datafile";
00166 _seError[INVALID_DATASPACE] =
00167 PREFIX "invalid dataspace";
00168 _seError[INVALID_DMPFILE] =
00169 PREFIX "invalid data map file";
00170 _seError[INVALID_DATAFILEMAXSIZE] =
00171 PREFIX "invalid datafile maxsize";
00172 _seError[INVALID_FILES_COPY] =
00173 PREFIX "invalid files copy";
00174 _seError[INVALID_DBFILES_COPY] =
00175 PREFIX "invalid database files copy";
00176 _seError[INVALID_DATAFILES_COPY] =
00177 PREFIX "invalid data files copy";
00178 _seError[INVALID_SHMFILES_COPY] =
00179 PREFIX "invalid shm files copy";
00180 _seError[INVALID_OBJMAPFILES_COPY] =
00181 PREFIX "invalid object map files copy";
00182 _seError[DBFILES_IDENTICAL] =
00183 PREFIX "database files are identical";
00184 _seError[DATAFILES_IDENTICAL] =
00185 PREFIX "data files are identical";
00186 _seError[DBFILE_ALREADY_EXISTS] =
00187 PREFIX "database file already exists";
00188 _seError[SHMFILE_ALREADY_EXISTS] =
00189 PREFIX "shm file already exists";
00190 _seError[OBJMAPFILE_ALREADY_EXISTS] =
00191 PREFIX "object map file already exists";
00192 _seError[DATAFILE_ALREADY_EXISTS] =
00193 PREFIX "data file already exists";
00194 _seError[SIZE_TOO_LARGE] =
00195 PREFIX "size too large";
00196 _seError[WRITE_FORBIDDEN] =
00197 PREFIX "write forbidden";
00198 _seError[BACKEND_INTERRUPTED] =
00199 PREFIX "backend interrupted";
00200 _seError[CONN_RESET_BY_PEER] =
00201 PREFIX "connection reset by peer";
00202 _seError[FATAL_MUTEX_LOCK_TIMEOUT] =
00203 PREFIX "fatal mutex lock timeout: the shmem must be cleanup "
00204 "(or possibly the computer is overloaded)";
00205 _seError[LOCK_TIMEOUT] =
00206 PREFIX "lock timeout";
00207 _seError[INVALID_FLAG] =
00208 PREFIX "invalid flag";
00209 _seError[INVALID_DB_HANDLE] =
00210 PREFIX "invalid database handle";
00211 _seError[TRANSACTION_TOO_MANY_NESTED] =
00212 PREFIX "too many transactions nested";
00213 _seError[TOO_MANY_TRANSACTIONS] =
00214 PREFIX "too many transactions";
00215 _seError[TRANSACTION_NEEDED] =
00216 PREFIX "transaction needed";
00217 _seError[TRANSACTION_LOCKING_FAILED] =
00218 PREFIX "transaction locking failed";
00219 _seError[TRANSACTION_UNLOCKING_FAILED] =
00220 PREFIX "transaction unlocking failed";
00221 _seError[DEADLOCK_DETECTED] =
00222 PREFIX "deadlock detected";
00223 _seError[INVALID_TRANSACTION_MODE] =
00224 PREFIX "invalid transaction mode";
00225 _seError[RW_TRANSACTION_NEEDED] =
00226 PREFIX "read write mode transaction needed";
00227 _seError[NOT_YET_IMPLEMENTED] =
00228 PREFIX "not yet implemented";
00229 _seError[MAP_ERROR] =
00230 PREFIX "map error";
00231 _seError[INVALID_MAPTYPE] =
00232 PREFIX "invalid map type";
00233 _seError[INVALID_OBJECT_SIZE] =
00234 PREFIX "invalid object size";
00235 _seError[INVALID_OFFSET] =
00236 PREFIX "invalid object offset";
00237 _seError[TOO_MANY_OBJECTS] =
00238 PREFIX "maximum object count has been reached";
00239 _seError[NO_DATAFILESPACE_LEFT] =
00240 PREFIX "no space left on dataspace";
00241 _seError[NO_SHMSPACE_LEFT] =
00242 PREFIX "no space left on shm";
00243 _seError[INVALID_SIZE] =
00244 PREFIX "invalid size";
00245 _seError[PROTECTION_INVALID_UID] =
00246 PREFIX "protection invalid uid";
00247 _seError[PROTECTION_DUPLICATE_UID] =
00248 PREFIX "protection duplicate uid";
00249 _seError[PROTECTION_DUPLICATE_NAME] =
00250 PREFIX "protection duplicate name";
00251 _seError[PROTECTION_NOT_FOUND] =
00252 PREFIX "protection not found";
00253 _seError[INVALID_OID] =
00254 PREFIX "invalid oid";
00255 _seError[OBJECT_PROTECTED] =
00256 PREFIX "object protected";
00257 _seError[INVALID_ROOT_ENTRY_SIZE] =
00258 PREFIX "invalid root entry size";
00259 _seError[INVALID_ROOT_ENTRY_KEY] =
00260 PREFIX "invalid root entry key";
00261 _seError[INVALID_READ_ACCESS] =
00262 PREFIX "invalid read access";
00263 _seError[INVALID_WRITE_ACCESS] =
00264 PREFIX "invalid write access";
00265 _seError[PROT_NAME_TOO_LONG] =
00266 PREFIX "prot name too long";
00267 _seError[ROOT_ENTRY_EXISTS] =
00268 PREFIX "root entry exists";
00269 _seError[TOO_MANY_ROOT_ENTRIES] =
00270 PREFIX "too many root entries";
00271 _seError[ROOT_ENTRY_NOT_FOUND] =
00272 PREFIX "root entry not found";
00273 _seError[NOTIMPLEMENTED] =
00274 PREFIX "notimplemented";
00275 _seError[NO_SETUID_PRIVILEGE] =
00276 PREFIX "no setuid privilege";
00277 _seError[COMPATIBILITY_ERROR] =
00278 PREFIX "compatibility error";
00279 _seError[INTERNAL_ERROR] =
00280 PREFIX "internal error";
00281 _seError[FATAL_ERROR] =
00282 PREFIX "fatal error";
00283
00284 #if 1
00285 {
00286 int i;
00287 for (i = 0; i < N_ERROR; i++)
00288 if (!_seError[i])
00289 fprintf(stderr, "_seError not set for %d\n", i);
00290 }
00291 #endif
00292 }
00293 }
00294
00295 const char *
00296 statusGet(Status status)
00297 {
00298 if (status != Success)
00299 {
00300 const char *s = status->err_msg;
00301 errorInit();
00302
00303 if (s && *s)
00304 {
00305 static int buf_len;
00306 static char *buf;
00307 int len = strlen(_seError[status->err]) + strlen(s) + 12;
00308 if (len >= buf_len) {
00309 buf_len = len + 256;
00310 free(buf);
00311 buf = (char *)m_malloc(buf_len);
00312 }
00313 sprintf(buf, "%s: %s", _seError[status->err], s);
00314 return buf;
00315 }
00316 else
00317 return _seError[status->err];
00318 }
00319
00320 return "";
00321 }
00322
00323 const char *
00324 statusGet_err(int err)
00325 {
00326 if (err != SUCCESS) {
00327 errorInit();
00328 if (err >= SUCCESS && err < N_ERROR)
00329 return _seError[err];
00330 else
00331 return "";
00332 }
00333
00334 return "";
00335 }
00336
00337 Status
00338 statusPrint(Status status, const char *fmt, ...)
00339 {
00340 va_list ap;
00341
00342 va_start(ap, fmt);
00343
00344 if (status != Success) {
00345 const char *s = status->err_msg;
00346 char *buf;
00347
00348 errorInit();
00349
00350 buf = eyedblib::getFBuffer(fmt, ap);
00351 vsprintf(buf, fmt, ap);
00352
00353 fprintf(stderr, "%s: ", _seError[status->err]);
00354 if (*buf) {
00355 fprintf(stderr, "%s: ", buf);
00356
00357 if (s && *s)
00358 fprintf(stderr, "%s\n", s);
00359 }
00360 else {
00361 if (s && *s)
00362 fprintf(stderr, ": %s", s);
00363 fprintf(stderr, "\n");
00364 }
00365
00366 fflush(stderr);
00367 }
00368
00369 va_end(ap);
00370 return status;
00371 }
00372 }