Пример #1
0
int createBSADumpObject(char *BackupFilePathName)
{
	/* Populate the object descriptor of the first object to be backed up. */
	object_desc = (BSA_ObjectDescriptor *)malloc(sizeof(BSA_ObjectDescriptor));
	if(object_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Failed to allocate memory for NetBackup BSA object descriptor to perform Backup\n");
		return -1;
	}
	memset(object_desc, 0x00, sizeof(BSA_ObjectDescriptor));
	strncpy(object_desc->objectOwner.bsa_ObjectOwner, "XBSA Client", (1 + strlen("XBSA Client")));
	strncpy(object_desc->objectOwner.app_ObjectOwner, "XBSA App", (1 + strlen("XBSA App")));
	strncpy(object_desc->objectName.pathName, BackupFilePathName, (1 + strlen(BackupFilePathName)));
	strncpy(object_desc->objectName.objectSpaceName, "", (1 + strlen("")));
	strncpy(object_desc->resourceType, "Dump Object", (1 + strlen("Dump Object")));
	strncpy(object_desc->objectDescription,"A dump object contains a fixed sized portion of the dump data", (1 + strlen("A dump object contains a fixed sized portion of the dump data")));
	object_desc->copyType = BSA_CopyType_BACKUP;
	object_desc->estimatedSize.left = 0;
	object_desc->estimatedSize.right = 100;
	object_desc->objectType = BSA_ObjectType_FILE;

	/* Create the sample object. If the object  cannot be created,    *
	 * terminate the session.                                         */
	status = BSACreateObject(BsaHandle, object_desc, data_block);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSACreateObject() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "BSACreateObject() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Backup");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}
	return 0;
}
Пример #2
0
int endBSARestoreSession()
{
	status = BSAEndData(BsaHandle);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAEndData() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAEndData() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	/* End the backup transaction and commit the object.  */
	status = BSAEndTxn(BsaHandle, BSA_Vote_COMMIT);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAEndTxn() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAEndTxn() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSATerminate(BsaHandle);
		return -1;
	}

	/* End the XBSA session  */
	BSATerminate(BsaHandle);

	free(gpBsaBuf);

	return 0;
}
Пример #3
0
int initBSARestoreSession(char *bsaServiceHost)
{
	/* Allocate memory for the XBSA environment variable array. */
	for(i=0; i<2; i++){
		envx[i] = malloc(40);
		if(envx[i] == NULL){
			mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup BSA environment variables\n");
			return -1;
		}
		memset(envx[i], 0x00, 40);
	}

	/* Populate the XBSA environment variables for this session. */
	strncpy(envx[0], "BSA_API_VERSION=1.1.0", (1 + strlen("BSA_API_VERSION=1.1.0")));
	snprintf(envx[1], (1 + strlen("BSA_SERVICE_HOST=") + strlen(bsaServiceHost)), "BSA_SERVICE_HOST=%s", bsaServiceHost);
	envx[2] = NULL;

	/* The NetBackup XBSA Interface does not use the security token. */
	security_tokenPtr = NULL;

	/* Populate the object owner structure. */
	strncpy(BsaObjectOwner.bsa_ObjectOwner, "XBSA Client", (1 + strlen("XBSA Client")));
	strncpy(BsaObjectOwner.app_ObjectOwner, "XBSA App", (1 + strlen("XBSA App")));

	/* Initialize an XBSA session. */
	status = BSAInit(&BsaHandle, security_tokenPtr, &BsaObjectOwner, envx);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAInit() failed with error: %s\n", ErrorString);
		return -1;
	}

	/* Begin a restore transaction.  If the transaction cannot be opened, *
	 * terminate the session.                                            */
	status = BSABeginTxn(BsaHandle);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSABeginTxn() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSABeginTxn() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSATerminate(BsaHandle);
		return -1;
	}

	return 0;
}
Пример #4
0
/*
 * makeSureMonitorThreadEnds: This function adds a request for a TASK_FINISH
 * status row, and then waits for the g_monitor_tid to end.
 * This will happen as soon as the monitor thread processes this request.
 */
void
makeSureMonitorThreadEnds(int TaskRC, char *pszErrorMsg)
{
	StatusOp   *pOp;

	if (g_monitor_tid)
	{
		char	   *pszSuffix;

		if (TaskRC == TASK_RC_SUCCESS)
			pszSuffix = SUFFIX_SUCCEED;
		else
			pszSuffix = SUFFIX_FAIL;

		pOp = CreateStatusOp(TASK_FINISH, TaskRC, pszSuffix, pszErrorMsg);
		if (pOp == NULL)
		{
			/*
			 * This is really bad, since the only way we cab shut down
			 * gracefully is if we can insert a row into the ststus table.	Oh
			 * well, at least log a message and exit.
			 */
			mpp_err_msg(logError, progname, "*** aborted because of fatal memory allocation error\n");
			exit(1);
		}
		else
			AddToStatusOpList(g_pStatusOpList, pOp);

		pthread_join(g_monitor_tid, NULL);
	}
}
Пример #5
0
int sendBSADumpData(int NetBackupBlockSize)
{
	int read_res  = 0;
	gpBsaBuf = (char *)malloc(NetBackupBlockSize * sizeof(char));
	if(gpBsaBuf == NULL){
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Failed to allocate memory for NetBackup data transfer buffer to perform Backup\n");
		return -1;
	}
	memset(gpBsaBuf, 0x00, NetBackupBlockSize);

	/* We try to read the data to be dumped in chunks of 'NetBackupBlockSize' size 
	and send each chunk to the NetBackup server to be backed up */
	while((read_res = fread(gpBsaBuf, 1, NetBackupBlockSize, stdin)) > 0)
	{
		data_block->bufferLen = NetBackupBlockSize;
		data_block->bufferPtr = gpBsaBuf;
		data_block->numBytes  = read_res;

		status = BSASendData(BsaHandle, data_block);
		if (status != BSA_RC_SUCCESS) {
			ErrStrSize = 512;
			NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
			snprintf(msg, sizeof(msg), "ERROR: BSASendData() failed with error: %s\n", ErrorString);
			mpp_err_msg("ERROR", "gp_bsa_dump_agent", "BSASendData() failed with error: %s\n", ErrorString);
			NBBSALogMsg(BsaHandle, MSERROR, msg, "Backup");
			BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
			BSATerminate(BsaHandle);
			return -1;
		}

		if(read_res < NetBackupBlockSize){
			if(feof(stdin)){
				break;
			}
			else if(ferror(stdin)){
				mpp_err_msg("ERROR", "gp_bsa_dump_agent", "The following error occurred while reading data to be backed up by NetBackup\n");
				perror("gp_bsa_dump_agent");
				return -1;
			}
		}

	}

	return 0;
}
Пример #6
0
int getBSARestoreData(int NetBackupBlockSize)
{
	gpBsaBuf = (char *)malloc(NetBackupBlockSize * sizeof(char));
	if(gpBsaBuf == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup data transfer buffer to perform Backup\n");
		return -1;
	}
	memset(gpBsaBuf, 0x00, NetBackupBlockSize);

	/* Initialize the data_block structure.  */
	data_block->bufferLen = NetBackupBlockSize;
	data_block->bufferPtr = gpBsaBuf;
	memset(data_block->bufferPtr, 0x00, NetBackupBlockSize);

	/* Read data in chunks of size 'NetBackupBlockSize' until the end of data. 
	 * Each chunk is sent to stdout which gets piped to the psql program
	 * in order to restore the database */
	while ((status = BSAGetData(BsaHandle, data_block)) == BSA_RC_SUCCESS) {

		write(1, data_block->bufferPtr, data_block->numBytes);
		total_bytes += data_block->numBytes;

	}
	if (status == BSA_RC_NO_MORE_DATA) {

		/* The last BSAGetData() that returns BSA_RC_NO_MORE_DATA may have data  *
		 * in the buffer.                                                        */
		write(1, data_block->bufferPtr, data_block->numBytes);
		total_bytes += data_block->numBytes;

	} else {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAGetData() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAGetData() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	return 0;
}
Пример #7
0
/*
 * ReadBackendBackupFile: This function calls the backend function gp_read_backup_file
 * which reads the contents out of the appropriate file on the database server.
 * If the call succeeds/fails, it returns status code 0/-1, an appropriate error string
 * is inserted into the buffer of pszRtn.
 */
int
ReadBackendBackupFileError(PGconn *pConn, const char *pszBackupDirectory, const char *pszKey,
		BackupFileType fileType, const char *progName, PQExpBuffer pszRtn)
{
	char       *pszFileType;
	PQExpBuffer Qry;
	PGresult   *pRes;
	int status = 0;

	switch (fileType)
	{
		case BFT_BACKUP:
			pszFileType = "0";
			break;
		case BFT_BACKUP_STATUS:
			pszFileType = "1";
			break;
		case BFT_RESTORE_STATUS:
			pszFileType = "2";
			break;
		default:
			appendPQExpBuffer(pszRtn, "Unknown file type passed to ReadBackendBackupFile");
			mpp_err_msg("ERROR", progName, " %s: %d\n", pszRtn->data, fileType);
			return -1;
	}

	Qry = createPQExpBuffer();

	appendPQExpBuffer(Qry, "SELECT * FROM gp_read_backup_file('%s', '%s', %s)",
			StringNotNull(pszBackupDirectory, ""),
			StringNotNull(pszKey, ""),
			pszFileType);

	pRes = PQexec(pConn, Qry->data);
	if (!pRes || PQresultStatus(pRes) != PGRES_TUPLES_OK || PQntuples(pRes) == 0)
	{
		appendPQExpBuffer(pszRtn, "Error executing query %s : %s\n", Qry->data, PQerrorMessage(pConn));
		mpp_err_msg_cache("ERROR", progName, pszRtn->data);
		status = -1;
	}
	else
	{
		char *res = PQgetvalue(pRes, 0, 0);
		appendPQExpBufferStr(pszRtn, res);
		if (strstr(res, "ERROR:") || strstr(res, "[ERROR]"))
		{
			status = -1;
		}
	}

	PQclear(pRes);
	destroyPQExpBuffer(Qry);

	return status;
}
Пример #8
0
char *queryBSAObject(char *BackupFilePathName)
{
	/* Populate query descriptor */

	query_desc = (BSA_QueryDescriptor *)malloc(sizeof(BSA_QueryDescriptor));
	if(query_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup BSA Query Descriptor to perform Restore\n");
		return NULL;
	}
	memset(query_desc, 0x00, sizeof(BSA_QueryDescriptor));

	query_desc->copyType = BSA_CopyType_BACKUP;
	query_desc->objectType = BSA_ObjectType_FILE;
	query_desc->objectStatus = BSA_ObjectStatus_MOST_RECENT;
	strncpy(query_desc->objectOwner.bsa_ObjectOwner, "XBSA Client", (1 + strlen("XBSA Client")));
	strncpy(query_desc->objectOwner.app_ObjectOwner, "XBSA App", (1 + strlen("XBSA App")));
	strncpy(query_desc->objectName.pathName, BackupFilePathName, (1 + strlen(BackupFilePathName)));
	strncpy(query_desc->objectName.objectSpaceName, "", (1 + strlen("")));

	object_desc = (BSA_ObjectDescriptor *)malloc(sizeof(BSA_ObjectDescriptor));
	if(object_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup BSA Object Descriptor to perform Restore\n");
		return NULL;
	}
	memset(object_desc, 0x00, sizeof(BSA_ObjectDescriptor));

	/* Query BSA object to check if it has been backed up */
	status = BSAQueryObject(BsaHandle, query_desc, object_desc);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAQueryObject() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAQueryObject() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return NULL;
	}

	return BackupFilePathName;
}
Пример #9
0
/*
 * Safe_strdup:  returns strdup if not NULL, NULL otherwise
 */
char *
Safe_strdup(const char *s)
{
	if (s == NULL)
		return NULL;

	char *res = strdup(s);
	if(res == NULL)
	{
		mpp_err_msg("ERROR", "Safe_strdup", "Out of memory\n");
		exit(1);
	}

	return res;
}
Пример #10
0
/*
 * ReadBackendBackupFile: This function calls the backend function gp_read_backup_file
 * which reads the contents out of the appropriate file on the database server.
 * If the call fails, it returns NULL.	The returned pointer must be freed by the caller.
 */
char *
ReadBackendBackupFile(PGconn *pConn, const char *pszBackupDirectory, const char *pszKey, BackupFileType fileType, const char *progName)
{
	char	   *pszRtn = NULL;
	char	   *pszFileType;
	PQExpBuffer Qry;
	PGresult   *pRes;

	switch (fileType)
	{
		case BFT_BACKUP:
			pszFileType = "0";
			break;
		case BFT_BACKUP_STATUS:
			pszFileType = "1";
			break;
		case BFT_RESTORE_STATUS:
			pszFileType = "2";
			break;
		default:
			mpp_err_msg("ERROR", progName, "Unknown file type passed to ReadBackendBackupFile : %d\n", fileType);
			return NULL;
	}

	Qry = createPQExpBuffer();
	appendPQExpBuffer(Qry, "SELECT * FROM gp_read_backup_file('%s', '%s', %s)",
					  StringNotNull(pszBackupDirectory, ""),
					  StringNotNull(pszKey, ""),
					  pszFileType);

	pRes = PQexec(pConn, Qry->data);
	if (!pRes || PQresultStatus(pRes) != PGRES_TUPLES_OK || PQntuples(pRes) == 0)
	{
		mpp_err_msg_cache("ERROR", progName, "Error executing query %s : %s\n",
						  Qry->data,
						  PQerrorMessage(pConn));
	}
	else
	{
		pszRtn = strdup(PQgetvalue(pRes, 0, 0));
	}

	PQclear(pRes);
	destroyPQExpBuffer(Qry);

	return pszRtn;
}
Пример #11
0
int
main(int argc, char **argv)
{
	PQExpBuffer valueBuf = NULL;
	PQExpBuffer escapeBuf = createPQExpBuffer();
	RestoreOptions *opts;
	int			c;
	int			exit_code = 0;
	Archive    *AH;
	char	   *inputFileSpec = NULL;
	extern int	optind;
	extern char *optarg;
	static int	use_setsessauth = 0;
	static int	disable_triggers = 0;
	SegmentDatabase SegDB;
	StatusOp   *pOp;
	struct sigaction act;
	pid_t		newpid;

	/* int i; */
	PQExpBuffer	pszCmdLine;
	int			status;
	int			rc;
	char	   *pszErrorMsg;
	ArchiveHandle *pAH;
	int 		postDataSchemaOnly = 0;

#ifdef USE_DDBOOST
	char    *ddp_file_name = NULL;
	char 	*dd_boost_dir = NULL;
#endif

	struct option cmdopts[] = {
		{"clean", 0, NULL, 'c'},
		{"create", 0, NULL, 'C'},
		{"data-only", 0, NULL, 'a'},
		{"dbname", 1, NULL, 'd'},
		{"exit-on-error", 0, NULL, 'e'},
		{"file", 1, NULL, 'f'},
		{"format", 1, NULL, 'F'},
		{"function", 1, NULL, 'P'},
		{"host", 1, NULL, 'h'},
		{"ignore-version", 0, NULL, 'i'},
		{"index", 1, NULL, 'I'},
		{"list", 0, NULL, 'l'},
		{"no-privileges", 0, NULL, 'x'},
		{"no-acl", 0, NULL, 'x'},
		{"no-owner", 0, NULL, 'O'},
		{"no-reconnect", 0, NULL, 'R'},
		{"port", 1, NULL, 'p'},
		{"password", 0, NULL, 'W'},
		{"schema-only", 0, NULL, 's'},
		{"superuser", 1, NULL, 'S'},
		{"table", 1, NULL, 't'},
		{"trigger", 1, NULL, 'T'},
		{"use-list", 1, NULL, 'L'},
		{"username", 1, NULL, 'U'},
		{"verbose", 0, NULL, 'v'},

		/*
		 * the following options don't have an equivalent short option letter,
		 * but are available as '-X long-name'
		 */
		{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
		{"disable-triggers", no_argument, &disable_triggers, 1},

		/*
		 * the following are cdb specific, and don't have an equivalent short
		 * option
		 */
		{"gp-d", required_argument, NULL, 1},
		{"gp-e", no_argument, NULL, 2},
		{"gp-k", required_argument, NULL, 3},
		{"gp-c", required_argument, NULL, 4},
		{"target-dbid", required_argument, NULL, 5},
		{"target-host", required_argument, NULL, 6},
		{"target-port", required_argument, NULL, 7},
		{"post-data-schema-only", no_argument, &postDataSchemaOnly, 1},
		{"dd_boost_file", required_argument, NULL, 8},
		{"dd_boost_enabled", no_argument, NULL, 9},
		{"dd_boost_dir", required_argument, NULL, 10},
		{"dd_boost_buf_size", required_argument, NULL, 11},
		{"gp-f", required_argument, NULL, 12},
		{"prefix", required_argument, NULL, 13},
		{"status", required_argument, NULL, 14},
		{"netbackup-service-host", required_argument, NULL, 15},
		{"netbackup-block-size", required_argument, NULL, 16},
		{"change-schema-file", required_argument, NULL, 17},
		{"schema-level-file", required_argument, NULL, 18},
		{"ddboost-storage-unit",required_argument, NULL, 19},
		{NULL, 0, NULL, 0}
	};

	set_pglocale_pgservice(argv[0], "pg_dump");

	opts = NewRestoreOptions();

	/* set format default */
	opts->formatName = "p";

	progname = get_progname(argv[0]);

	if (argc > 1)
	{
		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
		{
			usage(progname);
			exit(0);
		}
		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
		{
			puts("pg_restore (Greenplum Database) " PG_VERSION);
			exit(0);
		}
	}

	while ((c = getopt_long(argc, argv, "acCd:ef:F:h:iI:lL:Op:P:RsS:t:T:uU:vwWxX:",
							cmdopts, NULL)) != -1)
	{
		switch (c)
		{
			case 'a':			/* Dump data only */
				opts->dataOnly = 1;
				break;
			case 'c':			/* clean (i.e., drop) schema prior to create */
				opts->dropSchema = 1;
				break;
			case 'C':
				opts->createDB = 1;
				break;
			case 'd':
				opts->dbname = strdup(optarg);
				break;
			case 'e':
				opts->exit_on_error = true;
				break;
			case 'f':			/* output file name */
				opts->filename = strdup(optarg);
				break;
			case 'F':
				if (strlen(optarg) != 0)
					opts->formatName = strdup(optarg);
				break;
			case 'h':
				if (strlen(optarg) != 0)
					opts->pghost = strdup(optarg);
				break;
			case 'i':
				/* obsolete option */
				break;

			case 'l':			/* Dump the TOC summary */
				opts->tocSummary = 1;
				break;

			case 'L':			/* input TOC summary file name */
				opts->tocFile = strdup(optarg);
				break;

			case 'O':
				opts->noOwner = 1;
				break;
			case 'p':
				if (strlen(optarg) != 0)
					opts->pgport = strdup(optarg);
				break;
			case 'R':
				/* no-op, still accepted for backwards compatibility */
				break;
			case 'P':			/* Function */
				opts->selTypes = 1;
				opts->selFunction = 1;
				opts->functionNames = strdup(optarg);
				break;
			case 'I':			/* Index */
				opts->selTypes = 1;
				opts->selIndex = 1;
				opts->indexNames = strdup(optarg);
				break;
			case 'T':			/* Trigger */
				opts->selTypes = 1;
				opts->selTrigger = 1;
				opts->triggerNames = strdup(optarg);
				break;
			case 's':			/* dump schema only */
				opts->schemaOnly = 1;
				break;
			case 'S':			/* Superuser username */
				if (strlen(optarg) != 0)
					opts->superuser = strdup(optarg);
				break;
			case 't':			/* Dump data for this table only */
				opts->selTypes = 1;
				opts->selTable = 1;
				opts->tableNames = strdup(optarg);
				break;

			case 'u':
				opts->promptPassword = TRI_YES;
				opts->username = simple_prompt("User name: ", 100, true);
				break;

			case 'U':
				opts->username = optarg;
				break;

			case 'v':			/* verbose */
				opts->verbose = 1;
				break;

			case 'w':
				opts->promptPassword = TRI_NO;
				break;

			case 'W':
				opts->promptPassword = TRI_YES;
				break;

			case 'x':			/* skip ACL dump */
				opts->aclsSkip = 1;
				break;

			case 'X':
				/* -X is a deprecated alternative to long options */
				if (strcmp(optarg, "use-set-session-authorization") == 0)
					use_setsessauth = 1;
				else if (strcmp(optarg, "disable-triggers") == 0)
					disable_triggers = 1;
				else
				{
					fprintf(stderr,
							_("%s: invalid -X option -- %s\n"),
							progname, optarg);
					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
					exit(1);
				}
				break;

			case 0:
				/* This covers the long options equivalent to -X xxx. */
				break;

			case 1:				/* --gp-d MPP Output Directory */
				g_pszMPPOutputDirectory = strdup(optarg);
				break;

			case 2:				/* --gp-e On Error Stop for psql */
				g_bOnErrorStop = opts->exit_on_error = true;
				break;

			case 3:				/* --gp-k MPP Dump Info Format is
								 * Key_s-dbid_s-role_t-dbid */
				g_gpdumpInfo = strdup(optarg);
				if (!ParseCDBDumpInfo(progname, g_gpdumpInfo, &g_gpdumpKey, &g_role, &g_sourceDBID, &g_MPPPassThroughCredentials))
				{
					exit(1);
				}
				break;
			case 4:				/* gp-c */
				g_compPg = strdup(optarg);
				break;
			case 5:				/* target-dbid */
				g_targetDBID = atoi(strdup(optarg));
				break;
			case 6:				/* target-host */
				g_targetHost = strdup(optarg);
				break;
			case 7:				/* target-port */
				g_targetPort = strdup(optarg);
				break;
#ifdef USE_DDBOOST
			case 9:
				dd_boost_enabled = 1;
				break;
			case 10:
				dd_boost_dir = strdup(optarg);
				break;
			case 11:
				dd_boost_buf_size = strdup(optarg);
				break;
#endif
			case 12:
				table_filter_file = strdup(optarg);
				break;

			case 13:
				dump_prefix = strdup(optarg);
				break;
            /* Hack to pass in the status_file name to cdbbackup.c (gp_restore_launch) */
			case 14:
				break;
			case 15:
				netbackup_service_host = strdup(optarg);
				break;
			case 16:
				netbackup_block_size = strdup(optarg);
				break;
			case 17:
				change_schema_file = strdup(optarg);
				break;
			case 18:
				schema_level_file = strdup(optarg);
				break;
#ifdef USE_DDBOOST
			case 19:
				ddboost_storage_unit = strdup(optarg);
				break;
#endif
			default:
				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
				exit(1);
		}
	}

	/* Should get at most one of -d and -f, else user is confused */
	if (opts->dbname)
	{
		if (opts->filename)
		{
			fprintf(stderr, _("%s: cannot specify both -d and -f output\n"),
					progname);
			fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
					progname);
			exit(1);
		}
		opts->useDB = 1;
	}

	opts->disable_triggers = disable_triggers;
	opts->use_setsessauth = use_setsessauth;

	if (opts->formatName)
	{

		switch (opts->formatName[0])
		{

			case 'c':
			case 'C':
				opts->format = archCustom;
				break;

			case 'f':
			case 'F':
				opts->format = archFiles;
				break;

			case 't':
			case 'T':
				opts->format = archTar;
				break;

			case 'p':
			case 'P':
				bUsePSQL = true;
				break;

			default:
				mpp_err_msg(logInfo, progname, "unrecognized archive format '%s'; please specify 't' or 'c'\n",
							opts->formatName);
				exit(1);
		}
	}

	if (g_gpdumpInfo == NULL)
	{
		mpp_err_msg(logInfo, progname, "missing required parameter gp-k (backup key)\n");
		exit(1);
	}

#ifdef USE_DDBOOST
	if (dd_boost_enabled)
	{
		/* remote is always false when restoring from primary DDR */
		int err = DD_ERR_NONE;
		err = ddp_init("gp_dump");
		if (err != DD_ERR_NONE)
		{
			mpp_err_msg("ERROR", "ddboost", "ddboost init failed. Err = %d\n", err);
			exit(1);
		}

		if (initDDSystem(&ddp_inst, &ddp_conn, &dd_client_info, &ddboost_storage_unit, false, &DEFAULT_BACKUP_DIRECTORY, false))
               	{
			mpp_err_msg(logInfo, progname, "Initializing DD system failed\n");
			exit(1);
		}

		mpp_err_msg(logInfo, progname, "ddboost is initialized\n");

		ddp_file_name = formDDBoostFileName(g_gpdumpKey, postDataSchemaOnly, dd_boost_dir);
		if (ddp_file_name == NULL)
		{
			mpp_err_msg(logInfo, progname, "Error in opening ddboost file\n");
			exit(1);
		}
	}
#endif

	SegDB.dbid = g_sourceDBID;
	SegDB.role = g_role;
	SegDB.port = opts->pgport ? atoi(opts->pgport) : 5432;
	SegDB.pszHost = opts->pghost ? strdup(opts->pghost) : NULL;
	SegDB.pszDBName = opts->dbname ? strdup(opts->dbname) : NULL;
	SegDB.pszDBUser = opts->username ? strdup(opts->username) : NULL;
	SegDB.pszDBPswd = NULL;

	if (g_MPPPassThroughCredentials != NULL && *g_MPPPassThroughCredentials != '\0')
	{
		unsigned int nBytes;
		char	   *pszDBPswd = Base64ToData(g_MPPPassThroughCredentials, &nBytes);

		if (pszDBPswd == NULL)
		{
			mpp_err_msg(logError, progname, "Invalid Greenplum DB Credentials:  %s\n", g_MPPPassThroughCredentials);
			exit(1);
		}
		if (nBytes > 0)
		{
			SegDB.pszDBPswd = malloc(nBytes + 1);
			if (SegDB.pszDBPswd == NULL)
			{
				mpp_err_msg(logInfo, progname, "Cannot allocate memory for Greenplum Database Credentials\n");
				exit(1);
			}

			memcpy(SegDB.pszDBPswd, pszDBPswd, nBytes);
			SegDB.pszDBPswd[nBytes] = '\0';
		}
	}

	if (g_role == ROLE_MASTER)
		g_conn = MakeDBConnection(&SegDB, true);
	else
		g_conn = MakeDBConnection(&SegDB, false);
	if (PQstatus(g_conn) == CONNECTION_BAD)
	{
		exit_horribly(NULL, NULL, "connection to database \"%s\" failed: %s",
					  PQdb(g_conn), PQerrorMessage(g_conn));
	}

	if (g_gpdumpKey != NULL)
	{
		/*
		 * Open the database again, for writing status info
		 */
		g_conn_status = MakeDBConnection(&SegDB, false);

		if (PQstatus(g_conn_status) == CONNECTION_BAD)
		{
			exit_horribly(NULL, NULL, "Connection on host %s failed: %s",
						  StringNotNull(SegDB.pszHost, "localhost"),
						  PQerrorMessage(g_conn_status));
		}

		g_main_tid = pthread_self();

		g_pStatusOpList = CreateStatusOpList();
		if (g_pStatusOpList == NULL)
		{
			exit_horribly(NULL, NULL, "cannot allocate memory for gp_backup_status operation\n");
		}

		/*
		 * Create thread for monitoring for cancel requests.  If we're running
		 * using PSQL, the monitor is not allowed to start until the worker
		 * process is forked.  This is done to prevent the forked process from
		 * being blocked by locks held by library routines (__tz_convert, for
		 * example).
		 */
		if (bUsePSQL)
		{
			pthread_mutex_lock(&g_threadSyncPoint);
		}
		pthread_create(&g_monitor_tid,
					   NULL,
					   monitorThreadProc,
					   NULL);

		/* Install Ctrl-C interrupt handler, now that we have a connection */
		if (!bUsePSQL)
		{
			act.sa_handler = myHandler;
			sigemptyset(&act.sa_mask);
			act.sa_flags = 0;
			act.sa_flags |= SA_RESTART;
			if (sigaction(SIGINT, &act, NULL) < 0)
			{
				mpp_err_msg(logInfo, progname, "Error trying to set SIGINT interrupt handler\n");
			}

			act.sa_handler = myHandler;
			sigemptyset(&act.sa_mask);
			act.sa_flags = 0;
			act.sa_flags |= SA_RESTART;
			if (sigaction(SIGTERM, &act, NULL) < 0)
			{
				mpp_err_msg(logInfo, progname, "Error trying to set SIGTERM interrupt handler\n");
			}
		}

		pOp = CreateStatusOp(TASK_START, TASK_RC_SUCCESS, SUFFIX_START, TASK_MSG_SUCCESS);
		if (pOp == NULL)
		{
			exit_horribly(NULL, NULL, "cannot allocate memory for gp_backup_status operation\n");
		}
		AddToStatusOpList(g_pStatusOpList, pOp);
	}
	/* end cdb additions */

	if (bUsePSQL)
	{
		/* Install Ctrl-C interrupt handler, now that we have a connection */
		act.sa_handler = psqlHandler;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		act.sa_flags |= SA_RESTART;
		if (sigaction(SIGINT, &act, NULL) < 0)
		{
			mpp_err_msg(logInfo, progname, "Error trying to set SIGINT interrupt handler\n");
		}

		act.sa_handler = psqlHandler;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		act.sa_flags |= SA_RESTART;
		if (sigaction(SIGTERM, &act, NULL) < 0)
		{
			mpp_err_msg(logInfo, progname, "Error trying to set SIGTERM interrupt handler\n");
		}

		/* Establish a SIGCHLD handler to catch termination the psql process */
		act.sa_handler = myChildHandler;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		act.sa_flags |= SA_RESTART;
		if (sigaction(SIGCHLD, &act, NULL) < 0)
		{
			mpp_err_msg(logInfo, progname, "Error trying to set SIGCHLD interrupt handler\n");
			exit(1);
		}

		mpp_err_msg(logInfo, progname, "Before fork of gp_restore_agent\n");

		newpid = fork();
		if (newpid < 0)
		{
			mpp_err_msg(logError, progname, "Failed to fork\n");
		}
		else if (newpid == 0)
		{
			/* TODO: use findAcceptableBackupFilePathName(...) to look for the file name
			 *       if user invoked gp_restore_agent directly without supplying a file name.
			 *       If the agent is invoked from gp_restore_launch, then we are ok.
			 */
			if (optind < argc)
			{
				char *rawInputFile = argv[optind];

				valueBuf = createPQExpBuffer();
				inputFileSpec = shellEscape(rawInputFile, valueBuf, false, false);
			}

			if (inputFileSpec == NULL || inputFileSpec[0] == '\0')
			{
				mpp_err_msg(logError, progname, "dump file path is empty");
				exit(1);
			}

			if (postDataSchemaOnly)
			{
				if (strstr(inputFileSpec,"_post_data") == NULL)
				{
					fprintf(stderr,"Adding _post_data to the end of the file name?\n");
					char * newFS = malloc(strlen(inputFileSpec) + strlen("_post_data") + 1);
					strcpy(newFS, inputFileSpec);
					strcat(newFS, "_post_data");
					inputFileSpec = newFS;
				}
			}

			pszCmdLine = createPQExpBuffer();
#ifdef USE_DDBOOST
			if (dd_boost_enabled)
			{
				formDDBoostPsqlCommandLine(pszCmdLine, argv[0],
									(postDataSchemaOnly == 1 ? true : false),
									g_role, g_compPg, ddp_file_name,
									dd_boost_buf_size, table_filter_file,
									change_schema_file, schema_level_file,
									ddboost_storage_unit);
			}
			else
			{
#endif
				formPsqlCommandLine(pszCmdLine, argv[0], (postDataSchemaOnly == 1), g_role,
									inputFileSpec, g_compPg, table_filter_file,
									netbackup_service_host, netbackup_block_size,
									change_schema_file, schema_level_file);
#ifdef USE_DDBOOST
			}
#endif

			appendPQExpBuffer(pszCmdLine, " -h %s -p %s -U %s -d ",
							  g_targetHost, g_targetPort, SegDB.pszDBUser);
			shellEscape(SegDB.pszDBName, pszCmdLine, true /* quote */, false /* reset */);
			appendPQExpBuffer(pszCmdLine, " -a ");

			if (g_bOnErrorStop)
				appendPQExpBuffer(pszCmdLine, " -v ON_ERROR_STOP=");

			if (g_role == ROLE_SEGDB)
				putenv("PGOPTIONS=-c gp_session_role=UTILITY");
			if (g_role == ROLE_MASTER)
				putenv("PGOPTIONS=-c gp_session_role=DISPATCH");

			mpp_err_msg(logInfo, progname, "Command Line: %s\n", pszCmdLine->data);

			/*
			 * Make this new process the process group leader of the children
			 * being launched.	This allows a signal to be sent to all
			 * processes in the group simultaneously.
			 */
			setpgid(newpid, newpid);

			execl("/bin/sh", "sh", "-c", pszCmdLine->data, NULL);

			mpp_err_msg(logInfo, progname, "Error in gp_restore_agent - execl of %s with Command Line %s failed",
						"/bin/sh", pszCmdLine->data);

			_exit(127);
		}
		else
		{
			/*
			 * Make the new child process the process group leader of the
			 * children being launched.  This allows a signal to be sent to
			 * all processes in the group simultaneously.
			 *
			 * This is a redundant call to avoid a race condition suggested by
			 * Stevens.
			 */
			setpgid(newpid, newpid);

			/* Allow the monitor thread to begin execution. */
			pthread_mutex_unlock(&g_threadSyncPoint);

			/* Parent .  Lets sleep and wake up until we see it's done */
			while (!bPSQLDone)
			{
				sleep(5);
			}

			/*
			 * If this process has been sent a SIGINT or SIGTERM, we need to
			 * send a SIGINT to the psql process GROUP.
			 */
			if (bKillPsql)
			{
				mpp_err_msg(logInfo, progname, "Terminating psql due to signal.\n");
				kill(-newpid, SIGINT);
			}

			waitpid(newpid, &status, 0);
			if (WIFEXITED(status))
			{
				rc = WEXITSTATUS(status);
				if (rc == 0)
				{
					mpp_err_msg(logInfo, progname, "psql finished with rc %d.\n", rc);
					/* Normal completion falls to end of routine. */
				}
				else
				{
					if (rc >= 128)
					{
						/*
						 * If the exit code has the 128-bit set, the exit code
						 * represents a shell exited by signal where the
						 * signal number is exitCode - 128.
						 */
						rc -= 128;
						pszErrorMsg = MakeString("psql finished abnormally with signal number %d.\n", rc);
					}
					else
					{
						pszErrorMsg = MakeString("psql finished abnormally with return code %d.\n", rc);
					}
					makeSureMonitorThreadEnds(TASK_RC_FAILURE, pszErrorMsg);
					free(pszErrorMsg);
					exit_code = 2;
				}
			}
			else if (WIFSIGNALED(status))
			{
				pszErrorMsg = MakeString("psql finished abnormally with signal number %d.\n", WTERMSIG(status));
				mpp_err_msg(logError, progname, pszErrorMsg);
				makeSureMonitorThreadEnds(TASK_RC_FAILURE, pszErrorMsg);
				free(pszErrorMsg);
				exit_code = 2;
			}
			else
			{
				pszErrorMsg = MakeString("psql crashed or finished badly; status=%#x.\n", status);
				mpp_err_msg(logError, progname, pszErrorMsg);
				makeSureMonitorThreadEnds(TASK_RC_FAILURE, pszErrorMsg);
				free(pszErrorMsg);
				exit_code = 2;
			}
		}
	}
	else
	{
		AH = OpenArchive(inputFileSpec, opts->format);

		/* Let the archiver know how noisy to be */
		AH->verbose = opts->verbose;

		/*
	     * Whether to keep submitting sql commands as "pg_restore ... | psql ... "
		 */
		AH->exit_on_error = opts->exit_on_error;

		if (opts->tocFile)
			SortTocFromFile(AH, opts);

		if (opts->tocSummary)
			PrintTOCSummary(AH, opts);
		else
		{
			pAH = (ArchiveHandle *) AH;

			if (opts->useDB)
			{
				/* check for version mismatch */
				if (pAH->version < K_VERS_1_3)
					die_horribly(NULL, NULL, "direct database connections are not supported in pre-1.3 archives\n");

				pAH->connection = g_conn;
				/* XXX Should get this from the archive */
				AH->minRemoteVersion = 070100;
				AH->maxRemoteVersion = 999999;

				_check_database_version(pAH);
			}

			RestoreArchive(AH, opts);

			/*
			 * The following is necessary when the -C option is used.  A new
			 * connection is gotten to the database within RestoreArchive
			 */
			if (pAH->connection != g_conn)
				g_conn = pAH->connection;
		}

		/* done, print a summary of ignored errors */
		if (AH->n_errors)
			fprintf(stderr, _("WARNING: errors ignored on restore: %d\n"),
					AH->n_errors);

		/* AH may be freed in CloseArchive? */
		exit_code = AH->n_errors ? 1 : 0;

		CloseArchive(AH);
	}

#ifdef USE_DDBOOST
	if(dd_boost_enabled)
		cleanupDDSystem();
	free(ddboost_storage_unit);
#endif

	makeSureMonitorThreadEnds(TASK_RC_SUCCESS, TASK_MSG_SUCCESS);

	DestroyStatusOpList(g_pStatusOpList);

	if (change_schema_file)
		free(change_schema_file);
	if (schema_level_file)
		free(schema_level_file);
	if (SegDB.pszHost)
		free(SegDB.pszHost);
	if (SegDB.pszDBName)
		free(SegDB.pszDBName);
	if (SegDB.pszDBUser)
		free(SegDB.pszDBUser);
	if (SegDB.pszDBPswd)
		free(SegDB.pszDBPswd);
	if (valueBuf)
		destroyPQExpBuffer(valueBuf);
	if (escapeBuf)
		destroyPQExpBuffer(escapeBuf);

	PQfinish(g_conn);
	if (exit_code == 0)
		mpp_err_msg(logInfo, progname, "Finished successfully\n");
	else
		mpp_err_msg(logError, progname, "Finished with errors\n");
	return exit_code;
}
Пример #12
0
int deleteBSAObjects(char *NetBackupDeleteObject)
{
	int del_status;
	/* Populate query descriptor */

	query_desc = (BSA_QueryDescriptor *)malloc(sizeof(BSA_QueryDescriptor));
	if(query_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_delete_agent", "Failed to allocate memory for NetBackup BSA Query Descriptor to Query Objects to be deleted\n");
		return -1;
	}
	memset(query_desc, 0x00, sizeof(BSA_QueryDescriptor));

	query_desc->copyType = BSA_CopyType_BACKUP;
	query_desc->objectType = BSA_ObjectType_FILE;
	query_desc->objectStatus = BSA_ObjectStatus_MOST_RECENT;
	strncpy(query_desc->objectOwner.bsa_ObjectOwner, "XBSA Client", (1 + strlen("XBSA Client")));
	strncpy(query_desc->objectOwner.app_ObjectOwner, "XBSA App", (1 + strlen("XBSA App")));
	strncpy(query_desc->objectName.pathName, NetBackupDeleteObject, (1 + strlen(NetBackupDeleteObject)));
	strncpy(query_desc->objectName.objectSpaceName, "", (1 + strlen("")));

	object_desc = (BSA_ObjectDescriptor *)malloc(sizeof(BSA_ObjectDescriptor));
	if(object_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_delete_agent", "Failed to allocate memory for NetBackup BSA Object Descriptor to Query Objects to be deleted\n");
		return -1;
	}
	memset(object_desc, 0x00, sizeof(BSA_ObjectDescriptor));

	/* Query BSA object to check if it has been backed up */
	status = BSAQueryObject(BsaHandle, query_desc, object_desc);
	if (status == BSA_RC_SUCCESS) {
		printf("Deleting BSA object from NBU server: %s\n", (char *)object_desc->objectName.pathName);
		del_status = BSADeleteObject(BsaHandle, object_desc->copyId);
		if (del_status != BSA_RC_SUCCESS) {
			ErrStrSize = 512;
			NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
			snprintf(msg, sizeof(msg), "INFO: BSADeleteObject() failed to delete given BSA objects: %s\n", ErrorString);
			mpp_err_msg("INFO", "gp_bsa_delete_agent", "BSADeleteObject() did not find any object matching the given format: %s\n", ErrorString);
			NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
			BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
			BSATerminate(BsaHandle);
			return -1;
		}
	}
	else if (status == BSA_RC_NO_MATCH) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "INFO: BSAQueryObject() did not find any object matching the query to delete objects: %s\n", ErrorString);
		mpp_err_msg("INFO", "gp_bsa_delete_agent", "BSAQueryObject() did not find any object matching the query to delete objects: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}
	else {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAQueryObject() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_delete_agent", "BSAQueryObject() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	while ((status = BSAGetNextQueryObject(BsaHandle, object_desc)) == BSA_RC_SUCCESS) {
		printf("Deleting BSA object from NBU server: %s\n", (char *)object_desc->objectName.pathName);
		del_status = BSADeleteObject(BsaHandle, object_desc->copyId);
		if (del_status != BSA_RC_SUCCESS) {
			ErrStrSize = 512;
			NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
			snprintf(msg, sizeof(msg), "INFO: BSADeleteObject() failed to delete given BSA objects: %s\n", ErrorString);
			mpp_err_msg("INFO", "gp_bsa_delete_agent", "BSADeleteObject() did not find any object matching the given format: %s\n", ErrorString);
			NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
			BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
			BSATerminate(BsaHandle);
			return -1;
		}
	}

	if (status != BSA_RC_NO_MORE_DATA) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAQueryObject() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_delete_agent", "BSAQueryObject() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	status = BSAEndTxn(BsaHandle, BSA_Vote_COMMIT);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAEndTxn() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_delete_agent", "BSAEndTxn() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	return 0;
}
Пример #13
0
int
main(int argc, char *argv[]){

	int c;

	static struct option long_options[] = {
		{"netbackup-service-host", required_argument, NULL, 1},
		{"netbackup-filename", required_argument, NULL, 2},
		{"netbackup-block-size", required_argument, NULL, 3},
		{NULL, 0, NULL, 0}
	};

	int optindex;
	progname = (char *)get_progname(argv[0]);

	if (argc > 1)
	{
		if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-?") == 0))
		{
			help(progname);
			exit(0);
		}
		if ((strcmp(argv[1], "--version") == 0) || (strcmp(argv[1], "-V") == 0))
		{
			puts("pg_dump (PostgreSQL) " PG_VERSION);
			exit(0);
		}
	}

	while((c = getopt_long(argc, argv, "123", long_options, &optindex)) != -1)
	{
		switch(c)
		{
			case 1:
				netbackupServiceHost = Safe_strdup(optarg);
				break;
			case 2:
				netbackupRestoreFilename = Safe_strdup(optarg);
				break;
			case 3:
				netbackupBlockSize = atoi(optarg);
				break;
			default:
				fprintf(stderr, _("Wrong option entered. Try \"%s --help\" for more information.\n"), progname);
				exit(1);
		}
	}

	if (optind < argc)
	{
		fprintf(stderr, _("%s: Too many command-line arguments (first is \"%s\")\n"), progname, argv[optind + 1]);
		fprintf(stderr, _("Try \"%s --help\" for more information\n"), progname);
		exit(1);
	}

	if (netbackupServiceHost == NULL)
	{
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Need to provide --netbackup-service-host mandatory param.\nTry \"%s --help\" for more information\n", progname);
		exit(1);
	}

	if (netbackupRestoreFilename == NULL)
	{
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Need to provide NetBackup Dump File Path.\nTry \"%s --help\" for more information\n", progname);
		exit(1);
	}

	BackupFilePathLength = strlen(netbackupRestoreFilename);
	BackupFilePathName = (char *)malloc(sizeof(char) *(1 + BackupFilePathLength));
	if(BackupFilePathName == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for Restore Filename\n");
		exit(1);
	}
	memset(BackupFilePathName, 0x00, (1 + BackupFilePathLength));
	strncpy(BackupFilePathName, netbackupRestoreFilename, (1 + BackupFilePathLength));

	NetBackupServiceHost = (char *)malloc(sizeof(char) *(1 + strlen(netbackupServiceHost)));
	if(NetBackupServiceHost == NULL){
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Failed to allocate memory for NetBackup Service Hostname\n");
		exit(1);
	}
	memset(NetBackupServiceHost, 0x00, (1 + strlen(netbackupServiceHost)));
	strncpy(NetBackupServiceHost, netbackupServiceHost, (1 + strlen(netbackupServiceHost)));

	if(initBSARestoreSession(NetBackupServiceHost) != 0){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to initialize the NetBackup BSA session to perform Restore\n");
		exit(1);
	}

	if(getBSARestoreObject(BackupFilePathName) != 0){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to get the NetBackup BSA restore object to perform Restore\n");
		exit(1);
	}

	if(getBSARestoreData(netbackupBlockSize) != 0){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to get data from NetBackup in order to perform Restore\n");
		exit(1);
	}

	if(endBSARestoreSession() != 0){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to end the NetBackup BSA session after completion of Restore\n");
		exit(1);
	}

	free(BackupFilePathName);
	free(NetBackupServiceHost);
	free(netbackupRestoreFilename);
	free(netbackupServiceHost);
	exit(0);
}
Пример #14
0
int initBSADumpSession(char *bsaServiceHost, char *nbbsaPolicy, char *nbbsaSchedule, char *nbbsaKeyword)
{

	/* Allocate memory for the XBSA environment variable array. */
	for(i = 0; i<5; i++){
		envx[i] = malloc(40);
		if(envx[i] == NULL){
			mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Failed to allocate memory for NetBackup BSA enviroment variables\n");
			return -1;
		}
		memset(envx[i], 0x00, 40);
	}

	/* Populate the XBSA environment variables for this session. */
	strncpy(envx[0], "BSA_API_VERSION=1.1.0", (1 + strlen("BSA_API_VERSION=1.1.0")));
	snprintf(envx[1], (1 + strlen("BSA_SERVICE_HOST=") + strlen(bsaServiceHost)), "BSA_SERVICE_HOST=%s", bsaServiceHost);
	snprintf(envx[2], (1 + strlen("NBBSA_POLICY=") + strlen(nbbsaPolicy)), "NBBSA_POLICY=%s", nbbsaPolicy);
	snprintf(envx[3], (1 + strlen("NBBSA_SCHEDULE=") + strlen(nbbsaSchedule)), "NBBSA_SCHEDULE=%s", nbbsaSchedule);
	if(nbbsaKeyword)
	{
		if (strlen(nbbsaKeyword) > 100)
		{
			mpp_err_msg("ERROR", "gp_bsa_dump_agent", "NetBackup Keyword provided has more than max limit (100) characters. Cannot proceed with backup.\n");
			return -1;
		}
		snprintf(envx[4], (1 + strlen("NBBSA_KEYWORD=") + strlen(nbbsaKeyword)), "NBBSA_KEYWORD=%s", nbbsaKeyword);
	}
	else
		envx[4] = NULL;

	envx[5] = NULL;

	/* The NetBackup XBSA Interface does not use the security token. */
	security_tokenPtr = NULL;

	/* Populate the object owner structure. */
	strncpy(BsaObjectOwner.bsa_ObjectOwner, "XBSA Client", (1 + strlen("XBSA Client")));
	strncpy(BsaObjectOwner.app_ObjectOwner, "XBSA App", (1 + strlen("XBSA App")));

	/* Initialize an XBSA session. */
	status = BSAInit(&BsaHandle, security_tokenPtr, &BsaObjectOwner, envx);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "BSAInit() failed with error: %s\n", ErrorString);
		return -1;
	}

	/* Begin a backup transaction.  If the transaction cannot be opened, *
	 * terminate the session.                                            */
	status = BSABeginTxn(BsaHandle);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSABeginTxn() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "BSABeginTxn() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Backup");
		BSATerminate(BsaHandle);
		return -1;
	}

	/* Initialize the BSA_DataBlock32 structure.  */
	data_block = (BSA_DataBlock32 *)malloc(sizeof(BSA_DataBlock32));
	if(data_block == NULL){
		mpp_err_msg("ERROR", "gp_bsa_dump_agent", "Failed to allocate memory for NetBackup BSA data block to perform Backup\n");
		return -1;
	}
	memset(data_block, 0x00, sizeof(BSA_DataBlock32));

	return 0;
}
Пример #15
0
int getBSARestoreObject(char *BackupFilePathName)
{
	/* Populate the query descriptor of the object to be restored.  The query step  *
	 * can be skipped if the XBSA application keeps a catalog of the copyId's of   *
	 * the objects which have been backed up.                                      */

	query_desc = (BSA_QueryDescriptor *)malloc(sizeof(BSA_QueryDescriptor));
	if(query_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup BSA Query Descriptor to perform Restore\n");
		return -1;
	}
	memset(query_desc, 0x00, sizeof(BSA_QueryDescriptor));

	query_desc->copyType = BSA_CopyType_BACKUP;
	query_desc->objectType = BSA_ObjectType_FILE;
	query_desc->objectStatus = BSA_ObjectStatus_MOST_RECENT;
	strncpy(query_desc->objectOwner.bsa_ObjectOwner, "XBSA Client", (1 + strlen("XBSA Client")));
	strncpy(query_desc->objectOwner.app_ObjectOwner, "XBSA App", (1 + strlen("XBSA App")));
	strncpy(query_desc->objectName.pathName, BackupFilePathName, (1 + strlen(BackupFilePathName)));
	strncpy(query_desc->objectName.objectSpaceName, "", (1 + strlen("")));

	object_desc = (BSA_ObjectDescriptor *)malloc(sizeof(BSA_ObjectDescriptor));
	if(object_desc == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup BSA Object Descriptor to perform Restore\n");
		return -1;
	}
	memset(object_desc, 0x00, sizeof(BSA_ObjectDescriptor));

	/* Find the object to be restored.  If the copyId and other object information needed  *
	 * to restore the object are known, this step can be skipped. */
	status = BSAQueryObject(BsaHandle, query_desc, object_desc);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAQueryObject() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAQueryObject() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	/* Get the object.  */
	data_block = (BSA_DataBlock32 *)malloc(sizeof(BSA_DataBlock32));
	if(data_block == NULL){
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "Failed to allocate memory for NetBackup BSA data block to perform Restore\n");
		return -1;
	}
	memset(data_block, 0x00, sizeof(BSA_DataBlock32));
	status = BSAGetObject(BsaHandle, object_desc, data_block);
	if (status != BSA_RC_SUCCESS) {
		ErrStrSize = 512;
		NBBSAGetErrorString(status, &ErrStrSize, ErrorString);
		snprintf(msg, sizeof(msg), "ERROR: BSAQueryObject() failed with error: %s\n", ErrorString);
		mpp_err_msg("ERROR", "gp_bsa_restore_agent", "BSAQueryObject() failed with error: %s\n", ErrorString);
		NBBSALogMsg(BsaHandle, MSERROR, msg, "Restore");
		BSAEndTxn(BsaHandle, BSA_Vote_ABORT);
		BSATerminate(BsaHandle);
		return -1;
	}

	return 0;
}
Пример #16
0
bool
GetRestoreSegmentDatabaseArray(PGconn *pConn,
							   RestorePairArray * restorePairAr,
							   BackupLoc backupLocation,
							   char *restore_set_str,
							   bool dataOnly)
{
	bool		bRtn = true;
	PQExpBuffer pQry = NULL;
	PGresult   *pRes = NULL;
	int			ntups;
	int			count;
	int			i_dbid;
	int			i_content;
	int			i_host;
	int			i_port;
	int			i;
	int			j;
	int			x;
	int			dbidset_count = 0;
	int		   *dbidset = NULL;
	SegmentDatabase *sourceSegDB;
	SegmentDatabase *targetSegDB;

	pQry = createPQExpBuffer();

	appendPQExpBuffer(pQry, "SELECT"
					  " dbid,"
					  " content,"
					  " hostname,"
					  " port "
					  "FROM "
					  " gp_segment_configuration "
					  "WHERE role='p' "
					  "ORDER BY content DESC");

	pRes = PQexec(pConn, pQry->data);
	if (!pRes || PQresultStatus(pRes) != PGRES_TUPLES_OK)
	{
		mpp_err_msg("ERROR", "gp_restore", "query to obtain list of Greenplum segment databases failed: %s",
					PQerrorMessage(pConn));
		bRtn = false;
		goto cleanup;
	}

	ntups = PQntuples(pRes);
	if (ntups <= 0)
	{
		mpp_err_msg("ERROR", "gp_restore", "no Greenplum segment databases found on master segment schema");
		bRtn = false;
		goto cleanup;
	}

	count = ntups + 1;

	/*
	 * Allocate enough memory for all of them, even though some may be
	 * filtered out.
	 */
	restorePairAr->count = 0;
	restorePairAr->pData = (RestorePair *) calloc(count, sizeof(RestorePair));
	if (restorePairAr->pData == NULL)
	{
		mpp_err_msg("ERROR", "gp_restore", "Unable to allocate memory for Greenplum segment database information\n");
		bRtn = false;
		goto cleanup;
	}

	/* get the column numbers */
	i_dbid = PQfnumber(pRes, "dbid");
	i_content = PQfnumber(pRes, "content");
	i_host = PQfnumber(pRes, "hostname");
	i_port = PQfnumber(pRes, "port");

	/*
	 * if the dump file is on individual databases, parse the list of dbid's
	 * where those files exist.
	 */
	if (backupLocation == FILE_ON_INDIVIDUAL)
	{
		/* allocate dbidset. len is more than we need but it's a safe bet */
		dbidset = (int *) calloc(strlen(restore_set_str), sizeof(int));
		MemSet(dbidset, 0, strlen(restore_set_str) * sizeof(int));

		if (dbidset == NULL)
		{
			mpp_err_msg("ERROR", "gp_restore", "Unable to allocate memory for Greenplum dbidset information\n");
			bRtn = false;
			goto cleanup;
		}

		/* parse the user specified dbid list, return dbid count */
		dbidset_count = parseDbidSet(dbidset, restore_set_str);

		if (dbidset_count < 1)
		{
			bRtn = false;
			goto cleanup;
		}

		for (i = 0; i < dbidset_count; i++)
		{
			bool		match = false;

			for (j = 0; j < ntups; j++)
			{
				int			dbid = atoi(PQgetvalue(pRes, j, i_dbid));

				if (dbid == dbidset[i])
				{
					match = true;
					break;
				}
			}

			if (!match)
			{
				mpp_err_msg("ERROR", "gp_restore", "dbid %d is not a primary Greenplum segment databases entry\n",
							dbidset[i]);
				bRtn = false;
				goto cleanup;
			}
		}
	}

	mpp_err_msg("INFO", "gp_restore", "Preparing to restore the following segments:\n");

	/* Read through the results set.  */
	x = 0;
	for (i = 0; i < ntups; i++)
	{
		int			dbid = atoi(PQgetvalue(pRes, i, i_dbid));
		int			contentid = atoi(PQgetvalue(pRes, i, i_content));
		bool		should_restore = false;

		/* if dataOnly don't restore the master (table definitions) */
		if (dataOnly && contentid == -1)
			continue;

		if (backupLocation == FILE_ON_INDIVIDUAL)
		{
			should_restore = false;

			for (j = 0; j < dbidset_count; j++)
			{
				if (dbid == dbidset[j])
					should_restore = true;
			}

			if (!should_restore)
				continue;
		}

		targetSegDB = &restorePairAr->pData[x].segdb_target;
		targetSegDB->dbid = dbid;
		targetSegDB->role = (contentid == -1 ? ROLE_MASTER : ROLE_SEGDB);
		targetSegDB->port = atoi(PQgetvalue(pRes, i, i_port));
		targetSegDB->pszHost = strdup(PQgetvalue(pRes, i, i_host));
		targetSegDB->pszDBName = PQdb(pConn);
		targetSegDB->pszDBUser = PQuser(pConn);
		targetSegDB->pszDBPswd = PQpass(pConn);
		targetSegDB->content = contentid;

		sourceSegDB = &restorePairAr->pData[x].segdb_source;
		sourceSegDB->dbid = targetSegDB->dbid;
		sourceSegDB->role = targetSegDB->role;
		sourceSegDB->port = targetSegDB->port;
		sourceSegDB->pszHost = targetSegDB->pszHost;
		sourceSegDB->pszDBName = targetSegDB->pszDBName;
		sourceSegDB->pszDBUser = targetSegDB->pszDBUser;
		if (targetSegDB->pszDBPswd)
			sourceSegDB->pszDBPswd = targetSegDB->pszDBPswd;

		if (targetSegDB->role == ROLE_MASTER)
			mpp_err_msg("INFO", "gp_restore", "Master (dbid 1)\n");
		else
			mpp_err_msg("INFO", "gp_restore", "Segment %d (dbid %d)\n",
						contentid,
						targetSegDB->dbid);

		x++;
	}

	/* set the count to be the number that passed the set inclusion test */
	restorePairAr->count = x;

cleanup:
	if (pQry != NULL)
		destroyPQExpBuffer(pQry);
	if (pRes != NULL)
		PQclear(pRes);

	return bRtn;
}
Пример #17
0
/* GetSegmentDatabaseArray: This function reads all active instance segment pairs
 * from the function gp_segment_instance_map().
 * It then uses the set specification fo filter out any instid, segid combinations
 * that don't match the set.  bExcludeHead = true is used for restoring, because
 * the head is restored first seperately from the rest of the databases.
 */
bool
GetDumpSegmentDatabaseArray(PGconn *pConn,
							int remote_version,
							SegmentDatabaseArray *pSegDBAr,
							ActorSet actors,
							char *dump_set_str,
							char *pszDBName,
							char *pszUserName,
							bool dataOnly,
							bool schemaOnly)
{
	bool		bRtn = true;
	PQExpBuffer pQry = NULL;
	PGresult   *pRes = NULL;
	int			ntups;
	int			count;
	int			i_dbid;
	int			i_content;
	int			i_host;
	int			i_port;
	int			i;
	int			j;
	int			x;
	int			dbidset_count = 0;
	int		   *dbidset = NULL;
	SegmentDatabase *pSegDB;

	pQry = createPQExpBuffer();

	if (remote_version >= 80214)
		/* 4.0 and beyond */
		appendPQExpBuffer(pQry, "SELECT"
						  " dbid,"
						  " content,"
						  " hostname,"
						  " port "
						  "FROM "
						  " gp_segment_configuration "
						  "WHERE role='p' "
						  "ORDER BY content DESC");
	else
		/* pre 4.0 */
		appendPQExpBuffer(pQry, "SELECT"
						  " dbid,"
						  " content,"
						  " hostname,"
						  " port "
						  "FROM"
						  " gp_configuration "
						  "WHERE valid = 't' "
						  "AND isPrimary = 't' "
						  "ORDER BY content DESC");

	pRes = PQexec(pConn, pQry->data);
	if (!pRes || PQresultStatus(pRes) != PGRES_TUPLES_OK)
	{
		mpp_err_msg("ERROR", "gp_dump", "query to obtain list of Greenplum segment databases failed: %s",
					PQerrorMessage(pConn));
		bRtn = false;
		goto cleanup;
	}

	ntups = PQntuples(pRes);
	if (ntups <= 0)
	{
		mpp_err_msg("ERROR", "gp_dump", "no Greenplum segment databases found on master segment schema");
		bRtn = false;
		goto cleanup;
	}

	count = ntups + 1;

	/*
	 * See how many set elements there are that were specified by HostIP or
	 * name.
	 */

	/*
	 * Allocate enough memory for all of them, even though some may be
	 * filtered out.
	 */
	pSegDBAr->count = 0;
	pSegDBAr->pData = (SegmentDatabase *) calloc(count, sizeof(SegmentDatabase));
	if (pSegDBAr->pData == NULL)
	{
		mpp_err_msg("ERROR", "gp_dump", "Unable to allocate memory for Greenplum segment/instances information\n");
		bRtn = false;
		goto cleanup;
	}

	/* get the column numbers */
	i_dbid = PQfnumber(pRes, "dbid");
	i_content = PQfnumber(pRes, "content");
	i_host = PQfnumber(pRes, "hostname");
	i_port = PQfnumber(pRes, "port");

	/*
	 * if an individual set of dbid's was requested to be dumped, parse it and
	 * check that it really exists and is a primary segment.
	 */
	if (actors == SET_INDIVIDUAL)
	{
		/* allocate dbidset. len is more than we need but it's a safe bet */
		dbidset = (int *) calloc(strlen(dump_set_str), sizeof(int));
		MemSet(dbidset, 0, strlen(dump_set_str) * sizeof(int));

		if (dbidset == NULL)
		{
			mpp_err_msg("ERROR", "gp_dump", "Unable to allocate memory for Greenplum dbid set information\n");
			bRtn = false;
			goto cleanup;
		}

		/* parse the user specified dbid list, return dbid count */
		dbidset_count = parseDbidSet(dbidset, dump_set_str);

		if (dbidset_count < 1)
		{
			bRtn = false;
			goto cleanup;
		}

		for (i = 0; i < dbidset_count; i++)
		{
			bool		match = false;

			for (j = 0; j < ntups; j++)
			{
				int			dbid = atoi(PQgetvalue(pRes, j, i_dbid));

				if (dbid == dbidset[i])
				{
					match = true;
					break;
				}
			}

			if (!match)
			{
				mpp_err_msg("ERROR", "gp_dump", "dbid %d is not a correct Greenplum segment databases "
						"entry, or is not a primary segment\n ", dbidset[i]);
				bRtn = false;
				goto cleanup;
			}
		}
	}

	mpp_err_msg("INFO", "gp_dump", "Preparing to dump the following segments:\n");

	/* Read through the results set (all primary segments) */
	x = 0;
	for (i = 0; i < ntups; i++)
	{
		int			dbid = atoi(PQgetvalue(pRes, i, i_dbid));
		int			content = atoi(PQgetvalue(pRes, i, i_content));
		bool		should_dump = false;

		/* in dataOnly we don't dump master information */
		if (dataOnly && content == -1 && actors != SET_INDIVIDUAL)
			continue;

		/* in schemaOnly we skip all but the master */
		if (schemaOnly && content != -1 && actors != SET_INDIVIDUAL)
			continue;

		if (actors == SET_INDIVIDUAL)
		{
			should_dump = false;

			for (j = 0; j < dbidset_count; j++)
			{
				if (dbid == dbidset[j])
					should_dump = true;
			}

			if (!should_dump)
				continue;
		}

		pSegDB = &pSegDBAr->pData[x++];
		pSegDB->dbid = dbid;
		pSegDB->content = content;
		pSegDB->role = (content == -1 ? ROLE_MASTER : ROLE_SEGDB);
		pSegDB->port = atoi(PQgetvalue(pRes, i, i_port));
		pSegDB->pszHost = strdup(PQgetvalue(pRes, i, i_host));
		pSegDB->pszDBName = pszDBName;
		pSegDB->pszDBUser = pszUserName;
		pSegDB->pszDBPswd = PQpass(pConn);

		if (pSegDB->role == ROLE_MASTER)
			mpp_err_msg("INFO", "gp_dump", "Master (dbid 1)\n");
		else
			mpp_err_msg("INFO", "gp_dump", "Segment %d (dbid %d)\n",
						pSegDB->content,
						pSegDB->dbid);
	}

	/* set the count to be the number that passed the set inclusion test */
	pSegDBAr->count = x;

cleanup:
	if (pQry != NULL)
		destroyPQExpBuffer(pQry);
	if (pRes != NULL)
		PQclear(pRes);

	return bRtn;
}
Пример #18
0
int main(int argc, char **argv)
{
	mpp_err_msg("INFO", "gp_bsa_restore_agent", "\ngp_bsa_restore_agent is not supported on this platform\n\n");
	exit(0);
}