v3-0001-Add-InjectionPointList-to-retrieve-list-of-inject.patch

text/plain

Filename: v3-0001-Add-InjectionPointList-to-retrieve-list-of-inject.patch
Type: text/plain
Part: 0
Message: Re: Add pg_get_injection_points() for information of injection points

Patch

Format: format-patch
Series: patch v3-0001
Subject: Add InjectionPointList() to retrieve list of injection points
File+
src/backend/utils/misc/injection_point.c 52 0
src/include/utils/injection_point.h 14 0
src/tools/pgindent/typedefs.list 1 0
From d738943616f1af8fc2ce1d309a3b7a0b77f29a22 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
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