openGauss-server/contrib/pgxc_ctl/utils.cpp

370 lines
8.1 KiB
C++

/*-------------------------------------------------------------------------
*
* utils.c
*
* Utility module of Postgres-XC configuration and operation tool.
*
* Copyright (c) 2013 Postgres-XC Development Group
*
*-------------------------------------------------------------------------
*/
/*
* Variable useful tools/small routines.
*/
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include <stdio.h>
#include "../../src/interfaces/libpq/libpq-fe.h"
#include "utils.h"
#include "pgxc_ctl.h"
#include "pgxc_ctl_log.h"
#include "do_shell.h"
#include "config.h"
#include "variables.h"
#include "varnames.h"
static int Malloc_ed = 0;
static int Strdup_ed = 0;
static int Freed = 0;
void* Malloc(size_t size)
{
void* rv = malloc(size);
Malloc_ed++;
if (rv == NULL) {
elog(PANIC, "PANIC: No more memory. See core file for details.\n");
abort();
}
return (rv);
}
char** addToList(char** List, char* val)
{
char** rv;
int ii;
for (ii = 0; List[ii]; ii++)
;
rv = Realloc(List, sizeof(char*) * ii);
rv[ii - 1] = NULL;
return rv;
}
void* Malloc0(size_t size)
{
void* rv = malloc(size);
Malloc_ed++;
if (rv == NULL) {
elog(PANIC, "PANIC: No more memory. See core file for details.\n");
abort();
}
memset(rv, 0, size);
return (rv);
}
void* Realloc(void* ptr, size_t size)
{
void* rv = realloc(ptr, size);
if (rv == NULL) {
elog(PANIC, "PANIC: No more memory. See core file for details.\n");
abort();
}
return (rv);
}
void Free(void* ptr)
{
Freed++;
if (ptr)
free(ptr);
}
/*
* If flag is TRUE and chdir fails, then exit(1)
*/
int Chdir(char* path, int flag)
{
if (chdir(path)) {
elog(ERROR,
"ERROR: Could not change work directory to \"%s\". %s%s\n",
path,
flag == TRUE ? "Exiting. " : "",
strerror(errno));
if (flag == TRUE)
exit(1);
else
return -1;
}
return 0;
}
FILE* Fopen(char* path, char* mode)
{
FILE* rv = NULL;
if ((rv = fopen(path, mode)) == NULL)
elog(ERROR, "ERROR: Could not open the file \"%s\" in \"%s\", %s\n", path, mode, strerror(errno));
return (rv);
}
char* Strdup(const char* s)
{
char* rv = NULL;
Strdup_ed++;
rv = strdup(s);
if (rv == NULL) {
elog(PANIC, "PANIC: No more memory. See core file for details.\n");
abort();
}
return (rv);
}
void appendFiles(FILE* f, char** fileList)
{
FILE* src = NULL;
int ii;
char buf[MAXLINE + 1];
if (fileList)
for (ii = 0; fileList[ii]; ii++) {
if (!is_none(fileList[ii])) {
if ((src = fopen(fileList[ii], "r")) == 0) {
elog(ERROR, "ERROR: could not open file %s for read, %s\n", fileList[ii], strerror(errno));
continue;
}
while (fgets(buf, MAXLINE, src))
fputs(buf, f);
fclose(src);
}
}
}
FILE* prepareLocalStdin(char* buf, int len, char** fileList)
{
FILE* f = NULL;
if ((f = fopen(createLocalFileName(STDIN, buf, len), "w")) == NULL) {
elog(ERROR, "ERROR: could not open file %s for write, %s\n", buf, strerror(errno));
return (NULL);
}
appendFiles(f, fileList);
return (f);
}
char* timeStampString(char* buf, int len)
{
time_t nowTime;
struct tm nowTm;
nowTime = time(NULL);
localtime_r(&nowTime, &nowTm);
snprintf(buf,
len,
"%04d%02d%02d_%02d:%02d:%02d",
nowTm.tm_year + 1900,
nowTm.tm_mon + 1,
nowTm.tm_mday,
nowTm.tm_hour,
nowTm.tm_min,
nowTm.tm_sec);
return (buf);
}
char** makeActualNodeList(char** nodeList)
{
char** actualNodeList;
int ii, jj;
for (ii = 0, jj = 0; nodeList[ii]; ii++) {
if (!is_none(nodeList[ii]))
jj++;
}
actualNodeList = Malloc0(sizeof(char*) * (jj + 1));
for (ii = 0, jj = 0; nodeList[ii]; ii++) {
if (!is_none(nodeList[ii])) {
actualNodeList[jj] = Strdup(nodeList[ii]);
jj++;
}
}
return actualNodeList;
}
int gtmProxyIdx(char* gtmProxyName)
{
int ii;
for (ii = 0; aval(VAR_gtmProxyNames)[ii]; ii++) {
if (strcmp(aval(VAR_gtmProxyNames)[ii], gtmProxyName) == 0)
return ii;
}
return -1;
}
int coordIdx(char* coordName)
{
int ii;
if (is_none(coordName))
return -1;
for (ii = 0; aval(VAR_coordNames)[ii]; ii++) {
if (strcmp(aval(VAR_coordNames)[ii], coordName) == 0)
return ii;
}
return -1;
}
int datanodeIdx(char* datanodeName)
{
int ii;
if (is_none(datanodeName))
return -1;
for (ii = 0; aval(VAR_datanodeNames)[ii]; ii++) {
if (strcmp(aval(VAR_datanodeNames)[ii], datanodeName) == 0)
return ii;
}
return -1;
}
int getEffectiveGtmProxyIdxFromServerName(char* serverName)
{
int ii;
if (serverName == NULL)
return (-1);
for (ii = 0; aval(VAR_gtmProxyNames)[ii]; ii++) {
if (strcmp(aval(VAR_gtmProxyServers)[ii], serverName) == 0)
return ii;
}
return -1;
}
/*
* Please note that this function deeply depend upon
* the environment.
*
* It works find with CentOS/Ubuntu/ReadHat Linux but
* may need another tweak for other operation systems
* such as Solaris, FreeBSD, MacOS.
*/
pid_t get_prog_pid(char* host, char* progname, char* dir)
{
char cmd[MAXLINE + 1];
char pid_s[MAXLINE + 1];
int ii;
FILE* wkf = NULL;
char* token = NULL;
char* line = NULL;
snprintf(cmd,
MAXLINE,
"ssh %s@%s "
"\"ps -f -C %s | grep %s\"",
sval(VAR_pgxcUser),
host,
progname,
dir);
wkf = popen(cmd, "r");
if (wkf == NULL) {
elog(ERROR,
"ERROR: cannot obtain pid value of the remote postmaster, host \"%s\" dir \"%s\", %s\n",
host,
dir,
strerror(errno));
return (-1);
}
fgets(pid_s, MAXLINE, wkf);
fclose(wkf);
/* Get the second token */
line = pid_s;
if ((line = get_word(line, &token)) == NULL)
return 0;
get_word(line, &token);
if (token == NULL)
return 0;
for (ii = 0; token[ii]; ii++)
if (token[ii] < '0' || token[ii] > '9')
return 0;
return (atoi(token));
}
int pingNode(char* host, char* port)
{
PGPing status;
char conninfo[MAXLINE + 1];
char editBuf[MAXPATH + 1];
conninfo[0] = 0;
if (host) {
snprintf(editBuf, MAXPATH, "host = '%s' ", host);
strncat(conninfo, editBuf, MAXLINE);
}
if (port) {
snprintf(editBuf, MAXPATH, "port = %d ", atoi(port));
strncat(conninfo, editBuf, MAXLINE);
}
if (conninfo[0]) {
status = PQping(conninfo);
if (status == PQPING_OK)
return 0;
else
return 1;
} else
return -1;
}
void trimNl(char* s)
{
for (; *s && *s != '\n'; s++)
;
*s = 0;
}
char* getChPidList(char* host, pid_t ppid)
{
FILE* wkf = NULL;
char cmd[MAXLINE + 1];
char line[MAXLINE + 1];
char* rv = Malloc(MAXLINE + 1);
rv[0] = 0;
snprintf(cmd, MAXLINE, "ssh %s@%s pgrep -P %d", sval(VAR_pgxcUser), host, ppid);
wkf = popen(cmd, "r");
if (wkf == NULL)
return NULL;
while (fgets(line, MAXLINE, wkf)) {
trimNl(line);
strncat(rv, line, MAXLINE);
strncat(rv, " ", MAXLINE);
}
return rv;
}
char* getIpAddress(char* hostName)
{
char command[MAXLINE + 1];
char* ipAddr = NULL;
FILE* f = NULL;
snprintf(command, MAXLINE, "ping -c1 %s | head -n 1 | sed 's/^[^(]*(\\([^)]*\\).*$/\\1/'", hostName);
if ((f = popen(command, "r")) == NULL) {
elog(ERROR, "ERROR: could not open the command, \"%s\", %s\n", command, strerror(errno));
return NULL;
}
ipAddr = Malloc(MAXTOKEN + 1);
fgets(ipAddr, MAXTOKEN, f);
fclose(f);
trimNl(ipAddr);
return ipAddr;
}