1 /*------------------------------------------------------------------------- 2 * 3 * miscadmin.h 4 * This file contains general postgres administration and initialization 5 * stuff that used to be spread out between the following files: 6 * globals.h global variables 7 * pdir.h directory path crud 8 * pinit.h postgres initialization 9 * pmod.h processing modes 10 * Over time, this has also become the preferred place for widely known 11 * resource-limitation stuff, such as work_mem and check_stack_depth(). 12 * 13 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group 14 * Portions Copyright (c) 1994, Regents of the University of California 15 * 16 * src/include/miscadmin.h 17 * 18 * NOTES 19 * some of the information in this file should be moved to other files. 20 * 21 *------------------------------------------------------------------------- 22 */ 23 #ifndef MISCADMIN_H 24 #define MISCADMIN_H 25 26 #include <signal.h> 27 28 #include "pgtime.h" /* for pg_time_t */ 29 30 31 #define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" 32 33 #define InvalidPid (-1) 34 35 36 /***************************************************************************** 37 * System interrupt and critical section handling 38 * 39 * There are two types of interrupts that a running backend needs to accept 40 * without messing up its state: QueryCancel (SIGINT) and ProcDie (SIGTERM). 41 * In both cases, we need to be able to clean up the current transaction 42 * gracefully, so we can't respond to the interrupt instantaneously --- 43 * there's no guarantee that internal data structures would be self-consistent 44 * if the code is interrupted at an arbitrary instant. Instead, the signal 45 * handlers set flags that are checked periodically during execution. 46 * 47 * The CHECK_FOR_INTERRUPTS() macro is called at strategically located spots 48 * where it is normally safe to accept a cancel or die interrupt. In some 49 * cases, we invoke CHECK_FOR_INTERRUPTS() inside low-level subroutines that 50 * might sometimes be called in contexts that do *not* want to allow a cancel 51 * or die interrupt. The HOLD_INTERRUPTS() and RESUME_INTERRUPTS() macros 52 * allow code to ensure that no cancel or die interrupt will be accepted, 53 * even if CHECK_FOR_INTERRUPTS() gets called in a subroutine. The interrupt 54 * will be held off until CHECK_FOR_INTERRUPTS() is done outside any 55 * HOLD_INTERRUPTS() ... RESUME_INTERRUPTS() section. 56 * 57 * There is also a mechanism to prevent query cancel interrupts, while still 58 * allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and 59 * RESUME_CANCEL_INTERRUPTS(). 60 * 61 * Note that ProcessInterrupts() has also acquired a number of tasks that 62 * do not necessarily cause a query-cancel-or-die response. Hence, it's 63 * possible that it will just clear InterruptPending and return. 64 * 65 * INTERRUPTS_PENDING_CONDITION() can be checked to see whether an 66 * interrupt needs to be serviced, without trying to do so immediately. 67 * Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(), 68 * which tells whether ProcessInterrupts is sure to clear the interrupt. 69 * 70 * Special mechanisms are used to let an interrupt be accepted when we are 71 * waiting for a lock or when we are waiting for command input (but, of 72 * course, only if the interrupt holdoff counter is zero). See the 73 * related code for details. 74 * 75 * A lost connection is handled similarly, although the loss of connection 76 * does not raise a signal, but is detected when we fail to write to the 77 * socket. If there was a signal for a broken connection, we could make use of 78 * it by setting ClientConnectionLost in the signal handler. 79 * 80 * A related, but conceptually distinct, mechanism is the "critical section" 81 * mechanism. A critical section not only holds off cancel/die interrupts, 82 * but causes any ereport(ERROR) or ereport(FATAL) to become ereport(PANIC) 83 * --- that is, a system-wide reset is forced. Needless to say, only really 84 * *critical* code should be marked as a critical section! Currently, this 85 * mechanism is only used for XLOG-related code. 86 * 87 *****************************************************************************/ 88 89 /* in globals.c */ 90 /* these are marked volatile because they are set by signal handlers: */ 91 extern PGDLLIMPORT volatile bool InterruptPending; 92 extern PGDLLIMPORT volatile bool QueryCancelPending; 93 extern PGDLLIMPORT volatile bool ProcDiePending; 94 extern PGDLLIMPORT volatile bool IdleInTransactionSessionTimeoutPending; 95 extern PGDLLIMPORT volatile sig_atomic_t ConfigReloadPending; 96 97 extern volatile bool ClientConnectionLost; 98 99 /* these are marked volatile because they are examined by signal handlers: */ 100 extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount; 101 extern PGDLLIMPORT volatile uint32 QueryCancelHoldoffCount; 102 extern PGDLLIMPORT volatile uint32 CritSectionCount; 103 104 /* in tcop/postgres.c */ 105 extern void ProcessInterrupts(void); 106 107 /* Test whether an interrupt is pending */ 108 #ifndef WIN32 109 #define INTERRUPTS_PENDING_CONDITION() \ 110 (InterruptPending) 111 #else 112 #define INTERRUPTS_PENDING_CONDITION() \ 113 (UNBLOCKED_SIGNAL_QUEUE() ? pgwin32_dispatch_queued_signals() : 0, \ 114 InterruptPending) 115 #endif 116 117 /* Service interrupt, if one is pending and it's safe to service it now */ 118 #define CHECK_FOR_INTERRUPTS() \ 119 do { \ 120 if (INTERRUPTS_PENDING_CONDITION()) \ 121 ProcessInterrupts(); \ 122 } while(0) 123 124 /* Is ProcessInterrupts() guaranteed to clear InterruptPending? */ 125 #define INTERRUPTS_CAN_BE_PROCESSED() \ 126 (InterruptHoldoffCount == 0 && CritSectionCount == 0 && \ 127 QueryCancelHoldoffCount == 0) 128 129 #define HOLD_INTERRUPTS() (InterruptHoldoffCount++) 130 131 #define RESUME_INTERRUPTS() \ 132 do { \ 133 Assert(InterruptHoldoffCount > 0); \ 134 InterruptHoldoffCount--; \ 135 } while(0) 136 137 #define HOLD_CANCEL_INTERRUPTS() (QueryCancelHoldoffCount++) 138 139 #define RESUME_CANCEL_INTERRUPTS() \ 140 do { \ 141 Assert(QueryCancelHoldoffCount > 0); \ 142 QueryCancelHoldoffCount--; \ 143 } while(0) 144 145 #define START_CRIT_SECTION() (CritSectionCount++) 146 147 #define END_CRIT_SECTION() \ 148 do { \ 149 Assert(CritSectionCount > 0); \ 150 CritSectionCount--; \ 151 } while(0) 152 153 154 /***************************************************************************** 155 * globals.h -- * 156 *****************************************************************************/ 157 158 /* 159 * from utils/init/globals.c 160 */ 161 extern PGDLLIMPORT pid_t PostmasterPid; 162 extern bool IsPostmasterEnvironment; 163 extern PGDLLIMPORT bool IsUnderPostmaster; 164 extern bool IsBackgroundWorker; 165 extern PGDLLIMPORT bool IsBinaryUpgrade; 166 167 extern PGDLLIMPORT bool ExitOnAnyError; 168 169 extern PGDLLIMPORT char *DataDir; 170 171 extern PGDLLIMPORT int NBuffers; 172 extern PGDLLIMPORT int MaxBackends; 173 extern PGDLLIMPORT int MaxConnections; 174 extern PGDLLIMPORT int max_worker_processes; 175 176 extern PGDLLIMPORT int MyProcPid; 177 extern PGDLLIMPORT pg_time_t MyStartTime; 178 extern PGDLLIMPORT struct Port *MyProcPort; 179 extern PGDLLIMPORT struct Latch *MyLatch; 180 extern long MyCancelKey; 181 extern int MyPMChildSlot; 182 183 extern char OutputFileName[]; 184 extern PGDLLIMPORT char my_exec_path[]; 185 extern char pkglib_path[]; 186 187 #ifdef EXEC_BACKEND 188 extern char postgres_exec_path[]; 189 #endif 190 191 /* 192 * done in storage/backendid.h for now. 193 * 194 * extern BackendId MyBackendId; 195 */ 196 extern PGDLLIMPORT Oid MyDatabaseId; 197 198 extern PGDLLIMPORT Oid MyDatabaseTableSpace; 199 200 /* 201 * Date/Time Configuration 202 * 203 * DateStyle defines the output formatting choice for date/time types: 204 * USE_POSTGRES_DATES specifies traditional Postgres format 205 * USE_ISO_DATES specifies ISO-compliant format 206 * USE_SQL_DATES specifies Oracle/Ingres-compliant format 207 * USE_GERMAN_DATES specifies German-style dd.mm/yyyy 208 * 209 * DateOrder defines the field order to be assumed when reading an 210 * ambiguous date (anything not in YYYY-MM-DD format, with a four-digit 211 * year field first, is taken to be ambiguous): 212 * DATEORDER_YMD specifies field order yy-mm-dd 213 * DATEORDER_DMY specifies field order dd-mm-yy ("European" convention) 214 * DATEORDER_MDY specifies field order mm-dd-yy ("US" convention) 215 * 216 * In the Postgres and SQL DateStyles, DateOrder also selects output field 217 * order: day comes before month in DMY style, else month comes before day. 218 * 219 * The user-visible "DateStyle" run-time parameter subsumes both of these. 220 */ 221 222 /* valid DateStyle values */ 223 #define USE_POSTGRES_DATES 0 224 #define USE_ISO_DATES 1 225 #define USE_SQL_DATES 2 226 #define USE_GERMAN_DATES 3 227 #define USE_XSD_DATES 4 228 229 /* valid DateOrder values */ 230 #define DATEORDER_YMD 0 231 #define DATEORDER_DMY 1 232 #define DATEORDER_MDY 2 233 234 extern PGDLLIMPORT int DateStyle; 235 extern PGDLLIMPORT int DateOrder; 236 237 /* 238 * IntervalStyles 239 * INTSTYLE_POSTGRES Like Postgres < 8.4 when DateStyle = 'iso' 240 * INTSTYLE_POSTGRES_VERBOSE Like Postgres < 8.4 when DateStyle != 'iso' 241 * INTSTYLE_SQL_STANDARD SQL standard interval literals 242 * INTSTYLE_ISO_8601 ISO-8601-basic formatted intervals 243 */ 244 #define INTSTYLE_POSTGRES 0 245 #define INTSTYLE_POSTGRES_VERBOSE 1 246 #define INTSTYLE_SQL_STANDARD 2 247 #define INTSTYLE_ISO_8601 3 248 249 extern PGDLLIMPORT int IntervalStyle; 250 251 #define MAXTZLEN 10 /* max TZ name len, not counting tr. null */ 252 253 extern bool enableFsync; 254 extern PGDLLIMPORT bool allowSystemTableMods; 255 extern PGDLLIMPORT int work_mem; 256 extern PGDLLIMPORT int maintenance_work_mem; 257 extern PGDLLIMPORT int replacement_sort_tuples; 258 259 extern int VacuumCostPageHit; 260 extern int VacuumCostPageMiss; 261 extern int VacuumCostPageDirty; 262 extern int VacuumCostLimit; 263 extern int VacuumCostDelay; 264 265 extern int VacuumPageHit; 266 extern int VacuumPageMiss; 267 extern int VacuumPageDirty; 268 269 extern int VacuumCostBalance; 270 extern bool VacuumCostActive; 271 272 273 /* in tcop/postgres.c */ 274 275 #if defined(__ia64__) || defined(__ia64) 276 typedef struct 277 { 278 char *stack_base_ptr; 279 char *register_stack_base_ptr; 280 } pg_stack_base_t; 281 #else 282 typedef char *pg_stack_base_t; 283 #endif 284 285 extern pg_stack_base_t set_stack_base(void); 286 extern void restore_stack_base(pg_stack_base_t base); 287 extern void check_stack_depth(void); 288 extern bool stack_is_too_deep(void); 289 290 extern void PostgresSigHupHandler(SIGNAL_ARGS); 291 292 /* in tcop/utility.c */ 293 extern void PreventCommandIfReadOnly(const char *cmdname); 294 extern void PreventCommandIfParallelMode(const char *cmdname); 295 extern void PreventCommandDuringRecovery(const char *cmdname); 296 297 /* in utils/misc/guc.c */ 298 extern int trace_recovery_messages; 299 extern int trace_recovery(int trace_level); 300 301 /***************************************************************************** 302 * pdir.h -- * 303 * POSTGRES directory path definitions. * 304 *****************************************************************************/ 305 306 /* flags to be OR'd to form sec_context */ 307 #define SECURITY_LOCAL_USERID_CHANGE 0x0001 308 #define SECURITY_RESTRICTED_OPERATION 0x0002 309 #define SECURITY_NOFORCE_RLS 0x0004 310 311 extern char *DatabasePath; 312 313 /* now in utils/init/miscinit.c */ 314 extern void InitPostmasterChild(void); 315 extern void InitStandaloneProcess(const char *argv0); 316 317 extern void SetDatabasePath(const char *path); 318 319 extern char *GetUserNameFromId(Oid roleid, bool noerr); 320 extern Oid GetUserId(void); 321 extern Oid GetOuterUserId(void); 322 extern Oid GetSessionUserId(void); 323 extern Oid GetAuthenticatedUserId(void); 324 extern void GetUserIdAndSecContext(Oid *userid, int *sec_context); 325 extern void SetUserIdAndSecContext(Oid userid, int sec_context); 326 extern bool InLocalUserIdChange(void); 327 extern bool InSecurityRestrictedOperation(void); 328 extern bool InNoForceRLSOperation(void); 329 extern void GetUserIdAndContext(Oid *userid, bool *sec_def_context); 330 extern void SetUserIdAndContext(Oid userid, bool sec_def_context); 331 extern void InitializeSessionUserId(const char *rolename, Oid useroid); 332 extern void InitializeSessionUserIdStandalone(void); 333 extern void SetSessionAuthorization(Oid userid, bool is_superuser); 334 extern Oid GetCurrentRoleId(void); 335 extern void SetCurrentRoleId(Oid roleid, bool is_superuser); 336 337 extern void SetDataDir(const char *dir); 338 extern void ChangeToDataDir(void); 339 340 extern void SwitchToSharedLatch(void); 341 extern void SwitchBackToLocalLatch(void); 342 343 /* in utils/misc/superuser.c */ 344 extern bool superuser(void); /* current user is superuser */ 345 extern bool superuser_arg(Oid roleid); /* given user is superuser */ 346 347 348 /***************************************************************************** 349 * pmod.h -- * 350 * POSTGRES processing mode definitions. * 351 *****************************************************************************/ 352 353 /* 354 * Description: 355 * There are three processing modes in POSTGRES. They are 356 * BootstrapProcessing or "bootstrap," InitProcessing or 357 * "initialization," and NormalProcessing or "normal." 358 * 359 * The first two processing modes are used during special times. When the 360 * system state indicates bootstrap processing, transactions are all given 361 * transaction id "one" and are consequently guaranteed to commit. This mode 362 * is used during the initial generation of template databases. 363 * 364 * Initialization mode: used while starting a backend, until all normal 365 * initialization is complete. Some code behaves differently when executed 366 * in this mode to enable system bootstrapping. 367 * 368 * If a POSTGRES backend process is in normal mode, then all code may be 369 * executed normally. 370 */ 371 372 typedef enum ProcessingMode 373 { 374 BootstrapProcessing, /* bootstrap creation of template database */ 375 InitProcessing, /* initializing system */ 376 NormalProcessing /* normal processing */ 377 } ProcessingMode; 378 379 extern ProcessingMode Mode; 380 381 #define IsBootstrapProcessingMode() (Mode == BootstrapProcessing) 382 #define IsInitProcessingMode() (Mode == InitProcessing) 383 #define IsNormalProcessingMode() (Mode == NormalProcessing) 384 385 #define GetProcessingMode() Mode 386 387 #define SetProcessingMode(mode) \ 388 do { \ 389 AssertArg((mode) == BootstrapProcessing || \ 390 (mode) == InitProcessing || \ 391 (mode) == NormalProcessing); \ 392 Mode = (mode); \ 393 } while(0) 394 395 396 /* 397 * Auxiliary-process type identifiers. These used to be in bootstrap.h 398 * but it seems saner to have them here, with the ProcessingMode stuff. 399 * The MyAuxProcType global is defined and set in bootstrap.c. 400 */ 401 402 typedef enum 403 { 404 NotAnAuxProcess = -1, 405 CheckerProcess = 0, 406 BootstrapProcess, 407 StartupProcess, 408 BgWriterProcess, 409 CheckpointerProcess, 410 WalWriterProcess, 411 WalReceiverProcess, 412 413 NUM_AUXPROCTYPES /* Must be last! */ 414 } AuxProcType; 415 416 extern AuxProcType MyAuxProcType; 417 418 #define AmBootstrapProcess() (MyAuxProcType == BootstrapProcess) 419 #define AmStartupProcess() (MyAuxProcType == StartupProcess) 420 #define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess) 421 #define AmCheckpointerProcess() (MyAuxProcType == CheckpointerProcess) 422 #define AmWalWriterProcess() (MyAuxProcType == WalWriterProcess) 423 #define AmWalReceiverProcess() (MyAuxProcType == WalReceiverProcess) 424 425 426 /***************************************************************************** 427 * pinit.h -- * 428 * POSTGRES initialization and cleanup definitions. * 429 *****************************************************************************/ 430 431 /* in utils/init/postinit.c */ 432 extern void pg_split_opts(char **argv, int *argcp, const char *optstr); 433 extern void InitializeMaxBackends(void); 434 extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username, 435 Oid useroid, char *out_dbname); 436 extern void BaseInit(void); 437 438 /* in utils/init/miscinit.c */ 439 extern bool IgnoreSystemIndexes; 440 extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress; 441 extern char *session_preload_libraries_string; 442 extern char *shared_preload_libraries_string; 443 extern char *local_preload_libraries_string; 444 445 /* 446 * As of 9.1, the contents of the data-directory lock file are: 447 * 448 * line # 449 * 1 postmaster PID (or negative of a standalone backend's PID) 450 * 2 data directory path 451 * 3 postmaster start timestamp (time_t representation) 452 * 4 port number 453 * 5 first Unix socket directory path (empty if none) 454 * 6 first listen_address (IP address or "*"; empty if no TCP port) 455 * 7 shared memory key (not present on Windows) 456 * 457 * Lines 6 and up are added via AddToDataDirLockFile() after initial file 458 * creation. 459 * 460 * The socket lock file, if used, has the same contents as lines 1-5. 461 */ 462 #define LOCK_FILE_LINE_PID 1 463 #define LOCK_FILE_LINE_DATA_DIR 2 464 #define LOCK_FILE_LINE_START_TIME 3 465 #define LOCK_FILE_LINE_PORT 4 466 #define LOCK_FILE_LINE_SOCKET_DIR 5 467 #define LOCK_FILE_LINE_LISTEN_ADDR 6 468 #define LOCK_FILE_LINE_SHMEM_KEY 7 469 470 extern void CreateDataDirLockFile(bool amPostmaster); 471 extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster, 472 const char *socketDir); 473 extern void TouchSocketLockFiles(void); 474 extern void AddToDataDirLockFile(int target_line, const char *str); 475 extern bool RecheckDataDirLockFile(void); 476 extern void ValidatePgVersion(const char *path); 477 extern void process_shared_preload_libraries(void); 478 extern void process_session_preload_libraries(void); 479 extern void pg_bindtextdomain(const char *domain); 480 extern bool has_rolreplication(Oid roleid); 481 482 /* in access/transam/xlog.c */ 483 extern bool BackupInProgress(void); 484 extern void CancelBackup(void); 485 486 #endif /* MISCADMIN_H */ 487