On 22 Mar 2001, Guillaume Cottenceau wrote:
> Okay, after talking with fred, we came with a solution to this problem.
> Actually, the current way of doing the things is okay: when you do a
> chkconfig --level 345 httpd off, it only modifies the local states of the
> sysv links in the initscripts for each runlevel.
> The information on whether a service should be started is not kept as
> links; the links are just the way the system is used. The information is
> kept after a special token named "chkconfig:" in the header of the
> initscript.
> If you modify this rather than modifying with chkconfig --level, the
> upgrade should be smooth and keep your config.
> I'm currently working on a patch to chkconfig, so that chkconfig --level
> will modify the header of the initscript accordingly.
It would (IMO) be more elegant if the definitive start/stop status was
represented by the symlinks in /etc/rc.d/init.d - this is how it's meant
to work (at least according to the chkconfig manual).
You might find the following Perl script (which I knocked together today,
practically learning Perl as I went along) to be helpful. It reads the
current start/stop status according to the symlinks and writes out a
modified version of the /etc/rc.d/init.d/script that reflects this. The
idea is that, during an upgrade, the process would be:
1. Check to see if service is running ("service xxx status")
2. Stop the service (temporarily - "service xxx stop")
3. Upgrade the files
4. Run my script to modify the new /etc/rc.d/init.d/xxx script to edit
the initscript to reflect the administrator's previous settings.
Please feel free to edit (or completely rewrite) the script - I'm not a
Perl programmer so there's probably loads wrong with it. Note that it
currently writes the updated initscript to stdout, rather than replacing
the actual initscript file.
Michael
#!/usr/bin/perl
use IO::File;
$service = $ARGV[0];
$servicefile="/etc/rc.d/init.d/".$service;
if ( ! -f $servicefile )
{
die "No such service: ".$service;
}
$chkconfiglist = `/sbin/chkconfig --list $service`;
$runlevels = "";
for ( $runlevel = 0 ; $runlevel <= 6; $runlevel++ )
{
if ( $chkconfiglist =~ m/$runlevel:on/g )
{
$runlevels = $runlevels.$runlevel;
}
}
if ( $runlevels == "" )
{
$runlevels = "-";
}
$handle = new IO::File;
open( $handle, $servicefile );
while ( <$handle> )
{
$_ =~ s/# chkconfig: [-0-9]* /# chkconfig: $runlevels /;
print $_;
}
close ( $handle );