Esempio n. 1
0
void
RowKeyAdd(size_t i)
{
	g_row_key = pg_realloc(g_row_key, (g_row_key_n + 1) * sizeof(size_t));
	g_row_key[g_row_key_n] = i;
	g_row_key_n++;
}
Esempio n. 2
0
/*
 * load_directory()
 *
 * Read all the file names in the specified directory, and return them as
 * an array of "struct dirent" pointers.  The array address is returned in
 * *namelist, and the function result is the count of file names.
 *
 * To free the result data, free each namelist array member, then free the
 * namelist array itself.
 */
int
load_directory(const char *dirname, struct dirent *** namelist)
{
	DIR		   *dirdesc;
	struct dirent *direntry;
	int			count = 0;
	int			allocsize = 64;
	size_t		entrysize;

	*namelist = (struct dirent **)
		pg_malloc(allocsize * sizeof(struct dirent *));

	if ((dirdesc = opendir(dirname)) == NULL)
		pg_log(PG_FATAL, "could not open directory \"%s\": %s\n",
			   dirname, getErrorText(errno));

	while (errno = 0, (direntry = readdir(dirdesc)) != NULL)
	{
		if (count >= allocsize)
		{
			allocsize *= 2;
			*namelist = (struct dirent **)
				pg_realloc(*namelist, allocsize * sizeof(struct dirent *));
		}

		entrysize = offsetof(struct dirent, d_name) +
			strlen(direntry->d_name) + 1;

		(*namelist)[count] = (struct dirent *) pg_malloc(entrysize);

		memcpy((*namelist)[count], direntry, entrysize);

		count++;
	}

#ifdef WIN32
	/*
	 * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
	 * released version
	 */
	if (GetLastError() == ERROR_NO_MORE_FILES)
		errno = 0;
#endif

	if (errno)
		pg_log(PG_FATAL, "could not read directory \"%s\": %s\n",
			   dirname, getErrorText(errno));

	closedir(dirdesc);

	return count;
}
Esempio n. 3
0
/*
 * add_one_elt
 *
 * Add one element to a (possibly empty) eary struct.
 */
void
add_one_elt(char *eltname, eary *eary)
{
	if (eary->alloc == 0)
	{
		eary	  ->alloc = 8;
		eary	  ->array = (char **) pg_malloc(8 * sizeof(char *));
	}
	else if (eary->num >= eary->alloc)
	{
		eary	  ->alloc *= 2;
		eary	  ->array = (char **) pg_realloc(eary->array,
											   eary->alloc * sizeof(char *));
	}

	eary	  ->array[eary->num] = pg_strdup(eltname);
	eary	  ->num++;
}
Esempio n. 4
0
/*
 * Convert the linked list of entries in map->first/last to the array,
 * map->array.
 */
static void
filemap_list_to_array(filemap_t *map)
{
	int			narray;
	file_entry_t *entry,
			   *next;

	map->array = (file_entry_t **)
		pg_realloc(map->array,
				   (map->nlist + map->narray) * sizeof(file_entry_t *));

	narray = map->narray;
	for (entry = map->first; entry != NULL; entry = next)
	{
		map->array[narray++] = entry;
		next = entry->next;
		entry->next = NULL;
	}
	Assert(narray == map->nlist + map->narray);
	map->narray = narray;
	map->nlist = 0;
	map->first = map->last = NULL;
}
Esempio n. 5
0
void *
repalloc(void *pointer, Size size)
{
	return pg_realloc(pointer, size);
}
Esempio n. 6
0
/*
 * Try to read a timeline's history file.
 *
 * If successful, return the list of component TLIs (the given TLI followed by
 * its ancestor TLIs).  If we can't find the history file, assume that the
 * timeline has no parents, and return a list of just the specified timeline
 * ID.
 */
TimeLineHistoryEntry *
rewind_parseTimeLineHistory(char *buffer, TimeLineID targetTLI, int *nentries)
{
	char	   *fline;
	TimeLineHistoryEntry *entry;
	TimeLineHistoryEntry *entries = NULL;
	int			nlines = 0;
	TimeLineID	lasttli = 0;
	XLogRecPtr	prevend;
	char	   *bufptr;
	bool		lastline = false;

	/*
	 * Parse the file...
	 */
	prevend = InvalidXLogRecPtr;
	bufptr = buffer;
	while (!lastline)
	{
		char	   *ptr;
		TimeLineID	tli;
		uint32		switchpoint_hi;
		uint32		switchpoint_lo;
		int			nfields;

		fline = bufptr;
		while (*bufptr && *bufptr != '\n')
			bufptr++;
		if (!(*bufptr))
			lastline = true;
		else
			*bufptr++ = '\0';

		/* skip leading whitespace and check for # comment */
		for (ptr = fline; *ptr; ptr++)
		{
			if (!isspace((unsigned char) *ptr))
				break;
		}
		if (*ptr == '\0' || *ptr == '#')
			continue;

		nfields = sscanf(fline, "%u\t%X/%X", &tli, &switchpoint_hi, &switchpoint_lo);

		if (nfields < 1)
		{
			/* expect a numeric timeline ID as first field of line */
			fprintf(stderr, _("syntax error in history file: %s\n"), fline);
			fprintf(stderr, _("Expected a numeric timeline ID.\n"));
			exit(1);
		}
		if (nfields != 3)
		{
			fprintf(stderr, _("syntax error in history file: %s\n"), fline);
			fprintf(stderr, _("Expected a write-ahead log switchpoint location.\n"));
			exit(1);
		}
		if (entries && tli <= lasttli)
		{
			fprintf(stderr, _("invalid data in history file: %s\n"), fline);
			fprintf(stderr, _("Timeline IDs must be in increasing sequence.\n"));
			exit(1);
		}

		lasttli = tli;

		nlines++;
		entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));

		entry = &entries[nlines - 1];
		entry->tli = tli;
		entry->begin = prevend;
		entry->end = ((uint64) (switchpoint_hi)) << 32 | (uint64) switchpoint_lo;
		prevend = entry->end;

		/* we ignore the remainder of each line */
	}

	if (entries && targetTLI <= lasttli)
	{
		fprintf(stderr, _("invalid data in history file\n"));
		fprintf(stderr, _("Timeline IDs must be less than child timeline's ID.\n"));
		exit(1);
	}

	/*
	 * Create one more entry for the "tip" of the timeline, which has no entry
	 * in the history file.
	 */
	nlines++;
	if (entries)
		entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));
	else
		entries = pg_malloc(1 * sizeof(TimeLineHistoryEntry));

	entry = &entries[nlines - 1];
	entry->tli = targetTLI;
	entry->begin = prevend;
	entry->end = InvalidXLogRecPtr;

	*nentries = nlines;
	return entries;
}
Esempio n. 7
0
/*
 * Parse "arg", which is a string of column IDs separated by "separator".
 *
 * Each column ID can be:
 * - a number from 1 to PQnfields(res)
 * - an unquoted column name matching (case insensitively) one of PQfname(res,...)
 * - a quoted column name matching (case sensitively) one of PQfname(res,...)
 *
 * If max_columns > 0, it is the max number of column IDs allowed.
 *
 * On success, return number of column IDs found (possibly 0), and return a
 * malloc'd array of the matching column numbers of "res" into *col_numbers.
 *
 * On failure, return -1 and set *col_numbers to NULL.
 */
static int
parseColumnRefs(const char *arg,
				const PGresult *res,
				int **col_numbers,
				int max_columns,
				char separator)
{
	const char *p = arg;
	char		c;
	int			num_cols = 0;

	*col_numbers = NULL;
	while ((c = *p) != '\0')
	{
		const char *field_start = p;
		bool		quoted_field = false;

		/* first char */
		if (c == '"')
		{
			quoted_field = true;
			p++;
		}

		while ((c = *p) != '\0')
		{
			if (c == separator && !quoted_field)
				break;
			if (c == '"')		/* end of field or embedded double quote */
			{
				p++;
				if (*p == '"')
				{
					if (quoted_field)
					{
						p++;
						continue;
					}
				}
				else if (quoted_field && *p == separator)
					break;
			}
			if (*p)
				p += PQmblen(p, pset.encoding);
		}

		if (p != field_start)
		{
			char   *col_name;
			int		col_num;

			/* enforce max_columns limit */
			if (max_columns > 0 && num_cols == max_columns)
			{
				psql_error(_("No more than %d column references expected\n"),
						   max_columns);
				goto errfail;
			}
			/* look up the column and add its index into *col_numbers */
			col_name = pg_malloc(p - field_start + 1);
			memcpy(col_name, field_start, p - field_start);
			col_name[p - field_start] = '\0';
			col_num = indexOfColumn(col_name, res);
			pg_free(col_name);
			if (col_num < 0)
				goto errfail;
			*col_numbers = (int *) pg_realloc(*col_numbers,
											  (num_cols + 1) * sizeof(int));
			(*col_numbers)[num_cols++] = col_num;
		}
		else
		{
			psql_error(_("Empty column reference\n"));
			goto errfail;
		}

		if (*p)
			p += PQmblen(p, pset.encoding);
	}
	return num_cols;

errfail:
	pg_free(*col_numbers);
	*col_numbers = NULL;
	return -1;
}
Esempio n. 8
0
int
main(int argc, char **argv)
{
	int			c;
	char		*nodename = NULL; /* GTM Proxy nodename */

	progname = "gtm_ctl";

	/*
	 * save argv[0] so do_start() can look for the gtm if necessary. we
	 * don't look for gtm here because in many cases we won't need it.
	 */
	argv0 = argv[0];

	umask(077);

	/* support --help and --version even if invoked as root */
	if (argc > 1)
	{
		if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||
			strcmp(argv[1], "-?") == 0)
		{
			do_help();
			exit(0);
		}
		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
		{
			puts("gtm_ctl (Postgres-XC) " PGXC_VERSION);
			exit(0);
		}
	}

	/*
	 * Disallow running as root, to forestall any possible security holes.
	 */
	if (geteuid() == 0)
	{
		write_stderr(_("%s: cannot be run as root\n"
					   "Please log in (using, e.g., \"su\") as the "
					   "(unprivileged) user that will\n"
					   "own the server process.\n"),
					 progname);
		exit(1);
	}

	/*
	 * 'Action' can be before or after args so loop over both. Some
	 * getopt_long() implementations will reorder argv[] to place all flags
	 * first (GNU?), but we don't rely on it. Our /port version doesn't do
	 * that.
	 */
	optind = 1;

	/* process command-line options */
	while (optind < argc)
	{
		while ((c = getopt(argc, argv, "D:i:l:m:o:p:t:wWZ:C:")) != -1)
		{
			switch (c)
			{
				case 'D':
					{
						char	   *env_var = pg_malloc(strlen(optarg) + 9);

						gtmdata_D = xstrdup(optarg);
						canonicalize_path(gtmdata_D);
						snprintf(env_var, strlen(optarg) + 9, "GTMDATA=%s",
								 gtmdata_D);
						putenv(env_var);

						/*
						 * We could pass GTMDATA just in an environment
						 * variable but we do -D too for clearer gtm
						 * 'ps' display
						 */
						gtmdata_opt = (char *) pg_malloc(strlen(gtmdata_D) + 8);
						snprintf(gtmdata_opt, strlen(gtmdata_D) + 8,
								 "-D \"%s\" ",
								 gtmdata_D);
						break;
					}
				case 'i':
					nodename = strdup(optarg);
					break;
				case 'l':
					log_file = xstrdup(optarg);
					break;
				case 'm':
					set_mode(optarg);
					break;
				case 'o':
					gtm_opts = xstrdup(optarg);
					break;
				case 'p':
					gtm_path = xstrdup(optarg);
					canonicalize_path(gtm_path);
					break;
				case 't':
					wait_seconds = atoi(optarg);
					break;
				case 'C':
					control_file = xstrdup(optarg);
					break;
				case 'w':
					do_wait = true;
					wait_set = true;
					break;
				case 'W':
					do_wait = false;
					wait_set = true;
					break;
				case 'Z':
					gtm_app = xstrdup(optarg);
					if (strcmp(gtm_app,"gtm_proxy") != 0
						&& strcmp(gtm_app,"gtm_standby") != 0
						&& strcmp(gtm_app,"gtm") != 0)
					{
						write_stderr(_("%s: %s launch name set not correct\n"), progname, gtm_app);
						do_advice();
						exit(1);
					}
					break;
				default:
					/* getopt_long already issued a suitable error message */
					do_advice();
					exit(1);
			}
		}

		/* Process an action */
		if (optind < argc)
		{
			if (ctl_command != NO_COMMAND)
			{
				write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
				do_advice();
				exit(1);
			}

			if (strcmp(argv[optind], "start") == 0)
				ctl_command = START_COMMAND;
			else if (strcmp(argv[optind], "stop") == 0)
				ctl_command = STOP_COMMAND;
			else if (strcmp(argv[optind], "promote") == 0)
				ctl_command = PROMOTE_COMMAND;
			else if (strcmp(argv[optind], "restart") == 0)
				ctl_command = RESTART_COMMAND;
			else if (strcmp(argv[optind], "status") == 0)
				ctl_command = STATUS_COMMAND;
			else if (strcmp(argv[optind], "reconnect") == 0)
				ctl_command = RECONNECT_COMMAND;
			else
			{
				write_stderr(_("%s: unrecognized operation mode \"%s\"\n"),
							 progname, argv[optind]);
				do_advice();
				exit(1);
			}
			optind++;
		}
	}

	/*
	 * Take care of the control file (-C Option)
	 */
	if (control_file)
	{
		char ctrl_path[MAXPGPATH+1];
		char C_opt_path[MAXPGPATH+1];
		char bkup_path[MAXPGPATH+1];
		FILE *f1, *f2;
		int c;

		if (!gtmdata_D)
		{
			write_stderr(_("No -D option specified.\n"));
			exit(1);
		}
		if ((strcmp(gtm_app, "gtm") != 0) && (strcmp(gtm_app, "gtm_master") != 0))
		{
			write_stderr(_("-C option is valid only for gtm.\n"));
			exit(1);
		}
		/* If there's already a control file, backup it to *.bak */
		trim_last_slash(gtmdata_D);
		snprintf(ctrl_path, MAXPGPATH, "%s/%s", gtmdata_D, GTM_CONTROL_FILE);
		if ((f1 = fopen(ctrl_path, "r")))
		{

			snprintf(bkup_path, MAXPGPATH, "%s/%s.bak", gtmdata_D, GTM_CONTROL_FILE);
			if (!(f2 = fopen(bkup_path, "w")))
			{
				fclose(f1);
				write_stderr(_("Cannot open backup file, %s/%s.bak, %s\n"),
							 gtmdata_D, GTM_CONTROL_FILE, strerror(errno));
				exit(1);
			}
			while ((c = getc(f1)) != EOF)
				putc(c, f2);
			fclose(f1);
			fclose(f2);
		}
		/* Copy specified control file. */
		snprintf(C_opt_path, MAXPGPATH, "%s/%s", gtmdata_D, control_file);
		if (!(f1 = fopen(ctrl_path, "w")))
		{
			write_stderr(_("Cannot oopen control file, %s, %s\n"), ctrl_path, strerror(errno));
			exit(1);
		}
		if (!(f2 = fopen(C_opt_path, "r")))
		{
			fclose(f1);
			write_stderr(_("Cannot open -C option file, %s, %s\n"), C_opt_path, strerror(errno));
			exit(1);
		}
		while ((c = getc(f2)) != EOF)
			putc(c, f1);
		fclose(f1);
		fclose(f2);
	}

	if (ctl_command == NO_COMMAND)
	{
		write_stderr(_("%s: no operation specified\n"), progname);
		do_advice();
		exit(1);
	}

	gtm_data = getenv("GTMDATA");

	if (gtm_data)
	{
		gtm_data = xstrdup(gtm_data);
		canonicalize_path(gtm_data);
	}

	if (!gtm_data)
	{
		write_stderr("%s: no GTM/GTM Proxy directory specified \n",
					 progname);
		do_advice();
		exit(1);
	}

	/*
	 * pid files of gtm and gtm proxy are named differently
	 * -Z option has also to be set for STOP_COMMAND
	 * or gtm_ctl will not be able to find the correct pid_file
	 */
	if (!gtm_app)
	{
		write_stderr("%s: no launch option not specified\n",
					 progname);
		do_advice();
		exit(1);
	}

	if (strcmp(gtm_app,"gtm_proxy") != 0 &&
		strcmp(gtm_app, "gtm_standby") != 0 &&
		strcmp(gtm_app,"gtm") != 0)
	{
		write_stderr(_("%s: launch option incorrect\n"),
						progname);
		do_advice();
		exit(1);
	}

	/* Check if GTM Proxy ID is set, this is not necessary when stopping */
	if (ctl_command == START_COMMAND ||
		ctl_command == RESTART_COMMAND)
	{
		/* Rebuild option string to include Proxy ID */
		if (strcmp(gtm_app, "gtm_proxy") == 0)
		{
			gtmdata_opt = (char *) pg_realloc(gtmdata_opt, strlen(gtmdata_opt) + 9);
			if (nodename)
				sprintf(gtmdata_opt, "%s -i %s ", gtmdata_opt, nodename);
			else
				sprintf(gtmdata_opt, "%s ", gtmdata_opt);
		}
	}

	if (!wait_set)
	{
		switch (ctl_command)
		{
			case RESTART_COMMAND:
			case START_COMMAND:
			case PROMOTE_COMMAND:
			case STATUS_COMMAND:
				do_wait = false;
				break;
			case STOP_COMMAND:
				do_wait = true;
				break;
			default:
				break;
		}
	}

	/* Build strings for pid file and option file */
	if (strcmp(gtm_app,"gtm_proxy") == 0)
	{
		snprintf(pid_file, MAXPGPATH, "%s/gtm_proxy.pid", gtm_data);
		snprintf(gtmopts_file, MAXPGPATH, "%s/gtm_proxy.opts", gtm_data);
		snprintf(conf_file, MAXPGPATH, "%s/gtm_proxy.conf", gtm_data);
	}
	else if (strcmp(gtm_app,"gtm") == 0)
	{
		snprintf(pid_file, MAXPGPATH, "%s/gtm.pid", gtm_data);
		snprintf(gtmopts_file, MAXPGPATH, "%s/gtm.opts", gtm_data);
		snprintf(conf_file, MAXPGPATH, "%s/gtm.conf", gtm_data);
	}
	else if (strcmp(gtm_app,"gtm_standby") == 0)
	{
		snprintf(pid_file, MAXPGPATH, "%s/gtm.pid", gtm_data);
		snprintf(gtmopts_file, MAXPGPATH, "%s/gtm.opts", gtm_data);
		snprintf(conf_file, MAXPGPATH, "%s/gtm.conf", gtm_data);
	}

	if (ctl_command==STATUS_COMMAND)
		gtm_opts = xstrdup("-c");

	switch (ctl_command)
	{
		case START_COMMAND:
			do_start();
			break;
		case STOP_COMMAND:
			do_stop();
			break;
		case PROMOTE_COMMAND:
			do_promote();
			break;
		case RESTART_COMMAND:
			do_restart();
			break;
		case STATUS_COMMAND:
			do_status();
			break;
		case RECONNECT_COMMAND:
			do_reconnect();
			break;
		default:
			break;
	}

	exit(0);
}