+/*
+ * Data structures for policy management.
+ * Each device can have a policy structure that lists
+ * various name/value pairs each possibly with a metadata associated.
+ * The policy list is sorted by name/value/metadata
+ */
+struct dev_policy {
+ struct dev_policy *next;
+ char *name; /* None of these strings are allocated. They are
+ * all just references to strings which are known
+ * to exist elsewhere.
+ * name and metadata can be compared by address equality.
+ */
+ const char *metadata;
+ char *value;
+};
+
+extern char pol_act[], pol_domain[], pol_metadata[], pol_auto[];
+
+/* iterate over the sublist starting at list, having the same
+ * 'name' as 'list', and matching the given metadata (Where
+ * NULL matches anything
+ */
+#define pol_for_each(item, list, _metadata) \
+ for (item = list; \
+ item && item->name == list->name; \
+ item = item->next) \
+ if (!(!_metadata || !item->metadata || _metadata == item->metadata)) \
+ ; else
+
+/*
+ * policy records read from mdadm are largely just name-value pairs.
+ * The names are constants, not strdupped
+ */
+struct pol_rule {
+ struct pol_rule *next;
+ char *type; /* rule_policy or rule_part */
+ struct rule {
+ struct rule *next;
+ char *name;
+ char *value;
+ char *dups; /* duplicates of 'value' with a partNN appended */
+ } *rule;
+};
+
+extern char rule_policy[], rule_part[];
+extern char rule_path[], rule_type[];
+extern char type_part[], type_disk[];
+
+extern void policyline(char *line, char *type);
+extern void policy_add(char *type, ...);
+extern void policy_free(void);
+
+extern struct dev_policy *path_policy(char *path, char *type);
+extern struct dev_policy *disk_policy(struct mdinfo *disk);
+extern struct dev_policy *devnum_policy(int dev);
+extern void dev_policy_free(struct dev_policy *p);
+
+extern void pol_new(struct dev_policy **pol, char *name, char *val, char *metadata);
+extern struct dev_policy *pol_find(struct dev_policy *pol, char *name);
+
+enum policy_action {
+ act_default,
+ act_include,
+ act_re_add,
+ act_spare,
+ act_force_spare,
+ act_err
+};
+
+extern int policy_action_allows(struct dev_policy *plist, const char *metadata,
+ enum policy_action want);
+extern int disk_action_allows(struct mdinfo *disk, const char *metadata,
+ enum policy_action want);
+
+struct domainlist {
+ struct domainlist *next;
+ char *dom;
+};
+
+extern int domain_test(struct domainlist *dom, struct dev_policy *pol,
+ const char *metadata);
+extern struct domainlist *domain_from_array(struct mdinfo *mdi,
+ const char *metadata);
+extern void domain_free(struct domainlist *dl);
+extern void domain_merge(struct domainlist **domp, struct dev_policy *pol,
+ const char *metadata);
+