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