4168
Comment: added some thoughts on don't care behaviour
|
4169
converted to 1.6 markup
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
[[TableOfContents]] | <<TableOfContents>> |
Line 5: | Line 5: |
(taken from [:../Protocol-2008-09-03:meeting protocol]) | (taken from [[../Protocol-2008-09-03|meeting protocol]]) |
Logical data structure
(taken from meeting protocol) * 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)
- to enable correct un/marshalling, bogus union fields have to be added as well, but we won't need to use them in code
On "don't care" values
- it was clear to me very soon that policy rules must be capable of specifying "don't care" for
- stripes
- stripe-size
- copies
so far, the usd_osd field used to be yes/no, with no don't-care possible
- this isn't desirable in all cases though
- these things would be impossible as is:
- create a policy that uses striping in case OSD is used at all (e.g. by the default by-size behaviour), currently a striping rule implicitly enables OSD use
- conclusion
- it would be neat to have don't-care values for the OSD flag as well
- there are more than two different values then
- there shall be one bit each for OSD use and local disk (i.e. fileserver) use, and they cannot be both set
- setting neither has a don't-care semantics