Coverage Report

Created: 2026-11-12 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/postmaster/bgworker.c
Line
Count
Source
1
/*--------------------------------------------------------------------
2
 * bgworker.c
3
 *    POSTGRES pluggable background workers implementation
4
 *
5
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
6
 *
7
 * IDENTIFICATION
8
 *    src/backend/postmaster/bgworker.c
9
 *
10
 *-------------------------------------------------------------------------
11
 */
12
13
#include "postgres.h"
14
15
#include "access/parallel.h"
16
#include "commands/repack.h"
17
#include "libpq/pqsignal.h"
18
#include "miscadmin.h"
19
#include "pgstat.h"
20
#include "port/atomics.h"
21
#include "postmaster/bgworker_internals.h"
22
#include "postmaster/datachecksum_state.h"
23
#include "postmaster/postmaster.h"
24
#include "replication/logicallauncher.h"
25
#include "replication/logicalworker.h"
26
#include "storage/ipc.h"
27
#include "storage/latch.h"
28
#include "storage/lwlock.h"
29
#include "storage/pmsignal.h"
30
#include "storage/proc.h"
31
#include "storage/procarray.h"
32
#include "storage/procsignal.h"
33
#include "storage/shmem.h"
34
#include "storage/subsystems.h"
35
#include "tcop/tcopprot.h"
36
#include "utils/ascii.h"
37
#include "utils/memutils.h"
38
#include "utils/ps_status.h"
39
#include "utils/timeout.h"
40
#include "utils/wait_event.h"
41
42
/*
43
 * The postmaster's list of registered background workers, in private memory.
44
 */
45
dlist_head  BackgroundWorkerList = DLIST_STATIC_INIT(BackgroundWorkerList);
46
47
/*
48
 * BackgroundWorkerSlots exist in shared memory and can be accessed (via
49
 * the BackgroundWorkerArray) by both the postmaster and by regular backends.
50
 * However, the postmaster cannot take locks, even spinlocks, because this
51
 * might allow it to crash or become wedged if shared memory gets corrupted.
52
 * Such an outcome is intolerable.  Therefore, we need a lockless protocol
53
 * for coordinating access to this data.
54
 *
55
 * The 'in_use' flag is used to hand off responsibility for the slot between
56
 * the postmaster and the rest of the system.  When 'in_use' is false,
57
 * the postmaster will ignore the slot entirely, except for the 'in_use' flag
58
 * itself, which it may read.  In this state, regular backends may modify the
59
 * slot.  Once a backend sets 'in_use' to true, the slot becomes the
60
 * responsibility of the postmaster.  Regular backends may no longer modify it,
61
 * but the postmaster may examine it.  Thus, a backend initializing a slot
62
 * must fully initialize the slot - and insert a write memory barrier - before
63
 * marking it as in use.
64
 *
65
 * As an exception, however, even when the slot is in use, regular backends
66
 * may set the 'terminate' flag for a slot, telling the postmaster not
67
 * to restart it.  Once the background worker is no longer running, the slot
68
 * will be released for reuse.
69
 *
70
 * In addition to coordinating with the postmaster, backends modifying this
71
 * data structure must coordinate with each other.  Since they can take locks,
72
 * this is straightforward: any backend wishing to manipulate a slot must
73
 * take BackgroundWorkerLock in exclusive mode.  Backends wishing to read
74
 * data that might get concurrently modified by other backends should take
75
 * this lock in shared mode.  No matter what, backends reading this data
76
 * structure must be able to tolerate concurrent modifications by the
77
 * postmaster.
78
 */
79
typedef struct BackgroundWorkerSlot
80
{
81
  bool    in_use;
82
  bool    terminate;
83
  pid_t   pid;      /* InvalidPid = not started yet; 0 = dead */
84
  uint64    generation;   /* incremented when slot is recycled */
85
  BackgroundWorker worker;
86
} BackgroundWorkerSlot;
87
88
/*
89
 * In order to limit the total number of parallel workers (according to
90
 * max_parallel_workers GUC), we maintain the number of active parallel
91
 * workers.  Since the postmaster cannot take locks, two variables are used for
92
 * this purpose: the number of registered parallel workers (modified by the
93
 * backends, protected by BackgroundWorkerLock) and the number of terminated
94
 * parallel workers (modified only by the postmaster, lockless).  The active
95
 * number of parallel workers is the number of registered workers minus the
96
 * terminated ones.  These counters can of course overflow, but it's not
97
 * important here since the subtraction will still give the right number.
98
 */
99
typedef struct BackgroundWorkerArray
100
{
101
  int     total_slots;
102
  uint32    parallel_register_count;
103
  uint32    parallel_terminate_count;
104
  pg_attribute_counted_by(total_slots) BackgroundWorkerSlot slot[FLEXIBLE_ARRAY_MEMBER];
105
} BackgroundWorkerArray;
106
107
struct BackgroundWorkerHandle
108
{
109
  int     slot;
110
  uint64    generation;
111
};
112
113
static BackgroundWorkerArray *BackgroundWorkerData;
114
115
static void BackgroundWorkerShmemRequest(void *arg);
116
static void BackgroundWorkerShmemInit(void *arg);
117
118
const ShmemCallbacks BackgroundWorkerShmemCallbacks = {
119
  .request_fn = BackgroundWorkerShmemRequest,
120
  .init_fn = BackgroundWorkerShmemInit,
121
};
122
123
/*
124
 * List of internal background worker entry points.  We need this for
125
 * reasons explained in LookupBackgroundWorkerFunction(), below.
126
 */
127
static const struct
128
{
129
  const char *fn_name;
130
  bgworker_main_type fn_addr;
131
}     InternalBGWorkers[] =
132
133
{
134
  {
135
    .fn_name = "ApplyLauncherMain",
136
    .fn_addr = ApplyLauncherMain
137
  },
138
  {
139
    .fn_name = "ApplyWorkerMain",
140
    .fn_addr = ApplyWorkerMain
141
  },
142
  {
143
    .fn_name = "ParallelApplyWorkerMain",
144
    .fn_addr = ParallelApplyWorkerMain
145
  },
146
  {
147
    .fn_name = "ParallelWorkerMain",
148
    .fn_addr = ParallelWorkerMain
149
  },
150
  {
151
    .fn_name = "RepackWorkerMain",
152
    .fn_addr = RepackWorkerMain
153
  },
154
  {
155
    .fn_name = "SequenceSyncWorkerMain",
156
    .fn_addr = SequenceSyncWorkerMain
157
  },
158
  {
159
    .fn_name = "TableSyncWorkerMain",
160
    .fn_addr = TableSyncWorkerMain
161
  },
162
  {
163
    .fn_name = "DataChecksumsWorkerLauncherMain",
164
    .fn_addr = DataChecksumsWorkerLauncherMain
165
  },
166
  {
167
    .fn_name = "DataChecksumsWorkerMain",
168
    .fn_addr = DataChecksumsWorkerMain
169
  }
170
};
171
172
/* Private functions. */
173
static bgworker_main_type LookupBackgroundWorkerFunction(const char *libraryname, const char *funcname);
174
175
176
/*
177
 * Register shared memory needed for background workers.
178
 */
179
static void
180
BackgroundWorkerShmemRequest(void *arg)
181
0
{
182
0
  Size    size;
183
184
  /* Array of workers is variably sized. */
185
0
  size = offsetof(BackgroundWorkerArray, slot);
186
0
  size = add_size(size, mul_size(max_worker_processes,
187
0
                   sizeof(BackgroundWorkerSlot)));
188
0
  ShmemRequestStruct(.name = "Background Worker Data",
189
0
             .size = size,
190
0
             .ptr = (void **) &BackgroundWorkerData,
191
0
    );
192
0
}
193
194
/*
195
 * Initialize shared memory for background workers.
196
 */
197
static void
198
BackgroundWorkerShmemInit(void *arg)
199
0
{
200
0
  dlist_iter  iter;
201
0
  int     slotno = 0;
202
203
0
  BackgroundWorkerData->total_slots = max_worker_processes;
204
0
  BackgroundWorkerData->parallel_register_count = 0;
205
0
  BackgroundWorkerData->parallel_terminate_count = 0;
206
207
  /*
208
   * Copy contents of worker list into shared memory.  Record the shared
209
   * memory slot assigned to each worker.  This ensures a 1-to-1
210
   * correspondence between the postmaster's private list and the array in
211
   * shared memory.
212
   */
213
0
  dlist_foreach(iter, &BackgroundWorkerList)
214
0
  {
215
0
    BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
216
0
    RegisteredBgWorker *rw;
217
218
0
    rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
219
0
    Assert(slotno < max_worker_processes);
220
0
    slot->in_use = true;
221
0
    slot->terminate = false;
222
0
    slot->pid = InvalidPid;
223
0
    slot->generation = 0;
224
0
    rw->rw_shmem_slot = slotno;
225
0
    rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */
226
0
    memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker));
227
0
    ++slotno;
228
0
  }
229
230
  /*
231
   * Mark any remaining slots as not in use.
232
   */
233
0
  while (slotno < max_worker_processes)
234
0
  {
235
0
    BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
236
237
0
    slot->in_use = false;
238
0
    ++slotno;
239
0
  }
240
0
}
241
242
/*
243
 * Search the postmaster's backend-private list of RegisteredBgWorker objects
244
 * for the one that maps to the given slot number.
245
 */
246
static RegisteredBgWorker *
247
FindRegisteredWorkerBySlotNumber(int slotno)
248
0
{
249
0
  dlist_iter  iter;
250
251
0
  dlist_foreach(iter, &BackgroundWorkerList)
252
0
  {
253
0
    RegisteredBgWorker *rw;
254
255
0
    rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
256
0
    if (rw->rw_shmem_slot == slotno)
257
0
      return rw;
258
0
  }
259
260
0
  return NULL;
261
0
}
262
263
/*
264
 * Notice changes to shared memory made by other backends.
265
 * Accept new worker requests only if allow_new_workers is true.
266
 *
267
 * This code runs in the postmaster, so we must be very careful not to assume
268
 * that shared memory contents are sane.  Otherwise, a rogue backend could
269
 * take out the postmaster.
270
 */
271
void
272
BackgroundWorkerStateChange(bool allow_new_workers)
273
{
274
  int     slotno;
275
276
  /*
277
   * The total number of slots stored in shared memory should match our
278
   * notion of max_worker_processes.  If it does not, something is very
279
   * wrong.  Further down, we always refer to this value as
280
   * max_worker_processes, in case shared memory gets corrupted while we're
281
   * looping.
282
   */
283
  if (max_worker_processes != BackgroundWorkerData->total_slots)
284
  {
285
    ereport(LOG,
286
        (errmsg("inconsistent background worker state (\"max_worker_processes\"=%d, total slots=%d)",
287
            max_worker_processes,
288
            BackgroundWorkerData->total_slots)));
289
    return;
290
  }
291
292
  /*
293
   * Iterate through slots, looking for newly-registered workers or workers
294
   * who must die.
295
   */
296
  for (slotno = 0; slotno < max_worker_processes; ++slotno)
297
  {
298
    BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
299
    RegisteredBgWorker *rw;
300
301
    if (!slot->in_use)
302
      continue;
303
304
    /*
305
     * Make sure we don't see the in_use flag before the updated slot
306
     * contents.
307
     */
308
    pg_read_barrier();
309
310
    /* See whether we already know about this worker. */
311
    rw = FindRegisteredWorkerBySlotNumber(slotno);
312
    if (rw != NULL)
313
    {
314
      /*
315
       * In general, the worker data can't change after it's initially
316
       * registered.  However, someone can set the terminate flag.
317
       */
318
      if (slot->terminate && !rw->rw_terminate)
319
      {
320
        rw->rw_terminate = true;
321
        if (rw->rw_pid != 0)
322
          kill(rw->rw_pid, SIGTERM);
323
        else
324
        {
325
          /* Report never-started, now-terminated worker as dead. */
326
          ReportBackgroundWorkerPID(rw);
327
        }
328
      }
329
      continue;
330
    }
331
332
    /*
333
     * If we aren't allowing new workers, then immediately mark it for
334
     * termination; the next stanza will take care of cleaning it up.
335
     * Doing this ensures that any process waiting for the worker will get
336
     * awoken, even though the worker will never be allowed to run.
337
     */
338
    if (!allow_new_workers)
339
      slot->terminate = true;
340
341
    /*
342
     * If the worker is marked for termination, we don't need to add it to
343
     * the registered workers list; we can just free the slot. However, if
344
     * bgw_notify_pid is set, the process that registered the worker may
345
     * need to know that we've processed the terminate request, so be sure
346
     * to signal it.
347
     */
348
    if (slot->terminate)
349
    {
350
      int     notify_pid;
351
352
      /*
353
       * We need a memory barrier here to make sure that the load of
354
       * bgw_notify_pid and the update of parallel_terminate_count
355
       * complete before the store to in_use.
356
       */
357
      notify_pid = slot->worker.bgw_notify_pid;
358
      if ((slot->worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
359
        BackgroundWorkerData->parallel_terminate_count++;
360
      slot->pid = 0;
361
362
      pg_memory_barrier();
363
      slot->in_use = false;
364
365
      if (notify_pid != 0)
366
        kill(notify_pid, SIGUSR1);
367
368
      continue;
369
    }
370
371
    /*
372
     * Copy the registration data into the registered workers list.
373
     */
374
    rw = MemoryContextAllocExtended(PostmasterContext,
375
                    sizeof(RegisteredBgWorker),
376
                    MCXT_ALLOC_NO_OOM | MCXT_ALLOC_ZERO);
377
    if (rw == NULL)
378
    {
379
      ereport(LOG,
380
          (errcode(ERRCODE_OUT_OF_MEMORY),
381
           errmsg("out of memory")));
382
      return;
383
    }
384
385
    /*
386
     * Copy strings in a paranoid way.  If shared memory is corrupted, the
387
     * source data might not even be NUL-terminated.
388
     */
389
    ascii_safe_strlcpy(rw->rw_worker.bgw_name,
390
               slot->worker.bgw_name, BGW_MAXLEN);
391
    ascii_safe_strlcpy(rw->rw_worker.bgw_type,
392
               slot->worker.bgw_type, BGW_MAXLEN);
393
    ascii_safe_strlcpy(rw->rw_worker.bgw_library_name,
394
               slot->worker.bgw_library_name, MAXPGPATH);
395
    ascii_safe_strlcpy(rw->rw_worker.bgw_function_name,
396
               slot->worker.bgw_function_name, BGW_MAXLEN);
397
398
    /*
399
     * Copy various fixed-size fields.
400
     *
401
     * flags, start_time, and restart_time are examined by the postmaster,
402
     * but nothing too bad will happen if they are corrupted.  The
403
     * remaining fields will only be examined by the child process.  It
404
     * might crash, but we won't.
405
     */
406
    rw->rw_worker.bgw_flags = slot->worker.bgw_flags;
407
    rw->rw_worker.bgw_start_time = slot->worker.bgw_start_time;
408
    rw->rw_worker.bgw_restart_time = slot->worker.bgw_restart_time;
409
    rw->rw_worker.bgw_main_arg = slot->worker.bgw_main_arg;
410
    memcpy(rw->rw_worker.bgw_extra, slot->worker.bgw_extra, BGW_EXTRALEN);
411
412
    /*
413
     * Copy the PID to be notified about state changes, but only if the
414
     * postmaster knows about a backend with that PID.  It isn't an error
415
     * if the postmaster doesn't know about the PID, because the backend
416
     * that requested the worker could have died (or been killed) just
417
     * after doing so.  Nonetheless, at least until we get some experience
418
     * with how this plays out in the wild, log a message at a relative
419
     * high debug level.
420
     */
421
    rw->rw_worker.bgw_notify_pid = slot->worker.bgw_notify_pid;
422
    if (!PostmasterMarkPIDForWorkerNotify(rw->rw_worker.bgw_notify_pid))
423
    {
424
      elog(DEBUG1, "worker notification PID %d is not valid",
425
         (int) rw->rw_worker.bgw_notify_pid);
426
      rw->rw_worker.bgw_notify_pid = 0;
427
    }
428
429
    /* Initialize postmaster bookkeeping. */
430
    rw->rw_pid = 0;
431
    rw->rw_crashed_at = 0;
432
    rw->rw_shmem_slot = slotno;
433
    rw->rw_terminate = false;
434
435
    /* Log it! */
436
    ereport(DEBUG1,
437
        (errmsg_internal("registering background worker \"%s\"",
438
                 rw->rw_worker.bgw_name)));
439
440
    dlist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
441
  }
442
}
443
444
/*
445
 * Forget about a background worker that's no longer needed.
446
 *
447
 * NOTE: The entry is unlinked from BackgroundWorkerList.  If the caller is
448
 * iterating through it, better use a mutable iterator!
449
 *
450
 * Caller is responsible for notifying bgw_notify_pid, if appropriate.
451
 *
452
 * This function must be invoked only in the postmaster.
453
 */
454
void
455
ForgetBackgroundWorker(RegisteredBgWorker *rw)
456
{
457
  BackgroundWorkerSlot *slot;
458
459
  Assert(rw->rw_shmem_slot < max_worker_processes);
460
  slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
461
  Assert(slot->in_use);
462
463
  /*
464
   * We need a memory barrier here to make sure that the update of
465
   * parallel_terminate_count completes before the store to in_use.
466
   */
467
  if ((rw->rw_worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
468
    BackgroundWorkerData->parallel_terminate_count++;
469
470
  pg_memory_barrier();
471
  slot->in_use = false;
472
473
  ereport(DEBUG1,
474
      (errmsg_internal("unregistering background worker \"%s\"",
475
               rw->rw_worker.bgw_name)));
476
477
  dlist_delete(&rw->rw_lnode);
478
  pfree(rw);
479
}
480
481
/*
482
 * Report the PID of a newly-launched background worker in shared memory.
483
 *
484
 * This function should only be called from the postmaster.
485
 */
486
void
487
ReportBackgroundWorkerPID(RegisteredBgWorker *rw)
488
0
{
489
0
  BackgroundWorkerSlot *slot;
490
491
0
  Assert(rw->rw_shmem_slot < max_worker_processes);
492
0
  slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
493
0
  slot->pid = rw->rw_pid;
494
495
0
  if (rw->rw_worker.bgw_notify_pid != 0)
496
0
    kill(rw->rw_worker.bgw_notify_pid, SIGUSR1);
497
0
}
498
499
/*
500
 * Report that the PID of a background worker is now zero because a
501
 * previously-running background worker has exited.
502
 *
503
 * NOTE: The entry may be unlinked from BackgroundWorkerList.  If the caller
504
 * is iterating through it, better use a mutable iterator!
505
 *
506
 * This function should only be called from the postmaster.
507
 */
508
void
509
ReportBackgroundWorkerExit(RegisteredBgWorker *rw)
510
0
{
511
0
  BackgroundWorkerSlot *slot;
512
0
  int     notify_pid;
513
514
0
  Assert(rw->rw_shmem_slot < max_worker_processes);
515
0
  slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
516
0
  slot->pid = rw->rw_pid;
517
0
  notify_pid = rw->rw_worker.bgw_notify_pid;
518
519
  /*
520
   * If this worker is slated for deregistration, do that before notifying
521
   * the process which started it.  Otherwise, if that process tries to
522
   * reuse the slot immediately, it might not be available yet.  In theory
523
   * that could happen anyway if the process checks slot->pid at just the
524
   * wrong moment, but this makes the window narrower.
525
   */
526
0
  if (rw->rw_terminate ||
527
0
    rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
528
0
    ForgetBackgroundWorker(rw);
529
530
0
  if (notify_pid != 0)
531
0
    kill(notify_pid, SIGUSR1);
532
0
}
533
534
/*
535
 * Cancel SIGUSR1 notifications for a PID belonging to an exiting backend.
536
 *
537
 * This function should only be called from the postmaster.
538
 */
539
void
540
BackgroundWorkerStopNotifications(pid_t pid)
541
0
{
542
0
  dlist_iter  iter;
543
544
0
  dlist_foreach(iter, &BackgroundWorkerList)
545
0
  {
546
0
    RegisteredBgWorker *rw;
547
548
0
    rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
549
0
    if (rw->rw_worker.bgw_notify_pid == pid)
550
0
      rw->rw_worker.bgw_notify_pid = 0;
551
0
  }
552
0
}
553
554
/*
555
 * Cancel any not-yet-started worker requests that have waiting processes.
556
 *
557
 * This is called during a normal ("smart" or "fast") database shutdown.
558
 * After this point, no new background workers will be started, so anything
559
 * that might be waiting for them needs to be kicked off its wait.  We do
560
 * that by canceling the bgworker registration entirely, which is perhaps
561
 * overkill, but since we're shutting down it does not matter whether the
562
 * registration record sticks around.
563
 *
564
 * This function should only be called from the postmaster.
565
 */
566
void
567
ForgetUnstartedBackgroundWorkers(void)
568
0
{
569
0
  dlist_mutable_iter iter;
570
571
0
  dlist_foreach_modify(iter, &BackgroundWorkerList)
572
0
  {
573
0
    RegisteredBgWorker *rw;
574
0
    BackgroundWorkerSlot *slot;
575
576
0
    rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
577
0
    Assert(rw->rw_shmem_slot < max_worker_processes);
578
0
    slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
579
580
    /* If it's not yet started, and there's someone waiting ... */
581
0
    if (slot->pid == InvalidPid &&
582
0
      rw->rw_worker.bgw_notify_pid != 0)
583
0
    {
584
      /* ... then zap it, and notify the waiter */
585
0
      int     notify_pid = rw->rw_worker.bgw_notify_pid;
586
587
0
      ForgetBackgroundWorker(rw);
588
0
      if (notify_pid != 0)
589
0
        kill(notify_pid, SIGUSR1);
590
0
    }
591
0
  }
592
0
}
593
594
/*
595
 * Reset background worker crash state.
596
 *
597
 * We assume that, after a crash-and-restart cycle, background workers without
598
 * the never-restart flag should be restarted immediately, instead of waiting
599
 * for bgw_restart_time to elapse.  On the other hand, workers with that flag
600
 * should be forgotten immediately, since we won't ever restart them.
601
 *
602
 * This function should only be called from the postmaster.
603
 */
604
void
605
ResetBackgroundWorkerCrashTimes(void)
606
0
{
607
0
  dlist_mutable_iter iter;
608
609
0
  dlist_foreach_modify(iter, &BackgroundWorkerList)
610
0
  {
611
0
    RegisteredBgWorker *rw;
612
613
0
    rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
614
615
0
    if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
616
0
    {
617
      /*
618
       * Workers marked BGW_NEVER_RESTART shouldn't get relaunched after
619
       * the crash, so forget about them.  (If we wait until after the
620
       * crash to forget about them, and they are parallel workers,
621
       * parallel_terminate_count will get incremented after we've
622
       * already zeroed parallel_register_count, which would be bad.)
623
       */
624
0
      ForgetBackgroundWorker(rw);
625
0
    }
626
0
    else
627
0
    {
628
      /*
629
       * The accounting which we do via parallel_register_count and
630
       * parallel_terminate_count would get messed up if a worker marked
631
       * parallel could survive a crash and restart cycle. All such
632
       * workers should be marked BGW_NEVER_RESTART, and thus control
633
       * should never reach this branch.
634
       */
635
0
      Assert((rw->rw_worker.bgw_flags & BGWORKER_CLASS_PARALLEL) == 0);
636
637
      /*
638
       * Allow this worker to be restarted immediately after we finish
639
       * resetting.
640
       */
641
0
      rw->rw_crashed_at = 0;
642
0
      rw->rw_pid = 0;
643
644
      /*
645
       * If there was anyone waiting for it, they're history.
646
       */
647
0
      rw->rw_worker.bgw_notify_pid = 0;
648
0
    }
649
0
  }
650
0
}
651
652
/*
653
 * Complain about the BackgroundWorker definition using error level elevel.
654
 * Return true if it looks ok, false if not (unless elevel >= ERROR, in
655
 * which case we won't return at all in the not-OK case).
656
 */
657
static bool
658
SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
659
0
{
660
  /* sanity check for flags */
661
662
  /*
663
   * We used to support workers not connected to shared memory, but don't
664
   * anymore. Thus this is a required flag now. We're not removing the flag
665
   * for compatibility reasons and because the flag still provides some
666
   * signal when reading code.
667
   */
668
0
  if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
669
0
  {
670
0
    ereport(elevel,
671
0
        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
672
0
         errmsg("background worker \"%s\": background workers without shared memory access are not supported",
673
0
            worker->bgw_name)));
674
0
    return false;
675
0
  }
676
677
0
  if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
678
0
  {
679
0
    if (worker->bgw_start_time == BgWorkerStart_PostmasterStart)
680
0
    {
681
0
      ereport(elevel,
682
0
          (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
683
0
           errmsg("background worker \"%s\": cannot request database access if starting at postmaster start",
684
0
              worker->bgw_name)));
685
0
      return false;
686
0
    }
687
688
    /* XXX other checks? */
689
0
  }
690
691
  /* Interruptible workers require a database connection */
692
0
  if ((worker->bgw_flags & BGWORKER_INTERRUPTIBLE) &&
693
0
    !(worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION))
694
0
  {
695
0
    ereport(elevel,
696
0
        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
697
0
         errmsg("background worker \"%s\": cannot make background workers interruptible without database access",
698
0
            worker->bgw_name)));
699
0
    return false;
700
0
  }
701
702
0
  if ((worker->bgw_restart_time < 0 &&
703
0
     worker->bgw_restart_time != BGW_NEVER_RESTART) ||
704
0
    (worker->bgw_restart_time > USECS_PER_DAY / 1000))
705
0
  {
706
0
    ereport(elevel,
707
0
        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
708
0
         errmsg("background worker \"%s\": invalid restart interval",
709
0
            worker->bgw_name)));
710
0
    return false;
711
0
  }
712
713
  /*
714
   * Parallel workers may not be configured for restart, because the
715
   * parallel_register_count/parallel_terminate_count accounting can't
716
   * handle parallel workers lasting through a crash-and-restart cycle.
717
   */
718
0
  if (worker->bgw_restart_time != BGW_NEVER_RESTART &&
719
0
    (worker->bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
720
0
  {
721
0
    ereport(elevel,
722
0
        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
723
0
         errmsg("background worker \"%s\": parallel workers may not be configured for restart",
724
0
            worker->bgw_name)));
725
0
    return false;
726
0
  }
727
728
  /*
729
   * If bgw_type is not filled in, use bgw_name.
730
   */
731
0
  if (strcmp(worker->bgw_type, "") == 0)
732
0
    strcpy(worker->bgw_type, worker->bgw_name);
733
734
0
  return true;
735
0
}
736
737
/*
738
 * Main entry point for background worker processes.
739
 */
740
void
741
BackgroundWorkerMain(const void *startup_data, size_t startup_data_len)
742
0
{
743
0
  sigjmp_buf  local_sigjmp_buf;
744
0
  BackgroundWorker *worker;
745
0
  bgworker_main_type entrypt;
746
747
0
  if (startup_data == NULL)
748
0
    elog(FATAL, "unable to find bgworker entry");
749
0
  Assert(startup_data_len == sizeof(BackgroundWorker));
750
0
  worker = MemoryContextAlloc(TopMemoryContext, sizeof(BackgroundWorker));
751
0
  memcpy(worker, startup_data, sizeof(BackgroundWorker));
752
753
  /*
754
   * Now that we're done reading the startup data, release postmaster's
755
   * working memory context.
756
   */
757
0
  if (PostmasterContext)
758
0
  {
759
0
    MemoryContextDelete(PostmasterContext);
760
0
    PostmasterContext = NULL;
761
0
  }
762
763
0
  MyBgworkerEntry = worker;
764
0
  init_ps_display(worker->bgw_name);
765
766
0
  Assert(GetProcessingMode() == InitProcessing);
767
768
  /* Apply PostAuthDelay */
769
0
  if (PostAuthDelay > 0)
770
0
    pg_usleep(PostAuthDelay * 1000000L);
771
772
  /*
773
   * Set up signal handlers.
774
   */
775
0
  if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
776
0
  {
777
    /*
778
     * SIGINT is used to signal canceling the current action
779
     */
780
0
    pqsignal(SIGINT, StatementCancelHandler);
781
0
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
782
0
    pqsignal(SIGFPE, FloatExceptionHandler);
783
784
    /* XXX Any other handlers needed here? */
785
0
  }
786
0
  else
787
0
  {
788
0
    pqsignal(SIGINT, PG_SIG_IGN);
789
0
    pqsignal(SIGUSR1, PG_SIG_IGN);
790
0
    pqsignal(SIGFPE, PG_SIG_IGN);
791
0
  }
792
0
  pqsignal(SIGTERM, die);
793
  /* SIGQUIT handler was already set up by InitPostmasterChild */
794
0
  pqsignal(SIGHUP, PG_SIG_IGN);
795
796
0
  InitializeTimeouts();   /* establishes SIGALRM handler */
797
798
0
  pqsignal(SIGPIPE, PG_SIG_IGN);
799
0
  pqsignal(SIGUSR2, PG_SIG_IGN);
800
801
  /*
802
   * If an exception is encountered, processing resumes here.
803
   *
804
   * We just need to clean up, report the error, and go away.
805
   */
806
0
  if (sigsetjmp(local_sigjmp_buf, 1) != 0)
807
0
  {
808
    /* Since not using PG_TRY, must reset error stack by hand */
809
0
    error_context_stack = NULL;
810
811
    /* Prevent interrupts while cleaning up */
812
0
    HOLD_INTERRUPTS();
813
814
    /*
815
     * sigsetjmp will have blocked all signals, but we may need to accept
816
     * signals while communicating with our parallel leader.  Once we've
817
     * done HOLD_INTERRUPTS() it should be safe to unblock signals.
818
     */
819
0
    BackgroundWorkerUnblockSignals();
820
821
    /* Report the error to the parallel leader and the server log */
822
0
    EmitErrorReport();
823
824
    /*
825
     * Do we need more cleanup here?  For shmem-connected bgworkers, we
826
     * will call InitProcess below, which will install ProcKill as exit
827
     * callback.  That will take care of releasing locks, etc.
828
     */
829
830
    /* and go away */
831
0
    proc_exit(1);
832
0
  }
833
834
  /* We can now handle ereport(ERROR) */
835
0
  PG_exception_stack = &local_sigjmp_buf;
836
837
  /*
838
   * Create a per-backend PGPROC struct in shared memory.  We must do this
839
   * before we can use LWLocks or access any shared memory.
840
   */
841
0
  InitProcess();
842
843
  /*
844
   * Early initialization.
845
   */
846
0
  BaseInit();
847
848
  /*
849
   * Look up the entry point function, loading its library if necessary.
850
   */
851
0
  entrypt = LookupBackgroundWorkerFunction(worker->bgw_library_name,
852
0
                       worker->bgw_function_name);
853
854
  /*
855
   * Note that in normal processes, we would call InitPostgres here.  For a
856
   * worker, however, we don't know what database to connect to, yet; so we
857
   * need to wait until the user code does it via
858
   * BackgroundWorkerInitializeConnection().
859
   */
860
861
  /*
862
   * Now invoke the user-defined worker code
863
   */
864
0
  entrypt(worker->bgw_main_arg);
865
866
  /* ... and if it returns, we're done */
867
0
  proc_exit(0);
868
0
}
869
870
/*
871
 * Connect background worker to a database.
872
 */
873
void
874
BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags)
875
0
{
876
0
  BackgroundWorker *worker = MyBgworkerEntry;
877
0
  uint32    init_flags = 0; /* never honor session_preload_libraries */
878
879
  /* ignore datallowconn and ACL_CONNECT? */
880
0
  if (flags & BGWORKER_BYPASS_ALLOWCONN)
881
0
    init_flags |= INIT_PG_OVERRIDE_ALLOW_CONNS;
882
  /* ignore rolcanlogin? */
883
0
  if (flags & BGWORKER_BYPASS_ROLELOGINCHECK)
884
0
    init_flags |= INIT_PG_OVERRIDE_ROLE_LOGIN;
885
886
  /* XXX is this the right errcode? */
887
0
  if (!(worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION))
888
0
    ereport(FATAL,
889
0
        (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
890
0
         errmsg("database connection requirement not indicated during registration")));
891
892
0
  InitPostgres(dbname, InvalidOid, /* database to connect to */
893
0
         username, InvalidOid, /* role to connect as */
894
0
         init_flags,
895
0
         NULL);      /* no out_dbname */
896
897
  /* it had better not gotten out of "init" mode yet */
898
0
  if (!IsInitProcessingMode())
899
0
    ereport(ERROR,
900
0
        (errmsg("invalid processing mode in background worker")));
901
0
  SetProcessingMode(NormalProcessing);
902
0
}
903
904
/*
905
 * Connect background worker to a database using OIDs.
906
 */
907
void
908
BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags)
909
0
{
910
0
  BackgroundWorker *worker = MyBgworkerEntry;
911
0
  uint32    init_flags = 0; /* never honor session_preload_libraries */
912
913
  /* ignore datallowconn and ACL_CONNECT? */
914
0
  if (flags & BGWORKER_BYPASS_ALLOWCONN)
915
0
    init_flags |= INIT_PG_OVERRIDE_ALLOW_CONNS;
916
  /* ignore rolcanlogin? */
917
0
  if (flags & BGWORKER_BYPASS_ROLELOGINCHECK)
918
0
    init_flags |= INIT_PG_OVERRIDE_ROLE_LOGIN;
919
920
  /* XXX is this the right errcode? */
921
0
  if (!(worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION))
922
0
    ereport(FATAL,
923
0
        (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
924
0
         errmsg("database connection requirement not indicated during registration")));
925
926
0
  InitPostgres(NULL, dboid,  /* database to connect to */
927
0
         NULL, useroid, /* role to connect as */
928
0
         init_flags,
929
0
         NULL);      /* no out_dbname */
930
931
  /* it had better not gotten out of "init" mode yet */
932
0
  if (!IsInitProcessingMode())
933
0
    ereport(ERROR,
934
0
        (errmsg("invalid processing mode in background worker")));
935
0
  SetProcessingMode(NormalProcessing);
936
0
}
937
938
/*
939
 * Block/unblock signals in a background worker
940
 */
941
void
942
BackgroundWorkerBlockSignals(void)
943
0
{
944
0
  sigprocmask(SIG_SETMASK, &BlockSig, NULL);
945
0
}
946
947
void
948
BackgroundWorkerUnblockSignals(void)
949
0
{
950
0
  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
951
0
}
952
953
/*
954
 * Register a new static background worker.
955
 *
956
 * This can only be called directly from postmaster or in the _PG_init
957
 * function of a module library that's loaded by shared_preload_libraries;
958
 * otherwise it will have no effect.
959
 */
960
void
961
RegisterBackgroundWorker(BackgroundWorker *worker)
962
{
963
  RegisteredBgWorker *rw;
964
  static int  numworkers = 0;
965
966
  /*
967
   * Static background workers can only be registered in the postmaster
968
   * process.
969
   */
970
  if (IsUnderPostmaster || !IsPostmasterEnvironment)
971
  {
972
    /*
973
     * In EXEC_BACKEND or single-user mode, we process
974
     * shared_preload_libraries in backend processes too.  We cannot
975
     * register static background workers at that stage, but many
976
     * libraries' _PG_init() functions don't distinguish whether they're
977
     * being loaded in the postmaster or in a backend, they just check
978
     * process_shared_preload_libraries_in_progress.  It's a bit sloppy,
979
     * but for historical reasons we tolerate it.  In EXEC_BACKEND mode,
980
     * the background workers should already have been registered when the
981
     * library was loaded in postmaster.
982
     */
983
    if (process_shared_preload_libraries_in_progress)
984
      return;
985
    ereport(LOG,
986
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
987
         errmsg("background worker \"%s\": must be registered in \"shared_preload_libraries\"",
988
            worker->bgw_name)));
989
    return;
990
  }
991
992
  /*
993
   * Cannot register static background workers after calling
994
   * BackgroundWorkerShmemInit().
995
   */
996
  if (BackgroundWorkerData != NULL)
997
    elog(ERROR, "cannot register background worker \"%s\" after shmem init",
998
       worker->bgw_name);
999
1000
  ereport(DEBUG1,
1001
      (errmsg_internal("registering background worker \"%s\"", worker->bgw_name)));
1002
1003
  if (!SanityCheckBackgroundWorker(worker, LOG))
1004
    return;
1005
1006
  if (worker->bgw_notify_pid != 0)
1007
  {
1008
    ereport(LOG,
1009
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1010
         errmsg("background worker \"%s\": only dynamic background workers can request notification",
1011
            worker->bgw_name)));
1012
    return;
1013
  }
1014
1015
  /*
1016
   * Enforce maximum number of workers.  Note this is overly restrictive: we
1017
   * could allow more non-shmem-connected workers, because these don't count
1018
   * towards the MAX_BACKENDS limit elsewhere.  For now, it doesn't seem
1019
   * important to relax this restriction.
1020
   */
1021
  if (++numworkers > max_worker_processes)
1022
  {
1023
    ereport(LOG,
1024
        (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1025
         errmsg("too many background workers"),
1026
         errdetail_plural("Up to %d background worker can be registered with the current settings.",
1027
                  "Up to %d background workers can be registered with the current settings.",
1028
                  max_worker_processes,
1029
                  max_worker_processes),
1030
         errhint("Consider increasing the configuration parameter \"%s\".", "max_worker_processes")));
1031
    return;
1032
  }
1033
1034
  /*
1035
   * Copy the registration data into the registered workers list.
1036
   */
1037
  rw = MemoryContextAllocExtended(PostmasterContext,
1038
                  sizeof(RegisteredBgWorker),
1039
                  MCXT_ALLOC_NO_OOM);
1040
  if (rw == NULL)
1041
  {
1042
    ereport(LOG,
1043
        (errcode(ERRCODE_OUT_OF_MEMORY),
1044
         errmsg("out of memory")));
1045
    return;
1046
  }
1047
1048
  rw->rw_worker = *worker;
1049
  rw->rw_pid = 0;
1050
  rw->rw_crashed_at = 0;
1051
  rw->rw_terminate = false;
1052
1053
  dlist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
1054
}
1055
1056
/*
1057
 * Register a new background worker from a regular backend.
1058
 *
1059
 * Returns true on success and false on failure.  Failure typically indicates
1060
 * that no background worker slots are currently available.
1061
 *
1062
 * If handle != NULL, we'll set *handle to a pointer that can subsequently
1063
 * be used as an argument to GetBackgroundWorkerPid().  The caller can
1064
 * free this pointer using pfree(), if desired.
1065
 */
1066
bool
1067
RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
1068
                BackgroundWorkerHandle **handle)
1069
0
{
1070
0
  int     slotno;
1071
0
  bool    success = false;
1072
0
  bool    parallel;
1073
0
  uint64    generation = 0;
1074
1075
  /*
1076
   * We can't register dynamic background workers from the postmaster. If
1077
   * this is a standalone backend, we're the only process and can't start
1078
   * any more.  In a multi-process environment, it might be theoretically
1079
   * possible, but we don't currently support it due to locking
1080
   * considerations; see comments on the BackgroundWorkerSlot data
1081
   * structure.
1082
   */
1083
0
  if (!IsUnderPostmaster)
1084
0
    return false;
1085
1086
0
  if (!SanityCheckBackgroundWorker(worker, ERROR))
1087
0
    return false;
1088
1089
0
  parallel = (worker->bgw_flags & BGWORKER_CLASS_PARALLEL) != 0;
1090
1091
0
  LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
1092
1093
  /*
1094
   * If this is a parallel worker, check whether there are already too many
1095
   * parallel workers; if so, don't register another one.  Our view of
1096
   * parallel_terminate_count may be slightly stale, but that doesn't really
1097
   * matter: we would have gotten the same result if we'd arrived here
1098
   * slightly earlier anyway.  There's no help for it, either, since the
1099
   * postmaster must not take locks; a memory barrier wouldn't guarantee
1100
   * anything useful.
1101
   */
1102
0
  if (parallel && (BackgroundWorkerData->parallel_register_count -
1103
0
           BackgroundWorkerData->parallel_terminate_count) >=
1104
0
    max_parallel_workers)
1105
0
  {
1106
0
    Assert(BackgroundWorkerData->parallel_register_count -
1107
0
         BackgroundWorkerData->parallel_terminate_count <=
1108
0
         MAX_PARALLEL_WORKER_LIMIT);
1109
0
    LWLockRelease(BackgroundWorkerLock);
1110
0
    return false;
1111
0
  }
1112
1113
  /*
1114
   * Look for an unused slot.  If we find one, grab it.
1115
   */
1116
0
  for (slotno = 0; slotno < BackgroundWorkerData->total_slots; ++slotno)
1117
0
  {
1118
0
    BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
1119
1120
0
    if (!slot->in_use)
1121
0
    {
1122
0
      memcpy(&slot->worker, worker, sizeof(BackgroundWorker));
1123
0
      slot->pid = InvalidPid; /* indicates not started yet */
1124
0
      slot->generation++;
1125
0
      slot->terminate = false;
1126
0
      generation = slot->generation;
1127
0
      if (parallel)
1128
0
        BackgroundWorkerData->parallel_register_count++;
1129
1130
      /*
1131
       * Make sure postmaster doesn't see the slot as in use before it
1132
       * sees the new contents.
1133
       */
1134
0
      pg_write_barrier();
1135
1136
0
      slot->in_use = true;
1137
0
      success = true;
1138
0
      break;
1139
0
    }
1140
0
  }
1141
1142
0
  LWLockRelease(BackgroundWorkerLock);
1143
1144
  /* If we found a slot, tell the postmaster to notice the change. */
1145
0
  if (success)
1146
0
    SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE);
1147
1148
  /*
1149
   * If we found a slot and the user has provided a handle, initialize it.
1150
   */
1151
0
  if (success && handle)
1152
0
  {
1153
0
    *handle = palloc_object(BackgroundWorkerHandle);
1154
0
    (*handle)->slot = slotno;
1155
0
    (*handle)->generation = generation;
1156
0
  }
1157
1158
0
  return success;
1159
0
}
1160
1161
/*
1162
 * Get the PID of a dynamically-registered background worker.
1163
 *
1164
 * If the worker is determined to be running, the return value will be
1165
 * BGWH_STARTED and *pidp will get the PID of the worker process.  If the
1166
 * postmaster has not yet attempted to start the worker, the return value will
1167
 * be BGWH_NOT_YET_STARTED.  Otherwise, the return value is BGWH_STOPPED.
1168
 *
1169
 * BGWH_STOPPED can indicate either that the worker is temporarily stopped
1170
 * (because it is configured for automatic restart and exited non-zero),
1171
 * or that the worker is permanently stopped (because it exited with exit
1172
 * code 0, or was not configured for automatic restart), or even that the
1173
 * worker was unregistered without ever starting (either because startup
1174
 * failed and the worker is not configured for automatic restart, or because
1175
 * TerminateBackgroundWorker was used before the worker was successfully
1176
 * started).
1177
 */
1178
BgwHandleStatus
1179
GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp)
1180
0
{
1181
0
  BackgroundWorkerSlot *slot;
1182
0
  pid_t   pid;
1183
1184
0
  Assert(handle->slot < max_worker_processes);
1185
0
  slot = &BackgroundWorkerData->slot[handle->slot];
1186
1187
  /*
1188
   * We could probably arrange to synchronize access to data using memory
1189
   * barriers only, but for now, let's just keep it simple and grab the
1190
   * lock.  It seems unlikely that there will be enough traffic here to
1191
   * result in meaningful contention.
1192
   */
1193
0
  LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
1194
1195
  /*
1196
   * The generation number can't be concurrently changed while we hold the
1197
   * lock.  The pid, which is updated by the postmaster, can change at any
1198
   * time, but we assume such changes are atomic.  So the value we read
1199
   * won't be garbage, but it might be out of date by the time the caller
1200
   * examines it (but that's unavoidable anyway).
1201
   *
1202
   * The in_use flag could be in the process of changing from true to false,
1203
   * but if it is already false then it can't change further.
1204
   */
1205
0
  if (handle->generation != slot->generation || !slot->in_use)
1206
0
    pid = 0;
1207
0
  else
1208
0
    pid = slot->pid;
1209
1210
  /* All done. */
1211
0
  LWLockRelease(BackgroundWorkerLock);
1212
1213
0
  if (pid == 0)
1214
0
    return BGWH_STOPPED;
1215
0
  else if (pid == InvalidPid)
1216
0
    return BGWH_NOT_YET_STARTED;
1217
0
  *pidp = pid;
1218
0
  return BGWH_STARTED;
1219
0
}
1220
1221
/*
1222
 * Wait for a background worker to start up.
1223
 *
1224
 * This is like GetBackgroundWorkerPid(), except that if the worker has not
1225
 * yet started, we wait for it to do so; thus, BGWH_NOT_YET_STARTED is never
1226
 * returned.  However, if the postmaster has died, we give up and return
1227
 * BGWH_POSTMASTER_DIED, since it that case we know that startup will not
1228
 * take place.
1229
 *
1230
 * The caller *must* have set our PID as the worker's bgw_notify_pid,
1231
 * else we will not be awoken promptly when the worker's state changes.
1232
 */
1233
BgwHandleStatus
1234
WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp)
1235
0
{
1236
0
  BgwHandleStatus status;
1237
0
  int     rc;
1238
1239
0
  for (;;)
1240
0
  {
1241
0
    pid_t   pid;
1242
1243
0
    CHECK_FOR_INTERRUPTS();
1244
1245
0
    status = GetBackgroundWorkerPid(handle, &pid);
1246
0
    if (status == BGWH_STARTED)
1247
0
      *pidp = pid;
1248
0
    if (status != BGWH_NOT_YET_STARTED)
1249
0
      break;
1250
1251
0
    rc = WaitLatch(MyLatch,
1252
0
             WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
1253
0
             WAIT_EVENT_BGWORKER_STARTUP);
1254
1255
0
    if (rc & WL_POSTMASTER_DEATH)
1256
0
    {
1257
0
      status = BGWH_POSTMASTER_DIED;
1258
0
      break;
1259
0
    }
1260
1261
0
    ResetLatch(MyLatch);
1262
0
  }
1263
1264
0
  return status;
1265
0
}
1266
1267
/*
1268
 * Wait for a background worker to stop.
1269
 *
1270
 * If the worker hasn't yet started, or is running, we wait for it to stop
1271
 * and then return BGWH_STOPPED.  However, if the postmaster has died, we give
1272
 * up and return BGWH_POSTMASTER_DIED, because it's the postmaster that
1273
 * notifies us when a worker's state changes.
1274
 *
1275
 * The caller *must* have set our PID as the worker's bgw_notify_pid,
1276
 * else we will not be awoken promptly when the worker's state changes.
1277
 */
1278
BgwHandleStatus
1279
WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle)
1280
0
{
1281
0
  BgwHandleStatus status;
1282
0
  int     rc;
1283
1284
0
  for (;;)
1285
0
  {
1286
0
    pid_t   pid;
1287
1288
0
    CHECK_FOR_INTERRUPTS();
1289
1290
0
    status = GetBackgroundWorkerPid(handle, &pid);
1291
0
    if (status == BGWH_STOPPED)
1292
0
      break;
1293
1294
0
    rc = WaitLatch(MyLatch,
1295
0
             WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
1296
0
             WAIT_EVENT_BGWORKER_SHUTDOWN);
1297
1298
0
    if (rc & WL_POSTMASTER_DEATH)
1299
0
    {
1300
0
      status = BGWH_POSTMASTER_DIED;
1301
0
      break;
1302
0
    }
1303
1304
0
    ResetLatch(MyLatch);
1305
0
  }
1306
1307
0
  return status;
1308
0
}
1309
1310
/*
1311
 * Instruct the postmaster to terminate a background worker.
1312
 *
1313
 * Note that it's safe to do this without regard to whether the worker is
1314
 * still running, or even if the worker may already have exited and been
1315
 * unregistered.
1316
 */
1317
void
1318
TerminateBackgroundWorker(BackgroundWorkerHandle *handle)
1319
0
{
1320
0
  BackgroundWorkerSlot *slot;
1321
0
  bool    signal_postmaster = false;
1322
1323
0
  Assert(handle->slot < max_worker_processes);
1324
0
  slot = &BackgroundWorkerData->slot[handle->slot];
1325
1326
  /* Set terminate flag in shared memory, unless slot has been reused. */
1327
0
  LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
1328
0
  if (handle->generation == slot->generation)
1329
0
  {
1330
0
    slot->terminate = true;
1331
0
    signal_postmaster = true;
1332
0
  }
1333
0
  LWLockRelease(BackgroundWorkerLock);
1334
1335
  /* Make sure the postmaster notices the change to shared memory. */
1336
0
  if (signal_postmaster)
1337
0
    SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE);
1338
0
}
1339
1340
/*
1341
 * Look up (and possibly load) a bgworker entry point function.
1342
 *
1343
 * For functions contained in the core code, we use library name "postgres"
1344
 * and consult the InternalBGWorkers array.  External functions are
1345
 * looked up, and loaded if necessary, using load_external_function().
1346
 *
1347
 * The point of this is to pass function names as strings across process
1348
 * boundaries.  We can't pass actual function addresses because of the
1349
 * possibility that the function has been loaded at a different address
1350
 * in a different process.  This is obviously a hazard for functions in
1351
 * loadable libraries, but it can happen even for functions in the core code
1352
 * on platforms using EXEC_BACKEND (e.g., Windows).
1353
 *
1354
 * At some point it might be worthwhile to get rid of InternalBGWorkers[]
1355
 * in favor of applying load_external_function() for core functions too;
1356
 * but that raises portability issues that are not worth addressing now.
1357
 */
1358
static bgworker_main_type
1359
LookupBackgroundWorkerFunction(const char *libraryname, const char *funcname)
1360
0
{
1361
  /*
1362
   * If the function is to be loaded from postgres itself, search the
1363
   * InternalBGWorkers array.
1364
   */
1365
0
  if (strcmp(libraryname, "postgres") == 0)
1366
0
  {
1367
0
    for (size_t i = 0; i < lengthof(InternalBGWorkers); i++)
1368
0
    {
1369
0
      if (strcmp(InternalBGWorkers[i].fn_name, funcname) == 0)
1370
0
        return InternalBGWorkers[i].fn_addr;
1371
0
    }
1372
1373
    /* We can only reach this by programming error. */
1374
0
    elog(ERROR, "internal function \"%s\" not found", funcname);
1375
0
  }
1376
1377
  /* Otherwise load from external library. */
1378
0
  return (bgworker_main_type)
1379
0
    load_external_function(libraryname, funcname, true, NULL);
1380
0
}
1381
1382
/*
1383
 * Given a PID, get the bgw_type of the background worker.  Returns NULL if
1384
 * not a valid background worker.
1385
 *
1386
 * The return value is in static memory belonging to this function, so it has
1387
 * to be used before calling this function again.  This is so that the caller
1388
 * doesn't have to worry about the background worker locking protocol.
1389
 */
1390
const char *
1391
GetBackgroundWorkerTypeByPid(pid_t pid)
1392
0
{
1393
0
  int     slotno;
1394
0
  bool    found = false;
1395
0
  static char result[BGW_MAXLEN];
1396
1397
0
  LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
1398
1399
0
  for (slotno = 0; slotno < BackgroundWorkerData->total_slots; slotno++)
1400
0
  {
1401
0
    BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
1402
1403
0
    if (slot->pid > 0 && slot->pid == pid)
1404
0
    {
1405
0
      strcpy(result, slot->worker.bgw_type);
1406
0
      found = true;
1407
0
      break;
1408
0
    }
1409
0
  }
1410
1411
0
  LWLockRelease(BackgroundWorkerLock);
1412
1413
0
  if (!found)
1414
0
    return NULL;
1415
1416
0
  return result;
1417
0
}
1418
1419
/*
1420
 * Terminate all background workers connected to the given database, if the
1421
 * workers can be interrupted.  The workers are signaled directly, so that
1422
 * they can be restarted based on their bgw_restart_time.
1423
 */
1424
void
1425
TerminateBackgroundWorkersForDatabase(Oid databaseId)
1426
{
1427
  pid_t    *pids;
1428
  int     npids = 0;
1429
1430
  elog(DEBUG1, "attempting worker termination for database %u",
1431
     databaseId);
1432
1433
  pids = palloc_array(pid_t, BackgroundWorkerData->total_slots);
1434
1435
  LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
1436
1437
  /*
1438
   * Iterate through slots, looking for workers connected to the given
1439
   * database.
1440
   */
1441
  for (int slotno = 0; slotno < BackgroundWorkerData->total_slots; slotno++)
1442
  {
1443
    BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
1444
1445
    if (slot->in_use &&
1446
      (slot->worker.bgw_flags & BGWORKER_INTERRUPTIBLE))
1447
    {
1448
      PGPROC     *proc;
1449
      pid_t   pid = slot->pid;
1450
1451
      LWLockAcquire(ProcArrayLock, LW_SHARED);
1452
      proc = BackendPidGetProcWithLock(pid);
1453
      if (proc && proc->databaseId == databaseId)
1454
        pids[npids++] = pid;
1455
      LWLockRelease(ProcArrayLock);
1456
    }
1457
  }
1458
1459
  LWLockRelease(BackgroundWorkerLock);
1460
1461
  /*
1462
   * Signal the workers, avoiding kill() while holding the locks.
1463
   */
1464
  for (int i = 0; i < npids; i++)
1465
  {
1466
    elog(DEBUG1, "termination requested for worker (PID %d) on database %u",
1467
       (int) pids[i], databaseId);
1468
    (void) kill(pids[i], SIGTERM);  /* ignore any error */
1469
  }
1470
1471
  pfree(pids);
1472
}