a93c48f891a040718942ab2bd357f27c02930f52
[debian/amanda] / installcheck / Amanda_DB_Catalog.pl
1 # Copyright (c) 2008 Zmanda Inc.  All Rights Reserved.
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License version 2 as published
5 # by the Free Software Foundation.
6 #
7 # This program is distributed in the hope that it will be useful, but
8 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10 # for more details.
11 #
12 # You should have received a copy of the GNU General Public License along
13 # with this program; if not, write to the Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 #
16 # Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
17 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
18
19 # TODO: check large values of 'kb'
20
21 use Test::More tests => 35;
22 use File::Path;
23 use strict;
24
25 use lib "@amperldir@";
26 use Installcheck::Config;
27 use Amanda::Config qw( :init :getconf config_dir_relative );
28 use Amanda::DB::Catalog;
29
30 # set up and load a simple config
31 my $testconf = Installcheck::Config->new();
32 $testconf->write();
33 config_init($CONFIG_INIT_EXPLICIT_NAME, 'TESTCONF') == $CFGERR_OK
34     or die("Could not load test config");
35
36 # test functions against an empty set of logfiles
37
38 is_deeply([ Amanda::DB::Catalog::get_write_timestamps() ], [],
39     "No write_timestamps in an empty catalog");
40
41 is_deeply(Amanda::DB::Catalog::get_latest_write_timestamp(), undef,
42     "No latest write_timestamp in an empty catalog");
43
44 is_deeply([ Amanda::DB::Catalog::get_dumps() ], [],
45     "No dumpfiles in an empty catalog");
46
47 # and add some logfiles to query, and a corresponding tapelist, while also gathering
48 # a list of dumpfiles for comparison with the results from Amanda::DB::Catalog
49 my $logdir = config_dir_relative(getconf($CNF_LOGDIR));
50 my $tapelist_fn = config_dir_relative(getconf($CNF_TAPELIST));
51 my $output;
52 my $write_timestamp;
53 my %dumpfiles;
54 open (my $tapelist, ">", $tapelist_fn);
55 while (<DATA>) {
56     # skip comments
57     next if (/^#/ or /^\S*$/);
58
59     # add to tapelist
60     if (/^:tapelist (\d+) (\S+)\s*$/) {
61         print $tapelist "$1 $2 reuse\n";
62         next;
63     }
64     
65     # new logfile
66     if (/^::: (.*)/) {
67         open $output, ">", "$logdir/$1" or die("Could not open $1 for writing: $!");
68         next;
69     }
70
71     # write_timestamp
72     if (/^:timestamp (\d+)/) {
73         $write_timestamp = $1;
74         next;
75     }
76
77     # new dumpfile
78     if (/^:dumpfile (\S+) (\S+) (\S+) (\S+) (\d+) (\S+) (\d+) (\d+) (\d+) (\S+) (\S+) (\d+)/) {
79         $dumpfiles{$1} = {
80             'dump_timestamp' => $2,     'hostname' => $3,           'diskname' => $4,
81             'level' => $5+0,            'label' => $6,              'filenum' => $7+0,
82             'partnum' => $8+0,          'nparts' => $9+0,           'status' => $10,
83             'sec' => $11+0.0,           'kb' => $12+0,
84             'write_timestamp' => $write_timestamp,
85         };
86         next;
87     }
88
89     die("syntax error") if (/^:/);
90
91     print $output $_;
92 }
93 close($output);
94 close($tapelist);
95 Amanda::DB::Catalog::_clear_cache();
96
97 ##
98 # Test the timestamps
99
100 is_deeply([ Amanda::DB::Catalog::get_write_timestamps(), ],
101     [ '20080111000000', '20080222222222', '20080313133333', '20080414144444' ],
102     "get_write_timestamps returns all logfile datestamps in proper order, with zero-padding");
103
104 is(Amanda::DB::Catalog::get_latest_write_timestamp(), '20080414144444',
105     "get_latest_write_timestamp correctly returns the latest write timestamp");
106
107 ##
108 # test get_dumps and sort_dumps
109
110 # get dumps filtered by a regexp on the key
111 sub dump_names($) {
112     my ($expr) = @_; 
113     my @selected_keys = grep { $_ =~ $expr } keys %dumpfiles;
114     return map { $dumpfiles{$_} } @selected_keys;
115 }
116
117 # get dumps filtered by an expression on the dumpfile itself
118 sub dumps(&) {
119     my ($block) = @_; 
120     return grep { &$block } values %dumpfiles;
121 }
122
123 # put @_ in a canonical order
124 sub sortdumps {
125     map {
126         # convert bigints to strings so is_deeply doesn't get confused
127         $_->{'level'} = "$_->{level}";
128         $_->{'filenum'} = "$_->{filenum}";
129         $_->{'kb'} = "$_->{kb}";
130         $_;
131     } sort {
132         $a->{'label'} cmp $b->{'label'}
133             or $a->{'filenum'} cmp $b->{'filenum'}
134     }
135     @_;
136 }
137
138 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps() ],
139     [ sortdumps dump_names qr/.*/ ],
140     "get_dumps returns all dumps when given no parameters");
141
142 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(write_timestamp => '20080111000000') ],
143     [ sortdumps dump_names qr/somebox_lib_20080111/ ],
144     "get_dumps parameter write_timestamp");
145 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(write_timestamp => '20080111') ],
146     [ sortdumps dump_names qr/somebox_lib_20080111/ ],
147     "get_dumps accepts a short write_timestamp and zero-pads it");
148 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(write_timestamps => ['20080111000000','20080222222222']) ],
149     [ sortdumps dump_names qr/(20080111|20080222222222)$/ ],
150     "get_dumps parameter write_timestamps");
151
152 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(dump_timestamp => '20080111000000') ],
153     [ sortdumps dump_names qr/somebox_lib_20080111/ ],
154     "get_dumps parameter dump_timestamp");
155 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(dump_timestamp => '20080111') ],
156     [ sortdumps dump_names qr/somebox_lib_20080111/ ],
157     "get_dumps accepts a short dump_timestamp and zero-pads it");
158 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(dump_timestamps => ['20080111000000','20080222222222']) ],
159     [ sortdumps dump_names qr/(20080111|20080222222222)$/ ],
160     "get_dumps parameter dump_timestamps");
161 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(dump_timestamp_match => '200801-2') ],
162     [ sortdumps dump_names qr/20080[12]/ ],
163     "get_dumps parameter dump_timestamp_match");
164
165 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(hostname => 'otherbox') ],
166     [ sortdumps dump_names qr/^otherbox_/ ],
167     "get_dumps parameter hostname");
168 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(hostnames => ['otherbox','somebox']) ],
169     [ sortdumps dump_names qr/^(otherbox_|somebox_)/ ],
170     "get_dumps parameter hostnames");
171 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(hostname_match => '*box') ],
172     [ sortdumps dump_names qr/box/ ],
173     "get_dumps parameter hostname_match");
174
175 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(diskname => '/lib') ],
176     [ sortdumps dump_names qr/_lib_/ ],
177     "get_dumps parameter diskname");
178 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(disknames => ['/lib','/usr/bin']) ],
179     [ sortdumps dump_names qr/(_lib_|_usr_bin_)/ ],
180     "get_dumps parameter disknames");
181 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(diskname_match => '/usr') ],
182     [ sortdumps dump_names qr/_usr_/ ],
183     "get_dumps parameter diskname_match");
184
185 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(label => 'Conf-001') ],
186     [ sortdumps dumps { $_->{'label'} eq 'Conf-001' } ],
187     "get_dumps parameter label");
188 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(labels => ['Conf-002','Conf-003']) ],
189     [ sortdumps dumps { $_->{'label'} eq 'Conf-002' or $_->{'label'} eq 'Conf-003' } ],
190     "get_dumps parameter labels");
191
192 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(level => 0) ],
193     [ sortdumps dumps { $_->{'level'} == 0 } ],
194     "get_dumps parameter level");
195 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(levels => [ 1 ]) ],
196     [ sortdumps dumps { $_->{'level'} == 1 } ],
197     "get_dumps parameter levels");
198
199 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(status => "OK") ],
200     [ sortdumps dumps { $_->{'status'} eq "OK" } ],
201     "get_dumps parameter status = OK");
202
203 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(status => "PARTIAL") ],
204     [ sortdumps dumps { $_->{'status'} eq "PARTIAL" } ],
205     "get_dumps parameter status = PARTIAL");
206
207 ## more complex, multi-parameter queries
208
209 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(hostname => 'somebox',
210                                                      diskname_match => '/lib') ],
211     [ sortdumps dump_names qr/^somebox_lib_/ ],
212     "get_dumps parameters hostname and diskname_match");
213
214 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(write_timestamp => '20080313133333',
215                                                      dump_timestamp => '20080311131133') ],
216     [ sortdumps dumps { $_->{'dump_timestamp'} eq '20080311131133' 
217                     and $_->{'write_timestamp'} eq '20080313133333' } ],
218     "get_dumps parameters write_timestamp and dump_timestamp");
219
220 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(write_timestamp => '20080414144444',
221                                                      status => 'OK') ],
222     [ ], # there were no OK dumps on that date
223     "get_dumps parameters write_timestamp status");
224
225 ## test sorting
226 # (this is not exhaustive, as that would make the tests more complex than the
227 #  code being tested)
228
229 is_deeply([ Amanda::DB::Catalog::sort_dumps(['write_timestamp'],
230                 @dumpfiles{'somebox_lib_20080222222222','somebox_lib_20080111'}) ],
231               [ @dumpfiles{'somebox_lib_20080111','somebox_lib_20080222222222'} ],
232     "sort by write_timestamps");
233 is_deeply([ Amanda::DB::Catalog::sort_dumps(['-write_timestamp'],
234                 @dumpfiles{'somebox_lib_20080111','somebox_lib_20080222222222'}) ],
235               [ @dumpfiles{'somebox_lib_20080222222222','somebox_lib_20080111'} ],
236     "sort by write_timestamps, reverse");
237
238 is_deeply([ Amanda::DB::Catalog::sort_dumps(['hostname', '-diskname', 'write_timestamp'],
239                 @dumpfiles{
240                     'somebox_lib_20080222222222',
241                     'somebox_usr_bin_20080313133333',
242                     'somebox_lib_20080313133333_p4',
243                     'otherbox_lib_20080313133333',
244                     'somebox_lib_20080111',
245                     }) ],
246               [ @dumpfiles{
247                     'otherbox_lib_20080313133333',
248                     'somebox_usr_bin_20080313133333',
249                     'somebox_lib_20080111',
250                     'somebox_lib_20080222222222',
251                     'somebox_lib_20080313133333_p4',
252                     } ],
253     "multi-key sort");
254
255 ## add log entries
256
257 # one to an existing logfile, same tape
258 Amanda::DB::Catalog::add_dump({
259     'write_timestamp' => '20080111',
260     'dump_timestamp' => '20080707070707',
261     'hostname' => 'newbox',
262     'diskname' => '/newdisk',
263     'level' => 3,
264     'label' => 'Conf-001',
265     'filenum' => 2,
266     'partnum' => 1,
267     'nparts' => 1,
268     'status' => 'OK',
269     'sec' => 13.0,
270     'kb' => 12380,
271 });
272
273 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(hostname => 'newbox') ],
274     [ sortdumps {
275         'write_timestamp' => '20080111000000',
276         'dump_timestamp' => '20080707070707',
277         'hostname' => 'newbox',
278         'diskname' => '/newdisk',
279         'level' => 3,
280         'label' => 'Conf-001',
281         'filenum' => 2,
282         'partnum' => 1,
283         'nparts' => 1,
284         'status' => 'OK',
285         'sec' => 13.0,
286         'kb' => 12380,
287     } ],
288     "successfully re-read an added dump in an existing logfile");
289
290 # and again, to test the last-logfile cache in Amanda::DB::Catalog
291 Amanda::DB::Catalog::add_dump({
292     'write_timestamp' => '20080111',
293     'dump_timestamp' => '20080707070707',
294     'hostname' => 'newbox',
295     'diskname' => '/newdisk2',
296     'level' => 0,
297     'label' => 'Conf-001',
298     'filenum' => 3,
299     'partnum' => 1,
300     'nparts' => 1,
301     'status' => 'OK',
302     'sec' => 27.0,
303     'kb' => 32380,
304 });
305
306 is(scalar Amanda::DB::Catalog::get_dumps(hostname => 'newbox'), 2,
307     "adding another dump to that logfile and re-reading gives 2 dumps");
308
309 # and another in a new file, as well as a tapelist entry
310 Amanda::DB::Catalog::add_dump({
311     'write_timestamp' => '20080707070707',
312     'dump_timestamp' => '20080707070707',
313     'hostname' => 'newlog',
314     'diskname' => '/newdisk',
315     'level' => 3,
316     'label' => 'Conf-009',
317     'filenum' => 1,
318     'partnum' => 1,
319     'nparts' => 1,
320     'status' => 'OK',
321     'sec' => 13.0,
322     'kb' => 12380,
323 });
324
325 is_deeply([ sortdumps Amanda::DB::Catalog::get_dumps(hostname => 'newlog') ],
326     [ sortdumps {
327         'write_timestamp' => '20080707070707',
328         'dump_timestamp' => '20080707070707',
329         'hostname' => 'newlog',
330         'diskname' => '/newdisk',
331         'level' => 3,
332         'label' => 'Conf-009',
333         'filenum' => 1,
334         'partnum' => 1,
335         'nparts' => 1,
336         'status' => 'OK',
337         'sec' => 13.0,
338         'kb' => 12380,
339     } ],
340     "successfully re-read an added dump in a new logfile");
341
342 # and add a multipart dump to that same logfile
343 for (my $i = 1; $i <= 5; $i++) {
344     Amanda::DB::Catalog::add_dump({
345         'write_timestamp' => '20080707070707',
346         'dump_timestamp' => '20080707070707',
347         'hostname' => 'newlog',
348         'diskname' => '/bigdisk',
349         'level' => 1,
350         'label' => 'Conf-009',
351         'filenum' => $i+1,
352         'partnum' => $i,
353         'nparts' => 5,
354         'status' => 'OK',
355         'sec' => 13.0,
356         'kb' => 12380,
357     });
358 }
359
360 is(scalar Amanda::DB::Catalog::get_dumps(diskname => '/bigdisk'), 5,
361     "multi-part dump added and re-read successfully");
362
363 __DATA__
364 # a short-datestamp logfile with only a single, single-part file in it
365 ::: log.20080111.0
366 :tapelist 20080111 Conf-001
367 :timestamp 20080111000000
368 DISK planner somebox /lib
369 START planner date 20080111
370 START driver date 20080111
371 STATS driver hostname somebox
372 STATS driver startup time 0.051
373 FINISH planner date 20080111 time 82.721
374 START taper datestamp 20080111 label Conf-001 tape 1
375 SUCCESS dumper somebox /lib 20080111 0 [sec 0.209 kb 1970 kps 9382.2 orig-kb 1970]
376 SUCCESS chunker somebox /lib 20080111 0 [sec 0.305 kb 420 kps 1478.7]
377 STATS driver estimate somebox /lib 20080111 0 [sec 1 nkb 2002 ckb 480 kps 385]
378 :dumpfile somebox_lib_20080111 20080111000000 somebox /lib 0 Conf-001 1 1 1 OK 4.813543 419
379 PART taper Conf-001 1 somebox /lib 20080111 1/1 0 [sec 4.813543 kb 419 kps 87.133307]
380 DONE taper somebox /lib 20080111 1 0 [sec 4.813543 kb 419 kps 87.133307]
381 FINISH driver date 20080111 time 2167.581
382
383 # a long-datestamp logfile, also fairly simple
384 ::: log.20080222222222.0
385 :tapelist 20080222222222 Conf-002
386 :timestamp 20080222222222
387 DISK planner somebox /lib
388 START planner date 20080222222222
389 START driver date 20080222222222
390 STATS driver hostname somebox
391 STATS driver startup time 0.051
392 FINISH planner date 20080222222222 time 0.102
393 SUCCESS dumper somebox /lib 20080222222222 0 [sec 0.012 kb 100 kps 8115.6 orig-kb 100]
394 SUCCESS chunker somebox /lib 20080222222222 0 [sec 5.075 kb 100 kps 26.0]
395 STATS driver estimate somebox /lib 20080222222222 0 [sec 0 nkb 132 ckb 160 kps 1024]
396 START taper datestamp 20080222222222 label Conf-002 tape 1
397 :dumpfile somebox_lib_20080222222222 20080222222222 somebox /lib 0 Conf-002 1 1 1 OK 0.000733 100
398 PART taper Conf-002 1 somebox /lib 20080222222222 1/1 0 [sec 0.000733 kb 100 kps 136425.648022]
399 DONE taper somebox /lib 20080222222222 1 0 [sec 0.000733 kb 100 kps 136425.648022]
400 FINISH driver date 20080222222222 time 6.206
401
402 # a logfile with several dumps in it, one of which comes in many parts, and one of which is
403 # from a previous run
404 ::: log.20080313133333.0
405 :tapelist 20080313133333 Conf-003
406 :timestamp 20080313133333
407 DISK planner somebox /usr/bin
408 DISK planner somebox /lib
409 DISK planner otherbox /lib
410 DISK planner otherbox /usr/bin
411 START planner date 20080313133333
412 START driver date 20080313133333
413 STATS driver hostname somebox
414 STATS driver startup time 0.059
415 INFO planner Full dump of somebox:/lib promoted from 2 days ahead.
416 FINISH planner date 20080313133333 time 0.286
417 SUCCESS dumper somebox /usr/bin 20080313133333 1 [sec 0.001 kb 20 kps 10352.0 orig-kb 20]
418 SUCCESS chunker somebox /usr/bin 20080313133333 1 [sec 1.023 kb 20 kps 50.8]
419 STATS driver estimate somebox /usr/bin 20080313133333 1 [sec 0 nkb 52 ckb 64 kps 1024]
420 START taper datestamp 20080313133333 label Conf-003 tape 1
421 :dumpfile somebox_usr_bin_20080313133333 20080313133333 somebox /usr/bin 1 Conf-003 1 1 1 OK 0.000370 20
422 PART taper Conf-003 1 somebox /usr/bin 20080313133333 1/1 1 [sec 0.000370 kb 20 kps 54054.054054]
423 DONE taper somebox /usr/bin 20080313133333 1 1 [sec 0.000370 kb 20 kps 54054.054054]
424 # a multi-part dump
425 SUCCESS dumper somebox /lib 20080313133333 0 [sec 0.189 kb 3156 kps 50253.1 orig-kb 3156]
426 SUCCESS chunker somebox /lib 20080313133333 0 [sec 5.250 kb 3156 kps 1815.5]
427 STATS driver estimate somebox /lib 20080313133333 0 [sec 1 nkb 3156 ckb 3156 kps 9500]
428 :dumpfile somebox_lib_20080313133333_p1 20080313133333 somebox /lib 0 Conf-003 2 1 4 OK 0.005621 1024
429 PART taper Conf-003 2 somebox /lib 20080313133333 1/4 0 [sec 0.005621 kb 1024 kps 182173.990393]
430 :dumpfile somebox_lib_20080313133333_p2 20080313133333 somebox /lib 0 Conf-003 3 2 4 OK 0.006527 1024
431 PART taper Conf-003 3 somebox /lib 20080313133333 2/4 0 [sec 0.006527 kb 1024 kps 156886.777999]
432 :dumpfile somebox_lib_20080313133333_p3 20080313133333 somebox /lib 0 Conf-003 4 3 4 OK 0.005854 1024
433 PART taper Conf-003 4 somebox /lib 20080313133333 3/4 0 [sec 0.005854 kb 1024 kps 174923.129484]
434 :dumpfile somebox_lib_20080313133333_p4 20080313133333 somebox /lib 0 Conf-003 5 4 4 OK 0.001919 284
435 PART taper Conf-003 5 somebox /lib 20080313133333 4/4 0 [sec 0.001919 kb 284 kps 147993.746743]
436 DONE taper somebox /lib 20080313133333 10 0 [sec 0.051436 kb 3156 kps 184695.543977]
437 SUCCESS dumper otherbox /lib 20080313133333 0 [sec 0.001 kb 190 kps 10352.0 orig-kb 20]
438 SUCCESS chunker otherbox /lib 20080313133333 0 [sec 1.023 kb 190 kps 50.8]
439 STATS driver estimate otherbox /lib 20080313133333 0 [sec 0 nkb 190 ckb 190 kps 1024]
440 # this dump is from a previous run, with an older dump_timestamp
441 :dumpfile otherbox_usr_bin_20080313133333 20080311131133 otherbox /usr/bin 0 Conf-003 6 1 1 OK 0.002733 240
442 PART taper Conf-003 6 otherbox /usr/bin 20080311131133 1/1 0 [sec 0.002733 kb 240 kps 136425.648022]
443 :dumpfile otherbox_lib_20080313133333 20080313133333 otherbox /lib 0 Conf-003 7 1 1 OK 0.001733 190
444 PART taper Conf-003 7 otherbox /lib 20080313133333 1/1 0 [sec 0.001733 kb 190 kps 136425.648022]
445 DONE taper otherbox /lib 20080313133333 1 0 [sec 0.001733 kb 190 kps 136425.648022]
446 FINISH driver date 20080313133333 time 24.777
447
448 # A logfile with some partial parts (PARTPARTIAL) in it
449 ::: log.20080414144444.0
450 :tapelist 20080414144444 Conf-004
451 :tapelist 20080414144444 Conf-005
452 :timestamp 20080414144444
453 DISK planner otherbox /lib
454 START planner date 20080414144444
455 START driver date 20080414144444
456 STATS driver hostname otherbox
457 STATS driver startup time 0.075
458 INFO taper Will write new label `Conf-004' to new (previously non-amanda) tape
459 FINISH planner date 20080414144444 time 2.139
460 SUCCESS dumper otherbox /lib 20080414144444 1 [sec 0.003 kb 60 kps 16304.3 orig-kb 60]
461 SUCCESS chunker otherbox /lib 20080414144444 1 [sec 1.038 kb 60 kps 88.5]
462 STATS driver estimate otherbox /lib 20080414144444 1 [sec 0 nkb 92 ckb 96 kps 1024]
463 START taper datestamp 20080414144444 label Conf-004 tape 1
464 :dumpfile otherbox_lib_20080414144444_try1 20080414144444 otherbox /lib 1 Conf-004 1 1 1 PARTIAL 0.000707 32
465 PARTPARTIAL taper Conf-004 1 otherbox /lib 20080414144444 1/1 1 [sec 0.000707 kb 32 kps 45261.669024] ""
466 INFO taper Will request retry of failed split part.
467 INFO taper Will write new label `Conf-005' to new (previously non-amanda) tape
468 START taper datestamp 20080414144444 label Conf-005 tape 2
469 :dumpfile otherbox_lib_20080414144444_try2 20080414144444 otherbox /lib 1 Conf-005 1 1 1 PARTIAL 0.000540 32
470 PARTPARTIAL taper Conf-005 1 otherbox /lib 20080414144444 1/1 1 [sec 0.000540 kb 32 kps 59259.259259] ""
471 INFO taper Will request retry of failed split part.
472 WARNING driver Out of tapes; going into degraded mode.
473 PARTIAL taper otherbox /lib 20080414144444 1 1 [sec 0.000540 kb 32 kps 59259.259259] ""
474 FINISH driver date 20080414144444 time 6.959