From d738943616f1af8fc2ce1d309a3b7a0b77f29a22 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 15 Apr 2025 14:40:30 +0900 Subject: [PATCH v3 1/2] Add InjectionPointList() to retrieve list of injection points This hides the internals of the shmem array lookup, allocating the result in a palloc'd array usable by the caller. --- src/include/utils/injection_point.h | 14 +++++++ src/backend/utils/misc/injection_point.c | 52 ++++++++++++++++++++++++ src/tools/pgindent/typedefs.list | 1 + 3 files changed, 67 insertions(+) diff --git a/src/include/utils/injection_point.h b/src/include/utils/injection_point.h index 6ba64cd1ebc6..c5c78914b848 100644 --- a/src/include/utils/injection_point.h +++ b/src/include/utils/injection_point.h @@ -11,6 +11,17 @@ #ifndef INJECTION_POINT_H #define INJECTION_POINT_H +/* + * Injection point data, used when retrieving a list of all the attached + * injection points. + */ +typedef struct InjectionPointData +{ + const char *name; + const char *library; + const char *function; +} InjectionPointData; + /* * Injection points require --enable-injection-points. */ @@ -46,6 +57,9 @@ extern void InjectionPointCached(const char *name); extern bool IsInjectionPointAttached(const char *name); extern bool InjectionPointDetach(const char *name); +/* Get the current set of injection points attached */ +extern InjectionPointData *InjectionPointList(uint32 *num_points); + #ifdef EXEC_BACKEND extern PGDLLIMPORT struct InjectionPointsCtl *ActiveInjectionPoints; #endif diff --git a/src/backend/utils/misc/injection_point.c b/src/backend/utils/misc/injection_point.c index 97ab851f0a63..1f76f25aafb9 100644 --- a/src/backend/utils/misc/injection_point.c +++ b/src/backend/utils/misc/injection_point.c @@ -584,3 +584,55 @@ IsInjectionPointAttached(const char *name) return false; /* silence compiler */ #endif } + +/* + * Retrieve a list of all the injection points currently attached. + * + * This list is palloc'd in the current memory context. + */ +InjectionPointData * +InjectionPointList(uint32 *num_points) +{ +#ifdef USE_INJECTION_POINTS + InjectionPointData *result; + uint32 max_inuse; + int cur_pos = 0; + + LWLockAcquire(InjectionPointLock, LW_SHARED); + + max_inuse = pg_atomic_read_u32(&ActiveInjectionPoints->max_inuse); + + /* + * This overestimates the allocation size, including slots that may be + * free, for simplicity. + */ + result = palloc0(sizeof(InjectionPointData) * max_inuse); + + for (uint32 idx = 0; idx < max_inuse; idx++) + { + InjectionPointEntry *entry; + uint64 generation; + + entry = &ActiveInjectionPoints->entries[idx]; + generation = pg_atomic_read_u64(&entry->generation); + + /* skip free slots */ + if (generation % 2 == 0) + continue; + + result[cur_pos].name = pstrdup(entry->name); + result[cur_pos].library = pstrdup(entry->library); + result[cur_pos].function = pstrdup(entry->function); + cur_pos++; + } + + LWLockRelease(InjectionPointLock); + + *num_points = cur_pos; + return result; + +#else + *num_points = 0; + return NULL; +#endif +} diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index d16bc208654b..e7df2dc10684 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -1281,6 +1281,7 @@ InjectionPointCacheEntry InjectionPointCallback InjectionPointCondition InjectionPointConditionType +InjectionPointData InjectionPointEntry InjectionPointsCtl InjectionPointSharedState -- 2.49.0