BSD DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


BSD Tricks: Linux Compatibility, the Hard Way
Pages: 1, 2

Here I had a difficult situation. Not only was it doing something wrong, I had to figure out what "right" meant in this circumstance. I could set the Linux home directory to /bsd/usr/home/mwlucas, but the Linux environment is purely experimental; I don't want to damage my production environment with Linux errors. (The astute among you might notice that this entire process is endangering my production environment; you're welcome to wait in the hall for the rest of the article.) I want the Linuxulator to see files in both my Linux home directory and my BSD home directory. I decided that I'd prefer that programs run in Linux mode work with my BSD home directory first, only falling back to the Linux home directory if necessary.



FreeBSD has the ability to do this; it's called unionfs. Dire warnings fill mount_union(8). Since I'm already doing strange things, we'll charge on.

Unionfs mounts one section of the filesystem "over" another section, allowing both sections to appear to be one directory. For example, you could mount /tmp over /cdrom. An ls /cdrom would show all the files from /tmp intermingled with the files from /cdrom, as if they were one directory.

The layers are referred to as the "upper" and "lower" layers. When you alter a file, changes are made in the upper layer. If files in both the upper and lower layer have the same name, the upper file is visible. In the example above, /cdrom would appear to be writable. The files would actually be written and changed in /tmp, however. If you edited a file from /cdrom, the file would actually be copied to /tmp and edited there.

I don't really care about altering the Linux home directory -- I'm in Linux rarely enough that I can copy things from my BSD home directory should they become important. I want the BSD home /usr/home/mwlucas to be the upper layer, mounted over /usr/compat/linux/home/mwlucas. Do this with:

mount_union /usr/home/mwlucas /usr/compat/linux/home/mwlucas

Similarly, I want the Linuxulator to check for entries in /dev before /compat/linux/dev -- this will make RealPlayer access the correct /dev/audio. I had some concern about accessing entries in /dev, but Linux mode's default behavior does this, so what the heck.

mount_union /dev /usr/compat/linux/dev

To my surprise, this works as well. My Linux apps run, and things seem stable. When I'm finished, my filesystem table looks like this.

Don't worry about the "capacity" column on union-mounted partitions; I'm not sure how df calculates the amount of space used on a unionfs partition, but it's blatantly bogus. Note that when you add in union-mounted partitions, this drive supposedly has roughly 22 gigs of space on a 12-gig hard drive.

When you have a problem with the Linuxulator in this configuration, the first thing to do is restore the original configuration. If you can reproduce the problem with linux_base, it's an actual issue. If you can't, well, have fun.

If you go with the obvious default settings of /usr/compat/linux automounting via /etc/fstab, and LINUX_ENABLE="YES" in /etc/rc.conf, your system won't boot. FreeBSD mounts filesystems before loading linux.ko. If /usr/compat/linux is an ext2 partition, and is mounted before linux.ko is loaded, your system will shut down. It won't panic, it won't run any shutdown scripts, and it won't unmount your file systems; you'll just see a couple notices about waiting for core processes to stop, and be back at the BIOS screen.

The solution is to load linux.ko before mounting the file system. I use the following shell script (linux.sh) in /usr/local/etc/rc.d to mount /usr/compat/linux and run the assorted mount_union commands.

#!/bin/sh

/sbin/mount /usr/compat/linux

/sbin/mount_union /usr/home/mwlucas /usr/compat/linux/home/mwlucas
/sbin/mount_union /dev /usr/compat/linux/dev

You might also want to union mount /tmp over /usr/compat/linux/tmp.

When (not if) your system shuts down unnaturally, the reboot fsck will not clean the ext2 file system. When you try to mount it, you'll get a "permission denied" error and announcements in /var/log/messages. Do not attempt to use Linux's e2fsck under Linux mode; you will panic the system, and the folks up on -hackers don't want to hear about it.

To fix this, reboot into Linux. Let e2fsck do its work, then boot back into FreeBSD.

This is how I run Linux emulation. I can't say I recommend it for everyone's general use, but it might meet your needs. The surprising thing about running Linux mode in this way isn't that it works at all, but that it's so stable. Once I stopped trying to run Linux system programs in FreeBSD, it worked just as solidly as the standard FreeBSD linux_base package. This isn't because of my skill so much as it is a tribute to the FreeBSD developers; even when you do things clearly marked "dangerous," it still probably runs.

Note that "probably" doesn't mean that it's recommended.

Michael W. Lucas


Read more Big Scary Daemons columns.

Discuss this article in the Operating Systems Forum.

Return to the BSD DevCenter.

 





Sponsored by: