92
102
sub graph_addnode {
103
my ($isstopseq, $lsbinforef) = @_;
104
my %lsbinfo = %{$lsbinforef};
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}//;
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);
116
if (exists $sysmap{$name}) {
117
graph_addnode($isstopseq,
118
{'provides' => $sysmap{$name},
119
"required-$key" => $name});
109
123
if (1 < @provides) {
110
print STDERR "warning: Unable to properly handle multiple provides: @provides\n";
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";
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";
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});
136
for my $provide (@provides) {
139
"required-$key" => 'blue',
140
"should-$key" => 'springgreen',
141
"$revkey" => 'yellow'
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";
152
print "\"$pkg\" -> \"$provide\"[color=$color] ;\n";
158
print "\"$provide\" [shape=box];\n";
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",
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'};
179
graph_addnode($isstopseq, $lsbinforef);
128
184
sub graph_generate {
129
185
print "# Generating graph\n";
131
187
digraph packages {
132
189
concentrate=true;
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",
142
unless (defined $lsbinforef) {
143
print STDERR "warning: LSB header missing in $rcbase/$rcdir/$script\n";
144
$lsbinforef = {'provides' => $script};
146
my %lsbinfo = %{$lsbinforef};
147
graph_addnode %lsbinfo;
192
graph_generate_mode();
193
graph_generate_mode(1);
195
graph_generate_mode($opts{'k'});
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}
212
? $scriptorder{$tag}{$dep} < $bootorder
213
: $scriptorder{$tag}{$dep} > $bootorder)) {
215
if (exists $scriptorder{$tag}{$dep}) {
216
$deporder = $scriptorder{$tag}{$dep}
218
$deporder = exists $provideslist{$dep} ? $provideslist{$dep} : "?";
220
printf("Incorrect order %s@%s %s %s%s\n",
221
$dep, $deporder, 'S' eq $tag ? '>' : '<',
155
229
sub check_bootorder {
156
230
my $bootorder = 0;
157
231
my @dirs = $opts{'k'} ? $rcmap{6} : ($rcmap{S}, $rcmap{2});
158
233
for my $rcdir (@dirs) {
159
chdir "$rcbase/$rcdir/.";
160
my @scripts = $opts{'k'} ? <K*> : <S*>;
161
for my $script (@scripts) {
163
my ($tag, $order, $name) = $script =~ m/^(.)(\d{2})(.+)$/;
165
$scriptorder{$tag}{$name} = $bootorder;
166
$scriptorder{$tag}{$sysmap{$name}} = $bootorder
167
if (exists $sysmap{$name});
170
# print "T: $tag O: $order N: $name\n";
171
my $lsbinforef = load_lsb_tags("$rcbase/$rcdir/$script",
174
unless (defined $lsbinforef) {
175
print STDERR "LSB header missing in $rcbase/$rcdir/$script\n";
178
my %lsbinfo = %{$lsbinforef};
180
for my $provide (split(/\s+/, $lsbinfo{'provides'})) {
181
$scriptorder{$tag}{$provide} = $bootorder;
182
$scriptorder{$tag}{$sysmap{$provide}} = $bootorder
183
if (exists $sysmap{$provide});
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) {
193
if (exists $scriptorder{$tag}{$dep}) {
194
$deporder = $scriptorder{$tag}{$dep}
198
print "Incorrect order " .
199
"$dep\@$deporder > $name\@$order\n";
234
# chdir "$rcbase/$rcdir/.";
235
push(@scripts, $opts{'k'} ? <$rcbase/$rcdir/K*> : <$rcbase/$rcdir/S*>);
239
$scriptorder{'K'}{'$all'} = 1;
241
# Calculate script order for the script before the scripts
242
# with the last boot sequence number.
243
my $tmpbootorder = 0;
246
my $maxbootorder = 0;
247
for my $scriptpath (@scripts) {
248
my $script = $scriptpath;
249
$script =~ s%^.*/([^/]+)$%$1%;
251
my ($tag, $order, $name) = $script =~ m/^(.)(\d{2})(.+)$/;
252
if ($order > $maxorder) {
253
$allorder = $maxbootorder;
254
$maxbootorder = $tmpbootorder;
258
my $lsbinforef = load_lsb_tags($scriptpath,
261
if (exists $lsbinforef->{'provides'}) {
262
for my $provide (split(/\s+/, $lsbinforef->{'provides'})) {
263
$provideslist{$provide} = $order;
266
$provideslist{$script} = $order;
269
$scriptorder{'S'}{'$all'} = $allorder;
271
for my $scriptpath (@scripts) {
272
my $script = $scriptpath;
273
$script =~ s%^.*/([^/]+)$%$1%;
275
my ($tag, $order, $name) = $script =~ m/^(.)(\d{2})(.+)$/;
277
$scriptorder{$tag}{$name} = $bootorder;
278
$scriptorder{$tag}{$sysmap{$name}} = $bootorder
279
if (exists $sysmap{$name});
282
# print "T: $tag O: $order N: $name\n";
283
my $lsbinforef = load_lsb_tags($scriptpath,
286
unless (defined $lsbinforef) {
287
print STDERR "LSB header missing in $scriptpath\n";
290
my %lsbinfo = %{$lsbinforef};
292
for my $provide (split(/\s+/, $lsbinfo{'provides'})) {
293
$scriptorder{$tag}{$provide} = $bootorder;
294
$scriptorder{$tag}{$sysmap{$provide}} = $bootorder
295
if (exists $sysmap{$provide});
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);
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);