[[TableOfContents]] = 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 | 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`