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