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