* miscinit.c
* miscellaneous initialization support stuff
*
- * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
static bool SetRoleIsActive = false;
-
/*
* GetUserId - get the current effective user ID.
*
bool
is_authenticated_user_replication_role(void)
{
- bool result = false;
- HeapTuple utup;
+ bool result = false;
+ HeapTuple utup;
utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(AuthenticatedUserId));
if (HeapTupleIsValid(utup))
*
* These routines are used to create both a data-directory lockfile
* ($DATADIR/postmaster.pid) and a Unix-socket-file lockfile ($SOCKFILE.lock).
- * Both kinds of files contain the same info:
- *
- * Owning process' PID
- * Data directory path
- *
- * By convention, the owning process' PID is negated if it is a standalone
- * backend rather than a postmaster. This is just for informational purposes.
- * The path is also just for informational purposes (so that a socket lockfile
- * can be more easily traced to the associated postmaster).
- *
- * A data-directory lockfile can optionally contain a third line, containing
- * the key and ID for the shared memory block used by this postmaster.
+ * Both kinds of files contain the same info initially, although we can add
+ * more information to a data-directory lockfile after it's created, using
+ * AddToDataDirLockFile(). See miscadmin.h for documentation of the contents
+ * of these lockfiles.
*
* On successful lockfile creation, a proc_exit callback to remove the
* lockfile is automatically created.
* looking to see if there is an associated shmem segment that is
* still in use.
*
- * Note: because postmaster.pid is written in two steps, we might not
- * find the shmem ID values in it; we can't treat that as an error.
+ * Note: because postmaster.pid is written in multiple steps, we might
+ * not find the shmem ID values in it; we can't treat that as an
+ * error.
*/
if (isDDLock)
{
char *ptr = buffer;
unsigned long id1,
id2;
- int lineno;
+ int lineno;
- for (lineno = 1; lineno <= 4; lineno++)
+ for (lineno = 1; lineno < LOCK_FILE_LINE_SHMEM_KEY; lineno++)
{
if ((ptr = strchr(ptr, '\n')) == NULL)
- {
- elog(LOG, "bogus data in \"%s\"", DIRECTORY_LOCK_FILE);
break;
- }
ptr++;
}
- if (ptr && sscanf(ptr, "%lu %lu", &id1, &id2) == 2)
+ if (ptr != NULL &&
+ sscanf(ptr, "%lu %lu", &id1, &id2) == 2)
{
if (PGSharedMemoryIsInUse(id1, id2))
ereport(FATAL,
"(key %lu, ID %lu) is still in use",
id1, id2),
errhint("If you're sure there are no old "
- "server processes still running, remove "
+ "server processes still running, remove "
"the shared memory block "
"or just delete the file \"%s\".",
filename)));
}
/*
- * Successfully created the file, now fill it.
+ * Successfully created the file, now fill it. See comment in miscadmin.h
+ * about the contents. Note that we write the same info into both datadir
+ * and socket lockfiles; although more stuff may get added to the datadir
+ * lockfile later.
*/
- snprintf(buffer, sizeof(buffer), "%d\n%s\n%d\n%s\n",
+ snprintf(buffer, sizeof(buffer), "%d\n%s\n%ld\n%d\n%s\n",
amPostmaster ? (int) my_pid : -((int) my_pid),
- DataDir, PostPortNumber, UnixSocketDir);
+ DataDir,
+ (long) MyStartTime,
+ PostPortNumber,
+#ifdef HAVE_UNIX_SOCKETS
+ (*UnixSocketDir != '\0') ? UnixSocketDir : DEFAULT_PGSOCKET_DIR
+#else
+ ""
+#endif
+ );
+
errno = 0;
if (write(fd, buffer, strlen(buffer)) != strlen(buffer))
{
}
}
+
/*
- * Append information about a shared memory segment to the data directory
- * lock file.
+ * Add (or replace) a line in the data directory lock file.
+ * The given string should not include a trailing newline.
*
- * This may be called multiple times in the life of a postmaster, if we
- * delete and recreate shmem due to backend crash. Therefore, be prepared
- * to overwrite existing information. (As of 7.1, a postmaster only creates
- * one shm seg at a time; but for the purposes here, if we did have more than
- * one then any one of them would do anyway.)
+ * Caution: this erases all following lines. In current usage that is OK
+ * because lines are added in order. We could improve it if needed.
*/
void
-RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
+AddToDataDirLockFile(int target_line, const char *str)
{
int fd;
int len;
int lineno;
char *ptr;
- char buffer[MAXPGPATH * 2 + 256];
+ char buffer[BLCKSZ];
fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
if (fd < 0)
DIRECTORY_LOCK_FILE)));
return;
}
- len = read(fd, buffer, sizeof(buffer) - 100);
+ len = read(fd, buffer, sizeof(buffer) - 1);
if (len < 0)
{
ereport(LOG,
buffer[len] = '\0';
/*
- * Skip over first four lines (PID, pgdata, portnum, socketdir).
+ * Skip over lines we are not supposed to rewrite.
*/
ptr = buffer;
- for (lineno = 1; lineno <= 4; lineno++)
+ for (lineno = 1; lineno < target_line; lineno++)
{
if ((ptr = strchr(ptr, '\n')) == NULL)
{
}
ptr++;
}
-
+
/*
- * Append key information. Format to try to keep it the same length
- * always (trailing junk won't hurt, but might confuse humans).
+ * Write or rewrite the target line.
*/
- sprintf(ptr, "%9lu %9lu\n", id1, id2);
+ snprintf(ptr, buffer + sizeof(buffer) - ptr, "%s\n", str);
/*
* And rewrite the data. Since we write in a single kernel call, this