Skip to content

Commit

Permalink
[#108] switch-to support
Browse files Browse the repository at this point in the history
  • Loading branch information
jesperpedersen committed Sep 17, 2020
1 parent e39c054 commit 811477e
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ Commands:
cancel-shutdown Cancel the graceful shutdown
status Status of pgagroal
details Detailed status of pgagroal
switch-to Switch to another primary
reset Reset the Prometheus statistics
reset-server Reset the state of a server
```
Expand Down
3 changes: 3 additions & 0 deletions doc/man/pgagroal-cli.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ status
details
Detailed status of pgagroal

switch-to
Switch to another primary

reset
Reset the Prometheus statistics

Expand Down
26 changes: 26 additions & 0 deletions src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#define ACTION_DISABLEDB 9
#define ACTION_RESET 10
#define ACTION_RESET_SERVER 11
#define ACTION_SWITCH_TO 12

static int flush(SSL* ssl, int socket, int32_t mode);
static int enabledb(SSL* ssl, int socket, char* database);
Expand All @@ -75,6 +76,7 @@ static int details(SSL* ssl, int socket);
static int isalive(SSL* ssl, int socket);
static int reset(SSL* ssl, int socket);
static int reset_server(SSL* ssl, int socket, char* server);
static int switch_to(SSL* ssl, int socket, char* server);


static void
Expand Down Expand Up @@ -116,6 +118,7 @@ usage()
printf(" cancel-shutdown Cancel the graceful shutdown\n");
printf(" status Status of pgagroal\n");
printf(" details Detailed status of pgagroal\n");
printf(" switch-to Switch to another primary\n");
printf(" reset Reset the Prometheus statistics\n");
printf(" reset-server Reset the state of a server\n");
printf("\n");
Expand Down Expand Up @@ -322,6 +325,14 @@ main(int argc, char **argv)
server = argv[argc - 1];
}
}
else if (!strcmp("switch-to", argv[argc - 1]) || !strcmp("switch-to", argv[argc - 2]))
{
if (!strcmp("switch-to", argv[argc - 2]))
{
action = ACTION_SWITCH_TO;
server = argv[argc - 1];
}
}

if (action != ACTION_UNKNOWN)
{
Expand Down Expand Up @@ -440,6 +451,10 @@ main(int argc, char **argv)
{
exit_code = reset_server(s_ssl, socket, server);
}
else if (action == ACTION_SWITCH_TO)
{
exit_code = switch_to(s_ssl, socket, server);
}
}

done:
Expand Down Expand Up @@ -639,3 +654,14 @@ reset_server(SSL* ssl, int socket, char* server)

return 0;
}

static int
switch_to(SSL* ssl, int socket, char* server)
{
if (pgagroal_management_switch_to(ssl, socket, server))
{
return 1;
}

return 0;
}
11 changes: 11 additions & 0 deletions src/include/management.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extern "C" {
#define MANAGEMENT_RESET_SERVER 14
#define MANAGEMENT_CLIENT_DONE 15
#define MANAGEMENT_CLIENT_FD 16
#define MANAGEMENT_SWITCH_TO 17

/**
* Read the management header
Expand Down Expand Up @@ -282,6 +283,16 @@ pgagroal_management_client_done(void* shmem, pid_t pid);
int
pgagroal_management_client_fd(void* shmem, int32_t slot, pid_t pid);

/**
* Management operation: Switch to
* @param ssl The SSL connection
* @param socket The socket
* @param server The server
* @return 0 upon success, otherwise 1
*/
int
pgagroal_management_switch_to(SSL* ssl, int socket, char* server);

#ifdef __cplusplus
}
#endif
Expand Down
9 changes: 9 additions & 0 deletions src/include/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ pgagroal_server_force_failover(void* shmem, int server);
int
pgagroal_server_reset(void* shmem, char* server);

/**
* Switch server
* @param shmem The shared memory segment
* @param server The server
* @return 0 upon success, otherwise 1
*/
int
pgagroal_server_switch(void* shmem, char* server);

#ifdef __cplusplus
}
#endif
Expand Down
30 changes: 30 additions & 0 deletions src/libpgagroal/management.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ pgagroal_management_read_payload(int socket, signed char id, int* payload_i, cha
*payload_s = s;
break;
case MANAGEMENT_RESET_SERVER:
case MANAGEMENT_SWITCH_TO:
s = malloc(MISC_LENGTH);
memset(s, 0, MISC_LENGTH);
if (read_complete(NULL, socket, s, MISC_LENGTH))
Expand Down Expand Up @@ -1119,6 +1120,35 @@ pgagroal_management_client_fd(void* shmem, int32_t slot, pid_t pid)
return 1;
}

int
pgagroal_management_switch_to(SSL* ssl, int fd, char* server)
{
char name[MISC_LENGTH];

if (write_header(ssl, fd, MANAGEMENT_SWITCH_TO, -1))
{
ZF_LOGW("pgagroal_management_switch_to: write: %d", fd);
errno = 0;
goto error;
}

memset(&name[0], 0, MISC_LENGTH);
memcpy(&name[0], server, strlen(server));

if (write_complete(ssl, fd, &name[0], sizeof(name)))
{
ZF_LOGW("pgagroal_management_switch_to: write: %d %s", fd, strerror(errno));
errno = 0;
goto error;
}

return 0;

error:

return 1;
}

static int
read_complete(SSL* ssl, int socket, void* buf, size_t size)
{
Expand Down
1 change: 1 addition & 0 deletions src/libpgagroal/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pgagroal_remote_management(int client_fd, char* address, void* shmem, void* pipe
break;
case MANAGEMENT_FLUSH:
case MANAGEMENT_RESET_SERVER:
case MANAGEMENT_SWITCH_TO:
status = pgagroal_read_timeout_message(client_ssl, client_fd, config->authentication_timeout, &msg);
if (status != MESSAGE_STATUS_OK)
{
Expand Down
37 changes: 37 additions & 0 deletions src/libpgagroal/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,43 @@ pgagroal_server_reset(void* shmem, char* server)
return 1;
}

int
pgagroal_server_switch(void* shmem, char* server)
{
int old_primary;
int new_primary;
signed char state;
struct configuration* config = NULL;

config = (struct configuration*)shmem;

old_primary = -1;
new_primary = -1;

for (int i = 0; i < config->number_of_servers; i++)
{
state = atomic_load(&config->servers[i].state);

if (state == SERVER_PRIMARY)
{
old_primary = i;
}
else if (!strcmp(config->servers[i].name, server))
{
new_primary = i;
}
}

if (old_primary != -1 && new_primary != -1)
{
atomic_store(&config->servers[old_primary].state, SERVER_FAILED);
atomic_store(&config->servers[new_primary].state, SERVER_PRIMARY);
return 0;
}

return 1;
}

static int
failover(void* shmem, int old_primary)
{
Expand Down
11 changes: 11 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,17 @@ accept_mgt_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
remove_client(p);
}
break;
case MANAGEMENT_SWITCH_TO:
ZF_LOGD("pgagroal: Management switch to");
if (!pgagroal_server_switch(ai->shmem, payload_s))
{
if (!fork())
{
pgagroal_flush(ai->shmem, FLUSH_GRACEFULLY);
}
pgagroal_prometheus_failed_servers(ai->shmem);
}
break;
default:
ZF_LOGD("pgagroal: Unknown management id: %d", id);
break;
Expand Down

0 comments on commit 811477e

Please sign in to comment.