00001
00002
00003
00004
00005
00006
00007
00008 #include "getRescQuota.h"
00009 #include "miscUtil.h"
00010 #include "genQuery.h"
00011 #include "objMetaOpr.h"
00012 #include "resource.h"
00013
00014
00015
00016 #include "eirods_resource_backport.h"
00017
00018
00019 int
00020 rsGetRescQuota (rsComm_t *rsComm, getRescQuotaInp_t *getRescQuotaInp,
00021 rescQuota_t **rescQuota)
00022 {
00023 rodsServerHost_t *rodsServerHost;
00024 int status = 0;
00025
00026 status = getAndConnRcatHost (rsComm, SLAVE_RCAT,
00027 getRescQuotaInp->zoneHint, &rodsServerHost);
00028
00029 if (status < 0) return(status);
00030
00031 if (rodsServerHost->localFlag == LOCAL_HOST) {
00032 status = _rsGetRescQuota (rsComm, getRescQuotaInp, rescQuota);
00033 } else {
00034 status = rcGetRescQuota (rodsServerHost->conn, getRescQuotaInp,
00035 rescQuota);
00036 }
00037
00038 return status;
00039 }
00040
00041 int
00042 _rsGetRescQuota (rsComm_t *rsComm, getRescQuotaInp_t *getRescQuotaInp,
00043 rescQuota_t **rescQuota)
00044 {
00045 int status = 0;
00046 rescGrpInfo_t *tmpRescGrpInfo = NULL;
00047 rescGrpInfo_t *rescGrpInfo = 0;
00048
00049 genQueryOut_t *genQueryOut = NULL;
00050
00051 if (rescQuota == NULL) {
00052 return USER__NULL_INPUT_ERR;
00053 }
00054
00055 *rescQuota = NULL;
00056
00057
00058
00059 status = getQuotaByResc (rsComm, getRescQuotaInp->userName,
00060 getRescQuotaInp->rescName, &genQueryOut);
00061
00062 if (status >= 0) {
00063 queRescQuota (rescQuota, genQueryOut, NULL);
00064 freeGenQueryOut (&genQueryOut);
00065 return status;
00066 }
00067
00068
00069
00070 rescGrpInfo = new rescGrpInfo_t;
00071 rescGrpInfo->rescInfo = new rescInfo_t;
00072 eirods::error err = eirods::get_resc_grp_info( getRescQuotaInp->rescName, *rescGrpInfo );
00073 if ( !err.ok() ) {
00074 rodsLog (LOG_ERROR,
00075 "_rsGetRescQuota: _getRescInfo of %s error for %s. stat = %d",
00076 getRescQuotaInp->rescName, getRescQuotaInp->zoneHint, status);
00077 delete rescGrpInfo->rescInfo;
00078 delete rescGrpInfo;
00079 return status;
00080 }
00081
00082 tmpRescGrpInfo = rescGrpInfo;
00083 while (tmpRescGrpInfo != NULL) {
00084 status = getQuotaByResc (rsComm, getRescQuotaInp->userName,
00085 tmpRescGrpInfo->rescInfo->rescName, &genQueryOut);
00086
00087 if (status >= 0) {
00088 queRescQuota (rescQuota, genQueryOut, tmpRescGrpInfo->rescGroupName);
00089 }
00090 tmpRescGrpInfo = tmpRescGrpInfo->next;
00091 }
00092 delete rescGrpInfo->rescInfo;
00093 delete rescGrpInfo;
00094 freeGenQueryOut (&genQueryOut);
00095
00096 return 0;
00097 }
00098
00099
00100
00101
00102
00103 int
00104 getQuotaByResc (rsComm_t *rsComm, char *userName, char *rescName,
00105 genQueryOut_t **genQueryOut)
00106 {
00107 int status;
00108 genQueryInp_t genQueryInp;
00109 char condition1[MAX_NAME_LEN];
00110 char condition2[MAX_NAME_LEN];
00111
00112 if (genQueryOut == NULL) return USER__NULL_INPUT_ERR;
00113
00114 *genQueryOut = NULL;
00115 memset (&genQueryInp, 0, sizeof (genQueryInp));
00116
00117 genQueryInp.options = QUOTA_QUERY;
00118
00119 snprintf (condition1, MAX_NAME_LEN, "%s",
00120 userName);
00121 addInxVal (&genQueryInp.sqlCondInp, COL_USER_NAME, condition1);
00122
00123 if (rescName != NULL && strlen(rescName)>0) {
00124 snprintf (condition2, MAX_NAME_LEN, "%s",
00125 rescName);
00126 addInxVal (&genQueryInp.sqlCondInp, COL_R_RESC_NAME, condition2);
00127 }
00128
00129 genQueryInp.maxRows = MAX_SQL_ROWS;
00130
00131 status = rsGenQuery (rsComm, &genQueryInp, genQueryOut);
00132
00133 clearGenQueryInp(&genQueryInp);
00134
00135 return (status);
00136 }
00137
00138 int
00139 queRescQuota (rescQuota_t **rescQuotaHead, genQueryOut_t *genQueryOut,
00140 char *rescGroupName)
00141 {
00142 sqlResult_t *quotaLimit, *quotaOver, *rescName, *quotaRescId, *quotaUserId;
00143 char *tmpQuotaLimit, *tmpQuotaOver, *tmpRescName, *tmpQuotaRescId,
00144 *tmpQuotaUserId;
00145 int i;
00146 rescQuota_t *tmpRescQuota;
00147
00148 if ((quotaLimit = getSqlResultByInx (genQueryOut, COL_QUOTA_LIMIT)) ==
00149 NULL) {
00150 rodsLog (LOG_ERROR,
00151 "queRescQuota: getSqlResultByInx for COL_QUOTA_LIMIT failed");
00152 return (UNMATCHED_KEY_OR_INDEX);
00153 }
00154
00155 if ((quotaOver = getSqlResultByInx (genQueryOut, COL_QUOTA_OVER))==NULL) {
00156 rodsLog (LOG_ERROR,
00157 "queRescQuota: getSqlResultByInx for COL_QUOTA_OVER failed");
00158 return (UNMATCHED_KEY_OR_INDEX);
00159 }
00160
00161 if ((rescName = getSqlResultByInx (genQueryOut, COL_R_RESC_NAME))==NULL) {
00162 rodsLog (LOG_ERROR,
00163 "queRescQuota: getSqlResultByInx for COL_R_RESC_NAME failed");
00164 return (UNMATCHED_KEY_OR_INDEX);
00165 }
00166
00167 if ((quotaRescId = getSqlResultByInx (genQueryOut, COL_QUOTA_RESC_ID)) ==
00168 NULL) {
00169 rodsLog (LOG_ERROR,
00170 "queRescQuota: getSqlResultByInx for COL_QUOTA_RESC_ID failed");
00171 return (UNMATCHED_KEY_OR_INDEX);
00172 }
00173
00174 if ((quotaUserId = getSqlResultByInx (genQueryOut, COL_QUOTA_USER_ID)) ==
00175 NULL) {
00176 rodsLog (LOG_ERROR,
00177 "queRescQuota: getSqlResultByInx for COL_QUOTA_USER_ID failed");
00178 return (UNMATCHED_KEY_OR_INDEX);
00179 }
00180
00181 for (i = 0;i < genQueryOut->rowCnt; i++) {
00182 tmpQuotaLimit = "aLimit->value[quotaLimit->len * i];
00183 tmpQuotaOver = "aOver->value[quotaOver->len * i];
00184 tmpRescName = &rescName->value[rescName->len * i];
00185 tmpQuotaRescId = "aRescId->value[quotaRescId->len * i];
00186 tmpQuotaUserId = "aUserId->value[quotaUserId->len * i];
00187 tmpRescQuota = (rescQuota_t*)malloc (sizeof (rescQuota_t));
00188 fillRescQuotaStruct (tmpRescQuota, tmpQuotaLimit, tmpQuotaOver,
00189 tmpRescName, tmpQuotaRescId, tmpQuotaUserId, rescGroupName);
00190 tmpRescQuota->next = *rescQuotaHead;
00191 *rescQuotaHead = tmpRescQuota;
00192 }
00193
00194 return 0;
00195 }
00196
00197 int
00198 fillRescQuotaStruct (rescQuota_t *rescQuota, char *tmpQuotaLimit,
00199 char *tmpQuotaOver, char *tmpRescName, char *tmpQuotaRescId,
00200 char *tmpQuotaUserId, char *rescGroupName)
00201 {
00202 bzero (rescQuota, sizeof (rescQuota_t));
00203
00204 rescQuota->quotaLimit = strtoll (tmpQuotaLimit, 0, 0);
00205 rescQuota->quotaOverrun = strtoll (tmpQuotaOver, 0, 0);
00206 if (strtoll (tmpQuotaRescId, 0, 0) > 0) {
00207
00208 rstrcpy (rescQuota->rescName, tmpRescName, NAME_LEN);
00209 } else {
00210 rescQuota->flags = GLOBAL_QUOTA;
00211 }
00212 rstrcpy (rescQuota->userId, tmpQuotaUserId, NAME_LEN);
00213 if (rescGroupName != NULL)
00214 rstrcpy (rescQuota->rescGroupName, rescGroupName, NAME_LEN);
00215
00216 return 0;
00217 }
00218
00219 int
00220 setRescQuota (rsComm_t *rsComm, char *zoneHint,
00221 rescGrpInfo_t **rescGrpInfoHead, rodsLong_t dataSize)
00222 {
00223 rescGrpInfo_t *tmpRescGrpInfo;
00224 getRescQuotaInp_t getRescQuotaInp;
00225 rescQuota_t *rescQuota = NULL;
00226 rescQuota_t *tmpRescQuota;
00227 int needInit = 0;
00228 int status = 0;
00229
00230 status = chkRescQuotaPolicy (rsComm);
00231 if (status != RESC_QUOTA_ON) return 0;
00232
00233 if (rescGrpInfoHead == NULL) return USER__NULL_INPUT_ERR;
00234 tmpRescGrpInfo = *rescGrpInfoHead;
00235 while (tmpRescGrpInfo != NULL) {
00236 if (tmpRescGrpInfo->rescInfo->quotaLimit == RESC_QUOTA_UNINIT) {
00237 needInit = 1;
00238 break;
00239 }
00240 tmpRescGrpInfo = tmpRescGrpInfo->next;
00241 }
00242 if (needInit == 0) {
00243 status = chkRescGrpInfoForQuota (rescGrpInfoHead, dataSize);
00244 return status;
00245 }
00246 bzero (&getRescQuotaInp, sizeof (getRescQuotaInp));
00247 tmpRescGrpInfo = *rescGrpInfoHead;
00248 rstrcpy (getRescQuotaInp.zoneHint, zoneHint, MAX_NAME_LEN);
00249 if (strlen (tmpRescGrpInfo->rescGroupName) > 0) {
00250 rstrcpy (getRescQuotaInp.rescName, tmpRescGrpInfo->rescGroupName,
00251 NAME_LEN);
00252 } else {
00253 rstrcpy (getRescQuotaInp.rescName, tmpRescGrpInfo->rescInfo->rescName,
00254 NAME_LEN);
00255 }
00256 snprintf (getRescQuotaInp.userName, NAME_LEN, "%s#%s",
00257 rsComm->clientUser.userName, rsComm->clientUser.rodsZone);
00258 status = rsGetRescQuota (rsComm, &getRescQuotaInp, &rescQuota);
00259 if (status < 0) return status;
00260
00261
00262 tmpRescQuota = rescQuota;
00263 while (tmpRescQuota != NULL) {
00264 if ((tmpRescQuota->flags & GLOBAL_QUOTA) > 0) {
00265
00266
00267 if (GlobalQuotaLimit < 0 ||
00268 GlobalQuotaOverrun < tmpRescQuota->quotaOverrun) {
00269 GlobalQuotaLimit = tmpRescQuota->quotaLimit;
00270 GlobalQuotaOverrun = tmpRescQuota->quotaOverrun;
00271 }
00272 } else {
00273 tmpRescGrpInfo = *rescGrpInfoHead;
00274
00275 while (tmpRescGrpInfo != NULL) {
00276 rescInfo_t *rescInfo = tmpRescGrpInfo->rescInfo;
00277 if (strcmp (tmpRescQuota->rescName, rescInfo->rescName) == 0) {
00278 if (rescInfo->quotaLimit == RESC_QUOTA_UNINIT ||
00279 rescInfo->quotaOverrun < tmpRescQuota->quotaOverrun) {
00280 rescInfo->quotaLimit = tmpRescQuota->quotaLimit;
00281 rescInfo->quotaOverrun = tmpRescQuota->quotaOverrun;
00282 }
00283 break;
00284 }
00285 tmpRescGrpInfo = tmpRescGrpInfo->next;
00286 }
00287 }
00288 tmpRescQuota = tmpRescQuota->next;
00289 }
00290 freeAllRescQuota (rescQuota);
00291 status = chkRescGrpInfoForQuota (rescGrpInfoHead, dataSize);
00292
00293 return status;
00294 }
00295
00296 int
00297 chkRescGrpInfoForQuota (rescGrpInfo_t **rescGrpInfoHead, rodsLong_t dataSize)
00298 {
00299 rescGrpInfo_t *tmpRescGrpInfo, *prevRescGrpInfo;
00300
00301 if (dataSize < 0) dataSize = 0;
00302 if (GlobalQuotaLimit == RESC_QUOTA_UNINIT) {
00303
00304 GlobalQuotaLimit = 0;
00305 } else if (GlobalQuotaLimit > 0) {
00306 if (GlobalQuotaOverrun + dataSize >= 0) return SYS_RESC_QUOTA_EXCEEDED;
00307 }
00308
00309
00310
00311 prevRescGrpInfo = NULL;
00312 tmpRescGrpInfo = *rescGrpInfoHead;
00313 while (tmpRescGrpInfo != NULL) {
00314 rescGrpInfo_t *nextRescGrpInfo = tmpRescGrpInfo->next;
00315 if (tmpRescGrpInfo->rescInfo->quotaLimit > 0 &&
00316 tmpRescGrpInfo->rescInfo->quotaOverrun + dataSize >= 0) {
00317
00318 if (prevRescGrpInfo == NULL) {
00319
00320 *rescGrpInfoHead = nextRescGrpInfo;
00321 } else {
00322 prevRescGrpInfo->next = nextRescGrpInfo;
00323 }
00324 if (*rescGrpInfoHead != NULL) {
00325 (*rescGrpInfoHead)->status = SYS_RESC_QUOTA_EXCEEDED;
00326 }
00327 free (tmpRescGrpInfo);
00328 } else {
00329 if (tmpRescGrpInfo->rescInfo->quotaLimit == RESC_QUOTA_UNINIT) {
00330
00331 tmpRescGrpInfo->rescInfo->quotaLimit = 0;
00332 }
00333 prevRescGrpInfo = tmpRescGrpInfo;
00334 }
00335 tmpRescGrpInfo = nextRescGrpInfo;
00336 }
00337 if (rescGrpInfoHead == NULL || *rescGrpInfoHead == NULL)
00338 return SYS_RESC_QUOTA_EXCEEDED;
00339 else
00340 return 0;
00341 }
00342
00343 int
00344 updatequotaOverrun (rescInfo_t *rescInfo, rodsLong_t dataSize, int flags)
00345 {
00346 if ((flags & GLB_QUOTA) > 0 && GlobalQuotaLimit > 0) {
00347 GlobalQuotaOverrun += dataSize;
00348 }
00349
00350 if (rescInfo == NULL) return USER__NULL_INPUT_ERR;
00351 if ((flags & RESC_QUOTA) > 0 && rescInfo->quotaLimit > 0) {
00352 rescInfo->quotaOverrun += dataSize;
00353 }
00354 return 0;
00355 }
00356
00357 int
00358 chkRescQuotaPolicy (rsComm_t *rsComm)
00359 {
00360 int status;
00361 ruleExecInfo_t rei;
00362
00363 if (RescQuotaPolicy == RESC_QUOTA_UNINIT) {
00364 initReiWithDataObjInp (&rei, rsComm, NULL);
00365 status = applyRule ("acRescQuotaPolicy", NULL, &rei, NO_SAVE_REI);
00366 if (status < 0) {
00367 rodsLog (LOG_ERROR,
00368 "queRescQuota: acRescQuotaPolicy error status = %d", status);
00369 RescQuotaPolicy = RESC_QUOTA_OFF;
00370 }
00371 }
00372 return RescQuotaPolicy;
00373 }
00374