Each Wednesday Why article will discuss a configuration approach or packaging option used in Fedora packages.
Sometimes two or more Fedora package exist that serve the same purpose. The alternatives system provides a mechanism for selecting an active default application from several valid alternatives.
Alternatives works by creating symbolic links from a generic program name to the alternatives directory (/sbin/alternatives) and then from that directory to the desired file. The same approach is used to switch between manpages.
Here's an example: sendmail and postfix both provide mail transfer agent (MTA) capability -- they can send and receive SMTP mail. For various (and sometimes deeply-held) reasons, some administrators prefer one package, and some prefer the other. Both of these packages require the presence of the alternatives system (in the form of the utility /usr/sbin/alternatives):
# rpm -q --requires sendmail | grep alternatives
/usr/sbin/alternatives
# rpm -q --requires postfix | grep alternatives
/usr/sbin/alternatives
The command name /usr/sbin/sendmail is hard-coded into many scripts, and there's a sendmail and a postfix version of that program. The pathname /usr/sbin/sendmail is actually a symbolic link to /etc/alternatives/mta:
# ls -l /usr/sbin/sendmail
lrwxrwxrwx 1 root root 21 Dec 20 00:25 /usr/sbin/sendmail -> /etc/alternatives/mta
/etc/alternatives/mta is then symbolically linked to one of the two sendmail programs -- either /usr/sbin/sendmail.sendmail or /usr/sbin/sendmail.postfix, depending on the system administrator's preference. On this particular system, the link goes to /usr/sbin/sendmail.sendmail:
# ls -l /etc/alternatives/mta
lrwxrwxrwx 1 root root 27 Mar 13 22:52 /etc/alternatives/mta -> /usr/sbin/sendmail.sendmail
At first glance, it looks like you could switch to postfix simply by deleting the symlink and creating a new one pointing to /usr/sbin/sendmail.postfix. However, the /usr/sbin/sendmail program is just one of many files that comprise the MTA facility; others include utilities such as newaliases and mailq, the manpages, and the init scripts to start the MTA when the system boots. To simplify this process of switching between the two packages, Fedora provides the alternatives command.
When the postfix package is installed, this command is executed by the installation script within the RPM package:
/usr/sbin/alternatives --install /usr/sbin/sendmail mta /usr/sbin/sendmail.postfix 30 \
--slave /usr/bin/mailq mta-mailq /usr/bin/mailq.postfix \
--slave /usr/bin/newaliases mta-newaliases /usr/bin/newaliases.postfix \
--slave /etc/pam.d/smtp mta-pam /etc/pam.d/smtp.postfix \
--slave /usr/bin/rmail mta-rmail /usr/bin/rmail.postfix \
--slave /usr/lib/sendmail mta-sendmail /usr/lib/sendmail.postfix \
--slave /usr/share/man/man1/mailq.1.gz mta-mailqman /usr/share/man/man1/mailq.postfix.1.gz \
--slave /usr/share/man/man1/newaliases.1.gz mta-newaliasesman /usr/share/man/man1/newaliases.postfix.1.gz \
--slave /usr/share/man/man8/sendmail.8.gz mta-sendmailman /usr/share/man/man1/sendmail.postfix.1.gz \
--slave /usr/share/man/man5/aliases.5.gz mta-aliasesman /usr/share/man/man5/aliases.postfix.5.gz \
--initscript postfix
When sendmail is installed, this command is executed:
/usr/sbin/alternatives --install /usr/sbin/sendmail mta /usr/sbin/sendmail.sendmail 90 \
--slave /usr/bin/mailq mta-mailq /usr/bin/mailq.sendmail \
--slave /usr/bin/newaliases mta-newaliases /usr/bin/newaliases.sendmail \
--slave /usr/bin/rmail mta-rmail /usr/bin/rmail.sendmail \
--slave /usr/lib/sendmail mta-sendmail /usr/lib/sendmail.sendmail \
--slave /etc/pam.d/smtp mta-pam /etc/pam.d/smtp.sendmail \
--slave /usr/share/man/man8/sendmail.8.gz mta-sendmailman /usr/share/man/man8/sendmail.sendmail.8.gz \
--slave /usr/share/man/man1/mailq.1.gz mta-mailqman /usr/share/man/man1/mailq.sendmail.1.gz \
--slave /usr/share/man/man1/newaliases.1.gz mta-newaliasesman /usr/share/man/man1/newaliases.sendmail.1.gz \
--slave /usr/share/man/man5/aliases.5.gz mta-aliasesman /usr/share/man/man5/aliases.sendmail.5.gz \
--initscript sendmail
These commands set up the two alternatives, identifying the generic name, the main file that will be symlinked when this alternative is selected, the priority of this alternative, other files that also need to be symlinked when this alternative is selected, and any init script that also needs to be managed (via chkconfig).
To select one of these two packages interactively, the alternatives command is used with the --config option and the generic name of the feature that is being configured:
# alternatives --config mta
There are 2 programs which provide 'mta'.
Selection Command
-----------------------------------------------
*+ 1 /usr/sbin/sendmail.sendmail
2 /usr/sbin/sendmail.postfix
Enter to keep the current selection[+], or type selection number:
Note that the highest-priority alternative is marked with an astrisk (*), and the currently-selected option is marked with a plus-sign (+). Press enter to keep the current setting or enter a number to select another value.
To select an alternative directly from the command line, use the --set option:
# alternatives --set mta /usr/sbin/sendmail.postfix
You can see the current value by using the --display option:
# alternatives --display mta
mta - status is manual.
link currently points to /usr/sbin/sendmail.sendmail
/usr/sbin/sendmail.sendmail - priority 90
slave mta-pam: /etc/pam.d/smtp.sendmail
slave mta-mailq: /usr/bin/mailq.sendmail
slave mta-newaliases: /usr/bin/newaliases.sendmail
slave mta-rmail: /usr/bin/rmail.sendmail
slave mta-sendmail: /usr/lib/sendmail.sendmail
slave mta-mailqman: /usr/share/man/man1/mailq.sendmail.1.gz
slave mta-newaliasesman: /usr/share/man/man1/newaliases.sendmail.1.gz
slave mta-aliasesman: /usr/share/man/man5/aliases.sendmail.5.gz
slave mta-sendmailman: /usr/share/man/man8/sendmail.sendmail.8.gz
/usr/sbin/sendmail.postfix - priority 30
slave mta-pam: /etc/pam.d/smtp.postfix
slave mta-mailq: /usr/bin/mailq.postfix
slave mta-newaliases: /usr/bin/newaliases.postfix
slave mta-rmail: /usr/bin/rmail.postfix
slave mta-sendmail: /usr/lib/sendmail.postfix
slave mta-mailqman: /usr/share/man/man1/mailq.postfix.1.gz
slave mta-newaliasesman: /usr/share/man/man1/newaliases.postfix.1.gz
slave mta-aliasesman: /usr/share/man/man5/aliases.postfix.5.gz
slave mta-sendmailman: /usr/share/man/man1/sendmail.postfix.1.gz
Current `best' version is /usr/sbin/sendmail.sendmail.
Instead of selecting the alternative manually, you can choose to have the highest-priority option automatically selected. This will enable an automatic change as packages are added and removed:
# alternatives --auto mta
The most common use of the alternatives system is to select between implementations of Java, the print server, and the mail transfer agent. Fedora's implementation of alternatives is a rewrite and extension of the alternatives system used in Debian.
(Why is the generic name linked to a name in /etc/alternatives which is symlinked to the target, instead of the generic name being directly symlinked to the target? This was done so that the configuration information is contained in the /etc directory, centralizing the location of configuration data).