diff --git a/check_dir.c b/check_dir.c index 8d784b4c..79b6f7b6 100644 --- a/check_dir.c +++ b/check_dir.c @@ -44,9 +44,9 @@ int check_dir(char *dir) { - DIR *chkdir; - struct dirent *file; - int result = 1; + DIR *chkdir; + struct dirent *file; + int result = 1; errno = 0; @@ -58,7 +58,7 @@ check_dir(char *dir) while ((file = readdir(chkdir)) != NULL) { if (strcmp(".", file->d_name) == 0 || - strcmp("..", file->d_name) == 0) + strcmp("..", file->d_name) == 0) { /* skip this and parent directory */ continue; @@ -71,6 +71,7 @@ check_dir(char *dir) } #ifdef WIN32 + /* * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in * released version @@ -82,7 +83,7 @@ check_dir(char *dir) closedir(chkdir); if (errno != 0) - return -1; /* some kind of I/O error? */ + return -1; /* some kind of I/O error? */ return result; } @@ -98,7 +99,7 @@ create_directory(char *dir) return true; log_err(_("Could not create directory \"%s\": %s\n"), - dir, strerror(errno)); + dir, strerror(errno)); return false; } @@ -127,10 +128,10 @@ mkdir_p(char *path, mode_t omode) { struct stat sb; mode_t numask, - oumask; + oumask; int first, - last, - retval; + last, + retval; char *p; p = path; @@ -149,8 +150,8 @@ mkdir_p(char *path, mode_t omode) return 1; } else if (p[1] == ':' && - ((p[0] >= 'a' && p[0] <= 'z') || - (p[0] >= 'A' && p[0] <= 'Z'))) + ((p[0] >= 'a' && p[0] <= 'z') || + (p[0] >= 'A' && p[0] <= 'Z'))) { /* local drive */ p += 2; @@ -221,9 +222,9 @@ bool is_pg_dir(char *dir) { const size_t buf_sz = 8192; - char path[buf_sz]; - struct stat sb; - int r; + char path[buf_sz]; + struct stat sb; + int r; /* test pgdata */ xsnprintf(path, buf_sz, "%s/PG_VERSION", dir); @@ -243,65 +244,65 @@ is_pg_dir(char *dir) bool create_pgdir(char *dir, bool force) { - bool pg_dir = false; + bool pg_dir = false; /* Check this directory could be used as a PGDATA dir */ switch (check_dir(dir)) { - case 0: - /* dir not there, must create it */ - log_info(_("creating directory \"%s\"...\n"), dir); + case 0: + /* dir not there, must create it */ + log_info(_("creating directory \"%s\"...\n"), dir); - if (!create_directory(dir)) - { - log_err(_("couldn't create directory \"%s\"...\n"), - dir); - return false; - } - break; - case 1: - /* Present but empty, fix permissions and use it */ - log_info(_("checking and correcting permissions on existing directory %s ...\n"), - dir); - - if (!set_directory_permissions(dir)) - { - log_err(_("could not change permissions of directory \"%s\": %s\n"), - dir, strerror(errno)); - return false; - } - break; - case 2: - /* Present and not empty */ - log_warning(_("directory \"%s\" exists but is not empty\n"), - dir); - - pg_dir = is_pg_dir(dir); - - /* - * we use force to reduce the time needed to restore a node which - * turn async after a failover or anything else - */ - if (pg_dir && force) - { - /* Let it continue */ + if (!create_directory(dir)) + { + log_err(_("couldn't create directory \"%s\"...\n"), + dir); + return false; + } break; - } - else if (pg_dir && !force) - { - log_warning(_("\nThis looks like a PostgreSQL directory.\n" - "If you are sure you want to clone here, " - "please check there is no PostgreSQL server " - "running and use the --force option\n")); - return false; - } + case 1: + /* Present but empty, fix permissions and use it */ + log_info(_("checking and correcting permissions on existing directory %s ...\n"), + dir); - return false; - default: - /* Trouble accessing directory */ - log_err(_("could not access directory \"%s\": %s\n"), - dir, strerror(errno)); - return false; + if (!set_directory_permissions(dir)) + { + log_err(_("could not change permissions of directory \"%s\": %s\n"), + dir, strerror(errno)); + return false; + } + break; + case 2: + /* Present and not empty */ + log_warning(_("directory \"%s\" exists but is not empty\n"), + dir); + + pg_dir = is_pg_dir(dir); + + /* + * we use force to reduce the time needed to restore a node which + * turn async after a failover or anything else + */ + if (pg_dir && force) + { + /* Let it continue */ + break; + } + else if (pg_dir && !force) + { + log_warning(_("\nThis looks like a PostgreSQL directory.\n" + "If you are sure you want to clone here, " + "please check there is no PostgreSQL server " + "running and use the --force option\n")); + return false; + } + + return false; + default: + /* Trouble accessing directory */ + log_err(_("could not access directory \"%s\": %s\n"), + dir, strerror(errno)); + return false; } return true; } diff --git a/check_dir.h b/check_dir.h index 9953e885..44f1a6b2 100644 --- a/check_dir.h +++ b/check_dir.h @@ -20,11 +20,11 @@ #ifndef _REPMGR_CHECK_DIR_H_ #define _REPMGR_CHECK_DIR_H_ -int mkdir_p(char *path, mode_t omode); -int check_dir(char *dir); -bool create_directory(char *dir); -bool set_directory_permissions(char *dir); -bool is_pg_dir(char *dir); -bool create_pgdir(char *dir, bool force); +int mkdir_p(char *path, mode_t omode); +int check_dir(char *dir); +bool create_directory(char *dir); +bool set_directory_permissions(char *dir); +bool is_pg_dir(char *dir); +bool create_pgdir(char *dir, bool force); #endif diff --git a/config.c b/config.c index 2897992a..a992e648 100644 --- a/config.c +++ b/config.c @@ -23,13 +23,14 @@ #include "repmgr.h" void -parse_config(const char *config_file, t_configuration_options *options) +parse_config(const char *config_file, t_configuration_options * options) { - char *s, buff[MAXLINELENGTH]; - char name[MAXLEN]; - char value[MAXLEN]; + char *s, + buff[MAXLINELENGTH]; + char name[MAXLEN]; + char value[MAXLEN]; - FILE *fp = fopen (config_file, "r"); + FILE *fp = fopen(config_file, "r"); /* Initialize */ memset(options->cluster_name, 0, sizeof(options->cluster_name)); @@ -56,17 +57,18 @@ parse_config(const char *config_file, t_configuration_options *options) options->retry_promote_interval_secs = 300; /* - * Since some commands don't require a config file at all, not - * having one isn't necessarily a problem. + * Since some commands don't require a config file at all, not having one + * isn't necessarily a problem. */ if (fp == NULL) { - log_err(_("Did not find the configuration file '%s', continuing\n"), config_file); + log_err(_("Did not find the configuration file '%s', continuing\n"), + config_file); return; } /* Read next line */ - while ((s = fgets (buff, sizeof buff, fp)) != NULL) + while ((s = fgets(buff, sizeof buff, fp)) != NULL) { /* Skip blank lines and comments */ if (buff[0] == '\n' || buff[0] == '#') @@ -77,22 +79,23 @@ parse_config(const char *config_file, t_configuration_options *options) /* Copy into correct entry in parameters struct */ if (strcmp(name, "cluster") == 0) - strncpy (options->cluster_name, value, MAXLEN); + strncpy(options->cluster_name, value, MAXLEN); else if (strcmp(name, "node") == 0) options->node = atoi(value); else if (strcmp(name, "conninfo") == 0) - strncpy (options->conninfo, value, MAXLEN); + strncpy(options->conninfo, value, MAXLEN); else if (strcmp(name, "rsync_options") == 0) - strncpy (options->rsync_options, value, QUERY_STR_LEN); + strncpy(options->rsync_options, value, QUERY_STR_LEN); else if (strcmp(name, "ssh_options") == 0) - strncpy (options->ssh_options, value, QUERY_STR_LEN); + strncpy(options->ssh_options, value, QUERY_STR_LEN); else if (strcmp(name, "loglevel") == 0) - strncpy (options->loglevel, value, MAXLEN); + strncpy(options->loglevel, value, MAXLEN); else if (strcmp(name, "logfacility") == 0) - strncpy (options->logfacility, value, MAXLEN); + strncpy(options->logfacility, value, MAXLEN); else if (strcmp(name, "failover") == 0) { - char failoverstr[MAXLEN]; + char failoverstr[MAXLEN]; + strncpy(failoverstr, value, MAXLEN); if (strcmp(failoverstr, "manual") == 0) @@ -120,9 +123,9 @@ parse_config(const char *config_file, t_configuration_options *options) else if (strcmp(name, "reconnect_interval") == 0) options->reconnect_intvl = atoi(value); else if (strcmp(name, "pg_bindir") == 0) - strncpy (options->pg_bindir, value, MAXLEN); + strncpy(options->pg_bindir, value, MAXLEN); else if (strcmp(name, "pg_ctl_options") == 0) - strncpy (options->pgctl_options, value, MAXLEN); + strncpy(options->pgctl_options, value, MAXLEN); else if (strcmp(name, "logfile") == 0) strncpy(options->logfile, value, MAXLEN); else if (strcmp(name, "monitor_interval_secs") == 0) @@ -134,10 +137,10 @@ parse_config(const char *config_file, t_configuration_options *options) } /* Close file */ - fclose (fp); + fclose(fp); /* Check config settings */ - if (strnlen(options->cluster_name, MAXLEN)==0) + if (strnlen(options->cluster_name, MAXLEN) == 0) { log_err(_("Cluster name is missing. Check the configuration file.\n")); exit(ERR_BAD_CONFIG); @@ -176,22 +179,23 @@ parse_config(const char *config_file, t_configuration_options *options) char * -trim (char *s) +trim(char *s) { /* Initialize start, end pointers */ - char *s1 = s, *s2 = &s[strlen (s) - 1]; + char *s1 = s, + *s2 = &s[strlen(s) - 1]; /* Trim and delimit right side */ - while ( (isspace (*s2)) && (s2 >= s1) ) + while ((isspace(*s2)) && (s2 >= s1)) --s2; - *(s2+1) = '\0'; + *(s2 + 1) = '\0'; /* Trim left side */ - while ( (isspace (*s1)) && (s1 < s2) ) + while ((isspace(*s1)) && (s1 < s2)) ++s1; /* Copy finished string */ - memmove (s, s1, s2 - s1); + memmove(s, s1, s2 - s1); s[s2 - s1 + 1] = '\0'; return s; @@ -200,13 +204,13 @@ trim (char *s) void parse_line(char *buff, char *name, char *value) { - int i = 0; - int j = 0; + int i = 0; + int j = 0; /* * first we find the name of the parameter */ - for ( ; i < MAXLEN; ++i) + for (; i < MAXLEN; ++i) { if (buff[i] != '=') name[j++] = buff[i]; @@ -219,7 +223,7 @@ parse_line(char *buff, char *name, char *value) * Now the value */ j = 0; - for ( ++i ; i < MAXLEN; ++i) + for (++i; i < MAXLEN; ++i) if (buff[i] == '\'') continue; else if (buff[i] != '\n') @@ -231,9 +235,9 @@ parse_line(char *buff, char *name, char *value) } bool -reload_configuration(char *config_file, t_configuration_options *orig_options) +reload_configuration(char *config_file, t_configuration_options * orig_options) { - PGconn *conn; + PGconn *conn; t_configuration_options new_options; @@ -313,16 +317,16 @@ reload_configuration(char *config_file, t_configuration_options *orig_options) orig_options->master_response_timeout = new_options.master_response_timeout; orig_options->reconnect_attempts = new_options.reconnect_attempts; orig_options->reconnect_intvl = new_options.reconnect_intvl; + /* * XXX These ones can change with a simple SIGHUP? - - strcpy (orig_options->loglevel, new_options.loglevel); - strcpy (orig_options->logfacility, new_options.logfacility); - - logger_shutdown(); - XXX do we have progname here ? - logger_init(progname, orig_options.loglevel, orig_options.logfacility); - */ + * + * strcpy (orig_options->loglevel, new_options.loglevel); strcpy + * (orig_options->logfacility, new_options.logfacility); + * + * logger_shutdown(); XXX do we have progname here ? logger_init(progname, + * orig_options.loglevel, orig_options.logfacility); + */ return true; } diff --git a/config.h b/config.h index f3aacc37..9a344fe5 100644 --- a/config.h +++ b/config.h @@ -25,33 +25,33 @@ typedef struct { - char cluster_name[MAXLEN]; - int node; - char conninfo[MAXLEN]; - int failover; - int priority; - char node_name[MAXLEN]; - char promote_command[MAXLEN]; - char follow_command[MAXLEN]; - char loglevel[MAXLEN]; - char logfacility[MAXLEN]; - char rsync_options[QUERY_STR_LEN]; - char ssh_options[QUERY_STR_LEN]; - int master_response_timeout; - int reconnect_attempts; - int reconnect_intvl; - char pg_bindir[MAXLEN]; - char pgctl_options[MAXLEN]; - char logfile[MAXLEN]; - int monitor_interval_secs; - int retry_promote_interval_secs; -} t_configuration_options; + char cluster_name[MAXLEN]; + int node; + char conninfo[MAXLEN]; + int failover; + int priority; + char node_name[MAXLEN]; + char promote_command[MAXLEN]; + char follow_command[MAXLEN]; + char loglevel[MAXLEN]; + char logfacility[MAXLEN]; + char rsync_options[QUERY_STR_LEN]; + char ssh_options[QUERY_STR_LEN]; + int master_response_timeout; + int reconnect_attempts; + int reconnect_intvl; + char pg_bindir[MAXLEN]; + char pgctl_options[MAXLEN]; + char logfile[MAXLEN]; + int monitor_interval_secs; + int retry_promote_interval_secs; +} t_configuration_options; #define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", -1, -1, -1, "", "", "", 0, 0 } -void parse_config(const char *config_file, t_configuration_options *options); -void parse_line(char *buff, char *name, char *value); -char *trim(char *s); -bool reload_configuration(char *config_file, t_configuration_options *orig_options); +void parse_config(const char *config_file, t_configuration_options * options); +void parse_line(char *buff, char *name, char *value); +char *trim(char *s); +bool reload_configuration(char *config_file, t_configuration_options * orig_options); #endif diff --git a/dbutils.c b/dbutils.c index 03ce950d..f4387d0d 100644 --- a/dbutils.c +++ b/dbutils.c @@ -29,8 +29,8 @@ PGconn * establishDBConnection(const char *conninfo, const bool exit_on_error) { /* Make a connection to the database */ - PGconn *conn = NULL; - char connection_string[MAXLEN]; + PGconn *conn = NULL; + char connection_string[MAXLEN]; strcpy(connection_string, conninfo); strcat(connection_string, " fallback_application_name='repmgr'"); @@ -40,7 +40,7 @@ establishDBConnection(const char *conninfo, const bool exit_on_error) if ((PQstatus(conn) != CONNECTION_OK)) { log_err(_("Connection to database failed: %s\n"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); if (exit_on_error) { @@ -53,16 +53,17 @@ establishDBConnection(const char *conninfo, const bool exit_on_error) } PGconn * -establishDBConnectionByParams(const char *keywords[], const char *values[],const bool exit_on_error) +establishDBConnectionByParams(const char *keywords[], const char *values[], + const bool exit_on_error) { /* Make a connection to the database */ - PGconn *conn = PQconnectdbParams(keywords, values, true); + PGconn *conn = PQconnectdbParams(keywords, values, true); /* Check to see that the backend connection was successfully made */ if ((PQstatus(conn) != CONNECTION_OK)) { log_err(_("Connection to database failed: %s\n"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); if (exit_on_error) { PQfinish(conn); @@ -84,7 +85,7 @@ is_standby(PGconn *conn) if (res == NULL || PQresultStatus(res) != PGRES_TUPLES_OK) { log_err(_("Can't query server mode: %s"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); result = -1; } else if (PQntuples(res) == 1 && strcmp(PQgetvalue(res, 0, 0), "t") == 0) @@ -104,7 +105,7 @@ is_witness(PGconn *conn, char *schema, char *cluster, int node_id) char sqlquery[QUERY_STR_LEN]; sqlquery_snprintf(sqlquery, "SELECT witness from %s.repl_nodes where cluster = '%s' and id = %d", - schema, cluster, node_id); + schema, cluster, node_id); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { @@ -124,6 +125,7 @@ bool is_pgup(PGconn *conn, int timeout) { char sqlquery[QUERY_STR_LEN]; + /* Check the connection status twice in case it changes after reset */ bool twice = false; @@ -134,14 +136,14 @@ is_pgup(PGconn *conn, int timeout) { if (twice) return false; - PQreset(conn); /* reconnect */ + PQreset(conn); /* reconnect */ twice = true; } else { /* - * Send a SELECT 1 just to check if the connection is OK - */ + * Send a SELECT 1 just to check if the connection is OK + */ if (!CancelQuery(conn, timeout)) goto failed; if (wait_connection_availability(conn, timeout) != 1) @@ -151,7 +153,7 @@ is_pgup(PGconn *conn, int timeout) if (PQsendQuery(conn, sqlquery) == 0) { log_warning(_("PQsendQuery: Query could not be sent to primary. %s\n"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); goto failed; } if (wait_connection_availability(conn, timeout) != 1) @@ -159,11 +161,15 @@ is_pgup(PGconn *conn, int timeout) break; -failed: - /* we need to retry, because we might just have loose the connection once */ + failed: + + /* + * we need to retry, because we might just have loose the + * connection once + */ if (twice) return false; - PQreset(conn); /* reconnect */ + PQreset(conn); /* reconnect */ twice = true; } } @@ -176,23 +182,23 @@ failed: * if 8 or inferior returns an empty string */ char * -pg_version(PGconn *conn, char* major_version) +pg_version(PGconn *conn, char *major_version) { - PGresult *res; + PGresult *res; - int major_version1; - char *major_version2; + int major_version1; + char *major_version2; res = PQexec(conn, - "WITH pg_version(ver) AS " - "(SELECT split_part(version(), ' ', 2)) " - "SELECT split_part(ver, '.', 1), split_part(ver, '.', 2) " - "FROM pg_version"); + "WITH pg_version(ver) AS " + "(SELECT split_part(version(), ' ', 2)) " + "SELECT split_part(ver, '.', 1), split_part(ver, '.', 2) " + "FROM pg_version"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { log_err(_("Version check PQexec failed: %s"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); PQclear(res); return NULL; } @@ -204,7 +210,7 @@ pg_version(PGconn *conn, char* major_version) { /* form a major version string */ xsnprintf(major_version, MAXVERSIONSTR, "%d.%s", major_version1, - major_version2); + major_version2); } else strcpy(major_version, ""); @@ -217,21 +223,21 @@ pg_version(PGconn *conn, char* major_version) int guc_set(PGconn *conn, const char *parameter, const char *op, - const char *value) + const char *value) { - PGresult *res; + PGresult *res; char sqlquery[QUERY_STR_LEN]; int retval = 1; sqlquery_snprintf(sqlquery, "SELECT true FROM pg_settings " - " WHERE name = '%s' AND setting %s '%s'", - parameter, op, value); + " WHERE name = '%s' AND setting %s '%s'", + parameter, op, value); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { log_err(_("GUC setting check PQexec failed: %s"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); retval = -1; } else if (PQntuples(res) == 0) @@ -249,22 +255,22 @@ guc_set(PGconn *conn, const char *parameter, const char *op, * the pg datatype so that the comparison can be done properly. */ int -guc_set_typed(PGconn *conn, const char *parameter, const char *op, - const char *value, const char *datatype) +guc_set_typed(PGconn *conn, const char *parameter, const char *op, + const char *value, const char *datatype) { - PGresult *res; + PGresult *res; char sqlquery[QUERY_STR_LEN]; int retval = 1; sqlquery_snprintf(sqlquery, "SELECT true FROM pg_settings " - " WHERE name = '%s' AND setting::%s %s '%s'::%s", - parameter, datatype, op, value, datatype); + " WHERE name = '%s' AND setting::%s %s '%s'::%s", + parameter, datatype, op, value, datatype); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { log_err(_("GUC setting check PQexec failed: %s"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); retval = -1; } else if (PQntuples(res) == 0) @@ -281,20 +287,20 @@ guc_set_typed(PGconn *conn, const char *parameter, const char *op, const char * get_cluster_size(PGconn *conn) { - PGresult *res; - const char *size = NULL; - char sqlquery[QUERY_STR_LEN]; + PGresult *res; + const char *size = NULL; + char sqlquery[QUERY_STR_LEN]; sqlquery_snprintf( - sqlquery, - "SELECT pg_size_pretty(SUM(pg_database_size(oid))::bigint) " - " FROM pg_database "); + sqlquery, + "SELECT pg_size_pretty(SUM(pg_database_size(oid))::bigint) " + " FROM pg_database "); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { log_err(_("Get cluster size PQexec failed: %s"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); } else { @@ -309,23 +315,23 @@ get_cluster_size(PGconn *conn) * get a connection to master by reading repl_nodes, creating a connection * to each node (one at a time) and finding if it is a master or a standby * - * NB: If master_conninfo_out may be NULL. If it is non-null, it is assumed to + * NB: If master_conninfo_out may be NULL. If it is non-null, it is assumed to * point to allocated memory of MAXCONNINFO in length, and the master server * connection string is placed there. */ PGconn * getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, - int *master_id, char *master_conninfo_out) + int *master_id, char *master_conninfo_out) { - PGconn *master_conn = NULL; - PGresult *res1; - PGresult *res2; - char sqlquery[QUERY_STR_LEN]; - char master_conninfo_stack[MAXCONNINFO]; - char *master_conninfo = &*master_conninfo_stack; - char schema_quoted[MAXLEN]; + PGconn *master_conn = NULL; + PGresult *res1; + PGresult *res2; + char sqlquery[QUERY_STR_LEN]; + char master_conninfo_stack[MAXCONNINFO]; + char *master_conninfo = &*master_conninfo_stack; + char schema_quoted[MAXLEN]; - int i; + int i; /* * If the caller wanted to get a copy of the connection info string, sub @@ -340,8 +346,8 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, * Assemble the unquoted schema name */ { - char *identifier = PQescapeIdentifier(standby_conn, schema, - strlen(schema)); + char *identifier = PQescapeIdentifier(standby_conn, schema, + strlen(schema)); maxlen_snprintf(schema_quoted, "%s", identifier); PQfreemem(identifier); @@ -349,17 +355,17 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, /* find all nodes belonging to this cluster */ log_info(_("finding node list for cluster '%s'\n"), - cluster); + cluster); sqlquery_snprintf(sqlquery, "SELECT id, conninfo FROM %s.repl_nodes " - " WHERE cluster = '%s' and not witness", - schema_quoted, cluster); + " WHERE cluster = '%s' and not witness", + schema_quoted, cluster); res1 = PQexec(standby_conn, sqlquery); if (PQresultStatus(res1) != PGRES_TUPLES_OK) { log_err(_("Can't get nodes info: %s\n"), - PQerrorMessage(standby_conn)); + PQerrorMessage(standby_conn)); PQclear(res1); return NULL; } @@ -370,7 +376,7 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, *master_id = atoi(PQgetvalue(res1, i, 0)); strncpy(master_conninfo, PQgetvalue(res1, i, 1), MAXCONNINFO); log_info(_("checking role of cluster node '%s'\n"), - master_conninfo); + master_conninfo); master_conn = establishDBConnection(master_conninfo, false); if (PQstatus(master_conn) != CONNECTION_OK) @@ -378,15 +384,15 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, /* * Can't use the is_standby() function here because on error that - * function closes the connection passed and exits. This still - * needs to close master_conn first. + * function closes the connection passed and exits. This still needs + * to close master_conn first. */ res2 = PQexec(master_conn, "SELECT pg_is_in_recovery()"); if (PQresultStatus(res2) != PGRES_TUPLES_OK) { log_err(_("Can't get recovery state from this node: %s\n"), - PQerrorMessage(master_conn)); + PQerrorMessage(master_conn)); PQclear(res2); PQfinish(master_conn); continue; @@ -408,14 +414,13 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, } } - /* If we finish this loop without finding a master then - * we doesn't have the info or the master has failed (or we - * reached max_connections or superuser_reserved_connections, - * anything else I'm missing?). + /* + * If we finish this loop without finding a master then we doesn't have + * the info or the master has failed (or we reached max_connections or + * superuser_reserved_connections, anything else I'm missing?). * - * Probably we will need to check the error to know if we need - * to start failover procedure or just fix some situation on the - * standby. + * Probably we will need to check the error to know if we need to start + * failover procedure or just fix some situation on the standby. */ PQclear(res1); return NULL; @@ -423,17 +428,19 @@ getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, /* - * wait until current query finishes ignoring any results, this could be an async command - * or a cancelation of a query + * wait until current query finishes ignoring any results, this could be an + * async command or a cancelation of a query * return 1 if Ok; 0 if any error ocurred; -1 if timeout reached */ int wait_connection_availability(PGconn *conn, long long timeout) { PGresult *res; - fd_set read_set; - int sock = PQsocket(conn); - struct timeval tmout, before, after; + fd_set read_set; + int sock = PQsocket(conn); + struct timeval tmout, + before, + after; struct timezone tz; /* recalc to microseconds */ @@ -450,10 +457,11 @@ wait_connection_availability(PGconn *conn, long long timeout) if (PQisBusy(conn) == 0) { - do { + do + { res = PQgetResult(conn); PQclear(res); - } while(res != NULL); + } while (res != NULL); break; } @@ -469,8 +477,8 @@ wait_connection_availability(PGconn *conn, long long timeout) if (select(sock, &read_set, NULL, NULL, &tmout) == -1) { log_warning( - _("wait_connection_availability: select() returned with error: %s"), - strerror(errno)); + _("wait_connection_availability: select() returned with error: %s"), + strerror(errno)); return -1; } gettimeofday(&after, &tz); @@ -493,8 +501,8 @@ wait_connection_availability(PGconn *conn, long long timeout) bool CancelQuery(PGconn *conn, int timeout) { - char errbuf[ERRBUFF_SIZE]; - PGcancel *pgcancel; + char errbuf[ERRBUFF_SIZE]; + PGcancel *pgcancel; if (wait_connection_availability(conn, timeout) != 1) return false; @@ -505,9 +513,8 @@ CancelQuery(PGconn *conn, int timeout) return false; /* - * PQcancel can only return 0 if socket()/connect()/send() - * fails, in any of those cases we can assume something - * bad happened to the connection + * PQcancel can only return 0 if socket()/connect()/send() fails, in any + * of those cases we can assume something bad happened to the connection */ if (PQcancel(pgcancel, errbuf, ERRBUFF_SIZE) == 0) { diff --git a/dbutils.h b/dbutils.h index 5fb882bc..72c3accb 100644 --- a/dbutils.h +++ b/dbutils.h @@ -22,23 +22,24 @@ #include "strutil.h" -PGconn *establishDBConnection(const char *conninfo, const bool exit_on_error); +PGconn *establishDBConnection(const char *conninfo, const bool exit_on_error); PGconn *establishDBConnectionByParams(const char *keywords[], - const char *values[], - const bool exit_on_error); -int is_standby(PGconn *conn); -int is_witness(PGconn *conn, char *schema, char *cluster, int node_id); -bool is_pgup(PGconn *conn, int timeout); -char *pg_version(PGconn *conn, char* major_version); -int guc_set(PGconn *conn, const char *parameter, const char *op, - const char *value); -int guc_set_typed(PGconn *conn, const char *parameter, const char *op, - const char *value, const char *datatype); + const char *values[], + const bool exit_on_error); +int is_standby(PGconn *conn); +int is_witness(PGconn *conn, char *schema, char *cluster, int node_id); +bool is_pgup(PGconn *conn, int timeout); +char *pg_version(PGconn *conn, char *major_version); +int guc_set(PGconn *conn, const char *parameter, const char *op, + const char *value); +int guc_set_typed(PGconn *conn, const char *parameter, const char *op, + const char *value, const char *datatype); -const char *get_cluster_size(PGconn *conn); +const char *get_cluster_size(PGconn *conn); PGconn *getMasterConnection(PGconn *standby_conn, char *schema, char *cluster, - int *master_id, char *master_conninfo_out); + int *master_id, char *master_conninfo_out); + +int wait_connection_availability(PGconn *conn, long long timeout); +bool CancelQuery(PGconn *conn, int timeout); -int wait_connection_availability(PGconn *conn, long long timeout); -bool CancelQuery(PGconn *conn, int timeout); #endif diff --git a/errcode.h b/errcode.h index be09a3d7..e3114716 100644 --- a/errcode.h +++ b/errcode.h @@ -34,7 +34,7 @@ #define ERR_BAD_PASSWORD 9 #define ERR_STR_OVERFLOW 10 #define ERR_FAILOVER_FAIL 11 -#define ERR_BAD_SSH 12 +#define ERR_BAD_SSH 12 #define ERR_SYS_FAILURE 13 -#endif /* _ERRCODE_H_ */ +#endif /* _ERRCODE_H_ */ diff --git a/log.c b/log.c index bde662db..127107d5 100644 --- a/log.c +++ b/log.c @@ -39,15 +39,18 @@ /* #define REPMGR_DEBUG */ -void stderr_log_with_level(const char *level_name, int level, const char *fmt, ...) { - size_t len = strlen(fmt); - char fmt1[len + 150]; - time_t t; - struct tm *tm; - char buff[100]; - va_list ap; +void +stderr_log_with_level(const char *level_name, int level, const char *fmt,...) +{ + size_t len = strlen(fmt); + char fmt1[len + 150]; + time_t t; + struct tm *tm; + char buff[100]; + va_list ap; - if(log_level >= level) { + if (log_level >= level) + { time(&t); tm = localtime(&t); @@ -64,20 +67,20 @@ void stderr_log_with_level(const char *level_name, int level, const char *fmt, . } -static int detect_log_level(const char* level); -static int detect_log_facility(const char* facility); +static int detect_log_level(const char *level); +static int detect_log_facility(const char *facility); -int log_type = REPMGR_STDERR; -int log_level = LOG_NOTICE; +int log_type = REPMGR_STDERR; +int log_level = LOG_NOTICE; -bool logger_init(t_configuration_options *opts, const char* ident, const char* level, const char* facility) +bool +logger_init(t_configuration_options * opts, const char *ident, const char *level, const char *facility) { - - int l; - int f; + int l; + int f; #ifdef HAVE_SYSLOG - int syslog_facility = DEFAULT_SYSLOG_FACILITY; + int syslog_facility = DEFAULT_SYSLOG_FACILITY; #endif #ifdef REPMGR_DEBUG @@ -134,17 +137,17 @@ bool logger_init(t_configuration_options *opts, const char* ident, const char* l if (log_type == REPMGR_SYSLOG) { - setlogmask (LOG_UPTO (log_level)); - openlog (ident, LOG_CONS | LOG_PID | LOG_NDELAY, syslog_facility); + setlogmask(LOG_UPTO(log_level)); + openlog(ident, LOG_CONS | LOG_PID | LOG_NDELAY, syslog_facility); stderr_log_notice(_("Setup syslog (level: %s, facility: %s)\n"), level, facility); } - #endif if (*opts->logfile) { - FILE *fd; + FILE *fd; + fd = freopen(opts->logfile, "a", stderr); if (fd == NULL) @@ -158,9 +161,9 @@ bool logger_init(t_configuration_options *opts, const char* ident, const char* l } -bool logger_shutdown(void) +bool +logger_shutdown(void) { - #ifdef HAVE_SYSLOG if (log_type == REPMGR_SYSLOG) closelog(); @@ -174,13 +177,15 @@ bool logger_shutdown(void) * options, which might increase requested logging over what's specified * in the regular configuration file. */ -void logger_min_verbose(int minimum) +void +logger_min_verbose(int minimum) { if (log_level < minimum) log_level = minimum; } -int detect_log_level(const char* level) +int +detect_log_level(const char *level) { if (!strcmp(level, "DEBUG")) return LOG_DEBUG; @@ -202,40 +207,42 @@ int detect_log_level(const char* level) return 0; } -int detect_log_facility(const char* facility) +int +detect_log_facility(const char *facility) { - int local = 0; + int local = 0; + if (!strncmp(facility, "LOCAL", 5) && strlen(facility) == 6) { - local = atoi (&facility[5]); + local = atoi(&facility[5]); switch (local) { - case 0: - return LOG_LOCAL0; - break; - case 1: - return LOG_LOCAL1; - break; - case 2: - return LOG_LOCAL2; - break; - case 3: - return LOG_LOCAL3; - break; - case 4: - return LOG_LOCAL4; - break; - case 5: - return LOG_LOCAL5; - break; - case 6: - return LOG_LOCAL6; - break; - case 7: - return LOG_LOCAL7; - break; + case 0: + return LOG_LOCAL0; + break; + case 1: + return LOG_LOCAL1; + break; + case 2: + return LOG_LOCAL2; + break; + case 3: + return LOG_LOCAL3; + break; + case 4: + return LOG_LOCAL4; + break; + case 5: + return LOG_LOCAL5; + break; + case 6: + return LOG_LOCAL6; + break; + case 7: + return LOG_LOCAL7; + break; } } diff --git a/log.h b/log.h index 5fd48000..6faebf07 100644 --- a/log.h +++ b/log.h @@ -25,7 +25,9 @@ #define REPMGR_SYSLOG 1 #define REPMGR_STDERR 2 -void stderr_log_with_level(const char *level_name, int level, const char *fmt, ...) __attribute__ ((format (PG_PRINTF_ATTRIBUTE, 3, 4))); +void +stderr_log_with_level(const char *level_name, int level, const char *fmt,...) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); /* Standard error logging */ #define stderr_log_debug(...) stderr_log_with_level("DEBUG", LOG_DEBUG, __VA_ARGS__) @@ -88,17 +90,16 @@ void stderr_log_with_level(const char *level_name, int level, const char *fmt, . if (log_type == REPMGR_SYSLOG) syslog(LOG_ALERT, __VA_ARGS__); \ else stderr_log_alert(__VA_ARGS__); \ } - #else -#define LOG_EMERG 0 /* system is unusable */ -#define LOG_ALERT 1 /* action must be taken immediately */ -#define LOG_CRIT 2 /* critical conditions */ -#define LOG_ERR 3 /* error conditions */ -#define LOG_WARNING 4 /* warning conditions */ -#define LOG_NOTICE 5 /* normal but significant condition */ -#define LOG_INFO 6 /* informational */ -#define LOG_DEBUG 7 /* debug-level messages */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ #define log_debug(...) stderr_log_debug(__VA_ARGS__) #define log_info(...) stderr_log_info(__VA_ARGS__) @@ -108,16 +109,18 @@ void stderr_log_with_level(const char *level_name, int level, const char *fmt, . #define log_crit(...) stderr_log_crit(__VA_ARGS__) #define log_alert(...) stderr_log_alert(__VA_ARGS__) #define log_emerg(...) stderr_log_emerg(__VA_ARGS__) - #endif /* Logger initialisation and shutdown */ -bool logger_shutdown(void); -bool logger_init(t_configuration_options *opts, const char* ident, const char* level, const char* facility); -void logger_min_verbose(int minimum); +bool logger_shutdown(void); -extern int log_type; -extern int log_level; +bool logger_init(t_configuration_options * opts, const char *ident, + const char *level, const char *facility); + +void logger_min_verbose(int minimum); + +extern int log_type; +extern int log_level; #endif diff --git a/repmgr.c b/repmgr.c index 53a35d82..fe0294bb 100644 --- a/repmgr.c +++ b/repmgr.c @@ -44,23 +44,23 @@ #define RECOVERY_DONE_FILE "recovery.done" #define NO_ACTION 0 /* Not a real action, just to initialize */ -#define MASTER_REGISTER 1 +#define MASTER_REGISTER 1 #define STANDBY_REGISTER 2 -#define STANDBY_CLONE 3 +#define STANDBY_CLONE 3 #define STANDBY_PROMOTE 4 -#define STANDBY_FOLLOW 5 -#define WITNESS_CREATE 6 -#define CLUSTER_SHOW 7 +#define STANDBY_FOLLOW 5 +#define WITNESS_CREATE 6 +#define CLUSTER_SHOW 7 #define CLUSTER_CLEANUP 8 static bool create_recovery_file(const char *data_dir); -static int test_ssh_connection(char *host, char *remote_user); -static int copy_remote_files(char *host, char *remote_user, char *remote_path, - char *local_path, bool is_directory); +static int test_ssh_connection(char *host, char *remote_user); +static int copy_remote_files(char *host, char *remote_user, char *remote_path, + char *local_path, bool is_directory); static bool check_parameters_for_action(const int action); static bool create_schema(PGconn *conn); static bool copy_configuration(PGconn *masterconn, PGconn *witnessconn); -static void write_primary_conninfo(char* line); +static void write_primary_conninfo(char *line); static void do_master_register(void); static void do_standby_register(void); @@ -78,18 +78,18 @@ static void help(const char *progname); static const char *progname; static const char *keywords[6]; static const char *values[6]; -char repmgr_schema[MAXLEN]; -bool need_a_node = true; +char repmgr_schema[MAXLEN]; +bool need_a_node = true; /* XXX This should be mapped into a command line option */ -bool require_password = false; +bool require_password = false; /* Initialization of runtime options */ t_runtime_options runtime_options = T_RUNTIME_OPTIONS_INITIALIZER; t_configuration_options options = T_CONFIGURATION_OPTIONS_INITIALIZER; -static char *server_mode = NULL; -static char *server_cmd = NULL; +static char *server_mode = NULL; +static char *server_cmd = NULL; int main(int argc, char **argv) @@ -135,80 +135,79 @@ main(int argc, char **argv) while ((c = getopt_long(argc, argv, "d:h:p:U:D:l:f:R:w:k:FWIv", long_options, - &optindex)) != -1) + &optindex)) != -1) { switch (c) { - case 'd': - strncpy(runtime_options.dbname, optarg, MAXLEN); - break; - case 'h': - strncpy(runtime_options.host, optarg, MAXLEN); - break; - case 'p': - if (atoi(optarg) > 0) - strncpy(runtime_options.masterport, optarg, MAXLEN); - break; - case 'U': - strncpy(runtime_options.username, optarg, MAXLEN); - break; - case 'D': - strncpy(runtime_options.dest_dir, optarg, MAXFILENAME); - break; - case 'l': - if (atoi(optarg) > 0) - strncpy(runtime_options.localport, optarg, MAXLEN); - break; - case 'f': - strncpy(runtime_options.config_file, optarg, MAXLEN); - break; - case 'R': - strncpy(runtime_options.remote_user, optarg, MAXLEN); - break; - case 'w': - if (atoi(optarg) > 0) - strncpy(runtime_options.wal_keep_segments, optarg, MAXLEN); - break; - case 'k': - if (atoi(optarg) > 0) - runtime_options.keep_history = atoi(optarg); - else - runtime_options.keep_history = 0; - break; - case 'F': - runtime_options.force = true; - break; - case 'W': - runtime_options.wait_for_master = true; - break; - case 'I': - runtime_options.ignore_rsync_warn = true; - break; - case 'v': - runtime_options.verbose = true; - break; - default: - usage(); - exit(ERR_BAD_CONFIG); + case 'd': + strncpy(runtime_options.dbname, optarg, MAXLEN); + break; + case 'h': + strncpy(runtime_options.host, optarg, MAXLEN); + break; + case 'p': + if (atoi(optarg) > 0) + strncpy(runtime_options.masterport, optarg, MAXLEN); + break; + case 'U': + strncpy(runtime_options.username, optarg, MAXLEN); + break; + case 'D': + strncpy(runtime_options.dest_dir, optarg, MAXFILENAME); + break; + case 'l': + if (atoi(optarg) > 0) + strncpy(runtime_options.localport, optarg, MAXLEN); + break; + case 'f': + strncpy(runtime_options.config_file, optarg, MAXLEN); + break; + case 'R': + strncpy(runtime_options.remote_user, optarg, MAXLEN); + break; + case 'w': + if (atoi(optarg) > 0) + strncpy(runtime_options.wal_keep_segments, optarg, MAXLEN); + break; + case 'k': + if (atoi(optarg) > 0) + runtime_options.keep_history = atoi(optarg); + else + runtime_options.keep_history = 0; + break; + case 'F': + runtime_options.force = true; + break; + case 'W': + runtime_options.wait_for_master = true; + break; + case 'I': + runtime_options.ignore_rsync_warn = true; + break; + case 'v': + runtime_options.verbose = true; + break; + default: + usage(); + exit(ERR_BAD_CONFIG); } } /* * Now we need to obtain the action, this comes in one of these forms: - * MASTER REGISTER | - * STANDBY {REGISTER | CLONE [node] | PROMOTE | FOLLOW [node]} | - * WITNESS CREATE - * CLUSTER {SHOW | CLEANUP} + * MASTER REGISTER | STANDBY {REGISTER | CLONE [node] | PROMOTE | FOLLOW + * [node]} | WITNESS CREATE CLUSTER {SHOW | CLEANUP} * - * the node part is optional, if we receive it then we shouldn't - * have received a -h option + * the node part is optional, if we receive it then we shouldn't have + * received a -h option */ if (optind < argc) { server_mode = argv[optind++]; - if (strcasecmp(server_mode, "STANDBY") != 0 && strcasecmp(server_mode, "MASTER") != 0 && - strcasecmp(server_mode, "WITNESS") != 0 && - strcasecmp(server_mode, "CLUSTER") != 0 ) + if (strcasecmp(server_mode, "STANDBY") != 0 && + strcasecmp(server_mode, "MASTER") != 0 && + strcasecmp(server_mode, "WITNESS") != 0 && + strcasecmp(server_mode, "CLUSTER") != 0) { usage(); exit(ERR_BAD_CONFIG); @@ -237,9 +236,9 @@ main(int argc, char **argv) } else if (strcasecmp(server_mode, "CLUSTER") == 0) { - if( strcasecmp(server_cmd, "SHOW") == 0) + if (strcasecmp(server_cmd, "SHOW") == 0) action = CLUSTER_SHOW; - else if(strcasecmp(server_cmd, "CLEANUP") == 0) + else if (strcasecmp(server_cmd, "CLEANUP") == 0) action = CLUSTER_CLEANUP; } else if (strcasecmp(server_mode, "WITNESS") == 0) @@ -271,7 +270,7 @@ main(int argc, char **argv) if (optind < argc) { log_err(_("%s: too many command-line arguments (first extra is \"%s\")\n"), - progname, argv[optind]); + progname, argv[optind]); usage(); exit(ERR_BAD_CONFIG); } @@ -294,7 +293,8 @@ main(int argc, char **argv) strncpy(runtime_options.config_file, DEFAULT_CONFIG_FILE, MAXLEN); if (runtime_options.verbose) - printf(_("Opening configuration file: %s\n"), runtime_options.config_file); + printf(_("Opening configuration file: %s\n"), + runtime_options.config_file); /* * XXX Do not read config files for action where it is not required (clone @@ -312,63 +312,63 @@ main(int argc, char **argv) values[5] = NULL; /* - * Initialize the logger. If verbose command line parameter was - * input, make sure that the log level is at least INFO. This - * is mainly useful for STANDBY CLONE. That doesn't require a - * configuration file where a logging level might be specified - * at, but it often requires detailed logging to troubleshoot - * problems. + * Initialize the logger. If verbose command line parameter was input, + * make sure that the log level is at least INFO. This is mainly useful + * for STANDBY CLONE. That doesn't require a configuration file where a + * logging level might be specified at, but it often requires detailed + * logging to troubleshoot problems. */ logger_init(&options, progname, options.loglevel, options.logfacility); if (runtime_options.verbose) logger_min_verbose(LOG_INFO); /* - * Node configuration information is not needed for all actions, - * with STANDBY CLONE being the main exception. + * Node configuration information is not needed for all actions, with + * STANDBY CLONE being the main exception. */ if (need_a_node) { if (options.node == -1) { log_err(_("Node information is missing. " - "Check the configuration file.\n")); + "Check the configuration file.\n")); exit(ERR_BAD_CONFIG); } } /* Prepare the repmgr schema variable */ - snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, options.cluster_name); + snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, + options.cluster_name); switch (action) { - case MASTER_REGISTER: - do_master_register(); - break; - case STANDBY_REGISTER: - do_standby_register(); - break; - case STANDBY_CLONE: - do_standby_clone(); - break; - case STANDBY_PROMOTE: - do_standby_promote(); - break; - case STANDBY_FOLLOW: - do_standby_follow(); - break; - case WITNESS_CREATE: - do_witness_create(); - break; - case CLUSTER_SHOW: - do_cluster_show(); - break; - case CLUSTER_CLEANUP: - do_cluster_cleanup(); - break; - default: - usage(); - exit(ERR_BAD_CONFIG); + case MASTER_REGISTER: + do_master_register(); + break; + case STANDBY_REGISTER: + do_standby_register(); + break; + case STANDBY_CLONE: + do_standby_clone(); + break; + case STANDBY_PROMOTE: + do_standby_promote(); + break; + case STANDBY_FOLLOW: + do_standby_follow(); + break; + case WITNESS_CREATE: + do_witness_create(); + break; + case CLUSTER_SHOW: + do_cluster_show(); + break; + case CLUSTER_CLEANUP: + do_cluster_cleanup(); + break; + default: + usage(); + exit(ERR_BAD_CONFIG); } logger_shutdown(); @@ -378,22 +378,24 @@ main(int argc, char **argv) static void do_cluster_show(void) { - PGconn *conn; - PGresult *res; - char sqlquery[QUERY_STR_LEN]; - char node_role[MAXLEN]; - int i; + PGconn *conn; + PGresult *res; + char sqlquery[QUERY_STR_LEN]; + char node_role[MAXLEN]; + int i; /* We need to connect to check configuration */ log_info(_("%s connecting to database\n"), progname); conn = establishDBConnection(options.conninfo, true); - sqlquery_snprintf(sqlquery, "SELECT conninfo, witness FROM %s.repl_nodes;", repmgr_schema); + sqlquery_snprintf(sqlquery, "SELECT conninfo, witness FROM %s.repl_nodes;", + repmgr_schema); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get nodes information, have you registered them?\n%s\n"), PQerrorMessage(conn)); + log_err(_("Can't get nodes information, have you registered them?\n%s\n"), + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -425,11 +427,11 @@ do_cluster_show(void) static void do_cluster_cleanup(void) { - int master_id; - PGconn *conn = NULL; - PGconn *master_conn = NULL; - PGresult *res; - char sqlquery[QUERY_STR_LEN]; + int master_id; + PGconn *conn = NULL; + PGconn *master_conn = NULL; + PGresult *res; + char sqlquery[QUERY_STR_LEN]; /* We need to connect to check configuration */ log_info(_("%s connecting to database\n"), progname); @@ -438,7 +440,7 @@ do_cluster_cleanup(void) /* check if there is a master in this cluster */ log_info(_("%s connecting to master database\n"), progname); master_conn = getMasterConnection(conn, repmgr_schema, options.cluster_name, - &master_id, NULL); + &master_id, NULL); if (!master_conn) { log_err(_("cluster cleanup: cannot connect to master\n")); @@ -450,24 +452,29 @@ do_cluster_cleanup(void) if (runtime_options.keep_history > 0) { sqlquery_snprintf(sqlquery, "DELETE FROM %s.repl_monitor " - " WHERE age(now(), last_monitor_time) >= '%d days'::interval;", - repmgr_schema, runtime_options.keep_history); + " WHERE age(now(), last_monitor_time) >= '%d days'::interval;", + repmgr_schema, runtime_options.keep_history); } else { - sqlquery_snprintf(sqlquery, "TRUNCATE TABLE %s.repl_monitor;", repmgr_schema); + sqlquery_snprintf(sqlquery, "TRUNCATE TABLE %s.repl_monitor;", + repmgr_schema); } res = PQexec(master_conn, sqlquery); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - log_err(_("cluster cleanup: Couldn't clean history\n%s\n"), PQerrorMessage(master_conn)); + log_err(_("cluster cleanup: Couldn't clean history\n%s\n"), + PQerrorMessage(master_conn)); PQclear(res); PQfinish(master_conn); exit(ERR_BAD_CONFIG); } PQclear(res); - /* Let's VACUUM the table to avoid autovacuum to be launched in an unexpected hour */ + /* + * Let's VACUUM the table to avoid autovacuum to be launched in an + * unexpected hour + */ sqlquery_snprintf(sqlquery, "VACUUM %s.repl_monitor;", repmgr_schema); res = PQexec(master_conn, sqlquery); @@ -481,14 +488,15 @@ do_cluster_cleanup(void) static void do_master_register(void) { - PGconn *conn; - PGresult *res; - char sqlquery[QUERY_STR_LEN], *ret_ver; + PGconn *conn; + PGresult *res; + char sqlquery[QUERY_STR_LEN], + *ret_ver; bool schema_exists = false; char schema_quoted[MAXLEN]; - char master_version[MAXVERSIONSTR]; - int ret; + char master_version[MAXVERSIONSTR]; + int ret; conn = establishDBConnection(options.conninfo, true); @@ -499,7 +507,8 @@ do_master_register(void) { PQfinish(conn); if (ret_ver != NULL) - log_err( _("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), + progname); return; } @@ -516,13 +525,14 @@ do_master_register(void) exit(ERR_BAD_CONFIG); } - /* Assemble a quoted schema name - * XXX This is not currently used due to a merge conflict, but - * probably should be */ + /* + * Assemble a quoted schema name XXX This is not currently used due to a + * merge conflict, but probably should be + */ if (false) { - char *identifier = PQescapeIdentifier(conn, repmgr_schema, - strlen(repmgr_schema)); + char *identifier = PQescapeIdentifier(conn, repmgr_schema, + strlen(repmgr_schema)); maxlen_snprintf(schema_quoted, "%s", identifier); PQfreemem(identifier); @@ -530,8 +540,8 @@ do_master_register(void) /* Check if there is a schema for this cluster */ sqlquery_snprintf(sqlquery, - "SELECT 1 FROM pg_namespace " - "WHERE nspname = '%s'", repmgr_schema); + "SELECT 1 FROM pg_namespace " + "WHERE nspname = '%s'", repmgr_schema); log_debug(_("master register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -542,9 +552,9 @@ do_master_register(void) exit(ERR_BAD_CONFIG); } - if (PQntuples(res) > 0) /* schema exists */ + if (PQntuples(res) > 0) /* schema exists */ { - if (!runtime_options.force) /* and we are not forcing so error */ + if (!runtime_options.force) /* and we are not forcing so error */ { log_notice(_("Schema %s already exists.\n"), repmgr_schema); PQclear(res); @@ -557,7 +567,8 @@ do_master_register(void) if (!schema_exists) { - log_info(_("master register: creating database objects inside the %s schema\n"), repmgr_schema); + log_info(_("master register: creating database objects inside the %s schema\n"), + repmgr_schema); /* ok, create the schema */ if (!create_schema(conn)) @@ -565,8 +576,8 @@ do_master_register(void) } else { - PGconn *master_conn; - int id; + PGconn *master_conn; + int id; if (runtime_options.force) { @@ -588,11 +599,12 @@ do_master_register(void) /* Ensure there isn't any other master already registered */ master_conn = getMasterConnection(conn, repmgr_schema, - options.cluster_name, &id,NULL); + options.cluster_name, &id, NULL); if (master_conn != NULL) { PQfinish(master_conn); - log_warning(_("There is a master already in cluster %s\n"), options.cluster_name); + log_warning(_("There is a master already in cluster %s\n"), + options.cluster_name); exit(ERR_BAD_CONFIG); } } @@ -600,16 +612,16 @@ do_master_register(void) /* Now register the master */ sqlquery_snprintf(sqlquery, "INSERT INTO %s.repl_nodes (id, cluster, name, conninfo, priority) " - "VALUES (%d, '%s', '%s', '%s', %d)", - repmgr_schema, options.node, options.cluster_name, options.node_name, - options.conninfo, options.priority); + "VALUES (%d, '%s', '%s', '%s', %d)", + repmgr_schema, options.node, options.cluster_name, options.node_name, + options.conninfo, options.priority); log_debug(_("master register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_warning(_("Cannot insert node details, %s\n"), - PQerrorMessage(conn)); + PQerrorMessage(conn)); PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -617,7 +629,7 @@ do_master_register(void) PQfinish(conn); log_notice(_("Master node correctly registered for cluster %s with id %d (conninfo: %s)\n"), - options.cluster_name, options.node, options.conninfo); + options.cluster_name, options.node, options.conninfo); return; } @@ -625,16 +637,18 @@ do_master_register(void) static void do_standby_register(void) { - PGconn *conn; - PGconn *master_conn; - int master_id, ret; + PGconn *conn; + PGconn *master_conn; + int master_id, + ret; - PGresult *res; - char sqlquery[QUERY_STR_LEN], *ret_ver; + PGresult *res; + char sqlquery[QUERY_STR_LEN], + *ret_ver; char schema_quoted[MAXLEN]; - char master_version[MAXVERSIONSTR]; - char standby_version[MAXVERSIONSTR]; + char master_version[MAXVERSIONSTR]; + char standby_version[MAXVERSIONSTR]; /* XXX: A lot of copied code from do_master_register! Refactor */ @@ -648,7 +662,8 @@ do_standby_register(void) { PQfinish(conn); if (ret_ver != NULL) - log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), + progname); exit(ERR_BAD_CONFIG); } @@ -657,31 +672,34 @@ do_standby_register(void) if (ret == 0 || ret == -1) { log_err(_(ret == 0 ? "repmgr: This node should be a standby (%s)\n" : - "repmgr: connection to node (%s) lost\n"), options.conninfo); + "repmgr: connection to node (%s) lost\n"), options.conninfo); PQfinish(conn); exit(ERR_BAD_CONFIG); } - /* Assemble a quoted schema name - * XXX This is not currently used due to a merge conflict, but - * probably should be */ + /* + * Assemble a quoted schema name XXX This is not currently used due to a + * merge conflict, but probably should be + */ if (false) { - char *identifier = PQescapeIdentifier(conn, repmgr_schema, - strlen(repmgr_schema)); + char *identifier = PQescapeIdentifier(conn, repmgr_schema, + strlen(repmgr_schema)); maxlen_snprintf(schema_quoted, "%s", identifier); PQfreemem(identifier); } /* Check if there is a schema for this cluster */ - sqlquery_snprintf(sqlquery, "SELECT 1 FROM pg_namespace WHERE nspname = '%s'", repmgr_schema); + sqlquery_snprintf(sqlquery, "SELECT 1 FROM pg_namespace WHERE nspname = '%s'", + repmgr_schema); log_debug(_("standby register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get info about tablespaces: %s\n"), PQerrorMessage(conn)); + log_err(_("Can't get info about tablespaces: %s\n"), + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -700,7 +718,7 @@ do_standby_register(void) /* check if there is a master in this cluster */ log_info(_("%s connecting to master database\n"), progname); master_conn = getMasterConnection(conn, repmgr_schema, options.cluster_name, - &master_id, NULL); + &master_id, NULL); if (!master_conn) { log_err(_("A master must be defined before configuring a slave\n")); @@ -715,7 +733,8 @@ do_standby_register(void) PQfinish(conn); PQfinish(master_conn); if (ret_ver != NULL) - log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), + progname); exit(ERR_BAD_CONFIG); } @@ -725,7 +744,7 @@ do_standby_register(void) PQfinish(conn); PQfinish(master_conn); log_err(_("%s needs versions of both master (%s) and standby (%s) to match.\n"), - progname, master_version, standby_version); + progname, master_version, standby_version); exit(ERR_BAD_CONFIG); } @@ -734,8 +753,8 @@ do_standby_register(void) if (runtime_options.force) { sqlquery_snprintf(sqlquery, "DELETE FROM %s.repl_nodes " - " WHERE id = %d", - repmgr_schema, options.node); + " WHERE id = %d", + repmgr_schema, options.node); log_debug(_("standby register: %s\n"), sqlquery); @@ -743,7 +762,7 @@ do_standby_register(void) if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Cannot delete node details, %s\n"), - PQerrorMessage(master_conn)); + PQerrorMessage(master_conn)); PQfinish(master_conn); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -752,16 +771,16 @@ do_standby_register(void) } sqlquery_snprintf(sqlquery, "INSERT INTO %s.repl_nodes(id, cluster, name, conninfo, priority) " - "VALUES (%d, '%s', '%s', '%s', %d)", - repmgr_schema, options.node, options.cluster_name, options.node_name, - options.conninfo, options.priority); + "VALUES (%d, '%s', '%s', '%s', %d)", + repmgr_schema, options.node, options.cluster_name, options.node_name, + options.conninfo, options.priority); log_debug(_("standby register: %s\n"), sqlquery); res = PQexec(master_conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Cannot insert node details, %s\n"), - PQerrorMessage(master_conn)); + PQerrorMessage(master_conn)); PQfinish(master_conn); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -771,7 +790,7 @@ do_standby_register(void) PQfinish(master_conn); PQfinish(conn); log_notice(_("Standby node correctly registered for cluster %s with id %d (conninfo: %s)\n"), - options.cluster_name, options.node, options.conninfo); + options.cluster_name, options.node, options.conninfo); return; } @@ -779,13 +798,16 @@ do_standby_register(void) static void do_standby_clone(void) { - PGconn *conn; - PGresult *res; - char sqlquery[QUERY_STR_LEN], *ret; + PGconn *conn; + PGresult *res; + char sqlquery[QUERY_STR_LEN], + *ret; const char *cluster_size; - int r = 0, retval = SUCCESS; - int i, is_standby_retval; + int r = 0, + retval = SUCCESS; + int i, + is_standby_retval; bool flag_success = false; bool test_mode = false; @@ -807,21 +829,22 @@ do_standby_clone(void) char master_ident_file[MAXFILENAME]; char local_ident_file[MAXFILENAME]; - char *first_wal_segment = NULL; - const char *last_wal_segment = NULL; + char *first_wal_segment = NULL; + const char *last_wal_segment = NULL; char master_version[MAXVERSIONSTR]; /* - * if dest_dir has been provided, we copy everything in the same path - * if dest_dir is set and the master have tablespace, repmgr will stop + * if dest_dir has been provided, we copy everything in the same path if + * dest_dir is set and the master have tablespace, repmgr will stop * because it is more complex to remap the path for the tablespaces and it * does not look useful at the moment */ if (runtime_options.dest_dir[0]) { test_mode = true; - log_notice(_("%s Destination directory %s provided, try to clone everything in it.\n"), progname, runtime_options.dest_dir); + log_notice(_("%s Destination directory %s provided, try to clone everything in it.\n"), + progname, runtime_options.dest_dir); } /* Connection parameters for master only */ @@ -832,7 +855,7 @@ do_standby_clone(void) /* We need to connect to check configuration and start a backup */ log_info(_("%s connecting to master database\n"), progname); - conn = establishDBConnectionByParams(keywords,values,true); + conn = establishDBConnectionByParams(keywords, values, true); /* primary should be v9 or better */ log_info(_("%s connected to master, checking its state\n"), progname); @@ -841,7 +864,8 @@ do_standby_clone(void) { PQfinish(conn); if (ret != NULL) - log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), + progname); exit(ERR_BAD_CONFIG); } @@ -862,16 +886,19 @@ do_standby_clone(void) { PQfinish(conn); if (i == 0) - log_err(_("%s needs parameter 'wal_level' to be set to 'hot_standby'\n"), progname); + log_err(_("%s needs parameter 'wal_level' to be set to 'hot_standby'\n"), + progname); exit(ERR_BAD_CONFIG); } - i = guc_set_typed(conn, "wal_keep_segments", ">=", runtime_options.wal_keep_segments, "integer"); + i = guc_set_typed(conn, "wal_keep_segments", ">=", + runtime_options.wal_keep_segments, "integer"); if (i == 0 || i == -1) { PQfinish(conn); if (i == 0) - log_err(_("%s needs parameter 'wal_keep_segments' to be set to %s or greater (see the '-w' option or edit the postgresql.conf of the PostgreSQL master.)\n"), progname, runtime_options.wal_keep_segments); + log_err(_("%s needs parameter 'wal_keep_segments' to be set to %s or greater (see the '-w' option or edit the postgresql.conf of the PostgreSQL master.)\n"), + progname, runtime_options.wal_keep_segments); exit(ERR_BAD_CONFIG); } @@ -880,7 +907,8 @@ do_standby_clone(void) { PQfinish(conn); if (i == 0) - log_err(_("%s needs parameter 'archive_mode' to be set to 'on'\n"), progname); + log_err(_("%s needs parameter 'archive_mode' to be set to 'on'\n"), + progname); exit(ERR_BAD_CONFIG); } @@ -889,24 +917,25 @@ do_standby_clone(void) { PQfinish(conn); if (i == 0) - log_err(_("%s needs parameter 'hot_standby' to be set to 'on'\n"), progname); + log_err(_("%s needs parameter 'hot_standby' to be set to 'on'\n"), + progname); exit(ERR_BAD_CONFIG); } /* - * Check if the tablespace locations exists and that we can write to - * them. + * Check if the tablespace locations exists and that we can write to them. */ - if (strcmp(master_version, "9.0") == 0 || strcmp(master_version, "9.1") == 0) + if (strcmp(master_version, "9.0") == 0 || + strcmp(master_version, "9.1") == 0) sqlquery_snprintf(sqlquery, - "SELECT spclocation " - " FROM pg_tablespace " - "WHERE spcname NOT IN ('pg_default', 'pg_global')"); + "SELECT spclocation " + " FROM pg_tablespace " + "WHERE spcname NOT IN ('pg_default', 'pg_global')"); else sqlquery_snprintf(sqlquery, - "SELECT pg_tablespace_location(oid) spclocation " - " FROM pg_tablespace " - "WHERE spcname NOT IN ('pg_default', 'pg_global')"); + "SELECT pg_tablespace_location(oid) spclocation " + " FROM pg_tablespace " + "WHERE spcname NOT IN ('pg_default', 'pg_global')"); log_debug("standby clone: %s\n", sqlquery); @@ -929,10 +958,11 @@ do_standby_clone(void) } strncpy(tblspc_dir, PQgetvalue(res, i, 0), MAXFILENAME); + /* - * Check this directory could be used for tablespace - * this will create the directory a bit too early - * XXX build an array of tablespace to create later in the backup + * Check this directory could be used for tablespace this will create + * the directory a bit too early XXX build an array of tablespace to + * create later in the backup */ if (!create_pgdir(tblspc_dir, runtime_options.force)) { @@ -945,14 +975,15 @@ do_standby_clone(void) /* Get the data directory full path and the configuration files location */ sqlquery_snprintf(sqlquery, - "SELECT name, setting " - " FROM pg_settings " - " WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file', 'stats_temp_directory')"); + "SELECT name, setting " + " FROM pg_settings " + " WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file', 'stats_temp_directory')"); log_debug(_("standby clone: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get info about data directory and configuration files: %s\n"), PQerrorMessage(conn)); + log_err(_("Can't get info about data directory and configuration files: %s\n"), + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -978,7 +1009,8 @@ do_standby_clone(void) else if (strcmp(PQgetvalue(res, i, 0), "ident_file") == 0) strncpy(master_ident_file, PQgetvalue(res, i, 1), MAXFILENAME); else if (strcmp(PQgetvalue(res, i, 0), "stats_temp_directory") == 0) - strncpy(master_stats_temp_directory, PQgetvalue(res, i, 1), MAXFILENAME); + strncpy(master_stats_temp_directory, PQgetvalue(res, i, 1), + MAXFILENAME); else log_warning(_("unknown parameter: %s\n"), PQgetvalue(res, i, 0)); } @@ -987,11 +1019,13 @@ do_standby_clone(void) cluster_size = get_cluster_size(conn); if (cluster_size == NULL) exit(ERR_DB_QUERY); - log_info(_("Successfully connected to primary. Current installation size is %s\n"), cluster_size); + log_info(_("Successfully connected to primary. Current installation size is %s\n"), + cluster_size); /* - * XXX master_xlog_directory should be discovered from master configuration - * but it is not possible via SQL. We need to use a command via ssh + * XXX master_xlog_directory should be discovered from master + * configuration but it is not possible via SQL. We need to use a command + * via ssh */ maxlen_snprintf(master_xlog_directory, "%s/pg_xlog", master_data_directory); if (test_mode) @@ -1000,8 +1034,10 @@ do_standby_clone(void) strncpy(local_config_file, runtime_options.dest_dir, MAXFILENAME); strncpy(local_hba_file, runtime_options.dest_dir, MAXFILENAME); strncpy(local_ident_file, runtime_options.dest_dir, MAXFILENAME); - maxlen_snprintf(local_stats_temp_directory, "%s/pg_stat_tmp", runtime_options.dest_dir); - maxlen_snprintf(local_xlog_directory, "%s/pg_xlog", runtime_options.dest_dir); + maxlen_snprintf(local_stats_temp_directory, "%s/pg_stat_tmp", + runtime_options.dest_dir); + maxlen_snprintf(local_xlog_directory, "%s/pg_xlog", + runtime_options.dest_dir); } else { @@ -1009,14 +1045,16 @@ do_standby_clone(void) strncpy(local_config_file, master_config_file, MAXFILENAME); strncpy(local_hba_file, master_hba_file, MAXFILENAME); strncpy(local_ident_file, master_ident_file, MAXFILENAME); - strncpy(local_stats_temp_directory, master_stats_temp_directory, MAXFILENAME); + strncpy(local_stats_temp_directory, master_stats_temp_directory, + MAXFILENAME); strncpy(local_xlog_directory, master_xlog_directory, MAXFILENAME); } r = test_ssh_connection(runtime_options.host, runtime_options.remote_user); if (r != 0) { - log_err(_("%s: Aborting, remote host %s is not reachable.\n"), progname, runtime_options.host); + log_err(_("%s: Aborting, remote host %s is not reachable.\n"), + progname, runtime_options.host); PQfinish(conn); exit(ERR_BAD_SSH); } @@ -1024,8 +1062,8 @@ do_standby_clone(void) log_notice(_("Starting backup...\n")); /* - * in pg 9.1 default is to wait for a sync standby to ack, - * avoid that by turning off sync rep for this session + * in pg 9.1 default is to wait for a sync standby to ack, avoid that by + * turning off sync rep for this session */ sqlquery_snprintf(sqlquery, "SET synchronous_commit TO OFF"); res = PQexec(conn, sqlquery); @@ -1038,13 +1076,13 @@ do_standby_clone(void) } /* - * inform the master we will start a backup and get the first XLog filename - * so we can say to the user we need those files + * inform the master we will start a backup and get the first XLog + * filename so we can say to the user we need those files */ sqlquery_snprintf( - sqlquery, - "SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))", - time(NULL)); + sqlquery, + "SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))", + time(NULL)); log_debug(_("standby clone: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -1057,8 +1095,8 @@ do_standby_clone(void) if (runtime_options.verbose) { - char *first_wal_seg_pq = PQgetvalue(res, 0, 0); - size_t buf_sz = strlen(first_wal_seg_pq); + char *first_wal_seg_pq = PQgetvalue(res, 0, 0); + size_t buf_sz = strlen(first_wal_seg_pq); first_wal_segment = malloc(buf_sz + 1); xsnprintf(first_wal_segment, buf_sz + 1, "%s", first_wal_seg_pq); @@ -1070,7 +1108,7 @@ do_standby_clone(void) if (!create_pgdir(local_data_directory, runtime_options.force)) { log_err(_("%s: couldn't use directory %s ...\nUse --force option to force\n"), - progname, local_data_directory); + progname, local_data_directory); r = ERR_BAD_CONFIG; retval = ERR_BAD_CONFIG; goto stop_backup; @@ -1079,72 +1117,80 @@ do_standby_clone(void) /* * 1) first move global/pg_control * - * 2) then move data_directory ommiting the files we have already moved and - * pg_xlog content + * 2) then move data_directory ommiting the files we have already moved + * and pg_xlog content * - * 3) finally We need to backup configuration files (that could be on other - * directories, debian like systems likes to do that), so look at - * config_file, hba_file and ident_file but we can omit - * external_pid_file ;) + * 3) finally We need to backup configuration files (that could be on + * other directories, debian like systems likes to do that), so look at + * config_file, hba_file and ident_file but we can omit external_pid_file + * ;) * * On error we need to return but before that execute pg_stop_backup() */ /* need to create the global sub directory */ - maxlen_snprintf(master_control_file, "%s/global/pg_control", master_data_directory); + maxlen_snprintf(master_control_file, "%s/global/pg_control", + master_data_directory); maxlen_snprintf(local_control_file, "%s/global", local_data_directory); - log_info(_("standby clone: master control file '%s'\n"), master_control_file); + log_info(_("standby clone: master control file '%s'\n"), + master_control_file); if (!create_directory(local_control_file)) { log_err(_("%s: couldn't create directory %s ...\n"), - progname, local_control_file); + progname, local_control_file); goto stop_backup; } - log_info(_("standby clone: master control file '%s'\n"), master_control_file); + log_info(_("standby clone: master control file '%s'\n"), + master_control_file); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_control_file, local_control_file, - false); + master_control_file, local_control_file, + false); if (r != 0) { - log_warning(_("standby clone: failed copying master control file '%s'\n"), master_control_file); + log_warning(_("standby clone: failed copying master control file '%s'\n"), + master_control_file); goto stop_backup; } - log_info(_("standby clone: master data directory '%s'\n"), master_data_directory); + log_info(_("standby clone: master data directory '%s'\n"), + master_data_directory); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_data_directory, local_data_directory, - true); + master_data_directory, local_data_directory, + true); if (r != 0) { - log_warning(_("standby clone: failed copying master data directory '%s'\n"), master_data_directory); + log_warning(_("standby clone: failed copying master data directory '%s'\n"), + master_data_directory); goto stop_backup; } /* * Copy tablespace locations, i'm doing this separately because i couldn't * find and appropiate rsync option but besides we could someday make all - * these rsync happen concurrently - * XXX We may not do that if we are in test_mode but it does not hurt too much - * (except if a tablespace is created during the test) + * these rsync happen concurrently XXX We may not do that if we are in + * test_mode but it does not hurt too much (except if a tablespace is + * created during the test) */ - if (strcmp(master_version, "9.0") == 0 || strcmp(master_version, "9.1") == 0) + if (strcmp(master_version, "9.0") == 0 || + strcmp(master_version, "9.1") == 0) sqlquery_snprintf(sqlquery, - "SELECT spclocation " - " FROM pg_tablespace " - " WHERE spcname NOT IN ('pg_default', 'pg_global')"); + "SELECT spclocation " + " FROM pg_tablespace " + " WHERE spcname NOT IN ('pg_default', 'pg_global')"); else sqlquery_snprintf(sqlquery, - "SELECT pg_tablespace_location(oid) spclocation " - " FROM pg_tablespace " - " WHERE spcname NOT IN ('pg_default', 'pg_global')"); + "SELECT pg_tablespace_location(oid) spclocation " + " FROM pg_tablespace " + " WHERE spcname NOT IN ('pg_default', 'pg_global')"); log_debug("standby clone: %s\n", sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get info about tablespaces: %s\n"), PQerrorMessage(conn)); + log_err(_("Can't get info about tablespaces: %s\n"), + PQerrorMessage(conn)); PQclear(res); goto stop_backup; } @@ -1153,11 +1199,12 @@ do_standby_clone(void) strncpy(tblspc_dir, PQgetvalue(res, i, 0), MAXFILENAME); log_info(_("standby clone: master tablespace '%s'\n"), tblspc_dir); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - tblspc_dir, tblspc_dir, - true); + tblspc_dir, tblspc_dir, + true); if (r != 0) { - log_warning(_("standby clone: failed copying tablespace directory '%s'\n"), tblspc_dir); + log_warning(_("standby clone: failed copying tablespace directory '%s'\n"), + tblspc_dir); PQclear(res); goto stop_backup; } @@ -1166,31 +1213,34 @@ do_standby_clone(void) log_info(_("standby clone: master config file '%s'\n"), master_config_file); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_config_file, local_config_file, - false); + master_config_file, local_config_file, + false); if (r != 0) { - log_warning(_("standby clone: failed copying master config file '%s'\n"), master_config_file); + log_warning(_("standby clone: failed copying master config file '%s'\n"), + master_config_file); goto stop_backup; } log_info(_("standby clone: master hba file '%s'\n"), master_hba_file); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_hba_file, local_hba_file, - false); + master_hba_file, local_hba_file, + false); if (r != 0) { - log_warning(_("standby clone: failed copying master hba file '%s'\n"), master_hba_file); + log_warning(_("standby clone: failed copying master hba file '%s'\n"), + master_hba_file); goto stop_backup; } log_info(_("standby clone: master ident file '%s'\n"), master_ident_file); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_ident_file, local_ident_file, - false); + master_ident_file, local_ident_file, + false); if (r != 0) { - log_warning(_("standby clone: failed copying master ident file '%s'\n"), master_ident_file); + log_warning(_("standby clone: failed copying master ident file '%s'\n"), + master_ident_file); goto stop_backup; } @@ -1218,7 +1268,7 @@ stop_backup: if (runtime_options.verbose) log_info(_("%s requires primary to keep WAL files %s until at least %s\n"), - progname, first_wal_segment, last_wal_segment); + progname, first_wal_segment, last_wal_segment); /* Finished with the database connection now */ PQclear(res); @@ -1235,7 +1285,7 @@ stop_backup: if (r != 0) { log_err(_("Couldn't rsync the master...\nYou have to cleanup the destination directory (%s) manually!\n"), - local_data_directory); + local_data_directory); exit(ERR_BAD_RSYNC); } @@ -1245,26 +1295,28 @@ stop_backup: if (!create_directory(local_xlog_directory)) { log_err(_("%s: couldn't create directory %s, you will need to do it manually...\n"), - progname, local_xlog_directory); - r = ERR_NEEDS_XLOG; /* continue, but eventually exit returning error */ + progname, local_xlog_directory); + r = ERR_NEEDS_XLOG; /* continue, but eventually exit returning + * error */ } /* Finally, write the recovery.conf file */ create_recovery_file(local_data_directory); /* - * We don't start the service yet because we still may want to - * move the directory + * We don't start the service yet because we still may want to move the + * directory */ log_notice(_("%s standby clone complete\n"), progname); - /* HINT message : what to do next ? */ + /* HINT message : what to do next ? */ if (flag_success) { log_notice("HINT: You can now start your postgresql server\n"); if (test_mode) { - log_notice(_("for example : pg_ctl -D %s start\n"), local_data_directory); + log_notice(_("for example : pg_ctl -D %s start\n"), + local_data_directory); } else { @@ -1278,20 +1330,22 @@ stop_backup: static void do_standby_promote(void) { - PGconn *conn; - PGresult *res; - char sqlquery[QUERY_STR_LEN], *ret; + PGconn *conn; + PGresult *res; + char sqlquery[QUERY_STR_LEN], + *ret; char script[MAXLEN]; - PGconn *old_master_conn; + PGconn *old_master_conn; int old_master_id; - int r, retval; + int r, + retval; char data_dir[MAXLEN]; char recovery_file_path[MAXFILENAME]; char recovery_done_path[MAXFILENAME]; - char standby_version[MAXVERSIONSTR]; + char standby_version[MAXVERSIONSTR]; /* We need to connect to check configuration */ log_info(_("%s connecting to master database\n"), progname); @@ -1303,7 +1357,8 @@ do_standby_promote(void) if (ret == NULL || strcmp(standby_version, "") == 0) { if (ret != NULL) - log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), + progname); PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -1320,8 +1375,8 @@ do_standby_promote(void) } /* we also need to check if there isn't any master already */ - old_master_conn = getMasterConnection(conn, repmgr_schema, options.cluster_name, - &old_master_id, NULL); + old_master_conn = getMasterConnection(conn, repmgr_schema, + options.cluster_name, &old_master_id, NULL); if (old_master_conn != NULL) { log_err(_("There is a master already in this cluster\n")); @@ -1334,12 +1389,13 @@ do_standby_promote(void) /* Get the data directory full path and the last subdirectory */ sqlquery_snprintf(sqlquery, "SELECT setting " - " FROM pg_settings WHERE name = 'data_directory'"); + " FROM pg_settings WHERE name = 'data_directory'"); log_debug(_("standby promote: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get info about data directory: %s\n"), PQerrorMessage(conn)); + log_err(_("Can't get info about data directory: %s\n"), + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -1358,8 +1414,10 @@ do_standby_promote(void) * below will find an active server rather than one starting up. This may * hang for up the default timeout (60 seconds). */ - log_notice(_("%s: restarting server using %s/pg_ctl\n"), progname, options.pg_bindir); - maxlen_snprintf(script, "%s/pg_ctl %s -D %s -w -m fast restart", options.pg_bindir, options.pgctl_options, data_dir); + log_notice(_("%s: restarting server using %s/pg_ctl\n"), progname, + options.pg_bindir); + maxlen_snprintf(script, "%s/pg_ctl %s -D %s -w -m fast restart", + options.pg_bindir, options.pgctl_options, data_dir); r = system(script); if (r != 0) { @@ -1373,12 +1431,14 @@ do_standby_promote(void) retval = is_standby(conn); if (retval) { - log_err(_(retval == 1 ? "%s: STANDBY PROMOTE failed, this is still a standby node.\n" : + log_err(_(retval == 1 ? + "%s: STANDBY PROMOTE failed, this is still a standby node.\n" : "%s: connection to node lost!\n"), progname); } else { - log_err(_("%s: STANDBY PROMOTE successful. You should REINDEX any hash indexes you have.\n"), progname); + log_err(_("%s: STANDBY PROMOTE successful. You should REINDEX any hash indexes you have.\n"), + progname); } PQfinish(conn); return; @@ -1388,19 +1448,21 @@ do_standby_promote(void) static void do_standby_follow(void) { - PGconn *conn; - PGresult *res; - char sqlquery[QUERY_STR_LEN], *ret; + PGconn *conn; + PGresult *res; + char sqlquery[QUERY_STR_LEN], + *ret; char script[MAXLEN]; char master_conninfo[MAXLEN]; - PGconn *master_conn; + PGconn *master_conn; int master_id; - int r, retval; + int r, + retval; char data_dir[MAXLEN]; - char master_version[MAXVERSIONSTR]; - char standby_version[MAXVERSIONSTR]; + char master_version[MAXVERSIONSTR]; + char standby_version[MAXVERSIONSTR]; /* We need to connect to check configuration */ log_info(_("%s connecting to standby database\n"), progname); @@ -1423,14 +1485,15 @@ do_standby_follow(void) if (ret == NULL || strcmp(standby_version, "") == 0) { if (ret != NULL) - log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), + progname); PQfinish(conn); exit(ERR_BAD_CONFIG); } /* - * we also need to check if there is any master in the cluster - * or wait for one to appear if we have set the wait option + * we also need to check if there is any master in the cluster or wait for + * one to appear if we have set the wait option */ log_info(_("%s discovering new master...\n"), progname); @@ -1442,7 +1505,7 @@ do_standby_follow(void) } master_conn = getMasterConnection(conn, repmgr_schema, - options.cluster_name, &master_id,(char *) &master_conninfo); + options.cluster_name, &master_id, (char *) &master_conninfo); } while (master_conn == NULL && runtime_options.wait_for_master); @@ -1471,7 +1534,8 @@ do_standby_follow(void) if (ret == NULL || strcmp(master_version, "") == 0) { if (ret != NULL) - log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), + progname); PQfinish(conn); PQfinish(master_conn); exit(ERR_BAD_CONFIG); @@ -1481,32 +1545,33 @@ do_standby_follow(void) if (strcmp(master_version, standby_version) != 0) { log_err(_("%s needs versions of both master (%s) and standby (%s) to match.\n"), - progname, master_version, standby_version); + progname, master_version, standby_version); PQfinish(conn); PQfinish(master_conn); exit(ERR_BAD_CONFIG); } /* - * set the host and masterport variables with the master ones - * before closing the connection because we will need them to - * recreate the recovery.conf file + * set the host and masterport variables with the master ones before + * closing the connection because we will need them to recreate the + * recovery.conf file */ strncpy(runtime_options.host, PQhost(master_conn), MAXLEN); strncpy(runtime_options.masterport, PQport(master_conn), MAXLEN); strncpy(runtime_options.username, PQuser(master_conn), MAXLEN); PQfinish(master_conn); - log_info(_("%s Changing standby's master\n"),progname); + log_info(_("%s Changing standby's master\n"), progname); /* Get the data directory full path */ sqlquery_snprintf(sqlquery, "SELECT setting " - " FROM pg_settings WHERE name = 'data_directory'"); + " FROM pg_settings WHERE name = 'data_directory'"); log_debug(_("standby follow: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get info about data directory: %s\n"), PQerrorMessage(conn)); + log_err(_("Can't get info about data directory: %s\n"), + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); exit(ERR_BAD_CONFIG); @@ -1520,7 +1585,8 @@ do_standby_follow(void) exit(ERR_BAD_CONFIG); /* Finally, restart the service */ - maxlen_snprintf(script, "%s/pg_ctl %s -w -D %s -m fast restart", options.pg_bindir, options.pgctl_options, data_dir); + maxlen_snprintf(script, "%s/pg_ctl %s -w -D %s -m fast restart", + options.pg_bindir, options.pgctl_options, data_dir); r = system(script); if (r != 0) { @@ -1535,16 +1601,18 @@ do_standby_follow(void) static void do_witness_create(void) { - PGconn *masterconn; - PGconn *witnessconn; - PGresult *res; - char sqlquery[QUERY_STR_LEN], *ret; + PGconn *masterconn; + PGconn *witnessconn; + PGresult *res; + char sqlquery[QUERY_STR_LEN], + *ret; char script[MAXLEN]; char buf[MAXLEN]; - FILE *pg_conf = NULL; + FILE *pg_conf = NULL; - int r = 0, retval; + int r = 0, + retval; int i; char master_version[MAXVERSIONSTR]; @@ -1570,7 +1638,8 @@ do_witness_create(void) if (ret == NULL || strcmp(master_version, "") == 0) { if (ret != NULL) - log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), progname); + log_err(_("%s needs master to be PostgreSQL 9.0 or better\n"), + progname); PQfinish(masterconn); exit(ERR_BAD_CONFIG); } @@ -1579,7 +1648,8 @@ do_witness_create(void) retval = is_standby(masterconn); if (retval) { - log_err(_(retval == 1 ? "The command should not run on a standby node\n" : + log_err(_(retval == 1 ? + "The command should not run on a standby node\n" : "Connection to node lost!\n")); PQfinish(masterconn); @@ -1591,7 +1661,8 @@ do_witness_create(void) r = test_ssh_connection(runtime_options.host, runtime_options.remote_user); if (r != 0) { - log_err(_("%s: Aborting, remote host %s is not reachable.\n"), progname, runtime_options.host); + log_err(_("%s: Aborting, remote host %s is not reachable.\n"), + progname, runtime_options.host); PQfinish(masterconn); exit(ERR_BAD_SSH); } @@ -1600,20 +1671,19 @@ do_witness_create(void) if (!create_pgdir(runtime_options.dest_dir, runtime_options.force)) { log_err(_("witness create: couldn't create data directory (\"%s\") for witness"), - runtime_options.dest_dir); + runtime_options.dest_dir); exit(ERR_BAD_CONFIG); } /* - * To create a witness server we need to: - * 1) initialize the cluster - * 2) register the witness in repl_nodes - * 3) copy configuration from master + * To create a witness server we need to: 1) initialize the cluster 2) + * register the witness in repl_nodes 3) copy configuration from master */ /* Create the cluster for witness */ - sprintf(script, "%s/pg_ctl %s -D %s init -o \"-W\"", options.pg_bindir, options.pgctl_options, runtime_options.dest_dir); + sprintf(script, "%s/pg_ctl %s -D %s init -o \"-W\"", options.pg_bindir, + options.pgctl_options, runtime_options.dest_dir); log_info("Initialize cluster for witness: %s.\n", script); r = system(script); @@ -1625,14 +1695,15 @@ do_witness_create(void) } /* - * default port for the witness is 5499, - * but user can provide a different one + * default port for the witness is 5499, but user can provide a different + * one */ snprintf(buf, sizeof(buf), "%s/postgresql.conf", runtime_options.dest_dir); pg_conf = fopen(buf, "a"); if (pg_conf == NULL) { - log_err(_("%s: could not open \"%s\" for adding extra config: %s\n"), progname, buf, strerror(errno)); + log_err(_("%s: could not open \"%s\" for adding extra config: %s\n"), + progname, buf, strerror(errno)); PQfinish(masterconn); exit(ERR_BAD_CONFIG); } @@ -1645,23 +1716,24 @@ do_witness_create(void) snprintf(buf, sizeof(buf), "port = %s\n", runtime_options.localport); fputs(buf, pg_conf); - snprintf(buf, sizeof(buf), "shared_preload_libraries = 'repmgr_funcs'\n") ; + snprintf(buf, sizeof(buf), "shared_preload_libraries = 'repmgr_funcs'\n"); fputs(buf, pg_conf); - snprintf(buf, sizeof(buf), "listen_addresses = '*'\n") ; + snprintf(buf, sizeof(buf), "listen_addresses = '*'\n"); fputs(buf, pg_conf); fclose(pg_conf); /* Get the pg_hba.conf full path */ sqlquery_snprintf(sqlquery, "SELECT name, setting " - " FROM pg_settings " - " WHERE name IN ('hba_file')"); + " FROM pg_settings " + " WHERE name IN ('hba_file')"); log_debug(_("witness create: %s"), sqlquery); res = PQexec(masterconn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("Can't get info about pg_hba.conf: %s\n"), PQerrorMessage(masterconn)); + log_err(_("Can't get info about pg_hba.conf: %s\n"), + PQerrorMessage(masterconn)); PQclear(res); PQfinish(masterconn); exit(ERR_DB_QUERY); @@ -1676,8 +1748,8 @@ do_witness_create(void) PQclear(res); r = copy_remote_files(runtime_options.host, runtime_options.remote_user, - master_hba_file, runtime_options.dest_dir, - false); + master_hba_file, runtime_options.dest_dir, + false); if (r != 0) { log_err(_("Can't rsync the pg_hba.conf file from master\n")); @@ -1686,7 +1758,8 @@ do_witness_create(void) } /* start new instance */ - sprintf(script, "%s/pg_ctl %s -w -D %s start", options.pg_bindir, options.pgctl_options, runtime_options.dest_dir); + sprintf(script, "%s/pg_ctl %s -w -D %s start", options.pg_bindir, + options.pgctl_options, runtime_options.dest_dir); log_info(_("Start cluster for witness: %s"), script); r = system(script); if (r != 0) @@ -1698,14 +1771,16 @@ do_witness_create(void) /* register ourselves in the master */ sqlquery_snprintf(sqlquery, "INSERT INTO %s.repl_nodes(id, cluster, name, conninfo, priority, witness) " - "VALUES (%d, '%s', '%s', '%s', %d, true)", - repmgr_schema, options.node, options.cluster_name, options.node_name, options.conninfo, options.priority); + "VALUES (%d, '%s', '%s', '%s', %d, true)", + repmgr_schema, options.node, options.cluster_name, + options.node_name, options.conninfo, options.priority); log_debug(_("witness create: %s"), sqlquery); res = PQexec(masterconn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - log_err(_("Cannot insert node details, %s\n"), PQerrorMessage(masterconn)); + log_err(_("Cannot insert node details, %s\n"), + PQerrorMessage(masterconn)); PQfinish(masterconn); exit(ERR_DB_QUERY); } @@ -1753,7 +1828,7 @@ help(const char *progname) printf(_("Usage:\n")); printf(_(" %s [OPTIONS] master {register}\n"), progname); printf(_(" %s [OPTIONS] standby {register|clone|promote|follow}\n"), - progname); + progname); printf(_(" %s [OPTIONS] cluster {show|cleanup}\n"), progname); printf(_("\nGeneral options:\n")); printf(_(" --help show this help, then exit\n")); @@ -1766,17 +1841,17 @@ help(const char *progname) printf(_(" -U, --username=USERNAME database user name to connect as\n")); printf(_("\nConfiguration options:\n")); printf(_(" -D, --data-dir=DIR local directory where the files will be\n" \ - " copied to\n")); + " copied to\n")); printf(_(" -l, --local-port=PORT standby or witness server local port\n")); printf(_(" -f, --config_file=PATH path to the configuration file\n")); printf(_(" -R, --remote-user=USERNAME database server username for rsync\n")); printf(_(" -w, --wal-keep-segments=VALUE minimum value for the GUC\n" \ - " wal_keep_segments (default: 5000)\n")); + " wal_keep_segments (default: 5000)\n")); printf(_(" -I, --ignore-rsync-warning ignore rsync partial transfer warning\n")); printf(_(" -k, --keep-history=VALUE keeps indicated number of days of\n" \ - " history\n")); + " history\n")); printf(_(" -F, --force force potentially dangerous operations\n" \ - " to happen\n")); + " to happen\n")); printf(_(" -W, --wait wait for a master to appear\n")); printf(_("\n%s performs some tasks like clone a node, promote it or making follow\n"), progname); @@ -1786,9 +1861,9 @@ help(const char *progname) printf(_(" standby register - registers a standby in a cluster\n")); printf(_(" standby clone [node] - allows creation of a new standby\n")); printf(_(" standby promote - allows manual promotion of a specific standby into\n" \ - " a new master in the event of a failover\n")); + " a new master in the event of a failover\n")); printf(_(" standby follow - allows the standby to re-point itself to a new\n" \ - " master\n")); + " master\n")); printf(_(" cluster show - print node information\n")); printf(_(" cluster cleanup - cleans monitor's history\n")); } @@ -1800,7 +1875,7 @@ help(const char *progname) static bool create_recovery_file(const char *data_dir) { - FILE *recovery_file; + FILE *recovery_file; char recovery_file_path[MAXLEN]; char line[MAXLEN]; @@ -1830,7 +1905,7 @@ create_recovery_file(const char *data_dir) return false; } - /*FreeFile(recovery_file);*/ + /* FreeFile(recovery_file); */ fclose(recovery_file); return true; @@ -1839,8 +1914,8 @@ create_recovery_file(const char *data_dir) static int test_ssh_connection(char *host, char *remote_user) { - char script[MAXLEN]; - int r; + char script[MAXLEN]; + int r; /* On some OS, true is located in a different place than in Linux */ #ifdef __FreeBSD__ @@ -1851,9 +1926,11 @@ test_ssh_connection(char *host, char *remote_user) /* Check if we have ssh connectivity to host before trying to rsync */ if (!remote_user[0]) - maxlen_snprintf(script, "ssh -o Batchmode=yes %s %s %s", options.ssh_options, host, TRUEBIN_PATH); + maxlen_snprintf(script, "ssh -o Batchmode=yes %s %s %s", + options.ssh_options, host, TRUEBIN_PATH); else - maxlen_snprintf(script, "ssh -o Batchmode=yes %s %s -l %s %s", options.ssh_options, host, remote_user, TRUEBIN_PATH); + maxlen_snprintf(script, "ssh -o Batchmode=yes %s %s -l %s %s", + options.ssh_options, host, remote_user, TRUEBIN_PATH); log_debug(_("command is: %s\n"), script); r = system(script); @@ -1864,17 +1941,17 @@ test_ssh_connection(char *host, char *remote_user) static int copy_remote_files(char *host, char *remote_user, char *remote_path, - char *local_path, bool is_directory) + char *local_path, bool is_directory) { - char script[MAXLEN]; - char rsync_flags[MAXLEN]; - char host_string[MAXLEN]; - int r; + char script[MAXLEN]; + char rsync_flags[MAXLEN]; + char host_string[MAXLEN]; + int r; if (strnlen(options.rsync_options, MAXLEN) == 0) maxlen_snprintf( - rsync_flags, "%s", - "--archive --checksum --compress --progress --rsh=ssh"); + rsync_flags, "%s", + "--archive --checksum --compress --progress --rsh=ssh"); else maxlen_snprintf(rsync_flags, "%s", options.rsync_options); @@ -1887,19 +1964,20 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, } else { - maxlen_snprintf(host_string,"%s@%s",remote_user,host); + maxlen_snprintf(host_string, "%s@%s", remote_user, host); } if (is_directory) { - strcat(rsync_flags, " --exclude=pg_xlog* --exclude=pg_log* --exclude=pg_control --exclude=*.pid"); + strcat(rsync_flags, + " --exclude=pg_xlog* --exclude=pg_log* --exclude=pg_control --exclude=*.pid"); maxlen_snprintf(script, "rsync %s %s:%s/* %s", - rsync_flags, host_string, remote_path, local_path); + rsync_flags, host_string, remote_path, local_path); } else { maxlen_snprintf(script, "rsync %s %s:%s %s", - rsync_flags, host_string, remote_path, local_path); + rsync_flags, host_string, remote_path, local_path); } log_info(_("rsync command line: '%s'\n"), script); @@ -1907,12 +1985,13 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, r = system(script); /* - * If we are transfering a directory (data directory, tablespace directories) - * then we can ignore some rsync warnings. If we get some of those errors, we - * treat them as 0 only if passed the --ignore-rsync-warning command-line option. + * If we are transfering a directory (data directory, tablespace + * directories) then we can ignore some rsync warnings. If we get some of + * those errors, we treat them as 0 only if passed the + * --ignore-rsync-warning command-line option. * - * List of ignorable rsync errors: - * 24 Partial transfer due to vanished source files + * List of ignorable rsync errors: 24 Partial transfer due to vanished + * source files */ if ((WEXITSTATUS(r) == 24) && is_directory) { @@ -1922,17 +2001,17 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, log_info(_("rsync partial transfer warning ignored\n")); } else - log_warning( _("rsync completed with return code 24: " - "\"Partial transfer due to vanished source files\".\n" - "This can happen because of normal operation " - "on the master server, but it may indicate an " - "unexpected change during cloning. If you are certain " - "no changes were made to the master, try cloning " - "again using \"repmgr --force --ignore-rsync-warning\".")); + log_warning(_("rsync completed with return code 24: " + "\"Partial transfer due to vanished source files\".\n" + "This can happen because of normal operation " + "on the master server, but it may indicate an " + "unexpected change during cloning. If you are certain " + "no changes were made to the master, try cloning " + "again using \"repmgr --force --ignore-rsync-warning\".")); } if (r != 0) log_err(_("Can't rsync from remote file or directory (%s:%s)\n"), - host_string, remote_path); + host_string, remote_path); return r; } @@ -1944,127 +2023,133 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, static bool check_parameters_for_action(const int action) { - bool ok = true; + bool ok = true; switch (action) { - case MASTER_REGISTER: - /* - * To register a master we only need the repmgr.conf - * all other parameters are at least useless and could be - * confusing so reject them - */ - if (runtime_options.host[0] || runtime_options.masterport[0] || runtime_options.username[0] || - runtime_options.dbname[0]) - { - log_err(_("You can't use connection parameters to the master when issuing a MASTER REGISTER command.\n")); - usage(); - ok = false; - } - if (runtime_options.dest_dir[0]) - { - log_err(_("You don't need a destination directory for MASTER REGISTER command\n")); - usage(); - ok = false; - } - break; - case STANDBY_REGISTER: - /* - * To register a standby we only need the repmgr.conf - * we don't need connection parameters to the master - * because we can detect the master in repl_nodes - */ - if (runtime_options.host[0] || runtime_options.masterport[0] || runtime_options.username[0] || - runtime_options.dbname[0]) - { - log_err(_("You can't use connection parameters to the master when issuing a STANDBY REGISTER command.\n")); - usage(); - ok = false; - } - if (runtime_options.dest_dir[0]) - { - log_err(_("You don't need a destination directory for STANDBY REGISTER command\n")); - usage(); - ok = false; - } - break; - case STANDBY_PROMOTE: - /* - * To promote a standby we only need the repmgr.conf - * we don't want connection parameters to the master - * because we will try to detect the master in repl_nodes - * if we can't find it then the promote action will be cancelled - */ - if (runtime_options.host[0] || runtime_options.masterport[0] || runtime_options.username[0] || - runtime_options.dbname[0]) - { - log_err(_("You can't use connection parameters to the master when issuing a STANDBY PROMOTE command.\n")); - usage(); - ok = false; - } - if (runtime_options.dest_dir[0]) - { - log_err(_("You don't need a destination directory for STANDBY PROMOTE command\n")); - usage(); - ok = false; - } - break; - case STANDBY_FOLLOW: - /* - * To make a standby follow a master we only need the repmgr.conf - * we don't want connection parameters to the new master - * because we will try to detect the master in repl_nodes - * if we can't find it then the follow action will be cancelled - */ - if (runtime_options.host[0] || runtime_options.masterport[0] || runtime_options.username[0] || - runtime_options.dbname[0]) - { - log_err(_("You can't use connection parameters to the master when issuing a STANDBY FOLLOW command.\n")); - usage(); - ok = false; - } - if (runtime_options.dest_dir[0]) - { - log_err(_("You don't need a destination directory for STANDBY FOLLOW command\n")); - usage(); - ok = false; - } - break; - case STANDBY_CLONE: - /* - * Issue a friendly notice that the configuration file is not - * necessary nor read at all in when performing a STANDBY CLONE - * action. - */ - if (runtime_options.config_file[0]) - { - log_notice(_("Only command line parameters for the connection " - "to the master are used when issuing a STANDBY CLONE command. " - "The passed configuration file is neither required nor used for " - "its node configuration portions\n\n")); - } - /* - * To clone a master into a standby we need connection parameters - * repmgr.conf is useless because we don't have a server running in - * the standby; warn the user, but keep going. - */ - if (runtime_options.host == NULL) - { - log_notice(_("You need to use connection parameters to " - "the master when issuing a STANDBY CLONE command.")); - ok = false; - } - need_a_node = false; - break; - case WITNESS_CREATE: - /* allow all parameters to be supplied */ - break; - case CLUSTER_SHOW: - /* allow all parameters to be supplied */ - break; - case CLUSTER_CLEANUP: - /* allow all parameters to be supplied */ - break; + case MASTER_REGISTER: + + /* + * To register a master we only need the repmgr.conf all other + * parameters are at least useless and could be confusing so + * reject them + */ + if (runtime_options.host[0] || runtime_options.masterport[0] || + runtime_options.username[0] || runtime_options.dbname[0]) + { + log_err(_("You can't use connection parameters to the master when issuing a MASTER REGISTER command.\n")); + usage(); + ok = false; + } + if (runtime_options.dest_dir[0]) + { + log_err(_("You don't need a destination directory for MASTER REGISTER command\n")); + usage(); + ok = false; + } + break; + case STANDBY_REGISTER: + + /* + * To register a standby we only need the repmgr.conf we don't + * need connection parameters to the master because we can detect + * the master in repl_nodes + */ + if (runtime_options.host[0] || runtime_options.masterport[0] || + runtime_options.username[0] || runtime_options.dbname[0]) + { + log_err(_("You can't use connection parameters to the master when issuing a STANDBY REGISTER command.\n")); + usage(); + ok = false; + } + if (runtime_options.dest_dir[0]) + { + log_err(_("You don't need a destination directory for STANDBY REGISTER command\n")); + usage(); + ok = false; + } + break; + case STANDBY_PROMOTE: + + /* + * To promote a standby we only need the repmgr.conf we don't want + * connection parameters to the master because we will try to + * detect the master in repl_nodes if we can't find it then the + * promote action will be cancelled + */ + if (runtime_options.host[0] || runtime_options.masterport[0] || + runtime_options.username[0] || runtime_options.dbname[0]) + { + log_err(_("You can't use connection parameters to the master when issuing a STANDBY PROMOTE command.\n")); + usage(); + ok = false; + } + if (runtime_options.dest_dir[0]) + { + log_err(_("You don't need a destination directory for STANDBY PROMOTE command\n")); + usage(); + ok = false; + } + break; + case STANDBY_FOLLOW: + + /* + * To make a standby follow a master we only need the repmgr.conf + * we don't want connection parameters to the new master because + * we will try to detect the master in repl_nodes if we can't find + * it then the follow action will be cancelled + */ + if (runtime_options.host[0] || runtime_options.masterport[0] || + runtime_options.username[0] || runtime_options.dbname[0]) + { + log_err(_("You can't use connection parameters to the master when issuing a STANDBY FOLLOW command.\n")); + usage(); + ok = false; + } + if (runtime_options.dest_dir[0]) + { + log_err(_("You don't need a destination directory for STANDBY FOLLOW command\n")); + usage(); + ok = false; + } + break; + case STANDBY_CLONE: + + /* + * Issue a friendly notice that the configuration file is not + * necessary nor read at all in when performing a STANDBY CLONE + * action. + */ + if (runtime_options.config_file[0]) + { + log_notice(_("Only command line parameters for the connection " + "to the master are used when issuing a STANDBY CLONE command. " + "The passed configuration file is neither required nor used for " + "its node configuration portions\n\n")); + } + + /* + * To clone a master into a standby we need connection parameters + * repmgr.conf is useless because we don't have a server running + * in the standby; warn the user, but keep going. + */ + if (runtime_options.host == NULL) + { + log_notice(_("You need to use connection parameters to " + "the master when issuing a STANDBY CLONE command.")); + ok = false; + } + need_a_node = false; + break; + case WITNESS_CREATE: + /* allow all parameters to be supplied */ + break; + case CLUSTER_SHOW: + /* allow all parameters to be supplied */ + break; + case CLUSTER_CLEANUP: + /* allow all parameters to be supplied */ + break; } return ok; @@ -2075,8 +2160,8 @@ check_parameters_for_action(const int action) static bool create_schema(PGconn *conn) { - char sqlquery[QUERY_STR_LEN]; - PGresult *res; + char sqlquery[QUERY_STR_LEN]; + PGresult *res; sqlquery_snprintf(sqlquery, "CREATE SCHEMA %s", repmgr_schema); log_debug(_("master register: %s\n"), sqlquery); @@ -2084,23 +2169,25 @@ create_schema(PGconn *conn) if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Cannot create the schema %s: %s\n"), - repmgr_schema, PQerrorMessage(conn)); + repmgr_schema, PQerrorMessage(conn)); PQfinish(conn); exit(ERR_BAD_CONFIG); } PQclear(res); - /* to avoid confusion of the time_lag field and provide a consistent UI we - * use these functions for providing the latest update timestamp */ + /* + * to avoid confusion of the time_lag field and provide a consistent UI we + * use these functions for providing the latest update timestamp + */ sqlquery_snprintf(sqlquery, "CREATE FUNCTION %s.repmgr_update_last_updated() RETURNS TIMESTAMP WITH TIME ZONE " - "AS '$libdir/repmgr_funcs', 'repmgr_update_last_updated' " + "AS '$libdir/repmgr_funcs', 'repmgr_update_last_updated' " " LANGUAGE C STRICT", repmgr_schema); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Cannot create the function repmgr_update_last_updated: %s\n", - PQerrorMessage(conn)); + PQerrorMessage(conn)); return false; } PQclear(res); @@ -2114,7 +2201,7 @@ create_schema(PGconn *conn) if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Cannot create the function repmgr_get_last_updated: %s\n", - PQerrorMessage(conn)); + PQerrorMessage(conn)); return false; } PQclear(res); @@ -2122,38 +2209,38 @@ create_schema(PGconn *conn) /* ... the tables */ sqlquery_snprintf(sqlquery, "CREATE TABLE %s.repl_nodes ( " - " id integer primary key, " - " cluster text not null, " - " name text not null, " - " conninfo text not null, " - " priority integer not null, " - " witness boolean not null default false)", repmgr_schema); + " id integer primary key, " + " cluster text not null, " + " name text not null, " + " conninfo text not null, " + " priority integer not null, " + " witness boolean not null default false)", repmgr_schema); log_debug(_("master register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Cannot create the table %s.repl_nodes: %s\n"), - repmgr_schema, PQerrorMessage(conn)); + repmgr_schema, PQerrorMessage(conn)); PQfinish(conn); exit(ERR_BAD_CONFIG); } PQclear(res); sqlquery_snprintf(sqlquery, "CREATE TABLE %s.repl_monitor ( " - " primary_node INTEGER NOT NULL, " - " standby_node INTEGER NOT NULL, " - " last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL, " - " last_apply_time TIMESTAMP WITH TIME ZONE, " - " last_wal_primary_location TEXT NOT NULL, " - " last_wal_standby_location TEXT, " - " replication_lag BIGINT NOT NULL, " - " apply_lag BIGINT NOT NULL) ", repmgr_schema); + " primary_node INTEGER NOT NULL, " + " standby_node INTEGER NOT NULL, " + " last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL, " + " last_apply_time TIMESTAMP WITH TIME ZONE, " + " last_wal_primary_location TEXT NOT NULL, " + " last_wal_standby_location TEXT, " + " replication_lag BIGINT NOT NULL, " + " apply_lag BIGINT NOT NULL) ", repmgr_schema); log_debug(_("master register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Cannot create the table %s.repl_monitor: %s\n"), - repmgr_schema, PQerrorMessage(conn)); + repmgr_schema, PQerrorMessage(conn)); PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -2161,23 +2248,24 @@ create_schema(PGconn *conn) /* a view */ sqlquery_snprintf(sqlquery, "CREATE VIEW %s.repl_status AS " - " SELECT primary_node, standby_node, name AS standby_name, last_monitor_time, " - " last_wal_primary_location, last_wal_standby_location, " - " pg_size_pretty(replication_lag) replication_lag, " - " age(now(), last_apply_time) AS replication_time_lag, " - " pg_size_pretty(apply_lag) apply_lag, " - " age(now(), CASE WHEN pg_is_in_recovery() THEN %s.repmgr_get_last_updated() ELSE last_monitor_time END) AS communication_time_lag " - " FROM %s.repl_monitor JOIN %s.repl_nodes ON standby_node = id " - " WHERE (standby_node, last_monitor_time) IN (SELECT standby_node, MAX(last_monitor_time) " - " FROM %s.repl_monitor GROUP BY 1)", - repmgr_schema, repmgr_schema, repmgr_schema, repmgr_schema, repmgr_schema); + " SELECT primary_node, standby_node, name AS standby_name, last_monitor_time, " + " last_wal_primary_location, last_wal_standby_location, " + " pg_size_pretty(replication_lag) replication_lag, " + " age(now(), last_apply_time) AS replication_time_lag, " + " pg_size_pretty(apply_lag) apply_lag, " + " age(now(), CASE WHEN pg_is_in_recovery() THEN %s.repmgr_get_last_updated() ELSE last_monitor_time END) AS communication_time_lag " + " FROM %s.repl_monitor JOIN %s.repl_nodes ON standby_node = id " + " WHERE (standby_node, last_monitor_time) IN (SELECT standby_node, MAX(last_monitor_time) " + " FROM %s.repl_monitor GROUP BY 1)", + repmgr_schema, repmgr_schema, repmgr_schema, + repmgr_schema, repmgr_schema); log_debug(_("master register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Cannot create the view %s.repl_status: %s\n"), - repmgr_schema, PQerrorMessage(conn)); + repmgr_schema, PQerrorMessage(conn)); PQfinish(conn); exit(ERR_BAD_CONFIG); } @@ -2185,42 +2273,45 @@ create_schema(PGconn *conn) /* an index to improve performance of the view */ sqlquery_snprintf(sqlquery, "CREATE INDEX idx_repl_status_sort " - " ON %s.repl_monitor (last_monitor_time, standby_node) ", - repmgr_schema); + " ON %s.repl_monitor (last_monitor_time, standby_node) ", + repmgr_schema); log_debug(_("master register: %s\n"), sqlquery); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { log_err(_("Can't index table %s.repl_monitor: %s\n"), - repmgr_schema, PQerrorMessage(conn)); + repmgr_schema, PQerrorMessage(conn)); PQfinish(conn); exit(ERR_BAD_CONFIG); } PQclear(res); - /* XXX Here we MUST try to load the repmgr_function.sql not hardcode it here */ + /* + * XXX Here we MUST try to load the repmgr_function.sql not hardcode it + * here + */ sqlquery_snprintf(sqlquery, - "CREATE OR REPLACE FUNCTION %s.repmgr_update_standby_location(text) RETURNS boolean " - "AS '$libdir/repmgr_funcs', 'repmgr_update_standby_location' " - "LANGUAGE C STRICT ", repmgr_schema); + "CREATE OR REPLACE FUNCTION %s.repmgr_update_standby_location(text) RETURNS boolean " + "AS '$libdir/repmgr_funcs', 'repmgr_update_standby_location' " + "LANGUAGE C STRICT ", repmgr_schema); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Cannot create the function repmgr_update_standby_location: %s\n", - PQerrorMessage(conn)); + PQerrorMessage(conn)); return false; } PQclear(res); sqlquery_snprintf(sqlquery, - "CREATE OR REPLACE FUNCTION %s.repmgr_get_last_standby_location() RETURNS text " - "AS '$libdir/repmgr_funcs', 'repmgr_get_last_standby_location' " - "LANGUAGE C STRICT ", repmgr_schema); + "CREATE OR REPLACE FUNCTION %s.repmgr_get_last_standby_location() RETURNS text " + "AS '$libdir/repmgr_funcs', 'repmgr_get_last_standby_location' " + "LANGUAGE C STRICT ", repmgr_schema); res = PQexec(conn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Cannot create the function repmgr_get_last_standby_location: %s\n", - PQerrorMessage(conn)); + PQerrorMessage(conn)); return false; } PQclear(res); @@ -2233,7 +2324,7 @@ static bool copy_configuration(PGconn *masterconn, PGconn *witnessconn) { char sqlquery[MAXLEN]; - PGresult *res; + PGresult *res; int i; sqlquery_snprintf(sqlquery, "TRUNCATE TABLE %s.repl_nodes", repmgr_schema); @@ -2242,34 +2333,35 @@ copy_configuration(PGconn *masterconn, PGconn *witnessconn) if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Cannot clean node details in the witness, %s\n", - PQerrorMessage(witnessconn)); + PQerrorMessage(witnessconn)); return false; } - sqlquery_snprintf(sqlquery, "SELECT id, name, conninfo, priority, witness FROM %s.repl_nodes", repmgr_schema); + sqlquery_snprintf(sqlquery, "SELECT id, name, conninfo, priority, witness FROM %s.repl_nodes", + repmgr_schema); res = PQexec(masterconn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "Can't get configuration from master: %s\n", - PQerrorMessage(masterconn)); + PQerrorMessage(masterconn)); PQclear(res); return false; } for (i = 0; i < PQntuples(res); i++) { sqlquery_snprintf(sqlquery, "INSERT INTO %s.repl_nodes(id, cluster, name, conninfo, priority, witness) " - "VALUES (%d, '%s', '%s', '%s', %d, '%s')", - repmgr_schema, atoi(PQgetvalue(res, i, 0)), - options.cluster_name, PQgetvalue(res, i, 1), - PQgetvalue(res, i, 2), - atoi(PQgetvalue(res, i, 3)), - PQgetvalue(res, i, 4)); + "VALUES (%d, '%s', '%s', '%s', %d, '%s')", + repmgr_schema, atoi(PQgetvalue(res, i, 0)), + options.cluster_name, PQgetvalue(res, i, 1), + PQgetvalue(res, i, 2), + atoi(PQgetvalue(res, i, 3)), + PQgetvalue(res, i, 4)); res = PQexec(witnessconn, sqlquery); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "Cannot copy configuration to witness, %s\n", - PQerrorMessage(witnessconn)); + PQerrorMessage(witnessconn)); PQclear(res); return false; } @@ -2281,16 +2373,17 @@ copy_configuration(PGconn *masterconn, PGconn *witnessconn) /* This function uses global variables to determine connection settings. Special * usage of the PGPASSWORD variable is handled, but strongly discouraged */ static void -write_primary_conninfo(char* line) +write_primary_conninfo(char *line) { - char host_buf[MAXLEN] = ""; - char conn_buf[MAXLEN] = ""; - char user_buf[MAXLEN] = ""; - char appname_buf[MAXLEN] = ""; - char password_buf[MAXLEN] = ""; + char host_buf[MAXLEN] = ""; + char conn_buf[MAXLEN] = ""; + char user_buf[MAXLEN] = ""; + char appname_buf[MAXLEN] = ""; + char password_buf[MAXLEN] = ""; /* Environment variable for password (UGLY, please use .pgpass!) */ const char *password = getenv("PGPASSWORD"); + if (password != NULL) { maxlen_snprintf(password_buf, " password=%s", password); @@ -2298,7 +2391,7 @@ write_primary_conninfo(char* line) else if (require_password) { log_err(_("%s: PGPASSWORD not set, but having one is required\n"), - progname); + progname); exit(ERR_BAD_PASSWORD); } @@ -2318,8 +2411,9 @@ write_primary_conninfo(char* line) } maxlen_snprintf(conn_buf, "port=%s%s%s%s%s", - (runtime_options.masterport[0]) ? runtime_options.masterport : "5432", host_buf, user_buf, password_buf, - appname_buf); + (runtime_options.masterport[0]) ? runtime_options.masterport : "5432", + host_buf, user_buf, password_buf, + appname_buf); maxlen_snprintf(line, "primary_conninfo = '%s'", conn_buf); diff --git a/repmgr.h b/repmgr.h index 6cfee998..ff1aa2ee 100644 --- a/repmgr.h +++ b/repmgr.h @@ -50,24 +50,24 @@ typedef struct { - char dbname[MAXLEN]; - char host[MAXLEN]; - char username[MAXLEN]; - char dest_dir[MAXFILENAME]; - char config_file[MAXFILENAME]; - char remote_user[MAXLEN]; - char wal_keep_segments[MAXLEN]; - bool verbose; - bool force; - bool wait_for_master; - bool ignore_rsync_warn; + char dbname[MAXLEN]; + char host[MAXLEN]; + char username[MAXLEN]; + char dest_dir[MAXFILENAME]; + char config_file[MAXFILENAME]; + char remote_user[MAXLEN]; + char wal_keep_segments[MAXLEN]; + bool verbose; + bool force; + bool wait_for_master; + bool ignore_rsync_warn; - char masterport[MAXLEN]; - char localport[MAXLEN]; + char masterport[MAXLEN]; + char localport[MAXLEN]; /* parameter used by CLUSTER CLEANUP */ - int keep_history; -} t_runtime_options; + int keep_history; +} t_runtime_options; #define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, "", "", 0 } diff --git a/repmgrd.c b/repmgrd.c index 88a883ff..0d0633ae 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -49,23 +49,22 @@ const XLogRecPtr InvalidXLogRecPtr = {0, 0}; #endif #if PG_VERSION_NUM >= 90300 - #define XLAssign(a, b) \ - a = b +#define XLAssign(a, b) \ + a = b - #define XLAssignValue(a, xlogid, xrecoff) \ - a = xrecoff - - #define XLByteLT(a, b) \ - (a < b) +#define XLAssignValue(a, xlogid, xrecoff) \ + a = xrecoff +#define XLByteLT(a, b) \ + (a < b) #else - #define XLAssign(a, b) \ - a.xlogid = b.xlogid; \ - a.xrecoff = b.xrecoff +#define XLAssign(a, b) \ + a.xlogid = b.xlogid; \ + a.xrecoff = b.xrecoff - #define XLAssignValue(a, uxlogid, uxrecoff) \ - a.xlogid = uxlogid; \ - a.xrecoff = uxrecoff +#define XLAssignValue(a, uxlogid, uxrecoff) \ + a.xlogid = uxlogid; \ + a.xrecoff = uxrecoff #endif @@ -75,39 +74,39 @@ const XLogRecPtr InvalidXLogRecPtr = {0, 0}; */ typedef struct nodeInfo { - int nodeId; - char conninfostr[MAXLEN]; - XLogRecPtr xlog_location; - bool is_ready; - bool is_visible; - bool is_witness; -} nodeInfo; + int nodeId; + char conninfostr[MAXLEN]; + XLogRecPtr xlog_location; + bool is_ready; + bool is_visible; + bool is_witness; +} nodeInfo; -char myClusterName[MAXLEN]; +char myClusterName[MAXLEN]; /* Local info */ t_configuration_options local_options; -int myLocalMode = STANDBY_MODE; -PGconn *myLocalConn = NULL; +int myLocalMode = STANDBY_MODE; +PGconn *myLocalConn = NULL; /* Primary info */ t_configuration_options primary_options; -PGconn *primaryConn = NULL; +PGconn *primaryConn = NULL; -char sqlquery[QUERY_STR_LEN]; +char sqlquery[QUERY_STR_LEN]; const char *progname; -char *config_file = DEFAULT_CONFIG_FILE; -bool verbose = false; -bool monitoring_history = false; -char repmgr_schema[MAXLEN]; +char *config_file = DEFAULT_CONFIG_FILE; +bool verbose = false; +bool monitoring_history = false; +char repmgr_schema[MAXLEN]; -bool failover_done = false; +bool failover_done = false; -char *pid_file = NULL; +char *pid_file = NULL; /* * should initialize with {0} to be ANSI complaint ? but this raises @@ -115,7 +114,7 @@ char *pid_file = NULL; */ t_configuration_options config = T_CONFIGURATION_OPTIONS_INITIALIZER; -static void help(const char* progname); +static void help(const char *progname); static void usage(void); static void checkClusterConfiguration(PGconn *conn); static void checkNodeConfiguration(void); @@ -148,7 +147,8 @@ static void do_daemonize(void); static void check_and_create_pid_file(const char *pid_file); static void -CloseConnections() { +CloseConnections() +{ if (primaryConn != NULL && PQisBusy(primaryConn) == 1) CancelQuery(primaryConn, local_options.master_response_timeout); @@ -177,11 +177,13 @@ main(int argc, char **argv) }; int optindex; - int c, ret; + int c, + ret; bool daemonize = false; - FILE *fd; + FILE *fd; - char standby_version[MAXVERSIONSTR], *ret_ver; + char standby_version[MAXVERSIONSTR], + *ret_ver; progname = get_progname(argv[0]); @@ -203,24 +205,24 @@ main(int argc, char **argv) { switch (c) { - case 'f': - config_file = optarg; - break; - case 'v': - verbose = true; - break; - case 'm': - monitoring_history = true; - break; - case 'd': - daemonize = true; - break; - case 'p': - pid_file = optarg; - break; - default: - usage(); - exit(ERR_BAD_CONFIG); + case 'f': + config_file = optarg; + break; + case 'v': + verbose = true; + break; + case 'm': + monitoring_history = true; + break; + case 'd': + daemonize = true; + break; + case 'p': + pid_file = optarg; + break; + default: + usage(); + exit(ERR_BAD_CONFIG); } } @@ -234,9 +236,9 @@ main(int argc, char **argv) check_and_create_pid_file(pid_file); } - #ifndef WIN32 +#ifndef WIN32 setup_event_handlers(); - #endif +#endif /* * Read the configuration file: repmgr.conf @@ -245,7 +247,7 @@ main(int argc, char **argv) if (local_options.node == -1) { log_err(_("Node information is missing. " - "Check the configuration file, or provide one if you have not done so.\n")); + "Check the configuration file, or provide one if you have not done so.\n")); terminate(ERR_BAD_CONFIG); } @@ -263,7 +265,8 @@ main(int argc, char **argv) strerror(errno)); } - logger_init(&local_options, progname, local_options.loglevel, local_options.logfacility); + logger_init(&local_options, progname, local_options.loglevel, + local_options.logfacility); if (verbose) logger_min_verbose(LOG_INFO); @@ -278,9 +281,11 @@ main(int argc, char **argv) } } - snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, local_options.cluster_name); + snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, + local_options.cluster_name); - log_info(_("%s Connecting to database '%s'\n"), progname, local_options.conninfo); + log_info(_("%s Connecting to database '%s'\n"), progname, + local_options.conninfo); myLocalConn = establishDBConnection(local_options.conninfo, true); /* should be v9 or better */ @@ -288,26 +293,26 @@ main(int argc, char **argv) ret_ver = pg_version(myLocalConn, standby_version); if (ret_ver == NULL || strcmp(standby_version, "") == 0) { - if(ret_ver != NULL) - log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); + if (ret_ver != NULL) + log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), + progname); terminate(ERR_BAD_CONFIG); } /* - * MAIN LOOP - * This loops cicles once per failover and at startup - * Requisites: - * - myLocalConn needs to be already setted with an active connection - * - no master connection - */ + * MAIN LOOP This loops cicles once per failover and at startup + * Requisites: - myLocalConn needs to be already setted with an active + * connection - no master connection + */ do { /* - * Set my server mode, establish a connection to primary - * and start monitor + * Set my server mode, establish a connection to primary and start + * monitor */ - ret = is_witness(myLocalConn, repmgr_schema, local_options.cluster_name, local_options.node); + ret = is_witness(myLocalConn, repmgr_schema, + local_options.cluster_name, local_options.node); if (ret == 1) myLocalMode = WITNESS_MODE; @@ -317,13 +322,15 @@ main(int argc, char **argv) if (ret == 1) myLocalMode = STANDBY_MODE; - else if (ret == 0) /* is the master */ + else if (ret == 0) /* is the master */ myLocalMode = PRIMARY_MODE; } - /* XXX we did this before changing is_standby() to return int; we + /* + * XXX we did this before changing is_standby() to return int; we * should not exit at this point, but for now we do until we have a - * better strategy */ + * better strategy + */ if (ret == -1) terminate(1); @@ -331,7 +338,8 @@ main(int argc, char **argv) { case PRIMARY_MODE: primary_options.node = local_options.node; - strncpy(primary_options.conninfo, local_options.conninfo, MAXLEN); + strncpy(primary_options.conninfo, local_options.conninfo, + MAXLEN); primaryConn = myLocalConn; checkClusterConfiguration(myLocalConn); @@ -345,36 +353,42 @@ main(int argc, char **argv) update_registration(); } - log_info(_("%s Starting continuous primary connection check\n"), progname); - - /* Check that primary is still alive, and standbies are sending info */ + log_info(_("%s Starting continuous primary connection check\n"), + progname); /* - * Every local_options.monitor_interval_secs seconds, do master checks - * XXX - * Check that standbies are sending info + * Check that primary is still alive, and standbies are + * sending info + */ + + /* + * Every local_options.monitor_interval_secs seconds, do + * master checks XXX Check that standbies are sending info */ do { if (CheckConnection(primaryConn, "master")) { /* - CheckActiveStandbiesConnections(); - CheckInactiveStandbies(); - */ + * CheckActiveStandbiesConnections(); + * CheckInactiveStandbies(); + */ sleep(local_options.monitor_interval_secs); } else { - /* XXX - * May we do something more verbose ? + /* + * XXX May we do something more verbose ? */ terminate(1); } if (got_SIGHUP) { - /* if we can reload, then could need to change myLocalConn */ + /* + * if we can reload, then could need to change + * myLocalConn + */ if (reload_configuration(config_file, &local_options)) { PQfinish(myLocalConn); @@ -383,12 +397,13 @@ main(int argc, char **argv) if (*local_options.logfile) { - FILE *fd; + FILE *fd; + fd = freopen(local_options.logfile, "a", stderr); if (fd == NULL) { fprintf(stderr, "error reopening stderr to '%s': %s", - local_options.logfile, strerror(errno)); + local_options.logfile, strerror(errno)); } } @@ -403,10 +418,10 @@ main(int argc, char **argv) case STANDBY_MODE: /* I need the id of the primary as well as a connection to it */ log_info(_("%s Connecting to primary for cluster '%s'\n"), - progname, local_options.cluster_name); + progname, local_options.cluster_name); primaryConn = getMasterConnection(myLocalConn, repmgr_schema, - local_options.cluster_name, - &primary_options.node, NULL); + local_options.cluster_name, + &primary_options.node, NULL); if (primaryConn == NULL) { terminate(ERR_BAD_CONFIG); @@ -423,15 +438,18 @@ main(int argc, char **argv) } /* - * Every local_options.monitor_interval_secs seconds, do checks + * Every local_options.monitor_interval_secs seconds, do + * checks */ if (myLocalMode == WITNESS_MODE) { - log_info(_("%s Starting continuous witness node monitoring\n"), progname); + log_info(_("%s Starting continuous witness node monitoring\n"), + progname); } else if (myLocalMode == STANDBY_MODE) { - log_info(_("%s Starting continuous standby node monitoring\n"), progname); + log_info(_("%s Starting continuous standby node monitoring\n"), + progname); } do @@ -444,7 +462,10 @@ main(int argc, char **argv) if (got_SIGHUP) { - /* if we can reload, then could need to change myLocalConn */ + /* + * if we can reload, then could need to change + * myLocalConn + */ if (reload_configuration(config_file, &local_options)) { PQfinish(myLocalConn); @@ -456,7 +477,8 @@ main(int argc, char **argv) } while (!failover_done); break; default: - log_err(_("%s: Unrecognized mode for node %d\n"), progname, local_options.node); + log_err(_("%s: Unrecognized mode for node %d\n"), progname, + local_options.node); } failover_done = false; @@ -478,20 +500,24 @@ main(int argc, char **argv) static void WitnessMonitor(void) { - char monitor_witness_timestamp[MAXLEN]; - PGresult *res; + char monitor_witness_timestamp[MAXLEN]; + PGresult *res; /* * Check if the master is still available, if after 5 minutes of retries * we cannot reconnect, return false. */ - CheckConnection(primaryConn, "master"); /* this take up to local_options.reconnect_attempts * local_options.reconnect_intvl seconds */ + CheckConnection(primaryConn, "master"); /* this take up to + * local_options.reconnect_atte + * mpts * + * local_options.reconnect_intv + * l seconds */ if (PQstatus(primaryConn) != CONNECTION_OK) { /* - * If we can't reconnect, just exit... - * XXX we need to make witness connect to the new master + * If we can't reconnect, just exit... XXX we need to make witness + * connect to the new master */ terminate(0); } @@ -501,12 +527,13 @@ WitnessMonitor(void) return; /* - * Cancel any query that is still being executed, - * so i can insert the current record + * Cancel any query that is still being executed, so i can insert the + * current record */ if (!CancelQuery(primaryConn, local_options.master_response_timeout)) return; - if (wait_connection_availability(primaryConn, local_options.master_response_timeout) != 1) + if (wait_connection_availability(primaryConn, + local_options.master_response_timeout) != 1) return; /* Get local xlog info */ @@ -528,20 +555,21 @@ WitnessMonitor(void) * Build the SQL to execute on primary */ sqlquery_snprintf(sqlquery, - "INSERT INTO %s.repl_monitor " - "VALUES(%d, %d, '%s'::timestamp with time zone, " - " pg_current_xlog_location(), null, " - " 0, 0)", - repmgr_schema, primary_options.node, local_options.node, monitor_witness_timestamp); + "INSERT INTO %s.repl_monitor " + "VALUES(%d, %d, '%s'::timestamp with time zone, " + " pg_current_xlog_location(), null, " + " 0, 0)", + repmgr_schema, primary_options.node, local_options.node, + monitor_witness_timestamp); /* - * Execute the query asynchronously, but don't check for a result. We - * will check the result next time we pause for a monitor step. + * Execute the query asynchronously, but don't check for a result. We will + * check the result next time we pause for a monitor step. */ log_debug("WitnessMonitor: %s\n", sqlquery); if (PQsendQuery(primaryConn, sqlquery) == 0) log_warning(_("Query could not be sent to primary. %s\n"), - PQerrorMessage(primaryConn)); + PQerrorMessage(primaryConn)); } @@ -553,25 +581,30 @@ WitnessMonitor(void) static void StandbyMonitor(void) { - PGresult *res; - char monitor_standby_timestamp[MAXLEN]; - char last_wal_primary_location[MAXLEN]; - char last_wal_standby_received[MAXLEN]; - char last_wal_standby_applied[MAXLEN]; - char last_wal_standby_applied_timestamp[MAXLEN]; + PGresult *res; + char monitor_standby_timestamp[MAXLEN]; + char last_wal_primary_location[MAXLEN]; + char last_wal_standby_received[MAXLEN]; + char last_wal_standby_applied[MAXLEN]; + char last_wal_standby_applied_timestamp[MAXLEN]; unsigned long long int lsn_primary; unsigned long long int lsn_standby_received; unsigned long long int lsn_standby_applied; - int connection_retries, ret; - bool did_retry = false; + int connection_retries, + ret; + bool did_retry = false; /* * Check if the master is still available, if after 5 minutes of retries * we cannot reconnect, try to get a new master. */ - CheckConnection(primaryConn, "master"); /* this take up to local_options.reconnect_attempts * local_options.reconnect_intvl seconds */ + CheckConnection(primaryConn, "master"); /* this take up to + * local_options.reconnect_atte + * mpts * + * local_options.reconnect_intv + * l seconds */ if (!CheckConnection(myLocalConn, "standby")) { @@ -590,19 +623,27 @@ StandbyMonitor(void) for (connection_retries = 0; connection_retries < 6; connection_retries++) { primaryConn = getMasterConnection(myLocalConn, repmgr_schema, - local_options.cluster_name, &primary_options.node, NULL); + local_options.cluster_name, &primary_options.node, NULL); if (PQstatus(primaryConn) == CONNECTION_OK) { - /* Connected, we can continue the process so break the loop */ - log_err(_("Connected to node %d, continue monitoring.\n"), primary_options.node); + /* + * Connected, we can continue the process so break the + * loop + */ + log_err(_("Connected to node %d, continue monitoring.\n"), + primary_options.node); break; } else { log_err(_("We haven't found a new master, waiting before retry...\n")); - /* wait local_options.retry_promote_interval_secs minutes before retries, - * after 6 failures (6 * local_options.monitor_interval_secs - * seconds) we stop trying */ + + /* + * wait local_options.retry_promote_interval_secs minutes + * before retries, after 6 failures (6 * + * local_options.monitor_interval_secs seconds) we stop + * trying + */ sleep(local_options.retry_promote_interval_secs); } } @@ -616,8 +657,8 @@ StandbyMonitor(void) else if (local_options.failover == AUTOMATIC_FAILOVER) { /* - * When we returns from this function we will have a new primary and - * a new primaryConn + * When we returns from this function we will have a new primary + * and a new primaryConn */ do_failover(); return; @@ -625,28 +666,29 @@ StandbyMonitor(void) } /* Check if we still are a standby, we could have been promoted */ - do { + do + { ret = is_standby(myLocalConn); switch (ret) { - case 0: - log_err(_("It seems like we have been promoted, so exit from monitoring...\n")); - terminate(1); - break; + case 0: + log_err(_("It seems like we have been promoted, so exit from monitoring...\n")); + terminate(1); + break; - case -1: - log_err(_("Standby node disappeared, trying to reconnect...\n")); - did_retry = true; + case -1: + log_err(_("Standby node disappeared, trying to reconnect...\n")); + did_retry = true; - if (!CheckConnection(myLocalConn, "standby")) - { - terminate(0); - } + if (!CheckConnection(myLocalConn, "standby")) + { + terminate(0); + } - break; + break; } - } while(ret == -1); + } while (ret == -1); if (did_retry) { @@ -658,8 +700,8 @@ StandbyMonitor(void) return; /* - * Cancel any query that is still being executed, - * so i can insert the current record + * Cancel any query that is still being executed, so i can insert the + * current record */ if (!CancelQuery(primaryConn, local_options.master_response_timeout)) return; @@ -668,9 +710,9 @@ StandbyMonitor(void) /* Get local xlog info */ sqlquery_snprintf( - sqlquery, - "SELECT CURRENT_TIMESTAMP, pg_last_xlog_receive_location(), " - "pg_last_xlog_replay_location(), pg_last_xact_replay_timestamp()"); + sqlquery, + "SELECT CURRENT_TIMESTAMP, pg_last_xlog_receive_location(), " + "pg_last_xlog_replay_location(), pg_last_xact_replay_timestamp()"); res = PQexec(myLocalConn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -682,8 +724,8 @@ StandbyMonitor(void) } strncpy(monitor_standby_timestamp, PQgetvalue(res, 0, 0), MAXLEN); - strncpy(last_wal_standby_received , PQgetvalue(res, 0, 1), MAXLEN); - strncpy(last_wal_standby_applied , PQgetvalue(res, 0, 2), MAXLEN); + strncpy(last_wal_standby_received, PQgetvalue(res, 0, 1), MAXLEN); + strncpy(last_wal_standby_applied, PQgetvalue(res, 0, 2), MAXLEN); strncpy(last_wal_standby_applied_timestamp, PQgetvalue(res, 0, 3), MAXLEN); PQclear(res); @@ -710,66 +752,66 @@ StandbyMonitor(void) * Build the SQL to execute on primary */ sqlquery_snprintf(sqlquery, - "INSERT INTO %s.repl_monitor " - "VALUES(%d, %d, '%s'::timestamp with time zone, " - " '%s'::timestamp with time zone, '%s', '%s', " - " %lld, %lld)", repmgr_schema, - primary_options.node, local_options.node, monitor_standby_timestamp, - last_wal_standby_applied_timestamp, - last_wal_primary_location, - last_wal_standby_received, - (lsn_primary - lsn_standby_received), - (lsn_standby_received - lsn_standby_applied)); + "INSERT INTO %s.repl_monitor " + "VALUES(%d, %d, '%s'::timestamp with time zone, " + " '%s'::timestamp with time zone, '%s', '%s', " + " %lld, %lld)", repmgr_schema, + primary_options.node, local_options.node, monitor_standby_timestamp, + last_wal_standby_applied_timestamp, + last_wal_primary_location, + last_wal_standby_received, + (lsn_primary - lsn_standby_received), + (lsn_standby_received - lsn_standby_applied)); /* - * Execute the query asynchronously, but don't check for a result. We - * will check the result next time we pause for a monitor step. + * Execute the query asynchronously, but don't check for a result. We will + * check the result next time we pause for a monitor step. */ log_debug("StandbyMonitor: %s\n", sqlquery); if (PQsendQuery(primaryConn, sqlquery) == 0) log_warning(_("Query could not be sent to primary. %s\n"), - PQerrorMessage(primaryConn)); + PQerrorMessage(primaryConn)); } static void do_failover(void) { - PGresult *res; - char sqlquery[8192]; + PGresult *res; + char sqlquery[8192]; - int total_nodes = 0; - int visible_nodes = 0; - int ready_nodes = 0; + int total_nodes = 0; + int visible_nodes = 0; + int ready_nodes = 0; - bool find_best = false; + bool find_best = false; - int i; - int r; + int i; + int r; - uint32 uxlogid; - uint32 uxrecoff; - XLogRecPtr xlog_recptr; + uint32 uxlogid; + uint32 uxrecoff; + XLogRecPtr xlog_recptr; - char last_wal_standby_applied[MAXLEN]; + char last_wal_standby_applied[MAXLEN]; - PGconn *nodeConn = NULL; + PGconn *nodeConn = NULL; /* - * will get info about until 50 nodes, - * which seems to be large enough for most scenarios + * will get info about until 50 nodes, which seems to be large enough for + * most scenarios */ - nodeInfo nodes[50]; + nodeInfo nodes[50]; /* initialize to keep compiler quiet */ - nodeInfo best_candidate = {-1, "", InvalidXLogRecPtr, false, false, false}; + nodeInfo best_candidate = {-1, "", InvalidXLogRecPtr, false, false, false}; /* get a list of standby nodes, including myself */ sprintf(sqlquery, "SELECT id, conninfo, witness " - " FROM %s.repl_nodes " - " WHERE cluster = '%s' " - " ORDER BY priority, id ", - repmgr_schema, local_options.cluster_name); + " FROM %s.repl_nodes " + " WHERE cluster = '%s' " + " ORDER BY priority, id ", + repmgr_schema, local_options.cluster_name); res = PQexec(myLocalConn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -785,21 +827,28 @@ do_failover(void) total_nodes = PQntuples(res); log_debug(_("%s: there are %d nodes registered\n"), progname, total_nodes); - /* Build an array with the nodes and indicate which ones are visible and ready */ + /* + * Build an array with the nodes and indicate which ones are visible and + * ready + */ for (i = 0; i < total_nodes; i++) { nodes[i].nodeId = atoi(PQgetvalue(res, i, 0)); strncpy(nodes[i].conninfostr, PQgetvalue(res, i, 1), MAXLEN); nodes[i].is_witness = (strcmp(PQgetvalue(res, i, 2), "t") == 0) ? true : false; - /* Initialize on false so if we can't reach this node we know that later */ + /* + * Initialize on false so if we can't reach this node we know that + * later + */ nodes[i].is_visible = false; nodes[i].is_ready = false; XLAssignValue(nodes[i].xlog_location, 0, 0); log_debug(_("%s: node=%d conninfo=\"%s\" witness=%s\n"), - progname, nodes[i].nodeId, nodes[i].conninfostr, (nodes[i].is_witness) ? "true" : "false"); + progname, nodes[i].nodeId, nodes[i].conninfostr, + (nodes[i].is_witness) ? "true" : "false"); nodeConn = establishDBConnection(nodes[i].conninfostr, false); @@ -819,17 +868,18 @@ do_failover(void) } PQclear(res); - log_debug(_("Total nodes counted: registered=%d, visible=%d\n"), total_nodes, visible_nodes); + log_debug(_("Total nodes counted: registered=%d, visible=%d\n"), + total_nodes, visible_nodes); /* - * am i on the group that should keep alive? - * if i see less than half of total_nodes then i should do nothing + * am i on the group that should keep alive? if i see less than half of + * total_nodes then i should do nothing */ if (visible_nodes < (total_nodes / 2.0)) { log_err(_("Can't reach most of the nodes.\n" - "Let the other standby servers decide which one will be the primary.\n" - "Manual action will be needed to readd this node to the cluster.\n")); + "Let the other standby servers decide which one will be the primary.\n" + "Manual action will be needed to readd this node to the cluster.\n")); terminate(ERR_FAILOVER_FAIL); } @@ -844,9 +894,11 @@ do_failover(void) continue; nodeConn = establishDBConnection(nodes[i].conninfostr, false); - /* XXX - * This shouldn't happen, if this happens it means this is a major problem - * maybe network outages? anyway, is better for a human to react + + /* + * XXX This shouldn't happen, if this happens it means this is a major + * problem maybe network outages? anyway, is better for a human to + * react */ if (PQstatus(nodeConn) != CONNECTION_OK) { @@ -861,7 +913,8 @@ do_failover(void) res = PQexec(nodeConn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_info(_("Can't get node's last standby location: %s\n"), PQerrorMessage(nodeConn)); + log_info(_("Can't get node's last standby location: %s\n"), + PQerrorMessage(nodeConn)); log_info(_("Connection details: %s\n"), nodes[i].conninfostr); PQclear(res); PQfinish(nodeConn); @@ -869,10 +922,11 @@ do_failover(void) } if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2) - log_info(_("could not parse transaction log location \"%s\"\n"), PQgetvalue(res, 0, 0)); + log_info(_("could not parse transaction log location \"%s\"\n"), + PQgetvalue(res, 0, 0)); log_debug("XLog position of node %d: log id=%u (%X), offset=%u (%X)\n", - nodes[i].nodeId, uxlogid, uxlogid, uxrecoff, uxrecoff); + nodes[i].nodeId, uxlogid, uxlogid, uxrecoff, uxrecoff); /* If position is 0/0, error */ if (uxlogid == 0 && uxrecoff == 0) @@ -894,7 +948,9 @@ do_failover(void) res = PQexec(myLocalConn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_err(_("PQexec failed: %s.\nReport an invalid value to not be considered as new primary and exit.\n"), PQerrorMessage(myLocalConn)); + log_err(_("PQexec failed: %s.\nReport an invalid value to not be " + " considered as new primary and exit.\n"), + PQerrorMessage(myLocalConn)); PQclear(res); sprintf(last_wal_standby_applied, "'%X/%X'", 0, 0); update_shared_memory(last_wal_standby_applied); @@ -910,9 +966,9 @@ do_failover(void) while (!nodes[i].is_ready) { /* - * the witness will always be masked as ready if it's still - * not marked that way and avoid a useless query - */ + * the witness will always be masked as ready if it's still not + * marked that way and avoid a useless query + */ if (nodes[i].is_witness) { if (!nodes[i].is_ready) @@ -931,34 +987,42 @@ do_failover(void) if (nodes[i].is_ready) break; - nodeConn = establishDBConnection(nodes[i].conninfostr, false); - /* XXX - * This shouldn't happen, if this happens it means this is a major problem - * maybe network outages? anyway, is better for a human to react - */ - if (PQstatus(nodeConn) != CONNECTION_OK) - { + nodeConn = establishDBConnection(nodes[i].conninfostr, false); + + /* + * XXX This shouldn't happen, if this happens it means this is a + * major problem maybe network outages? anyway, is better for a + * human to react + */ + if (PQstatus(nodeConn) != CONNECTION_OK) + { /* XXX */ - log_info(_("At this point, it could be some race conditions that are acceptable, assume the node is restarting and starting failover procedure\n")); + log_info(_("At this point, it could be some race conditions " + "that are acceptable, assume the node is restarting " + "and starting failover procedure\n")); break; - } + } uxlogid = 0; uxrecoff = 0; - sqlquery_snprintf(sqlquery, "SELECT %s.repmgr_get_last_standby_location()", repmgr_schema); + sqlquery_snprintf(sqlquery, "SELECT %s.repmgr_get_last_standby_location()", + repmgr_schema); res = PQexec(nodeConn, sqlquery); - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - log_err(_("PQexec failed: %s.\nReport an invalid value to not be considered as new primary and exit.\n"), PQerrorMessage(nodeConn)); - PQclear(res); - PQfinish(nodeConn); - terminate(ERR_DB_QUERY); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + log_err(_("PQexec failed: %s.\nReport an invalid value to not" + "be considered as new primary and exit.\n"), + PQerrorMessage(nodeConn)); + PQclear(res); + PQfinish(nodeConn); + terminate(ERR_DB_QUERY); } - if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2) + if (sscanf(PQgetvalue(res, 0, 0), "%X/%X", &uxlogid, &uxrecoff) != 2) { - log_info(_("could not parse transaction log location \"%s\"\n"), PQgetvalue(res, 0, 0)); + log_info(_("could not parse transaction log location \"%s\"\n"), + PQgetvalue(res, 0, 0)); /* we can't do anything but fail at this point... */ if (*PQgetvalue(res, 0, 0) == '\0') @@ -969,11 +1033,11 @@ do_failover(void) } - PQclear(res); - PQfinish(nodeConn); - /* If position is 0/0, keep checking */ - if (uxlogid == 0 && uxrecoff == 0) - continue; + PQclear(res); + PQfinish(nodeConn); + /* If position is 0/0, keep checking */ + if (uxlogid == 0 && uxrecoff == 0) + continue; XLAssignValue(xlog_recptr, uxlogid, uxrecoff); @@ -982,9 +1046,9 @@ do_failover(void) XLAssignValue(nodes[i].xlog_location, uxlogid, uxrecoff); } - log_debug("Last XLog position of node %d: log id=%u (%X), offset=%u (%X)\n", - nodes[i].nodeId, uxlogid, uxlogid, - uxrecoff, uxrecoff); + log_debug("Last XLog position of node %d: log id=%u (%X), offset=%u (%X)\n", + nodes[i].nodeId, uxlogid, uxlogid, + uxrecoff, uxrecoff); ready_nodes++; nodes[i].is_ready = true; @@ -1009,26 +1073,30 @@ do_failover(void) if (!find_best) { - /* start with the first ready node, and then move on to the next one */ - best_candidate.nodeId = nodes[i].nodeId; + /* + * start with the first ready node, and then move on to the next + * one + */ + best_candidate.nodeId = nodes[i].nodeId; XLAssign(best_candidate.xlog_location, nodes[i].xlog_location); - best_candidate.is_ready = nodes[i].is_ready; - best_candidate.is_witness = nodes[i].is_witness; + best_candidate.is_ready = nodes[i].is_ready; + best_candidate.is_witness = nodes[i].is_witness; find_best = true; } /* we use the macros provided by xlogdefs.h to compare XLogRecPtr */ + /* - * Nodes are retrieved ordered by priority, so if the current - * best candidate is lower than the next node's wal location - * then assign next node as the new best candidate. + * Nodes are retrieved ordered by priority, so if the current best + * candidate is lower than the next node's wal location then assign + * next node as the new best candidate. */ if (XLByteLT(best_candidate.xlog_location, nodes[i].xlog_location)) { - best_candidate.nodeId = nodes[i].nodeId; + best_candidate.nodeId = nodes[i].nodeId; XLAssign(best_candidate.xlog_location, nodes[i].xlog_location); - best_candidate.is_ready = nodes[i].is_ready; - best_candidate.is_witness = nodes[i].is_witness; + best_candidate.is_ready = nodes[i].is_ready; + best_candidate.is_witness = nodes[i].is_witness; } } @@ -1037,7 +1105,8 @@ do_failover(void) { if (best_candidate.is_witness) { - log_err(_("%s: Node selected as new master is a witness. Can't be promoted.\n"), progname); + log_err(_("%s: Node selected as new master is a witness. Can't be promoted.\n"), + progname); terminate(ERR_FAILOVER_FAIL); } @@ -1046,8 +1115,9 @@ do_failover(void) if (verbose) log_info(_("%s: This node is the best candidate to be the new primary, promoting...\n"), - progname); - log_debug(_("promote command is: \"%s\"\n"), local_options.promote_command); + progname); + log_debug(_("promote command is: \"%s\"\n"), + local_options.promote_command); if (log_type == REPMGR_STDERR && *local_options.logfile) { @@ -1057,7 +1127,8 @@ do_failover(void) r = system(local_options.promote_command); if (r != 0) { - log_err(_("%s: promote command failed. You could check and try it manually.\n"), progname); + log_err(_("%s: promote command failed. You could check and try it manually.\n"), + progname); terminate(ERR_BAD_CONFIG); } } @@ -1068,11 +1139,12 @@ do_failover(void) if (verbose) log_info(_("%s: Node %d is the best candidate to be the new primary, we should follow it...\n"), - progname, best_candidate.nodeId); + progname, best_candidate.nodeId); log_debug(_("follow command is: \"%s\"\n"), local_options.follow_command); + /* - * New Primary need some time to be promoted. - * The follow command should take care of that. + * New Primary need some time to be promoted. The follow command + * should take care of that. */ if (log_type == REPMGR_STDERR && *local_options.logfile) { @@ -1082,13 +1154,15 @@ do_failover(void) r = system(local_options.follow_command); if (r != 0) { - log_err(_("%s: follow command failed. You could check and try it manually.\n"), progname); + log_err(_("%s: follow command failed. You could check and try it manually.\n"), + progname); terminate(ERR_BAD_CONFIG); } } else { - log_err(_("%s: Did not find candidates. You should check and try manually.\n"), progname); + log_err(_("%s: Did not find candidates. You should check and try manually.\n"), + progname); terminate(ERR_FAILOVER_FAIL); } @@ -1103,37 +1177,38 @@ do_failover(void) static bool CheckConnection(PGconn *conn, const char *type) { - int connection_retries; + int connection_retries; /* - * Check if the master is still available - * if after local_options.reconnect_attempts * local_options.reconnect_intvl seconds of retries - * we cannot reconnect - * return false + * Check if the master is still available if after + * local_options.reconnect_attempts * local_options.reconnect_intvl + * seconds of retries we cannot reconnect return false */ for (connection_retries = 0; connection_retries < local_options.reconnect_attempts; connection_retries++) { if (!is_pgup(conn, local_options.master_response_timeout)) { log_warning(_("%s: Connection to %s has been lost, trying to recover... %i seconds before failover decision\n"), - progname, + progname, type, - (local_options.reconnect_intvl * (local_options.reconnect_attempts - connection_retries))); + (local_options.reconnect_intvl * (local_options.reconnect_attempts - connection_retries))); /* wait local_options.reconnect_intvl seconds between retries */ sleep(local_options.reconnect_intvl); } else { - if ( connection_retries > 0) + if (connection_retries > 0) { - log_info(_("%s: Connection to %s has been restored.\n"), progname, type); + log_info(_("%s: Connection to %s has been restored.\n"), + progname, type); } return true; } } if (!is_pgup(conn, local_options.master_response_timeout)) { - log_err(_("%s: We couldn't reconnect for long enough, exiting...\n"), progname); + log_err(_("%s: We couldn't reconnect for long enough, exiting...\n"), + progname); /* XXX Anything else to do here? */ return false; } @@ -1147,10 +1222,10 @@ checkClusterConfiguration(PGconn *conn) PGresult *res; log_info(_("%s Checking cluster configuration with schema '%s'\n"), - progname, repmgr_schema); + progname, repmgr_schema); sqlquery_snprintf(sqlquery, "SELECT oid FROM pg_class " - " WHERE oid = '%s.repl_nodes'::regclass", - repmgr_schema); + " WHERE oid = '%s.repl_nodes'::regclass", + repmgr_schema); res = PQexec(conn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { @@ -1185,11 +1260,11 @@ checkNodeConfiguration(void) * Check if we have my node information in repl_nodes */ log_info(_("%s Checking node %d in cluster '%s'\n"), - progname, local_options.node, local_options.cluster_name); + progname, local_options.node, local_options.cluster_name); sqlquery_snprintf(sqlquery, "SELECT * FROM %s.repl_nodes " - " WHERE id = %d AND cluster = '%s' ", - repmgr_schema, local_options.node, - local_options.cluster_name); + " WHERE id = %d AND cluster = '%s' ", + repmgr_schema, local_options.node, + local_options.cluster_name); res = PQexec(myLocalConn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -1200,8 +1275,8 @@ checkNodeConfiguration(void) } /* - * If there isn't any results then we have not configured this node yet - * in repmgr, if that is the case we will insert the node to the cluster, + * If there isn't any results then we have not configured this node yet in + * repmgr, if that is the case we will insert the node to the cluster, * except if it is a witness */ if (PQntuples(res) == 0) @@ -1216,18 +1291,18 @@ checkNodeConfiguration(void) /* Adding the node */ log_info(_("%s Adding node %d to cluster '%s'\n"), - progname, local_options.node, local_options.cluster_name); + progname, local_options.node, local_options.cluster_name); sqlquery_snprintf(sqlquery, "INSERT INTO %s.repl_nodes " - "VALUES (%d, '%s', '%s', '%s', 0, 'f')", - repmgr_schema, local_options.node, - local_options.cluster_name, - local_options.node_name, - local_options.conninfo); + "VALUES (%d, '%s', '%s', '%s', 0, 'f')", + repmgr_schema, local_options.node, + local_options.cluster_name, + local_options.node_name, + local_options.conninfo); if (!PQexec(primaryConn, sqlquery)) { log_err(_("Cannot insert node details, %s\n"), - PQerrorMessage(primaryConn)); + PQerrorMessage(primaryConn)); terminate(ERR_BAD_CONFIG); } } @@ -1249,18 +1324,20 @@ walLocationToBytes(char *wal_location) log_err(_("wrong log location format: %s\n"), wal_location); return 0; } - return (( (long long) xlogid * 16 * 1024 * 1024 * 255) + xrecoff); + return (((long long) xlogid * 16 * 1024 * 1024 * 255) + xrecoff); } -void usage(void) +void +usage(void) { log_err(_("%s: Replicator manager daemon \n"), progname); log_err(_("Try \"%s --help\" for more information.\n"), progname); } -void help(const char *progname) +void +help(const char *progname) { printf(_("Usage: %s [OPTIONS]\n"), progname); printf(_("Replicator manager daemon for PostgreSQL.\n")); @@ -1319,16 +1396,17 @@ terminate(int retval) static void update_shared_memory(char *last_wal_standby_applied) { - PGresult *res; + PGresult *res; sprintf(sqlquery, "SELECT %s.repmgr_update_standby_location('%s')", - repmgr_schema, last_wal_standby_applied); + repmgr_schema, last_wal_standby_applied); /* If an error happens, just inform about that and continue */ res = PQexec(myLocalConn, sqlquery); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - log_warning(_("Cannot update this standby's shared memory: %s\n"), PQerrorMessage(myLocalConn)); + log_warning(_("Cannot update this standby's shared memory: %s\n"), + PQerrorMessage(myLocalConn)); /* XXX is this enough reason to terminate this repmgrd? */ } else if (strcmp(PQgetvalue(res, 0, 0), "f") == 0) @@ -1344,18 +1422,20 @@ update_shared_memory(char *last_wal_standby_applied) static void update_registration(void) { - PGresult *res; + PGresult *res; sqlquery_snprintf(sqlquery, "UPDATE %s.repl_nodes " - " SET conninfo = '%s', " - " priority = %d " - " WHERE id = %d", - repmgr_schema, local_options.conninfo, local_options.priority, local_options.node); + " SET conninfo = '%s', " + " priority = %d " + " WHERE id = %d", + repmgr_schema, local_options.conninfo, + local_options.priority, local_options.node); res = PQexec(primaryConn, sqlquery); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - log_err(_("Cannot update registration: %s\n"), PQerrorMessage(primaryConn)); + log_err(_("Cannot update registration: %s\n"), + PQerrorMessage(primaryConn)); terminate(ERR_DB_CON); } PQclear(res); @@ -1364,68 +1444,69 @@ update_registration(void) static void do_daemonize() { - char *ptr, path[MAXLEN]; - pid_t pid = fork(); - int ret; + char *ptr, + path[MAXLEN]; + pid_t pid = fork(); + int ret; switch (pid) { - case -1: - log_err("Error in fork(): %s\n", strerror(errno)); - exit(ERR_SYS_FAILURE); - break; - - case 0: /* child process */ - pid = setsid(); - if (pid == (pid_t)-1) - { - log_err("Error in setsid(): %s\n", strerror(errno)); - exit(ERR_SYS_FAILURE); - } - - /* ensure that we are no longer able to open a terminal */ - pid = fork(); - - if(pid == -1) /* error case */ - { + case -1: log_err("Error in fork(): %s\n", strerror(errno)); exit(ERR_SYS_FAILURE); break; - } - if (pid != 0) /* parent process */ - { - exit(0); - } - - /* a child just flows along */ - - memset(path, 0, MAXLEN); - - for (ptr = config_file + strlen(config_file); ptr > config_file; --ptr) - { - if (*ptr == '/') + case 0: /* child process */ + pid = setsid(); + if (pid == (pid_t) -1) { - strncpy(path, config_file, ptr - config_file); + log_err("Error in setsid(): %s\n", strerror(errno)); + exit(ERR_SYS_FAILURE); } - } - if (*path == '\0') - { - *path = '/'; - } + /* ensure that we are no longer able to open a terminal */ + pid = fork(); - ret = chdir(path); - if (ret != 0) - { - log_err("Error changing directory to '%s': %s", path, - strerror(errno)); - } + if (pid == -1) /* error case */ + { + log_err("Error in fork(): %s\n", strerror(errno)); + exit(ERR_SYS_FAILURE); + break; + } - break; + if (pid != 0) /* parent process */ + { + exit(0); + } - default: /* parent process */ - exit(0); + /* a child just flows along */ + + memset(path, 0, MAXLEN); + + for (ptr = config_file + strlen(config_file); ptr > config_file; --ptr) + { + if (*ptr == '/') + { + strncpy(path, config_file, ptr - config_file); + } + } + + if (*path == '\0') + { + *path = '/'; + } + + ret = chdir(path); + if (ret != 0) + { + log_err("Error changing directory to '%s': %s", path, + strerror(errno)); + } + + break; + + default: /* parent process */ + exit(0); } } @@ -1433,10 +1514,10 @@ static void check_and_create_pid_file(const char *pid_file) { struct stat st; - FILE *fd; - char buff[MAXLEN]; - pid_t pid; - size_t nread; + FILE *fd; + char buff[MAXLEN]; + pid_t pid; + size_t nread; if (stat(pid_file, &st) != -1) { @@ -1446,7 +1527,9 @@ check_and_create_pid_file(const char *pid_file) if (fd == NULL) { - log_err("PID file %s exists but could not opened for reading. If repmgrd is no longer alive remove the file and restart repmgrd.\n", pid_file); + log_err("PID file %s exists but could not opened for reading. " + "If repmgrd is no longer alive remove the file and restart repmgrd.\n", + pid_file); exit(ERR_BAD_CONFIG); } @@ -1466,7 +1549,9 @@ check_and_create_pid_file(const char *pid_file) { if (kill(pid, 0) != -1) { - log_err("PID file %s exists and seems to contain a valid PID. If repmgrd is no longer alive remove the file and restart repmgrd.\n", pid_file); + log_err("PID file %s exists and seems to contain a valid PID. " + "If repmgrd is no longer alive remove the file and restart repmgrd.\n", + pid_file); exit(ERR_BAD_CONFIG); } } diff --git a/sql/repmgr_funcs.c b/sql/repmgr_funcs.c index dfeb139b..8344819b 100644 --- a/sql/repmgr_funcs.c +++ b/sql/repmgr_funcs.c @@ -18,7 +18,7 @@ #include "utils/timestamp.h" /* same definition as the one in xlog_internal.h */ -#define MAXFNAMELEN 64 +#define MAXFNAMELEN 64 PG_MODULE_MAGIC; @@ -27,32 +27,32 @@ PG_MODULE_MAGIC; */ typedef struct repmgrSharedState { - LWLockId lock; /* protects search/modification */ - char location[MAXFNAMELEN]; /* last known xlog location */ + LWLockId lock; /* protects search/modification */ + char location[MAXFNAMELEN]; /* last known xlog location */ TimestampTz last_updated; -} repmgrSharedState; +} repmgrSharedState; /* Links to shared memory state */ static repmgrSharedState *shared_state = NULL; static shmem_startup_hook_type prev_shmem_startup_hook = NULL; -void _PG_init(void); -void _PG_fini(void); +void _PG_init(void); +void _PG_fini(void); static void repmgr_shmem_startup(void); static Size repmgr_memsize(void); static bool repmgr_set_standby_location(char *locationstr); -Datum repmgr_update_standby_location(PG_FUNCTION_ARGS); -Datum repmgr_get_last_standby_location(PG_FUNCTION_ARGS); +Datum repmgr_update_standby_location(PG_FUNCTION_ARGS); +Datum repmgr_get_last_standby_location(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(repmgr_update_standby_location); PG_FUNCTION_INFO_V1(repmgr_get_last_standby_location); -Datum repmgr_update_last_updated(PG_FUNCTION_ARGS); -Datum repmgr_get_last_updated(PG_FUNCTION_ARGS); +Datum repmgr_update_last_updated(PG_FUNCTION_ARGS); +Datum repmgr_get_last_updated(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(repmgr_update_last_updated); PG_FUNCTION_INFO_V1(repmgr_get_last_updated); @@ -68,9 +68,9 @@ _PG_init(void) * In order to create our shared memory area, we have to be loaded via * shared_preload_libraries. If not, fall out without hooking into any of * the main system. (We don't throw error here because it seems useful to - * allow the repmgr functions to be created even when the - * module isn't active. The functions must protect themselves against - * being called then, however.) + * allow the repmgr functions to be created even when the module isn't + * active. The functions must protect themselves against being called + * then, however.) */ if (!process_shared_preload_libraries_in_progress) return; @@ -120,15 +120,15 @@ repmgr_shmem_startup(void) LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); shared_state = ShmemInitStruct("repmgr shared state", - sizeof(repmgrSharedState), - &found); + sizeof(repmgrSharedState), + &found); if (!found) { /* First time through ... */ shared_state->lock = LWLockAssign(); snprintf(shared_state->location, - sizeof(shared_state->location), "%X/%X", 0, 0); + sizeof(shared_state->location), "%X/%X", 0, 0); } LWLockRelease(AddinShmemInitLock); @@ -141,20 +141,20 @@ repmgr_shmem_startup(void) static Size repmgr_memsize(void) { - return MAXALIGN(sizeof(repmgrSharedState)); + return MAXALIGN(sizeof(repmgrSharedState)); } static bool repmgr_set_standby_location(char *locationstr) { - /* Safety check... */ - if (!shared_state) - return false; + /* Safety check... */ + if (!shared_state) + return false; - LWLockAcquire(shared_state->lock, LW_EXCLUSIVE); + LWLockAcquire(shared_state->lock, LW_EXCLUSIVE); strncpy(shared_state->location, locationstr, MAXFNAMELEN); - LWLockRelease(shared_state->lock); + LWLockRelease(shared_state->lock); return true; } @@ -166,7 +166,7 @@ repmgr_set_standby_location(char *locationstr) Datum repmgr_get_last_standby_location(PG_FUNCTION_ARGS) { - char location[MAXFNAMELEN]; + char location[MAXFNAMELEN]; /* Safety check... */ if (!shared_state) @@ -184,14 +184,14 @@ repmgr_get_last_standby_location(PG_FUNCTION_ARGS) Datum repmgr_update_standby_location(PG_FUNCTION_ARGS) { - text *location = PG_GETARG_TEXT_P(0); - char *locationstr; + text *location = PG_GETARG_TEXT_P(0); + char *locationstr; - /* Safety check... */ - if (!shared_state) - PG_RETURN_BOOL(false); + /* Safety check... */ + if (!shared_state) + PG_RETURN_BOOL(false); - locationstr = text_to_cstring(location); + locationstr = text_to_cstring(location); PG_RETURN_BOOL(repmgr_set_standby_location(locationstr)); } @@ -220,9 +220,9 @@ repmgr_get_last_updated(PG_FUNCTION_ARGS) { TimestampTz last_updated; - /* Safety check... */ - if (!shared_state) - PG_RETURN_NULL(); + /* Safety check... */ + if (!shared_state) + PG_RETURN_NULL(); LWLockAcquire(shared_state->lock, LW_EXCLUSIVE); last_updated = shared_state->last_updated; diff --git a/strutil.c b/strutil.c index f1a6f532..091d1e31 100644 --- a/strutil.c +++ b/strutil.c @@ -25,7 +25,9 @@ #include "log.h" #include "strutil.h" -static int xvsnprintf(char *str, size_t size, const char *format, va_list ap) __attribute__ ((format (PG_PRINTF_ATTRIBUTE, 3, 0))); +static int +xvsnprintf(char *str, size_t size, const char *format, va_list ap) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0))); /* Add strnlen on platforms that don't have it, like OS X */ #ifndef strnlen @@ -33,21 +35,22 @@ size_t strnlen(const char *s, size_t n) { const char *end = (const char *) memchr(s, '\0', n); - return(end ? end - s : n); + + return (end ? end - s : n); } #endif static int xvsnprintf(char *str, size_t size, const char *format, va_list ap) { - int retval; + int retval; retval = vsnprintf(str, size, format, ap); - if (retval >= (int)size) + if (retval >= (int) size) { log_err(_("Buffer of size not large enough to format entire string '%s'\n"), - str); + str); exit(ERR_STR_OVERFLOW); } @@ -56,10 +59,10 @@ xvsnprintf(char *str, size_t size, const char *format, va_list ap) int -xsnprintf(char *str, size_t size, const char *format, ...) +xsnprintf(char *str, size_t size, const char *format,...) { - va_list arglist; - int retval; + va_list arglist; + int retval; va_start(arglist, format); retval = xvsnprintf(str, size, format, arglist); @@ -70,7 +73,7 @@ xsnprintf(char *str, size_t size, const char *format, ...) int -sqlquery_snprintf(char *str, const char *format, ...) +sqlquery_snprintf(char *str, const char *format,...) { va_list arglist; int retval; @@ -83,7 +86,8 @@ sqlquery_snprintf(char *str, const char *format, ...) } -int maxlen_snprintf(char *str, const char *format, ...) +int +maxlen_snprintf(char *str, const char *format,...) { va_list arglist; int retval; diff --git a/strutil.h b/strutil.h index a1cd2b17..0ef9ed64 100644 --- a/strutil.h +++ b/strutil.h @@ -31,13 +31,21 @@ #define MAXCONNINFO 1024 -extern int xsnprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (PG_PRINTF_ATTRIBUTE, 3, 4))); -extern int sqlquery_snprintf(char *str, const char *format, ...) __attribute__ ((format (PG_PRINTF_ATTRIBUTE, 2, 3))); -extern int maxlen_snprintf(char *str, const char *format, ...) __attribute__ ((format (PG_PRINTF_ATTRIBUTE, 2, 3))); +extern int +xsnprintf(char *str, size_t size, const char *format,...) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); + +extern int +sqlquery_snprintf(char *str, const char *format,...) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); + +extern int +maxlen_snprintf(char *str, const char *format,...) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); /* Add strnlen on platforms that don't have it, like OS X */ #ifndef strnlen extern size_t strnlen(const char *s, size_t n); #endif -#endif /* _STRUTIL_H_ */ +#endif /* _STRUTIL_H_ */ diff --git a/version.h b/version.h index a8f799ab..78833c57 100644 --- a/version.h +++ b/version.h @@ -2,4 +2,5 @@ #define _VERSION_H_ #define REPMGR_VERSION "2.0" + #endif