~peter-pearse/ubuntu/natty/insserv/prop001

« back to all changes in this revision

Viewing changes to debian/check-initd-order

  • Committer: Bazaar Package Importer
  • Author(s): Petter Reinholdtsen
  • Date: 2008-01-16 23:29:09 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080116232909-5v6j752kg141eouw
Tags: 1.10.0-5
* Made sure to initialize the badstate variable before it is used in
  update-bootsystem-insserv.
* Removed override files for uptimed and uptimed.sh, as the uptimed
  package now include the LSB headers.
* Make sure to give a proper error message when failing to enable
  dependency based boot system and insserv return an error code
  (Closes: #461141).

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
#
9
9
# To generate a graph, run it like this
10
10
#
11
 
#   check-initd-order -g > initorder.dotty && dotty initorder.dotty 
 
11
#   check-initd-order -g > initorder.dotty && dotty initorder.dotty
12
12
 
13
13
use strict;
14
14
use warnings;
41
41
     'networking'   => '$network',
42
42
     'syslog'       => '$syslog',
43
43
     'sysklogd'     => '$syslog',
44
 
     'klogd'        => '$syslog',
45
44
     'mountall'     => '$local_fs',
46
45
     'umountfs'     => '$local_fs',
47
 
     'sendsigs'     => '$local_fs',
48
46
     'mountnfs'     => '$remote_fs',
 
47
     'mountnfs-bootclean' => '$remote_fs',
49
48
     'umountnfs'    => '$remote_fs',
 
49
     'sendsigs'     => '$remote_fs',
50
50
     'hwclock'      => '$time',
51
51
     'ntpdate'      => '$time',
 
52
     'ntp-server'   => '$time',
 
53
     'named'        => '$named',
 
54
     'dnsmasq'      => '$named',
 
55
     'lwresd'       => '$named',
52
56
     'bind9'        => '$named',
53
57
     'portmap'      => '$portmap',
54
58
     );
55
59
 
 
60
my %provideslist;
56
61
my %scriptorder;
57
62
my %opts;
58
63
 
59
64
while($#ARGV >= 0 && ($_ = $ARGV[0]) =~ /^-/) {
60
 
        shift @ARGV;
61
 
        if (/^-([dgko])$/) { $opts{$1}++; next }
62
 
        if (/^-h|--help$/) { &usage; }
63
 
        &usage("unknown option");
 
65
        shift @ARGV;
 
66
        if (/^-([cdgko])$/) { $opts{$1}++; next }
 
67
        if (/^-h|--help$/) { &usage; }
 
68
        &usage("unknown option");
64
69
}
65
70
 
66
71
$debug = $opts{'d'};
76
81
sub usage {
77
82
    print STDERR "check-initd-order: error: @_\n" if ($#_ >= 0);
78
83
    print STDERR <<EOF;
79
 
usage: check-initd-order [-dgko]
 
84
usage: check-initd-order [-cdgko]
 
85
  -d enable debug output
 
86
  -o do not load override files
 
87
  -k use shutdown (reboot) sequence instead of boot sequence
 
88
  -g generate graph
 
89
  -c use combined boot and shutdown sequence (only for graphs)
80
90
EOF
81
91
    exit 1;
82
92
}
90
100
}
91
101
 
92
102
sub graph_addnode {
93
 
    my %lsbinfo = @_;
 
103
    my ($isstopseq, $lsbinforef) = @_;
 
104
    my %lsbinfo = %{$lsbinforef};
94
105
 
95
106
    unless ($lsbinfo{'provides'}) {
96
 
        print STDERR "error: File ". $lsbinfo{'file'} . " is missing the provides header\n";
97
 
        $lsbinfo{'provides'} = $lsbinfo{'file'};
 
107
        print STDERR "error: File ". $lsbinfo{'file'} . " is missing the provides header\n";
 
108
        $lsbinfo{'provides'} = $lsbinfo{'file'};
 
109
        $lsbinfo{'provides'} =~ s/^[SK]\d{2}//;
98
110
    }
99
111
 
100
112
    my $key = $opts{'k'} ? 'stop' : 'start';
 
113
    my $revkey = $opts{'k'} ? 'stop-after' : 'start-before';
101
114
    my @provides = split(/\s+/, $lsbinfo{'provides'});
102
115
    for my $name (@provides) {
103
 
        if (exists $sysmap{$name}) {
104
 
            graph_addnode('provides'      => $sysmap{$name},
105
 
                          "required-$key" => $name);
106
 
        }
 
116
        if (exists $sysmap{$name}) {
 
117
            graph_addnode($isstopseq,
 
118
                          {'provides'      => $sysmap{$name},
 
119
                          "required-$key" => $name});
 
120
        }
107
121
    }
108
122
 
109
123
    if (1 < @provides) {
110
 
        print STDERR "warning: Unable to properly handle multiple provides: @provides\n";
111
 
    }
112
 
 
113
 
    if (exists $lsbinfo{"required-$key"} && $lsbinfo{"required-$key"}) {
114
 
        my @depends = split(/\s+/, $lsbinfo{"required-$key"});
115
 
        for my $pkg (@depends) {
116
 
            print "\"$pkg\" -> \"$provides[0]\"[color=blue];\n";
117
 
        }
118
 
    }
119
 
    if (exists $lsbinfo{"should-$key"} && $lsbinfo{"should-$key"}) {
120
 
        my @depends = split(/\s+/, $lsbinfo{"should-$key"});
121
 
        for my $pkg (@depends) {
122
 
            print "\"$pkg\" -> \"$provides[0]\"[color=springgreen] ;\n";
123
 
        }
124
 
    }
125
 
    print "\"$provides[0]\" [shape=box];\n";
 
124
        my @providescopy = @provides;
 
125
        my $lastprovide = shift @providescopy;
 
126
        for my $provide (@providescopy) {
 
127
            graph_addnode($isstopseq,
 
128
                          {'provides'      => $lastprovide,
 
129
                           "required-$key" => $provide});
 
130
            graph_addnode($isstopseq,
 
131
                          {'provides'      => $provide,
 
132
                           "required-$key" => $lastprovide});
 
133
        }
 
134
    }
 
135
 
 
136
    for my $provide (@provides) {
 
137
        my %deps =
 
138
            (
 
139
             "required-$key" => 'blue',
 
140
             "should-$key" => 'springgreen',
 
141
             "$revkey" => 'yellow'
 
142
             );
 
143
 
 
144
        for $key (keys %deps) {
 
145
            if (exists $lsbinfo{$key} && $lsbinfo{$key}) {
 
146
                my @depends = split(/\s+/, $lsbinfo{$key});
 
147
                for my $pkg (@depends) {
 
148
                    my $color = $deps{$key};
 
149
                    if ($revkey eq $key) {
 
150
                        print "\"$provide\" -> \"$pkg\"[color=$color] ;\n";
 
151
                    } else {
 
152
                        print "\"$pkg\" -> \"$provide\"[color=$color] ;\n";
 
153
                    }
 
154
                }
 
155
            }
 
156
        }
 
157
 
 
158
        print "\"$provide\" [shape=box];\n";
 
159
    }
 
160
}
 
161
 
 
162
sub graph_generate_mode {
 
163
    my ($isstopseq) = @_;
 
164
    my @dirs = $isstopseq ? $rcmap{6} : ($rcmap{S}, $rcmap{2});
 
165
    for my $rcdir (@dirs) {
 
166
        chdir "$rcbase/$rcdir/.";
 
167
        my @scripts = $isstopseq ? <K*> : <S*>;
 
168
        for my $script (@scripts) {
 
169
            my $lsbinforef = load_lsb_tags("$rcbase/$rcdir/$script",
 
170
                                           $useoverrides);
 
171
 
 
172
            unless (defined $lsbinforef) {
 
173
                print STDERR "warning: LSB header missing in $rcbase/$rcdir/$script\n";
 
174
                $script =~ s/^[SK]\d{2}//;
 
175
                $lsbinforef = {'provides'       => $script,
 
176
                               'required-start' => '$remote_fs $syslog',
 
177
                               'required-stop'  => '$remote_fs $syslog'};
 
178
            }
 
179
            graph_addnode($isstopseq, $lsbinforef);
 
180
        }
 
181
    }
126
182
}
127
183
 
128
184
sub graph_generate {
129
185
    print "# Generating graph\n";
130
186
    print <<EOF;
131
187
digraph packages {
 
188
rankdir=LR;
132
189
concentrate=true;
133
190
EOF
134
 
    my @dirs = $opts{'k'} ? $rcmap{6} : ($rcmap{S}, $rcmap{2});
135
 
    for my $rcdir (@dirs) {
136
 
        chdir "$rcbase/$rcdir/.";
137
 
        my @scripts = $opts{'k'} ? <K*> : <S*>;
138
 
        for my $script (@scripts) {
139
 
            my $lsbinforef = load_lsb_tags("$rcbase/$rcdir/$script",
140
 
                                           $useoverrides);
141
 
            
142
 
            unless (defined $lsbinforef) {
143
 
                print STDERR "warning: LSB header missing in $rcbase/$rcdir/$script\n";
144
 
                $lsbinforef = {'provides' => $script};
145
 
            }
146
 
            my %lsbinfo = %{$lsbinforef};
147
 
            graph_addnode %lsbinfo;
148
 
        }
 
191
    if ($opts{'c'}) {
 
192
        graph_generate_mode();
 
193
        graph_generate_mode(1);
 
194
    } else {
 
195
        graph_generate_mode($opts{'k'});
149
196
    }
150
197
    print <<EOF;
151
198
}
152
199
EOF
153
200
}
154
201
 
 
202
sub check_deps {
 
203
    my ($lsbinforef, $tag, $order, $bootorder, $headername, $required) = @_;
 
204
    my %lsbinfo = %{$lsbinforef};
 
205
    my $name = $lsbinfo{'file'};
 
206
    if ($lsbinfo{$headername}) {
 
207
        my @depends = split(/\s+/, $lsbinfo{$headername});
 
208
        for my $dep (@depends) {
 
209
            if (! $required && exists $provideslist{$dep}) {
 
210
                unless (exists $scriptorder{$tag}{$dep}
 
211
                        and ("S" eq $tag
 
212
                             ? $scriptorder{$tag}{$dep} < $bootorder
 
213
                             : $scriptorder{$tag}{$dep} > $bootorder)) {
 
214
                    my $deporder;
 
215
                    if (exists $scriptorder{$tag}{$dep}) {
 
216
                        $deporder = $scriptorder{$tag}{$dep}
 
217
                    } else {
 
218
                        $deporder = exists $provideslist{$dep} ? $provideslist{$dep} : "?";
 
219
                    }
 
220
                    printf("Incorrect order %s@%s %s %s%s\n",
 
221
                           $dep, $deporder, 'S' eq $tag ? '>' : '<',
 
222
                           $name, $order);
 
223
                }
 
224
            }
 
225
        }
 
226
    }
 
227
}
 
228
 
155
229
sub check_bootorder {
156
230
    my $bootorder = 0;
157
231
    my @dirs = $opts{'k'} ? $rcmap{6} : ($rcmap{S}, $rcmap{2});
 
232
    my @scripts;
158
233
    for my $rcdir (@dirs) {
159
 
        chdir "$rcbase/$rcdir/.";
160
 
        my @scripts = $opts{'k'} ? <K*> : <S*>;
161
 
        for my $script (@scripts) {
162
 
            $bootorder++;
163
 
            my ($tag, $order, $name) = $script =~ m/^(.)(\d{2})(.+)$/;
164
 
 
165
 
            $scriptorder{$tag}{$name} = $bootorder;
166
 
            $scriptorder{$tag}{$sysmap{$name}} = $bootorder
167
 
                if (exists $sysmap{$name});
168
 
 
169
 
#           print "$script\n";
170
 
#           print "T: $tag O: $order N: $name\n";
171
 
            my $lsbinforef = load_lsb_tags("$rcbase/$rcdir/$script",
172
 
                                           $useoverrides);
173
 
 
174
 
            unless (defined $lsbinforef) {
175
 
                print STDERR "LSB header missing in $rcbase/$rcdir/$script\n";
176
 
                next;
177
 
            }
178
 
            my %lsbinfo = %{$lsbinforef};
179
 
 
180
 
            for my $provide (split(/\s+/, $lsbinfo{'provides'})) {
181
 
                $scriptorder{$tag}{$provide} = $bootorder;
182
 
                $scriptorder{$tag}{$sysmap{$provide}} = $bootorder
183
 
                    if (exists $sysmap{$provide});
184
 
            }
185
 
 
186
 
            if ('S' eq $tag) {
187
 
                if ($lsbinfo{'required-start'}) {
188
 
                    my @depends = split(/\s+/, $lsbinfo{'required-start'});
189
 
                    for my $dep (@depends) {
190
 
                        unless (exists $scriptorder{$tag}{$dep}
191
 
                                and $scriptorder{$tag}{$dep} < $bootorder) {
192
 
                            my $deporder;
193
 
                            if (exists $scriptorder{$tag}{$dep}) {
194
 
                                $deporder = $scriptorder{$tag}{$dep}
195
 
                            } else {
196
 
                                $deporder = "?";
197
 
                            }
198
 
                            print "Incorrect order " .
199
 
                                "$dep\@$deporder > $name\@$order\n";
200
 
                        }
201
 
                    }
202
 
                }
203
 
            }
204
 
            if ('K' eq $tag) {
205
 
            }
206
 
        }
 
234
#        chdir "$rcbase/$rcdir/.";
 
235
        push(@scripts, $opts{'k'} ? <$rcbase/$rcdir/K*> : <$rcbase/$rcdir/S*>);
 
236
    }
 
237
 
 
238
    if ($opts{'k'}) {
 
239
        $scriptorder{'K'}{'$all'} = 1;
 
240
    } else {
 
241
        # Calculate script order for the script before the scripts
 
242
        # with the last boot sequence number.
 
243
        my $tmpbootorder = 0;
 
244
        my $allorder = 0;
 
245
        my $maxorder = 0;
 
246
        my $maxbootorder = 0;
 
247
        for my $scriptpath (@scripts) {
 
248
            my $script = $scriptpath;
 
249
            $script =~ s%^.*/([^/]+)$%$1%;
 
250
            $tmpbootorder++;
 
251
            my ($tag, $order, $name) = $script =~ m/^(.)(\d{2})(.+)$/;
 
252
            if ($order > $maxorder) {
 
253
                $allorder = $maxbootorder;
 
254
                $maxbootorder = $tmpbootorder;
 
255
                $maxorder = $order;
 
256
            }
 
257
 
 
258
            my $lsbinforef = load_lsb_tags($scriptpath,
 
259
                                           $useoverrides);
 
260
 
 
261
            if (exists $lsbinforef->{'provides'}) {
 
262
                for my $provide (split(/\s+/, $lsbinforef->{'provides'})) {
 
263
                    $provideslist{$provide} = $order;
 
264
                }
 
265
            } else {
 
266
                $provideslist{$script} = $order;
 
267
            }
 
268
        }
 
269
        $scriptorder{'S'}{'$all'} = $allorder;
 
270
    }
 
271
    for my $scriptpath (@scripts) {
 
272
        my $script = $scriptpath;
 
273
        $script =~ s%^.*/([^/]+)$%$1%;
 
274
        $bootorder++;
 
275
        my ($tag, $order, $name) = $script =~ m/^(.)(\d{2})(.+)$/;
 
276
 
 
277
        $scriptorder{$tag}{$name} = $bootorder;
 
278
        $scriptorder{$tag}{$sysmap{$name}} = $bootorder
 
279
            if (exists $sysmap{$name});
 
280
 
 
281
#           print "$script\n";
 
282
#           print "T: $tag O: $order N: $name\n";
 
283
        my $lsbinforef = load_lsb_tags($scriptpath,
 
284
                                       $useoverrides);
 
285
 
 
286
        unless (defined $lsbinforef) {
 
287
            print STDERR "LSB header missing in $scriptpath\n";
 
288
            next;
 
289
        }
 
290
        my %lsbinfo = %{$lsbinforef};
 
291
 
 
292
        for my $provide (split(/\s+/, $lsbinfo{'provides'})) {
 
293
            $scriptorder{$tag}{$provide} = $bootorder;
 
294
            $scriptorder{$tag}{$sysmap{$provide}} = $bootorder
 
295
                if (exists $sysmap{$provide});
 
296
        }
 
297
 
 
298
        if ('S' eq $tag) {
 
299
            check_deps($lsbinforef, $tag, $order, $bootorder, 'required-start', 1);
 
300
            check_deps($lsbinforef, $tag, $order, $bootorder, 'should-start', 0);
 
301
#            check_deps($lsbinforef, 'K', $order, $bootorder, 'start-before', 0);
 
302
        }
 
303
        if ('K' eq $tag) {
 
304
            check_deps($lsbinforef, $tag, $order, $bootorder, 'required-stop', 1);
 
305
            check_deps($lsbinforef, $tag, $order, $bootorder, 'should-stop', 0);
 
306
#            check_deps($lsbinforef, 'S', $order, $bootorder, 'stop-after', 0);
 
307
        }
207
308
    }
208
309
}
209
310
 
212
313
    my $lsbinforef = load_lsb_tags_from_file($initfile);
213
314
 
214
315
    if ($useoverrides) {
215
 
        # Try override file
216
 
        $initfile = readlink($initfile) if (-l $initfile);
217
 
        my $basename = basename($initfile);
218
 
 
219
 
        # Only read shipped override file when initscript does not
220
 
        # contain LSB tags.
221
 
        if (! defined($lsbinforef) && -f "$overridepath/$basename") {
222
 
            print STDERR "Override $overridepath/$basename\n" if $debug;
223
 
            $lsbinforef = load_lsb_tags_from_file("$overridepath/$basename");
224
 
        }
225
 
 
226
 
        # Always read the host override in $hostoverridepath.
227
 
        if (-f "$hostoverridepath/$basename") {
228
 
            print STDERR "Override $hostoverridepath/$basename\n" if $debug;
229
 
            $lsbinforef = load_lsb_tags_from_file("$hostoverridepath/$basename");
230
 
        }
 
316
        # Try override file
 
317
        $initfile = readlink($initfile) if (-l $initfile);
 
318
        my $basename = basename($initfile);
 
319
 
 
320
        # Only read shipped override file when initscript does not
 
321
        # contain LSB tags.
 
322
        if (! defined($lsbinforef) && -f "$overridepath/$basename") {
 
323
            print STDERR "Override $overridepath/$basename\n" if $debug;
 
324
            $lsbinforef = load_lsb_tags_from_file("$overridepath/$basename");
 
325
        }
 
326
 
 
327
        # Always read the host override in $hostoverridepath.
 
328
        if (-f "$hostoverridepath/$basename") {
 
329
            print STDERR "Override $hostoverridepath/$basename\n" if $debug;
 
330
            $lsbinforef = load_lsb_tags_from_file("$hostoverridepath/$basename");
 
331
        }
231
332
 
232
333
    }
233
334
    return $lsbinforef;
248
349
    ### END INIT INFO
249
350
    unless (open(FILE, "<$file")) {
250
351
        warn "error: Unable to read $file";
251
 
        return;
 
352
        return;
252
353
    }
253
354
    my $found = 0;
254
355
    my ($provides, $requiredstart, $requiredstop, $shouldstart, $shouldstop);
 
356
    my ($startbefore, $stopafter);
255
357
    while (<FILE>) {
256
 
        chomp;
257
 
        $found = 1 if (m/\#\#\# BEGIN INIT INFO/);
258
 
        next unless $found;
259
 
        last if (m/\#\#\# END INIT INFO/);
 
358
        chomp;
 
359
        $found = 1 if (m/\#\#\# BEGIN INIT INFO/);
 
360
        next unless $found;
 
361
        last if (m/\#\#\# END INIT INFO/);
260
362
 
261
 
        $provides = $1      if (m/^\# provides:\s+(\S*.*\S+)\s*$/i);
262
 
        $requiredstart = $1 if (m/^\# required-start:\s+(\S*.*\S+)\s*$/i);
263
 
        $requiredstop = $1  if (m/^\# required-stop:\s+(\S*.*\S+)\s*$/i);
264
 
        $shouldstart = $1   if (m/^\# should-start:\s+(\S*.*\S+)\s*$/i);
265
 
        $shouldstop = $1    if (m/^\# should-stop:\s+(\S*.*\S+)\s*$/i);
 
363
        $provides = $1      if (m/^\# provides:\s+(\S*.*\S+)\s*$/i);
 
364
        $requiredstart = $1 if (m/^\# required-start:\s+(\S*.*\S+)\s*$/i);
 
365
        $requiredstop = $1  if (m/^\# required-stop:\s+(\S*.*\S+)\s*$/i);
 
366
        $shouldstart = $1   if (m/^\# should-start:\s+(\S*.*\S+)\s*$/i);
 
367
        $shouldstop = $1    if (m/^\# should-stop:\s+(\S*.*\S+)\s*$/i);
 
368
        $startbefore = $1   if (m/^\# X-Start-Before:\s+(\S*.*\S+)\s*$/i);
 
369
        $stopafter = $1     if (m/^\# X-Stop-After:\s+(\S*.*\S+)\s*$/i);
266
370
    }
267
371
    close(FILE);
268
372
 
270
374
 
271
375
#    print "Provides: $provides\n" if $provides;
272
376
    return {
273
 
            'provides'       => $provides,
274
 
            'required-start' => $requiredstart,
275
 
            'required-stop'  => $requiredstop,
276
 
            'should-start'   => $shouldstart,
277
 
            'should-stop'    => $shouldstop,
278
 
            'file'           => $file,
279
 
            };
 
377
            'provides'       => $provides,
 
378
            'required-start' => $requiredstart,
 
379
            'required-stop'  => $requiredstop,
 
380
            'should-start'   => $shouldstart,
 
381
            'should-stop'    => $shouldstop,
 
382
            'start-before'   => $startbefore,
 
383
            'stop-after'     => $stopafter,
 
384
            'file'           => $file,
 
385
            };
280
386
}