Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2113ac4

Browse files
committed
Don't use bgw_main even to specify in-core bgworker entrypoints.
On EXEC_BACKEND builds, this can fail if ASLR is in use.Backpatch to 9.5. On master, completely remove the bgw_main fieldcompletely, since there is no situation in which it is safe for anEXEC_BACKEND build. On 9.6 and 9.5, leave the field intact to avoidbreaking things for third-party code that doesn't care about workingunder EXEC_BACKEND. Prior to 9.5, there are no in-core bgworkerentrypoints.Petr Jelinek, reviewed by me.Discussion:http://postgr.es/m/09d8ad33-4287-a09b-a77f-77f8761adb5e@2ndquadrant.com
1 parentc281cd5 commit2113ac4

File tree

8 files changed

+75
-66
lines changed

8 files changed

+75
-66
lines changed

‎doc/src/sgml/bgworker.sgml

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ typedef struct BackgroundWorker
5454
int bgw_flags;
5555
BgWorkerStartTime bgw_start_time;
5656
int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
57-
bgworker_main_type bgw_main;
58-
char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
59-
char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
57+
char bgw_library_name[BGW_MAXLEN];
58+
char bgw_function_name[BGW_MAXLEN];
6059
Datum bgw_main_arg;
6160
char bgw_extra[BGW_EXTRALEN];
6261
int bgw_notify_pid;
@@ -130,27 +129,13 @@ typedef struct BackgroundWorker
130129
process in case of a crash.
131130
</para>
132131

133-
<para>
134-
<structfield>bgw_main</structfield> is a pointer to the function to run when
135-
the process is started. This field can only safely be used to launch
136-
functions within the core server, because shared libraries may be loaded
137-
at different starting addresses in different backend processes. This will
138-
happen on all platforms when the library is loaded using any mechanism
139-
other than <xref linkend="guc-shared-preload-libraries">. Even when that
140-
mechanism is used, address space layout variations will still occur on
141-
Windows, and when <literal>EXEC_BACKEND</> is used. Therefore, most users
142-
of this API should set this field to NULL. If it is non-NULL, it takes
143-
precedence over <structfield>bgw_library_name</> and
144-
<structfield>bgw_function_name</>.
145-
</para>
146-
147132
<para>
148133
<structfield>bgw_library_name</structfield> is the name of a library in
149134
which the initial entry point for the background worker should be sought.
150135
The named library will be dynamically loaded by the worker process and
151136
<structfield>bgw_function_name</structfield> will be used to identify the
152-
function to be called. If loading a function from the core code,
153-
<structfield>bgw_main</> shouldbe setinstead.
137+
function to be called. If loading a function from the core code, this must
138+
be setto "postgres".
154139
</para>
155140

156141
<para>
@@ -161,13 +146,10 @@ typedef struct BackgroundWorker
161146

162147
<para>
163148
<structfield>bgw_main_arg</structfield> is the <type>Datum</> argument
164-
to the background worker main function. Regardless of whether that
165-
function is specified via <structfield>bgw_main</> or via the combination
166-
of <function>bgw_library_name</> and <function>bgw_function_name</>,
167-
this main function should take a single argument of type <type>Datum</>
168-
and return <type>void</>. <structfield>bgw_main_arg</structfield> will be
169-
passed as the argument. In addition, the global variable
170-
<literal>MyBgworkerEntry</literal>
149+
to the background worker main function. This main function should take a
150+
single argument of type <type>Datum</> and return <type>void</>.
151+
<structfield>bgw_main_arg</structfield> will be passed as the argument.
152+
In addition, the global variable <literal>MyBgworkerEntry</literal>
171153
points to a copy of the <structname>BackgroundWorker</structname> structure
172154
passed at registration time; the worker may find it helpful to examine
173155
this structure.
@@ -215,7 +197,7 @@ typedef struct BackgroundWorker
215197

216198
<para>
217199
Signals are initially blocked when control reaches the
218-
<structfield>bgw_main</> function, and must be unblocked by it; this is to
200+
background worker's main function, and must be unblocked by it; this is to
219201
allow the process to customize its signal handlers, if necessary.
220202
Signals can be unblocked in the new process by calling
221203
<function>BackgroundWorkerUnblockSignals</> and blocked by calling

‎src/backend/access/transam/parallel.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ static dlist_head pcxt_list = DLIST_STATIC_INIT(pcxt_list);
110110
/* Private functions. */
111111
staticvoidHandleParallelMessage(ParallelContext*pcxt,inti,StringInfomsg);
112112
staticvoidParallelExtensionTrampoline(dsm_segment*seg,shm_toc*toc);
113-
staticvoidParallelWorkerMain(Datummain_arg);
114113
staticvoidWaitForParallelWorkersToExit(ParallelContext*pcxt);
115114

116115

@@ -458,7 +457,8 @@ LaunchParallelWorkers(ParallelContext *pcxt)
458457
|BGWORKER_CLASS_PARALLEL;
459458
worker.bgw_start_time=BgWorkerStart_ConsistentState;
460459
worker.bgw_restart_time=BGW_NEVER_RESTART;
461-
worker.bgw_main=ParallelWorkerMain;
460+
sprintf(worker.bgw_library_name,"postgres");
461+
sprintf(worker.bgw_function_name,"ParallelWorkerMain");
462462
worker.bgw_main_arg=UInt32GetDatum(dsm_segment_handle(pcxt->seg));
463463
worker.bgw_notify_pid=MyProcPid;
464464
memset(&worker.bgw_extra,0,BGW_EXTRALEN);
@@ -931,7 +931,7 @@ AtEOXact_Parallel(bool isCommit)
931931
/*
932932
* Main entrypoint for parallel workers.
933933
*/
934-
staticvoid
934+
void
935935
ParallelWorkerMain(Datummain_arg)
936936
{
937937
dsm_segment*seg;

‎src/backend/postmaster/bgworker.c

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#include<unistd.h>
1616

1717
#include"libpq/pqsignal.h"
18+
#include"access/parallel.h"
1819
#include"miscadmin.h"
1920
#include"pgstat.h"
2021
#include"port/atomics.h"
2122
#include"postmaster/bgworker_internals.h"
2223
#include"postmaster/postmaster.h"
2324
#include"replication/logicallauncher.h"
25+
#include"replication/logicalworker.h"
2426
#include"storage/dsm.h"
2527
#include"storage/ipc.h"
2628
#include"storage/latch.h"
@@ -109,14 +111,26 @@ struct BackgroundWorkerHandle
109111
staticBackgroundWorkerArray*BackgroundWorkerData;
110112

111113
/*
112-
* List of workers that are allowed to be started outside of
113-
* shared_preload_libraries.
114+
* List of internal background workers. These are used for mapping the
115+
* function name to actual function when building with EXEC_BACKEND and also
116+
* to allow these to be loaded outside of shared_preload_libraries.
114117
*/
115-
staticconstbgworker_main_typeInternalBGWorkers[]= {
116-
ApplyLauncherMain,
117-
NULL
118+
typedefstructInternalBGWorkerMain
119+
{
120+
char*bgw_function_name;
121+
bgworker_main_typebgw_main;
122+
}InternalBGWorkerMain;
123+
124+
staticconstInternalBGWorkerMainInternalBGWorkers[]= {
125+
{"ParallelWorkerMain",ParallelWorkerMain},
126+
{"ApplyLauncherMain",ApplyLauncherMain},
127+
{"ApplyWorkerMain",ApplyWorkerMain},
128+
/* Dummy entry marking end of the array. */
129+
{NULL,NULL}
118130
};
119131

132+
staticbgworker_main_typeGetInternalBgWorkerMain(BackgroundWorker*worker);
133+
120134
/*
121135
* Calculate shared memory needed.
122136
*/
@@ -341,7 +355,6 @@ BackgroundWorkerStateChange(void)
341355
rw->rw_worker.bgw_flags=slot->worker.bgw_flags;
342356
rw->rw_worker.bgw_start_time=slot->worker.bgw_start_time;
343357
rw->rw_worker.bgw_restart_time=slot->worker.bgw_restart_time;
344-
rw->rw_worker.bgw_main=slot->worker.bgw_main;
345358
rw->rw_worker.bgw_main_arg=slot->worker.bgw_main_arg;
346359
memcpy(rw->rw_worker.bgw_extra,slot->worker.bgw_extra,BGW_EXTRALEN);
347360

@@ -763,17 +776,14 @@ StartBackgroundWorker(void)
763776
}
764777

765778
/*
766-
* If bgw_main is set, we use that value as the initial entrypoint.
767-
* However, if the library containing the entrypoint wasn't loaded at
768-
* postmaster startup time, passing it as a direct function pointer is not
769-
* possible. To work around that, we allow callers for whom a function
770-
* pointer is not available to pass a library name (which will be loaded,
771-
* if necessary) and a function name (which will be looked up in the named
772-
* library).
779+
* For internal workers set the entry point to known function address.
780+
* Otherwise use the entry point specified by library name (which will
781+
* be loaded, if necessary) and a function name (which will be looked up
782+
* in the named library).
773783
*/
774-
if (worker->bgw_main!=NULL)
775-
entrypt=worker->bgw_main;
776-
else
784+
entrypt=GetInternalBgWorkerMain(worker);
785+
786+
if (entrypt==NULL)
777787
entrypt= (bgworker_main_type)
778788
load_external_function(worker->bgw_library_name,
779789
worker->bgw_function_name,
@@ -806,23 +816,13 @@ RegisterBackgroundWorker(BackgroundWorker *worker)
806816
{
807817
RegisteredBgWorker*rw;
808818
staticintnumworkers=0;
809-
boolinternal= false;
810-
inti;
811819

812820
if (!IsUnderPostmaster)
813821
ereport(DEBUG1,
814822
(errmsg("registering background worker \"%s\"",worker->bgw_name)));
815823

816-
for (i=0;InternalBGWorkers[i];i++)
817-
{
818-
if (worker->bgw_main==InternalBGWorkers[i])
819-
{
820-
internal= true;
821-
break;
822-
}
823-
}
824-
825-
if (!process_shared_preload_libraries_in_progress&& !internal)
824+
if (!process_shared_preload_libraries_in_progress&&
825+
GetInternalBgWorkerMain(worker)==NULL)
826826
{
827827
if (!IsUnderPostmaster)
828828
ereport(LOG,
@@ -1152,3 +1152,28 @@ TerminateBackgroundWorker(BackgroundWorkerHandle *handle)
11521152
if (signal_postmaster)
11531153
SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE);
11541154
}
1155+
1156+
/*
1157+
* Search the known internal worker array and return its main function
1158+
* pointer if found.
1159+
*
1160+
* Returns NULL if not known internal worker.
1161+
*/
1162+
staticbgworker_main_type
1163+
GetInternalBgWorkerMain(BackgroundWorker*worker)
1164+
{
1165+
inti;
1166+
1167+
/* Internal workers always have to use postgres as library name. */
1168+
if (strncmp(worker->bgw_library_name,"postgres",BGW_MAXLEN)!=0)
1169+
returnNULL;
1170+
1171+
for (i=0;InternalBGWorkers[i].bgw_function_name;i++)
1172+
{
1173+
if (strncmp(InternalBGWorkers[i].bgw_function_name,
1174+
worker->bgw_function_name,BGW_MAXLEN)==0)
1175+
returnInternalBGWorkers[i].bgw_main;
1176+
}
1177+
1178+
returnNULL;
1179+
}

‎src/backend/replication/logical/launcher.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid,
295295
bgw.bgw_flags=BGWORKER_SHMEM_ACCESS |
296296
BGWORKER_BACKEND_DATABASE_CONNECTION;
297297
bgw.bgw_start_time=BgWorkerStart_RecoveryFinished;
298-
bgw.bgw_main=ApplyWorkerMain;
298+
snprintf(bgw.bgw_library_name,BGW_MAXLEN,"postgres");
299+
snprintf(bgw.bgw_function_name,BGW_MAXLEN,"ApplyWorkerMain");
299300
if (OidIsValid(relid))
300301
snprintf(bgw.bgw_name,BGW_MAXLEN,
301302
"logical replication worker for subscription %u sync %u",subid,relid);
@@ -553,7 +554,8 @@ ApplyLauncherRegister(void)
553554
bgw.bgw_flags=BGWORKER_SHMEM_ACCESS |
554555
BGWORKER_BACKEND_DATABASE_CONNECTION;
555556
bgw.bgw_start_time=BgWorkerStart_RecoveryFinished;
556-
bgw.bgw_main=ApplyLauncherMain;
557+
snprintf(bgw.bgw_library_name,BGW_MAXLEN,"postgres");
558+
snprintf(bgw.bgw_function_name,BGW_MAXLEN,"ApplyLauncherMain");
557559
snprintf(bgw.bgw_name,BGW_MAXLEN,
558560
"logical replication launcher");
559561
bgw.bgw_restart_time=5;

‎src/include/access/parallel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,6 @@ extern void AtEOXact_Parallel(bool isCommit);
6767
externvoidAtEOSubXact_Parallel(boolisCommit,SubTransactionIdmySubId);
6868
externvoidParallelWorkerReportLastRecEnd(XLogRecPtrlast_xlog_end);
6969

70+
externvoidParallelWorkerMain(Datummain_arg);
71+
7072
#endif/* PARALLEL_H */

‎src/include/postmaster/bgworker.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ typedef struct BackgroundWorker
9191
intbgw_flags;
9292
BgWorkerStartTimebgw_start_time;
9393
intbgw_restart_time;/* in seconds, or BGW_NEVER_RESTART */
94-
bgworker_main_typebgw_main;
95-
charbgw_library_name[BGW_MAXLEN];/* only if bgw_main is NULL */
96-
charbgw_function_name[BGW_MAXLEN];/* only if bgw_main is NULL */
94+
charbgw_library_name[BGW_MAXLEN];
95+
charbgw_function_name[BGW_MAXLEN];
9796
Datumbgw_main_arg;
9897
charbgw_extra[BGW_EXTRALEN];
9998
pid_tbgw_notify_pid;/* SIGUSR1 this backend on start/stop */

‎src/test/modules/test_shm_mq/setup.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ setup_background_workers(int nworkers, dsm_segment *seg)
216216
worker.bgw_flags=BGWORKER_SHMEM_ACCESS;
217217
worker.bgw_start_time=BgWorkerStart_ConsistentState;
218218
worker.bgw_restart_time=BGW_NEVER_RESTART;
219-
worker.bgw_main=NULL;/* new worker might not have library loaded */
220219
sprintf(worker.bgw_library_name,"test_shm_mq");
221220
sprintf(worker.bgw_function_name,"test_shm_mq_main");
222221
snprintf(worker.bgw_name,BGW_MAXLEN,"test_shm_mq");

‎src/test/modules/worker_spi/worker_spi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,8 @@ _PG_init(void)
347347
BGWORKER_BACKEND_DATABASE_CONNECTION;
348348
worker.bgw_start_time=BgWorkerStart_RecoveryFinished;
349349
worker.bgw_restart_time=BGW_NEVER_RESTART;
350-
worker.bgw_main=worker_spi_main;
350+
sprintf(worker.bgw_library_name,"worker_spi");
351+
sprintf(worker.bgw_function_name,"worker_spi_main");
351352
worker.bgw_notify_pid=0;
352353

353354
/*
@@ -378,7 +379,6 @@ worker_spi_launch(PG_FUNCTION_ARGS)
378379
BGWORKER_BACKEND_DATABASE_CONNECTION;
379380
worker.bgw_start_time=BgWorkerStart_RecoveryFinished;
380381
worker.bgw_restart_time=BGW_NEVER_RESTART;
381-
worker.bgw_main=NULL;/* new worker might not have library loaded */
382382
sprintf(worker.bgw_library_name,"worker_spi");
383383
sprintf(worker.bgw_function_name,"worker_spi_main");
384384
snprintf(worker.bgw_name,BGW_MAXLEN,"worker %d",i);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp