PostgreSQL Source Code git master
Loading...
Searching...
No Matches
datachecksum_state.h File Reference
Include dependency graph for datachecksum_state.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef enum DataChecksumsWorkerOperation DataChecksumsWorkerOperation
 

Enumerations

enum  DataChecksumsWorkerOperation { ENABLE_DATACHECKSUMS , DISABLE_DATACHECKSUMS }
 
enum  DataChecksumsWorkerResult { DATACHECKSUMSWORKER_SUCCESSFUL = 0 , DATACHECKSUMSWORKER_ABORTED , DATACHECKSUMSWORKER_FAILED , DATACHECKSUMSWORKER_DROPDB }
 

Functions

bool AbsorbDataChecksumsBarrier (ProcSignalBarrierType target_state)
 
void EmitAndWaitDataChecksumsBarrier (uint32 state)
 
void StartDataChecksumsWorkerLauncher (DataChecksumsWorkerOperation op, int cost_delay, int cost_limit)
 
void DataChecksumsWorkerLauncherMain (Datum arg)
 
void DataChecksumsWorkerMain (Datum arg)
 

Typedef Documentation

◆ DataChecksumsWorkerOperation

Enumeration Type Documentation

◆ DataChecksumsWorkerOperation

Enumerator
ENABLE_DATACHECKSUMS 
DISABLE_DATACHECKSUMS 

Definition at line 21 of file datachecksum_state.h.

◆ DataChecksumsWorkerResult

Enumerator
DATACHECKSUMSWORKER_SUCCESSFUL 
DATACHECKSUMSWORKER_ABORTED 
DATACHECKSUMSWORKER_FAILED 
DATACHECKSUMSWORKER_DROPDB 

Definition at line 31 of file datachecksum_state.h.

Function Documentation

◆ AbsorbDataChecksumsBarrier()

bool AbsorbDataChecksumsBarrier ( ProcSignalBarrierType  target_state)

Definition at line 411 of file datachecksum_state.c.

412{
414 int current = data_checksums;
415 bool found = false;
416
417 /*
418 * Translate the barrier condition to the target state, doing it here
419 * instead of in the procsignal code saves the latter from knowing about
420 * checksum states.
421 */
422 switch (barrier)
423 {
426 break;
429 break;
432 break;
435 break;
436 default:
437 elog(ERROR, "incorrect barrier \"%i\" received", barrier);
438 }
439
440 /*
441 * If the target state matches the current state then the barrier has been
442 * repeated.
443 */
444 if (current == target_state)
445 return true;
446
447 /*
448 * If the cluster is in recovery we skip the validation of current state
449 * since the replay is trusted.
450 */
451 if (RecoveryInProgress())
452 {
454 return true;
455 }
456
457 /*
458 * Find the barrier condition definition for the target state. Not finding
459 * a condition would be a grave programmer error as the states are a
460 * discrete set.
461 */
462 for (int i = 0; i < lengthof(checksum_barriers) && !found; i++)
463 {
464 if (checksum_barriers[i].from == current && checksum_barriers[i].to == target_state)
465 found = true;
466 }
467
468 /*
469 * If the relevant state criteria aren't satisfied, throw an error which
470 * will be caught by the procsignal machinery for a later retry.
471 */
472 if (!found)
475 errmsg("incorrect data checksum state %i for target state %i",
476 current, target_state));
477
479 return true;
480}
uint32_t uint32
Definition c.h:624
#define lengthof(array)
Definition c.h:873
@ PG_DATA_CHECKSUM_VERSION
Definition checksum.h:29
@ PG_DATA_CHECKSUM_INPROGRESS_OFF
Definition checksum.h:30
@ PG_DATA_CHECKSUM_INPROGRESS_ON
Definition checksum.h:31
@ PG_DATA_CHECKSUM_OFF
Definition checksum.h:28
static const ChecksumBarrierCondition checksum_barriers[6]
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:227
#define ereport(elevel,...)
Definition elog.h:151
int i
Definition isn.c:77
static char * errmsg
static THREAD_BARRIER_T barrier
Definition pgbench.c:488
static int fb(int x)
@ PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_OFF
Definition procsignal.h:53
@ PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_ON
Definition procsignal.h:52
@ PROCSIGNAL_BARRIER_CHECKSUM_ON
Definition procsignal.h:54
@ PROCSIGNAL_BARRIER_CHECKSUM_OFF
Definition procsignal.h:51
bool RecoveryInProgress(void)
Definition xlog.c:6830
void SetLocalDataChecksumState(uint32 data_checksum_version)
Definition xlog.c:4969
int data_checksums
Definition xlog.c:683

References barrier, checksum_barriers, data_checksums, elog, ereport, errcode(), errmsg, ERROR, fb(), i, lengthof, PG_DATA_CHECKSUM_INPROGRESS_OFF, PG_DATA_CHECKSUM_INPROGRESS_ON, PG_DATA_CHECKSUM_OFF, PG_DATA_CHECKSUM_VERSION, PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_OFF, PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_ON, PROCSIGNAL_BARRIER_CHECKSUM_OFF, PROCSIGNAL_BARRIER_CHECKSUM_ON, RecoveryInProgress(), and SetLocalDataChecksumState().

Referenced by ProcessProcSignalBarrier().

◆ DataChecksumsWorkerLauncherMain()

void DataChecksumsWorkerLauncherMain ( Datum  arg)

Definition at line 1013 of file datachecksum_state.c.

1014{
1016
1018 errmsg("background worker \"datachecksums launcher\" started"));
1019
1024
1026
1029
1030 INJECTION_POINT("datachecksumsworker-launcher-delay", NULL);
1031
1033
1035 {
1036 ereport(LOG,
1037 errmsg("background worker \"datachecksums launcher\" already running, exiting"));
1038 /* Launcher was already running, let it finish */
1040 return;
1041 }
1042
1043 launcher_running = true;
1044
1045 /* Initialize a connection to shared catalogs only */
1047
1054
1055 /*
1056 * The target state can change while we are busy enabling/disabling
1057 * checksums, if the user calls pg_disable/enable_data_checksums() before
1058 * we are finished with the previous request. In that case, we will loop
1059 * back here, to process the new request.
1060 */
1061again:
1062
1064 InvalidOid);
1065
1067 {
1068 /*
1069 * If we are asked to enable checksums in a cluster which already has
1070 * checksums enabled, exit immediately as there is nothing more to do.
1071 */
1073 goto done;
1074
1075 ereport(LOG,
1076 errmsg("enabling data checksums requested, starting data checksum calculation"));
1077
1078 /*
1079 * Set the state to inprogress-on and wait on the procsignal barrier.
1080 */
1084
1085 /*
1086 * All backends are now in inprogress-on state and are writing data
1087 * checksums. Start processing all data at rest.
1088 */
1089 if (!ProcessAllDatabases())
1090 {
1091 /*
1092 * If the target state changed during processing then it's not a
1093 * failure, so restart processing instead.
1094 */
1097 {
1099 goto done;
1100 }
1102 ereport(ERROR,
1104 errmsg("unable to enable data checksums in cluster"));
1105 }
1106
1107 /*
1108 * Data checksums have been set on all pages, set the state to on in
1109 * order to instruct backends to validate checksums on reading.
1110 */
1112
1113 ereport(LOG,
1114 errmsg("data checksums are now enabled"));
1115 }
1116 else if (operation == DISABLE_DATACHECKSUMS)
1117 {
1118 ereport(LOG,
1119 errmsg("disabling data checksums requested"));
1120
1124 ereport(LOG,
1125 errmsg("data checksums are now disabled"));
1126 }
1127 else
1128 Assert(false);
1129
1130done:
1131
1132 /*
1133 * This state will only be displayed for a fleeting moment, but for the
1134 * sake of correctness it is still added before ending the command.
1135 */
1138
1139 /*
1140 * All done. But before we exit, check if the target state was changed
1141 * while we were running. In that case we will have to start all over
1142 * again.
1143 */
1146 {
1152 goto again;
1153 }
1154
1155 /* Shut down progress reporting as we are done */
1157
1158 launcher_running = false;
1161}
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_end_command(void)
@ PROGRESS_COMMAND_DATACHECKSUMS
void BackgroundWorkerUnblockSignals(void)
Definition bgworker.c:944
void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags)
Definition bgworker.c:904
#define Assert(condition)
Definition c.h:943
static DataChecksumsStateStruct * DataChecksumState
static volatile sig_atomic_t launcher_running
static DataChecksumsWorkerOperation operation
static void launcher_cancel_handler(SIGNAL_ARGS)
static bool ProcessAllDatabases(void)
static void launcher_exit(int code, Datum arg)
#define LOG
Definition elog.h:31
#define DEBUG1
Definition elog.h:30
#define INJECTION_POINT(name, arg)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:372
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
@ LW_EXCLUSIVE
Definition lwlock.h:104
@ B_DATACHECKSUMSWORKER_LAUNCHER
Definition miscadmin.h:370
BackendType MyBackendType
Definition miscinit.c:65
#define die(msg)
#define pqsignal
Definition port.h:547
#define InvalidOid
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition procsignal.c:686
#define PROGRESS_DATACHECKSUMS_PHASE_DONE
Definition progress.h:202
#define PROGRESS_DATACHECKSUMS_PHASE
Definition progress.h:189
#define PROGRESS_DATACHECKSUMS_PHASE_ENABLING
Definition progress.h:198
#define PROGRESS_DATACHECKSUMS_PHASE_DISABLING
Definition progress.h:199
void init_ps_display(const char *fixed_part)
Definition ps_status.c:286
DataChecksumsWorkerOperation launch_operation
DataChecksumsWorkerOperation operation
#define SIGUSR1
Definition win32_port.h:170
#define SIGUSR2
Definition win32_port.h:171
void SetDataChecksumsOff(void)
Definition xlog.c:4858
bool DataChecksumsNeedVerify(void)
Definition xlog.c:4706
void SetDataChecksumsOn(void)
Definition xlog.c:4786
void SetDataChecksumsOnInProgress(void)
Definition xlog.c:4722

References Assert, B_DATACHECKSUMSWORKER_LAUNCHER, BackgroundWorkerInitializeConnectionByOid(), BackgroundWorkerUnblockSignals(), DataChecksumsStateStruct::cost_delay, DataChecksumsStateStruct::cost_limit, DataChecksumsNeedVerify(), DataChecksumState, DEBUG1, die, DISABLE_DATACHECKSUMS, ENABLE_DATACHECKSUMS, ereport, errcode(), errmsg, ERROR, fb(), init_ps_display(), INJECTION_POINT, InvalidOid, DataChecksumsStateStruct::launch_cost_delay, DataChecksumsStateStruct::launch_cost_limit, DataChecksumsStateStruct::launch_operation, launcher_cancel_handler(), launcher_exit(), DataChecksumsStateStruct::launcher_running, launcher_running, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyBackendType, on_shmem_exit(), DataChecksumsStateStruct::operation, operation, pgstat_progress_end_command(), pgstat_progress_start_command(), pgstat_progress_update_param(), pqsignal, ProcessAllDatabases(), procsignal_sigusr1_handler(), PROGRESS_COMMAND_DATACHECKSUMS, PROGRESS_DATACHECKSUMS_PHASE, PROGRESS_DATACHECKSUMS_PHASE_DISABLING, PROGRESS_DATACHECKSUMS_PHASE_DONE, PROGRESS_DATACHECKSUMS_PHASE_ENABLING, SetDataChecksumsOff(), SetDataChecksumsOn(), SetDataChecksumsOnInProgress(), SIGUSR1, and SIGUSR2.

◆ DataChecksumsWorkerMain()

void DataChecksumsWorkerMain ( Datum  arg)

Definition at line 1453 of file datachecksum_state.c.

1454{
1455 Oid dboid = DatumGetObjectId(arg);
1458 BufferAccessStrategy strategy;
1459 bool aborted = false;
1461#ifdef USE_INJECTION_POINTS
1462 bool retried = false;
1463#endif
1464
1466
1469
1471
1474
1477
1478 /* worker will have a separate entry in pg_stat_progress_data_checksums */
1480 InvalidOid);
1481
1482 /*
1483 * Get a list of all temp tables present as we start in this database. We
1484 * need to wait until they are all gone until we are done, since we cannot
1485 * access these relations and modify them.
1486 */
1488
1489 /*
1490 * Enable vacuum cost delay, if any. While this process isn't doing any
1491 * vacuuming, we are re-using the infrastructure that vacuum cost delay
1492 * provides rather than inventing something bespoke. This is an internal
1493 * implementation detail and care should be taken to avoid it bleeding
1494 * through to the user to avoid confusion.
1495 */
1504
1505 /*
1506 * Create and set the vacuum strategy as our buffer strategy.
1507 */
1508 strategy = GetAccessStrategy(BAS_VACUUM);
1509
1512
1513 /* Update the total number of relations to be processed in this DB. */
1514 {
1515 const int index[] = {
1518 };
1519
1520 int64 vals[2];
1521
1522 vals[0] = list_length(RelationList);
1523 vals[1] = 0;
1524
1526 }
1527
1528 /* Process the relations */
1529 rels_done = 0;
1530 foreach_oid(reloid, RelationList)
1531 {
1533
1534 if (!ProcessSingleRelationByOid(reloid, strategy))
1535 {
1536 aborted = true;
1537 break;
1538 }
1539
1541 ++rels_done);
1542 }
1544
1545 if (aborted)
1546 {
1549 errmsg("data checksum processing aborted in database OID %u",
1550 dboid));
1551 return;
1552 }
1553
1554 /* The worker is about to wait for temporary tables to go away. */
1557
1558 /*
1559 * Wait for all temp tables that existed when we started to go away. This
1560 * is necessary since we cannot "reach" them to enable checksums. Any temp
1561 * tables created after we started will already have checksums in them
1562 * (due to the "inprogress-on" state), so no need to wait for those.
1563 */
1564 for (;;)
1565 {
1567 int numleft;
1568 char activity[64];
1569
1570 CurrentTempTables = BuildRelationList(true, false);
1571 numleft = 0;
1573 {
1575 numleft++;
1576 }
1578
1579#ifdef USE_INJECTION_POINTS
1580 if (IS_INJECTION_POINT_ATTACHED("datachecksumsworker-fake-temptable-wait"))
1581 {
1582 /* Make sure to just cause one retry */
1583 if (!retried && numleft == 0)
1584 {
1585 numleft = 1;
1586 retried = true;
1587
1588 INJECTION_POINT_CACHED("datachecksumsworker-fake-temptable-wait", NULL);
1589 }
1590 }
1591#endif
1592
1593 if (numleft == 0)
1594 break;
1595
1596 /*
1597 * At least one temp table is left to wait for, indicate in pgstat
1598 * activity and progress reporting.
1599 */
1601 sizeof(activity),
1602 "Waiting for %d temp tables to be removed", numleft);
1604
1605 /* Retry every 3 seconds */
1609 3000,
1611
1615
1617
1618 if (aborted || abort_requested)
1619 {
1621 ereport(LOG,
1622 errmsg("data checksum processing aborted in database OID %u",
1623 dboid));
1624 return;
1625 }
1626 }
1627
1629
1630 /* worker done */
1632
1636}
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_report_activity(BackendState state, const char *cmd_str)
@ STATE_RUNNING
#define BGWORKER_BYPASS_ALLOWCONN
Definition bgworker.h:166
@ BAS_VACUUM
Definition bufmgr.h:40
int64_t int64
Definition c.h:621
static volatile sig_atomic_t abort_requested
static bool ProcessSingleRelationByOid(Oid relationId, BufferAccessStrategy strategy)
static List * BuildRelationList(bool temp_relations, bool include_shared)
Datum arg
Definition elog.c:1322
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition freelist.c:426
int VacuumCostLimit
Definition globals.c:154
int VacuumCostPageMiss
Definition globals.c:152
bool VacuumCostActive
Definition globals.c:158
int VacuumCostBalance
Definition globals.c:157
int VacuumCostPageDirty
Definition globals.c:153
int VacuumCostPageHit
Definition globals.c:151
struct Latch * MyLatch
Definition globals.c:63
double VacuumCostDelay
Definition globals.c:155
#define IS_INJECTION_POINT_ATTACHED(name)
#define INJECTION_POINT_CACHED(name, arg)
void ResetLatch(Latch *latch)
Definition latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition latch.c:172
void list_free(List *list)
Definition list.c:1546
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
@ B_DATACHECKSUMSWORKER_WORKER
Definition miscadmin.h:371
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define foreach_oid(var, lst)
Definition pg_list.h:503
#define snprintf
Definition port.h:260
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
unsigned int Oid
#define PROGRESS_DATACHECKSUMS_RELS_TOTAL
Definition progress.h:192
#define PROGRESS_DATACHECKSUMS_PHASE_WAITING_TEMPREL
Definition progress.h:200
#define PROGRESS_DATACHECKSUMS_RELS_DONE
Definition progress.h:193
DataChecksumsWorkerResult success
Definition pg_list.h:54
Definition type.h:96
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET

References abort_requested, arg, Assert, B_DATACHECKSUMSWORKER_WORKER, BackgroundWorkerInitializeConnectionByOid(), BackgroundWorkerUnblockSignals(), BAS_VACUUM, BGWORKER_BYPASS_ALLOWCONN, BuildRelationList(), CHECK_FOR_INTERRUPTS, DataChecksumsStateStruct::cost_delay, DataChecksumsStateStruct::cost_limit, DataChecksumState, DATACHECKSUMSWORKER_ABORTED, DATACHECKSUMSWORKER_SUCCESSFUL, DatumGetObjectId(), DEBUG1, die, ENABLE_DATACHECKSUMS, ereport, errmsg, fb(), foreach_oid, GetAccessStrategy(), init_ps_display(), INJECTION_POINT_CACHED, InvalidOid, IS_INJECTION_POINT_ATTACHED, DataChecksumsStateStruct::launch_operation, list_free(), list_length(), list_member_oid(), LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyBackendType, MyLatch, NIL, DataChecksumsStateStruct::operation, operation, pgstat_progress_end_command(), pgstat_progress_start_command(), pgstat_progress_update_multi_param(), pgstat_progress_update_param(), pgstat_report_activity(), pqsignal, DataChecksumsStateStruct::process_shared_catalogs, ProcessSingleRelationByOid(), procsignal_sigusr1_handler(), PROGRESS_COMMAND_DATACHECKSUMS, PROGRESS_DATACHECKSUMS_PHASE, PROGRESS_DATACHECKSUMS_PHASE_WAITING_TEMPREL, PROGRESS_DATACHECKSUMS_RELS_DONE, PROGRESS_DATACHECKSUMS_RELS_TOTAL, ResetLatch(), SIGUSR1, snprintf, STATE_RUNNING, DataChecksumsStateStruct::success, VacuumCostActive, VacuumCostBalance, VacuumCostDelay, VacuumCostLimit, VacuumCostPageDirty, VacuumCostPageHit, VacuumCostPageMiss, WaitLatch(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_TIMEOUT.

◆ EmitAndWaitDataChecksumsBarrier()

void EmitAndWaitDataChecksumsBarrier ( uint32  state)

◆ StartDataChecksumsWorkerLauncher()

void StartDataChecksumsWorkerLauncher ( DataChecksumsWorkerOperation  op,
int  cost_delay,
int  cost_limit 
)

Definition at line 543 of file datachecksum_state.c.

546{
549 bool launcher_running;
551
552#ifdef USE_ASSERT_CHECKING
553 /* The cost delay settings have no effect when disabling */
554 if (op == DISABLE_DATACHECKSUMS)
555 Assert(cost_delay == 0 && cost_limit == 0);
556#endif
557
558 INJECTION_POINT("datachecksumsworker-startup-delay", NULL);
559
560 /* Store the desired state in shared memory */
562
566
567 /* Is the launcher already running? If so, what is it doing? */
571
573
574 /*
575 * Launch a new launcher process, if it's not running already.
576 *
577 * If the launcher is currently busy enabling the checksums, and we want
578 * them disabled (or vice versa), the launcher will notice that at latest
579 * when it's about to exit, and will loop back process the new request. So
580 * if the launcher is already running, we don't need to do anything more
581 * here to abort it.
582 *
583 * If you call pg_enable/disable_data_checksums() twice in a row, before
584 * the launcher has had a chance to start up, we still end up launching it
585 * twice. That's OK, the second invocation will see that a launcher is
586 * already running and exit quickly.
587 *
588 * TODO: We could optimize here and skip launching the launcher, if we are
589 * already in the desired state, i.e. if the checksums are already enabled
590 * and you call pg_enable_data_checksums().
591 */
592 if (!launcher_running)
593 {
594 /*
595 * Prepare the BackgroundWorker and launch it.
596 */
597 memset(&bgw, 0, sizeof(bgw));
599 bgw.bgw_start_time = BgWorkerStart_RecoveryFinished;
600 snprintf(bgw.bgw_library_name, BGW_MAXLEN, "postgres");
601 snprintf(bgw.bgw_function_name, BGW_MAXLEN, "DataChecksumsWorkerLauncherMain");
602 snprintf(bgw.bgw_name, BGW_MAXLEN, "datachecksum launcher");
603 snprintf(bgw.bgw_type, BGW_MAXLEN, "datachecksum launcher");
604 bgw.bgw_restart_time = BGW_NEVER_RESTART;
605 bgw.bgw_notify_pid = MyProcPid;
606 bgw.bgw_main_arg = (Datum) 0;
607
611 errmsg("failed to start background worker to process data checksums"));
612 }
613 else
614 {
615 if (launcher_running_op == op)
617 errmsg("data checksum processing already running"));
618 }
619}
bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker, BackgroundWorkerHandle **handle)
Definition bgworker.c:1063
#define BGW_NEVER_RESTART
Definition bgworker.h:92
@ BgWorkerStart_RecoveryFinished
Definition bgworker.h:88
#define BGWORKER_BACKEND_DATABASE_CONNECTION
Definition bgworker.h:60
#define BGWORKER_SHMEM_ACCESS
Definition bgworker.h:53
#define BGW_MAXLEN
Definition bgworker.h:93
int MyProcPid
Definition globals.c:47
uint64_t Datum
Definition postgres.h:70

References Assert, BGW_MAXLEN, BGW_NEVER_RESTART, BGWORKER_BACKEND_DATABASE_CONNECTION, BGWORKER_SHMEM_ACCESS, BgWorkerStart_RecoveryFinished, DataChecksumState, DISABLE_DATACHECKSUMS, ereport, errcode(), errmsg, ERROR, fb(), INJECTION_POINT, DataChecksumsStateStruct::launch_cost_delay, DataChecksumsStateStruct::launch_cost_limit, DataChecksumsStateStruct::launch_operation, DataChecksumsStateStruct::launcher_running, launcher_running, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProcPid, DataChecksumsStateStruct::operation, RegisterDynamicBackgroundWorker(), and snprintf.

Referenced by disable_data_checksums(), and enable_data_checksums().