TinyLogin: Booting up in Small Places
The feature sets of many of the latest Linux products are often so vast that it may take four to six CDs to hold them all. But a number of developers are going the other direction, slimming Linux down to the bare minimum to meet the needs of the latest embedded Linux systems. Embedded Linux systems are growing in number, popularity and usefulness. Witness the launch of Embedded Linux Journal as a sign of the times.
TinyLogin is a utility intended for embedded systems. It provides the functionality of ten login and user-management utilities in a single tiny binary. TinyLogin was started by Sean Bastille back in 1998. It is now maintained as an open-source project by Erik Andersen, sponsored by his employer, Lineo, Inc. Erik also maintains the BusyBox utility; it's no coincidence that the two are designed to work well together.
Why have a single binary for these ten login utilities? The standard utilities that TinyLogin replaces occupy 140K. That isn't much space, but the attitude of an embedded Linux developer is generally to avoid wasting any space on things that are not needed. The TinyLogin binary is 40K. It doesn't have all the options of the programs it replaces, but most embedded systems don't need them all.
Furthermore, since many developers use GNU libc, TinyLogin allows embedded Linux systems the option to bypass the GNU Name Service Switch (NSS) libraries. These libraries allow GNU libc to use a number of alternative methods for obtaining information such as user names and passwords. Most embedded systems have no need for this functionality, so by eliminating these libraries from their target systems, developers can save another 200K.
Linux distributions normally include packages with many separate utilities, often in sets named initscripts, textutils, shellutils or something similar. These utilities and scripts are generally quite feature ladened. The command to list files, ls, supports over 50 command-line options. Because these utilities are so full-featured, they are sometimes larger than expected. For example, on my system the ls command (dynamically linked) occupies 48KB of disk space. While you wouldn't notice that on a standard PC, many of the 50 options are just wasted space on an embedded system or boot disk. TinyLogin combines numerous utilities in a single binary, limiting the features of each utility to those most commonly needed. As another example, the adduser command in TinyLogin supports only three options rather than the 20-plus options of a typical adduser command.
When you enter the name of a utility in a shell it attempts to locate a binary with that name and then execute it. When you install TinyLogin, it creates symbolic links in your filesystem so that instead of having a real adduser command, you have a symbolic link that refers to the TinyLogin binary. A directory listing of adduser would then appear like this:
lrwxrwxrwx 1 nwells users 12 Jan 17 14:47 <@cont_arrow><\#229><@$p>adduser -> /bin/tinylogin
Typing adduser at the command prompt causes the shell to launch the TinyLogin program, which in turn examines the text that you entered to launch it. The program does this by examining the argv programming variable (similar to the positional variables in shell scripting). Seeing that you entered adduser, the TinyLogin program proceeds to act like adduser, interpreting any additional items on the command line as adduser would.
TinyLogin includes the following ten utilities:
adduser to add new user accounts.
addgroup to add new group accounts.
deluser to delete users from the /etc/passwd and /etc/shadow files.
delgroup to delete groups from /etc/group.
passwd to change a user's password.
getty to manage terminals and start the login process.
login to begin a login session.
su to change current user ID (substitute user, normally used to become root for a while).
sulogin for single-user login (runlevel 1)--this functionality is disabled by default but can be turned on in the Config.h file.
vlock to lock a virtual console until a password is entered--this functionality is disabled by default but can be turned on by modifying the config.h file.
You'll have to judge for yourself if the features included with each of these commands will meet the needs of your embedded-system project. For example, the getty command implemented in TinyLogin doesn't use the /etc/gettydefs or /etc/gettytab configuration files. Instead it relies on a number of command-line options. Fortunately, TinyLogin is completely modular. If you need a more full-featured utility, you can always disable any of the TinyLogin utilities that you prefer not to use and use the standard Linux tools to provide those features.
Compiling TinyLogin is simple because no special libraries or configuration steps are necessary. First obtain the source code by visiting http://tinylogin.lineo.com or ftp://opensource.lineo.com/tinylogin and download the most recent version of the compressed tar file. At the time of this writing, the most recent version is the file tinylogin-0.80.tar.gz, but a more recent version may be available soon. Work on TinyLogin seems to progress at a steady pace.
After you've download the tar file, place it in a working directory and use this command to untar the file:
tar -xvzf tinylogin-0.80.tar.gz
Change to the newly created tinylogin directory and enter the command:
cd tinylogin-0.80 makeTinyLogin is written in C and so requires a C library to operate. Most Linux developers use the GNU C libraries (glibc), which can add substantially to the space requirements of an embedded system or boot disk. Statically linking TinyLogin with glibc also has less than ideal results because of the heavyweight nature of glibc. You might consider looking at alternate implementations of libc to save space. Examples of alternatives include libc5, glibc 2.0.7, minix libc and newlib. The best choice for TinyLogin, however, may be the uClibc Project, currently being maintained by Erik Andersen. This library is a great way to reduce the total system requirements.
TinyLogin is most useful on systems without a set of regular Linux utility programs, but you'll probably be exploring it on a standard Linux system. Because of this, you should install the TinyLogin programs (and the symbolic links that make them work as expected) in a separate directory until you're comfortable with them.
By using a directory name with the make install command you can place the TinyLogin command and matching relative symbolic links in a directory of your choosing. For example, use this command from the tinylogin-0.80 directory after compiling the source code as above:
make PREFIX=/tmp install
The /tmp directory will then contain subdirectories named bin, sbin and usr, each with symbolic links to /tmp/bin/tinylogin.
If you use make install with no PREFIX, the binary and symbolic links are installed into a _install subdirectory of your current directory, which also works fine for testing.
To really use TinyLogin for your system's utilities, you would use the following command:
make PREFIX=/ install
(Don't use this command until you've explored the utilities as I describe in the next section, especially the getty command.)
Now you're ready to test the functions of TinyLogin.
For testing purposes, I'll assume that you've installed TinyLogin in the /tmp directory, so the TinyLogin binary is located in the directory /tmp/bin. As a first test, use TinyLogin with a command name such as adduser as a parameter. For example, the following command will add the user david to your system:
/tmp/bin/tinylogin adduser david
Enter a password for david as prompted. To delete this user with deluser, enter:
/tmp/bin/tinylogin deluser davidNext you can try using the symbolic links that were installed by the make install command. The two commands above would then look like this:
/tmp/bin/adduser david /tmp/bin/deluser davidThe particulars of each command are important to understand. All of the user and group management commands will use the shadow password file (/etc/shadow) if it's installed, and the adduser and passwd commands check for things like simply reversing existing passwords or adding a digit to the end of the current password (the password_check( ) function in the file, obscure.c, will show you the details). If shadow passwords are used on your system and support for them is compiled into TinyLogin, features like expiring passwords are also supported. The defaults installed on your system are used for these values. You'll also note that the comment field of /etc/passwd defaults to using ``Embedix User'' for the full name of a user created with adduser in TinyLogin. You can specify an alternative name using adduser -g or you can use a text editor to change the default value on line 54 of adduser.c.
A special consideration with user and password management is the GNU C Library Name Service Switch system used on all desktop Linux distributions. This system defines where utilities, such as passwd, look for user data. Options like NIS databases, DNS servers, local text files and local database files are all supported to make large networks easier to manage. TinyLogin doesn't use nsswitch by default, though it can. If you want to support this feature, which is useful but requires additional space and configuration effort, be certain that you have /etc/nsswitch installed and configured. Then set the USE_SYSTEM_PWD_GRP setting in the TinyLogin Makefile equal to true. The maintainer of TinyLogin recommends against using nsswitch because of the additional complications, but he does provide some guidelines for preparing libraries and the nsswitch.conf configruation file. See TinyLogin.html in the docs subdirectory for the details.
Unlike the BusyBox program, TinyLogin doesn't provide much in the way of on-line help for its available options. Of course, the utilities in TinyLogin are more straightforward than those in BusyBox. In fact, you don't need any options for most of the TinyLogin commands (su, login, etc.).
It's a good idea, however, to review the man pages for TinyLogin and for the getty command to see exactly how they work. These are contained in the docs subdirectory of the tinylogin-0.80 directory after you untar the source code.
Using the getty feature of TinyLogin on a standard Linux system is the most dangerous part of testing the program. It requires editing the /etc/inittab file. If you make any silly mistakes while doing this, you may spend some time booting from a floppy disk and fixing things, so be very careful.
As a review, this is the standard process for launching a Linux system in text mode (runlevel 3, nongraphical):
The computer's BIOS loads LILO from the boot sector or master boot record of the hard disk.
LILO loads the Linux kernel.
The kernel starts the init program.
If the kernel was started in single-user mode, the init program starts the sulogin program.
In standard modes (nonsingle user), the init program starts a getty program on each terminal (tty), which waits for someone to log in. (You'll see getty programs called mgetty, mingetty, agetty, etc., all with slightly different features, but all doing the same task: waiting for someone to log in.)
getty collects a user name from the person logging in and launches /bin/login.
The login command processes the password entry and launches a shell.
To test getty, you can alter the /etc/inittab file so that one of the ttys (say, tty6) uses the TinyLogin version of getty rather than the standard version that comes with your Linux. To do this, log in as root, make a backup copy of /etc/inittab, and then load the original file into a text editor.
Find the line in inittab that looks like the following sample taken from Red Hat Linux 7. The name of the getty program or the parameters after getty may differ on your system:
Now change that line to look like this for the test, using the location where you have the TinyLogin symbolic link for getty:
6:2345:respawn:/tmp/sbin/getty -i 38400 tty6Save the inittab file and exit the text editor. Now enter this command to make the init program reread the inittab file:
init qSwitch to the tty6 virtual console by pressing Alt+F6 (or Ctrl+Alt+F6 if you've been working in a graphical environment). Most systems have a file called /etc/issue that contains the name of the distribution and the Linux version. You see this each time you log in. But the -i option that I included in the getty command above causes this file not to be displayed. Enter a nonexistent username a few times on virtual console six until the getty program restarts (respawns). You should see a difference from the standard login prompt. Switch back and forth between consoles five and six to check this (use Alt+F5 and Alt+F6). The getty man page in the TinyLogin docs directory describes all the command-line options that getty supports.
When you log in with a valid user name and password, the TinyLogin version of getty still launches the /bin/login program, rather than the /tmp/bin/login program. You'll need to install TinyLogin into the standard system locations or move around the regular login program and add a symbolic link from /bin/login to the tinylogin binary in order to test the login features of TinyLogin. But testing getty as outlined gives a good glimpse of how TinyLogin can operate in a minimal-boot environment, saving space with a single small binary.
Now go back and change the inittab file back to its previous state so that tty6 will still be usable when you move the TinyLogin files from /tmp.
The documentation for TinyLogin mentions a file called tinylogin.def.h. Here, the docs are not quite up to date, since this file is now called config.h. Using this file, you can select which of the utilities described above are included in the single TinyLogin binary file. This is the same process used to control the contents of the BusyBox application.
By making changes to the #define statements in the config.h file, you can determine which capabilities are, and are not included when you compile the TinyLogin binary. For example, if you don't want to include one of the ten utilities, such as deluser, simply comment out the line by means of C++-style, double-forward slashes, something like this:
By default, the sulogin and vlock commands are disabled in the config.h file. If you want to include these commands as part of TinyLogin, you'll need to remove the comment slashes in config.h before you compile the program.
Several other miniature utilities can help you in this type of project, such as the minimal editors ae, nano and elvis-tiny; the BusyBox single-binary utility set (which I've referred to several times); and a small Bourne-compatible shell called ash. Links to all of these projects are available on the TinyLogin web site.
Nicholas D. Wells is the director of corporate business strategy at embedded Linux vendor, Lineo, Inc. (sponsors of the TinyLogin Project). He began working with Linux at Novell in 1993 and has written numerous books on Linux and Linux applications for Que, Coriolis, Sybex, and others.