Skip to main content

skip to main content

developerWorks  >  Linux | Open source  >

Common threads: Advanced filesystem implementor's guide, Part 5

Setting up devfs

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

Daniel Robbins (drobbins@gentoo.org), President/CEO, Gentoo Technologies, Inc.

01 Oct 2001

With the 2.4 release of Linux come a host of new filesystem possibilities, including Reiserfs, XFS, GFS, and others. These filesystems sound cool, but what exactly can they do, what are they good at, and exactly how do you go about safely using them in a production Linux environment? Daniel Robbins answers these questions by showing you how to set up these new advanced filesystems under Linux 2.4. In this installment, Daniel guides you through the process of preparing your system for devfs. By the end of this article, you'll be ready to enable devfs on your system; Daniel will cover final devfs setup in detail in the next article.

In the previous installment (Part 4), we took a close look at what devfs is and how it solves nearly all device management problems. Now, it's time to get devfs up and running on your system. In this article, we'll get your system devfs-ready, and in the next, we will do the actual conversion to devfs. It's perfectly fine to follow the steps in this article even before the next and final devfs article is published, because after we finish all these steps, your system will continue to operate as normal -- it will simply be ready for the upcoming devfs transition. So there's no need to hold off until the next article before following these steps.

Note: Because we'll be making fairly major changes to portions of a Linux system, there's the real potential of messing up your system. So, if you're inexperienced with making "under the hood" modifications to your Linux system, you'll definitely want to do this on a non-critical Linux box, at least for your first time.

Requirements

To get devfs up and running, you'll need to be using some version of Linux 2.4 (2.4.6 or 2.4.8 would be a good choice) and glibc 2.1.3 or greater. It's also recommended that you use Xfree86 4.0 or greater; if you aren't, I recommend that you upgrade to Xfree86 4.1 first.



Back to top


Emergency bash rescue

In our next article, we'll be making changes to boot-critical portions of your Linux system. Since it's definitely possible that you could mess up your boot process by accident if something goes wrong, I'm going to start off this article by first showing you how to get your system up and running with an emergency bash shell. You can use this emergency boot process if you do happen to find that your system doesn't boot due to some problem with your init scripts or /sbin/init itself.

The easiest way to do an emergency boot is to pass an init=/bin/bash option to the kernel at boot-time using either GRUB or LILO. With GRUB, you should be able to pass this option interactively as needed, by hitting e to edit your current menu entry in real-time. With LILO, make sure that you've figured out how to pass kernel boot options before continuing, and create a new "emergency" LILO boot option if necessary.

The process

So, the basic "rescue" process is as follows. First, pass init=/bin/bash to the kernel as a kernel boot option. When the kernel boots, it will then start /bin/bash instead of the normal /sbin/init as the first process. You'll be greeted with a root bash prompt without even having been prompted to log in:

#

However, even though you are greeted with a root bash prompt, only your root filesystem is mounted, and even it is only mounted read-only. Here's how to get your system up and running from this point forward. If your filesystems weren't unmounted cleanly, you should fsck them first. First, do an fsck -a on your root filesystem, and then an fsck -R -A -a should take care of all of your other filesystems:

# fsck -a /dev/hda1
# fsck -R -A -a

Now that your filesystems are consistent (or if your filesystems were unmounted cleanly when you rebooted and you skipped the previous step), you can simply remount the root filesystem as read-write and mount /proc as follows:

# mount / -o remount,rw
# mount /proc

Then, mount any important filesystem trees that you may have on other partitions. For example, if you have /usr on another partition, you'll also need to type:

# mount /usr

It may also be a good idea to activate your swap if you plan to do anything more than fire up an editor. If you use emacs, you may need it :)

# swapon -a

Now, you should be able to run your favorite editor and edit whatever files need to be edited in order to fix the boot problem that you are having. Once complete, simply remount the partitions as read-only in the order that you mounted them. For example, if you have a separate /usr partition, you'd get all your filesystems in a consistent state (ready for reboot) by typing:

# mount /usr -o remount,ro
# mount / -o remount,ro

Now, you can safely reboot. The boot problem is hopefully now resolved and your normal LILO or GRUB options will get the system up and running:

# /sbin/reboot -nfi



Back to top


Getting ready for devfs

Devfs configuration

Now that you know what to do in case of an emergency, we're ready to get your system ready for devfs. In the next article, we're going to be making some relatively complex changes to your Linux system. Why is this necessary? Because we're not just enabling devfs functionality in the kernel, which is actually quite easy. We're also going to set up devfsd (the device management daemon) in a special mode so that it backs up and restores any changes to device permissions and ownership. We need to do a lot of little tricks to get this new system working perfectly. But once it is, I think you'll be very pleased with the result.

Devfs kernel support

The first step to enabling devfs on your system is easy: you'll need to enable devfs support in the kernel. For this, you'll need a 2.4 series kernel. Using make menuconfig or make xconfig, head over to the Code maturity level options section and make sure that the Prompt for development and/or incomplete code/drivers option is enabled. Then, head over to the File systems kernel configuration section and look for the /dev file system support (EXPERIMENTAL) option. Enable it. You'll see a couple of additional options appear below the option you just enabled. The first one controls whether devfs will be mounted to /dev automatically when the kernel boots. Don't enable this option; we will manually mount /dev using a special script. The second option, Debug devfs, should also be disabled.

Disable /dev/pts

While you have the File systems kernel configuration section on screen, disable support for the /dev/pts file system for Unix98 PTYs if you happen to have it enabled. Devfs provides similar functionality, so you won't need the devpts filesystem anymore. Go ahead and save your kernel configuration; we'll compile and install a new kernel in a bit. Finally, before moving on to the next step, check to see if you have a /dev/pts entry in your /etc/fstab; if you do, comment it out so that it doesn't get mounted at boot-time anymore.

Miscellaneous configuration quirks

Next, load the /etc/securetty file into an editor. This file is used by login and allows you to specify the ttys that the root user is allowed to use to login. Normally, it contains the devices tty1 through tty12, one per line. In order to get this file ready for devfs, you should add the appropriate devfs-style names for these ttys, keeping the older tty? names in case you decide to boot with devfs disabled. Add the following lines to the bottom of /etc/securetty.

vc/1
vc/2
vc/3
vc/4
vc/5
vc/6
vc/7
vc/8
vc/9
vc/10
vc/11
vc/12

Installing devfsd

The next step is to get devfsd, the devfs helper daemon, installed on the system. Devfsd will take care of creating "old-style" compatibility device nodes, performing automated actions when a driver is registered/unregistered, take care of backing up changes to device permissions and ownership to a directory on the root filesystem, and more. Right now, we'll just get devfsd installed; next article, we'll get it up and running, along with devfs. To install devfsd, first download the most recent version of the devfsd tarball (see Resources later in this article), currently version 1.3.16. Then perform the following steps:

# tar xzvf devfsd-1.3.16.tar.gz
# cd devfsd
# make

Now, devfsd should be compiled and ready to install. If your man pages are stored in /usr/man, type make install; if you are using an FHS-compliant system and your man pages are in /usr/share/man, type make mandir=/usr/share/man install. Devfsd will now be installed but not runnning, which is exactly how we want it at this point.

Configuration note
We will be configuring so that we will have full support for compatibility devices, so the tty? entries should be adequate. However, it's better to be safe than sorry, especially when it may affect whether login will allow the superuser to gain access to the system. With our approach, even if there is a problem and devfsd isn't able to start, the superuser can log in at the login: prompt without problems, even with devfs enabled.

Getting the new kernel going

Now, go ahead and compile and install your recently configured kernel. This kernel should be a drop-in replacement for your current kernel; it should boot normally, and although it has devfs support built in, you should notice no difference from the one you're running now. Once the new kernel is installed, reboot your system to make sure that everything is working fine up to this point.



Back to top


Devfs configuration approaches

Your system is now ready for the devfs conversion, which I will cover in detail in the next article. Now would be a good time to get familiar with the approach we are using. As you will see, devfs-enabling a distribution can be very tricky, especially if you want to use all the nice devfs features like persistent permissions and ownership.

The problems with kernel automounting

There are actually a number of ways to devfs-enable a system. One is to have the kernel automatically mount devfs to /dev at boot; we won't be using this option, but it is available. At first glance, this approach would seem to make a lot of sense because it would ensure that all devfs-style devices are available to all processes, even the first process, /sbin/init. However, there's a problem with this approach. While devfs provides all the "new-style" devices, the old-style device nodes are created by the devfsd daemon. devfsd isn't started by the kernel, so even if we have the kernel mount devfs at boot, we are still only left with a partial set of device nodes by the time /sbin/init starts up. This means that tweaks to your system initializations scripts will be required in order to get devfsd up and running at just the right time. Not only is this tricky (since it requires that you have an expert understanding of your own system's startup scripts), but this approach has other problems as well.

The main problem with the kernel mounting approach is that devfsd works best when it has access to the contents of your original old-style on-disk /dev directory. Typically, we allow access to the original old-style devices by bind-mounting /dev to another location (typically /dev-state) before devfs itself is mounted to /dev.

This ensures that the contents of your old /dev are still accessible at /dev-state even after devfs is mounted, which allows devfsd to use this directory for persistent device storage. It's important to understand that without the bind mount, the old contents of /dev would be inaccessible, since mounting devfs at /dev would effectively cover them up. And this is the problem with having the kernel mount devfs. If the kernel mounts the devfs filesystem at /dev before any process is able to start, then we have no opportunity to perform the bind mount, and the original contents of /dev are completely hidden. Icky, isn't it? (To learn more about bind mounts, see Part 3 of this series.)



Back to top


The best solution

Ideally, it would be great if we could have a full set of device nodes (new-style and compatibility devices) as soon as /sbin/init is started and also have the opportunity to bind mount /dev to another location before devfs is even mounted; but how is this possible?

The init wrapper

Well, one way would be to add a kernel patch to perform the bind mount from /dev to /dev-state. However, while this is definitely possible and actually quite easy to perform, it would be inconvenient to manually patch every new Linux kernel you install. Therefore, probably the best way to solve the devfs "chicken and egg" problem is to use an init wrapper. For our particular application, the init wrapper will be a bash script that takes the place of /sbin/init -- our real init has been renamed as /sbin/init.system. In short, this is what the init wrapper will do:

#!/bin/bash
mkdir -f /dev-state
mount --bind /dev /dev-state
mount -t devfs none /dev
devfsd /dev
exec /sbin/init.system

As you can see, the first thing the wrapper does is ensure that /dev-state exists. Then, the /dev tree is bind mounted to /dev-state, so that the contents of /dev are available via the /dev-state directory. Then, our devfs filesystem is mounted on top of /dev and we start devfsd so that our compatibility devices are automatically registered with devfs. Finally, we exec the original /sbin/init, which has now been renamed to /sbin/init.system. The exec command causes init.system to replace the running bash process. This means that our bash script terminates and init.system inherits process ID 1, the coveted process ID of the init process. When /sbin/init.system starts up, the system boots as normal except that devfs is now fully operational; by using an init wrapper, we avoided having to patch the kernel, tweak our startup scripts, or deal with having only a semi-operational devfs system.

In my next article, I'll guide you through the process of getting the full version of the init wrapper up and running and show you how to take advantage of devfsd's many powerful features. Stay tuned!



Resources



About the author

Residing in Albuquerque, New Mexico, Daniel Robbins is the President/CEO of Gentoo Technologies, Inc., the creator of Gentoo Linux, an advanced Linux for the PC, and the Portage system, a next-generation ports system for Linux. He has also served as a contributing author for the Macmillan books Caldera OpenLinux Unleashed, SuSE Linux Unleashed, and Samba Unleashed. Daniel has been involved with computers in some fashion since the second grade, when he was first exposed to the Logo programming language as well as a potentially dangerous dose of Pac Man. This probably explains why he has since served as a Lead Graphic Artist at SONY Electronic Publishing/Psygnosis. Daniel enjoys spending time with his wife, Mary, and his daughter, Hadassah. You can contact Daniel at drobbins@gentoo.org.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top