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