00001
00002
00003
00004
00005
00006
00007
00008 #include "unbunAndRegPhyBunfile.h"
00009 #include "apiHeaderAll.h"
00010 #include "miscServerFunct.h"
00011 #include "objMetaOpr.h"
00012 #include "resource.h"
00013 #include "dataObjOpr.h"
00014 #include "physPath.h"
00015 #include "rcGlobalExtern.h"
00016 #include "reGlobalsExtern.h"
00017
00018 #include "eirods_stacktrace.h"
00019
00020
00021
00022 #include "eirods_resource_backport.h"
00023
00024 int
00025 rsUnbunAndRegPhyBunfile (rsComm_t *rsComm, dataObjInp_t *dataObjInp)
00026 {
00027 int status;
00028 char *rescName;
00029
00030 if ((rescName = getValByKey (&dataObjInp->condInput, DEST_RESC_NAME_KW))
00031 == NULL) {
00032 return USER_NO_RESC_INPUT_ERR;
00033 }
00034 #if 0 // JMC - legacy resource
00035 rescGrpInfo_t *rescGrpInfo = NULL;
00036 status = resolveAndQueResc (rescName, NULL, &rescGrpInfo);
00037 if (status < 0|| NULL == rescGrpInfo) {
00038 rodsLog (LOG_NOTICE,
00039 "rsUnbunAndRegPhyBunfile: resolveAndQueRescerror for %s, status = %d",
00040 rescName, status);
00041 return (status);
00042 }
00043 #endif // JMC - legacy resource
00044
00045 rescInfo_t* rescInfo = new rescInfo_t;
00046 eirods::error err = eirods::get_resc_info( rescName, *rescInfo );
00047 if( !err.ok() ) {
00048 delete rescInfo;
00049 std::stringstream msg;
00050 msg << "failed for [";
00051 msg << rescName;
00052 msg << "]";
00053 eirods::log( PASSMSG( msg.str(), err ) );
00054 return -1;
00055 }
00056 status = _rsUnbunAndRegPhyBunfile( rsComm, dataObjInp, rescInfo );
00057
00058
00059 return (status);
00060 }
00061
00062 int
00063 _rsUnbunAndRegPhyBunfile (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00064 rescInfo_t *rescInfo)
00065 {
00066 int status;
00067 int remoteFlag;
00068 rodsServerHost_t *rodsServerHost;
00069 char *bunFilePath;
00070 char phyBunDir[MAX_NAME_LEN];
00071 int rmBunCopyFlag;
00072 char *dataType = NULL;
00073
00074 char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00075 if( !resc_hier ) {
00076 rodsLog( LOG_NOTICE, "_rsUnbunAndRegPhyBunfile - RESC_HIER_STR_KW is NULL" );
00077 return -1;
00078 }
00079
00080
00081
00082 std::string location;
00083 eirods::error ret = eirods::get_loc_for_hier_string( resc_hier, location );
00084 if( !ret.ok() ) {
00085 eirods::log( PASS( ret ) );
00086 return -1;
00087 }
00088
00089
00090 rodsHostAddr_t addr;
00091 memset (&addr, 0, sizeof (addr));
00092 rstrcpy( addr.hostAddr, location.c_str(), NAME_LEN );
00093 remoteFlag = resolveHost( &addr, &rodsServerHost );
00094 if (remoteFlag == REMOTE_HOST) {
00095 addKeyVal (&dataObjInp->condInput, DEST_RESC_NAME_KW,
00096 rescInfo->rescName);
00097 status = remoteUnbunAndRegPhyBunfile (rsComm, dataObjInp,
00098 rodsServerHost);
00099 return status;
00100 }
00101
00102 if ((bunFilePath = getValByKey (&dataObjInp->condInput, BUN_FILE_PATH_KW))
00103 == NULL) {
00104 rodsLog (LOG_ERROR,
00105 "_rsUnbunAndRegPhyBunfile: No filePath input for %s",
00106 dataObjInp->objPath);
00107 return (SYS_INVALID_FILE_PATH);
00108 }
00109
00110 createPhyBundleDir (rsComm, bunFilePath, phyBunDir);
00111 dataType = getValByKey (&dataObjInp->condInput, DATA_TYPE_KW);
00112 status = unbunPhyBunFile (rsComm, dataObjInp->objPath, rescInfo, bunFilePath, phyBunDir,
00113 dataType, 0, resc_hier );
00114
00115 if (status < 0) {
00116 rodsLog (LOG_ERROR,
00117 "_rsUnbunAndRegPhyBunfile:unbunPhyBunFile err for %s to dir %s.stat=%d",
00118 bunFilePath, phyBunDir, status);
00119 return status;
00120 }
00121
00122 if (getValByKey (&dataObjInp->condInput, RM_BUN_COPY_KW) == NULL) {
00123 rmBunCopyFlag = 0;
00124 } else {
00125 rmBunCopyFlag = 1;
00126 }
00127
00128 status = regUnbunPhySubfiles (rsComm, rescInfo, phyBunDir, rmBunCopyFlag);
00129
00130 if (status == CAT_NO_ROWS_FOUND) {
00131
00132 status = 0;
00133 } else if (status < 0) {
00134 rodsLog (LOG_ERROR,
00135 "_rsUnbunAndRegPhyBunfile: regUnbunPhySubfiles for dir %s. stat = %d",
00136 phyBunDir, status);
00137 }
00138
00139 return status;
00140 }
00141
00142 int
00143 regUnbunPhySubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, char *phyBunDir,
00144 int rmBunCopyFlag)
00145 {
00146 #ifndef USE_BOOST_FS
00147 DIR *dirPtr;
00148 struct dirent *myDirent;
00149 struct stat statbuf;
00150 #endif
00151 char subfilePath[MAX_NAME_LEN];
00152 dataObjInp_t dataObjInp;
00153 dataObjInp_t dataObjUnlinkInp;
00154 int status;
00155 int savedStatus = 0;
00156
00157 dataObjInfo_t *dataObjInfoHead = NULL;
00158 dataObjInfo_t *bunDataObjInfo= NULL;
00159 #ifdef USE_BOOST_FS
00160 path srcDirPath (phyBunDir);
00161 if (!exists(srcDirPath) || !is_directory(srcDirPath)) {
00162 #else
00163 dirPtr = opendir (phyBunDir);
00164 if (dirPtr == NULL) {
00165 #endif
00166 rodsLog (LOG_ERROR,
00167 "regUnbunphySubfiles: opendir error for %s, errno = %d",
00168 phyBunDir, errno);
00169 return (UNIX_FILE_OPENDIR_ERR - errno);
00170 }
00171 bzero (&dataObjInp, sizeof (dataObjInp));
00172 if (rmBunCopyFlag > 0) {
00173 bzero (&dataObjUnlinkInp, sizeof (dataObjUnlinkInp));
00174 addKeyVal (&dataObjUnlinkInp.condInput, IRODS_ADMIN_KW, "");
00175 }
00176
00177 #ifdef USE_BOOST_FS
00178 directory_iterator end_itr;
00179 for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) {
00180 path p = itr->path();
00181 snprintf (subfilePath, MAX_NAME_LEN, "%s",
00182 p.c_str ());
00183 #else
00184 while ((myDirent = readdir (dirPtr)) != NULL) {
00185 if (strcmp (myDirent->d_name, ".") == 0 ||
00186 strcmp (myDirent->d_name, "..") == 0) {
00187 continue;
00188 }
00189 snprintf (subfilePath, MAX_NAME_LEN, "%s/%s",
00190 phyBunDir, myDirent->d_name);
00191 #endif
00192
00193 #ifdef USE_BOOST_FS
00194 #if 0
00195 path p (subfilePath);
00196 #endif
00197 if (!exists(p)) {
00198 #else
00199 status = stat (subfilePath, &statbuf);
00200 if (status != 0) {
00201 closedir (dirPtr);
00202 #endif
00203 rodsLog (LOG_ERROR,
00204 "regUnbunphySubfiles: stat error for %s, errno = %d",
00205 subfilePath, errno);
00206 return (UNIX_FILE_STAT_ERR - errno);
00207 }
00208
00209 #ifdef USE_BOOST_FS
00210 if (!is_regular_file(p)) continue;
00211
00212 path childPath = p.filename();
00213
00214 addKeyVal (&dataObjInp.condInput, QUERY_BY_DATA_ID_KW,
00215 (char *) childPath.c_str ());
00216 #else
00217 if ((statbuf.st_mode & S_IFREG) == 0) continue;
00218
00219
00220 addKeyVal (&dataObjInp.condInput, QUERY_BY_DATA_ID_KW,
00221 myDirent->d_name);
00222 #endif
00223 status = getDataObjInfo (rsComm, &dataObjInp, &dataObjInfoHead,
00224 NULL, 1);
00225 if (status < 0) {
00226 rodsLog (LOG_DEBUG,
00227 "regUnbunphySubfiles: getDataObjInfo error for %s, status = %d",
00228 subfilePath, status);
00229
00230 unlink (subfilePath);
00231 continue;
00232 }
00233 requeDataObjInfoByResc (&dataObjInfoHead, BUNDLE_RESC, 1, 1);
00234 bunDataObjInfo = NULL;
00235 if (strcmp (dataObjInfoHead->rescName, BUNDLE_RESC) != 0) {
00236
00237 rodsLog (LOG_DEBUG,
00238 "regUnbunphySubfiles: No copy in BUNDLE_RESC for %s",
00239 dataObjInfoHead->objPath);
00240
00241 unlink (subfilePath);
00242 continue;
00243 } else {
00244 bunDataObjInfo = dataObjInfoHead;
00245 }
00246 requeDataObjInfoByResc (&dataObjInfoHead, rescInfo->rescName, 1, 1);
00247
00248 if (strcmp (dataObjInfoHead->rescName, rescInfo->rescName) != 0) {
00249
00250 status = regPhySubFile (rsComm, subfilePath, bunDataObjInfo,
00251 rescInfo);
00252 unlink (subfilePath);
00253 if (status < 0) {
00254 rodsLog (LOG_DEBUG,
00255 "regUnbunphySubfiles: regPhySubFile err for %s, status = %d",
00256 bunDataObjInfo->objPath, status);
00257 }
00258 } else {
00259
00260 unlink (subfilePath);
00261 }
00262 if (rmBunCopyFlag > 0) {
00263 rstrcpy (dataObjUnlinkInp.objPath, bunDataObjInfo->objPath,
00264 MAX_NAME_LEN);
00265 status = dataObjUnlinkS (rsComm, &dataObjUnlinkInp, bunDataObjInfo);
00266 if (status < 0) {
00267 rodsLog (LOG_ERROR,
00268 "regUnbunphySubfiles: dataObjUnlinkS err for %s, status = %d",
00269 bunDataObjInfo->objPath, status);
00270 savedStatus = status;
00271 }
00272 }
00273 freeAllDataObjInfo (dataObjInfoHead);
00274
00275 }
00276 clearKeyVal (&dataObjInp.condInput);
00277 #ifndef USE_BOOST_FS
00278 closedir (dirPtr);
00279 #endif
00280 if (status >= 0 && savedStatus < 0) {
00281 return savedStatus;
00282 } else {
00283 return status;
00284 }
00285 }
00286
00287 int
00288 regPhySubFile (rsComm_t *rsComm, char *subfilePath,
00289 dataObjInfo_t *bunDataObjInfo, rescInfo_t *rescInfo)
00290 {
00291 dataObjInfo_t stageDataObjInfo;
00292 dataObjInp_t dataObjInp;
00293 #ifndef USE_BOOST_FS
00294 struct stat statbuf;
00295 #endif
00296 int status;
00297 regReplica_t regReplicaInp;
00298
00299 bzero (&dataObjInp, sizeof (dataObjInp));
00300 bzero (&stageDataObjInfo, sizeof (stageDataObjInfo));
00301 rstrcpy (dataObjInp.objPath, bunDataObjInfo->objPath, MAX_NAME_LEN);
00302 rstrcpy (stageDataObjInfo.objPath, bunDataObjInfo->objPath, MAX_NAME_LEN);
00303 rstrcpy (stageDataObjInfo.rescName, rescInfo->rescName, NAME_LEN);
00304 stageDataObjInfo.rescInfo = new rescInfo_t;
00305 memcpy( stageDataObjInfo.rescInfo, rescInfo, sizeof( rescInfo_t ) );
00306
00307 status = getFilePathName (rsComm, &stageDataObjInfo, &dataObjInp);
00308 if (status < 0) {
00309 rodsLog (LOG_ERROR,
00310 "regPhySubFile: getFilePathName err for %s. status = %d",
00311 dataObjInp.objPath, status);
00312 delete stageDataObjInfo.rescInfo;
00313 return (status);
00314 }
00315
00316 #ifdef USE_BOOST_FS
00317 path p (stageDataObjInfo.filePath);
00318 if (exists (p)) {
00319 #else
00320 status = stat (stageDataObjInfo.filePath, &statbuf);
00321 if (status == 0 || errno != ENOENT) {
00322 #endif
00323 status = resolveDupFilePath (rsComm, &stageDataObjInfo, &dataObjInp);
00324 if (status < 0) {
00325 rodsLog (LOG_ERROR,
00326 "regPhySubFile: resolveDupFilePath err for %s. status = %d",
00327 stageDataObjInfo.filePath, status);
00328 delete stageDataObjInfo.rescInfo;
00329 return (status);
00330 }
00331 }
00332
00333 mkDirForFilePath (rsComm, "/", stageDataObjInfo.filePath, getDefDirMode ());
00334
00335 status = link (subfilePath, stageDataObjInfo.filePath);
00336 if (status < 0) {
00337 rodsLog (LOG_ERROR,
00338 "regPhySubFile: link error %s to %s. errno = %d",
00339 subfilePath, stageDataObjInfo.filePath, errno);
00340 delete stageDataObjInfo.rescInfo;
00341 return (UNIX_FILE_LINK_ERR - errno);
00342 }
00343
00344 bzero (®ReplicaInp, sizeof (regReplicaInp));
00345 regReplicaInp.srcDataObjInfo = bunDataObjInfo;
00346 regReplicaInp.destDataObjInfo = &stageDataObjInfo;
00347 addKeyVal (®ReplicaInp.condInput, SU_CLIENT_USER_KW, "");
00348 addKeyVal (®ReplicaInp.condInput, IRODS_ADMIN_KW, "");
00349
00350 status = rsRegReplica (rsComm, ®ReplicaInp);
00351
00352 clearKeyVal (®ReplicaInp.condInput);
00353 if (status < 0) {
00354 rodsLog (LOG_ERROR,
00355 "regPhySubFile: rsRegReplica error for %s. status = %d",
00356 bunDataObjInfo->objPath, status);
00357 delete stageDataObjInfo.rescInfo;
00358 return status;
00359 }
00360
00361 delete stageDataObjInfo.rescInfo;
00362 return status;
00363 }
00364
00365 int unbunPhyBunFile( rsComm_t *rsComm, char *objPath,
00366 rescInfo_t *rescInfo, char *bunFilePath, char *phyBunDir,
00367 char *dataType, int oprType, const char* resc_hier )
00368 {
00369 int status;
00370 structFileOprInp_t structFileOprInp;
00371
00372
00373
00374 std::string location;
00375 eirods::error ret = eirods::get_loc_for_hier_string( resc_hier, location );
00376 if( !ret.ok() ) {
00377 eirods::log( PASS( ret ) );
00378 return -1;
00379 }
00380
00381
00382 memset (&structFileOprInp, 0, sizeof (structFileOprInp_t));
00383 structFileOprInp.specColl = (specColl_t*)malloc (sizeof (specColl_t));
00384 memset (structFileOprInp.specColl, 0, sizeof (specColl_t));
00385 structFileOprInp.specColl->type = TAR_STRUCT_FILE_T;
00386 snprintf (structFileOprInp.specColl->collection, MAX_NAME_LEN,
00387 "%s.dir", objPath);
00388 rstrcpy (structFileOprInp.specColl->objPath,
00389 objPath, MAX_NAME_LEN);
00390 structFileOprInp.specColl->collClass = STRUCT_FILE_COLL;
00391 rstrcpy (structFileOprInp.specColl->resource, rescInfo->rescName,NAME_LEN);
00392 rstrcpy (structFileOprInp.specColl->phyPath, bunFilePath, MAX_NAME_LEN);
00393 rstrcpy (structFileOprInp.addr.hostAddr, location.c_str(), NAME_LEN );
00394
00395
00396 rstrcpy (structFileOprInp.specColl->cacheDir, phyBunDir, MAX_NAME_LEN);
00397
00398
00399
00400 if( dataType != NULL &&
00401 ( strstr (dataType, GZIP_TAR_DT_STR) != NULL ||
00402 strstr (dataType, BZIP2_TAR_DT_STR) != NULL ||
00403 strstr (dataType, ZIP_DT_STR) != NULL) ) {
00404 addKeyVal (&structFileOprInp.condInput, DATA_TYPE_KW, dataType);
00405 }
00406
00407 if ((oprType & PRESERVE_DIR_CONT) == 0)
00408 rmLinkedFilesInUnixDir (phyBunDir);
00409 structFileOprInp.oprType = oprType;
00410 status = rsStructFileExtract (rsComm, &structFileOprInp);
00411 if (status == SYS_DIR_IN_VAULT_NOT_EMPTY) {
00412
00413 if (chkOrphanDir (rsComm, phyBunDir, rescInfo->rescName) > 0) {
00414
00415 fileRenameInp_t fileRenameInp;
00416 bzero (&fileRenameInp, sizeof (fileRenameInp));
00417 rstrcpy (fileRenameInp.oldFileName, phyBunDir, MAX_NAME_LEN);
00418 status = renameFilePathToNewDir (rsComm, ORPHAN_DIR,
00419 &fileRenameInp, rescInfo, 1);
00420
00421 if (status >= 0) {
00422 rodsLog (LOG_NOTICE,
00423 "unbunPhyBunFile: %s has been moved to ORPHAN_DIR.stat=%d",
00424 phyBunDir, status);
00425 status = rsStructFileExtract (rsComm, &structFileOprInp);
00426 } else {
00427 rodsLog (LOG_ERROR,
00428 "unbunPhyBunFile: renameFilePathToNewDir err for %s.stat=%d",
00429 phyBunDir, status);
00430 status = SYS_DIR_IN_VAULT_NOT_EMPTY;
00431 }
00432 }
00433 }
00434 clearKeyVal (&structFileOprInp.condInput);
00435 if (status < 0) {
00436 rodsLog (LOG_ERROR,
00437 "unbunPhyBunFile: rsStructFileExtract err for %s. status = %d",
00438 objPath, status);
00439 }
00440 free (structFileOprInp.specColl);
00441
00442 return (status);
00443 }
00444
00445 int
00446 remoteUnbunAndRegPhyBunfile (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00447 rodsServerHost_t *rodsServerHost)
00448 {
00449 int status;
00450
00451 if (rodsServerHost == NULL) {
00452 rodsLog (LOG_NOTICE,
00453 "remoteUnbunAndRegPhyBunfile: Invalid rodsServerHost");
00454 return SYS_INVALID_SERVER_HOST;
00455 }
00456
00457 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00458 return status;
00459 }
00460
00461 status = rcUnbunAndRegPhyBunfile (rodsServerHost->conn, dataObjInp);
00462
00463 return status;
00464 }
00465
00466 int
00467 rmLinkedFilesInUnixDir (char *phyBunDir)
00468 {
00469 #ifndef USE_BOOST_FS
00470 DIR *dirPtr;
00471 struct dirent *myDirent;
00472 struct stat statbuf;
00473 #endif
00474 char subfilePath[MAX_NAME_LEN];
00475 int status;
00476 int linkCnt;
00477
00478 #ifdef USE_BOOST_FS
00479 path srcDirPath (phyBunDir);
00480 if (!exists(srcDirPath) || !is_directory(srcDirPath)) return 0;
00481 #else
00482 dirPtr = opendir (phyBunDir);
00483 if (dirPtr == NULL) return 0;
00484 #endif
00485
00486 #ifdef USE_BOOST_FS
00487 directory_iterator end_itr;
00488 for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) {
00489 path p = itr->path();
00490 snprintf (subfilePath, MAX_NAME_LEN, "%s",
00491 p.c_str ());
00492 #else
00493 while ((myDirent = readdir (dirPtr)) != NULL) {
00494 if (strcmp (myDirent->d_name, ".") == 0 ||
00495 strcmp (myDirent->d_name, "..") == 0) {
00496 continue;
00497 }
00498 snprintf (subfilePath, MAX_NAME_LEN, "%s/%s",
00499 phyBunDir, myDirent->d_name);
00500 #endif
00501 #ifdef USE_BOOST_FS
00502 if (!exists (p)) {
00503 continue;
00504 }
00505
00506 if (is_regular_file(p)) {
00507 if ((linkCnt = hard_link_count (p)) >= 2) {
00508 #else
00509 status = stat (subfilePath, &statbuf);
00510
00511 if (status != 0) {
00512 continue;
00513 }
00514
00515 if ((statbuf.st_mode & S_IFREG) != 0) {
00516 if ((linkCnt = statbuf.st_nlink) >= 2) {
00517 #endif
00518
00519 unlink (subfilePath);
00520 } else {
00521 rodsLog (LOG_ERROR,
00522 "rmLinkedFilesInUnixDir: st_nlink of %s is only %d",
00523 subfilePath, linkCnt);
00524 }
00525 } else {
00526 status = rmLinkedFilesInUnixDir (subfilePath);
00527
00528 rmdir (subfilePath);
00529 }
00530 }
00531 #ifndef USE_BOOST_FS
00532 closedir (dirPtr);
00533 #endif
00534 return 0;
00535 }
00536
00537 int
00538 rmUnlinkedFilesInUnixDir (char *phyBunDir)
00539 {
00540 DIR *dirPtr;
00541 struct dirent *myDirent;
00542 struct stat statbuf;
00543 int status;
00544 char subfilePath[MAX_NAME_LEN];
00545 time_t myTime = time (0) - UNLINK_FILE_AGE;
00546
00547 dirPtr = opendir (phyBunDir);
00548 if (dirPtr == NULL) return 0;
00549 while ((myDirent = readdir (dirPtr)) != NULL) {
00550 if (strcmp (myDirent->d_name, ".") == 0 ||
00551 strcmp (myDirent->d_name, "..") == 0) {
00552 continue;
00553 }
00554 snprintf (subfilePath, MAX_NAME_LEN, "%s/%s",
00555 phyBunDir, myDirent->d_name);
00556 status = stat (subfilePath, &statbuf);
00557
00558 if (status != 0) {
00559 continue;
00560 }
00561
00562 if ((statbuf.st_mode & S_IFREG) != 0) {
00563
00564
00565 if (statbuf.st_nlink == 1 && statbuf.st_mtime > myTime)
00566 unlink (subfilePath);
00567 } else {
00568 status = rmUnlinkedFilesInUnixDir (subfilePath);
00569
00570 rmdir (subfilePath);
00571 }
00572 }
00573 closedir (dirPtr);
00574 return 0;
00575 }
00576