Motr  M0
finject.h
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #pragma once
24 
25 #ifndef __MOTR_LIB_FINJECT_H__
26 #define __MOTR_LIB_FINJECT_H__
27 
28 #ifdef HAVE_CONFIG_H
29 # include "config.h" /* ENABLE_FAULT_INJECTION */
30 #endif
31 
32 #include "lib/types.h"
33 #include "lib/assert.h" /* M0_PRE */
34 
49 M0_INTERNAL int m0_fi_init(void);
50 
54 M0_INTERNAL void m0_fi_fini(void);
55 
60 M0_INTERNAL void m0_fi_print_info(void);
61 
62 struct m0_fi_fpoint_state;
63 
69  const char *fp_module;
71  const char *fp_file;
73  uint32_t fp_line_num;
75  const char *fp_func;
81  const char *fp_tag;
88 };
89 
110  /* Not valid FP type (used by internal API) */
113  /* this should be the last */
115 };
116 
121 typedef bool (*m0_fi_fpoint_state_func_t)(void *data);
122 
133  union {
134  struct {
140  uint32_t fpd_n;
146  uint32_t fpd_m;
151  uint32_t fpd___n_cnt;
157  uint32_t fpd___m_cnt;
158  } s1;
159  struct {
166  void *fpd_private;
167  } s2;
174  uint32_t fpd_p;
175  } u;
180  uint32_t fpd_hit_cnt;
185  uint32_t fpd_trigger_cnt;
186 };
187 
188 #ifdef ENABLE_FAULT_INJECTION
189 
231 #define M0_FI_ENABLED(tag) \
232 ({ \
233  static struct m0_fi_fault_point fp = { \
234  .fp_state = NULL, \
235  /* TODO: add some macro to automatically get name of current module */ \
236  .fp_module = "UNKNOWN", \
237  .fp_file = __FILE__, \
238  .fp_line_num = __LINE__, \
239  .fp_func = __func__, \
240  .fp_tag = (tag), \
241  }; \
242  \
243  if (unlikely(fp.fp_state == NULL)) { \
244  m0_fi_register(&fp); \
245  M0_ASSERT(fp.fp_state != NULL); \
246  } \
247  \
248  m0_fi_enabled(fp.fp_state); \
249 })
250 
264 M0_INTERNAL void m0_fi_enable_generic(const char *fp_func, const char *fp_tag,
265  const struct m0_fi_fpoint_data *fp_data);
266 
276 static inline void m0_fi_enable(const char *func, const char *tag)
277 {
278 /*
279  * Our headers are processed by gccxml, which is essentially a C++
280  * compiler, and it doesn't support C99 compound literals and designated
281  * initializers. So we want to hide this fancy code from gccxml to protect it
282  * from brain damage :D It's safe, because we are interested only in type
283  * definition information, produced by gccxml, and not a function
284  * implementation.
285  */
286 #if !defined(__cplusplus)
287  m0_fi_enable_generic(func, tag, &(const struct m0_fi_fpoint_data){
288  .fpd_type = M0_FI_ALWAYS });
289 #endif
290 }
291 
301 static inline void m0_fi_enable_once(const char *func, const char *tag)
302 {
303 /* See the comment inside m0_fi_enable() about purpose of this C++ guard */
304 #if !defined(__cplusplus)
305  m0_fi_enable_generic(func, tag, &(const struct m0_fi_fpoint_data){
306  .fpd_type = M0_FI_ONESHOT });
307 #endif
308 }
309 
321 static inline void m0_fi_enable_random(const char *func, const char *tag,
322  uint32_t p)
323 {
324 /* See the comment inside m0_fi_enable() about purpose of this C++ guard */
325 #if !defined(__cplusplus)
326  m0_fi_enable_generic(func, tag, &(const struct m0_fi_fpoint_data){
327  .fpd_type = M0_FI_RANDOM,
328  .u = { .fpd_p = p } });
329 #endif
330 }
331 
346 static inline void m0_fi_enable_off_n_on_m(const char *func, const char *tag,
347  uint32_t n, uint32_t m)
348 {
349 /* See the comment inside m0_fi_enable() about purpose of this C++ guard */
350 #if !defined(__cplusplus)
352  &(const struct m0_fi_fpoint_data){
353  .fpd_type = M0_FI_OFF_N_ON_M,
354  .u = { .s1 = { .fpd_n = n, .fpd_m = m } } });
355 #endif
356 }
357 
366 static inline void m0_fi_enable_each_nth_time(const char *func, const char *tag,
367  uint32_t n)
368 {
369  M0_PRE(n > 0);
370  m0_fi_enable_off_n_on_m(func, tag, n - 1, 1);
371 }
372 
387 static inline void m0_fi_enable_func(const char *func, const char *tag,
388  m0_fi_fpoint_state_func_t trigger_func,
389  void *data)
390 {
391 /* See the comment inside m0_fi_enable() about purpose of this C++ guard */
392 #if !defined(__cplusplus)
394  &(const struct m0_fi_fpoint_data){
395  .fpd_type = M0_FI_FUNC,
396  .u = { .s2 = {
397  .fpd_trigger_func = trigger_func,
398  .fpd_private = data
399  }
400  } });
401 #endif
402 }
403 
410 M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag);
411 
422 void m0_fi_register(struct m0_fi_fault_point *fp);
423 
438 bool m0_fi_enabled(struct m0_fi_fpoint_state *fps);
439 
440 M0_INTERNAL enum m0_fi_fpoint_type m0_fi_fpoint_type_from_str(const char
441  *type_name);
442 
443 #else /* ENABLE_FAULT_INJECTION */
444 #define M0_FI_ENABLED(tag) (false)
445 
446 static inline void m0_fi_enable_generic(const char *fp_func, const char *fp_tag,
447  const struct m0_fi_fpoint_data *fp_data)
448 {
449 }
450 
451 static inline void m0_fi_enable(const char *func, const char *tag)
452 {
453 }
454 
455 static inline void m0_fi_enable_once(const char *func, const char *tag)
456 {
457 }
458 
459 static inline void m0_fi_enable_random(const char *func, const char *tag,
460  uint32_t p)
461 {
462 }
463 
464 static inline void m0_fi_enable_each_nth_time(const char *func, const char *tag,
465  uint32_t n)
466 {
467 }
468 
469 static inline void m0_fi_enable_off_n_on_m(const char *func, const char *tag,
470  uint32_t n, uint32_t m)
471 {
472 }
473 
474 static inline void m0_fi_enable_func(const char *func, const char *tag,
475  m0_fi_fpoint_state_func_t trigger_func,
476  void *data)
477 {
478 }
479 
480 static inline void m0_fi_disable(const char *fp_func, const char *fp_tag)
481 {
482 }
483 
484 static inline void m0_fi_register(struct m0_fi_fault_point *fp)
485 {
486 }
487 
488 static inline bool m0_fi_enabled(struct m0_fi_fpoint_state *fps)
489 {
490  return false;
491 }
492 
493 #endif /* ENABLE_FAULT_INJECTION */
494 M0_INTERNAL int m0_fi_enable_fault_point(const char *str);
495 M0_INTERNAL int m0_fi_enable_fault_points_from_file(const char *file_name);
497 #endif /* __MOTR_LIB_FINJECT_H__ */
498 
uint32_t fpd_m
Definition: finject.h:146
static struct m0_addb2_philter p
Definition: consumer.c:40
uint32_t fpd_p
Definition: finject.h:174
struct m0_fi_fpoint_data::@247::@249 s2
#define M0_PRE(cond)
uint32_t fp_line_num
Definition: finject.h:73
m0_fi_fpoint_state_func_t fpd_trigger_func
Definition: finject.h:161
M0_INTERNAL void m0_fi_print_info(void)
Definition: finject_init.c:78
static struct m0_addb2_mach * m
Definition: consumer.c:38
uint32_t fpd_trigger_cnt
Definition: finject.h:185
static uint64_t tag(uint8_t code, uint64_t id)
Definition: addb2.c:1047
M0_INTERNAL enum m0_fi_fpoint_type m0_fi_fpoint_type_from_str(const char *type_name)
Definition: finject.c:364
struct m0_fi_fpoint_data::@247::@248 s1
struct m0_bufvec data
Definition: di.c:40
uint32_t fpd_hit_cnt
Definition: finject.h:180
static void m0_fi_enable_random(const char *func, const char *tag, uint32_t p)
Definition: finject.h:321
void m0_fi_register(struct m0_fi_fault_point *fp)
Definition: finject.c:423
const char * fp_func
Definition: finject.h:75
M0_INTERNAL int m0_fi_init(void)
Definition: finject_init.c:40
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
static void m0_fi_enable_each_nth_time(const char *func, const char *tag, uint32_t n)
Definition: finject.h:366
enum m0_fi_fpoint_type fpd_type
Definition: finject.h:132
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
static void m0_fi_enable_func(const char *func, const char *tag, m0_fi_fpoint_state_func_t trigger_func, void *data)
Definition: finject.h:387
union m0_fi_fpoint_data::@247 u
struct m0_fi_fpoint_state * fp_state
Definition: finject.h:87
const char * fp_tag
Definition: finject.h:81
uint32_t fpd___n_cnt
Definition: finject.h:151
uint32_t fpd___m_cnt
Definition: finject.h:157
static void m0_fi_enable_off_n_on_m(const char *func, const char *tag, uint32_t n, uint32_t m)
Definition: finject.h:346
bool(* m0_fi_fpoint_state_func_t)(void *data)
Definition: finject.h:121
M0_INTERNAL int m0_fi_enable_fault_point(const char *str)
Definition: finject_init.c:103
uint64_t n
Definition: fops.h:107
M0_INTERNAL void m0_fi_enable_generic(const char *fp_func, const char *fp_tag, const struct m0_fi_fpoint_data *fp_data)
Definition: finject.c:462
bool m0_fi_enabled(struct m0_fi_fpoint_state *fps)
Definition: finject.c:445
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
const char * fp_file
Definition: finject.h:71
void * fpd_private
Definition: finject.h:166
uint32_t fpd_n
Definition: finject.h:140
m0_fi_fpoint_type
Definition: finject.h:93
Definition: rcv_session.c:58
M0_INTERNAL void m0_fi_fini(void)
Definition: finject_init.c:47
M0_INTERNAL int m0_fi_enable_fault_points_from_file(const char *file_name)
Definition: finject_init.c:258
const char * fp_module
Definition: finject.h:69