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; }
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; }
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; }
/* * 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); } }
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; }
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; }
/* * 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; }
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; }
/* * 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; }
/* * 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; }
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; }
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; }
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); }
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; }
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; }
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; }
/* 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; }
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); }