Re: [Exim] 3.36 -> 4.x upgrade.. [For the ARCHIVES]

Top Page
Delete this message
Reply to this message
Author: ODHIAMBO G. Washington
Date:  
To: exim-users
CC: wakko, Nigel.Metheringham
Old-Topics: Re: [Exim] 3.36 -> 4.x upgrade...
Subject: Re: [Exim] 3.36 -> 4.x upgrade.. [For the ARCHIVES]
* Wakko Warner <wakko@???> [20030520 03:26]: wrote:
> > Okay, hit me with the duh stick if this is already something that's been
> > asked... Is there a comprehensive 3.36 -> 4.x upgrade howto? I know I can't
> > just drop in my old /etc/exim.conf and expect it to work.
>
> Try reading the spec.txt and using convert4r4. It may or may not product an
> equivilant config for 4.x to use. But You can use that as a guide. I did,
> but threw it away in favor of configureing the entire thing by hand.



Since this question has been asked many times, I'll take leave to give an
answer once and for all.

When Philip released Exim-3.59, these are the notes that he gave about
upgrade from Exim-3.x to the new Exim-4.x:


Perhaps Nigel should prominently put the document that was named Exim4.Upgrade
somewhere on the website?? I believe it's wrong for me to send that document
in-line to a mailing list because of bandwidth considerations.





##########################################################################

Upgrading Exim from Release 3.33 to 4.xx
----------------------------------------

Exim 4.00 represents the largest upheaval in Exim's history. There are a lot of
changes to the way some parts of Exim work, and a lot of incompatible changes
to the runtime configuration file.

This document is in two parts. The first part contains instructions and
suggestions for how you might go about performing the upgrade. The second part
is a brief list of all the changes that have taken place. For full details of
all the new features, please consult the reference manual.


HOW TO UPGRADE YOUR EXIM
------------------------

When you compile Exim 4, a Perl script called convert4r4 is built in the build
directory. It is not installed by the install script, because it is likely that
you will run it only once.

This script is provided to assist in updating Exim configuration files. It
reads an Exim 3 configuration file on the standard input, writes a modified
file on the standard output. It also writes comments about what it has done to
the standard error file. It assumes that the input is a valid Exim 3
configuration file. A typical call to the conversion script might be

./convert4r4 </etc/exim/configure >/etc/exim/configure.new

The output file should be checked and tested before trying to use it. Each
option change is preceded by an identifying comment. In fact, the conversion
script tends to make quite a mess of your configuration, and you should expect
to go through it afterwards and tidy it up by hand.

Unless you are running a very straightforward configuration, the automatic
conversion is likely to generate a non-optimal configuration. You should not
only check it thoroughly, but also run as many tests as you can, to ensure that
it is working as you expect. In particular, you should test address routing,
using -bt and -bv, and the policy controls, using -bh. If possible, you should
also do some live tests (i.e. send and receive some messages) before putting
Exim 4 into service.

If you have a very complicated configuration, it is possible that convert4r4
will break it in some situations, which is why thorough testing is strongly
recommended. You Have Been Warned.

One way of upgrading Exim from a pre-4.00 release is as follows:

1. Suppose your configuration file is called /usr/exim/configure, and you want
to continue with this name after upgrading. The first thing to do is to make
another copy of this file called, say, /usr/exim/configure.pre-4.00.

2. Rebuild your existing Exim to use the copy of the configuration file instead
of the standard file. Install this version of Exim under a special name such
as exim-3.33, and point a symbolic link called "exim" at it. Then HUP your
daemon. You can check on the name of the configuration file by running

exim -bP configure_file

Ensure that everything is running smoothly. You now have something you can
fall back to.

3. Build the new release, configured to use the standard configuration file.

4. Use the convert4r4 utility to upgrade your configuration file for the new
release. After running it, check the file by hand, and tidy it up.

5. Test, test, test!

6. You can run complete tests, including actual deliveries, from an uninstalled
binary, but you have to tell it where it is, so that any re-executions can
be done. You can do this by temporarily inserting a setting such as

exim_path = /source/exim/exim-4.00/build-SunOS5-5.8-sparc/exim

into the runtime configuration. If you want to, you can also insert settings
for spool_directory and log_file_path to divert those away from their normal
places. Remember to remove these temporary settings when you eventually
install the binary!

7. The new installation script installs the new release as exim-4.00, and
set a symbolic link called "exim" to point to it.

8. You can now easily change between the new and old releases simply by moving
the symbolic link and HUPping your daemon. The format of message files on
Exim's spool has _not_ changed, so there should be no problem in changing
between releases while there are messages on the queue.


WHAT HAS NOT CHANGED IN EXIM 4.00
---------------------------------

The basic overall philosophy, design, and process structure has not changed.
The format of spool files is the same. The transports have had only minor
modifications. The command line options remain the same, with a couple of
additions.

The general configuration approach has not changed, but the actual details of
the configuration file are different.

The Exim monitor has not changed, and there have been only very minor changes
to other Exim utilities.


WHAT HAS CHANGED IN EXIM 4.00
-----------------------------

The rest of this document lists the very many changes that have taken place.
I'm going to give only brief details here, because this part of the document is
intended as a way of alerting you to areas of difference. The reference manual
describes how the new features work in detail.


Named domain, host, address, and local part lists
-------------------------------------------------

A new feature makes it possible to give names to lists of domains, hosts,
addresses, and local parts. The syntax used is

domainlist <name> = <a domain list>
hostlist <name> = <a host list>
addresslist <name> = <an address list>
localpartlist <name> = <a list of local parts>

For example:

domainlist local_domains = *.my.domain
addresslist bad_senders = cdb;/etc/badsenders

These lists are referenced in options by giving the name preceded by a + sign.
For example, in a router you might have

domains = +local_domains

At first sight, these lists might seem to be the same as macros, but they are
not. Macros are just textual substitutions. If you write

ALIST = host1 : host2
auth_advertise_hosts = !ALIST

it probably won't do what you want, because that is exactly the same as

auth_advertise_hosts = !host1 : host2

Notice that the second host name is not negated. However, if you use a host
list, and write

hostlist alist = host1 : host2
auth_advertise_hosts = ! +alist

the negation applies to the whole list, and so that is equivalent to

auth_advertise_hosts = !host1 : !host2

These named lists also have a performance advantage. When Exim is routing an
address or checking an incoming message, it caches the result of tests on the
lists. So, if you have a setting such as

domains = +local_domains

on several of your routers, the actual test is done only for the first one.
However, this caching works only if there are no expansions within the list
itself. In other words, caching happens only if the list is known to be the
same each time it is referenced.

By default, there may be up to 16 named lists of each type. This limit can be
extended by changing a compile-time variable.

The use of domain and host lists is recommended for concepts such as local
domains, relay domains, and relay hosts. The default configuration is set up
like this.


Processing of domain, host, local part, and address lists
---------------------------------------------------------

The handling of these lists is now more uniform. Every list is expanded as a
single string before it is used. (In Exim 3, some options were expanded and
some weren't, and query-style lookup items were then re-expanded.)

If an expansion is forced to fail, Exim behaves as if the item has not been
found in the list.

The confusing $key variable has been abolished. When processing a domain list,
$domain contains the relevant domain and can be used in generating database
queries. Other appropriate variables are set when processing other kinds of
list; $sender_host and $sender_host_address for checking incoming hosts and
$host and $host_address for checking outgoing hosts.

Note that this means that any \ and $ characters in regular expressions must be
escaped if they appear in one of these lists. The new expansion feature to turn
off expansion (\N ... \N) which is described below can be helpful here.

The details of the processing of address lists has been revised.

If an item in a host list is the empty string, it matches only when no host is
defined. For example, if used when checking an incoming message, it matches
only when the message is arriving by SMTP on the standard input from a local
process (using -bs).


Merge of Directors and Routers
------------------------------

There are no longer any directors in Exim 4. There are just routers. All
addresses are passed to a single list of routers which typically makes use of
the "domains" option to choose which way to handle specific groups of domains.

A consequence of this is that the code no longer contains any concept of "local
domains". However, a typical configuration will probably define a named domain
list (see above) called local_domains, and use it to control routing something
like this:

route_remote:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
no_more

system_aliases:
....

The first router does DNS routing for all domains that are not in the named
list of local domains, and no_more ensures that it is the last router for those
domains. All other domains fall through to the system_aliases and subsequent
routers. For a complete configuration example, look at the default
configuration file in src/configure.default.


Router Actions
--------------

The concepts of how the routers work are as follows:

A number or pre-tests are run (details below). If any of them fails, control
is passed to the next router. We say "the router is skipped". Otherwise the
router is run, and can yield one of several different results:

. skip: The pre-conditions for running the router are not met. The address
is passed to the next router.

. accept: The router accepts the address, and either queues it for a transport,
or generates one or more "child" addresses. Processing the original address
ceases, unless "unseen" is set on the router, in which case the address is
passed to the next router. Processing of any child addresses starts with the
first router by default, or at the router defined by redirect_router if it is
set. This may be any router in the list.

. decline: The router declines to accept the address because it does not
recognize it at all. The address is passed to the next router, unless no_more
is set, in which case the address fails.

. pass: The router recognizes the address, but cannot handle it itself. It
requests that the address be passed to another router. This overrides no_more.
By default the address is passed to the next router, but this can be changed by
setting pass_router. However, in this case (unlike redirect_router) the named
router must be below the current router (to avoid loops).

. fail: The router determines that the address should fail, and queues it for
the generation of a bounce message. There is no further processing of the
original address, unless "unseen" is set.

. defer: The router cannot handle the address at the present time. (For
example, a database may be offline.) No further processing of the address
happens in this delivery attempt. It is tried again next time.

. error: There is some error in the router (for example, a syntax error in
its configuration). The action is as for defer.


Router pre-tests
----------------

In Exim 3 there are some strange interactions between the generic options that
test things before running a director or router and the no_more test that
happens afterwards.

In Exim 4 it is all more straightforward. If any fail, the router is skipped
and control passes to the next router. The no_more option has an effect only if
the router is actually run - that is, if all the pre-tests succeed. The order
in which these tests are run is:

verify status, expn status, domains, local_parts, check_local_user

If all those match, the debug_print string is output when debugging. Exim then
goes on to test

senders, require_files, condition

Note that require_files comes near the end of the list, so you cannot use it to
check for the existence of a file in which to lookup up a domain, local part,
or sender. However, as these options are all expanded, you can use the "exists"
expansion condition to make such tests. The require_files option is intended
for checking files that the router may be going to use internally, or which are
needed by a specific transport (e.g. .procmailrc).

In Exim 4, local part prefixes and suffixes are recognized and re