diff options
author | Mark Wong <mark@2ndQuadrant.com> | 2019-06-07 20:22:35 +0000 |
---|---|---|
committer | Mark Wong <mark@2ndQuadrant.com> | 2019-06-26 22:13:50 +0000 |
commit | 4483ea4e505f22345783fa42ae1fef19ea0d4a2c (patch) | |
tree | fef564ddc887c09b6785eac26c85ad7c4ab95beb | |
parent | be64213990cbaa607b422099d323b54be513077e (diff) |
Make connections with passwords persistent
In these cases clear the connection information from memory after the
connection is established since it's not needed after that.
-rw-r--r-- | HISTORY | 2 | ||||
-rw-r--r-- | commands.c | 49 | ||||
-rw-r--r-- | commands.h | 6 | ||||
-rw-r--r-- | machine.h | 6 | ||||
-rw-r--r-- | machine/m_common.c | 22 | ||||
-rw-r--r-- | machine/m_linux.c | 11 | ||||
-rw-r--r-- | machine/m_remote.c | 50 | ||||
-rw-r--r-- | pg.c | 35 | ||||
-rw-r--r-- | pg.h | 10 | ||||
-rw-r--r-- | pg_top.1.in | 7 | ||||
-rw-r--r-- | pg_top.c | 42 | ||||
-rw-r--r-- | pg_top.h | 2 | ||||
-rw-r--r-- | remote.h | 6 |
13 files changed, 134 insertions, 114 deletions
@@ -8,6 +8,8 @@ Release 4.0.0 * Remove kill and renice command, and stop displaying nice priority * Show backend state instead of operating system state * Show database username instead of operating system username + * Make connections with password persistent and clear connection memory in + these scenarios Release 3.7.0 @@ -150,7 +150,7 @@ cmd_current_query(struct pg_top_context *pgtctx) newval = readline(tempbuf1, 8, Yes); reset_display(pgtctx); display_pagerstart(); - show_current_query(pgtctx->values, newval); + show_current_query(&pgtctx->conninfo, newval); display_pagerend(); return No; } @@ -203,7 +203,7 @@ cmd_explain(struct pg_top_context *pgtctx) newval = readline(tempbuf1, 8, Yes); reset_display(pgtctx); display_pagerstart(); - show_explain(pgtctx->values, newval, EXPLAIN); + show_explain(&pgtctx->conninfo, newval, EXPLAIN); display_pagerend(); return No; } @@ -218,7 +218,7 @@ cmd_explain_analyze(struct pg_top_context *pgtctx) newval = readline(tempbuf1, 8, Yes); reset_display(pgtctx); display_pagerstart(); - show_explain(pgtctx->values, newval, EXPLAIN_ANALYZE); + show_explain(&pgtctx->conninfo, newval, EXPLAIN_ANALYZE); display_pagerend(); return No; } @@ -271,7 +271,7 @@ cmd_locks(struct pg_top_context *pgtctx) newval = readline(tempbuf1, 8, Yes); reset_display(pgtctx); display_pagerstart(); - show_locks(pgtctx->values, newval); + show_locks(&pgtctx->conninfo, newval); display_pagerend(); return No; } @@ -675,22 +675,21 @@ scanint(char *str, int *intp) } void -show_current_query(const char *values[], int procpid) +show_current_query(struct pg_conninfo_ctx *conninfo, int procpid) { int i; int rows; char info[64]; - PGconn *pgconn; PGresult *pgresult = NULL; sprintf(info, "Current query for procpid %d:\n\n", procpid); display_pager(info); /* Get the currently running query. */ - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { - pgresult = pg_query(pgconn, procpid); + pgresult = pg_query(conninfo->connection, procpid); rows = PQntuples(pgresult); } else @@ -705,11 +704,11 @@ show_current_query(const char *values[], int procpid) if (pgresult != NULL) PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); } void -show_explain(const char *values[], int procpid, int analyze) +show_explain(struct pg_conninfo_ctx *conninfo, int procpid, int analyze) { int i, j; @@ -717,7 +716,6 @@ show_explain(const char *values[], int procpid, int analyze) r; char sql[4096]; char info[1024]; - PGconn *pgconn; PGresult *pgresult_query = NULL; PGresult *pgresult_explain = NULL; @@ -727,10 +725,10 @@ show_explain(const char *values[], int procpid, int analyze) display_pager(info); /* Get the currently running query. */ - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { - pgresult_query = pg_query(pgconn, procpid); + pgresult_query = pg_query(conninfo->connection, procpid); rows = PQntuples(pgresult_query); } else @@ -752,9 +750,9 @@ show_explain(const char *values[], int procpid, int analyze) { sprintf(sql, "EXPLAIN\n%s", PQgetvalue(pgresult_query, i, 0)); } - PQexec(pgconn, BEGIN); - pgresult_explain = PQexec(pgconn, sql); - PQexec(pgconn, ROLLBACK); + PQexec(conninfo->connection, BEGIN); + pgresult_explain = PQexec(conninfo->connection, sql); + PQexec(conninfo->connection, ROLLBACK); r = PQntuples(pgresult_explain); /* This will display an error if the EXPLAIN fails. */ display_pager("\n\nQuery Plan:\n\n"); @@ -771,11 +769,11 @@ show_explain(const char *values[], int procpid, int analyze) if (pgresult_query != NULL) PQclear(pgresult_query); - PQfinish(pgconn); + disconnect_from_db(conninfo); } void -show_locks(const char *values[], int procpid) +show_locks(struct pg_conninfo_ctx *conninfo, int procpid) { int i, j, @@ -783,7 +781,6 @@ show_locks(const char *values[], int procpid) int rows; char info[64]; int width[5] = {1, 8, 5, 4, 7}; - PGconn *pgconn; PGresult *pgresult = NULL; char header_format[1024]; char line_format[1024]; @@ -794,14 +791,14 @@ show_locks(const char *values[], int procpid) display_pager(info); /* Get the locks helf by the process. */ - pgconn = connect_to_db(values); - if (pgconn == NULL) + connect_to_db(conninfo); + if (conninfo->connection == NULL) { - PQfinish(pgconn); + disconnect_from_db(conninfo); return; } - pgresult = pg_locks(pgconn, procpid); + pgresult = pg_locks(conninfo->connection, procpid); rows = PQntuples(pgresult); /* Determine column sizes. */ @@ -851,5 +848,5 @@ show_locks(const char *values[], int procpid) display_pager("\n"); PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); } @@ -48,8 +48,8 @@ int execute_command(struct pg_top_context *, char); void show_help(struct statics *); int scanint(char *str, int *intp); -void show_current_query(const char **, int); -void show_explain(const char **, int, int); -void show_locks(const char **, int); +void show_current_query(struct pg_conninfo_ctx *, int); +void show_explain(struct pg_conninfo_ctx *, int, int); +void show_locks(struct pg_conninfo_ctx *, int); #endif /* _COMMANDS_H_ */ @@ -148,15 +148,15 @@ int machine_init(struct statics *); void get_system_info(struct system_info *); #ifdef __linux__ caddr_t get_process_info(struct system_info *, struct process_select *, int, - const char **, int); + struct pg_conninfo_ctx *, int); #else caddr_t get_process_info(struct system_info *, struct process_select *, int, char *); #endif /* __linux__ */ void get_disk_info(struct disk_info *, char *); void get_io_info(struct io_info *); -void get_database_info(struct db_info *, const char **); -char *get_data_directory(const char **); +void get_database_info(struct db_info *, struct pg_conninfo_ctx *); +char *get_data_directory(struct pg_conninfo_ctx *); char *format_header(char *); char *format_next_io(caddr_t); char *format_next_process(caddr_t); diff --git a/machine/m_common.c b/machine/m_common.c index c8cf952..ff03365 100644 --- a/machine/m_common.c +++ b/machine/m_common.c @@ -37,13 +37,12 @@ static char *data_directory = NULL; * values with previous values. */ void -get_database_info(struct db_info *db_info, const char *values[]) +get_database_info(struct db_info *db_info, struct pg_conninfo_ctx *conninfo) { struct timeval thistime; double timediff; int i; int rows; - PGconn *pgconn; PGresult *pgresult = NULL; struct db_info cur_info; static struct timeval lasttime; @@ -60,10 +59,10 @@ get_database_info(struct db_info *db_info, const char *values[]) lasttime = thistime; rows = 0; - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { - pgresult = PQexec(pgconn, QUERY_STAT_DB); + pgresult = PQexec(conninfo->connection, QUERY_STAT_DB); if (PQresultStatus(pgresult) == PGRES_TUPLES_OK) rows = PQntuples(pgresult); @@ -91,7 +90,7 @@ get_database_info(struct db_info *db_info, const char *values[]) } if (pgresult != NULL) PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); if (timediff <= 0) { last_db_info = cur_info; @@ -116,9 +115,8 @@ get_database_info(struct db_info *db_info, const char *values[]) * queried to server, return existing value. */ char * -get_data_directory(const char *values[]) +get_data_directory(struct pg_conninfo_ctx *conninfo) { - PGconn *pgconn; PGresult *pgresult = NULL; int rows; @@ -128,10 +126,10 @@ get_data_directory(const char *values[]) /* No existing value, so query server */ rows = 0; - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { - pgresult = PQexec(pgconn, QUERY_DATA_DIRECTORY); + pgresult = PQexec(conninfo->connection, QUERY_DATA_DIRECTORY); if (PQresultStatus(pgresult) == PGRES_TUPLES_OK) rows = PQntuples(pgresult); } @@ -147,7 +145,7 @@ get_data_directory(const char *values[]) /* Clean up */ if (pgresult != NULL) PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); return data_directory; } diff --git a/machine/m_linux.c b/machine/m_linux.c index c07cd31..3440655 100644 --- a/machine/m_linux.c +++ b/machine/m_linux.c @@ -823,7 +823,7 @@ read_one_proc_stat(pid_t pid, struct top_proc * proc, struct process_select * se caddr_t get_process_info(struct system_info * si, struct process_select * sel, - int compare_index, const char *values[], int mode) + int compare_index, struct pg_conninfo_ctx *conninfo, int mode) { struct timeval thistime; double timediff, @@ -885,15 +885,14 @@ get_process_info(struct system_info * si, int i; int rows; - PGconn *pgconn; PGresult *pgresult = NULL; memset(process_states, 0, sizeof(process_states)); - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { - pgresult = pg_processes(pgconn); + pgresult = pg_processes(conninfo->connection); rows = PQntuples(pgresult); } else @@ -964,7 +963,7 @@ get_process_info(struct system_info * si, } if (pgresult != NULL) PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); /* make sure we have enough slots for the active procs */ if (activesize < total_procs) diff --git a/machine/m_remote.c b/machine/m_remote.c index ec1595a..c11694a 100644 --- a/machine/m_remote.c +++ b/machine/m_remote.c @@ -432,16 +432,15 @@ free_proc(struct top_proc *proc) } void -get_system_info_r(struct system_info *info, const char *values[]) +get_system_info_r(struct system_info *info, struct pg_conninfo_ctx *conninfo) { - PGconn *pgconn; PGresult *pgresult = NULL; int rows = 0; - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { - pgresult = PQexec(pgconn, QUERY_LOADAVG); + pgresult = PQexec(conninfo->connection, QUERY_LOADAVG); rows = PQntuples(pgresult); } @@ -462,9 +461,9 @@ get_system_info_r(struct system_info *info, const char *values[]) } /* Get processor time info. */ - if (pgconn != NULL) + if (conninfo->connection != NULL) { - pgresult = PQexec(pgconn, QUERY_CPUTIME); + pgresult = PQexec(conninfo->connection, QUERY_CPUTIME); rows = PQntuples(pgresult); } if (rows > 0) @@ -488,9 +487,9 @@ get_system_info_r(struct system_info *info, const char *values[]) } /* Get system wide memory usage. */ - if (pgconn != NULL) + if (conninfo->connection != NULL) { - pgresult = PQexec(pgconn, QUERY_MEMUSAGE); + pgresult = PQexec(conninfo->connection, QUERY_MEMUSAGE); rows = PQntuples(pgresult); } if (rows > 0) @@ -522,12 +521,12 @@ get_system_info_r(struct system_info *info, const char *values[]) if (pgresult != NULL) PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); } caddr_t get_process_info_r(struct system_info *si, struct process_select *sel, - int compare_index, const char *values[]) + int compare_index, struct pg_conninfo_ctx *conninfo) { int i; struct top_proc *pp; @@ -535,7 +534,6 @@ get_process_info_r(struct system_info *si, struct process_select *sel, struct top_proc **active; pid_t pid; - PGconn *pgconn; PGresult *pgresult = NULL; int rows; @@ -587,16 +585,16 @@ get_process_info_r(struct system_info *si, struct process_select *sel, for (proc = ptable[i]; proc; proc = proc->next) proc->state = 0; - pgconn = connect_to_db(values); - if (pgconn != NULL) + connect_to_db(conninfo); + if (conninfo->connection != NULL) { if (sel->fullcmd == 2) { - pgresult = PQexec(pgconn, QUERY_PROCTAB_QUERY); + pgresult = PQexec(conninfo->connection, QUERY_PROCTAB_QUERY); } else { - pgresult = PQexec(pgconn, QUERY_PROCTAB); + pgresult = PQexec(conninfo->connection, QUERY_PROCTAB); } rows = PQntuples(pgresult); } @@ -718,7 +716,7 @@ get_process_info_r(struct system_info *si, struct process_select *sel, if (pgresult != NULL) PQclear(pgresult); - PQfinish(pgconn); + disconnect_from_db(conninfo); /* Make sure we have enough slots for the active procs. */ if (activesize < total_procs) @@ -782,27 +780,25 @@ get_process_info_r(struct system_info *si, struct process_select *sel, } int -machine_init_r(struct statics *statics, const char *values[]) +machine_init_r(struct statics *statics, struct pg_conninfo_ctx *conninfo) { - PGconn *pgconn; - /* Make sure the remote system has the stored function installed. */ - pgconn = connect_to_db(values); - if (pgconn == NULL) + connect_to_db(conninfo); + if (conninfo->connection == NULL) { fprintf(stderr, "Cannot connect to database.\n"); return -1; } - if (check_for_function(pgconn, "pg_cputime") != 0) + if (check_for_function(conninfo->connection, "pg_cputime") != 0) return -1; - if (check_for_function(pgconn, "pg_loadavg") != 0) + if (check_for_function(conninfo->connection, "pg_loadavg") != 0) return -1; - if (check_for_function(pgconn, "pg_memusage") != 0) + if (check_for_function(conninfo->connection, "pg_memusage") != 0) return -1; - if (check_for_function(pgconn, "pg_proctab") != 0) + if (check_for_function(conninfo->connection, "pg_proctab") != 0) return -1; - PQfinish(pgconn); + disconnect_from_db(conninfo); /* fill in the statics information */ statics->procstate_names = procstatenames; @@ -44,22 +44,39 @@ int pg_version(PGconn *); -PGconn * -connect_to_db(const char *values[]) +void +connect_to_db(struct pg_conninfo_ctx *conninfo) { - PGconn *pgconn = NULL; + int i; const char *keywords[6] = {"host", "port", "user", "password", "dbname", NULL}; - pgconn = PQconnectdbParams(keywords, values, 1); - if (PQstatus(pgconn) != CONNECTION_OK) + if (conninfo->persistent && PQsocket(conninfo->connection) >= 0) + return; + + conninfo->connection = PQconnectdbParams(keywords, conninfo->values, 1); + if (PQstatus(conninfo->connection) != CONNECTION_OK) { - new_message(MT_standout | MT_delayed, " %s", PQerrorMessage(pgconn)); + new_message(MT_standout | MT_delayed, " %s", + PQerrorMessage(conninfo->connection)); - PQfinish(pgconn); - return NULL; + PQfinish(conninfo->connection); + conninfo->connection = NULL; + return; } - return pgconn; + + if (conninfo->persistent) + for (i = 0; i <5; i++) + if (conninfo->values[i] != NULL) + free((void *) conninfo->values[i]); +} + +void +disconnect_from_db(struct pg_conninfo_ctx *conninfo) +{ + if (conninfo->persistent) + return; + PQfinish(conninfo->connection); } PGresult * @@ -5,7 +5,15 @@ #include <libpq-fe.h> -PGconn *connect_to_db(const char **); +struct pg_conninfo_ctx +{ + PGconn *connection; + int persistent; + const char *values[6]; +}; + +void connect_to_db(struct pg_conninfo_ctx *); +void disconnect_from_db(struct pg_conninfo_ctx *); PGresult *pg_locks(PGconn *, int); PGresult *pg_processes(PGconn *); diff --git a/pg_top.1.in b/pg_top.1.in index d0558ba..9fd305c 100644 --- a/pg_top.1.in +++ b/pg_top.1.in @@ -58,7 +58,9 @@ List all available color tags and the current set of tests used for color highlighting, then exit. .TP .B \-W, \-\-password -Forces pg_top to prompt for a password before connecting to a database. +Forces pg_top to prompt for a password before connecting to a database. pg_top +will also keep the database connection open while running, and will clear the +database connection from memory for security. .TP .B \-b, \-\-batch Use \*(lqbatch\*(rq mode. In this mode, all input from the terminal is @@ -134,9 +136,6 @@ variable, if set. .TP \fB\-U \fR\fB\fIUSERNAME\fR\fR, \fB\-\-username=\fR\fB\fIUSERNAME\fR\fR User name to connect as. -.TP -.B \-W, \-\-password -Force pg_top to prompt for a password before connecting to a database. .PP Both .I COUNT @@ -168,7 +168,7 @@ usage(const char *progname) printf(" -h, --host=HOSTNAME database server host or socket directory\n"); printf(" -p, --port=PORT database server port\n"); printf(" -U, --username=USERNAME user name to connect as\n"); - printf(" -W, --password force password prompt\n"); + printf(" -W, --password force password prompt, and persistent connection\n"); } RETSIGTYPE @@ -204,27 +204,27 @@ do_display(struct pg_top_context *pgtctx) get_system_info(&pgtctx->system_info); #ifdef __linux__ processes = get_process_info(&pgtctx->system_info, &pgtctx->ps, tmp_index, - pgtctx->values, pgtctx->mode); + &pgtctx->conninfo, pgtctx->mode); #else processes = get_process_info(&pgtctx->system_info, &pgtctx->ps, tmp_index, - pgtctx->values); + &pgtctx->conninfo); #endif /* __linux__ */ } else { - get_system_info_r(&pgtctx->system_info, pgtctx->values); + get_system_info_r(&pgtctx->system_info, &pgtctx->conninfo); processes = get_process_info_r(&pgtctx->system_info, &pgtctx->ps, - pgtctx->order_index, pgtctx->values); + pgtctx->order_index, &pgtctx->conninfo); } /* Get database activity information */ - get_database_info(&pgtctx->db_info, pgtctx->values); + get_database_info(&pgtctx->db_info, &pgtctx->conninfo); /* Get database I/O information */ get_io_info(&pgtctx->io_info); /* display database disk info */ - get_disk_info(&pgtctx->disk_info, get_data_directory(pgtctx->values)); + get_disk_info(&pgtctx->disk_info, get_data_directory(&pgtctx->conninfo)); /* display the load averages */ (*d_loadave) (pgtctx->system_info.last_pid, pgtctx->system_info.load_avg); @@ -471,24 +471,26 @@ process_arguments(struct pg_top_context *pgtctx, int ac, char **av) } else { - pgtctx->values[PG_PORT] = strdup(optarg); + pgtctx->conninfo.values[PG_PORT] = strdup(optarg); } break; case 'W': /* prompt for database password */ - pgtctx->values[PG_PASSWORD] = simple_prompt("Password: ", 1000, 0); + pgtctx->conninfo.persistent = 1; + pgtctx->conninfo.values[PG_PASSWORD] = + simple_prompt("Password: ", 1000, 0); break; case 'U': /* database user name */ - pgtctx->values[PG_USER] = strdup(optarg); + pgtctx->conninfo.values[PG_USER] = strdup(optarg); break; case 'd': /* database name */ - pgtctx->values[PG_DBNAME] = strdup(optarg); + pgtctx->conninfo.values[PG_DBNAME] = strdup(optarg); break; case 'h': /* socket location */ - pgtctx->values[PG_HOST] = strdup(optarg); + pgtctx->conninfo.values[PG_HOST] = strdup(optarg); break; case 'r': /* remote mode */ @@ -720,6 +722,8 @@ main(int argc, char *argv[]) pgtctx.ps.usename[0] = '\0'; pgtctx.show_tags = No; pgtctx.topn = 0; + pgtctx.conninfo.connection = NULL; + pgtctx.conninfo.persistent = 0; /* Show help or version number if necessary */ if (argc > 1) @@ -836,7 +840,7 @@ main(int argc, char *argv[]) if (pgtctx.mode_remote == 0) i = machine_init(&pgtctx.statics); else - i = machine_init_r(&pgtctx.statics, pgtctx.values); + i = machine_init_r(&pgtctx.statics, &pgtctx.conninfo); if (i == -1) exit(1); @@ -1011,27 +1015,27 @@ main(int argc, char *argv[]) get_system_info(&pgtctx.system_info); #ifdef __linux__ (void) get_process_info(&pgtctx.system_info, &pgtctx.ps, 0, - pgtctx.values, pgtctx.mode); + &pgtctx.conninfo, pgtctx.mode); #else (void) get_process_info(&pgtctx.system_info, &pgtctx.ps, 0, - pgtctx.values); + &pgtctx.conninfo); #endif /* __linux__ */ } else { - get_system_info_r(&pgtctx.system_info, pgtctx.values); + get_system_info_r(&pgtctx.system_info, &pgtctx.conninfo); (void) get_process_info_r(&pgtctx.system_info, &pgtctx.ps, 0, - pgtctx.values); + &pgtctx.conninfo); } /* Get database activity information */ - get_database_info(&pgtctx.db_info, pgtctx.values); + get_database_info(&pgtctx.db_info, &pgtctx.conninfo); /* Get database I/O information */ get_io_info(&pgtctx.io_info); /* Get database disk information */ - get_disk_info(&pgtctx.disk_info, get_data_directory(pgtctx.values)); + get_disk_info(&pgtctx.disk_info, get_data_directory(&pgtctx.conninfo)); pgtctx.timeout.tv_sec = 1; pgtctx.timeout.tv_usec = 0; @@ -109,7 +109,7 @@ struct pg_top_context struct system_info system_info; struct timeval timeout; int topn; - const char *values[6]; + struct pg_conninfo_ctx conninfo; }; void quit(int); @@ -7,10 +7,10 @@ #include "machine.h" -int machine_init_r(struct statics *, const char **); -void get_system_info_r(struct system_info *, const char **); +int machine_init_r(struct statics *, struct pg_conninfo_ctx *); +void get_system_info_r(struct system_info *, struct pg_conninfo_ctx *); caddr_t get_process_info_r(struct system_info *, struct process_select *, int, - const char **); + struct pg_conninfo_ctx *); char *format_header_r(char *); char *format_next_io_r(caddr_t); char *format_next_process_r(caddr_t); |