Transname version 1.9 (C) 1997 Thomas Schoebel-Theuer transname enables diskless clients, X-terminals etc to mount the *root filesystem* of the server. This make administration of large pools a lot easier. Wherefore is linux-2.0.21-transname.patch? Currently different diskless clients must have their root / on different directories on the server, beause each client has _some_ different configuration files. However, most files (typically about 99%) have the same contents on the clients and on the server, but have to be replicated (and maintained separately) just because of the 1% differences. This duplication causes very large efforts in practise, since at least the /etc directory has to be duplicated for every client. Even in /etc many files are identical, for example sendmail.cf, initrc scripts and others. Maintaining a large pool means to ensure coherence amoung the duplicates. Classical methods like symlinks are unconvenient for this task because they have to be valid in the view of mounted filesystems at all clients, not at the server. Linux transname overcomes this problem by allowing filenames to be context-dependend. For example, if you have a file /etc/config that should differ on the hosts "myserver" and "myclient", you just create two different files named /etc/config#host=myserver# and /etc/config#host=myclient# . On host "myserver", the file /etc/config#host=myserver# will appear as if it were hardlinked to file /etc/config (without the #...=...# suffix). On host "myclient", the corresponding other file will appear as /etc/config. So you can access the right file contents under the _same_ name, depending on which host you are working. A similar concept can be found in elder HP-UX versions, but with so-called "hidden directories" which don't allow contemporary viewing all versions by default. In contrast, transname shows all context-dependent files in the dir listing and they can be edited using the fully qualified name. Transname was developped for and is used at our Linux pool at the University of Stuttgart with good results. Maintainance of the pool is at a minimum, and adding new clients is a child's play. No worry with keeping up mail configurations, newly installed tools, changed /etc/services, /etc/shells, /etc/resolv.conf and many, many others. In contrast to a sophisticated symlink solution, adding a new file to the /etc directory is seen immediately by all clients. An example for the use of linux-2.0-transname.patch: For example, you can make your /etc/fstab context-dependend. If you want to do that, you should create an /etc/fstab#ktype=default# for the server and an /etc/fstab#ktype=diskless# for all clients. This is because your clients may not yet know their own hostname when they attempt to mount the root filesystem. You can compile in the kerneltypes "default" and "diskless" into different kernels for servers and clients. Of course, if your clients boot via bootp and know their names when mounting the root, you can use /etc/fstab#host=myclient# instead. But at least servers booting from disk normally dont know their hostname at root mount time, so you can mix methods and use /etc/fstab#ktype=default# for the server, /etc/fstab#ktype=diskless# for the majority of the clients and /etc/fstab#host=myclient# for some specific client, because translation of #host=...# is given precedence over #ktype=...# by default. This sort of name translation works with any underlying file system and with any inode type (i.e. with directories, symlinks, devices etc), because it is implemented in the VFS layer of the kernel. Currently, five types of default translations are supported: * #host=# depends on the hostname, see "uname -n" * #kname=# works with a hard compiled-in string * #ktype=# works with a hard compiled-in string * #machine=# depends on architecture, see "uname -m" * #system=# currently only supported by Linux, see "uname -s" Others may be added in future. The current translation are displayed at boot time in the kernel messages for easier debugging, and can be retrieved by reading /proc/sys/kernel/nametrans which is a special file containing the currently valid translations. The default translations change whenever the hostname(1) is set or changed. Thus, the hostname is not set (or set to the name "(none)") at boot time before init(8) sets it. So, if you want to use the hostname before that moment, there are three ways: a) set the hostname before via bootp or similar. b) use the compiled-in translations kname and ktype solely. c) set all translations by lilo (or on the boot command line) with kernel parameter nametrans=#host=banana#:#ktype=diskless# , thus overriding and hiding the default (built-in) translations. Note that by supplying the colon-separated list of at most 16 suffixes, you can also use other translation types that are not defined in the default translations. However, you must ensure that the syntax #...=...# is correct. The specified contexts will be tried in the specified order *instead* of the default translations. You can override the default (or parameter-supplied) translations at runtime by executing echo "#host=$HOST#:#ktype=diskless#:#myconfig=something#" > /proc/sys/kernel/nametrans However, after doing this (or setting as kernel parameter) the built-in default translations have no effect any more, thus changing the hostname will not be reflected in the overridden translations. You can switch back to the default translations by executing echo "" > /proc/sys/kernel/nametrans Another drawback is that administration tools currently are not aware of context-dependend files, so you cannot switch between contexts inside one tool session. However, you can simulate administration sessions on the server as if they were running on some client. To do this, you have to set an environment variable NAMETRANS which has to be the *first* environment variable in the list. For example, you can execute 'env - NAMETRANS=#host=mango#:#ktype=diskless# "`env`" command ...' where the command will see the same files as if it had been executed on host "mango" with a "diskless" kernel. To switch off translations entirely, use an empty list, e.g. 'env - NAMETRANS= "`env`" command ...'. Hopefully the creators of administration tools and maintainers of Linux distributions will support changing environments in future, so that maintaining different views will be very easy. Some hints: Archivers like tar, dump, restore should be used with translation switched off, in order to avoid doubled space in archive files and when extracting from them. Also, make sure that nfsd, mountd (and similar ones like samba daemons) run without translation, in order to avoid doubled (or even wrong) translation at the server and at the client. You can automatically force the creation of context-dependent filenames if there exists a template filename like /etc/mtab#host=CREATE#. As soon as a process running on "mango" tries to create a file /etc/mtab, the version /etc/mtab#host=mango# is created instead (which appears in turn as hardlinked to /etc/mtab). Note that if you want to make /etc/fstab context-dependend, you should execute "touch /etc/mtab#host=CREATE#" and "touch /etc/mtab.tmp#host=CREATE#", because mount, umount and others running on different hosts would otherwise try to create one shared /etc/mtab which would result in a clash. Also one should execute "touch /etc/nologin#host=CREATE#" to prevent global side effects from shutdown resp. runlevel. Which files you have to make context-dependent will differ for different needs and different applications. Hopefully some day a standard will cover the most common cases and the mist common Linux distributions. A HOWTO on this subject is in preparation. How to install linux-2.0.21-transname.patch? First of all, keep a backup of your kernel on your disk. Second, keep a floppy with a miniroot handy, so you can boot from the floppy, mount your harddisk root filesystem and change the names of your configuration files back to their old names in case of emergency. Then, make a kernel with transname support enabled. With "make config" or "make xconfig", just go to the section "filesystems". Take a look at the help texts that are associated with the transname options, they tell you further hints not mentioned in this README. Then build your kernel as usual, install it with a *new* kernel-filename, add a *new* entry to /etc/lilo.conf and run lilo. **DONT CHANGE** any configuration files for the first reboot! Just reboot the new kernel and play a little bit around with creating context-dependend filenames in your home directory. Try all modes including setting NAMETRANS to different values. As an example for the changes necessary on our LST-1.8-based Linux pool, here is the output of the command find / /tmp -xdev -name "*#*#" -print | sort -u | xargs ls -ld -r--r--r-- 1 root root 1725 Dec 21 1995 /etc/X11R6/xdm/xdm-config#host=eiche# -r--r--r-- 3 root root 9509 Feb 15 17:35 /etc/XF86Config#host=balsa# -r--r--r-- 1 root root 9401 Feb 15 17:34 /etc/XF86Config#host=eiche# -rw-r--r-- 1 root root 9820 Feb 21 17:00 /etc/XF86Config#host=fichte# -rw-r--r-- 1 root root 9822 Feb 14 15:45 /etc/XF86Config#host=laerche# -r--r--r-- 3 root root 9509 Feb 15 17:35 /etc/XF86Config#host=mahagoni# -r--r--r-- 3 root root 9509 Feb 15 17:35 /etc/XF86Config#host=palisander# -r--r--r-- 2 root root 9509 Feb 15 17:41 /etc/XF86Config#host=pcbs10# -r--r--r-- 2 root root 9509 Feb 15 17:41 /etc/XF86Config#host=pcbs11# -rw-r--r-- 1 root root 586 Jun 11 23:13 /etc/fstab#ktype=default# -rw-r--r-- 1 root root 242 May 29 17:35 /etc/fstab#ktype=diskless# -rw------- 1 root root 338 Jun 14 16:37 /etc/lilo.conf#host=eiche# -rw------- 1 root root 5236 Dec 16 1995 /etc/lst.cnf#host=balsa# -rw------- 1 root root 5254 Dec 16 1995 /etc/lst.cnf#host=eiche# -rw------- 1 root root 5236 Dec 19 1995 /etc/lst.cnf#host=fichte# -rw------- 1 root root 5236 Jan 11 13:47 /etc/lst.cnf#host=laerche# -rw------- 1 root root 5236 Feb 14 16:57 /etc/lst.cnf#host=mahagoni# -rw------- 1 root root 5236 Jan 4 1996 /etc/lst.cnf#host=palisander# -rw------- 1 root root 5236 Feb 15 13:57 /etc/lst.cnf#host=pcbs10# -rw------- 1 root root 5236 Feb 14 17:06 /etc/lst.cnf#host=pcbs11# -rw-r--r-- 1 root root 0 Dec 18 1995 /etc/mtab#host=CREATE# -rw-r--r-- 1 root root 157 Jun 23 21:16 /etc/mtab#host=balsa# -rw-r--r-- 1 root root 466 Jul 1 16:15 /etc/mtab#host=eiche# -rw-r--r-- 1 root root 239 Jul 4 11:10 /etc/mtab#host=fichte# -rw-r--r-- 1 root root 239 Jun 18 14:17 /etc/mtab#host=laerche# -rw-r--r-- 1 root root 239 May 23 10:50 /etc/mtab#host=mahagoni# -rw-r--r-- 1 root root 239 Jul 3 10:36 /etc/mtab#host=palisander# -rw-r--r-- 1 root root 47 Feb 15 14:57 /etc/mtab#host=pcbs10# -rw-r--r-- 1 root root 47 Feb 14 20:04 /etc/mtab#host=pcbs11# -rw-r--r-- 1 root root 0 Dec 18 1995 /etc/mtab.tmp#host=CREATE# -rw-r--r-- 1 root root 0 Dec 19 1995 /etc/nologin#host=CREATE# ---------- 1 root root 115 Feb 15 14:57 /etc/nologin#host=pcbs10# ---------- 1 root root 115 Feb 14 20:04 /etc/nologin#host=pcbs11# -rw-r--r-- 1 root root 4818 Dec 16 1995 /etc/system.cnf#host=balsa# lrwxrwxrwx 1 root root 25 Dec 22 1995 /etc/system.cnf#host=eiche# -> system.cnf#ktype=default# -rw-r--r-- 1 root root 4821 Dec 19 1995 /etc/system.cnf#host=fichte# -rw-r--r-- 1 root root 4824 Jan 11 13:47 /etc/system.cnf#host=laerche# -rw-r--r-- 1 root root 4827 Feb 14 16:57 /etc/system.cnf#host=mahagoni# -rw-r--r-- 1 root root 4833 Jan 4 1996 /etc/system.cnf#host=palisander# -rw-r--r-- 1 root root 4840 Feb 15 14:10 /etc/system.cnf#host=pcbs10# -rw-r--r-- 1 root root 4846 Feb 14 18:23 /etc/system.cnf#host=pcbs11# -rw-r--r-- 1 root root 4818 Dec 13 1995 /etc/system.cnf#ktype=default# drwxrwxrwt 16 root root 3072 Jul 4 14:29 /tmp#ktype=default# lrwxrwxrwx 1 root root 26 Jul 4 14:22 /tmp#ktype=diskless# -> /tmp#ktype=default#/client -rw-rw-rw- 1 root root 0 Feb 15 14:57 /tmp/client#host=CREATE# drwxrwxrwx 4 root root 1024 Jun 28 12:15 /tmp/client#host=balsa# drwxrwxrwx 3 root root 1024 Jul 4 11:10 /tmp/client#host=fichte# drwxrwxrwx 3 root root 1024 Jun 18 14:18 /tmp/client#host=laerche# drwxrwxrwx 3 root root 1024 May 24 13:06 /tmp/client#host=mahagoni# drwxrwxrwx 3 root root 1024 Jul 3 10:37 /tmp/client#host=palisander# drwxrwxrwx 4 root root 1024 Feb 15 14:57 /tmp/client#host=pcbs10# drwxrwxrwx 3 root root 1024 Feb 20 06:43 /tmp/client#host=pcbs11# lrwxrwxrwx 1 root root 9 Feb 15 13:58 /usr/X11R6/bin/X#host=pcbs10# -> XF86_SVGA lrwxrwxrwx 1 root root 9 Feb 14 17:37 /usr/X11R6/bin/X#host=pcbs11# -> XF86_SVGA lrwxrwxrwx 1 root root 7 Feb 14 17:15 /usr/X11R6/bin/X#ktype=diskless# -> XF86_S3 drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=balsa# drwxr-xr-x 23 root root 1024 Jan 12 14:22 /var#host=eiche# drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=fichte# drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=laerche# drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=mahagoni# drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=palisander# drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=pcbs10# drwxr-xr-x 22 root root 1024 Dec 13 1995 /var#host=pcbs11# Notes: The /tmp directory has an own filesystem on server "eiche", in order to prevent users from filling the whole filestore (we dont use quotas). Each client needs a different /tmp because of possible name clashes. Also, the whole /var hierarchy is kept differently to prevent any risk, but that could be optimized perhaps. Note that nfsd and mountd have been replaced by a script which switches off translations, in the style -rwxr-xr-x 2 root root 70 Mar 22 12:54 /usr/sbin/rpc.mountd -rwxr-xr-x 1 root root 32772 Jun 11 1995 /usr/sbin/rpc.mountd.notrans -rwxr-xr-x 2 root root 70 Mar 22 12:54 /usr/sbin/rpc.nfsd -rwxr-xr-x 1 root root 45060 Jun 11 1995 /usr/sbin/rpc.nfsd.notrans where /usr/sbin/rpc.mountd has the contents #!/bin/sh exec /usr/bin/env - NAMETRANS= "`/usr/bin/env`" $0.notrans $* Of course, that could be improved, but is a quick hack to get things work. Enjoy, -- Thomas The author can be contacted under schoebel@informatik.uni-stuttgart.de or snailmail Thomas Schoebel-Theuer Institut fuer Informatik Breitwiesenstr. 20-22 D-70565 Stuttgart