Archive wide checking of init.d scripts - summary

Petter Reinholdtsen pere at hungry.com
Tue Aug 25 21:19:26 UTC 2009


I wrote a script to check all the init.d scripts available from
bellini.debian.org:/org/lintian.debian.org/laboratory/binary/, and
report obvious errors in the LSB headers.  Here is a list.

error: unable to read apcupsd/init.d/ups-monitor at ./check-archive-initd-scripts line 95.
error: script connman/init.d/connman is missing LSB header
error: script powstatd/init.d/powerfail is missing LSB header
error: unable to read thin/init.d/thin at ./check-archive-initd-scripts line 95.
error: duplicate provide $PROJECT in scripts fossology-scheduler-single/init.d/fossology fossology-scheduler/init.d/fossology
error: duplicate provide $network in scripts virtual whereami/init.d/whereami
error: duplicate provide bandwidthd in scripts bandwidthd-pgsql/init.d/bandwidthd bandwidthd/init.d/bandwidthd
error: duplicate provide block in scripts gnbd-client/init.d/gnbd-client gnbd-server/init.d/gnbd-server
error: duplicate provide cluster in scripts clvm/init.d/clvm cman/init.d/cman iscsitarget/init.d/iscsitarget rgmanager/init.d/rgmanager
error: duplicate provide console-screen in scripts console-tools/init.d/console-screen.sh kbd/init.d/console-screen.kbd.sh
error: duplicate provide daemon in scripts clvm/init.d/clvm mailscanner/init.d/mailscanner
error: duplicate provide device in scripts gnbd-client/init.d/gnbd-client gnbd-server/init.d/gnbd-server
error: duplicate provide dicod in scripts dicod/init.d/dicod dicod/init.d/dictd
error: duplicate provide drbd in scripts drbd0.7-utils/init.d/drbd drbd8-utils/init.d/drbd
error: duplicate provide filesystem in scripts gfs-tools/init.d/gfs-tools gfs2-tools/init.d/gfs2-tools
error: duplicate provide firebird-server in scripts firebird2.0-classic/init.d/firebird2.0-classic firebird2.0-super/init.d/firebird2.0-super firebird2.1-classic/init.d/firebird2.1-classic firebird2.1-super/init.d/firebird2.1-super
error: duplicate provide gearmand in scripts gearman-job-server/init.d/gearman-job-server gearman-server/init.d/gearman-server
error: duplicate provide genpower in scripts genpower/init.d/genpower genpower/init.d/ups-monitor
error: duplicate provide global in scripts gfs-tools/init.d/gfs-tools gfs2-tools/init.d/gfs2-tools gnbd-client/init.d/gnbd-client gnbd-server/init.d/gnbd-server
error: duplicate provide inn2 in scripts inn2-lfs/init.d/inn2 inn2/init.d/inn2
error: duplicate provide lpd in scripts lpr/init.d/lpd lprng/init.d/lprng
error: duplicate provide lvm in scripts clvm/init.d/clvm lvm2/init.d/lvm2
error: duplicate provide mail-transport-agent in scripts postfix/init.d/postfix xmail/init.d/xmail
error: duplicate provide manager in scripts cman/init.d/cman iscsitarget/init.d/iscsitarget rgmanager/init.d/rgmanager
error: duplicate provide network in scripts gnbd-client/init.d/gnbd-client gnbd-server/init.d/gnbd-server
error: duplicate provide networking in scripts netbase/init.d/networking netscript-2.4/init.d/netscript
error: duplicate provide postgresql in scripts postgresql-8.3/init.d/postgresql-8.3 postgresql-8.4/init.d/postgresql-8.4
error: duplicate provide powstatd in scripts powstatd/init.d/powstatd powstatd/init.d/ups-monitor
error: duplicate provide pure-ftpd in scripts pure-ftpd-ldap/init.d/pure-ftpd-ldap pure-ftpd-mysql/init.d/pure-ftpd-mysql pure-ftpd-postgresql/init.d/pure-ftpd-postgresql pure-ftpd/init.d/pure-ftpd
error: duplicate provide radiusd in scripts freeradius/init.d/freeradius xtradius/init.d/radiusd
error: duplicate provide root-file-server in scripts root-system-rootd/init.d/root-system-rootd root-system-xrootd/init.d/root-system-xrootd
error: duplicate provide skeleton in scripts dspam/init.d/dspam initscripts/init.d/skeleton snmptt/init.d/snmptt
error: duplicate provide slpd in scripts portsentry/init.d/portsentry slpd/init.d/slpd
error: duplicate provide snort in scripts snort-mysql/init.d/snort snort-pgsql/init.d/snort snort/init.d/snort
error: duplicate provide squid in scripts squid/init.d/squid squid3/init.d/squid3
error: duplicate provide sshd in scripts lsh-server/init.d/lsh-server openssh-server/init.d/ssh
error: duplicate provide sudo in scripts sudo-ldap/init.d/sudo sudo/init.d/sudo
error: duplicate provide syslog in scripts inetutils-syslogd/init.d/inetutils-syslogd syslog-ng/init.d/syslog-ng
error: duplicate provide vpn in scripts openvpn/init.d/openvpn strongswan-starter/init.d/ipsec strongswan/init.d/ipsec
error: duplicate provide xfs in scripts xfs/init.d/xfs xfstt/init.d/xfstt
error: duplicate provide zabbix-proxy in scripts zabbix-proxy-mysql/init.d/zabbix-proxy zabbix-proxy-pgsql/init.d/zabbix-proxy
error: duplicate provide zabbix-server in scripts zabbix-server-mysql/init.d/zabbix-server zabbix-server-pgsql/init.d/zabbix-server
error: duplicate provide zephyrd in scripts zephyr-server-krb5/init.d/zephyrd zephyr-server/init.d/zephyrd
error: script am-utils/init.d/am-utils relate to non-existing provides: nis
error: script autofs5/init.d/autofs relate to non-existing provides: $ypbind
error: script blootbot/init.d/blootbot relate to non-existing provides: mysql-ndb mysql-ndb-mgm
error: script capi4hylafax/init.d/capi4hylafax relate to non-existing provides: faxq hfaxd capiinit isdnactivecards
error: script clvm/init.d/clvm relate to non-existing provides: cman
error: script cman/init.d/cman relate to non-existing provides: ssh
error: script controlaula/init.d/sirvecole relate to non-existing provides: avahi-daemon
error: script debian-edu-config/init.d/fetch-ldap-cert relate to non-existing provides: apache
error: script dhcp-probe/init.d/dhcp-probe relate to non-existing provides: $networking
error: script dmucs/init.d/dmucs relate to non-existing provides: loadavg
error: script fail2ban/init.d/fail2ban relate to non-existing provides: ipmasq
error: script freeradius/init.d/freeradius relate to non-existing provides: ldap
error: script g15daemon/init.d/g15daemon relate to non-existing provides: ldm sdm
error: script gfs-tools/init.d/gfs-tools relate to non-existing provides: cman
error: script gfs2-tools/init.d/gfs2-tools relate to non-existing provides: cman
error: script hpoj/init.d/hpoj relate to non-existing provides: cupsys
error: script ltsp-controlaula/init.d/ltsp-sirvecole relate to non-existing provides: avahi-daemon
error: script mandos/init.d/mandos relate to non-existing provides: avahi-daemon
error: script mumble-server/init.d/mumble-server relate to non-existing provides: $mysql
error: script mythtv-status/init.d/mythtv-status relate to non-existing provides: $mythtv-backend
error: script open-iscsi/init.d/umountiscsi.sh relate to non-existing provides: open-iscsi
error: script openais-legacy/init.d/openais-legacy relate to non-existing provides: $null
error: script pdnsd/init.d/pdnsd relate to non-existing provides: $networking
error: script python-poker-network/init.d/python-poker-network relate to non-existing provides: mysqld
error: script qpsmtpd/init.d/qpsmtpd relate to non-existing provides: $mail-transport-agent $clamav-daemon $spamassassin
error: script randomsound/init.d/randomsound relate to non-existing provides: $alsa
error: script rgmanager/init.d/rgmanager relate to non-existing provides: cman clvm gfs-tools gfs2-tools
error: script smokeping/init.d/smokeping relate to non-existing provides: apache
error: script speech-dispatcher/init.d/speech-dispatcher relate to non-existing provides: festival
error: script synce-hal-bluetooth/init.d/synce-hal-bluetooth relate to non-existing provides: $bluetooth $hal
error: script tenshi/init.d/tenshi relate to non-existing provides: $mail
error: script watchdog/init.d/wd_keepalive relate to non-existing provides: bittorrent
error: script webgui/init.d/webgui relate to non-existing provides: $apache

Most of these errors are reported to BTS already, and listed on
<URL:http://bugs.debian.org/cgi-bin/pkgreport.cgi?users=initscripts-ng-devel@lists.alioth.debian.org>.
The remaining ones should be reported too, of course.


This is the script I used to check for errors.  It should have some
runlevel related checks too.  Did not find time to implement it yet.
The script can also check if $remote_fs and $local_fs are likely
missing as dependencies, but I did not see the point of reporting this
without also checking the runlevel settings, as missing them will not
change the boot and shutdown sequence in runlevels 0-6.

#!/usr/bin/perl

use warnings;
use strict;
use File::Basename;

my $warn = 0;

my @scripts = @ARGV;
@scripts = </org/lintian.debian.org/laboratory/binary/*/init.d/*>
    unless @scripts;

my %scriptinfo;
my %provides;

my @virts = qw($local_fs $remote_fs $syslog $time $named
               $portmap $network $all);
my @depheaders = qw(required-start required-stop should-start
                    should-stop x-start-before x-stop-after);
my $lsbheaders = "Provides|Required-Start|Required-Stop|Default-Start|Default-Stop";
my $optheaders = "x-start-before|x-stop-after|should-start|should-stop";

for my $virt (@virts) {
    $provides{$virt} = ['virtual'];
}

# Ignore obsolete scripts, as these are unlikely to cause problems.
for my $old (qw(glibc devfsd hotplug evms raid2)) {
    $provides{$old} = ['obsolete'];
}

# First pass to find the obvious problems.
for my $initdscript (@scripts) {
    my %lsbinfo = parse_lsb_header($initdscript);
    $scriptinfo{$initdscript} = \%lsbinfo;
    next unless ($lsbinfo{'found'});

    my %checked;
    for my $provide (split(/[ ,\t]+/, $lsbinfo{provides})) {
        if (exists $provides{$provide}) {
            push(@{$provides{$provide}}, $initdscript)
        } else {
            $provides{$provide} = [$initdscript];
        }
        $checked{$provide} = 1;
    }
    my $basename = basename($initdscript, ".sh");
    warning("script $initdscript do not provide its own name")
        unless exists $checked{$basename};

}

for my $provide (sort keys %provides) {
    if (1 < scalar @{$provides{$provide}}) {
        error("duplicate provide $provide in scripts "
              . join(" ", @{$provides{$provide}}));
    }
}

# Second pass, to see which dependencies are missing
for my $initdscript (@scripts) {
    next unless ($scriptinfo{$initdscript}->{'found'});
    my %checked;
    my @missing = ();
    for my $header (@depheaders) {
        my $list = $scriptinfo{$initdscript}->{$header};
        next unless defined $list;
        for my $facility (split(/[ ,\t]+/, $list)) {
            next if exists $checked{$facility};
            $checked{$facility} = 1;
            push(@missing, $facility)
                unless exists $provides{$facility};
        }
    }
    error("script $initdscript relate to non-existing provides: "
          . join(" ", @missing)) if (@missing);

    if (!exists $checked{'$remote_fs'}
        && $scriptinfo{$initdscript}->{'need_remove_fs'}) {
        warning("script $initdscript possibly missing dependency on \$remote_fs");
    } elsif (!exists $checked{'$local_fs'}
             && !exists $checked{'$remote_fs'}
             && $scriptinfo{$initdscript}->{'need_local_fs'}) {
        warning("script $initdscript possibly missing dependency on \$local_fs");
    }

}

exit 0;

sub parse_lsb_header {
    my $initdscript = shift;
    my %lsbinfo;
    unless (open(INIT, "<", $initdscript)) {
        warn "error: unable to read $initdscript";
        return undef;
    }
    my $inheader = 0;
    while (<INIT>) {
#        print;
        chomp;
        if (m/^\#\#\# BEGIN INIT INFO\s*$/) {
            $lsbinfo{'found'} = 1;
            $inheader = 1;
        }
        $inheader = 0 if (m/\#\#\# END INIT INFO$/);
        if ($inheader
            && m/^\# ($lsbheaders|$optheaders):\s*(\S?.*)$/i) {
#            print "$1\n";
            $lsbinfo{lc($1)} = $2;
        }
        $lsbinfo{'need_remove_fs'} = 1 if m%/usr/s?bin/%;
        $lsbinfo{'need_local_fs'} = 1 if m%/var/%;
    }
    close(INIT);

    # Check that all the required headers are present
    if (!$lsbinfo{'found'}) {
        error("script $initdscript is missing LSB header");
    } else {
        for my $key (split(/\|/, lc($lsbheaders))) {
            if (!exists $lsbinfo{$key}) {
                error("$initdscript missing LSB keyword '$key'");
            }
        }
    }
    return %lsbinfo
}

sub info {
    print "info: @_\n";
}

sub warning {
    print "warning: @_\n" if $warn;
}

sub error {
    print "error: @_\n";
}



More information about the initscripts-ng-devel mailing list