The Am-utils cookbook Prepared for Debian GNU/Linux by Philippe Troin * 0. Foreword This cookbook is not intended to be an automounter or amd primer. You should know some automounter concepts and know a few things about amd. * 1. Preparing maps ** 1.1 A simple map A mount map is associated to every amd-managed mount point. This map contains a set of key value pairs. Typically, mount maps are used for home directories. For example, consider this simple map (/tmp/samplemap1): foo fstype:=nfs;rhost:=server1;rfs:=/p1/foo;opts:=rsize=8192,wsize=8192 bar fstype:=nfs;rhost:=server1;rfs:=/p1/bar;opts:=rsize=8192,wsize=8192 baz fstype:=nfs;rhost:=server2;rfs:=/p2/baz;opts:=rsize=8192,wsize=8192;\ noac assuming that server1 exports /p1, and server2 exports /p2. One would use this map with amd on /home with: amd /home /tmp/samplemap1 Then every access to /home1/foo will mount /p1/foo "somewhere" (under /amd/server1/p1/foo with Debian), and /home1/foo will be a symlink to this location. Similarly for bar and baz. For every key, we specify: - the mount filesystem type, here nfs (fstype:=nfs); - which host to mount from (host:=); - which filesystem to mount (rfs:=); - and the mount options (opts:=). Note that amd so-called "selectors" are specified with := and are separated by semicolons. You can split a logical line into two physical lines by using a backslash just before the newline (no whitespace is allowed between the backslash and the newline). This map can be improved several ways... ** 1.2 Avoiding duplication You'll notice that the `fstype' selector is the same for all the keys. Similarly, most of the options are the same. Amd uses the `/defaults' key to specify defaults. We will put the fstype selector and the common options there. We will use addopts to "add options" without overwriting what was specified in /defaults: /defaults fstype:=nfs;opts:=rsize=8192,wsize=8192 foo rhost:=server1;rfs:=/p1/foo bar rhost:=server1;rfs:=/p1/bar baz rhost:=server2;rfs:=/p2/baz;addopts:=noac ** 1.3 Avoiding multiple mounts of the same filesystem If /home/foo and /home/bar are used at the same time, the /p1 filesystem from server1 will be mounted twice (assuming /p1/foo and /p1/bar reside on the same filesystem on server1). This is generally not a problem until you have a lot of keys, yet it is quite a waste (of kernel superblocks that is). Amd can be told that several keys use the same remote filesystem and use different directories inside this filesystem. The remote filesystem will then be mounted only once. An improved mount map would be: /defaults fstype:=nfs;opts:=rsize=8192,wsize=8192 foo rhost:=server1;rfs:=/p1;sublink=foo bar rhost:=server1;rfs:=/p1;sublink=bar baz rhost:=server2;rfs:=/p2/baz;addopts:=noac With this map, accessing either foo or bar would mount server1:/p1 under /amd/server1/p1, and foo would point to /amd/server1/p1/foo while bar would point to /amd/server1/p1/bar. ** 1.4 Avoiding duplicated lines Now the foo and bar keys are very similar... We can use amd to do the following: If the key is foo or bar, then mount /p1 from server1 and use the key as a sublink with this map: ^/defaults$ fstype:=nfs;opts:=rsize=8192,wsize=8192 ^(foo|bar)$ rhost:=server1;rfs:=/p1;sublink=${key} ^baz$ rhost:=server2;rfs:=/p2/baz;addopts:=noac Here we're using egrep-style regular expressions as keys. Amd does not use these kind of maps by default, and we must use the cache option to enable this feature by starting it with: amd /home /tmp/samplemap1 -cache:=regexp Also note that we provided the ^ and $ anchors for every key, otherwise `abarman' would match the regular expression `bar'. ** 1.5 Using one mount map with multiple OSes Amd can make some simple decisions when mounting a filesystem. A lot of selectors can be used for that purpose: os, cluster, architecture, etc... You can use this feature by using the `==' and `!=' tests. Let's say we want baz to be mounted from server2 if the os is linux and from server3 otherwise: ^/defaults$ fstype:=nfs;opts:=rsize=8192,wsize=8192 ^(foo|bar)$ rhost:=server1;rfs:=/p1;sublink=${key} ^baz$ os==linux;rhost:=server2;rfs:=/p2/baz;addopts:=noac \ os!=linux;rhost:=server3;rfs:=/p2/baz;addopts:=noac A note about continuation lines and spacing: When parsing a map, amd considers all whitespace-delimited strings to be a single group (as an exception, whitespace at the beginning of a line is considered as an empty string). Amd then evaluates the `==' and `!=' selectors in groups sequentially, and the first matching group is used. That's why we separate the two clause (os==linux and os!=linux) by a space at the end of the line before the backslash. ** 1.6 Removing more duplication The map in 1.5 can still be improved by grouping the common parts of the `os==linux' and `os!=linux' stances: ^/defaults$ fstype:=nfs;opts:=rsize=8192,wsize=8192 ^(foo|bar)$ rhost:=server1;rfs:=/p1;sublink=${key} ^baz$ -rfs:=/p2/baz;addopts:=noac \ os==linux;rhost:=server2 \ os!=linux;rhost:=server3 A (whitespace-delimited) `group' starting with a dash will cause amd not to stop processing the groups, but to evaluate all the selectors (rfs and addopts) and to go on trying to find a group that matches all the selectors. This map is strictly equivalent to the 1.5 map, but it's nicer because no information is duplicated. ** 1.7 Using the automounter on server and clients at the same time The previous examples assumed the mount maps were used on various clients, but not on the machines exporting the filesystems themselves (server1, server2 and server3). In order to do this, we will use the `fs' selector and the nfsl filesystem type. The nfsl filesystem type means: - if ${rhost} is myself, then use a link (equivalent to fstype:=link). The target of the link is read from ${fs}. - otherwise, use nfs (equivalent to fstype:=nfs) The `fs' selector is used to specify: - the location the filesystem is mounted on (instead of the default /amd/${rhost}/${rfs} location) when fstype is nfs; - the location to point to when fstype is link. We will also make sure that both clients and servers will actually mount the filesystem on the same location. We assume that server1 mounts the local disk to be exported on /amd/p1, server2 on /amd/p2 and server3 on /amd/p2. Here's the map: ^/defaults$ fstype:=nfsl;opts:=rsize=8192,wsize=8192 ^(foo|bar)$ rhost:=server1;fs:=/amd/p1;rfs:=${fs};sublink=${key} ^baz$ -fs:=/amd/p2/baz;rfs:=${fs};addopts:=noac \ os==linux;rhost:=server2 \ os!=linux;rhost:=server3 With this map, a user can be logged on a NFS server or client, yet the filesystems mount points will be exactly the same. * 2. The master map ** 2.1 Map propagation In the section 1 of this cookbook, we used files to specify automount maps. Amd can also use NIS maps. When using NIS maps, use a map name instead of a file name when starting amd: amd /home /tmp/somemap vs. amd /home somemap On Debian systems, you will have to edit /var/yp/Makefile to be able to generate the NIS maps from the maps text files. ** 2.2 What's the master map ? The arguments passed to amd at startup is called the master map. The master map can be a simple "flat" list of (, , ) triples or can be propagated via NIS. Propagating the master map by NIS allows controlling all the automounting mechanisms from a central server. In the rest of the section 2, we will focus on different styles of NIS master map. Using a "flat" list of mount points and maps is not as flexible. ** 2.3 Master map styles The Debian am-utils package supports three different types of NIS master maps (but the startup script can be customized to fit your fancy requirements), named after what is the function of the master map's key: - configuration - one-key - mount-point *** 2.3.1 Master map where the key is the configuration This is the most flexible setup: every client knows in what configuration amd should be ran. The configuration is the master map's key, and the value contains a list of (, , ) triples. The configuration key can represent the computer's function, and/or the operating system to run for example: linux-dev /home amd.home -cache:=regexp /software amd.software-linux linux-prod /software amd.software-linux freebsd-dev /home amd.home -cache:=regexp /software amd.software-fbsd Every client is configured to know whether it's: - a linux development machine (the mount point /home uses the amd.home map and the mount point /software uses the amd.software-linux map); - a linux production machine (only the mount point /software using the amd.software-linux map is configured); - a freebsd development machine (the mount point /home uses the amd.home map (same as linux-dev), and the mount point /software uses the amd.software-fbsd map). If you pick this master map style (`config') while configuring amd, amd will be started like this: amd `ypmatch ` *** 2.3.2 Master map with one single key It is a degenerate case of 2.3.1 where only one configuration is used. In this case, we don't even have to know the configuration key. Here's such a map: whatever /home amd.home -cache:=regexp /software amd.software-linux If you pick this master map style (`onekey') while configuring amd, amd will be started like this: amd `ypcat ` *** 2.3.3 Master map where the key is the mount point Every map entry has the mount point as the key and the mount map and eventually the options as the value: /home amd.home -cache:=regexp /software amd.software-linux If you pick this master map style (`mountpoint') while configuring amd, amd will be started like this: amd `ypcat -k `