Wandering Thoughts archives

2006-05-25

A Linux su surprise

I found out about Linux su's '-p' option from comments on a a previous entry. The option is also known as -m and --preserve-environment; the manpage describes it tersely as 'do not reset environment variables', but the info document tells the full story:

Do not change the environment variables `HOME', `USER', `LOGNAME', or `SHELL'. Run the shell given in the environment variable `SHELL' instead of the shell from USER's passwd entry, unless the user running `su' is not the superuser and USER's shell is restricted. A "restricted shell" is one that is not listed in the file `/etc/shells', or in a compiled-in list if that file does not exist. Parts of what this option does can be overridden by `--login' and `--shell'.

I'm used to old-fashioned su's that always run the target user's login shell, no matter what. Being able to override the login shell is a bit alarming; although there are safeguards, it does make what you put in /etc/shells somewhat more dangerous. (Clearly you never want to put /bin/false or the like in there, in order to get something else to work right.)

At the same time, being able to run alternate shells for 'restricted' accounts as root is a useful trick (whether done through -p or directly through --shell). I'll have to remember it for the next time I want to fiddle with an environment owned by such an account; it certainly beats trying to do it as root and then chown'ing the setup all over.

LinuxSuSurprise written at 16:01:26; Add Comment

2006-05-24

The not so secret history of vmlinuz

By convention, Linux kernels are called vmlinuz (usually with a version suffix and found in /boot, although Debian is in love with a /vmlinuz symlink). This name has an interesting history that probably stretches back to the early days of Unix.

(I say probably because I'm just guessing at some of the Linux history, as it predates my involvement with Linux.)

Originally, Unix kernels were just called /unix; this is the name Bell Labs used for the original versions up through V7. These early Unixes ran on PDP-11s and only had whole-process swapping, not paging. (I'm not sure if PDP-11s even had paging hardware.)

When UC Berkeley moved V7 to the new DEC VAX series, they added paged virtual memory (among other things). To mark this, UCB changed the conventional kernel name to /vmunix.

Mutating this to vmlinux for Linux kernel images is a small step (especially given the old commotion about 'Linux is not Unix'). Even today, vmlinux is the name used for the uncompressed kernel executable that's created as part of the kernel build process.

When it became necessary to compress kernel images in order to make them fit into the available early boot memory, vmlinux was transmogrified to today's vmlinuz, with the 'z' marking the use of compression.

(The vmlinux name dates from Linux 0.99, if not earlier; vmlinuz came in slightly later. The very earliest Linux kernel source just called the bootable kernel file 'Image'.)

Sidebar: Linux kernel image names (on PClone hardware)

  • Image: as mentioned, the original name for the bootable kernel image. Uncompressed.
  • zImage: a gzip-compressed image, with a decompresser et al glued on the front.
  • bzImage: contrary to popular legend, not compressed with bzip2 instead of gzip; instead it stands for 'big zImage', and is a new format that allows for much bigger kernel images.

Apparently one reason bzip2 compression is not used for kernel images is that the bzip2 decompresser requires a significant amount of memory.

In theory Linux could go back to uncompressed kernel images now, but compressed ones are much smaller and thus load much faster; a recent kernel build on my 64-bit Athlon created an 8 megabyte vmlinux file (with 4 megabytes of real content) that compressed into a 1.75 megabyte vmlinuz.

VmlinuzHistory written at 02:04:56; Add Comment

2006-05-11

Building a boot floppy for BIOS flashing

Part of today was arranging to flash a new BIOS on my new machine here (in the hopes that the most recent BIOS version would fix a mysterious memory corruption problem). This was a bunch of annoyance, because I had to come up with a bootable MS-DOS floppy to run Tyan's BIOS flasher program from. So that I don't have to go through all the work next time around, I'm going to put what I found here.

In the old days, it was simple: I'd go ask someone running Windows 95 or 98 to make me a boot floppy, slap the flash update program on it, and go. Unfortunately, no one around here is running those Windows versions any more and apparently newer versions can't do this any more. (Since Windows is no longer based on MS-DOS, this isn't too surprising.)

What you really need is a bootable DOS floppy image that you can just dump onto a floppy. What I used is the FreeDOS image from Flashing BIOSes; the actual article is mostly about making bootable CD-ROMs for BIOS flashing. (When booted the image will offer you a bunch of options for what next; pick 'clean boot'. There's probably some way to set it to boot straight to the old-style DOS prompt, but I didn't poke around.)

There's also HOWTO Create a DOS boot disk (and here), from the Gentoo wiki. The FreeDOS images they use seem to be more minimalistic than the Flashing BIOSes ones.

Other approaches and more information

There's a number of places with actual MS-DOS boot images (copyright Microsoft and all), like here or here, but they tend to have them wrapped up in DOS .exe files and other odd formats instead of being in nice dd-able images. And of course they're almost certainly being distributed without Microsoft's permission.

Flashing PC BIOS under Unix/Linux in non-traumatic fashion has one of these in a convenient for Linux format, and instructions as well.

If you don't want to bother with the mess of an actual floppy and already have a working Linux installation, look at memdisk. Memdisk will boot a floppy image from memory, without the mess of a physical floppy. The drawback of this is that you can't save the old BIOS image if your BIOS flashing program offers this option.

(While SYSLINUX can make a bootable floppy it doesn't include a MS-DOS compatible command.com et al, without which you can't run the BIOS update utilities.)

BuildingFlashFloppy written at 02:36:39; Add Comment

2006-05-06

Using a stock kernel.org kernel on Fedora Core 5

If you like initrds, the stock Linux kernels from kernel.org should just compile and work. Install the kernel-devel RPM, copy the .config from /usr/src/kernels/<ver> to your source tree to duplicate the normal Fedora Core kernel configuration, make oldconfig, and go.

I don't like initrds, though. So one of the usual benefits of compiling my own kernel is not needing one, so there's one fewer moving part in my system environment. Unfortunately, Fedora Core 5 uses udev, which introduces a problem: the normal initrd is what creates /dev. No initrd, no /dev/console, and your kernel reports:

Warning: unable to open an initial console.

Usually things blow up shortly afterward. (You're also missing /dev/zero and /dev/null, which doesn't help.)

One way around this is to populate a basic /dev on the root filesystem. To get around the chicken and egg problem that FC5 boots with something mounted on top of /dev, you can use the NFS trick I mentioned yesterday.

The simpler way out is just to make an initrd anyways, despite theoretically not needing one. mkinitrd is happy to set you up with a basic initrd that just does the necessary magic to create /dev and switch into the real root filesystem and so on. As a bonus, this initrd is kernel agnostic: you can use it for any kernel version (making it slightly more palatable).

It looks somewhat like the resulting 'generic' initrd does know what your root filesystem is. Unfortunately the nash manual page and the actual init script buried in the initrd disagree with each other, so I'm not entirely sure.

Since I was in a rush yesterday, I opted to hold my nose a bit and use the initrd approach. Thus, unfortunately, I have no idea what additional steps making a real /dev may require; caveat emptor.

Sidebar: inspecting initrds

Fedora Core 5 initrds are gzip'd cpio archives. cpio -tv will list the contents; cpio -id will extract them (into the current directory). /init is the magic script that does all the work.

I will reluctantly concede that this is more convenient than the old approach of gziped filesystem images.

FC5WithStockKernel written at 03:07:53; Add Comment

2006-05-03

Fedora Core 5's missing 32-bit shared library symlinks

For my sins, I decided that my new machine should run the 64-bit version of Fedora Core 5. I knew this was going to be somewhat painful, because various important things (such as Flash and Sun's Java) don't yet have 64-bit versions; I was going to have to build 32-bit versions of things like Firefox in order to use them.

Little did I know that Fedora has made it all but impossible to compile a 32-bit version of anything more complicated than a 'Hello World' program. Consider the following simple X11 program, extracted from the configure script for MPlayer:

$ cat testit.c
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(void) { (void) XCreateWindow(0,0,0,0,0,0,0,0,0,0,0,0); return 0; }
$ cc -m32 -o testit testit.c -lX11
/usr/bin/ld: skipping incompatible /usr/lib64/libX11.so when searching for -lX11
/usr/bin/ld: cannot find -lX11
collect2: ld returned 1 exit status

The error message is the clue, and here is the problem:

$ echo /usr/lib/libX11.so*
/usr/lib/libX11.so.6 /usr/lib/libX11.so.6.2.0

There should be a /usr/lib/libX11.so symlink that points to the 32-bit libX11 shared library, just like there is a 64-bit libX11.so symlink that ld is helpfully telling us about in the error message (it's part of the libX11-devel RPM). There isn't.

This isn't an isolated incident. On my Fedora Core 5 machine, there are 292 32-bit shared libraries in /usr/lib, from 113 different RPMs; 196 of them don't have the necessary symlink to actually compile 32-bit programs. The broken 32-bit RPMs cover everything from bzip2-libs through readline, including basically all of the X11 and core GTK libraries. (Ironically, the KDE libraries are fine; advantage to KDE again. Not that you'll be compiling many 32-bit KDE programs with the basic X11 libraries unlinkable.)

Unless I'm missing something major, it's pretty clear to me that no one at Red Hat actually tried to build real 32-bit applications under 64-bit Fedora Core 5. I'm not even sure how they built the 32-bit versions of the RPMs they ship as part of the system; I doubt the source RPMs will actually rebuild on a normal 64-bit FC5 machine.

(As an experiment, I tried rebuilding the 32-bit ImageMagick RPM; it blew up more or less on schedule.)

Sidebar: the manual fix

If you want to fix this manually, it's relatively simple: for every affected 32-bit shared library, just go to /usr/lib and symlink libWhat.so to the current version of libWhat.so.blah.blah. The tricky bits are:

  1. finding every affected 32-bit library that you care about (usually you find them by having programs fail to link, which is a bit tedious), and
  2. figuring out what the current version is. (Fortunately, only a few things have multiple versions of the same shared library.)

I will probably wind up writing some sort of program to do this for me. That I need such a program, and that I need to mangle my system outside of RPMs, irritates the heck out of me.

The better fix presumably starts with a mass bug filing in the Red Hat Bugzilla. The temptation to automate it is strong; after all, I do have curl lying around.

FC5MissingSoSymlinks written at 03:24:40; Add Comment

2006-05-01

Emergency repairs with GRUB

This server lost its boot drive today, which occasioned a certain amount of flailing. We use mirrored drives, but there were two problems: the dead disk wasn't actually dead, just puking, and the second disk hadn't been set up to be bootable (although it had a fully populated copy of the /boot partition). The first problem was dealt with by yanking the drive's power plug out, but the second one took more work.

Although GRUB people may hem and haw about it, GRUB needs boot blocks and other magic setup done just like LILO does (some more details are here). If you don't have them set up, it doesn't matter that all of the GRUB stuff is sitting in a /boot2 partition; your drive's not booting. To fix that, I needed to install the GRUB boot stuff. Which meant that I needed to boot the system so I could run the GRUB boot block installer.

First attempt: boot the FC2 CD in rescue mode. This failed to bring up the RAID-1 partitions on the remaining drive, so it couldn't find our install, so it went nowhere. (I don't know why it failed; possibly the rescue mode refuses to bring up incomplete RAID-1 mirrors.)

Second attempt: boot through a GRUB boot floppy. This is the one area where GRUB is a clear win over LILO; armed with a boot floppy, you can boot anything that is sitting on a readable partition. The easy way to make a boot floppy is with:

$ cd /usr/share/grub/i386*
$ cat stage1 stage2 | dd of=/dev/fd0

(The fine manual has a more complicated incantation with multiple dd commands that didn't work for me for some reason.)

This worked, once I had a working floppy. (Familiarity with kernel boot arguments is recommended.)

With the system at least booted, I could make the drive bootable. The important thing was to fix GRUB's idea of what Linux drive was what BIOS drive; since /dev/hdc was the only surviving drive, it was clearly hd0 (GRUB's name for the first BIOS drive), so I changed the surviving device.map file accordingly.

The GRUB documentation will tell you to install GRUB with grub-install. Ignore it; grub-install makes a number of unwise assumptions that make it rather fragile, and most of the time it's easy enough to use the grub shell under Linux. The magic incantation I used was:

$ grub --device-map=/boot2/grub/devices.map
root (hd0,N)
setup --prefix=/grub (hd0)
quit

Our boot partition copy was /boot2, with the usual layout. N is the number of that partition minus one; GRUB counts partitions from 0 instead of 1. Our custom is to make the boot partition the first partition on the drive, so for me it was (hd0,0).

Fortunately the drive that died had starting glitching out a few days earlier, so we had a replacement drive already on hand. Once the system was at least up (and the mail backlog had cleared), I swapped it in as /dev/hda; this led to another run of the GRUB shell to install bootblocks on it. (Being careful to change GRUB's device mapping so that /dev/hda would now be hd0.)

Apart from that, bringing the new drive into service was pretty much like the last time we had to do this.

(Department of belated corrections, November 14th: I've changed the setup line above to have the correct '(hd0)' instead of the 'hd0' that I originally wrote. I actually noticed the error some time back, when I had to do this again and the literal version didn't work, but I never got around to actually correcting it until now. Bad me.)

GrubEmergencyRepairs written at 02:23:11; Add Comment

By day for May 2006: 1 3 6 11 24 25; before May; after May.

Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.