00001
00002
00003
00004
00005
00006 #include "apiHeaderAll.h"
00007 #include "rsApiHandler.h"
00008 #include "objMetaOpr.h"
00009 #include "dataObjOpr.h"
00010
00011
00012 typedef struct __replicas_check_status_
00013 {
00014 int registered;
00015 char checksum[200];
00016 int chksum_status;
00017 int repl_num;
00018 char resc[200];
00019 }ReplicaCheckStatusStruct;
00020
00021 static int repl_storage_error;
00022
00023 static int process_single_obj(rsComm_t *conn, char *parColl, char *fileName,
00024 int required_num_replicas, char *grpRescForReplication, char *emailToNotify);
00025 static int get_resource_path(rsComm_t *conn, char *rescName, char *rescPath);
00026
00027 void UnixSendEmail(char *toAddr, char *subjectLine, char *msgBody)
00028 {
00029 char fileName[1024];
00030 char mailStr[100];
00031 FILE *fd;
00032 int t;
00033 char *t1, *t2;
00034
00035 if((toAddr==NULL) || (strlen(toAddr) == 0))
00036 return;
00037
00038 srand(time(0));
00039 t = rand()%281;
00040 sprintf(fileName, "/tmp/rodstmpmail%d.txt", t);
00041
00042 fd = fopen(fileName, "w");
00043 if(fd == NULL)
00044 return;
00045
00046 #ifdef solaris_platform
00047 if((subjectLine != NULL) && (strlen(subjectLine) > 0))
00048 {
00049 fprintf(fd,"Subject:%s\n\n", subjectLine);
00050 }
00051 #endif
00052
00053 t1 = msgBody;
00054 while (t1 != NULL) {
00055 if ((t2 = strstr(t1,"\\n")) != NULL)
00056 *t2 = '\0';
00057 fprintf(fd,"%s\n",t1);
00058 if (t2 != NULL) {
00059 *t2 = '\\';
00060 t1 = t2+2;
00061 }
00062 else
00063 t1 = NULL;
00064 }
00065 fclose(fd);
00066
00067 #ifdef solaris_platform
00068 sprintf(mailStr,"cat %s| mail %s",fileName,toAddr);
00069 #else
00070 if((subjectLine != NULL) && (strlen(subjectLine) > 0)) {
00071 if (checkStringForSystem(fileName)) return;
00072 if (checkStringForSystem(subjectLine)) return;
00073 if (checkStringForSystem(toAddr)) return;
00074 sprintf(mailStr,"cat %s| mail -s '%s' %s",fileName,
00075 subjectLine, toAddr);
00076 }
00077 else {
00078 if (checkStringForSystem(fileName)) return;
00079 if (checkStringForSystem(toAddr)) return;
00080 sprintf(mailStr,"cat %s| mail %s",fileName, toAddr);
00081 }
00082 #endif
00083 system(mailStr);
00084 sprintf(mailStr,"rm %s",fileName);
00085 system(mailStr);
00086 }
00087
00088 static int _myAutoReplicateService(rsComm_t *conn, char *topColl, int recursiveFlag,
00089 int requiredNumReplicas, char *rescGroup,
00090 char *emailToNotify)
00091 {
00092
00093 genQueryInp_t genQueryInp;
00094 int i;
00095 genQueryOut_t *genQueryOut = NULL;
00096 char query_str[2048];
00097 sqlResult_t *collNameStruct, *dataNameStruct;
00098 char *collName, *dataName;
00099 int t;
00100 int loop_stop;
00101
00102 rodsLog(LOG_NOTICE,"_myAutoReplicateService(): topColl=%s, recursiveFlag=%d, requiredNumReplicas=%d, rescGroup=%s, emailToNotify=NULL\n",
00103 topColl, recursiveFlag, requiredNumReplicas, rescGroup);
00104
00105 if((emailToNotify!=NULL)&&(strlen(emailToNotify)>0))
00106 {
00107 fprintf(stderr,"_myAutoReplicateService(): topColl=%s, recursiveFlag=%d, requiredNumReplicas=%d, rescGroup=%s, emailToNotify=%s\n",
00108 topColl, recursiveFlag, requiredNumReplicas, rescGroup, emailToNotify);
00109 }
00110
00111 if(recursiveFlag)
00112 {
00113 sprintf(query_str, "select COLL_NAME, DATA_NAME where COLL_NAME like '%s%%'", topColl);
00114 }
00115 else
00116 {
00117 sprintf(query_str, "select COLL_NAME, DATA_NAME where COLL_NAME = '%s'", topColl);
00118 }
00119
00120 memset (&genQueryInp, 0, sizeof (genQueryInp_t));
00121 t = fillGenQueryInpFromStrCond(query_str, &genQueryInp);
00122 if (t < 0)
00123 {
00124 rodsLog (LOG_ERROR, "_myAutoReplicateService(): fillGenQueryInpFromStrCond() failed. err code=%d", t);
00125 return(t);
00126 }
00127
00128 genQueryInp.maxRows= MAX_SQL_ROWS;
00129 genQueryInp.continueInx=0;
00130 t = rsGenQuery (conn, &genQueryInp, &genQueryOut);
00131 if (t < 0)
00132 {
00133 if(t == CAT_NO_ROWS_FOUND)
00134 {
00135 rodsLog(LOG_ERROR, "_myAutoReplicateService():rsGenQuery(): no data is found. The service ended.");
00136 return 0;
00137 }
00138 rodsLog(LOG_ERROR, "_myAutoReplicateService():rsGenQuery(): failed. err code=%d. The service quit.", t);
00139 return(t);
00140 }
00141
00142 repl_storage_error = 0;
00143 loop_stop = 0;
00144 do
00145 {
00146
00147 for(i=0;i<genQueryOut->rowCnt; i++) {
00148 collNameStruct = getSqlResultByInx (genQueryOut, COL_COLL_NAME);
00149 dataNameStruct = getSqlResultByInx (genQueryOut, COL_DATA_NAME);
00150
00151 collName = &collNameStruct->value[collNameStruct->len*i];
00152 dataName = &dataNameStruct->value[dataNameStruct->len*i];
00153
00154 t = process_single_obj(conn, collName, dataName, requiredNumReplicas, rescGroup, emailToNotify);
00155 rodsLog(LOG_DEBUG, "_myAutoReplicateService(): finished processing obj %s/%s\n", collName, dataName);
00156
00157 if(t == SYS_OUT_OF_FILE_DESC) {
00158 rodsLog(LOG_ERROR, "_myAutoReplicateService():process_single_obj() returned SYS_OUT_OF_FILE_DESC. The service quit.");
00159 return t;
00160 }
00161
00162 if((t < 0) && (repl_storage_error == 1)) {
00163 rodsLog(LOG_ERROR, "_myAutoReplicateService():process_single_obj() returned a storage eror. The service quit.");
00164 loop_stop = 1;
00165 }
00166 }
00167
00168 if(loop_stop ==0) {
00169
00170 if(genQueryOut->continueInx == 0) {
00171 loop_stop = 1;
00172 }
00173 else {
00174 genQueryInp.continueInx=genQueryOut->continueInx;
00175 t = rsGenQuery (conn, &genQueryInp, &genQueryOut);
00176 loop_stop = 0;
00177 }
00178 }
00179 }
00180 while ((t == 0) && (loop_stop == 0));
00181
00182 freeGenQueryOut(&genQueryOut);
00183
00184 rodsLog(LOG_NOTICE,"_myAutoReplicateService(): topColl=%s ended.\n", topColl);
00185
00186 return 0;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 int msiAutoReplicateService(msParam_t *xColl, msParam_t *xRecursive,
00240 msParam_t *xRequireNumReplicas, msParam_t *xRescGroup,
00241 msParam_t *xEmailAccountToNotify,
00242 ruleExecInfo_t *rei)
00243 {
00244 char *sColl;
00245 char *sTmpstr;
00246 int nRecursive;
00247 int nRequiredNumOfReplica;
00248 char *sRescGroup;
00249 char *emailAccount;
00250 int t;
00251
00252 sColl = (char *)xColl->inOutStruct;
00253 if((sColl == NULL) || (strcmp(sColl, "null")==0))
00254 {
00255 rodsLog (LOG_ERROR, "msiAutoReplicateService(): xColl is null.");
00256 return SYS_INTERNAL_NULL_INPUT_ERR;
00257 }
00258
00259 sTmpstr = (char *)xRecursive->inOutStruct;
00260 if((sTmpstr == NULL)|| (strcmp(sTmpstr, "null") == 0))
00261 {
00262 rodsLog (LOG_ERROR, "msiAutoReplicateService(): xRecursive is null.");
00263 return SYS_INTERNAL_NULL_INPUT_ERR;
00264 }
00265 else
00266 {
00267 if(strcmp(sTmpstr, "true") == 0)
00268 {
00269 nRecursive = 1;
00270 }
00271 else
00272 {
00273 nRecursive = 0;
00274 }
00275 }
00276
00277 sTmpstr = (char *)xRequireNumReplicas->inOutStruct;
00278 if((sTmpstr == NULL) || (strcmp(sTmpstr, "null") == 0))
00279 {
00280 rodsLog (LOG_ERROR, "msiAutoReplicateService(): xRequireNumReplicas is null.");
00281 return SYS_INTERNAL_NULL_INPUT_ERR;
00282 }
00283 nRequiredNumOfReplica = atoi(sTmpstr);
00284 if(nRequiredNumOfReplica <= 0)
00285 {
00286 rodsLog (LOG_ERROR, "msiAutoReplicateService(): xRequireNumReplicas must be at least 1.");
00287 return SYS_INTERNAL_NULL_INPUT_ERR;
00288 }
00289
00290 emailAccount = (char *)xEmailAccountToNotify->inOutStruct;
00291 if((emailAccount==NULL) || (strcmp(emailAccount, "null")==0))
00292 {
00293 emailAccount = NULL;
00294 }
00295
00296 sRescGroup = (char *)xRescGroup->inOutStruct;
00297 if(sRescGroup == NULL)
00298 {
00299 rodsLog(LOG_NOTICE, "msiAutoReplicateService(): sRescGroup is null.");
00300 return SYS_INTERNAL_NULL_INPUT_ERR;
00301 }
00302
00303 t = _myAutoReplicateService(rei->rsComm, sColl, nRecursive, nRequiredNumOfReplica, sRescGroup, emailAccount);
00304
00305 return t;
00306 }
00307
00308 static int process_single_obj(rsComm_t *conn, char *parColl, char *fileName,
00309 int required_num_replicas, char *grpRescForReplication, char *emailToNotify)
00310 {
00311 genQueryInp_t genQueryInp;
00312 int i;
00313 genQueryOut_t *genQueryOut = NULL;
00314 sqlResult_t *replNumStruct, *rescStruct, *dataPathStruct, *chkSumStruct;
00315 char *replNum, *rescName, *dataPathName, *chkSum;
00316 int t;
00317
00318 int i1a[10];
00319 int i1b[10];
00320 int i2a[10];
00321 char *condVal[2];
00322 char v1[200], v2[200];
00323 char vault_path[2048];
00324
00325 char *chksum_str=NULL;
00326 dataObjInp_t myDataObjInp;
00327 dataObjInfo_t *myDataObjInfo=NULL;
00328 unregDataObj_t myUnregDataObjInp;
00329 transferStat_t *transStat=NULL;
00330
00331 ReplicaCheckStatusStruct *pReplicaStatus;
00332 int nReplicas;
00333
00334 char tmpstr[1024];
00335
00336 int at_least_one_copy_is_good = 0;
00337 int newN;
00338 int rn;
00339
00340 int validKwFlags;
00341 char *outBadKeyWd;
00342 msParam_t msGrpRescStr;
00343
00344
00345
00346 memset (&genQueryInp, 0, sizeof (genQueryInp_t));
00347 i1a[0]=COL_DATA_REPL_NUM;
00348 i1b[0]=0;
00349 i1a[1] = COL_D_RESC_NAME;
00350 i1b[1] = 0;
00351 i1a[2] = COL_D_RESC_GROUP_NAME;
00352 i1b[2] = 0;
00353 i1a[3] = COL_D_DATA_PATH;
00354 i1b[3] = 0;
00355 i1a[4] = COL_D_DATA_CHECKSUM;
00356 i1b[4] = 0;
00357 genQueryInp.selectInp.inx = i1a;
00358 genQueryInp.selectInp.value = i1b;
00359 genQueryInp.selectInp.len = 5;
00360
00361 i2a[0] = COL_COLL_NAME;
00362 i2a[1] = COL_DATA_NAME;
00363 genQueryInp.sqlCondInp.inx = i2a;
00364 sprintf(v1,"='%s'", parColl);
00365 condVal[0]=v1;
00366 sprintf(v2, "='%s'", fileName);
00367 condVal[1] = v2;
00368 genQueryInp.sqlCondInp.value = condVal;
00369 genQueryInp.sqlCondInp.len = 2;
00370
00371 genQueryInp.maxRows= 10;
00372 genQueryInp.continueInx=0;
00373 t = rsGenQuery (conn, &genQueryInp, &genQueryOut);
00374 if(t < 0)
00375 {
00376 rodsLog(LOG_NOTICE,"msiAutoReplicateService():process_single_obj(): rsGenQuery failed errocode=%d", t);
00377 if(t == CAT_NO_ROWS_FOUND)
00378 return 0;
00379
00380 return(t);
00381 }
00382
00383 if(genQueryOut->rowCnt <= 0)
00384 {
00385 rodsLog(LOG_ERROR, "msiAutoReplicateService():process_single_obj(): return 0 record from calling rsGenQuery() for objid=%s/%s", parColl, fileName);
00386 return 0;
00387 }
00388
00389 nReplicas = genQueryOut->rowCnt;
00390 pReplicaStatus = (ReplicaCheckStatusStruct *)calloc(nReplicas, sizeof(ReplicaCheckStatusStruct));
00391
00392 for(i=0;i<nReplicas;i++)
00393 {
00394 pReplicaStatus[i].registered = 0;
00395 pReplicaStatus[i].checksum[0] = '\0';
00396 }
00397
00398 for(i=0;i<genQueryOut->rowCnt; i++)
00399 {
00400 replNumStruct = getSqlResultByInx (genQueryOut, COL_DATA_REPL_NUM);
00401 replNum = &replNumStruct->value[replNumStruct->len*i];
00402 pReplicaStatus[i].repl_num = atoi(replNum);
00403
00404 rescStruct = getSqlResultByInx (genQueryOut, COL_D_RESC_NAME);
00405 rescName = &rescStruct->value[rescStruct->len*i];
00406
00407 getSqlResultByInx (genQueryOut, COL_D_RESC_GROUP_NAME);
00408
00409 dataPathStruct = getSqlResultByInx(genQueryOut, COL_D_DATA_PATH);
00410 dataPathName = &dataPathStruct->value[dataPathStruct->len*i];
00411
00412 chkSumStruct = getSqlResultByInx (genQueryOut, COL_D_DATA_CHECKSUM);
00413 chkSum = &chkSumStruct->value[chkSumStruct->len*i];
00414
00415 vault_path[0] = '\0';
00416 t = get_resource_path(conn, rescName, vault_path);
00417 if(t < 0)
00418 {
00419 rodsLog(LOG_NOTICE,"msiAutoReplicateService():process_single_obj():get_resource_path failed, status=%d", t);
00420 free( pReplicaStatus );
00421 return t;
00422 }
00423
00424 if(strncmp(dataPathName, vault_path, strlen(vault_path)) != 0)
00425 {
00426
00427 pReplicaStatus[i].registered = 1;
00428 }
00429 else
00430 {
00431 pReplicaStatus[i].registered = 0;
00432 }
00433
00434 if((chkSum != NULL)&&(strlen(chkSum) > 0))
00435 {
00436 strcpy(pReplicaStatus[i].checksum, chkSum);
00437 }
00438 }
00439 freeGenQueryOut(&genQueryOut);
00440
00441
00442 at_least_one_copy_is_good = 0;
00443 for(i=0;i<nReplicas;i++)
00444 {
00445
00446 memset (&myDataObjInp, 0, sizeof(dataObjInp_t));
00447 snprintf (myDataObjInp.objPath, MAX_NAME_LEN, "%s/%s",parColl, fileName);
00448 myDataObjInp.openFlags = O_RDONLY;
00449 sprintf(tmpstr, "%d", pReplicaStatus[i].repl_num);
00450 addKeyVal (&myDataObjInp.condInput, REPL_NUM_KW, tmpstr);
00451 rn = pReplicaStatus[i].repl_num;
00452 t = rsDataObjOpen(conn, &myDataObjInp);
00453 if(t < 0)
00454 {
00455
00456 if(t == SYS_OUT_OF_FILE_DESC) {
00457 free( pReplicaStatus );
00458 return t;
00459 }
00460 else {
00461 pReplicaStatus[i].chksum_status = t;
00462 }
00463 }
00464 else {
00465 openedDataObjInp_t myDataObjCloseInp;
00466 memset (&myDataObjCloseInp, 0, sizeof(openedDataObjInp_t));
00467 myDataObjCloseInp.l1descInx = t;
00468 t = rsDataObjClose(conn, &myDataObjCloseInp);
00469
00470 chksum_str = NULL;
00471
00472 memset(&myDataObjInp, 0, sizeof(dataObjInp_t));
00473 sprintf(myDataObjInp.objPath, "%s/%s", parColl, fileName);
00474 addKeyVal (&myDataObjInp.condInput, FORCE_CHKSUM_KW, "");
00475 sprintf(tmpstr, "%d", pReplicaStatus[i].repl_num);
00476 addKeyVal (&myDataObjInp.condInput, REPL_NUM_KW, tmpstr);
00477 t = rsDataObjChksum(conn, &myDataObjInp, &chksum_str);
00478 pReplicaStatus[i].chksum_status = t;
00479
00480 if(t >= 0) {
00481 if(strlen(pReplicaStatus[i].checksum) > 0) {
00482 if(strcmp(pReplicaStatus[i].checksum, chksum_str) != 0)
00483 {
00484 pReplicaStatus[i].chksum_status = USER_CHKSUM_MISMATCH;
00485 }
00486 else {
00487 at_least_one_copy_is_good = 1;
00488 }
00489 }
00490 else {
00491 at_least_one_copy_is_good = 1;
00492 }
00493 }
00494 }
00495 }
00496
00497
00498
00499 if(at_least_one_copy_is_good == 0)
00500 {
00501 rodsLog(LOG_ERROR, "msiAutoReplicateService():process_single_obj(): Obj='%s/%s': Wanring: The system detects that all copies might be corrupted.", parColl, fileName);
00502
00503 #ifndef windows_platform
00504 if((emailToNotify!=NULL)&&(strlen(emailToNotify)>0))
00505 {
00506 char msg_sub[1024], msg_body[1024];
00507 strcpy(msg_sub, "iRODS msiAutoReplicateService() error");
00508 sprintf(msg_body, "msiAutoReplicateService():process_single_obj(): Obj='%s/%s': at least one storage server is down or all copies are corrupted.",
00509 parColl, fileName);
00510 UnixSendEmail(emailToNotify, msg_sub, msg_body);
00511 }
00512 #endif
00513
00514 free( pReplicaStatus );
00515 return 0;
00516 }
00517
00518
00519 newN = nReplicas;
00520 for(i=0;i<nReplicas;i++)
00521 {
00522 memset(&myDataObjInp, 0, sizeof(dataObjInp_t));
00523 sprintf(myDataObjInp.objPath, "%s/%s", parColl, fileName);
00524 sprintf(tmpstr, "%d", pReplicaStatus[i].repl_num);
00525 addKeyVal (&myDataObjInp.condInput, REPL_NUM_KW, tmpstr);
00526 rn = pReplicaStatus[i].repl_num;
00527 if(pReplicaStatus[i].registered == 1)
00528 {
00529
00530 int adchksum;
00531
00532 adchksum = ((int)(pReplicaStatus[i].chksum_status/1000))*1000;
00533 if((pReplicaStatus[i].chksum_status == USER_CHKSUM_MISMATCH)||(pReplicaStatus[i].chksum_status==UNIX_FILE_OPEN_ERR)||(adchksum==UNIX_FILE_OPEN_ERR))
00534
00535
00536
00537
00538 {
00539 rodsLog(LOG_NOTICE,"msiAutoReplicateService():process_single_obj(): registered copy will be removed: %s, repl=%d", myDataObjInp.objPath, rn);
00540 t = getDataObjInfo(conn, &myDataObjInp, &myDataObjInfo, NULL, 0);
00541 if(t >= 0) {
00542 myUnregDataObjInp.dataObjInfo = myDataObjInfo;
00543 myUnregDataObjInp.condInput = &myDataObjInp.condInput;
00544 t = rsUnregDataObj(conn, &myUnregDataObjInp);
00545 if(t >= 0) {
00546 newN = newN -1;
00547 }
00548 else {
00549 rodsLog(LOG_ERROR, "msiAutoReplicateService():rsUnregDataObj(): failed for %s/%s:%d. erStat=%d", parColl, fileName, rn, t);
00550 return t;
00551 }
00552 }
00553 else {
00554 rodsLog(LOG_ERROR, "msiAutoReplicateService():getDataObjInfo(): failed for %s/%s:%d. erStat=%d", parColl, fileName, rn, t);
00555 return t;
00556 }
00557 }
00558 else
00559 {
00560 rodsLog(LOG_ERROR,"%s:%d, the registered copy has errored checksum status=%d.", myDataObjInp.objPath, rn, pReplicaStatus[i].chksum_status);
00561 return t;
00562 }
00563 }
00564 else
00565 {
00566 if(pReplicaStatus[i].chksum_status == USER_CHKSUM_MISMATCH)
00567 {
00568 t = rsDataObjUnlink(conn, &myDataObjInp);
00569 if(t >= 0) {
00570 newN = newN -1;
00571 }
00572 else {
00573 rodsLog(LOG_ERROR, "msiAutoReplicateService():rsDataObjUnlink() for %s:%d failed. errStat=%d", myDataObjInp.objPath, rn, t);
00574 free( pReplicaStatus );
00575 return t;
00576 }
00577 }
00578 }
00579 }
00580
00581 fillStrInMsParam(&msGrpRescStr, grpRescForReplication);
00582
00583
00584 if(newN < required_num_replicas)
00585 {
00586 rodsLog(LOG_NOTICE,"msiAutoReplicateService():process_single_obj(): making necessary %d copies as required.", (required_num_replicas-newN));
00587 for(i=0;i<(required_num_replicas-newN);i++)
00588 {
00589 memset(&myDataObjInp, 0, sizeof(dataObjInp_t));
00590 snprintf (myDataObjInp.objPath, MAX_NAME_LEN, "%s/%s", parColl, fileName);
00591
00592 validKwFlags = OBJ_PATH_FLAG | DEST_RESC_NAME_FLAG | NUM_THREADS_FLAG |
00593 BACKUP_RESC_NAME_FLAG | RESC_NAME_FLAG | UPDATE_REPL_FLAG |
00594 REPL_NUM_FLAG | ALL_FLAG | IRODS_ADMIN_FLAG | VERIFY_CHKSUM_FLAG |
00595 RBUDP_TRANSFER_FLAG | RBUDP_SEND_RATE_FLAG | RBUDP_PACK_SIZE_FLAG;
00596 t = parseMsKeyValStrForDataObjInp(&msGrpRescStr, &myDataObjInp, DEST_RESC_NAME_KW, validKwFlags, &outBadKeyWd);
00597 if(t < 0)
00598 {
00599 if(outBadKeyWd != NULL)
00600 {
00601 rodsLog(LOG_ERROR, "msiAutoReplicateService():rsDataObjRepl(): input keyWd - %s error. status = %d", outBadKeyWd, t);
00602 free(outBadKeyWd);
00603 }
00604 else
00605 {
00606 rodsLog(LOG_ERROR, "msiAutoReplicateService():rsDataObjRepl(): input msKeyValStr error. status = %d", t);
00607 }
00608
00609 free( pReplicaStatus );
00610 return t;
00611 }
00612
00613 t = rsDataObjRepl(conn, &myDataObjInp, &transStat);
00614 if(t < 0)
00615 {
00616 rodsLog(LOG_ERROR, "msiAutoReplicateService():rsDataObjRepl() failed for %s/%s:%d into '%s'. err code=%d.", parColl, fileName, rn, grpRescForReplication, t);
00617 repl_storage_error = 1;
00618 free( pReplicaStatus );
00619 return t;
00620 }
00621 if (transStat != NULL) free (transStat);
00622 }
00623 }
00624
00625 free( pReplicaStatus );
00626 return 0;
00627 }
00628
00629 static int get_resource_path(rsComm_t *conn, char *rescName, char *rescPath)
00630 {
00631 genQueryInp_t genQueryInp;
00632 int i1a[10];
00633 int i1b[10];
00634 int i2a[10];
00635 char *condVal[2];
00636 char v1[200];
00637 genQueryOut_t *genQueryOut = NULL;
00638 sqlResult_t *vaultPathSTruct;
00639 char *vaultPath;
00640 int t;
00641
00642 memset (&genQueryInp, 0, sizeof (genQueryInp_t));
00643
00644 i1a[0] = COL_R_VAULT_PATH;
00645 i1b[0]=0;
00646 genQueryInp.selectInp.inx = i1a;
00647 genQueryInp.selectInp.value = i1b;
00648 genQueryInp.selectInp.len = 1;
00649
00650 i2a[0] = COL_R_RESC_NAME;
00651 genQueryInp.sqlCondInp.inx = i2a;
00652 sprintf(v1,"='%s'", rescName);
00653 condVal[0]=v1;
00654 genQueryInp.sqlCondInp.value = condVal;
00655 genQueryInp.sqlCondInp.len = 1;
00656
00657 genQueryInp.maxRows= 2;
00658 genQueryInp.continueInx=0;
00659 t = rsGenQuery (conn, &genQueryInp, &genQueryOut);
00660 if( NULL == genQueryOut ) {
00661 rodsLog( LOG_ERROR, "get_resource_path :: genQueryOut is NULL" );
00662 return 0;
00663 }
00664
00665 if(t < 0)
00666 {
00667 if(t == CAT_NO_ROWS_FOUND)
00668 return 0;
00669
00670 return(t);
00671 }
00672
00673 if(genQueryOut->rowCnt < 0)
00674 {
00675 return -1;
00676 }
00677
00678 vaultPathSTruct = getSqlResultByInx (genQueryOut, COL_R_VAULT_PATH);
00679 vaultPath = &vaultPathSTruct->value[0];
00680 strcpy(rescPath, vaultPath);
00681
00682 freeGenQueryOut(&genQueryOut);
00683
00684 return 0;
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 int msiDataObjAutoMove(msParam_t *inpParam1, msParam_t *inpParam2, msParam_t *inpParam3,
00729 msParam_t *inpParam4, msParam_t *inpParam5, ruleExecInfo_t *rei)
00730 {
00731 char *obj_path, *truct_path, *dest_coll, *new_owner;
00732 char *new_truct_path;
00733 char *new_obj_path;
00734 int t;
00735 int new_truct_path_len;
00736 rsComm_t *rsconn;
00737 char mdest_coll[MAX_NAME_LEN];
00738
00739 char query_str[2048];
00740 genQueryInp_t genQueryInp;
00741 genQueryOut_t *genQueryOut = NULL;
00742
00743 char new_obj_parent[MAX_NAME_LEN];
00744 char obj_name[MAX_NAME_LEN];
00745
00746 collInp_t collCreateInp;
00747 dataObjCopyInp_t dataObjRenameInp;
00748 modAccessControlInp_t myModAccessCntlInp;
00749
00750 dataObjInp_t myDataObjInp;
00751 char own_perm[20], null_perm[20];
00752 char user_name[NAME_LEN], zone_name[NAME_LEN];
00753
00754 char *sTmpstr;
00755 int compute_checksum = 0;
00756 char *chksum_str=NULL;
00757 char tmpstr[1024];
00758
00759 strcpy(own_perm, "own");
00760 strcpy(null_perm, "null");
00761
00762 if (rei == NULL || rei->rsComm == NULL) {
00763 rodsLog (LOG_ERROR,
00764 "msiDataObjAutoMove: input rei or rei->rsComm is NULL");
00765 return (SYS_INTERNAL_NULL_INPUT_ERR);
00766 }
00767
00768 rsconn = rei->rsComm;
00769
00770 if(inpParam1 == NULL) {
00771 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input objpath (inpParam1) is NULL.");
00772 return SYS_INTERNAL_NULL_INPUT_ERR;
00773 }
00774 obj_path = (char *)inpParam1->inOutStruct;
00775 if((obj_path==NULL)||(strlen(obj_path)==0)) {
00776 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input objpath (inpParam1->inOutStruct) is NULL.");
00777 return SYS_INTERNAL_NULL_INPUT_ERR;
00778 }
00779
00780 if(inpParam2 == NULL) {
00781 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input truct_path (inpParam2) is NULL.");
00782 return SYS_INTERNAL_NULL_INPUT_ERR;
00783 }
00784 truct_path = (char *)inpParam2->inOutStruct;
00785 if((truct_path==NULL)||(strlen(truct_path)==0)) {
00786 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input truct_path (inpParam2->inOutStruct) is NULL.");
00787 return SYS_INTERNAL_NULL_INPUT_ERR;
00788 }
00789
00790 if(inpParam3 == NULL) {
00791 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input dest_coll (inpParam3) is NULL.");
00792 return SYS_INTERNAL_NULL_INPUT_ERR;
00793 }
00794 dest_coll = (char *)inpParam3->inOutStruct;
00795 if((dest_coll==NULL)||(strlen(dest_coll)==0)) {
00796 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input dest_coll (inpParam3->inOutStruct) is NULL.");
00797 return SYS_INTERNAL_NULL_INPUT_ERR;
00798 }
00799
00800 if(inpParam4 == NULL) {
00801 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input new_owner (inpParam4) is NULL.");
00802 return SYS_INTERNAL_NULL_INPUT_ERR;
00803 }
00804 new_owner = (char *)inpParam4->inOutStruct;
00805 if(new_owner != NULL)
00806 {
00807 if(strlen(new_owner) == 0) {
00808 new_owner = NULL;
00809 }
00810 else if(strcmp(new_owner, "null") == 0) {
00811 new_owner = NULL;
00812 }
00813 }
00814 if(new_owner != NULL)
00815 {
00816 user_name[0] = '\0';
00817 zone_name[0] = '\0';
00818 t = parseUserName(new_owner, user_name, zone_name);
00819 if(t < 0) {
00820 rodsLog(LOG_ERROR, "msiDataObjAutoMove: parseUserName() failed. errStatus=%d.", t);
00821 return t;
00822 }
00823 if(strlen(zone_name) == 0) {
00824 strcpy(zone_name, rei->uoip->rodsZone);
00825 }
00826 }
00827
00828 if(inpParam5 == NULL) {
00829 rodsLog(LOG_ERROR, "msiDataObjAutoMove: input compute_checksum (inpParam5) is NULL.");
00830 return SYS_INTERNAL_NULL_INPUT_ERR;
00831 }
00832 sTmpstr = (char *)inpParam5->inOutStruct;
00833 compute_checksum = 1;
00834 if((sTmpstr != NULL)&&(strlen(sTmpstr) >= 0))
00835 {
00836 if(strcmp(sTmpstr, "false") == 0)
00837 compute_checksum = 0;
00838 }
00839
00840 if(compute_checksum == 1) {
00841 chksum_str = NULL;
00842 memset(&myDataObjInp, 0, sizeof(dataObjInp_t));
00843 strncpy(myDataObjInp.objPath, obj_path, MAX_NAME_LEN);
00844 addKeyVal (&myDataObjInp.condInput, VERIFY_CHKSUM_KW, "");
00845 sprintf(tmpstr, "%d", 0);
00846 addKeyVal (&myDataObjInp.condInput, REPL_NUM_KW, tmpstr);
00847 t = rsDataObjChksum(rsconn, &myDataObjInp, &chksum_str);
00848 if(t < 0) {
00849 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsDataObjChksum() for '%s' failed. errStatus=%d.", obj_path, t);
00850 return t;
00851 }
00852 }
00853
00854 if(new_owner != NULL)
00855 {
00856
00857 memset(&myModAccessCntlInp, 0, sizeof(modAccessControlInp_t));
00858 myModAccessCntlInp.recursiveFlag = False;
00859 myModAccessCntlInp.accessLevel = own_perm;
00860 myModAccessCntlInp.userName = user_name;
00861 myModAccessCntlInp.zone = zone_name;
00862 myModAccessCntlInp.path = obj_path;
00863 t = rsModAccessControl(rsconn, &myModAccessCntlInp);
00864 if(t < 0) {
00865 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsModAccessControl() add new owner for '%s' failed. errStatus=%d.", obj_path, t);
00866 return t;
00867 }
00868
00869 }
00870
00871 t = strlen(truct_path);
00872 new_truct_path = (char *)calloc(t+2, sizeof(char));
00873 if(truct_path[t-1] != '/') {
00874 strcpy(new_truct_path, truct_path);
00875 new_truct_path_len = t;
00876 }
00877 else {
00878 strcpy(new_truct_path, truct_path);
00879 new_truct_path[t] = '/';
00880 new_truct_path[t+1] = '\0';
00881 new_truct_path_len = t + 1;
00882 }
00883 if(strncmp(new_truct_path, obj_path, t) != 0) {
00884
00885 rodsLog(LOG_ERROR, "msiDataObjAutoMove: The object path, %s, is not in the specified collection, %s.", obj_path, new_truct_path);
00886 return SYS_INTERNAL_NULL_INPUT_ERR;
00887 }
00888
00889 t = strlen(dest_coll);
00890 new_obj_path = (char *)calloc(t+strlen(obj_path), sizeof(char));
00891 strcpy(mdest_coll, dest_coll);
00892 if(dest_coll[t-1] == '/')
00893 {
00894 mdest_coll[t-1] = '\0';
00895 }
00896 sprintf(new_obj_path, "%s/%s", mdest_coll, &(obj_path[new_truct_path_len+1]));
00897 sprintf(query_str, "SELECT COLL_NAME WHERE COLL_NAME like '%s%%'", mdest_coll);
00898
00899
00900 memset (&genQueryInp, 0, sizeof (genQueryInp_t));
00901 t = fillGenQueryInpFromStrCond(query_str, &genQueryInp);
00902 if(t < 0)
00903 {
00904 rodsLog(LOG_ERROR, "msiDataObjAutoMove: fillGenQueryInpFromStrCond() failed. errStatus=%d", t);
00905 free( new_obj_path );
00906 free( new_truct_path );
00907 return t;
00908 }
00909 genQueryInp.maxRows= MAX_SQL_ROWS;
00910 genQueryInp.continueInx=0;
00911 t = rsGenQuery(rsconn, &genQueryInp, &genQueryOut);
00912 if(t < 0) {
00913 if(t == CAT_NO_ROWS_FOUND) {
00914 rodsLog(LOG_ERROR, "msiDataObjAutoMove: The destination collection '%s' does not exist.", dest_coll);
00915 }
00916 else {
00917 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsGenQuery() failed. errStatus=%d", t);
00918 }
00919 free( new_obj_path );
00920 free( new_truct_path );
00921 return t;
00922 }
00923
00924
00925 t = splitPathByKey(new_obj_path, new_obj_parent, obj_name, '/');
00926 if(t < 0) {
00927 rodsLog(LOG_ERROR, "msiDataObjAutoMove: splitPathByKey() failed for splitting '%s'. errStatus=%d.", new_obj_path, t);
00928 free( new_obj_path );
00929 free( new_truct_path );
00930 return t;
00931 }
00932
00933
00934
00935
00936 if(strlen(new_obj_parent) > strlen(mdest_coll))
00937 {
00938 memset (&collCreateInp, 0, sizeof (collCreateInp));
00939 rstrcpy (collCreateInp.collName, new_obj_parent, MAX_NAME_LEN);
00940 addKeyVal (&collCreateInp.condInput, RECURSIVE_OPR__KW, "");
00941 t = rsCollCreate(rsconn, &collCreateInp);
00942 if(t < 0)
00943 {
00944 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsCollCreate() failed for %s. errStatus=%d.", new_obj_parent, t);
00945 free( new_obj_path );
00946 free( new_truct_path );
00947 return t;
00948 }
00949 }
00950
00951 fprintf(stderr,"new_obj_path=%s, obj_path=%s\n", new_obj_path, obj_path);
00952
00953 memset(&dataObjRenameInp, 0, sizeof(dataObjCopyInp_t));
00954 rstrcpy(dataObjRenameInp.destDataObjInp.objPath, new_obj_path, MAX_NAME_LEN);
00955 rstrcpy(dataObjRenameInp.srcDataObjInp.objPath, obj_path, MAX_NAME_LEN);
00956 t = rsDataObjRename(rsconn, &dataObjRenameInp);
00957 if(t < 0) {
00958 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsDataObjRename() failed. errStatus=%d.", t);
00959 free( new_obj_path );
00960 free( new_truct_path );
00961 return t;
00962 }
00963
00964 memset(&myModAccessCntlInp, 0, sizeof(modAccessControlInp_t));
00965 myModAccessCntlInp.recursiveFlag = False;
00966 myModAccessCntlInp.accessLevel = null_perm;
00967 myModAccessCntlInp.userName = rei->uoic->userName;
00968 myModAccessCntlInp.zone = zone_name;
00969 myModAccessCntlInp.path = new_obj_path;
00970 t = rsModAccessControl(rsconn, &myModAccessCntlInp);
00971 if(t < 0) {
00972 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsModAccessControl() remove user for '%s' failed. errStatus=%d.", obj_path, t);
00973 }
00974
00975
00976 #if 0
00977 if(new_owner != NULL)
00978 {
00979 if(strlen(new_obj_parent) > strlen(mdest_coll))
00980 {
00981 char *ta, *tb;
00982 char ttab_coll[MAX_NAME_LEN];
00983 char ttab[MAX_NAME_LEN];
00984
00985 strcpy(ttab, new_obj_parent);
00986 t = strlen(mdest_coll);
00987 ta = &(ttab[t+1]);
00988 tb = strchr(ta, '/');
00989 if(tb != NULL)
00990 *tb = '\0';
00991 sprintf(ttab_coll, "%s/%s", mdest_coll, ta);
00992
00993 memset(&myModAccessCntlInp, 0, sizeof(modAccessControlInp_t));
00994 myModAccessCntlInp.recursiveFlag = True;
00995 myModAccessCntlInp.accessLevel = own_perm;
00996 myModAccessCntlInp.userName = user_name;
00997 myModAccessCntlInp.zone = zone_name;
00998 myModAccessCntlInp.path = ttab_coll;
00999 t = rsModAccessControl(rsconn, &myModAccessCntlInp);
01000 if(t < 0) {
01001 rodsLog(LOG_ERROR, "msiDataObjAutoMove: rsModAccessControl() for '%s' failed. errStatus=%d.", ttab_coll, t);
01002 return t;
01003 }
01004 }
01005 }
01006 #endif
01007
01008 free( new_truct_path );
01009 return 0;
01010 }