itself. The "filter" directive is only supported by filters registering a
keyword with flt_register_keywords() (see section 3.2.2).
-The list of available filter classes is reported by 'haproxy -vv' :
+The list of available filter classes is reported by 'haproxy -vv'. It contains
+the built-in classes and the ones other modules register from the STG_REGISTER
+stage (see section 3.2) :
$> haproxy -vv
HAProxy version 1.7-dev2-3a1d4a-33 2016/03/21
return -1;
return 0;
}
- INITCALL1(STG_INIT, my_filter_register_class);
+ INITCALL0(STG_REGISTER, my_filter_register_class);
filter_place_class() accepts the three sides, FLT_SIDE_GLOBAL, FLT_SIDE_REQ
and FLT_SIDE_RES, and may be called once per side :
evaluation order of the instances of the class relative to the other classes,
which may then be refined per proxy with "filter-sequence" (section 2.2).
-WARNING : filter_register_class() must be called after the built-in classes
- were initialized, so from an initcall of the STG_INIT stage or a later
- one. Otherwise the class registration fails.
+WARNING : filter_register_class() and filter_place_class() must be called after
+ the built-in classes were initialized at the STG_PREPARE stage. Call
+ them from an STG_REGISTER initcall. From STG_PREPARE, the result
+ depends on the link order, and an addon is linked first, so its
+ registration always fails. 'haproxy -vv' is handled right after the
+ STG_REGISTER stage and only lists the classes registered so far. A
+ class registered from a later stage still works and is listed by the
+ "show filter classes" CLI command, but not by 'haproxy -vv'.
Then the filter internal configuration must be defined. For instance :
directive uses the keyword name.
2. Register the class and place it on each side it supports, relative to an
- already placed class. For a filter maintained out of the HAProxy tree,
- use the public API from an initcall, because the registration must happen
- after the built-in classes were initialized :
+ already placed class. For a filter maintained out of the HAProxy tree, use
+ the public API from an STG_REGISTER initcall. The built-in classes are
+ initialized before this stage, and 'haproxy -vv' only lists the classes
+ registered by its end (see section 3.2) :
static int my_filter_register_class(void)
{
return -1;
return 0;
}
- INITCALL1(STG_INIT, my_filter_register_class);
+ INITCALL0(STG_REGISTER, my_filter_register_class);
filter_register_class_full() registers the class and places it at the
same position on both sides in a single call, which is enough for most
only drives the side-independent operations (configuration checks,
initialization and destruction).
- * A class must be registered after the built-in classes were initialized,
- from a STG_INIT initcall or a later stage, otherwise the registration
- fails. For a filter inside the HAProxy tree, the class is registered in
- filter_init_classes() to explicitly define its default order with the
- other internal classes.
+ * A class must be registered after the built-in classes were initialized, from
+ a STG_REGISTER initcall. From STG_PREPARE, the registration fails or
+ succeeds depending on the link order. A class registered after STG_REGISTER
+ works, but 'haproxy -vv' does not list it. For a filter inside the HAProxy
+ tree, the class is registered in filter_init_classes() to explicitly define
+ its default order with the other internal classes.
* The instance id is optional for a class that does not set
FLT_CLS_FL_MULTI: the parse callback may receive a NULL 'inst->id'. A
* not support the "filter-config" directive). The class is initialized and
* added to the global registry of the known classes, and appended at the end
* of the global order. It is not usable on any channel side until placed with
- * filter_place_class(). Must be called after filter_init_classes().
+ * filter_place_class(). Must be called after filter_init_classes(), which
+ * runs at the prepare stage: a class registered from the register stage on
+ * is added in time for "haproxy -vv" to list it, a class registered later
+ * is reported by the CLI alone.
* Returns 0 on success, -1 on error (too early call, duplicate name).
*/
int filter_register_class(struct filter_class *cls, const char *name,
/* Init function responsible to initialize all intenral filter classes and to
* insert them is global list above. The default evaluation order of all
- * internal filters is defined in this function.
+ * internal filters is defined in this function. It runs from the prepare stage
+ * so that a class registered by another module from the register stage is
+ * initialized in time: "haproxy -vv" reports the available filter classes from
+ * the argument parsing, which happens between the two.
*
* Exemple to register a new filter class:
*
* return -1;
* return 0;
* }
- * INITCALL1(STG_INIT, myfilter_register_class);
+ * INITCALL1(STG_REGISTER, myfilter_register_class);
*/
static void filter_init_classes(void)
{
REGISTER_PER_THREAD_INIT(flt_init_all_per_thread);
REGISTER_PER_THREAD_DEINIT(flt_deinit_all_per_thread);
-INITCALL0(STG_REGISTER, filter_init_classes);
+INITCALL0(STG_PREPARE, filter_init_classes);
/*
* Local variables: