The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/fail.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2009 Isilon Inc http://www.isilon.com/
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD: releng/12.0/sys/sys/fail.h 326256 2017-11-27 15:01:59Z pfg $
   28  */
   29 /**
   30  * @file
   31  *
   32  * Main header for failpoint facility.
   33  */
   34 #ifndef _SYS_FAIL_H_
   35 #define _SYS_FAIL_H_
   36 
   37 #include <sys/param.h>
   38 #include <sys/cdefs.h>
   39 #include <sys/linker_set.h>
   40 #include <sys/queue.h>
   41 #include <sys/sysctl.h>
   42 #include <sys/condvar.h>
   43 #include <sys/kernel.h>
   44 #include <sys/lock.h>
   45 #include <sys/mutex.h>
   46 #include <sys/systm.h>
   47 
   48 /**
   49  * Failpoint return codes, used internally.
   50  * @ingroup failpoint_private
   51  */
   52 enum fail_point_return_code {
   53         FAIL_POINT_RC_CONTINUE = 0,     /**< Continue with normal execution */
   54         FAIL_POINT_RC_RETURN,           /**< FP evaluated to 'return' */
   55         FAIL_POINT_RC_QUEUED,           /**< sleep_fn will be called */
   56 };
   57 
   58 struct fail_point_entry;
   59 struct fail_point_setting;
   60 
   61 /**
   62  * Internal failpoint structure, tracking all the current details of the
   63  * failpoint.  This structure is the core component shared between the
   64  * failure-injection code and the user-interface.
   65  * @ingroup failpoint_private
   66  */
   67 struct fail_point {
   68         const char *fp_name;            /* name of fail point */
   69         const char *fp_location;        /* file:line of fail point */
   70         volatile int fp_ref_cnt;        /**
   71                                      * protects fp_setting: while holding
   72                                      * a ref, fp_setting points to an
   73                                      * unfreed fail_point_setting
   74                                      */
   75         struct fail_point_setting * volatile fp_setting;
   76         int fp_flags;
   77 
   78         /**< Function to call before sleep or pause */
   79         void (*fp_pre_sleep_fn)(void *);
   80         /**< Arg for fp_pre_sleep_fn */
   81         void *fp_pre_sleep_arg;
   82 
   83         /**< Function to call after waking from sleep or pause */
   84         void (*fp_post_sleep_fn)(void *);
   85         /**< Arg for fp_post_sleep_fn */
   86         void *fp_post_sleep_arg;
   87 };
   88 
   89 #define FAIL_POINT_DYNAMIC_NAME 0x01    /**< Must free name on destroy */
   90 /**< Use timeout path for sleep instead of msleep */
   91 #define FAIL_POINT_USE_TIMEOUT_PATH 0x02
   92 /**< If fail point is set to sleep, replace the sleep call with delay */
   93 #define FAIL_POINT_NONSLEEPABLE 0x04
   94 
   95 #define FAIL_POINT_CV_DESC "fp cv no iterators"
   96 #define FAIL_POINT_IS_OFF(fp) (__predict_true((fp)->fp_setting == NULL) || \
   97         __predict_true(fail_point_is_off(fp)))
   98 
   99 __BEGIN_DECLS
  100 
  101 /* Private failpoint eval function -- use fail_point_eval() instead. */
  102 enum fail_point_return_code fail_point_eval_nontrivial(struct fail_point *,
  103         int *ret);
  104 
  105 /**
  106  * @addtogroup failpoint
  107  * @{
  108  */
  109 /*
  110  * Initialize a fail-point.  The name is formed in printf-like fashion
  111  * from "fmt" and the subsequent arguments.
  112  * Pair with fail_point_destroy().
  113  */
  114 void fail_point_init(struct fail_point *, const char *fmt, ...)
  115     __printflike(2, 3);
  116 
  117 /* Return true iff this fail point is set to off, false otherwise */
  118 bool fail_point_is_off(struct fail_point *fp);
  119 
  120 /**
  121  * Set the pre-sleep function for a fail point
  122  * If fp_post_sleep_fn is specified, then FAIL_POINT_SLEEP will result in a
  123  * (*fp->fp_pre_sleep_fn)(fp->fp_pre_sleep_arg) call by the thread.
  124  */
  125 static inline void
  126 fail_point_sleep_set_pre_func(struct fail_point *fp, void (*sleep_fn)(void *))
  127 {
  128         fp->fp_pre_sleep_fn = sleep_fn;
  129 }
  130 
  131 static inline void
  132 fail_point_sleep_set_pre_arg(struct fail_point *fp, void *sleep_arg)
  133 {
  134         fp->fp_pre_sleep_arg = sleep_arg;
  135 }
  136 
  137 /**
  138  * Set the post-sleep function.  This will be passed to timeout if we take
  139  * the timeout path. This must be set if you sleep using the timeout path.
  140  */
  141 static inline void
  142 fail_point_sleep_set_post_func(struct fail_point *fp, void (*sleep_fn)(void *))
  143 {
  144         fp->fp_post_sleep_fn = sleep_fn;
  145 }
  146 
  147 static inline void
  148 fail_point_sleep_set_post_arg(struct fail_point *fp, void *sleep_arg)
  149 {
  150         fp->fp_post_sleep_arg = sleep_arg;
  151 }
  152 /**
  153  * If the FAIL_POINT_USE_TIMEOUT flag is set on a failpoint, then
  154  * FAIL_POINT_SLEEP will result in a call to timeout instead of
  155  * msleep. Note that if you sleep while this flag is set, you must
  156  * set fp_post_sleep_fn or an error will occur upon waking.
  157  */
  158 static inline void
  159 fail_point_use_timeout_path(struct fail_point *fp, bool use_timeout,
  160         void (*post_sleep_fn)(void *))
  161 {
  162         KASSERT(!use_timeout || post_sleep_fn != NULL ||
  163                 (post_sleep_fn == NULL && fp->fp_post_sleep_fn != NULL),
  164                 ("Setting fp to use timeout, but not setting post_sleep_fn\n"));
  165 
  166         if (use_timeout)
  167                 fp->fp_flags |= FAIL_POINT_USE_TIMEOUT_PATH;
  168         else
  169                 fp->fp_flags &= ~FAIL_POINT_USE_TIMEOUT_PATH;
  170 
  171         if (post_sleep_fn != NULL)
  172                 fp->fp_post_sleep_fn = post_sleep_fn;
  173 }
  174 
  175 /**
  176  * Free the resources used by a fail-point.  Pair with fail_point_init().
  177  */
  178 void fail_point_destroy(struct fail_point *);
  179 
  180 /**
  181  * Evaluate a failpoint.
  182  */
  183 static inline enum fail_point_return_code
  184 fail_point_eval(struct fail_point *fp, int *ret)
  185 {
  186         if (__predict_true(fp->fp_setting == NULL))
  187                 return (FAIL_POINT_RC_CONTINUE);
  188         return (fail_point_eval_nontrivial(fp, ret));
  189 }
  190 
  191 __END_DECLS
  192 
  193 /* Declare a fail_point and its sysctl in a function. */
  194 #define _FAIL_POINT_NAME(name) _fail_point_##name
  195 #define _FAIL_POINT_LOCATION() "(" __FILE__ ":" __XSTRING(__LINE__) ")"
  196 #define _FAIL_POINT_INIT(parent, name, flags) \
  197         static struct fail_point _FAIL_POINT_NAME(name) = { \
  198                 .fp_name = #name, \
  199                 .fp_location = _FAIL_POINT_LOCATION(), \
  200                 .fp_ref_cnt = 0, \
  201                 .fp_setting = NULL, \
  202                 .fp_flags = (flags), \
  203                 .fp_pre_sleep_fn = NULL, \
  204                 .fp_pre_sleep_arg = NULL, \
  205                 .fp_post_sleep_fn = NULL, \
  206                 .fp_post_sleep_arg = NULL, \
  207         }; \
  208         SYSCTL_OID(parent, OID_AUTO, name, \
  209                 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, \
  210                 &_FAIL_POINT_NAME(name), 0, fail_point_sysctl, \
  211                 "A", ""); \
  212         SYSCTL_OID(parent, OID_AUTO, status_##name, \
  213                 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, \
  214                 &_FAIL_POINT_NAME(name), 0, \
  215                 fail_point_sysctl_status, "A", "");
  216 #define _FAIL_POINT_EVAL(name, cond, code...) \
  217         int RETURN_VALUE; \
  218  \
  219         if (__predict_false(cond && \
  220                 fail_point_eval(&_FAIL_POINT_NAME(name), &RETURN_VALUE))) { \
  221  \
  222                 code; \
  223  \
  224         }
  225 
  226 
  227 /**
  228  * Instantiate a failpoint which returns "RETURN_VALUE" from the function
  229  * when triggered.
  230  * @param parent  The parent sysctl under which to locate the fp's sysctl
  231  * @param name    The name of the failpoint in the sysctl tree (and printouts)
  232  * @return        Instantly returns the RETURN_VALUE specified in the
  233  *                failpoint, if triggered.
  234  */
  235 #define KFAIL_POINT_RETURN(parent, name) \
  236         KFAIL_POINT_CODE(parent, name, return RETURN_VALUE)
  237 
  238 /**
  239  * Instantiate a failpoint which returns (void) from the function when
  240  * triggered.
  241  * @param parent  The parent sysctl under which to locate the sysctl
  242  * @param name    The name of the failpoint in the sysctl tree (and printouts)
  243  * @return        Instantly returns void, if triggered in the failpoint.
  244  */
  245 #define KFAIL_POINT_RETURN_VOID(parent, name) \
  246         KFAIL_POINT_CODE(parent, name, return)
  247 
  248 /**
  249  * Instantiate a failpoint which sets an error when triggered.
  250  * @param parent     The parent sysctl under which to locate the sysctl
  251  * @param name       The name of the failpoint in the sysctl tree (and
  252  *                   printouts)
  253  * @param error_var  A variable to set to the failpoint's specified
  254  *                   return-value when triggered
  255  */
  256 #define KFAIL_POINT_ERROR(parent, name, error_var) \
  257         KFAIL_POINT_CODE(parent, name, (error_var) = RETURN_VALUE)
  258 
  259 /**
  260  * Instantiate a failpoint which sets an error and then goes to a
  261  * specified label in the function when triggered.
  262  * @param parent     The parent sysctl under which to locate the sysctl
  263  * @param name       The name of the failpoint in the sysctl tree (and
  264  *                   printouts)
  265  * @param error_var  A variable to set to the failpoint's specified
  266  *                   return-value when triggered
  267  * @param label      The location to goto when triggered.
  268  */
  269 #define KFAIL_POINT_GOTO(parent, name, error_var, label) \
  270         KFAIL_POINT_CODE(parent, name, (error_var) = RETURN_VALUE; goto label)
  271 
  272 /**
  273  * Instantiate a failpoint which sets its pre- and post-sleep callback
  274  * mechanisms.
  275  * @param parent     The parent sysctl under which to locate the sysctl
  276  * @param name       The name of the failpoint in the sysctl tree (and
  277  *                   printouts)
  278  * @param pre_func   Function pointer to the pre-sleep function, which will be
  279  *                   called directly before going to sleep.
  280  * @param pre_arg    Argument to the pre-sleep function
  281  * @param post_func  Function pointer to the pot-sleep function, which will be
  282  *                   called directly before going to sleep.
  283  * @param post_arg   Argument to the post-sleep function
  284  */
  285 #define KFAIL_POINT_SLEEP_CALLBACKS(parent, name, pre_func, pre_arg, \
  286         post_func, post_arg) \
  287         KFAIL_POINT_CODE_SLEEP_CALLBACKS(parent, name, pre_func, \
  288             pre_arg, post_func, post_arg, return RETURN_VALUE)
  289 
  290 /**
  291  * Instantiate a failpoint which runs arbitrary code when triggered, and sets
  292  * its pre- and post-sleep callback mechanisms
  293  * @param parent     The parent sysctl under which to locate the sysctl
  294  * @param name       The name of the failpoint in the sysctl tree (and
  295  *                   printouts)
  296  * @param pre_func   Function pointer to the pre-sleep function, which will be
  297  *                   called directly before going to sleep.
  298  * @param pre_arg    Argument to the pre-sleep function
  299  * @param post_func  Function pointer to the pot-sleep function, which will be
  300  *                   called directly before going to sleep.
  301  * @param post_arg   Argument to the post-sleep function
  302  * @param code       The arbitrary code to run when triggered.  Can reference
  303  *                   "RETURN_VALUE" if desired to extract the specified
  304  *                   user return-value when triggered.  Note that this is
  305  *                   implemented with a do-while loop so be careful of
  306  *                   break and continue statements.
  307  */
  308 #define KFAIL_POINT_CODE_SLEEP_CALLBACKS(parent, name, pre_func, pre_arg, \
  309         post_func, post_arg, code...) \
  310         do { \
  311                 _FAIL_POINT_INIT(parent, name) \
  312                 _FAIL_POINT_NAME(name).fp_pre_sleep_fn = pre_func; \
  313                 _FAIL_POINT_NAME(name).fp_pre_sleep_arg = pre_arg; \
  314                 _FAIL_POINT_NAME(name).fp_post_sleep_fn = post_func; \
  315                 _FAIL_POINT_NAME(name).fp_post_sleep_arg = post_arg; \
  316                 _FAIL_POINT_EVAL(name, true, code) \
  317         } while (0)
  318 
  319 
  320 /**
  321  * Instantiate a failpoint which runs arbitrary code when triggered.
  322  * @param parent     The parent sysctl under which to locate the sysctl
  323  * @param name       The name of the failpoint in the sysctl tree
  324  *                   (and printouts)
  325  * @param code       The arbitrary code to run when triggered.  Can reference
  326  *                   "RETURN_VALUE" if desired to extract the specified
  327  *                   user return-value when triggered.  Note that this is
  328  *                   implemented with a do-while loop so be careful of
  329  *                   break and continue statements.
  330  */
  331 #define KFAIL_POINT_CODE(parent, name, code...) \
  332         do { \
  333                 _FAIL_POINT_INIT(parent, name, 0) \
  334                 _FAIL_POINT_EVAL(name, true, code) \
  335         } while (0)
  336 
  337 #define KFAIL_POINT_CODE_FLAGS(parent, name, flags, code...) \
  338         do { \
  339                 _FAIL_POINT_INIT(parent, name, flags) \
  340                 _FAIL_POINT_EVAL(name, true, code) \
  341         } while (0)
  342 
  343 #define KFAIL_POINT_CODE_COND(parent, name, cond, flags, code...) \
  344         do { \
  345                 _FAIL_POINT_INIT(parent, name, flags) \
  346                 _FAIL_POINT_EVAL(name, cond, code) \
  347         } while (0)
  348 
  349 /**
  350  * @}
  351  * (end group failpoint)
  352  */
  353 
  354 #ifdef _KERNEL
  355 int fail_point_sysctl(SYSCTL_HANDLER_ARGS);
  356 int fail_point_sysctl_status(SYSCTL_HANDLER_ARGS);
  357 
  358 /* The fail point sysctl tree. */
  359 SYSCTL_DECL(_debug_fail_point);
  360 #define DEBUG_FP        _debug_fail_point
  361 #endif
  362 
  363 #endif /* _SYS_FAIL_H_ */

Cache object: a6238708490138b5cc5dc32af814fd2f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.