Logical data structure
(taken from [ ../Protocol-2008-09-03 ]) * as a directory can use no more than one policy, it appears sensible to allow creating "meta policies" from existing ones
- possible grammars
- a very simple way would be
- Policy
Rule Rule ...
- Rule
Simple_Rule | PolicyID
- Simple_Rule
Predicate Predicate ... Verdict
- Verdict
NoOSD | SimpleFile | StripingRules
- StripingRules
NumStripes StripeSize NumCopies
- in this model, the first rule with all predicates being matched by a given file will apply, return its verdict and evaluation ends
- a very simple way would be
- an alternative implementation of the above grammar could be: Don't ever abort evaluation. Each matching rule will override the previous verdict. Thus, later rules have priority.
- a combination of the two ideas would require an enhanced grammar:
- Rule
Predicate Predicate ... Verdict ContinueOption
- ContinueOption
AbortIfMatched | AbortAlways | Continue
this would allow to specify wether the volume global policy should be used as a fallback. That's the only conceivable use of the "AbortAlways" tag.
update: still makes no sense, as an "AbortAlways" rule can be embedded as a "AbortIfMatched" rule without any predicates. Thus:
- ContinueOption
AbortIfMatched | Continue
implementation: this will hopefully translate to policies like "if <..> do x, otherwise if <..> do y, however if <..> do z, otherwise do default"
Implementation
- unions are a fine way to stuff the different possible types of predicates into one value
- they complicate the generated data structures, however
- also, to have more than value in one union branch, a structure needs to be created
- that's no design problem in itself, but code readability suffers
- therefore, neither rule nor verdict are unions
- instead, the verdict is a bitmap containing
- OSD usage yes/no
- striping options (#stripes, stripe-size, #copies)
- continue flag (actually, a stop-flag)
to work around an extraneous struct access (as in policy.rules[0].rule_u.simple_rule.predicates vs policy.rules[0].predicates) the rule struct holds all:
- a field for the used policy id (to be 0 in case of a simple rule)
- a pointer to the list of predicates (to be NULL in case of a policy reference)
- an afs_int32 that serves as verdict bitmap (s.a.), unused in case of a policy reference
negative predicates
- didn't want to add actual union cases for these
- couldn't include it as a flag, as predicate is a union and can have only one field per case
didn't want to introduce an extraneous struct level (policy.rule[0].predicates[0].pred_struct.predicate_u.min_size == madness)
versus: policy.rule[0].predicates[0].predicate_u.min_size == oh_well_you_know
- solution
introduced artificial predicate types for negated predicates (e.g. POLICY_MIN_SIZE => POLICY_MIN_SIZE_NOT)
- invariant: ( PREDTYPE_NOT == PREDTYPE | 1 )
if the negated types are used, the union content is void, will use the regular fields regardless (e.g. min_size)
- hope marshalling will work regardless
if marshalling does not work the union fields will have to be doubled as well
- the same coding techniques should still work (masking the LSB and using the regular union field then)
will hopefully add overhead in osddb.xg only