123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114(*
* Copyright (C) Citrix Systems Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*)letwarnfmt=Logging.warn"quota"fmtexceptionLimit_reachedexceptionData_too_bigexceptionTransaction_openedtypedomid=int(* Global defaults *)letmaxent=ref(10000)letmaxsize=ref(4096)letmaxwatch=ref50letmaxtransaction=ref20letmaxwatchevent=ref256typeoverrides=(int,int)Hashtbl.tletmaxent_overrides=Hashtbl.create10letmaxwatch_overrides=Hashtbl.create10letmaxtransaction_overrides=Hashtbl.create10letmaxwatchevent_overrides=Hashtbl.create10letget_overridetdomid=ifHashtbl.memtdomidthenSome(Hashtbl.findtdomid)elseNoneletset_overridetdomidoverride=matchoverridewith|None->Hashtbl.removetdomid|Someoverride->Hashtbl.replacetdomidoverrideletlist_overridest=Hashtbl.fold(fundomidxacc->(domid,x)::acc)t[]letof_domaintdefaultdomid=ifHashtbl.memtdomidthenHashtbl.findtdomidelse!defaultletmaxent_of_domain=of_domainmaxent_overridesmaxentletmaxwatch_of_domain=of_domainmaxwatch_overridesmaxwatchletmaxtransaction_of_domain=of_domainmaxtransaction_overridesmaxtransactionletmaxwatchevent_of_domain=of_domainmaxwatchevent_overridesmaxwatcheventtypet={cur:(domid,int)Hashtbl.t;(* current domains entry usage *)}letcreate()={cur=Hashtbl.create100;}letcopyquota={cur=(Hashtbl.copyquota.cur)}(*let del quota id = Hashtbl.remove quota.cur id*)letcheck_quotaidsize=ifsize>!maxsizethen(warn"domain %u err create entry: data too big %d"idsize;raiseData_too_big)letlistquota=Hashtbl.fold(fundomidxacc->(domid,x)::acc)quota.cur[]letgetquotaid=ifHashtbl.memquota.curidthenHashtbl.findquota.curidelse0letsetquotaidnb=ifnb=0thenHashtbl.removequota.curidelsebeginifHashtbl.memquota.curidthenHashtbl.replacequota.curidnbelseHashtbl.addquota.curidnbendletdecrquotaid=letnb=getquotaidinifnb>0thensetquotaid(nb-1)letincrquotaid=letnb=getquotaidinletmaxent=maxent_of_domainidinifnb>=maxentthenraiseLimit_reached;setquotaid(nb+1)letunionquotadiff=Hashtbl.iter(funidnb->setquotaid(getquotaid+nb))diff.curletmergeorig_quotamod_quotadest_quota=Hashtbl.iter(funidnb->letdiff=nb-(getorig_quotaid)inifdiff<>0thensetdest_quotaid((getdest_quotaid)+diff))mod_quota.cur