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