/* read the control file */
ControlFile = get_controlfile(DataDir, NULL);
+ if (!ControlFile)
+ ereport(ERROR,
+ (errmsg("calculated CRC checksum does not match value stored in file")));
values[0] = Int32GetDatum(ControlFile->pg_control_version);
nulls[0] = false;
/* Read the control file. */
ControlFile = get_controlfile(DataDir, NULL);
+ if (!ControlFile)
+ ereport(ERROR,
+ (errmsg("calculated CRC checksum does not match value stored in file")));
/*
* Calculate name of the WAL file containing the latest checkpoint's REDO
/* read the control file */
ControlFile = get_controlfile(DataDir, NULL);
+ if (!ControlFile)
+ ereport(ERROR,
+ (errmsg("calculated CRC checksum does not match value stored in file")));
values[0] = LSNGetDatum(ControlFile->minRecoveryPoint);
nulls[0] = false;
/* read the control file */
ControlFile = get_controlfile(DataDir, NULL);
+ if (!ControlFile)
+ ereport(ERROR,
+ (errmsg("calculated CRC checksum does not match value stored in file")));
values[0] = Int32GetDatum(ControlFile->maxAlign);
nulls[0] = false;
#include "postgres_fe.h"
+#include "catalog/pg_control.h"
+#include "common/controldata_utils.h"
#include "libpq-fe.h"
#include "pqexpbuffer.h"
static char version_file[MAXPGPATH];
static char pid_file[MAXPGPATH];
static char backup_file[MAXPGPATH];
-static char recovery_file[MAXPGPATH];
static char promote_file[MAXPGPATH];
#ifdef WIN32
static void unlimit_core_size(void);
#endif
+static DBState get_control_dbstate(void);
+
#ifdef WIN32
static void
/*
* If backup_label exists, an online backup is running. Warn the user
* that smart shutdown will wait for it to finish. However, if
- * recovery.conf is also present, we're recovering from an online
+ * the server is in archive recovery, we're recovering from an online
* backup instead of performing one.
*/
if (shutdown_mode == SMART_MODE &&
stat(backup_file, &statbuf) == 0 &&
- stat(recovery_file, &statbuf) != 0)
+ get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
{
print_msg(_("WARNING: online backup mode is active\n"
"Shutdown will not complete until pg_stop_backup() is called.\n\n"));
/*
* If backup_label exists, an online backup is running. Warn the user
* that smart shutdown will wait for it to finish. However, if
- * recovery.conf is also present, we're recovering from an online
+ * the server is in archive recovery, we're recovering from an online
* backup instead of performing one.
*/
if (shutdown_mode == SMART_MODE &&
stat(backup_file, &statbuf) == 0 &&
- stat(recovery_file, &statbuf) != 0)
+ get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
{
print_msg(_("WARNING: online backup mode is active\n"
"Shutdown will not complete until pg_stop_backup() is called.\n\n"));
{
FILE *prmfile;
pgpid_t pid;
- struct stat statbuf;
pid = get_pgpid(false);
exit(1);
}
- /* If recovery.conf doesn't exist, the server is not in standby mode */
- if (stat(recovery_file, &statbuf) != 0)
+ if (get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
{
write_stderr(_("%s: cannot promote server; "
"server is not in standby mode\n"),
}
+static DBState
+get_control_dbstate(void)
+{
+ DBState ret;
+
+ for (;;)
+ {
+ ControlFileData *control_file_data = get_controlfile(pg_data, progname);
+
+ if (control_file_data)
+ {
+ ret = control_file_data->state;
+ pfree(control_file_data);
+ return ret;
+ }
+
+ if (wait_seconds > 0)
+ {
+ pg_usleep(1000000); /* 1 sec */
+ wait_seconds--;
+ continue;
+ }
+
+ write_stderr(_("%s: control file appears to be corrupt\n"), progname);
+ exit(1);
+ }
+}
+
+
int
main(int argc, char **argv)
{
snprintf(version_file, MAXPGPATH, "%s/PG_VERSION", pg_data);
snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
- snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data);
}
switch (ctl_command)
*
* Get controlfile values. The caller is responsible
* for pfreeing the result.
+ *
+ * Returns NULL if the CRC did not match.
*/
ControlFileData *
-get_controlfile(char *DataDir, const char *progname)
+get_controlfile(const char *DataDir, const char *progname)
{
ControlFileData *ControlFile;
int fd;
FIN_CRC32C(crc);
if (!EQ_CRC32C(crc, ControlFile->crc))
-#ifndef FRONTEND
- elog(ERROR, _("calculated CRC checksum does not match value stored in file"));
-#else
- printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
- "Either the file is corrupt, or it has a different layout than this program\n"
- "is expecting. The results below are untrustworthy.\n\n"));
-#endif
+ {
+ pfree(ControlFile);
+ return NULL;
+ }
/* Make sure the control file is valid byte order. */
if (ControlFile->pg_control_version % 65536 == 0 &&