Power off and kernels version 2.1.xx and 2.2.xx

The problem

With the stable kernels version 2.0.xx, answering yes to the kernel option "Power off on shutdown", would make your PC power off, when you did a `shutdown -h now'. This doesn't happen if your using kernels version 2.1.xx or 2.2.xx (perhaps for very early versions in the 2.1 series, but you don't want to use those).

If you read the help to the "Power off on shutdown" option for a 2.1.xx or 2.2.xx kernel, you'll see the following message:

You will need software (e.g., a suitable version of the halt(8) command ("man 8 halt")) to cause the computer to power down. Recent versions of the sysvinit package available from ftp://sunsite.unc.edu/pub/Linux/system/daemons/init/ (user: anonymous) contain support for this ("halt -p" shuts down Linux and powers off the computer).

Then you might want to try `halt -p' instead of `shutdown -h now', but that probably won't help you either.

Is this a kernel bug?

Even though you might think this is a kernel bug (after all it did work with older kernels), it's not. It's a kernel feature! With this change, it's possible to halt your computer without doing a poweroff, and on some architectures (e.g. SPARC's) there's a use for this.

But what is the problem then?

Note: You may skip this and the next section, and jump straight to the solutions.

One of the first things that halt does, is to check whether you're in runlevel 0 or 6 (halt or reboot - if you entered the `halt -p' in a shell yourself, you probably weren't in any of these runlevels), and if you're weren't halt will call shutdown, which doesn't support the "-p" switch. Shutdown in turn calls init, which executes the scripts in /etc/rc.d/rc0.d, the last of these scripts to run (which on my system is called S00halt), then calls halt without a "-p" since the request for a power off has been lost long ago.

What can be done?

The first thing that can be done, is adding a "-p" switch to shutdown, this will mean two things:

Unfortunately, this doesn't solve the problem. Init doesn't have a "-p" switch either, this could be added, but I see two reasons not to do this:

There's a better solution. Shutdown, if invoked with the "-p" switch, can create an empty file called /poweroff. And halt, when invoked in runlevel 0 or 6 (it's only interesting in runlevel 0), can check for the existence of this file. There's a minor problem with this approach, when halt checks for the existence of this file, the filesystem is most-likely mounted read-only, so halt can't remove this file. There are (atleast) three ways to get this file removed:

  1. Make init remove it
  2. Make one of the initscripts remove it
  3. Make shutdown remove it, when invoked without a "-p" switch

I believe that approach number 3, is the best, since shutdown is the only of the three possibilities, that should worry about power off.

Solutions

The most simple (and for most people probably sufficient) solution

Note: This is based on a RedHat 5.0 installation, if you use another distribution (or just another RedHat version), things may differ a little, but you should be able to figure out, what to do.

Warning: There are some problems with making sysvinit 2.74 working with SuSE 5.3!

Start your favourite editor, load the file /etc/rc.d/init.d/halt. Find a line looking like this:

        command="halt"

and add a " -p".

Why you should choose this solution

Why you should not choose this solution

A solution that seems absolutely useless to me

Reserve a runlevel (e.g. 2) for poweroff.

Why you should choose this solution

Why you should not choose this solution

The (almost) complete solution

Do as described in the section "What can be done above". (You still don't need to read that section.)

You don't have to make all these changes yourself, I allready did, and you can find my patch for sysvinit v. 2.76 here.

Note: The patch is provided as is, and if it break things or just doesn't work, that's your problem.

You can download the source for Sysvinit version 2.76 (97K) from your favourite sunsite mirror (it's in the /pub/Linux/system/daemons/init directory). Or right here.

If you're not allready using version 2.76, you should install (and try) it unpatched first. Be sure to read the files README.RIGHT.NOW and doc/install.

To patch the source, place yourself in the directory right above the sysvinit-2.76 directory, and do a patch -p0 < sysvinit-2.76.patch.

When you have patched the source, you should recompile it by doing a make in the /src subdirectory. Now you can just copy the new shutdown and halt programs to /sbin. You should also copy man/shutdown.8 to /usr/man/man8/.

Now you should be ready to do a shutdown -p now and your computer will hopefully turn off.

If you go through with this, please mail me at grove@diku.dk, and tell me about your results.

Why you should choose this solution

Why you should not choose this solution

Choose for yourself:

The hard (and stupid) solution

Make your own changes to shutdown and halt.

Why you should choose this solution

Why you should not choose this solution


This page was written by Henrik Grove (grove@diku.dk). Last updated on january 25th 1999.