| 1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
| 2 | // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: |
| 3 | #ident "$Id$" |
| 4 | /*====== |
| 5 | This file is part of PerconaFT. |
| 6 | |
| 7 | |
| 8 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
| 9 | |
| 10 | PerconaFT is free software: you can redistribute it and/or modify |
| 11 | it under the terms of the GNU General Public License, version 2, |
| 12 | as published by the Free Software Foundation. |
| 13 | |
| 14 | PerconaFT is distributed in the hope that it will be useful, |
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | GNU General Public License for more details. |
| 18 | |
| 19 | You should have received a copy of the GNU General Public License |
| 20 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
| 21 | |
| 22 | ---------------------------------------- |
| 23 | |
| 24 | PerconaFT is free software: you can redistribute it and/or modify |
| 25 | it under the terms of the GNU Affero General Public License, version 3, |
| 26 | as published by the Free Software Foundation. |
| 27 | |
| 28 | PerconaFT is distributed in the hope that it will be useful, |
| 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 31 | GNU Affero General Public License for more details. |
| 32 | |
| 33 | You should have received a copy of the GNU Affero General Public License |
| 34 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
| 35 | ======= */ |
| 36 | |
| 37 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
| 38 | |
| 39 | /** |
| 40 | \file errors.c |
| 41 | \brief Error handling |
| 42 | |
| 43 | The error handling routines for ydb |
| 44 | */ |
| 45 | |
| 46 | #include <toku_portability.h> |
| 47 | #include <stdio.h> |
| 48 | #include <stdarg.h> |
| 49 | |
| 50 | #include "ydb-internal.h" |
| 51 | |
| 52 | /** Checks whether the environment has panicked */ |
| 53 | int toku_env_is_panicked(DB_ENV *dbenv /**< The environment to check */) { |
| 54 | if (dbenv==0) return 0; |
| 55 | return dbenv->i->is_panicked; |
| 56 | } |
| 57 | |
| 58 | /* Prints an error message to a file specified by env (or stderr), |
| 59 | preceded by the environment's error prefix. */ |
| 60 | static void toku__ydb_error_file(const DB_ENV *env, bool use_stderr, |
| 61 | char errmsg[]) { |
| 62 | /* Determine the error file to use */ |
| 63 | FILE *CAST_FROM_VOIDP(efile, env->i->errfile); |
| 64 | if (efile==NULL && env->i->errcall==0 && use_stderr) efile = stderr; |
| 65 | |
| 66 | /* Print out on a file */ |
| 67 | if (efile) { |
| 68 | if (env->i->errpfx) fprintf(efile, "%s: " , env->i->errpfx); |
| 69 | fprintf(efile, "%s" , errmsg); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | |
| 75 | Prints out environment errors, adjusting to a variety of options |
| 76 | and formats. |
| 77 | The printout format can be controlled to print the following optional |
| 78 | messages: |
| 79 | - The environment error message prefix |
| 80 | - User-supplied prefix obtained by printing ap with the |
| 81 | fmt string |
| 82 | - The standard db error string |
| 83 | The print out takes place via errcall (if set), errfile (if set), |
| 84 | or stderr if neither is set (and the user so toggles the printout). |
| 85 | Both errcall and errfile can be set. |
| 86 | The error message is truncated to approximately 4,000 characters. |
| 87 | |
| 88 | \param env The environment that the error refers to. |
| 89 | \param error The error code |
| 90 | \param include_stderrstring Controls whether the standard db error |
| 91 | string should be included in the print out |
| 92 | \param use_stderr_if_nothing_else Toggles the use of stderr. |
| 93 | \param fmt Output format for optional prefix arguments (must be NULL |
| 94 | if the prefix is empty) |
| 95 | \param ap Optional prefix |
| 96 | */ |
| 97 | void toku_ydb_error_all_cases(const DB_ENV * env, |
| 98 | int error, |
| 99 | bool include_stderrstring, |
| 100 | bool use_stderr_if_nothing_else, |
| 101 | const char *fmt, va_list ap) { |
| 102 | /* Construct the error message */ |
| 103 | char buf [4000]; |
| 104 | int count=0; |
| 105 | if (fmt) count=vsnprintf(buf, sizeof(buf), fmt, ap); |
| 106 | if (include_stderrstring) { |
| 107 | count+=snprintf(&buf[count], sizeof(buf)-count, ": %s" , |
| 108 | db_strerror(error)); |
| 109 | } |
| 110 | |
| 111 | /* Print via errcall */ |
| 112 | if (env->i->errcall) env->i->errcall(env, env->i->errpfx, buf); |
| 113 | |
| 114 | /* Print out on a file */ |
| 115 | toku__ydb_error_file(env, use_stderr_if_nothing_else, buf); |
| 116 | } |
| 117 | |
| 118 | /** Handle all the error cases (but don't do the default thing.) |
| 119 | \param dbenv The environment that is subject to errors |
| 120 | \param error The error code |
| 121 | \param fmt The format string for additional variable arguments to |
| 122 | be printed */ |
| 123 | int toku_ydb_do_error (const DB_ENV *dbenv, int error, const char *fmt, ...) { |
| 124 | va_list ap; |
| 125 | va_start(ap, fmt); |
| 126 | toku_ydb_error_all_cases(dbenv, error, false, false, fmt, ap); |
| 127 | va_end(ap); |
| 128 | return error; |
| 129 | } |
| 130 | |
| 131 | /** Handle errors on an environment, |
| 132 | \param dbenv The environment that is subject to errors |
| 133 | \param error The error code |
| 134 | \param fmt The format string for additional variable arguments to |
| 135 | be printed */ |
| 136 | void toku_env_err(const DB_ENV * env, int error, const char *fmt, ...) { |
| 137 | va_list ap; |
| 138 | va_start(ap, fmt); |
| 139 | toku_ydb_error_all_cases(env, error, false, true, fmt, ap); |
| 140 | va_end(ap); |
| 141 | } |
| 142 | |