PostgreSQL Source Code git master
Loading...
Searching...
No Matches
injection_point.h File Reference
#include "nodes/pg_list.h"
Include dependency graph for injection_point.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  InjectionPointData
 

Macros

#define INJECTION_POINT_LOAD(name)   ((void) name)
 
#define INJECTION_POINT(name, arg)   ((void) name)
 
#define INJECTION_POINT_CACHED(name, arg)   ((void) name)
 
#define IS_INJECTION_POINT_ATTACHED(name)   (false)
 

Typedefs

typedef struct InjectionPointData InjectionPointData
 
typedef void(* InjectionPointCallback) (const char *name, const void *private_data, void *arg)
 

Functions

void InjectionPointAttach (const char *name, const char *library, const char *function, const void *private_data, int private_data_size)
 
void InjectionPointLoad (const char *name)
 
void InjectionPointRun (const char *name, void *arg)
 
void InjectionPointCached (const char *name, void *arg)
 
bool IsInjectionPointAttached (const char *name)
 
bool InjectionPointDetach (const char *name)
 
ListInjectionPointList (void)
 

Macro Definition Documentation

◆ INJECTION_POINT

#define INJECTION_POINT (   name,
  arg 
)    ((void) name)

Definition at line 37 of file injection_point.h.

◆ INJECTION_POINT_CACHED

#define INJECTION_POINT_CACHED (   name,
  arg 
)    ((void) name)

Definition at line 38 of file injection_point.h.

◆ INJECTION_POINT_LOAD

#define INJECTION_POINT_LOAD (   name)    ((void) name)

Definition at line 36 of file injection_point.h.

◆ IS_INJECTION_POINT_ATTACHED

#define IS_INJECTION_POINT_ATTACHED (   name)    (false)

Definition at line 39 of file injection_point.h.

Typedef Documentation

◆ InjectionPointCallback

typedef void(* InjectionPointCallback) (const char *name, const void *private_data, void *arg)

Definition at line 45 of file injection_point.h.

◆ InjectionPointData

Function Documentation

◆ InjectionPointAttach()

void InjectionPointAttach ( const char name,
const char library,
const char function,
const void private_data,
int  private_data_size 
)
extern

Definition at line 262 of file injection_point.c.

267{
268#ifdef USE_INJECTION_POINTS
269 InjectionPointEntry *entry;
270 uint64 generation;
272 int free_idx;
273
275 elog(ERROR, "injection point name %s too long (maximum of %u characters)",
276 name, INJ_NAME_MAXLEN - 1);
277 if (strlen(library) >= INJ_LIB_MAXLEN)
278 elog(ERROR, "injection point library %s too long (maximum of %u characters)",
279 library, INJ_LIB_MAXLEN - 1);
281 elog(ERROR, "injection point function %s too long (maximum of %u characters)",
284 elog(ERROR, "injection point data too long (maximum of %u bytes)",
286
287 /*
288 * Allocate and register a new injection point. A new point should not
289 * exist. For testing purposes this should be fine.
290 */
293 free_idx = -1;
294
295 for (int idx = 0; idx < max_inuse; idx++)
296 {
297 entry = &ActiveInjectionPoints->entries[idx];
298 generation = pg_atomic_read_u64(&entry->generation);
299 if (generation % 2 == 0)
300 {
301 /*
302 * Found a free slot where we can add the new entry, but keep
303 * going so that we will find out if the entry already exists.
304 */
305 if (free_idx == -1)
306 free_idx = idx;
307 }
308 else if (strcmp(entry->name, name) == 0)
309 elog(ERROR, "injection point \"%s\" already defined", name);
310 }
311 if (free_idx == -1)
312 {
314 elog(ERROR, "too many injection points");
316 }
317 entry = &ActiveInjectionPoints->entries[free_idx];
318 generation = pg_atomic_read_u64(&entry->generation);
319 Assert(generation % 2 == 0);
320
321 /* Save the entry */
322 strlcpy(entry->name, name, sizeof(entry->name));
323 strlcpy(entry->library, library, sizeof(entry->library));
324 strlcpy(entry->function, function, sizeof(entry->function));
325 memset(entry->private_data, 0, INJ_PRIVATE_MAXLEN);
326 if (private_data != NULL)
327 memcpy(entry->private_data, private_data, private_data_size);
328
330 pg_atomic_write_u64(&entry->generation, generation + 1);
331
332 if (free_idx + 1 > max_inuse)
334
336
337#else
338 elog(ERROR, "injection points are not supported by this build");
339#endif
340}
Datum idx(PG_FUNCTION_ARGS)
Definition _int_op.c:262
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:485
#define pg_write_barrier()
Definition atomics.h:155
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition atomics.h:274
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition atomics.h:237
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:467
#define Assert(condition)
Definition c.h:943
uint64_t uint64
Definition c.h:625
uint32_t uint32
Definition c.h:624
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define INJ_NAME_MAXLEN
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
@ LW_EXCLUSIVE
Definition lwlock.h:104
on_exit_nicely_callback function
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static int fb(int x)
const char * name

References Assert, elog, ERROR, fb(), function, idx(), INJ_NAME_MAXLEN, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), memcpy(), name, pg_atomic_read_u32(), pg_atomic_read_u64(), pg_atomic_write_u32(), pg_atomic_write_u64(), pg_write_barrier, and strlcpy().

Referenced by dcw_inject_delay_barrier(), dcw_inject_launcher_delay(), dcw_inject_startup_delay(), injection_points_attach(), injection_points_attach_func(), and test_aio_shmem_init().

◆ InjectionPointCached()

void InjectionPointCached ( const char name,
void arg 
)
extern

Definition at line 548 of file injection_point.c.

549{
550#ifdef USE_INJECTION_POINTS
552
554 if (cache_entry)
555 cache_entry->callback(name, cache_entry->private_data, arg);
556#else
557 elog(ERROR, "Injection points are not supported by this build");
558#endif
559}
Datum arg
Definition elog.c:1323

References arg, elog, ERROR, fb(), and name.

◆ InjectionPointDetach()

bool InjectionPointDetach ( const char name)
extern

Definition at line 348 of file injection_point.c.

349{
350#ifdef USE_INJECTION_POINTS
351 bool found = false;
352 int idx;
353 int max_inuse;
354
356
357 /* Find it in the shmem array, and mark the slot as unused */
359 for (idx = max_inuse - 1; idx >= 0; --idx)
360 {
362 uint64 generation;
363
364 generation = pg_atomic_read_u64(&entry->generation);
365 if (generation % 2 == 0)
366 continue; /* empty slot */
367
368 if (strcmp(entry->name, name) == 0)
369 {
370 Assert(!found);
371 found = true;
372 pg_atomic_write_u64(&entry->generation, generation + 1);
373 break;
374 }
375 }
376
377 /* If we just removed the highest-numbered entry, update 'max_inuse' */
378 if (found && idx == max_inuse - 1)
379 {
380 for (; idx >= 0; --idx)
381 {
383 uint64 generation;
384
385 generation = pg_atomic_read_u64(&entry->generation);
386 if (generation % 2 != 0)
387 break;
388 }
390 }
392
393 return found;
394#else
395 elog(ERROR, "Injection points are not supported by this build");
396 return true; /* silence compiler */
397#endif
398}

References Assert, elog, ERROR, fb(), idx(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), name, pg_atomic_read_u32(), pg_atomic_read_u64(), pg_atomic_write_u32(), and pg_atomic_write_u64().

Referenced by dcw_inject_delay_barrier(), dcw_inject_launcher_delay(), dcw_inject_startup_delay(), injection_points_cleanup(), and injection_points_detach().

◆ InjectionPointList()

List * InjectionPointList ( void  )
extern

Definition at line 581 of file injection_point.c.

582{
583#ifdef USE_INJECTION_POINTS
586
588
590
591 for (uint32 idx = 0; idx < max_inuse; idx++)
592 {
593 InjectionPointEntry *entry;
595 uint64 generation;
596
597 entry = &ActiveInjectionPoints->entries[idx];
598 generation = pg_atomic_read_u64(&entry->generation);
599
600 /* skip free slots */
601 if (generation % 2 == 0)
602 continue;
603
605 inj_point->name = pstrdup(entry->name);
606 inj_point->library = pstrdup(entry->library);
607 inj_point->function = pstrdup(entry->function);
609 }
610
612
613 return inj_points;
614
615#else
616 elog(ERROR, "Injection points are not supported by this build");
617 return NIL; /* keep compiler quiet */
618#endif
619}
#define palloc0_object(type)
Definition fe_memutils.h:75
List * lappend(List *list, void *datum)
Definition list.c:339
@ LW_SHARED
Definition lwlock.h:105
char * pstrdup(const char *in)
Definition mcxt.c:1781
#define NIL
Definition pg_list.h:68
Definition pg_list.h:54

References elog, ERROR, fb(), idx(), lappend(), LW_SHARED, LWLockAcquire(), LWLockRelease(), NIL, palloc0_object, pg_atomic_read_u32(), pg_atomic_read_u64(), and pstrdup().

Referenced by injection_points_list().

◆ InjectionPointLoad()

void InjectionPointLoad ( const char name)
extern

Definition at line 518 of file injection_point.c.

519{
520#ifdef USE_INJECTION_POINTS
522#else
523 elog(ERROR, "Injection points are not supported by this build");
524#endif
525}

References elog, ERROR, fb(), and name.

Referenced by test_aio_shmem_attach(), and test_aio_shmem_init().

◆ InjectionPointRun()

void InjectionPointRun ( const char name,
void arg 
)
extern

Definition at line 531 of file injection_point.c.

532{
533#ifdef USE_INJECTION_POINTS
535
537 if (cache_entry)
538 cache_entry->callback(name, cache_entry->private_data, arg);
539#else
540 elog(ERROR, "Injection points are not supported by this build");
541#endif
542}

References arg, elog, ERROR, fb(), and name.

◆ IsInjectionPointAttached()

bool IsInjectionPointAttached ( const char name)
extern

Definition at line 565 of file injection_point.c.

566{
567#ifdef USE_INJECTION_POINTS
569#else
570 elog(ERROR, "Injection points are not supported by this build");
571 return false; /* silence compiler */
572#endif
573}

References elog, ERROR, fb(), and name.