<> = Usage Instructions = See AfsOsd/UsageInstructions. = Logical data structure = (taken from [[../Protocol-2008-09-03|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 | Simple``File | ''Striping``Rules'' StripingRules:: Num``Stripes Stripe``Size Num``Copies * in this model, the first rule with all predicates being matched by a given file will apply, return its verdict and evaluation ends * 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'' ''Continue``Option'' ContinueOption:: Abort``If``Matched | Abort``Always | 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 "Abort``Always" tag. * update: still makes no sense, as an "Abort``Always" rule can be embedded as a "Abort``If``Matched" rule without any predicates. Thus: ContinueOption:: Abort``If``Matched | 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