Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 388491f

Browse files
committed
Pass BackgroundWorker entry in the parameter file in EXEC_BACKEND mode
The BackgroundWorker struct is now passed the same way as the Port struct. Seems more consistent. This makes it possible to move InitProcess later in SubPostmasterMain (in next commit), as we no longer need to access shared memory to read background worker entry. Reviewed-by: Tristan Partin, Andres Freund, Alexander Lakhin Discussion: https://www.postgresql.org/message-id/7a59b073-5b5b-151e-7ed3-8b01ff7ce9ef@iki.fi
1 parent 69d9033 commit 388491f

File tree

3 files changed

+75
-72
lines changed

3 files changed

+75
-72
lines changed

src/backend/postmaster/bgworker.c

+1-22
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ BackgroundWorkerStateChange(bool allow_new_workers)
350350
*/
351351
rw = MemoryContextAllocExtended(PostmasterContext,
352352
sizeof(RegisteredBgWorker),
353-
MCXT_ALLOC_NO_OOM);
353+
MCXT_ALLOC_NO_OOM | MCXT_ALLOC_ZERO);
354354
if (rw == NULL)
355355
{
356356
ereport(LOG,
@@ -631,27 +631,6 @@ ResetBackgroundWorkerCrashTimes(void)
631631
}
632632
}
633633

634-
#ifdef EXEC_BACKEND
635-
/*
636-
* In EXEC_BACKEND mode, workers use this to retrieve their details from
637-
* shared memory.
638-
*/
639-
BackgroundWorker *
640-
BackgroundWorkerEntry(int slotno)
641-
{
642-
static BackgroundWorker myEntry;
643-
BackgroundWorkerSlot *slot;
644-
645-
Assert(slotno < BackgroundWorkerData->total_slots);
646-
slot = &BackgroundWorkerData->slot[slotno];
647-
Assert(slot->in_use);
648-
649-
/* must copy this in case we don't intend to retain shmem access */
650-
memcpy(&myEntry, &slot->worker, sizeof myEntry);
651-
return &myEntry;
652-
}
653-
#endif
654-
655634
/*
656635
* Complain about the BackgroundWorker definition using error level elevel.
657636
* Return true if it looks ok, false if not (unless elevel >= ERROR, in

src/backend/postmaster/postmaster.c

+74-46
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ typedef struct
476476
#endif /* WIN32 */
477477

478478
static pid_t backend_forkexec(Port *port);
479-
static pid_t internal_forkexec(int argc, char *argv[], Port *port);
479+
static pid_t internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker);
480480

481481
/* Type for a socket that can be inherited to a client process */
482482
#ifdef WIN32
@@ -495,8 +495,13 @@ typedef int InheritableSocket;
495495
*/
496496
typedef struct
497497
{
498+
bool has_port;
498499
Port port;
499500
InheritableSocket portsocket;
501+
502+
bool has_bgworker;
503+
BackgroundWorker bgworker;
504+
500505
char DataDir[MAXPGPATH];
501506
int32 MyCancelKey;
502507
int MyPMChildSlot;
@@ -542,13 +547,13 @@ typedef struct
542547
char pkglib_path[MAXPGPATH];
543548
} BackendParameters;
544549

545-
static void read_backend_variables(char *id, Port *port);
546-
static void restore_backend_variables(BackendParameters *param, Port *port);
550+
static void read_backend_variables(char *id, Port **port, BackgroundWorker **worker);
551+
static void restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorker **worker);
547552

548553
#ifndef WIN32
549-
static bool save_backend_variables(BackendParameters *param, Port *port);
554+
static bool save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker);
550555
#else
551-
static bool save_backend_variables(BackendParameters *param, Port *port,
556+
static bool save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker,
552557
HANDLE childProcess, pid_t childPid);
553558
#endif
554559

@@ -4441,11 +4446,7 @@ BackendRun(Port *port)
44414446
pid_t
44424447
postmaster_forkexec(int argc, char *argv[])
44434448
{
4444-
Port port;
4445-
4446-
/* This entry point passes dummy values for the Port variables */
4447-
memset(&port, 0, sizeof(port));
4448-
return internal_forkexec(argc, argv, &port);
4449+
return internal_forkexec(argc, argv, NULL, NULL);
44494450
}
44504451

44514452
/*
@@ -4470,7 +4471,7 @@ backend_forkexec(Port *port)
44704471
av[ac] = NULL;
44714472
Assert(ac < lengthof(av));
44724473

4473-
return internal_forkexec(ac, av, port);
4474+
return internal_forkexec(ac, av, port, NULL);
44744475
}
44754476

44764477
#ifndef WIN32
@@ -4482,7 +4483,7 @@ backend_forkexec(Port *port)
44824483
* - fork():s, and then exec():s the child process
44834484
*/
44844485
static pid_t
4485-
internal_forkexec(int argc, char *argv[], Port *port)
4486+
internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker)
44864487
{
44874488
static unsigned long tmpBackendFileNum = 0;
44884489
pid_t pid;
@@ -4498,7 +4499,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
44984499
*/
44994500
memset(&param, 0, sizeof(BackendParameters));
45004501

4501-
if (!save_backend_variables(&param, port))
4502+
if (!save_backend_variables(&param, port, worker))
45024503
return -1; /* log made by save_backend_variables */
45034504

45044505
/* Calculate name for temp file */
@@ -4582,7 +4583,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
45824583
* file is complete.
45834584
*/
45844585
static pid_t
4585-
internal_forkexec(int argc, char *argv[], Port *port)
4586+
internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker)
45864587
{
45874588
int retry_count = 0;
45884589
STARTUPINFO si;
@@ -4679,7 +4680,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
46794680
return -1;
46804681
}
46814682

4682-
if (!save_backend_variables(param, port, pi.hProcess, pi.dwProcessId))
4683+
if (!save_backend_variables(param, port, worker, pi.hProcess, pi.dwProcessId))
46834684
{
46844685
/*
46854686
* log made by save_backend_variables, but we have to clean up the
@@ -4796,7 +4797,8 @@ internal_forkexec(int argc, char *argv[], Port *port)
47964797
void
47974798
SubPostmasterMain(int argc, char *argv[])
47984799
{
4799-
Port port;
4800+
Port *port;
4801+
BackgroundWorker *worker;
48004802

48014803
/* In EXEC_BACKEND case we will not have inherited these settings */
48024804
IsPostmasterEnvironment = true;
@@ -4810,8 +4812,7 @@ SubPostmasterMain(int argc, char *argv[])
48104812
elog(FATAL, "invalid subpostmaster invocation");
48114813

48124814
/* Read in the variables file */
4813-
memset(&port, 0, sizeof(Port));
4814-
read_backend_variables(argv[2], &port);
4815+
read_backend_variables(argv[2], &port, &worker);
48154816

48164817
/* Close the postmaster's sockets (as soon as we know them) */
48174818
ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0);
@@ -4839,7 +4840,7 @@ SubPostmasterMain(int argc, char *argv[])
48394840
strcmp(argv[1], "--forkavlauncher") == 0 ||
48404841
strcmp(argv[1], "--forkavworker") == 0 ||
48414842
strcmp(argv[1], "--forkaux") == 0 ||
4842-
strncmp(argv[1], "--forkbgworker=", 15) == 0)
4843+
strcmp(argv[1], "--forkbgworker") == 0)
48434844
PGSharedMemoryReAttach();
48444845
else
48454846
PGSharedMemoryNoReAttach();
@@ -4912,7 +4913,7 @@ SubPostmasterMain(int argc, char *argv[])
49124913
* PGPROC slots, we have already initialized libpq and are able to
49134914
* report the error to the client.
49144915
*/
4915-
BackendInitialize(&port);
4916+
BackendInitialize(port);
49164917

49174918
/* Restore basic shared memory pointers */
49184919
InitShmemAccess(UsedShmemSegAddr);
@@ -4924,7 +4925,7 @@ SubPostmasterMain(int argc, char *argv[])
49244925
AttachSharedMemoryStructs();
49254926

49264927
/* And run the backend */
4927-
BackendRun(&port); /* does not return */
4928+
BackendRun(port); /* does not return */
49284929
}
49294930
if (strcmp(argv[1], "--forkaux") == 0)
49304931
{
@@ -4970,10 +4971,8 @@ SubPostmasterMain(int argc, char *argv[])
49704971

49714972
AutoVacWorkerMain(argc - 2, argv + 2); /* does not return */
49724973
}
4973-
if (strncmp(argv[1], "--forkbgworker=", 15) == 0)
4974+
if (strcmp(argv[1], "--forkbgworker") == 0)
49744975
{
4975-
int shmem_slot;
4976-
49774976
/* do this as early as possible; in particular, before InitProcess() */
49784977
IsBackgroundWorker = true;
49794978

@@ -4986,10 +4985,7 @@ SubPostmasterMain(int argc, char *argv[])
49864985
/* Attach process to shared data structures */
49874986
AttachSharedMemoryStructs();
49884987

4989-
/* Fetch MyBgworkerEntry from shared memory */
4990-
shmem_slot = atoi(argv[1] + 15);
4991-
MyBgworkerEntry = BackgroundWorkerEntry(shmem_slot);
4992-
4988+
MyBgworkerEntry = worker;
49934989
BackgroundWorkerMain();
49944990
}
49954991
if (strcmp(argv[1], "--forklog") == 0)
@@ -5648,22 +5644,19 @@ BackgroundWorkerUnblockSignals(void)
56485644

56495645
#ifdef EXEC_BACKEND
56505646
static pid_t
5651-
bgworker_forkexec(int shmem_slot)
5647+
bgworker_forkexec(BackgroundWorker *worker)
56525648
{
56535649
char *av[10];
56545650
int ac = 0;
5655-
char forkav[MAXPGPATH];
5656-
5657-
snprintf(forkav, MAXPGPATH, "--forkbgworker=%d", shmem_slot);
56585651

56595652
av[ac++] = "postgres";
5660-
av[ac++] = forkav;
5661-
av[ac++] = NULL; /* filled in by postmaster_forkexec */
5653+
av[ac++] = "--forkbgworker";
5654+
av[ac++] = NULL; /* filled in by internal_forkexec */
56625655
av[ac] = NULL;
56635656

56645657
Assert(ac < lengthof(av));
56655658

5666-
return postmaster_forkexec(ac, av);
5659+
return internal_forkexec(ac, av, NULL, worker);
56675660
}
56685661
#endif
56695662

@@ -5704,7 +5697,7 @@ do_start_bgworker(RegisteredBgWorker *rw)
57045697
rw->rw_worker.bgw_name)));
57055698

57065699
#ifdef EXEC_BACKEND
5707-
switch ((worker_pid = bgworker_forkexec(rw->rw_shmem_slot)))
5700+
switch ((worker_pid = bgworker_forkexec(&rw->rw_worker)))
57085701
#else
57095702
switch ((worker_pid = fork_process()))
57105703
#endif
@@ -6037,16 +6030,36 @@ static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
60376030
/* Save critical backend variables into the BackendParameters struct */
60386031
#ifndef WIN32
60396032
static bool
6040-
save_backend_variables(BackendParameters *param, Port *port)
6033+
save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker)
60416034
#else
60426035
static bool
6043-
save_backend_variables(BackendParameters *param, Port *port,
6036+
save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker,
60446037
HANDLE childProcess, pid_t childPid)
60456038
#endif
60466039
{
6047-
memcpy(&param->port, port, sizeof(Port));
6048-
if (!write_inheritable_socket(&param->portsocket, port->sock, childPid))
6049-
return false;
6040+
if (port)
6041+
{
6042+
memcpy(&param->port, port, sizeof(Port));
6043+
if (!write_inheritable_socket(&param->portsocket, port->sock, childPid))
6044+
return false;
6045+
param->has_port = true;
6046+
}
6047+
else
6048+
{
6049+
memset(&param->port, 0, sizeof(Port));
6050+
param->has_port = false;
6051+
}
6052+
6053+
if (worker)
6054+
{
6055+
memcpy(&param->bgworker, worker, sizeof(BackgroundWorker));
6056+
param->has_bgworker = true;
6057+
}
6058+
else
6059+
{
6060+
memset(&param->bgworker, 0, sizeof(BackgroundWorker));
6061+
param->has_bgworker = false;
6062+
}
60506063

60516064
strlcpy(param->DataDir, DataDir, MAXPGPATH);
60526065

@@ -6202,7 +6215,7 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
62026215
#endif
62036216

62046217
static void
6205-
read_backend_variables(char *id, Port *port)
6218+
read_backend_variables(char *id, Port **port, BackgroundWorker **worker)
62066219
{
62076220
BackendParameters param;
62086221

@@ -6269,15 +6282,30 @@ read_backend_variables(char *id, Port *port)
62696282
}
62706283
#endif
62716284

6272-
restore_backend_variables(&param, port);
6285+
restore_backend_variables(&param, port, worker);
62736286
}
62746287

62756288
/* Restore critical backend variables from the BackendParameters struct */
62766289
static void
6277-
restore_backend_variables(BackendParameters *param, Port *port)
6290+
restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorker **worker)
62786291
{
6279-
memcpy(port, &param->port, sizeof(Port));
6280-
read_inheritable_socket(&port->sock, &param->portsocket);
6292+
if (param->has_port)
6293+
{
6294+
*port = (Port *) MemoryContextAlloc(TopMemoryContext, sizeof(Port));
6295+
memcpy(*port, &param->port, sizeof(Port));
6296+
read_inheritable_socket(&(*port)->sock, &param->portsocket);
6297+
}
6298+
else
6299+
*port = NULL;
6300+
6301+
if (param->has_bgworker)
6302+
{
6303+
*worker = (BackgroundWorker *)
6304+
MemoryContextAlloc(TopMemoryContext, sizeof(BackgroundWorker));
6305+
memcpy(*worker, &param->bgworker, sizeof(BackgroundWorker));
6306+
}
6307+
else
6308+
*worker = NULL;
62816309

62826310
SetDataDir(param->DataDir);
62836311

src/include/postmaster/bgworker_internals.h

-4
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,4 @@ extern void ResetBackgroundWorkerCrashTimes(void);
5757
/* Entry point for background worker processes */
5858
extern void BackgroundWorkerMain(void) pg_attribute_noreturn();
5959

60-
#ifdef EXEC_BACKEND
61-
extern BackgroundWorker *BackgroundWorkerEntry(int slotno);
62-
#endif
63-
6460
#endif /* BGWORKER_INTERNALS_H */

0 commit comments

Comments
 (0)