3.7 Preprocessing with m4

In the previous section we have seen how to define two servers which use the same expression to compute relative load. In real configurations, the number of servers is likely to be considerably greater than that, and adding each of them to the configuration soon becomes a tedious and error-prone task. This task is greatly simplified by the use of preprocessor. As mentioned earlier, the configuration file is preprocessed using m4, a traditional UNIX macro processor. It provides a powerful framework for implementing complex slb configurations.

For example, note that in our sample configuration the ‘server’ statements differ by only three values: the server ID, its IP and community. Taking this into account, we may define the following m4 macro:

 
m4_define(`defsrv',`server $1 {
  host $2;
  community "m4_ifelse(`$3',,`public',`$3')";
  variable out "IF-MIB::ifOutOctets.3";
  variable la1 "UCD-SNMP-MIB::laLoadFloat.1";
  constant k 2.5;
  constant m 2.2;
}')

The ‘defsrv’ macro takes two mandatory and one optional argument. Mandatory arguments are the server ID and its IP address. Optional argument is SNMP community; if it is absent, the default community ‘public’ is used.

Notice, that we use m4_define, instead of the familiar define. It is because the default slb setup renames all m4 built-in macro names so they all start with the prefix ‘m4_’. This avoids possible name clashes and makes preprocessor statements clearly visible in the configuration.

Using this new macro, the above configuration is reduced to the following two lines:

 
defsrv(srv01, 192.168.10.6)
defsrv(srv02, 192.168.10.1, private)

Declaring a new server is now a matter of adding a single line of text.

The default preprocessor setup defines a set of useful macros, among them m4_foreach (see (m4)Improved foreach section `foreach' in GNU M4 macro processor). This macro can be used to further simplify the configuration, as shown in the example below:

 
m4_foreach(args,
 ``srv01, 192.168.10.6',
  `srv02, 192.168.10.1, private',
  `srv03, 192.168.0.3',
  `srv04, 192.168.100.1, foo',
  `srv05, 192.168.100.2, bar'',
 `defserv(args)
')

The second argument to m4_foreach is a comma-separated list of values. The expansion is as follows: for each value from this list, the value is assigned to the first argument (‘args’). Then the third argument is expanded and the result is appended to the overall expansion.

In this particular example, each line produces an expansion of the ‘defserv’ macro with the arguments taken from that line. Note, that each argument in the list must be quoted, because it contains commas. Note also the use of the optional third arguments to supply community names that differ from the default one.

For a detailed information about slb preprocessor feature, see Preprocessor.