00001
00002
00003
00004
00005
00006
00007
00008 #include "apiHeaderAll.h"
00009 #include "objMetaOpr.h"
00010 #include "resource.h"
00011 #include "collection.h"
00012 #include "specColl.h"
00013 #include "dataObjOpr.h"
00014 #include "physPath.h"
00015 #include "miscServerFunct.h"
00016 #include "rcGlobalExtern.h"
00017 #include "reGlobalsExtern.h"
00018 #include "rsApiHandler.h"
00019 #include "eirods_stacktrace.h"
00020
00021
00022
00023 #include "eirods_resource_backport.h"
00024 #include "eirods_resource_redirect.h"
00025
00026
00027 int
00028 rsBulkDataObjPut (rsComm_t *rsComm, bulkOprInp_t *bulkOprInp,
00029 bytesBuf_t *bulkOprInpBBuf)
00030 {
00031 int status;
00032 int remoteFlag;
00033 rodsServerHost_t *rodsServerHost;
00034 specCollCache_t *specCollCache = NULL;
00035 dataObjInp_t dataObjInp;
00036
00037 resolveLinkedPath (rsComm, bulkOprInp->objPath, &specCollCache,
00038 &bulkOprInp->condInput);
00039
00040
00041 initDataObjInpFromBulkOpr (&dataObjInp, bulkOprInp);
00042
00043 remoteFlag = getAndConnRemoteZone (rsComm, &dataObjInp, &rodsServerHost,
00044 REMOTE_CREATE);
00045
00046 if (remoteFlag < 0) {
00047 return (remoteFlag);
00048 } else if (remoteFlag == LOCAL_HOST) {
00049 int local = LOCAL_HOST;
00050 rodsServerHost_t* host = 0;
00051 if( getValByKey( &dataObjInp.condInput, RESC_HIER_STR_KW ) == NULL ) {
00052 std::string hier;
00053 eirods::error ret = eirods::resource_redirect( eirods::EIRODS_CREATE_OPERATION, rsComm,
00054 &dataObjInp, hier, host, local );
00055 if( !ret.ok() ) {
00056 std::stringstream msg;
00057 msg << "failed for [";
00058 msg << dataObjInp.objPath << "]";
00059 eirods::log( PASSMSG( msg.str(), ret ) );
00060 return ret.code();
00061 }
00062
00063
00064
00065
00066 addKeyVal( &bulkOprInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
00067
00068 }
00069
00070 if( LOCAL_HOST == local ) {
00071 status = _rsBulkDataObjPut( rsComm, bulkOprInp, bulkOprInpBBuf );
00072 } else {
00073 status = rcBulkDataObjPut( host->conn, bulkOprInp, bulkOprInpBBuf );
00074
00075 }
00076 } else {
00077 status = rcBulkDataObjPut (rodsServerHost->conn, bulkOprInp,
00078 bulkOprInpBBuf);
00079 }
00080 return status;
00081 }
00082
00083 int
00084 unbunBulkBuf (
00085 rsComm_t* rsComm,
00086 dataObjInp_t* dataObjInp,
00087 rescInfo_t* rescInfo,
00088 bulkOprInp_t *bulkOprInp,
00089 bytesBuf_t *bulkBBuf,
00090 const std::string& baseDir)
00091 {
00092 sqlResult_t *objPath, *offset;
00093 char *tmpObjPath;
00094 char *bufPtr;
00095 int status, i;
00096 genQueryOut_t *attriArray = &bulkOprInp->attriArray;
00097 int intOffset[MAX_NUM_BULK_OPR_FILES];
00098 char phyBunPath[MAX_NAME_LEN];
00099
00100 if (bulkOprInp == NULL) return USER__NULL_INPUT_ERR;
00101
00102 if ((objPath = getSqlResultByInx (attriArray, COL_DATA_NAME)) == NULL) {
00103 rodsLog (LOG_NOTICE,
00104 "unbunBulkBuf: getSqlResultByInx for COL_DATA_NAME failed");
00105 return (UNMATCHED_KEY_OR_INDEX);
00106 }
00107
00108 if ((offset = getSqlResultByInx (attriArray, OFFSET_INX)) == NULL) {
00109 rodsLog (LOG_NOTICE,
00110 "unbunBulkBuf: getSqlResultByInx for OFFSET_INX failed");
00111 return (UNMATCHED_KEY_OR_INDEX);
00112 }
00113 if (attriArray->rowCnt > MAX_NUM_BULK_OPR_FILES) {
00114 rodsLog (LOG_NOTICE,
00115 "unbunBulkBuf: rowCnt %d too large",
00116 attriArray->rowCnt);
00117 return (SYS_REQUESTED_BUF_TOO_LARGE);
00118 }
00119
00120 for (i = 0; i < attriArray->rowCnt; i++) {
00121 intOffset[i] = atoi (&offset->value[offset->len * i]);
00122 }
00123
00124 addKeyVal(&dataObjInp->condInput, DATA_INCLUDED_KW, "");
00125 for (i = 0; i < attriArray->rowCnt; i++) {
00126 int size;
00127 int out_fd;
00128 bytesBuf_t buffer;
00129 tmpObjPath = &objPath->value[objPath->len * i];
00130 if (i == 0) {
00131 bufPtr = (char *)bulkBBuf->buf;
00132 size = intOffset[0];
00133 } else {
00134 bufPtr = (char *)bulkBBuf->buf + intOffset[i - 1];
00135 size = intOffset[i] - intOffset[i - 1];
00136 }
00137 buffer.buf = bufPtr;
00138 buffer.len = size;
00139
00140 std::string collString = tmpObjPath;
00141 std::size_t last_slash = collString.find_last_of('/');
00142 collString.erase(last_slash);
00143
00144 status = rsMkCollR(rsComm, "/", collString.c_str());
00145 if(status < 0) {
00146 std::stringstream msg;
00147 msg << __FUNCTION__ << ": Unable to make collection \"" << collString << "\"";
00148 eirods::log(LOG_ERROR, msg.str());
00149 return status;
00150 }
00151
00152
00153
00154
00155 rstrcpy(dataObjInp->objPath, tmpObjPath, MAX_NAME_LEN);
00156 status = _rsDataObjPut(rsComm, dataObjInp, &buffer, NULL );
00157 if(status < 0) {
00158 std::stringstream msg;
00159 msg << __FUNCTION__ << ": Failed to put data into file \"" << phyBunPath << "\"";
00160 eirods::log(LOG_NOTICE, msg.str());
00161 return status;
00162 }
00163 }
00164 return 0;
00165 }
00166
00167 int
00168 _rsBulkDataObjPut (rsComm_t *rsComm, bulkOprInp_t *bulkOprInp,
00169 bytesBuf_t *bulkOprInpBBuf)
00170 {
00171 int status;
00172 int remoteFlag;
00173 rodsServerHost_t *rodsServerHost;
00174 rescInfo_t *rescInfo;
00175 char *inpRescGrpName;
00176 char phyBunDir[MAX_NAME_LEN];
00177 rescGrpInfo_t *myRescGrpInfo = new rescGrpInfo_t;
00178 myRescGrpInfo->rescInfo = new rescInfo_t;
00179 int flags = 0;
00180 dataObjInp_t dataObjInp;
00181 fileDriverType_t fileType;
00182 rodsObjStat_t *myRodsObjStat = NULL;
00183
00184 inpRescGrpName = getValByKey (&bulkOprInp->condInput, RESC_GROUP_NAME_KW);
00185
00186 status = chkCollForExtAndReg (rsComm, bulkOprInp->objPath, &myRodsObjStat);
00187 if (status < 0 || myRodsObjStat == NULL ) {
00188 delete myRescGrpInfo->rescInfo;
00189 delete myRescGrpInfo;
00190 return status;
00191 }
00192
00193
00194
00195
00196 initDataObjInpFromBulkOpr (&dataObjInp, bulkOprInp);
00197
00198 if (myRodsObjStat->specColl != NULL) {
00199
00200
00201
00202
00203
00204
00205
00206 eirods::resource_ptr resc;
00207 eirods::error err = eirods::get_resc_grp_info( myRodsObjStat->specColl->resource, *myRescGrpInfo );
00208 if( !err.ok() ) {
00209 delete myRescGrpInfo->rescInfo;
00210 delete myRescGrpInfo;
00211
00212 std::stringstream msg;
00213 msg << "failed to get resource info [";
00214 msg << myRodsObjStat->specColl->resource << "]";
00215 eirods::log( PASSMSG( msg.str(), err ) );
00216 freeRodsObjStat (myRodsObjStat);
00217 return err.code();
00218 }
00219
00220 } else {
00221 status = getRescGrpForCreate (rsComm, &dataObjInp, &myRescGrpInfo);
00222 if (status < 0 || myRescGrpInfo == NULL ) {
00223 freeRodsObjStat (myRodsObjStat);
00224 return status;
00225 }
00226
00227
00228 rescInfo = myRescGrpInfo->rescInfo;
00229 }
00230 #if 0 // JMC :: we did this above with the resc hier redirect
00231 remoteFlag = resolveHostByRescInfo (rescInfo, &rodsServerHost);
00232
00233 if (remoteFlag == REMOTE_HOST) {
00234 addKeyVal (&bulkOprInp->condInput, DEST_RESC_NAME_KW,
00235 rescInfo->rescName);
00236 if (myRodsObjStat->specColl == NULL && inpRescGrpName == NULL &&
00237 strlen (myRescGrpInfo->rescGroupName) > 0) {
00238 addKeyVal (&bulkOprInp->condInput, RESC_GROUP_NAME_KW,
00239 myRescGrpInfo->rescGroupName);
00240 }
00241 freeRodsObjStat (myRodsObjStat);
00242 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00243 return status;
00244 }
00245 status = rcBulkDataObjPut (rodsServerHost->conn, bulkOprInp,
00246 bulkOprInpBBuf);
00247 freeAllRescGrpInfo (myRescGrpInfo);
00248 return status;
00249 }
00250 #endif
00251 status = createBunDirForBulkPut(rsComm, &dataObjInp, rescInfo, myRodsObjStat->specColl, phyBunDir);
00252 if(status < 0) {
00253 std::stringstream msg;
00254 msg << __FUNCTION__ << ": Unable to create BunDir";
00255 eirods::log(LOG_ERROR, msg.str());
00256 return status;
00257 }
00258
00259 status = rsMkCollR(rsComm, "/", bulkOprInp->objPath);
00260 if(status < 0) {
00261 std::stringstream msg;
00262 msg << __FUNCTION__ << ": Unable to make collection \"" << bulkOprInp->objPath << "\"";
00263 eirods::log(LOG_ERROR, msg.str());
00264 return status;
00265 }
00266
00267
00268
00269
00270 status = unbunBulkBuf (rsComm, &dataObjInp, rescInfo, bulkOprInp, bulkOprInpBBuf, phyBunDir);
00271 if (status < 0) {
00272 rodsLog (LOG_ERROR,
00273 "_rsBulkDataObjPut: unbunBulkBuf for dir %s. stat = %d",
00274 phyBunDir, status);
00275 return status;
00276 }
00277
00278 if (myRodsObjStat->specColl != NULL) {
00279 freeRodsObjStat (myRodsObjStat);
00280 return status;
00281 } else {
00282 freeRodsObjStat (myRodsObjStat);
00283 }
00284
00285 freeAllRescGrpInfo (myRescGrpInfo);
00286
00287 return status;
00288 }
00289
00290 int
00291 createBunDirForBulkPut (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00292 rescInfo_t *rescInfo, specColl_t *specColl, char *phyBunDir)
00293 {
00294 dataObjInfo_t dataObjInfo;
00295 #ifndef USE_BOOST_FS
00296 struct stat statbuf;
00297 #endif
00298 int status;
00299
00300 if (dataObjInp == NULL || rescInfo == NULL || phyBunDir == NULL)
00301 return USER__NULL_INPUT_ERR;
00302
00303 if (specColl != NULL) {
00304 status = getMountedSubPhyPath (specColl->collection,
00305 specColl->phyPath, dataObjInp->objPath, phyBunDir);
00306 if (status >= 0) {
00307 mkdirR ("/", phyBunDir, getDefDirMode ());
00308 }
00309 return status;
00310 }
00311 bzero (&dataObjInfo, sizeof (dataObjInfo));
00312 rstrcpy (dataObjInfo.objPath, dataObjInp->objPath, MAX_NAME_LEN);
00313 rstrcpy (dataObjInfo.rescName, rescInfo->rescName, NAME_LEN);
00314
00315 char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00316 if( resc_hier ) {
00317 rstrcpy (dataObjInfo.rescHier, resc_hier, MAX_NAME_LEN );
00318 } else {
00319 rstrcpy (dataObjInfo.rescHier, rescInfo->rescName, NAME_LEN);
00320 }
00321
00322 dataObjInfo.rescInfo = new rescInfo_t;
00323 memcpy( dataObjInfo.rescInfo, rescInfo, sizeof( rescInfo_t ) );
00324
00325 status = getFilePathName (rsComm, &dataObjInfo, dataObjInp);
00326 if (status < 0) {
00327 rodsLog (LOG_ERROR,
00328 "createBunDirForBulkPut: getFilePathName err for %s. status = %d",
00329 dataObjInp->objPath, status);
00330 return (status);
00331 }
00332 do {
00333 snprintf (phyBunDir, MAX_NAME_LEN, "%s/%s.%d", dataObjInfo.filePath,
00334 TMP_PHY_BUN_DIR, (int) random ());
00335 #ifdef USE_BOOST_FS
00336 path p (phyBunDir);
00337 if (exists (p)) status = 0;
00338 else status = -1;
00339 #else
00340 status = stat (phyBunDir, &statbuf);
00341 #endif
00342 } while (status == 0);
00343
00344 mkdirR ("/", phyBunDir, getDefDirMode ());
00345
00346 return 0;
00347 }
00348
00349 int
00350 initDataObjInpFromBulkOpr (dataObjInp_t *dataObjInp, bulkOprInp_t *bulkOprInp)
00351 {
00352 if (dataObjInp == NULL || bulkOprInp == NULL)
00353 return USER__NULL_INPUT_ERR;
00354
00355 bzero (dataObjInp, sizeof (dataObjInp_t));
00356 rstrcpy (dataObjInp->objPath, bulkOprInp->objPath, MAX_NAME_LEN);
00357 dataObjInp->condInput = bulkOprInp->condInput;
00358
00359 return (0);
00360 }
00361
00362 int
00363 bulkRegUnbunSubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, const std::string& rescHier,
00364 char *rescGroupName, char *collection, char *phyBunDir, int flags,
00365 genQueryOut_t *attriArray)
00366 {
00367 genQueryOut_t bulkDataObjRegInp;
00368 renamedPhyFiles_t renamedPhyFiles;
00369 int status = 0;
00370
00371 bzero (&renamedPhyFiles, sizeof (renamedPhyFiles));
00372 initBulkDataObjRegInp (&bulkDataObjRegInp);
00373
00374 if (attriArray != NULL) attriArray->continueInx = 0;
00375
00376 status = _bulkRegUnbunSubfiles (rsComm, rescInfo, rescHier, rescGroupName, collection,
00377 phyBunDir, flags, &bulkDataObjRegInp, &renamedPhyFiles, attriArray);
00378
00379 if (bulkDataObjRegInp.rowCnt > 0) {
00380 int status1;
00381 genQueryOut_t *bulkDataObjRegOut = NULL;
00382 status1 = rsBulkDataObjReg (rsComm, &bulkDataObjRegInp,
00383 &bulkDataObjRegOut);
00384 if (status1 < 0) {
00385 status = status1;
00386 rodsLog (LOG_ERROR,
00387 "regUnbunSubfiles: rsBulkDataObjReg error for %s. stat = %d",
00388 collection, status1);
00389 cleanupBulkRegFiles (rsComm, &bulkDataObjRegInp);
00390 }
00391 postProcRenamedPhyFiles (&renamedPhyFiles, status);
00392 postProcBulkPut (rsComm, &bulkDataObjRegInp, bulkDataObjRegOut);
00393 freeGenQueryOut (&bulkDataObjRegOut);
00394 }
00395 clearGenQueryOut (&bulkDataObjRegInp);
00396 return status;
00397 }
00398
00399 int
00400 _bulkRegUnbunSubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, const std::string& rescHier,
00401 char *rescGroupName, char *collection, char *phyBunDir, int flags,
00402 genQueryOut_t *bulkDataObjRegInp, renamedPhyFiles_t *renamedPhyFiles,
00403 genQueryOut_t *attriArray)
00404 {
00405 #ifndef USE_BOOST_FS
00406 DIR *dirPtr;
00407 struct dirent *myDirent;
00408 struct stat statbuf;
00409 #endif
00410 char subfilePath[MAX_NAME_LEN];
00411 char subObjPath[MAX_NAME_LEN];
00412 dataObjInp_t dataObjInp;
00413 int status;
00414 int savedStatus = 0;
00415 int st_mode;
00416 rodsLong_t st_size;
00417
00418 #ifdef USE_BOOST_FS
00419 path srcDirPath (phyBunDir);
00420 if (!exists(srcDirPath) || !is_directory(srcDirPath)) {
00421 #else
00422 dirPtr = opendir (phyBunDir);
00423 if (dirPtr == NULL) {
00424 #endif
00425 rodsLog (LOG_ERROR,
00426 "regUnbunphySubfiles: opendir error for %s, errno = %d",
00427 phyBunDir, errno);
00428 return (UNIX_FILE_OPENDIR_ERR - errno);
00429 }
00430 bzero (&dataObjInp, sizeof (dataObjInp));
00431 #ifdef USE_BOOST_FS
00432 directory_iterator end_itr;
00433 for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) {
00434 path p = itr->path();
00435 snprintf (subfilePath, MAX_NAME_LEN, "%s",
00436 p.c_str ());
00437 #else
00438 while ((myDirent = readdir (dirPtr)) != NULL) {
00439 if (strcmp (myDirent->d_name, ".") == 0 ||
00440 strcmp (myDirent->d_name, "..") == 0) {
00441 continue;
00442 }
00443 snprintf (subfilePath, MAX_NAME_LEN, "%s/%s",
00444 phyBunDir, myDirent->d_name);
00445 #endif
00446
00447 #ifdef USE_BOOST_FS
00448 if (!exists (p)) {
00449 #else
00450 status = stat (subfilePath, &statbuf);
00451
00452 if (status != 0) {
00453 #endif
00454 rodsLog (LOG_ERROR,
00455 "regUnbunphySubfiles: stat error for %s, errno = %d",
00456 subfilePath, errno);
00457 savedStatus = UNIX_FILE_STAT_ERR - errno;
00458 unlink (subfilePath);
00459 continue;
00460 }
00461
00462 #ifdef USE_BOOST_FS
00463 path childPath = p.filename();
00464 snprintf (subObjPath, MAX_NAME_LEN, "%s/%s",
00465 collection, childPath.c_str());
00466 if (is_directory (p)) {
00467 #else
00468 snprintf (subObjPath, MAX_NAME_LEN, "%s/%s",
00469 collection, myDirent->d_name);
00470 if ((statbuf.st_mode & S_IFDIR) != 0) {
00471 #endif
00472 status = rsMkCollR (rsComm, "/", subObjPath);
00473 if (status < 0) {
00474 rodsLog (LOG_ERROR,
00475 "regUnbunSubfiles: rsMkCollR of %s error. status = %d",
00476 subObjPath, status);
00477 savedStatus = status;
00478 continue;
00479 }
00480 status = _bulkRegUnbunSubfiles (rsComm, rescInfo, rescHier, rescGroupName,
00481 subObjPath, subfilePath, flags, bulkDataObjRegInp,
00482 renamedPhyFiles, attriArray);
00483 if (status < 0) {
00484 rodsLog (LOG_ERROR,
00485 "regUnbunSubfiles: regUnbunSubfiles of %s error. status=%d",
00486 subObjPath, status);
00487 savedStatus = status;
00488 continue;
00489 }
00490 #ifdef USE_BOOST_FS
00491 } else if (is_regular_file (p)) {
00492 st_mode = getPathStMode (p);
00493 st_size = file_size (p);
00494 #else
00495 } else if ((statbuf.st_mode & S_IFREG) != 0) {
00496 st_mode = statbuf.st_mode;
00497 st_size = statbuf.st_size;
00498 #endif
00499 status = bulkProcAndRegSubfile (rsComm, rescInfo, rescHier, rescGroupName,
00500 subObjPath, subfilePath, st_size,
00501 st_mode & 0777, flags, bulkDataObjRegInp,
00502 renamedPhyFiles, attriArray);
00503 unlink (subfilePath);
00504 if (status < 0) {
00505 rodsLog (LOG_ERROR,
00506 "regUnbunSubfiles:bulkProcAndRegSubfile of %s err.stat=%d",
00507 subObjPath, status);
00508 savedStatus = status;
00509 continue;
00510 }
00511 }
00512 }
00513 #ifndef USE_BOOST_FS
00514 closedir (dirPtr);
00515 #endif
00516 rmdir (phyBunDir);
00517 return savedStatus;
00518 }
00519
00520 int
00521 bulkProcAndRegSubfile (rsComm_t *rsComm, rescInfo_t *rescInfo, const std::string& rescHier,
00522 char *rescGroupName, char *subObjPath, char *subfilePath, rodsLong_t dataSize,
00523 int dataMode, int flags, genQueryOut_t *bulkDataObjRegInp,
00524 renamedPhyFiles_t *renamedPhyFiles, genQueryOut_t *attriArray)
00525 {
00526 dataObjInfo_t dataObjInfo;
00527 dataObjInp_t dataObjInp;
00528 #ifndef USE_BOOST_FS
00529 struct stat statbuf;
00530 #endif
00531 int status;
00532 int modFlag = 0;
00533 char *myChksum = NULL;
00534 int myDataMode = dataMode;
00535
00536 bzero (&dataObjInp, sizeof (dataObjInp));
00537 bzero (&dataObjInfo, sizeof (dataObjInfo));
00538 rstrcpy (dataObjInp.objPath, subObjPath, MAX_NAME_LEN);
00539 rstrcpy (dataObjInfo.objPath, subObjPath, MAX_NAME_LEN);
00540 rstrcpy (dataObjInfo.rescName, rescInfo->rescName, NAME_LEN);
00541 rstrcpy (dataObjInfo.rescHier, rescHier.c_str(), MAX_NAME_LEN);
00542 rstrcpy (dataObjInfo.dataType, "generic", NAME_LEN);
00543 dataObjInfo.rescInfo = new rescInfo_t;
00544 memcpy( dataObjInfo.rescInfo, rescInfo, sizeof( rescInfo_t ) );
00545 dataObjInfo.dataSize = dataSize;
00546
00547 status = getFilePathName (rsComm, &dataObjInfo, &dataObjInp);
00548 if (status < 0) {
00549 rodsLog (LOG_ERROR,
00550 "regSubFile: getFilePathName err for %s. status = %d",
00551 dataObjInp.objPath, status);
00552 return (status);
00553 }
00554
00555 #ifdef USE_BOOST_FS
00556 path p (dataObjInfo.filePath);
00557 if (exists (p)) {
00558 if (is_directory (p)) {
00559 #else
00560 status = stat (dataObjInfo.filePath, &statbuf);
00561 if (status == 0 || errno != ENOENT) {
00562 if ((statbuf.st_mode & S_IFDIR) != 0) {
00563 #endif
00564 return SYS_PATH_IS_NOT_A_FILE;
00565 }
00566 if (chkOrphanFile (rsComm, dataObjInfo.filePath, rescInfo->rescName,
00567 &dataObjInfo) <= 0) {
00568
00569 if ((flags & FORCE_FLAG_FLAG) != 0 && dataObjInfo.dataId > 0 &&
00570 strcmp (dataObjInfo.objPath, subObjPath) == 0) {
00571
00572 modFlag = 1;
00573 } else {
00574 status = SYS_COPY_ALREADY_IN_RESC;
00575 rodsLog (LOG_ERROR,
00576 "bulkProcAndRegSubfile: phypath %s is already in use. status = %d",
00577 dataObjInfo.filePath, status);
00578 return (status);
00579 }
00580 }
00581
00582 fileRenameInp_t fileRenameInp;
00583 bzero (&fileRenameInp, sizeof (fileRenameInp));
00584 rstrcpy (fileRenameInp.oldFileName, dataObjInfo.filePath, MAX_NAME_LEN);
00585 rstrcpy (fileRenameInp.rescHier, dataObjInfo.rescHier, MAX_NAME_LEN);
00586 status = renameFilePathToNewDir (rsComm, ORPHAN_DIR,
00587 &fileRenameInp, rescInfo, 1);
00588 if (status < 0) {
00589 rodsLog (LOG_ERROR,
00590 "bulkProcAndRegSubfile: renameFilePathToNewDir err for %s. status = %d",
00591 fileRenameInp.oldFileName, status);
00592 return (status);
00593 }
00594 if (modFlag > 0) {
00595 status = addRenamedPhyFile (subObjPath, fileRenameInp.oldFileName,
00596 fileRenameInp.newFileName, renamedPhyFiles);
00597 if (status < 0) return status;
00598 }
00599 } else {
00600
00601 mkDirForFilePath (rsComm, "/", dataObjInfo.filePath, getDefDirMode ());
00602 }
00603
00604 #ifndef windows_platform
00605 status = link (subfilePath, dataObjInfo.filePath);
00606 if (status < 0) {
00607 rodsLog (LOG_ERROR,
00608 "bulkProcAndRegSubfile: link error %s to %s. errno = %d",
00609 subfilePath, dataObjInfo.filePath, errno);
00610 return (UNIX_FILE_LINK_ERR - errno);
00611 }
00612 #endif
00613
00614
00615 if (attriArray != NULL) {
00616
00617 status =getAttriInAttriArray (subObjPath, attriArray, &myDataMode,
00618 &myChksum);
00619 if (status < 0) {
00620 rodsLog (LOG_NOTICE,
00621 "bulkProcAndRegSubfile: matchObjPath error for %s, stat = %d",
00622 subObjPath, status);
00623 } else {
00624 if ((flags & VERIFY_CHKSUM_FLAG) != 0 && myChksum != NULL) {
00625 char chksumStr[NAME_LEN];
00626
00627 status = chksumLocFile (dataObjInfo.filePath, chksumStr);
00628 if (status < 0) {
00629 rodsLog (LOG_ERROR,
00630 "bulkProcAndRegSubfile: chksumLocFile error for %s ",
00631 dataObjInfo.filePath);
00632 return (status);
00633 }
00634 if (strcmp (myChksum, chksumStr) != 0) {
00635 rodsLog (LOG_ERROR,
00636 "bulkProcAndRegSubfile: chksum of %s %s != input %s",
00637 dataObjInfo.filePath, chksumStr, myChksum);
00638 return (USER_CHKSUM_MISMATCH);
00639 }
00640 }
00641 }
00642 }
00643
00644 status = bulkRegSubfile (rsComm, rescInfo->rescName, rescHier, rescGroupName,
00645 subObjPath, dataObjInfo.filePath, dataSize, myDataMode, modFlag,
00646 dataObjInfo.replNum, myChksum, bulkDataObjRegInp, renamedPhyFiles);
00647
00648 return status;
00649 }
00650
00651 int
00652 bulkRegSubfile (rsComm_t *rsComm, char *rescName, const std::string& rescHier, char *rescGroupName,
00653 char *subObjPath, char *subfilePath, rodsLong_t dataSize, int dataMode,
00654 int modFlag, int replNum, char *chksum, genQueryOut_t *bulkDataObjRegInp,
00655 renamedPhyFiles_t *renamedPhyFiles)
00656 {
00657 int status;
00658
00659
00660 status = fillBulkDataObjRegInp (rescName, rescHier, rescGroupName, subObjPath,
00661 subfilePath, "generic", dataSize, dataMode, modFlag,
00662 replNum, chksum, bulkDataObjRegInp);
00663 if (status < 0) {
00664 rodsLog (LOG_ERROR,
00665 "bulkRegSubfile: fillBulkDataObjRegInp error for %s. status = %d",
00666 subfilePath, status);
00667 return status;
00668 }
00669
00670 if (bulkDataObjRegInp->rowCnt >= MAX_NUM_BULK_OPR_FILES) {
00671 genQueryOut_t *bulkDataObjRegOut = NULL;
00672 status = rsBulkDataObjReg (rsComm, bulkDataObjRegInp,
00673 &bulkDataObjRegOut);
00674 if (status < 0) {
00675 rodsLog (LOG_ERROR,
00676 "bulkRegSubfile: rsBulkDataObjReg error for %s. status = %d",
00677 subfilePath, status);
00678 cleanupBulkRegFiles (rsComm, bulkDataObjRegInp);
00679 }
00680 postProcRenamedPhyFiles (renamedPhyFiles, status);
00681 postProcBulkPut (rsComm, bulkDataObjRegInp, bulkDataObjRegOut);
00682 freeGenQueryOut (&bulkDataObjRegOut);
00683 bulkDataObjRegInp->rowCnt = 0;
00684 }
00685 return status;
00686 }
00687
00688 int
00689 addRenamedPhyFile (char *subObjPath, char *oldFileName, char *newFileName,
00690 renamedPhyFiles_t *renamedPhyFiles)
00691 {
00692 if (subObjPath == NULL || oldFileName == NULL || newFileName == NULL ||
00693 renamedPhyFiles == NULL) return USER__NULL_INPUT_ERR;
00694
00695 if (renamedPhyFiles->count >= MAX_NUM_BULK_OPR_FILES) {
00696 rodsLog (LOG_ERROR,
00697 "addRenamedPhyFile: count >= %d for %s", MAX_NUM_BULK_OPR_FILES,
00698 subObjPath);
00699 return (SYS_RENAME_STRUCT_COUNT_EXCEEDED);
00700 }
00701 rstrcpy (&renamedPhyFiles->objPath[renamedPhyFiles->count][0],
00702 subObjPath, MAX_NAME_LEN);
00703 rstrcpy (&renamedPhyFiles->origFilePath[renamedPhyFiles->count][0],
00704 oldFileName, MAX_NAME_LEN);
00705 rstrcpy (&renamedPhyFiles->newFilePath[renamedPhyFiles->count][0],
00706 newFileName, MAX_NAME_LEN);
00707 renamedPhyFiles->count++;
00708 return 0;
00709 }
00710
00711 int
00712 postProcRenamedPhyFiles (renamedPhyFiles_t *renamedPhyFiles, int regStatus)
00713 {
00714 int i;
00715 int status = 0;
00716 int savedStatus = 0;
00717
00718 if (renamedPhyFiles == NULL) return USER__NULL_INPUT_ERR;
00719
00720 if (regStatus >= 0) {
00721 for (i = 0; i < renamedPhyFiles->count; i++) {
00722 unlink (&renamedPhyFiles->newFilePath[i][0]);
00723 }
00724 } else {
00725
00726 for (i = 0; i < renamedPhyFiles->count; i++) {
00727 status = rename (&renamedPhyFiles->newFilePath[i][0],
00728 &renamedPhyFiles->origFilePath[i][0]);
00729 savedStatus = UNIX_FILE_RENAME_ERR - errno;
00730 rodsLog (LOG_ERROR,
00731 "postProcRenamedPhyFiles: rename error from %s to %s, status=%d",
00732 &renamedPhyFiles->newFilePath[i][0],
00733 &renamedPhyFiles->origFilePath[i][0], savedStatus);
00734 }
00735 }
00736 bzero (renamedPhyFiles, sizeof (renamedPhyFiles_t));
00737
00738 return savedStatus;
00739 }
00740
00741 int
00742 cleanupBulkRegFiles (rsComm_t *rsComm, genQueryOut_t *bulkDataObjRegInp)
00743 {
00744 sqlResult_t *filePath, *rescName;
00745 char *tmpFilePath, *tmpRescName;
00746 int i;
00747
00748 if (bulkDataObjRegInp == NULL) return USER__NULL_INPUT_ERR;
00749
00750 if ((filePath =
00751 getSqlResultByInx (bulkDataObjRegInp, COL_D_DATA_PATH)) == NULL) {
00752 rodsLog (LOG_NOTICE,
00753 "cleanupBulkRegFiles: getSqlResultByInx for COL_D_DATA_PATH failed");
00754 return (UNMATCHED_KEY_OR_INDEX);
00755 }
00756 if ((rescName =
00757 getSqlResultByInx (bulkDataObjRegInp, COL_D_RESC_NAME)) == NULL) {
00758 rodsLog (LOG_NOTICE,
00759 "rsBulkDataObjReg: getSqlResultByInx for COL_D_RESC_NAME failed");
00760 return (UNMATCHED_KEY_OR_INDEX);
00761 }
00762
00763 for (i = 0;i < bulkDataObjRegInp->rowCnt; i++) {
00764 tmpFilePath = &filePath->value[filePath->len * i];
00765 tmpRescName = &rescName->value[rescName->len * i];
00766
00767 if (chkOrphanFile (rsComm, tmpFilePath, tmpRescName, NULL) > 0) {
00768 unlink (tmpFilePath);
00769 }
00770 }
00771
00772 return 0;
00773 }
00774
00775 int
00776 postProcBulkPut (rsComm_t *rsComm, genQueryOut_t *bulkDataObjRegInp,
00777 genQueryOut_t *bulkDataObjRegOut)
00778 {
00779 dataObjInfo_t dataObjInfo;
00780 sqlResult_t *objPath, *dataType, *dataSize, *rescName, *filePath,
00781 *dataMode, *oprType, *rescGroupName, *replNum, *chksum;
00782 char *tmpObjPath, *tmpDataType, *tmpDataSize, *tmpFilePath,
00783 *tmpDataMode, *tmpOprType, *tmpReplNum, *tmpChksum;
00784 sqlResult_t *objId;
00785 char *tmpObjId;
00786 int status, i;
00787 dataObjInp_t dataObjInp;
00788 ruleExecInfo_t rei;
00789 int savedStatus = 0;
00790
00791 if (bulkDataObjRegInp == NULL || bulkDataObjRegOut == NULL)
00792 return USER__NULL_INPUT_ERR;
00793
00794 initReiWithDataObjInp (&rei, rsComm, NULL);
00795 status = applyRule ("acBulkPutPostProcPolicy", NULL, &rei, NO_SAVE_REI);
00796 if (status < 0) {
00797 rodsLog (LOG_ERROR,
00798 "postProcBulkPut: acBulkPutPostProcPolicy error status = %d", status);
00799 return status;
00800 }
00801
00802 if (rei.status == POLICY_OFF) return 0;
00803
00804 if ((objPath =
00805 getSqlResultByInx (bulkDataObjRegInp, COL_DATA_NAME)) == NULL) {
00806 rodsLog (LOG_ERROR,
00807 "postProcBulkPut: getSqlResultByInx for COL_DATA_NAME failed");
00808 return (UNMATCHED_KEY_OR_INDEX);
00809 }
00810
00811 if ((dataType =
00812 getSqlResultByInx (bulkDataObjRegInp, COL_DATA_TYPE_NAME)) == NULL) {
00813 rodsLog (LOG_ERROR,
00814 "postProcBulkPut: getSqlResultByInx for COL_DATA_TYPE_NAME failed");
00815 return (UNMATCHED_KEY_OR_INDEX);
00816 }
00817 if ((dataSize =
00818 getSqlResultByInx (bulkDataObjRegInp, COL_DATA_SIZE)) == NULL) {
00819 rodsLog (LOG_ERROR,
00820 "postProcBulkPut: getSqlResultByInx for COL_DATA_SIZE failed");
00821 return (UNMATCHED_KEY_OR_INDEX);
00822 }
00823 if ((rescName =
00824 getSqlResultByInx (bulkDataObjRegInp, COL_D_RESC_NAME)) == NULL) {
00825 rodsLog (LOG_ERROR,
00826 "postProcBulkPut: getSqlResultByInx for COL_D_RESC_NAME failed");
00827 return (UNMATCHED_KEY_OR_INDEX);
00828 }
00829
00830 if ((filePath =
00831 getSqlResultByInx (bulkDataObjRegInp, COL_D_DATA_PATH)) == NULL) {
00832 rodsLog (LOG_ERROR,
00833 "postProcBulkPut: getSqlResultByInx for COL_D_DATA_PATH failed");
00834 return (UNMATCHED_KEY_OR_INDEX);
00835 }
00836
00837 if ((dataMode =
00838 getSqlResultByInx (bulkDataObjRegInp, COL_DATA_MODE)) == NULL) {
00839 rodsLog (LOG_ERROR,
00840 "postProcBulkPut: getSqlResultByInx for COL_DATA_MODE failed");
00841 return (UNMATCHED_KEY_OR_INDEX);
00842 }
00843
00844 if ((oprType =
00845 getSqlResultByInx (bulkDataObjRegInp, OPR_TYPE_INX)) == NULL) {
00846 rodsLog (LOG_ERROR,
00847 "postProcBulkPut: getSqlResultByInx for OPR_TYPE_INX failed");
00848 return (UNMATCHED_KEY_OR_INDEX);
00849 }
00850
00851 if ((rescGroupName =
00852 getSqlResultByInx (bulkDataObjRegInp, COL_RESC_GROUP_NAME)) == NULL) {
00853 rodsLog (LOG_ERROR,
00854 "postProcBulkPut: getSqlResultByInx for COL_RESC_GROUP_NAME failed");
00855 return (UNMATCHED_KEY_OR_INDEX);
00856 }
00857
00858 if ((replNum =
00859 getSqlResultByInx (bulkDataObjRegInp, COL_DATA_REPL_NUM)) == NULL) {
00860 rodsLog (LOG_ERROR,
00861 "postProcBulkPut: getSqlResultByInx for COL_DATA_REPL_NUM failed");
00862 return (UNMATCHED_KEY_OR_INDEX);
00863 }
00864 chksum = getSqlResultByInx (bulkDataObjRegInp, COL_D_DATA_CHECKSUM);
00865
00866
00867 if ((objId =
00868 getSqlResultByInx (bulkDataObjRegOut, COL_D_DATA_ID)) == NULL) {
00869 rodsLog (LOG_ERROR,
00870 "postProcBulkPut: getSqlResultByInx for COL_D_DATA_ID failed");
00871 return (UNMATCHED_KEY_OR_INDEX);
00872 }
00873
00874
00875 bzero (&dataObjInfo, sizeof (dataObjInfo_t));
00876 rstrcpy (dataObjInfo.rescName, rescName->value, NAME_LEN);
00877 rstrcpy (dataObjInfo.rescGroupName, rescGroupName->value, NAME_LEN);
00878 dataObjInfo.replStatus = NEWLY_CREATED_COPY;
00879
00880
00881
00882
00883
00884
00885
00886 dataObjInfo.rescInfo = new rescInfo_t;
00887 eirods::error err = eirods::get_resc_info( rescName->value, *dataObjInfo.rescInfo );
00888 if( !err.ok() ) {
00889 std::stringstream msg;
00890 msg << "failed to get resource info [";
00891 msg << rescName->value << "]";
00892 eirods::log( PASSMSG( msg.str(), err ) );
00893 return err.code();
00894 }
00895
00896 bzero (&dataObjInp, sizeof (dataObjInp_t));
00897 dataObjInp.openFlags = O_WRONLY;
00898
00899 for (i = 0;i < bulkDataObjRegInp->rowCnt; i++) {
00900 dataObjInfo_t *tmpDataObjInfo;
00901
00902 tmpDataObjInfo = (dataObjInfo_t *)malloc (sizeof (dataObjInfo_t));
00903 if (tmpDataObjInfo == NULL) return SYS_MALLOC_ERR;
00904
00905 *tmpDataObjInfo = dataObjInfo;
00906
00907 tmpObjPath = &objPath->value[objPath->len * i];
00908 tmpDataType = &dataType->value[dataType->len * i];
00909 tmpDataSize = &dataSize->value[dataSize->len * i];
00910 tmpFilePath = &filePath->value[filePath->len * i];
00911 tmpDataMode = &dataMode->value[dataMode->len * i];
00912 tmpOprType = &oprType->value[oprType->len * i];
00913 tmpReplNum = &replNum->value[replNum->len * i];
00914 tmpObjId = &objId->value[objId->len * i];
00915
00916 rstrcpy (tmpDataObjInfo->objPath, tmpObjPath, MAX_NAME_LEN);
00917 rstrcpy (dataObjInp.objPath, tmpObjPath, MAX_NAME_LEN);
00918 rstrcpy (tmpDataObjInfo->dataType, tmpDataType, NAME_LEN);
00919 tmpDataObjInfo->dataSize = strtoll (tmpDataSize, 0, 0);
00920 #if 0
00921 rstrcpy (tmpDataObjInfo->rescName, tmpRescName, NAME_LEN);
00922 rstrcpy (tmpDataObjInfo->rescGroupName, tmpRescGroupName, NAME_LEN);
00923 #endif
00924 rstrcpy (tmpDataObjInfo->filePath, tmpFilePath, MAX_NAME_LEN);
00925 rstrcpy (tmpDataObjInfo->dataMode, tmpDataMode, NAME_LEN);
00926 tmpDataObjInfo->replNum = atoi (tmpReplNum);
00927 if (chksum != NULL) {
00928 tmpChksum = &chksum->value[chksum->len * i];
00929 if (strlen (tmpChksum) > 0) {
00930 rstrcpy (tmpDataObjInfo->chksum, tmpChksum, NAME_LEN);
00931 }
00932 }
00933 initReiWithDataObjInp (&rei, rsComm, &dataObjInp);
00934 rei.doi = tmpDataObjInfo;
00935
00936 status = applyRule ("acPostProcForPut", NULL, &rei, NO_SAVE_REI);
00937 if (status < 0) savedStatus = status;
00938
00939 freeAllDataObjInfo (rei.doi);
00940 }
00941 return savedStatus;
00942 }
00943