1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * miscinit.c |
4 | * miscellaneous initialization support stuff |
5 | * |
6 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
7 | * Portions Copyright (c) 1994, Regents of the University of California |
8 | * |
9 | * |
10 | * IDENTIFICATION |
11 | * src/backend/utils/init/miscinit.c |
12 | * |
13 | *------------------------------------------------------------------------- |
14 | */ |
15 | #include "postgres.h" |
16 | |
17 | #include <sys/param.h> |
18 | #include <signal.h> |
19 | #include <time.h> |
20 | #include <sys/file.h> |
21 | #include <sys/stat.h> |
22 | #include <sys/time.h> |
23 | #include <fcntl.h> |
24 | #include <unistd.h> |
25 | #include <grp.h> |
26 | #include <pwd.h> |
27 | #include <netinet/in.h> |
28 | #include <arpa/inet.h> |
29 | #ifdef HAVE_UTIME_H |
30 | #include <utime.h> |
31 | #endif |
32 | |
33 | #include "access/htup_details.h" |
34 | #include "catalog/pg_authid.h" |
35 | #include "common/file_perm.h" |
36 | #include "libpq/libpq.h" |
37 | #include "mb/pg_wchar.h" |
38 | #include "miscadmin.h" |
39 | #include "pgstat.h" |
40 | #include "postmaster/autovacuum.h" |
41 | #include "postmaster/postmaster.h" |
42 | #include "storage/fd.h" |
43 | #include "storage/ipc.h" |
44 | #include "storage/latch.h" |
45 | #include "storage/pg_shmem.h" |
46 | #include "storage/pmsignal.h" |
47 | #include "storage/proc.h" |
48 | #include "storage/procarray.h" |
49 | #include "utils/builtins.h" |
50 | #include "utils/guc.h" |
51 | #include "utils/inval.h" |
52 | #include "utils/memutils.h" |
53 | #include "utils/pidfile.h" |
54 | #include "utils/syscache.h" |
55 | #include "utils/varlena.h" |
56 | |
57 | |
58 | #define DIRECTORY_LOCK_FILE "postmaster.pid" |
59 | |
60 | ProcessingMode Mode = InitProcessing; |
61 | |
62 | /* List of lock files to be removed at proc exit */ |
63 | static List *lock_files = NIL; |
64 | |
65 | static Latch LocalLatchData; |
66 | |
67 | /* ---------------------------------------------------------------- |
68 | * ignoring system indexes support stuff |
69 | * |
70 | * NOTE: "ignoring system indexes" means we do not use the system indexes |
71 | * for lookups (either in hardwired catalog accesses or in planner-generated |
72 | * plans). We do, however, still update the indexes when a catalog |
73 | * modification is made. |
74 | * ---------------------------------------------------------------- |
75 | */ |
76 | |
77 | bool IgnoreSystemIndexes = false; |
78 | |
79 | |
80 | /* ---------------------------------------------------------------- |
81 | * database path / name support stuff |
82 | * ---------------------------------------------------------------- |
83 | */ |
84 | |
85 | void |
86 | SetDatabasePath(const char *path) |
87 | { |
88 | /* This should happen only once per process */ |
89 | Assert(!DatabasePath); |
90 | DatabasePath = MemoryContextStrdup(TopMemoryContext, path); |
91 | } |
92 | |
93 | /* |
94 | * Validate the proposed data directory. |
95 | * |
96 | * Also initialize file and directory create modes and mode mask. |
97 | */ |
98 | void |
99 | checkDataDir(void) |
100 | { |
101 | struct stat stat_buf; |
102 | |
103 | Assert(DataDir); |
104 | |
105 | if (stat(DataDir, &stat_buf) != 0) |
106 | { |
107 | if (errno == ENOENT) |
108 | ereport(FATAL, |
109 | (errcode_for_file_access(), |
110 | errmsg("data directory \"%s\" does not exist" , |
111 | DataDir))); |
112 | else |
113 | ereport(FATAL, |
114 | (errcode_for_file_access(), |
115 | errmsg("could not read permissions of directory \"%s\": %m" , |
116 | DataDir))); |
117 | } |
118 | |
119 | /* eventual chdir would fail anyway, but let's test ... */ |
120 | if (!S_ISDIR(stat_buf.st_mode)) |
121 | ereport(FATAL, |
122 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
123 | errmsg("specified data directory \"%s\" is not a directory" , |
124 | DataDir))); |
125 | |
126 | /* |
127 | * Check that the directory belongs to my userid; if not, reject. |
128 | * |
129 | * This check is an essential part of the interlock that prevents two |
130 | * postmasters from starting in the same directory (see CreateLockFile()). |
131 | * Do not remove or weaken it. |
132 | * |
133 | * XXX can we safely enable this check on Windows? |
134 | */ |
135 | #if !defined(WIN32) && !defined(__CYGWIN__) |
136 | if (stat_buf.st_uid != geteuid()) |
137 | ereport(FATAL, |
138 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
139 | errmsg("data directory \"%s\" has wrong ownership" , |
140 | DataDir), |
141 | errhint("The server must be started by the user that owns the data directory." ))); |
142 | #endif |
143 | |
144 | /* |
145 | * Check if the directory has correct permissions. If not, reject. |
146 | * |
147 | * Only two possible modes are allowed, 0700 and 0750. The latter mode |
148 | * indicates that group read/execute should be allowed on all newly |
149 | * created files and directories. |
150 | * |
151 | * XXX temporarily suppress check when on Windows, because there may not |
152 | * be proper support for Unix-y file permissions. Need to think of a |
153 | * reasonable check to apply on Windows. |
154 | */ |
155 | #if !defined(WIN32) && !defined(__CYGWIN__) |
156 | if (stat_buf.st_mode & PG_MODE_MASK_GROUP) |
157 | ereport(FATAL, |
158 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
159 | errmsg("data directory \"%s\" has invalid permissions" , |
160 | DataDir), |
161 | errdetail("Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." ))); |
162 | #endif |
163 | |
164 | /* |
165 | * Reset creation modes and mask based on the mode of the data directory. |
166 | * |
167 | * The mask was set earlier in startup to disallow group permissions on |
168 | * newly created files and directories. However, if group read/execute |
169 | * are present on the data directory then modify the create modes and mask |
170 | * to allow group read/execute on newly created files and directories and |
171 | * set the data_directory_mode GUC. |
172 | * |
173 | * Suppress when on Windows, because there may not be proper support for |
174 | * Unix-y file permissions. |
175 | */ |
176 | #if !defined(WIN32) && !defined(__CYGWIN__) |
177 | SetDataDirectoryCreatePerm(stat_buf.st_mode); |
178 | |
179 | umask(pg_mode_mask); |
180 | data_directory_mode = pg_dir_create_mode; |
181 | #endif |
182 | |
183 | /* Check for PG_VERSION */ |
184 | ValidatePgVersion(DataDir); |
185 | } |
186 | |
187 | /* |
188 | * Set data directory, but make sure it's an absolute path. Use this, |
189 | * never set DataDir directly. |
190 | */ |
191 | void |
192 | SetDataDir(const char *dir) |
193 | { |
194 | char *new; |
195 | |
196 | AssertArg(dir); |
197 | |
198 | /* If presented path is relative, convert to absolute */ |
199 | new = make_absolute_path(dir); |
200 | |
201 | if (DataDir) |
202 | free(DataDir); |
203 | DataDir = new; |
204 | } |
205 | |
206 | /* |
207 | * Change working directory to DataDir. Most of the postmaster and backend |
208 | * code assumes that we are in DataDir so it can use relative paths to access |
209 | * stuff in and under the data directory. For convenience during path |
210 | * setup, however, we don't force the chdir to occur during SetDataDir. |
211 | */ |
212 | void |
213 | ChangeToDataDir(void) |
214 | { |
215 | AssertState(DataDir); |
216 | |
217 | if (chdir(DataDir) < 0) |
218 | ereport(FATAL, |
219 | (errcode_for_file_access(), |
220 | errmsg("could not change directory to \"%s\": %m" , |
221 | DataDir))); |
222 | } |
223 | |
224 | |
225 | /* ---------------------------------------------------------------- |
226 | * User ID state |
227 | * |
228 | * We have to track several different values associated with the concept |
229 | * of "user ID". |
230 | * |
231 | * AuthenticatedUserId is determined at connection start and never changes. |
232 | * |
233 | * SessionUserId is initially the same as AuthenticatedUserId, but can be |
234 | * changed by SET SESSION AUTHORIZATION (if AuthenticatedUserIsSuperuser). |
235 | * This is the ID reported by the SESSION_USER SQL function. |
236 | * |
237 | * OuterUserId is the current user ID in effect at the "outer level" (outside |
238 | * any transaction or function). This is initially the same as SessionUserId, |
239 | * but can be changed by SET ROLE to any role that SessionUserId is a |
240 | * member of. (XXX rename to something like CurrentRoleId?) |
241 | * |
242 | * CurrentUserId is the current effective user ID; this is the one to use |
243 | * for all normal permissions-checking purposes. At outer level this will |
244 | * be the same as OuterUserId, but it changes during calls to SECURITY |
245 | * DEFINER functions, as well as locally in some specialized commands. |
246 | * |
247 | * SecurityRestrictionContext holds flags indicating reason(s) for changing |
248 | * CurrentUserId. In some cases we need to lock down operations that are |
249 | * not directly controlled by privilege settings, and this provides a |
250 | * convenient way to do it. |
251 | * ---------------------------------------------------------------- |
252 | */ |
253 | static Oid AuthenticatedUserId = InvalidOid; |
254 | static Oid SessionUserId = InvalidOid; |
255 | static Oid OuterUserId = InvalidOid; |
256 | static Oid CurrentUserId = InvalidOid; |
257 | |
258 | /* We also have to remember the superuser state of some of these levels */ |
259 | static bool AuthenticatedUserIsSuperuser = false; |
260 | static bool SessionUserIsSuperuser = false; |
261 | |
262 | static int SecurityRestrictionContext = 0; |
263 | |
264 | /* We also remember if a SET ROLE is currently active */ |
265 | static bool SetRoleIsActive = false; |
266 | |
267 | /* |
268 | * Initialize the basic environment for a postmaster child |
269 | * |
270 | * Should be called as early as possible after the child's startup. |
271 | */ |
272 | void |
273 | InitPostmasterChild(void) |
274 | { |
275 | IsUnderPostmaster = true; /* we are a postmaster subprocess now */ |
276 | |
277 | InitProcessGlobals(); |
278 | |
279 | /* |
280 | * make sure stderr is in binary mode before anything can possibly be |
281 | * written to it, in case it's actually the syslogger pipe, so the pipe |
282 | * chunking protocol isn't disturbed. Non-logpipe data gets translated on |
283 | * redirection (e.g. via pg_ctl -l) anyway. |
284 | */ |
285 | #ifdef WIN32 |
286 | _setmode(fileno(stderr), _O_BINARY); |
287 | #endif |
288 | |
289 | /* We don't want the postmaster's proc_exit() handlers */ |
290 | on_exit_reset(); |
291 | |
292 | /* Initialize process-local latch support */ |
293 | InitializeLatchSupport(); |
294 | MyLatch = &LocalLatchData; |
295 | InitLatch(MyLatch); |
296 | |
297 | /* |
298 | * If possible, make this process a group leader, so that the postmaster |
299 | * can signal any child processes too. Not all processes will have |
300 | * children, but for consistency we make all postmaster child processes do |
301 | * this. |
302 | */ |
303 | #ifdef HAVE_SETSID |
304 | if (setsid() < 0) |
305 | elog(FATAL, "setsid() failed: %m" ); |
306 | #endif |
307 | |
308 | /* Request a signal if the postmaster dies, if possible. */ |
309 | PostmasterDeathSignalInit(); |
310 | } |
311 | |
312 | /* |
313 | * Initialize the basic environment for a standalone process. |
314 | * |
315 | * argv0 has to be suitable to find the program's executable. |
316 | */ |
317 | void |
318 | InitStandaloneProcess(const char *argv0) |
319 | { |
320 | Assert(!IsPostmasterEnvironment); |
321 | |
322 | InitProcessGlobals(); |
323 | |
324 | /* Initialize process-local latch support */ |
325 | InitializeLatchSupport(); |
326 | MyLatch = &LocalLatchData; |
327 | InitLatch(MyLatch); |
328 | |
329 | /* Compute paths, no postmaster to inherit from */ |
330 | if (my_exec_path[0] == '\0') |
331 | { |
332 | if (find_my_exec(argv0, my_exec_path) < 0) |
333 | elog(FATAL, "%s: could not locate my own executable path" , |
334 | argv0); |
335 | } |
336 | |
337 | if (pkglib_path[0] == '\0') |
338 | get_pkglib_path(my_exec_path, pkglib_path); |
339 | } |
340 | |
341 | void |
342 | SwitchToSharedLatch(void) |
343 | { |
344 | Assert(MyLatch == &LocalLatchData); |
345 | Assert(MyProc != NULL); |
346 | |
347 | MyLatch = &MyProc->procLatch; |
348 | |
349 | if (FeBeWaitSet) |
350 | ModifyWaitEvent(FeBeWaitSet, 1, WL_LATCH_SET, MyLatch); |
351 | |
352 | /* |
353 | * Set the shared latch as the local one might have been set. This |
354 | * shouldn't normally be necessary as code is supposed to check the |
355 | * condition before waiting for the latch, but a bit care can't hurt. |
356 | */ |
357 | SetLatch(MyLatch); |
358 | } |
359 | |
360 | void |
361 | SwitchBackToLocalLatch(void) |
362 | { |
363 | Assert(MyLatch != &LocalLatchData); |
364 | Assert(MyProc != NULL && MyLatch == &MyProc->procLatch); |
365 | |
366 | MyLatch = &LocalLatchData; |
367 | |
368 | if (FeBeWaitSet) |
369 | ModifyWaitEvent(FeBeWaitSet, 1, WL_LATCH_SET, MyLatch); |
370 | |
371 | SetLatch(MyLatch); |
372 | } |
373 | |
374 | /* |
375 | * GetUserId - get the current effective user ID. |
376 | * |
377 | * Note: there's no SetUserId() anymore; use SetUserIdAndSecContext(). |
378 | */ |
379 | Oid |
380 | GetUserId(void) |
381 | { |
382 | AssertState(OidIsValid(CurrentUserId)); |
383 | return CurrentUserId; |
384 | } |
385 | |
386 | |
387 | /* |
388 | * GetOuterUserId/SetOuterUserId - get/set the outer-level user ID. |
389 | */ |
390 | Oid |
391 | GetOuterUserId(void) |
392 | { |
393 | AssertState(OidIsValid(OuterUserId)); |
394 | return OuterUserId; |
395 | } |
396 | |
397 | |
398 | static void |
399 | SetOuterUserId(Oid userid) |
400 | { |
401 | AssertState(SecurityRestrictionContext == 0); |
402 | AssertArg(OidIsValid(userid)); |
403 | OuterUserId = userid; |
404 | |
405 | /* We force the effective user ID to match, too */ |
406 | CurrentUserId = userid; |
407 | } |
408 | |
409 | |
410 | /* |
411 | * GetSessionUserId/SetSessionUserId - get/set the session user ID. |
412 | */ |
413 | Oid |
414 | GetSessionUserId(void) |
415 | { |
416 | AssertState(OidIsValid(SessionUserId)); |
417 | return SessionUserId; |
418 | } |
419 | |
420 | |
421 | static void |
422 | SetSessionUserId(Oid userid, bool is_superuser) |
423 | { |
424 | AssertState(SecurityRestrictionContext == 0); |
425 | AssertArg(OidIsValid(userid)); |
426 | SessionUserId = userid; |
427 | SessionUserIsSuperuser = is_superuser; |
428 | SetRoleIsActive = false; |
429 | |
430 | /* We force the effective user IDs to match, too */ |
431 | OuterUserId = userid; |
432 | CurrentUserId = userid; |
433 | } |
434 | |
435 | /* |
436 | * GetAuthenticatedUserId - get the authenticated user ID |
437 | */ |
438 | Oid |
439 | GetAuthenticatedUserId(void) |
440 | { |
441 | AssertState(OidIsValid(AuthenticatedUserId)); |
442 | return AuthenticatedUserId; |
443 | } |
444 | |
445 | |
446 | /* |
447 | * GetUserIdAndSecContext/SetUserIdAndSecContext - get/set the current user ID |
448 | * and the SecurityRestrictionContext flags. |
449 | * |
450 | * Currently there are three valid bits in SecurityRestrictionContext: |
451 | * |
452 | * SECURITY_LOCAL_USERID_CHANGE indicates that we are inside an operation |
453 | * that is temporarily changing CurrentUserId via these functions. This is |
454 | * needed to indicate that the actual value of CurrentUserId is not in sync |
455 | * with guc.c's internal state, so SET ROLE has to be disallowed. |
456 | * |
457 | * SECURITY_RESTRICTED_OPERATION indicates that we are inside an operation |
458 | * that does not wish to trust called user-defined functions at all. This |
459 | * bit prevents not only SET ROLE, but various other changes of session state |
460 | * that normally is unprotected but might possibly be used to subvert the |
461 | * calling session later. An example is replacing an existing prepared |
462 | * statement with new code, which will then be executed with the outer |
463 | * session's permissions when the prepared statement is next used. Since |
464 | * these restrictions are fairly draconian, we apply them only in contexts |
465 | * where the called functions are really supposed to be side-effect-free |
466 | * anyway, such as VACUUM/ANALYZE/REINDEX. |
467 | * |
468 | * SECURITY_NOFORCE_RLS indicates that we are inside an operation which should |
469 | * ignore the FORCE ROW LEVEL SECURITY per-table indication. This is used to |
470 | * ensure that FORCE RLS does not mistakenly break referential integrity |
471 | * checks. Note that this is intentionally only checked when running as the |
472 | * owner of the table (which should always be the case for referential |
473 | * integrity checks). |
474 | * |
475 | * Unlike GetUserId, GetUserIdAndSecContext does *not* Assert that the current |
476 | * value of CurrentUserId is valid; nor does SetUserIdAndSecContext require |
477 | * the new value to be valid. In fact, these routines had better not |
478 | * ever throw any kind of error. This is because they are used by |
479 | * StartTransaction and AbortTransaction to save/restore the settings, |
480 | * and during the first transaction within a backend, the value to be saved |
481 | * and perhaps restored is indeed invalid. We have to be able to get |
482 | * through AbortTransaction without asserting in case InitPostgres fails. |
483 | */ |
484 | void |
485 | GetUserIdAndSecContext(Oid *userid, int *sec_context) |
486 | { |
487 | *userid = CurrentUserId; |
488 | *sec_context = SecurityRestrictionContext; |
489 | } |
490 | |
491 | void |
492 | SetUserIdAndSecContext(Oid userid, int sec_context) |
493 | { |
494 | CurrentUserId = userid; |
495 | SecurityRestrictionContext = sec_context; |
496 | } |
497 | |
498 | |
499 | /* |
500 | * InLocalUserIdChange - are we inside a local change of CurrentUserId? |
501 | */ |
502 | bool |
503 | InLocalUserIdChange(void) |
504 | { |
505 | return (SecurityRestrictionContext & SECURITY_LOCAL_USERID_CHANGE) != 0; |
506 | } |
507 | |
508 | /* |
509 | * InSecurityRestrictedOperation - are we inside a security-restricted command? |
510 | */ |
511 | bool |
512 | InSecurityRestrictedOperation(void) |
513 | { |
514 | return (SecurityRestrictionContext & SECURITY_RESTRICTED_OPERATION) != 0; |
515 | } |
516 | |
517 | /* |
518 | * InNoForceRLSOperation - are we ignoring FORCE ROW LEVEL SECURITY ? |
519 | */ |
520 | bool |
521 | InNoForceRLSOperation(void) |
522 | { |
523 | return (SecurityRestrictionContext & SECURITY_NOFORCE_RLS) != 0; |
524 | } |
525 | |
526 | |
527 | /* |
528 | * These are obsolete versions of Get/SetUserIdAndSecContext that are |
529 | * only provided for bug-compatibility with some rather dubious code in |
530 | * pljava. We allow the userid to be set, but only when not inside a |
531 | * security restriction context. |
532 | */ |
533 | void |
534 | GetUserIdAndContext(Oid *userid, bool *sec_def_context) |
535 | { |
536 | *userid = CurrentUserId; |
537 | *sec_def_context = InLocalUserIdChange(); |
538 | } |
539 | |
540 | void |
541 | SetUserIdAndContext(Oid userid, bool sec_def_context) |
542 | { |
543 | /* We throw the same error SET ROLE would. */ |
544 | if (InSecurityRestrictedOperation()) |
545 | ereport(ERROR, |
546 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
547 | errmsg("cannot set parameter \"%s\" within security-restricted operation" , |
548 | "role" ))); |
549 | CurrentUserId = userid; |
550 | if (sec_def_context) |
551 | SecurityRestrictionContext |= SECURITY_LOCAL_USERID_CHANGE; |
552 | else |
553 | SecurityRestrictionContext &= ~SECURITY_LOCAL_USERID_CHANGE; |
554 | } |
555 | |
556 | |
557 | /* |
558 | * Check whether specified role has explicit REPLICATION privilege |
559 | */ |
560 | bool |
561 | has_rolreplication(Oid roleid) |
562 | { |
563 | bool result = false; |
564 | HeapTuple utup; |
565 | |
566 | utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); |
567 | if (HeapTupleIsValid(utup)) |
568 | { |
569 | result = ((Form_pg_authid) GETSTRUCT(utup))->rolreplication; |
570 | ReleaseSysCache(utup); |
571 | } |
572 | return result; |
573 | } |
574 | |
575 | /* |
576 | * Initialize user identity during normal backend startup |
577 | */ |
578 | void |
579 | InitializeSessionUserId(const char *rolename, Oid roleid) |
580 | { |
581 | HeapTuple roleTup; |
582 | Form_pg_authid rform; |
583 | char *rname; |
584 | |
585 | /* |
586 | * Don't do scans if we're bootstrapping, none of the system catalogs |
587 | * exist yet, and they should be owned by postgres anyway. |
588 | */ |
589 | AssertState(!IsBootstrapProcessingMode()); |
590 | |
591 | /* call only once */ |
592 | AssertState(!OidIsValid(AuthenticatedUserId)); |
593 | |
594 | /* |
595 | * Make sure syscache entries are flushed for recent catalog changes. This |
596 | * allows us to find roles that were created on-the-fly during |
597 | * authentication. |
598 | */ |
599 | AcceptInvalidationMessages(); |
600 | |
601 | if (rolename != NULL) |
602 | { |
603 | roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(rolename)); |
604 | if (!HeapTupleIsValid(roleTup)) |
605 | ereport(FATAL, |
606 | (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), |
607 | errmsg("role \"%s\" does not exist" , rolename))); |
608 | } |
609 | else |
610 | { |
611 | roleTup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); |
612 | if (!HeapTupleIsValid(roleTup)) |
613 | ereport(FATAL, |
614 | (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), |
615 | errmsg("role with OID %u does not exist" , roleid))); |
616 | } |
617 | |
618 | rform = (Form_pg_authid) GETSTRUCT(roleTup); |
619 | roleid = rform->oid; |
620 | rname = NameStr(rform->rolname); |
621 | |
622 | AuthenticatedUserId = roleid; |
623 | AuthenticatedUserIsSuperuser = rform->rolsuper; |
624 | |
625 | /* This sets OuterUserId/CurrentUserId too */ |
626 | SetSessionUserId(roleid, AuthenticatedUserIsSuperuser); |
627 | |
628 | /* Also mark our PGPROC entry with the authenticated user id */ |
629 | /* (We assume this is an atomic store so no lock is needed) */ |
630 | MyProc->roleId = roleid; |
631 | |
632 | /* |
633 | * These next checks are not enforced when in standalone mode, so that |
634 | * there is a way to recover from sillinesses like "UPDATE pg_authid SET |
635 | * rolcanlogin = false;". |
636 | */ |
637 | if (IsUnderPostmaster) |
638 | { |
639 | /* |
640 | * Is role allowed to login at all? |
641 | */ |
642 | if (!rform->rolcanlogin) |
643 | ereport(FATAL, |
644 | (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), |
645 | errmsg("role \"%s\" is not permitted to log in" , |
646 | rname))); |
647 | |
648 | /* |
649 | * Check connection limit for this role. |
650 | * |
651 | * There is a race condition here --- we create our PGPROC before |
652 | * checking for other PGPROCs. If two backends did this at about the |
653 | * same time, they might both think they were over the limit, while |
654 | * ideally one should succeed and one fail. Getting that to work |
655 | * exactly seems more trouble than it is worth, however; instead we |
656 | * just document that the connection limit is approximate. |
657 | */ |
658 | if (rform->rolconnlimit >= 0 && |
659 | !AuthenticatedUserIsSuperuser && |
660 | CountUserBackends(roleid) > rform->rolconnlimit) |
661 | ereport(FATAL, |
662 | (errcode(ERRCODE_TOO_MANY_CONNECTIONS), |
663 | errmsg("too many connections for role \"%s\"" , |
664 | rname))); |
665 | } |
666 | |
667 | /* Record username and superuser status as GUC settings too */ |
668 | SetConfigOption("session_authorization" , rname, |
669 | PGC_BACKEND, PGC_S_OVERRIDE); |
670 | SetConfigOption("is_superuser" , |
671 | AuthenticatedUserIsSuperuser ? "on" : "off" , |
672 | PGC_INTERNAL, PGC_S_OVERRIDE); |
673 | |
674 | ReleaseSysCache(roleTup); |
675 | } |
676 | |
677 | |
678 | /* |
679 | * Initialize user identity during special backend startup |
680 | */ |
681 | void |
682 | InitializeSessionUserIdStandalone(void) |
683 | { |
684 | /* |
685 | * This function should only be called in single-user mode, in autovacuum |
686 | * workers, and in background workers. |
687 | */ |
688 | AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess() || IsBackgroundWorker); |
689 | |
690 | /* call only once */ |
691 | AssertState(!OidIsValid(AuthenticatedUserId)); |
692 | |
693 | AuthenticatedUserId = BOOTSTRAP_SUPERUSERID; |
694 | AuthenticatedUserIsSuperuser = true; |
695 | |
696 | SetSessionUserId(BOOTSTRAP_SUPERUSERID, true); |
697 | } |
698 | |
699 | |
700 | /* |
701 | * Change session auth ID while running |
702 | * |
703 | * Only a superuser may set auth ID to something other than himself. Note |
704 | * that in case of multiple SETs in a single session, the original userid's |
705 | * superuserness is what matters. But we set the GUC variable is_superuser |
706 | * to indicate whether the *current* session userid is a superuser. |
707 | * |
708 | * Note: this is not an especially clean place to do the permission check. |
709 | * It's OK because the check does not require catalog access and can't |
710 | * fail during an end-of-transaction GUC reversion, but we may someday |
711 | * have to push it up into assign_session_authorization. |
712 | */ |
713 | void |
714 | SetSessionAuthorization(Oid userid, bool is_superuser) |
715 | { |
716 | /* Must have authenticated already, else can't make permission check */ |
717 | AssertState(OidIsValid(AuthenticatedUserId)); |
718 | |
719 | if (userid != AuthenticatedUserId && |
720 | !AuthenticatedUserIsSuperuser) |
721 | ereport(ERROR, |
722 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
723 | errmsg("permission denied to set session authorization" ))); |
724 | |
725 | SetSessionUserId(userid, is_superuser); |
726 | |
727 | SetConfigOption("is_superuser" , |
728 | is_superuser ? "on" : "off" , |
729 | PGC_INTERNAL, PGC_S_OVERRIDE); |
730 | } |
731 | |
732 | /* |
733 | * Report current role id |
734 | * This follows the semantics of SET ROLE, ie return the outer-level ID |
735 | * not the current effective ID, and return InvalidOid when the setting |
736 | * is logically SET ROLE NONE. |
737 | */ |
738 | Oid |
739 | GetCurrentRoleId(void) |
740 | { |
741 | if (SetRoleIsActive) |
742 | return OuterUserId; |
743 | else |
744 | return InvalidOid; |
745 | } |
746 | |
747 | /* |
748 | * Change Role ID while running (SET ROLE) |
749 | * |
750 | * If roleid is InvalidOid, we are doing SET ROLE NONE: revert to the |
751 | * session user authorization. In this case the is_superuser argument |
752 | * is ignored. |
753 | * |
754 | * When roleid is not InvalidOid, the caller must have checked whether |
755 | * the session user has permission to become that role. (We cannot check |
756 | * here because this routine must be able to execute in a failed transaction |
757 | * to restore a prior value of the ROLE GUC variable.) |
758 | */ |
759 | void |
760 | SetCurrentRoleId(Oid roleid, bool is_superuser) |
761 | { |
762 | /* |
763 | * Get correct info if it's SET ROLE NONE |
764 | * |
765 | * If SessionUserId hasn't been set yet, just do nothing --- the eventual |
766 | * SetSessionUserId call will fix everything. This is needed since we |
767 | * will get called during GUC initialization. |
768 | */ |
769 | if (!OidIsValid(roleid)) |
770 | { |
771 | if (!OidIsValid(SessionUserId)) |
772 | return; |
773 | |
774 | roleid = SessionUserId; |
775 | is_superuser = SessionUserIsSuperuser; |
776 | |
777 | SetRoleIsActive = false; |
778 | } |
779 | else |
780 | SetRoleIsActive = true; |
781 | |
782 | SetOuterUserId(roleid); |
783 | |
784 | SetConfigOption("is_superuser" , |
785 | is_superuser ? "on" : "off" , |
786 | PGC_INTERNAL, PGC_S_OVERRIDE); |
787 | } |
788 | |
789 | |
790 | /* |
791 | * Get user name from user oid, returns NULL for nonexistent roleid if noerr |
792 | * is true. |
793 | */ |
794 | char * |
795 | GetUserNameFromId(Oid roleid, bool noerr) |
796 | { |
797 | HeapTuple tuple; |
798 | char *result; |
799 | |
800 | tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); |
801 | if (!HeapTupleIsValid(tuple)) |
802 | { |
803 | if (!noerr) |
804 | ereport(ERROR, |
805 | (errcode(ERRCODE_UNDEFINED_OBJECT), |
806 | errmsg("invalid role OID: %u" , roleid))); |
807 | result = NULL; |
808 | } |
809 | else |
810 | { |
811 | result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); |
812 | ReleaseSysCache(tuple); |
813 | } |
814 | return result; |
815 | } |
816 | |
817 | |
818 | /*------------------------------------------------------------------------- |
819 | * Interlock-file support |
820 | * |
821 | * These routines are used to create both a data-directory lockfile |
822 | * ($DATADIR/postmaster.pid) and Unix-socket-file lockfiles ($SOCKFILE.lock). |
823 | * Both kinds of files contain the same info initially, although we can add |
824 | * more information to a data-directory lockfile after it's created, using |
825 | * AddToDataDirLockFile(). See miscadmin.h for documentation of the contents |
826 | * of these lockfiles. |
827 | * |
828 | * On successful lockfile creation, a proc_exit callback to remove the |
829 | * lockfile is automatically created. |
830 | *------------------------------------------------------------------------- |
831 | */ |
832 | |
833 | /* |
834 | * proc_exit callback to remove lockfiles. |
835 | */ |
836 | static void |
837 | UnlinkLockFiles(int status, Datum arg) |
838 | { |
839 | ListCell *l; |
840 | |
841 | foreach(l, lock_files) |
842 | { |
843 | char *curfile = (char *) lfirst(l); |
844 | |
845 | unlink(curfile); |
846 | /* Should we complain if the unlink fails? */ |
847 | } |
848 | /* Since we're about to exit, no need to reclaim storage */ |
849 | lock_files = NIL; |
850 | |
851 | /* |
852 | * Lock file removal should always be the last externally visible action |
853 | * of a postmaster or standalone backend, while we won't come here at all |
854 | * when exiting postmaster child processes. Therefore, this is a good |
855 | * place to log completion of shutdown. We could alternatively teach |
856 | * proc_exit() to do it, but that seems uglier. In a standalone backend, |
857 | * use NOTICE elevel to be less chatty. |
858 | */ |
859 | ereport(IsPostmasterEnvironment ? LOG : NOTICE, |
860 | (errmsg("database system is shut down" ))); |
861 | } |
862 | |
863 | /* |
864 | * Create a lockfile. |
865 | * |
866 | * filename is the path name of the lockfile to create. |
867 | * amPostmaster is used to determine how to encode the output PID. |
868 | * socketDir is the Unix socket directory path to include (possibly empty). |
869 | * isDDLock and refName are used to determine what error message to produce. |
870 | */ |
871 | static void |
872 | CreateLockFile(const char *filename, bool amPostmaster, |
873 | const char *socketDir, |
874 | bool isDDLock, const char *refName) |
875 | { |
876 | int fd; |
877 | char buffer[MAXPGPATH * 2 + 256]; |
878 | int ntries; |
879 | int len; |
880 | int encoded_pid; |
881 | pid_t other_pid; |
882 | pid_t my_pid, |
883 | my_p_pid, |
884 | my_gp_pid; |
885 | const char *envvar; |
886 | |
887 | /* |
888 | * If the PID in the lockfile is our own PID or our parent's or |
889 | * grandparent's PID, then the file must be stale (probably left over from |
890 | * a previous system boot cycle). We need to check this because of the |
891 | * likelihood that a reboot will assign exactly the same PID as we had in |
892 | * the previous reboot, or one that's only one or two counts larger and |
893 | * hence the lockfile's PID now refers to an ancestor shell process. We |
894 | * allow pg_ctl to pass down its parent shell PID (our grandparent PID) |
895 | * via the environment variable PG_GRANDPARENT_PID; this is so that |
896 | * launching the postmaster via pg_ctl can be just as reliable as |
897 | * launching it directly. There is no provision for detecting |
898 | * further-removed ancestor processes, but if the init script is written |
899 | * carefully then all but the immediate parent shell will be root-owned |
900 | * processes and so the kill test will fail with EPERM. Note that we |
901 | * cannot get a false negative this way, because an existing postmaster |
902 | * would surely never launch a competing postmaster or pg_ctl process |
903 | * directly. |
904 | */ |
905 | my_pid = getpid(); |
906 | |
907 | #ifndef WIN32 |
908 | my_p_pid = getppid(); |
909 | #else |
910 | |
911 | /* |
912 | * Windows hasn't got getppid(), but doesn't need it since it's not using |
913 | * real kill() either... |
914 | */ |
915 | my_p_pid = 0; |
916 | #endif |
917 | |
918 | envvar = getenv("PG_GRANDPARENT_PID" ); |
919 | if (envvar) |
920 | my_gp_pid = atoi(envvar); |
921 | else |
922 | my_gp_pid = 0; |
923 | |
924 | /* |
925 | * We need a loop here because of race conditions. But don't loop forever |
926 | * (for example, a non-writable $PGDATA directory might cause a failure |
927 | * that won't go away). 100 tries seems like plenty. |
928 | */ |
929 | for (ntries = 0;; ntries++) |
930 | { |
931 | /* |
932 | * Try to create the lock file --- O_EXCL makes this atomic. |
933 | * |
934 | * Think not to make the file protection weaker than 0600/0640. See |
935 | * comments below. |
936 | */ |
937 | fd = open(filename, O_RDWR | O_CREAT | O_EXCL, pg_file_create_mode); |
938 | if (fd >= 0) |
939 | break; /* Success; exit the retry loop */ |
940 | |
941 | /* |
942 | * Couldn't create the pid file. Probably it already exists. |
943 | */ |
944 | if ((errno != EEXIST && errno != EACCES) || ntries > 100) |
945 | ereport(FATAL, |
946 | (errcode_for_file_access(), |
947 | errmsg("could not create lock file \"%s\": %m" , |
948 | filename))); |
949 | |
950 | /* |
951 | * Read the file to get the old owner's PID. Note race condition |
952 | * here: file might have been deleted since we tried to create it. |
953 | */ |
954 | fd = open(filename, O_RDONLY, pg_file_create_mode); |
955 | if (fd < 0) |
956 | { |
957 | if (errno == ENOENT) |
958 | continue; /* race condition; try again */ |
959 | ereport(FATAL, |
960 | (errcode_for_file_access(), |
961 | errmsg("could not open lock file \"%s\": %m" , |
962 | filename))); |
963 | } |
964 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_READ); |
965 | if ((len = read(fd, buffer, sizeof(buffer) - 1)) < 0) |
966 | ereport(FATAL, |
967 | (errcode_for_file_access(), |
968 | errmsg("could not read lock file \"%s\": %m" , |
969 | filename))); |
970 | pgstat_report_wait_end(); |
971 | close(fd); |
972 | |
973 | if (len == 0) |
974 | { |
975 | ereport(FATAL, |
976 | (errcode(ERRCODE_LOCK_FILE_EXISTS), |
977 | errmsg("lock file \"%s\" is empty" , filename), |
978 | errhint("Either another server is starting, or the lock file is the remnant of a previous server startup crash." ))); |
979 | } |
980 | |
981 | buffer[len] = '\0'; |
982 | encoded_pid = atoi(buffer); |
983 | |
984 | /* if pid < 0, the pid is for postgres, not postmaster */ |
985 | other_pid = (pid_t) (encoded_pid < 0 ? -encoded_pid : encoded_pid); |
986 | |
987 | if (other_pid <= 0) |
988 | elog(FATAL, "bogus data in lock file \"%s\": \"%s\"" , |
989 | filename, buffer); |
990 | |
991 | /* |
992 | * Check to see if the other process still exists |
993 | * |
994 | * Per discussion above, my_pid, my_p_pid, and my_gp_pid can be |
995 | * ignored as false matches. |
996 | * |
997 | * Normally kill() will fail with ESRCH if the given PID doesn't |
998 | * exist. |
999 | * |
1000 | * We can treat the EPERM-error case as okay because that error |
1001 | * implies that the existing process has a different userid than we |
1002 | * do, which means it cannot be a competing postmaster. A postmaster |
1003 | * cannot successfully attach to a data directory owned by a userid |
1004 | * other than its own, as enforced in checkDataDir(). Also, since we |
1005 | * create the lockfiles mode 0600/0640, we'd have failed above if the |
1006 | * lockfile belonged to another userid --- which means that whatever |
1007 | * process kill() is reporting about isn't the one that made the |
1008 | * lockfile. (NOTE: this last consideration is the only one that |
1009 | * keeps us from blowing away a Unix socket file belonging to an |
1010 | * instance of Postgres being run by someone else, at least on |
1011 | * machines where /tmp hasn't got a stickybit.) |
1012 | */ |
1013 | if (other_pid != my_pid && other_pid != my_p_pid && |
1014 | other_pid != my_gp_pid) |
1015 | { |
1016 | if (kill(other_pid, 0) == 0 || |
1017 | (errno != ESRCH && errno != EPERM)) |
1018 | { |
1019 | /* lockfile belongs to a live process */ |
1020 | ereport(FATAL, |
1021 | (errcode(ERRCODE_LOCK_FILE_EXISTS), |
1022 | errmsg("lock file \"%s\" already exists" , |
1023 | filename), |
1024 | isDDLock ? |
1025 | (encoded_pid < 0 ? |
1026 | errhint("Is another postgres (PID %d) running in data directory \"%s\"?" , |
1027 | (int) other_pid, refName) : |
1028 | errhint("Is another postmaster (PID %d) running in data directory \"%s\"?" , |
1029 | (int) other_pid, refName)) : |
1030 | (encoded_pid < 0 ? |
1031 | errhint("Is another postgres (PID %d) using socket file \"%s\"?" , |
1032 | (int) other_pid, refName) : |
1033 | errhint("Is another postmaster (PID %d) using socket file \"%s\"?" , |
1034 | (int) other_pid, refName)))); |
1035 | } |
1036 | } |
1037 | |
1038 | /* |
1039 | * No, the creating process did not exist. However, it could be that |
1040 | * the postmaster crashed (or more likely was kill -9'd by a clueless |
1041 | * admin) but has left orphan backends behind. Check for this by |
1042 | * looking to see if there is an associated shmem segment that is |
1043 | * still in use. |
1044 | * |
1045 | * Note: because postmaster.pid is written in multiple steps, we might |
1046 | * not find the shmem ID values in it; we can't treat that as an |
1047 | * error. |
1048 | */ |
1049 | if (isDDLock) |
1050 | { |
1051 | char *ptr = buffer; |
1052 | unsigned long id1, |
1053 | id2; |
1054 | int lineno; |
1055 | |
1056 | for (lineno = 1; lineno < LOCK_FILE_LINE_SHMEM_KEY; lineno++) |
1057 | { |
1058 | if ((ptr = strchr(ptr, '\n')) == NULL) |
1059 | break; |
1060 | ptr++; |
1061 | } |
1062 | |
1063 | if (ptr != NULL && |
1064 | sscanf(ptr, "%lu %lu" , &id1, &id2) == 2) |
1065 | { |
1066 | if (PGSharedMemoryIsInUse(id1, id2)) |
1067 | ereport(FATAL, |
1068 | (errcode(ERRCODE_LOCK_FILE_EXISTS), |
1069 | errmsg("pre-existing shared memory block (key %lu, ID %lu) is still in use" , |
1070 | id1, id2), |
1071 | errhint("Terminate any old server processes associated with data directory \"%s\"." , |
1072 | refName))); |
1073 | } |
1074 | } |
1075 | |
1076 | /* |
1077 | * Looks like nobody's home. Unlink the file and try again to create |
1078 | * it. Need a loop because of possible race condition against other |
1079 | * would-be creators. |
1080 | */ |
1081 | if (unlink(filename) < 0) |
1082 | ereport(FATAL, |
1083 | (errcode_for_file_access(), |
1084 | errmsg("could not remove old lock file \"%s\": %m" , |
1085 | filename), |
1086 | errhint("The file seems accidentally left over, but " |
1087 | "it could not be removed. Please remove the file " |
1088 | "by hand and try again." ))); |
1089 | } |
1090 | |
1091 | /* |
1092 | * Successfully created the file, now fill it. See comment in miscadmin.h |
1093 | * about the contents. Note that we write the same first five lines into |
1094 | * both datadir and socket lockfiles; although more stuff may get added to |
1095 | * the datadir lockfile later. |
1096 | */ |
1097 | snprintf(buffer, sizeof(buffer), "%d\n%s\n%ld\n%d\n%s\n" , |
1098 | amPostmaster ? (int) my_pid : -((int) my_pid), |
1099 | DataDir, |
1100 | (long) MyStartTime, |
1101 | PostPortNumber, |
1102 | socketDir); |
1103 | |
1104 | /* |
1105 | * In a standalone backend, the next line (LOCK_FILE_LINE_LISTEN_ADDR) |
1106 | * will never receive data, so fill it in as empty now. |
1107 | */ |
1108 | if (isDDLock && !amPostmaster) |
1109 | strlcat(buffer, "\n" , sizeof(buffer)); |
1110 | |
1111 | errno = 0; |
1112 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_WRITE); |
1113 | if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) |
1114 | { |
1115 | int save_errno = errno; |
1116 | |
1117 | close(fd); |
1118 | unlink(filename); |
1119 | /* if write didn't set errno, assume problem is no disk space */ |
1120 | errno = save_errno ? save_errno : ENOSPC; |
1121 | ereport(FATAL, |
1122 | (errcode_for_file_access(), |
1123 | errmsg("could not write lock file \"%s\": %m" , filename))); |
1124 | } |
1125 | pgstat_report_wait_end(); |
1126 | |
1127 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_CREATE_SYNC); |
1128 | if (pg_fsync(fd) != 0) |
1129 | { |
1130 | int save_errno = errno; |
1131 | |
1132 | close(fd); |
1133 | unlink(filename); |
1134 | errno = save_errno; |
1135 | ereport(FATAL, |
1136 | (errcode_for_file_access(), |
1137 | errmsg("could not write lock file \"%s\": %m" , filename))); |
1138 | } |
1139 | pgstat_report_wait_end(); |
1140 | if (close(fd) != 0) |
1141 | { |
1142 | int save_errno = errno; |
1143 | |
1144 | unlink(filename); |
1145 | errno = save_errno; |
1146 | ereport(FATAL, |
1147 | (errcode_for_file_access(), |
1148 | errmsg("could not write lock file \"%s\": %m" , filename))); |
1149 | } |
1150 | |
1151 | /* |
1152 | * Arrange to unlink the lock file(s) at proc_exit. If this is the first |
1153 | * one, set up the on_proc_exit function to do it; then add this lock file |
1154 | * to the list of files to unlink. |
1155 | */ |
1156 | if (lock_files == NIL) |
1157 | on_proc_exit(UnlinkLockFiles, 0); |
1158 | |
1159 | /* |
1160 | * Use lcons so that the lock files are unlinked in reverse order of |
1161 | * creation; this is critical! |
1162 | */ |
1163 | lock_files = lcons(pstrdup(filename), lock_files); |
1164 | } |
1165 | |
1166 | /* |
1167 | * Create the data directory lockfile. |
1168 | * |
1169 | * When this is called, we must have already switched the working |
1170 | * directory to DataDir, so we can just use a relative path. This |
1171 | * helps ensure that we are locking the directory we should be. |
1172 | * |
1173 | * Note that the socket directory path line is initially written as empty. |
1174 | * postmaster.c will rewrite it upon creating the first Unix socket. |
1175 | */ |
1176 | void |
1177 | CreateDataDirLockFile(bool amPostmaster) |
1178 | { |
1179 | CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, "" , true, DataDir); |
1180 | } |
1181 | |
1182 | /* |
1183 | * Create a lockfile for the specified Unix socket file. |
1184 | */ |
1185 | void |
1186 | CreateSocketLockFile(const char *socketfile, bool amPostmaster, |
1187 | const char *socketDir) |
1188 | { |
1189 | char lockfile[MAXPGPATH]; |
1190 | |
1191 | snprintf(lockfile, sizeof(lockfile), "%s.lock" , socketfile); |
1192 | CreateLockFile(lockfile, amPostmaster, socketDir, false, socketfile); |
1193 | } |
1194 | |
1195 | /* |
1196 | * TouchSocketLockFiles -- mark socket lock files as recently accessed |
1197 | * |
1198 | * This routine should be called every so often to ensure that the socket |
1199 | * lock files have a recent mod or access date. That saves them |
1200 | * from being removed by overenthusiastic /tmp-directory-cleaner daemons. |
1201 | * (Another reason we should never have put the socket file in /tmp...) |
1202 | */ |
1203 | void |
1204 | TouchSocketLockFiles(void) |
1205 | { |
1206 | ListCell *l; |
1207 | |
1208 | foreach(l, lock_files) |
1209 | { |
1210 | char *socketLockFile = (char *) lfirst(l); |
1211 | |
1212 | /* No need to touch the data directory lock file, we trust */ |
1213 | if (strcmp(socketLockFile, DIRECTORY_LOCK_FILE) == 0) |
1214 | continue; |
1215 | |
1216 | /* |
1217 | * utime() is POSIX standard, utimes() is a common alternative; if we |
1218 | * have neither, fall back to actually reading the file (which only |
1219 | * sets the access time not mod time, but that should be enough in |
1220 | * most cases). In all paths, we ignore errors. |
1221 | */ |
1222 | #ifdef HAVE_UTIME |
1223 | utime(socketLockFile, NULL); |
1224 | #else /* !HAVE_UTIME */ |
1225 | #ifdef HAVE_UTIMES |
1226 | utimes(socketLockFile, NULL); |
1227 | #else /* !HAVE_UTIMES */ |
1228 | int fd; |
1229 | char buffer[1]; |
1230 | |
1231 | fd = open(socketLockFile, O_RDONLY | PG_BINARY, 0); |
1232 | if (fd >= 0) |
1233 | { |
1234 | read(fd, buffer, sizeof(buffer)); |
1235 | close(fd); |
1236 | } |
1237 | #endif /* HAVE_UTIMES */ |
1238 | #endif /* HAVE_UTIME */ |
1239 | } |
1240 | } |
1241 | |
1242 | |
1243 | /* |
1244 | * Add (or replace) a line in the data directory lock file. |
1245 | * The given string should not include a trailing newline. |
1246 | * |
1247 | * Note: because we don't truncate the file, if we were to rewrite a line |
1248 | * with less data than it had before, there would be garbage after the last |
1249 | * line. While we could fix that by adding a truncate call, that would make |
1250 | * the file update non-atomic, which we'd rather avoid. Therefore, callers |
1251 | * should endeavor never to shorten a line once it's been written. |
1252 | */ |
1253 | void |
1254 | AddToDataDirLockFile(int target_line, const char *str) |
1255 | { |
1256 | int fd; |
1257 | int len; |
1258 | int lineno; |
1259 | char *srcptr; |
1260 | char *destptr; |
1261 | char srcbuffer[BLCKSZ]; |
1262 | char destbuffer[BLCKSZ]; |
1263 | |
1264 | fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0); |
1265 | if (fd < 0) |
1266 | { |
1267 | ereport(LOG, |
1268 | (errcode_for_file_access(), |
1269 | errmsg("could not open file \"%s\": %m" , |
1270 | DIRECTORY_LOCK_FILE))); |
1271 | return; |
1272 | } |
1273 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ); |
1274 | len = read(fd, srcbuffer, sizeof(srcbuffer) - 1); |
1275 | pgstat_report_wait_end(); |
1276 | if (len < 0) |
1277 | { |
1278 | ereport(LOG, |
1279 | (errcode_for_file_access(), |
1280 | errmsg("could not read from file \"%s\": %m" , |
1281 | DIRECTORY_LOCK_FILE))); |
1282 | close(fd); |
1283 | return; |
1284 | } |
1285 | srcbuffer[len] = '\0'; |
1286 | |
1287 | /* |
1288 | * Advance over lines we are not supposed to rewrite, then copy them to |
1289 | * destbuffer. |
1290 | */ |
1291 | srcptr = srcbuffer; |
1292 | for (lineno = 1; lineno < target_line; lineno++) |
1293 | { |
1294 | char *eol = strchr(srcptr, '\n'); |
1295 | |
1296 | if (eol == NULL) |
1297 | break; /* not enough lines in file yet */ |
1298 | srcptr = eol + 1; |
1299 | } |
1300 | memcpy(destbuffer, srcbuffer, srcptr - srcbuffer); |
1301 | destptr = destbuffer + (srcptr - srcbuffer); |
1302 | |
1303 | /* |
1304 | * Fill in any missing lines before the target line, in case lines are |
1305 | * added to the file out of order. |
1306 | */ |
1307 | for (; lineno < target_line; lineno++) |
1308 | { |
1309 | if (destptr < destbuffer + sizeof(destbuffer)) |
1310 | *destptr++ = '\n'; |
1311 | } |
1312 | |
1313 | /* |
1314 | * Write or rewrite the target line. |
1315 | */ |
1316 | snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n" , str); |
1317 | destptr += strlen(destptr); |
1318 | |
1319 | /* |
1320 | * If there are more lines in the old file, append them to destbuffer. |
1321 | */ |
1322 | if ((srcptr = strchr(srcptr, '\n')) != NULL) |
1323 | { |
1324 | srcptr++; |
1325 | snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s" , |
1326 | srcptr); |
1327 | } |
1328 | |
1329 | /* |
1330 | * And rewrite the data. Since we write in a single kernel call, this |
1331 | * update should appear atomic to onlookers. |
1332 | */ |
1333 | len = strlen(destbuffer); |
1334 | errno = 0; |
1335 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE); |
1336 | if (lseek(fd, (off_t) 0, SEEK_SET) != 0 || |
1337 | (int) write(fd, destbuffer, len) != len) |
1338 | { |
1339 | pgstat_report_wait_end(); |
1340 | /* if write didn't set errno, assume problem is no disk space */ |
1341 | if (errno == 0) |
1342 | errno = ENOSPC; |
1343 | ereport(LOG, |
1344 | (errcode_for_file_access(), |
1345 | errmsg("could not write to file \"%s\": %m" , |
1346 | DIRECTORY_LOCK_FILE))); |
1347 | close(fd); |
1348 | return; |
1349 | } |
1350 | pgstat_report_wait_end(); |
1351 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC); |
1352 | if (pg_fsync(fd) != 0) |
1353 | { |
1354 | ereport(LOG, |
1355 | (errcode_for_file_access(), |
1356 | errmsg("could not write to file \"%s\": %m" , |
1357 | DIRECTORY_LOCK_FILE))); |
1358 | } |
1359 | pgstat_report_wait_end(); |
1360 | if (close(fd) != 0) |
1361 | { |
1362 | ereport(LOG, |
1363 | (errcode_for_file_access(), |
1364 | errmsg("could not write to file \"%s\": %m" , |
1365 | DIRECTORY_LOCK_FILE))); |
1366 | } |
1367 | } |
1368 | |
1369 | |
1370 | /* |
1371 | * Recheck that the data directory lock file still exists with expected |
1372 | * content. Return true if the lock file appears OK, false if it isn't. |
1373 | * |
1374 | * We call this periodically in the postmaster. The idea is that if the |
1375 | * lock file has been removed or replaced by another postmaster, we should |
1376 | * do a panic database shutdown. Therefore, we should return true if there |
1377 | * is any doubt: we do not want to cause a panic shutdown unnecessarily. |
1378 | * Transient failures like EINTR or ENFILE should not cause us to fail. |
1379 | * (If there really is something wrong, we'll detect it on a future recheck.) |
1380 | */ |
1381 | bool |
1382 | RecheckDataDirLockFile(void) |
1383 | { |
1384 | int fd; |
1385 | int len; |
1386 | long file_pid; |
1387 | char buffer[BLCKSZ]; |
1388 | |
1389 | fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0); |
1390 | if (fd < 0) |
1391 | { |
1392 | /* |
1393 | * There are many foreseeable false-positive error conditions. For |
1394 | * safety, fail only on enumerated clearly-something-is-wrong |
1395 | * conditions. |
1396 | */ |
1397 | switch (errno) |
1398 | { |
1399 | case ENOENT: |
1400 | case ENOTDIR: |
1401 | /* disaster */ |
1402 | ereport(LOG, |
1403 | (errcode_for_file_access(), |
1404 | errmsg("could not open file \"%s\": %m" , |
1405 | DIRECTORY_LOCK_FILE))); |
1406 | return false; |
1407 | default: |
1408 | /* non-fatal, at least for now */ |
1409 | ereport(LOG, |
1410 | (errcode_for_file_access(), |
1411 | errmsg("could not open file \"%s\": %m; continuing anyway" , |
1412 | DIRECTORY_LOCK_FILE))); |
1413 | return true; |
1414 | } |
1415 | } |
1416 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ); |
1417 | len = read(fd, buffer, sizeof(buffer) - 1); |
1418 | pgstat_report_wait_end(); |
1419 | if (len < 0) |
1420 | { |
1421 | ereport(LOG, |
1422 | (errcode_for_file_access(), |
1423 | errmsg("could not read from file \"%s\": %m" , |
1424 | DIRECTORY_LOCK_FILE))); |
1425 | close(fd); |
1426 | return true; /* treat read failure as nonfatal */ |
1427 | } |
1428 | buffer[len] = '\0'; |
1429 | close(fd); |
1430 | file_pid = atol(buffer); |
1431 | if (file_pid == getpid()) |
1432 | return true; /* all is well */ |
1433 | |
1434 | /* Trouble: someone's overwritten the lock file */ |
1435 | ereport(LOG, |
1436 | (errmsg("lock file \"%s\" contains wrong PID: %ld instead of %ld" , |
1437 | DIRECTORY_LOCK_FILE, file_pid, (long) getpid()))); |
1438 | return false; |
1439 | } |
1440 | |
1441 | |
1442 | /*------------------------------------------------------------------------- |
1443 | * Version checking support |
1444 | *------------------------------------------------------------------------- |
1445 | */ |
1446 | |
1447 | /* |
1448 | * Determine whether the PG_VERSION file in directory `path' indicates |
1449 | * a data version compatible with the version of this program. |
1450 | * |
1451 | * If compatible, return. Otherwise, ereport(FATAL). |
1452 | */ |
1453 | void |
1454 | ValidatePgVersion(const char *path) |
1455 | { |
1456 | char full_path[MAXPGPATH]; |
1457 | FILE *file; |
1458 | int ret; |
1459 | long file_major; |
1460 | long my_major; |
1461 | char *endptr; |
1462 | char file_version_string[64]; |
1463 | const char *my_version_string = PG_VERSION; |
1464 | |
1465 | my_major = strtol(my_version_string, &endptr, 10); |
1466 | |
1467 | snprintf(full_path, sizeof(full_path), "%s/PG_VERSION" , path); |
1468 | |
1469 | file = AllocateFile(full_path, "r" ); |
1470 | if (!file) |
1471 | { |
1472 | if (errno == ENOENT) |
1473 | ereport(FATAL, |
1474 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
1475 | errmsg("\"%s\" is not a valid data directory" , |
1476 | path), |
1477 | errdetail("File \"%s\" is missing." , full_path))); |
1478 | else |
1479 | ereport(FATAL, |
1480 | (errcode_for_file_access(), |
1481 | errmsg("could not open file \"%s\": %m" , full_path))); |
1482 | } |
1483 | |
1484 | file_version_string[0] = '\0'; |
1485 | ret = fscanf(file, "%63s" , file_version_string); |
1486 | file_major = strtol(file_version_string, &endptr, 10); |
1487 | |
1488 | if (ret != 1 || endptr == file_version_string) |
1489 | ereport(FATAL, |
1490 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
1491 | errmsg("\"%s\" is not a valid data directory" , |
1492 | path), |
1493 | errdetail("File \"%s\" does not contain valid data." , |
1494 | full_path), |
1495 | errhint("You might need to initdb." ))); |
1496 | |
1497 | FreeFile(file); |
1498 | |
1499 | if (my_major != file_major) |
1500 | ereport(FATAL, |
1501 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
1502 | errmsg("database files are incompatible with server" ), |
1503 | errdetail("The data directory was initialized by PostgreSQL version %s, " |
1504 | "which is not compatible with this version %s." , |
1505 | file_version_string, my_version_string))); |
1506 | } |
1507 | |
1508 | /*------------------------------------------------------------------------- |
1509 | * Library preload support |
1510 | *------------------------------------------------------------------------- |
1511 | */ |
1512 | |
1513 | /* |
1514 | * GUC variables: lists of library names to be preloaded at postmaster |
1515 | * start and at backend start |
1516 | */ |
1517 | char *session_preload_libraries_string = NULL; |
1518 | char *shared_preload_libraries_string = NULL; |
1519 | char *local_preload_libraries_string = NULL; |
1520 | |
1521 | /* Flag telling that we are loading shared_preload_libraries */ |
1522 | bool process_shared_preload_libraries_in_progress = false; |
1523 | |
1524 | /* |
1525 | * load the shared libraries listed in 'libraries' |
1526 | * |
1527 | * 'gucname': name of GUC variable, for error reports |
1528 | * 'restricted': if true, force libraries to be in $libdir/plugins/ |
1529 | */ |
1530 | static void |
1531 | load_libraries(const char *libraries, const char *gucname, bool restricted) |
1532 | { |
1533 | char *rawstring; |
1534 | List *elemlist; |
1535 | ListCell *l; |
1536 | |
1537 | if (libraries == NULL || libraries[0] == '\0') |
1538 | return; /* nothing to do */ |
1539 | |
1540 | /* Need a modifiable copy of string */ |
1541 | rawstring = pstrdup(libraries); |
1542 | |
1543 | /* Parse string into list of filename paths */ |
1544 | if (!SplitDirectoriesString(rawstring, ',', &elemlist)) |
1545 | { |
1546 | /* syntax error in list */ |
1547 | list_free_deep(elemlist); |
1548 | pfree(rawstring); |
1549 | ereport(LOG, |
1550 | (errcode(ERRCODE_SYNTAX_ERROR), |
1551 | errmsg("invalid list syntax in parameter \"%s\"" , |
1552 | gucname))); |
1553 | return; |
1554 | } |
1555 | |
1556 | foreach(l, elemlist) |
1557 | { |
1558 | /* Note that filename was already canonicalized */ |
1559 | char *filename = (char *) lfirst(l); |
1560 | char *expanded = NULL; |
1561 | |
1562 | /* If restricting, insert $libdir/plugins if not mentioned already */ |
1563 | if (restricted && first_dir_separator(filename) == NULL) |
1564 | { |
1565 | expanded = psprintf("$libdir/plugins/%s" , filename); |
1566 | filename = expanded; |
1567 | } |
1568 | load_file(filename, restricted); |
1569 | ereport(DEBUG1, |
1570 | (errmsg("loaded library \"%s\"" , filename))); |
1571 | if (expanded) |
1572 | pfree(expanded); |
1573 | } |
1574 | |
1575 | list_free_deep(elemlist); |
1576 | pfree(rawstring); |
1577 | } |
1578 | |
1579 | /* |
1580 | * process any libraries that should be preloaded at postmaster start |
1581 | */ |
1582 | void |
1583 | process_shared_preload_libraries(void) |
1584 | { |
1585 | process_shared_preload_libraries_in_progress = true; |
1586 | load_libraries(shared_preload_libraries_string, |
1587 | "shared_preload_libraries" , |
1588 | false); |
1589 | process_shared_preload_libraries_in_progress = false; |
1590 | } |
1591 | |
1592 | /* |
1593 | * process any libraries that should be preloaded at backend start |
1594 | */ |
1595 | void |
1596 | process_session_preload_libraries(void) |
1597 | { |
1598 | load_libraries(session_preload_libraries_string, |
1599 | "session_preload_libraries" , |
1600 | false); |
1601 | load_libraries(local_preload_libraries_string, |
1602 | "local_preload_libraries" , |
1603 | true); |
1604 | } |
1605 | |
1606 | void |
1607 | pg_bindtextdomain(const char *domain) |
1608 | { |
1609 | #ifdef ENABLE_NLS |
1610 | if (my_exec_path[0] != '\0') |
1611 | { |
1612 | char locale_path[MAXPGPATH]; |
1613 | |
1614 | get_locale_path(my_exec_path, locale_path); |
1615 | bindtextdomain(domain, locale_path); |
1616 | pg_bind_textdomain_codeset(domain); |
1617 | } |
1618 | #endif |
1619 | } |
1620 | |