1 ################################################################
6 Bacula® - The Network Backup Solution
8 Copyright (C) 2008-2014 Bacula Systems SA
10 The main author of Bacula is Kern Sibbald, with contributions from
11 many others, a complete list can be found in the file AUTHORS.
13 Licensees holding a valid Bacula Systems SA license may use this file
14 and others of this release in accordance with the proprietary license
15 agreement provided in the LICENSE file. Redistribution of any part of
16 this release is not permitted.
18 Bacula® is a registered trademark of Kern Sibbald.
22 package scripts::functions;
23 use File::Basename qw/basename/;
24 # Export all functions needed to be used by a simple
25 # perl -Mscripts::functions -e '' script
27 our @ISA = qw(Exporter);
29 our @EXPORT = qw(update_some_files create_many_files check_multiple_copies
30 update_client $HOST $BASEPORT add_to_backup_list
31 run_bconsole run_bacula start_test end_test create_bconcmds
32 create_many_dirs cleanup start_bacula
34 stop_bacula get_resource set_maximum_concurrent_jobs get_time
35 add_attribute check_prune_list check_min_volume_size
36 init_delta update_delta check_max_backup_size comment_out
37 create_many_files_size $plugins debug p
38 check_max_volume_size $estat $bstat $rstat $zstat $cwd $bin
39 $scripts $conf $rscripts $tmp $working $dstat extract_resource
40 $db_name $db_user $db_password $src $tmpsrc $out $CLIENT docmd
41 set_global_maximum_concurrent_jobs check_volumes update_some_files_rep
42 remote_init remote_config remote_stop remote_diff remote_check
43 get_field_size get_field_ratio create_binfile );
46 use File::Copy qw/copy/;
48 our ($cwd, $bin, $scripts, $conf, $rscripts, $tmp, $working, $estat, $dstat,
49 $plugins, $bstat, $zstat, $rstat, $debug, $out, $TestName,
50 $REMOTE_CLIENT, $REMOTE_ADDR, $REMOTE_FILE, $REMOTE_PORT, $REMOTE_PASSWORD,
51 $REMOTE_STORE_ADDR, $REGRESS_DEBUG, $REMOTE_USER, $start_time, $end_time,
52 $db_name, $db_user, $db_password, $src, $tmpsrc, $HOST, $BASEPORT, $CLIENT);
55 if ($estat || $rstat || $zstat || $bstat || $dstat) {
61 # start by loading the ./config file
63 if (! -f "./config") {
64 die "Could not find ./config file\n";
66 # load the ./config file in a subshell doesn't allow to use "env" to display all variable
67 open(IN, ". ./config; set |") or die "Could not run shell: $!\n";
68 while ( my $l = <IN> ) {
70 if ($l =~ /^([\w\d]+)='?([^']+)'?/) {
71 next if ($1 eq 'SHELLOPTS'); # is in read-only
72 ($envar,$enval) = ($1, $2);
73 $ENV{$envar} = $enval;
80 # set internal variable name and update environment variable
81 $ENV{db_name} = $db_name = $ENV{db_name} || 'regress';
82 $ENV{db_user} = $db_user = $ENV{db_user} || 'regress';
83 $ENV{db_password} = $db_password = $ENV{db_password} || '';
85 $ENV{bin} = $bin = $ENV{bin} || "$cwd/bin";
86 $ENV{tmp} = $tmp = $ENV{tmp} || "$cwd/tmp";
87 $ENV{src} = $src = $ENV{src} || "$cwd/src";
88 $ENV{conf} = $conf = $ENV{conf} || $bin;
89 $ENV{scripts} = $scripts = $ENV{scripts} || $bin;
90 $ENV{plugins} = $plugins = $ENV{plugins} || "$bin/plugins";
91 $ENV{tmpsrc} = $tmpsrc = $ENV{tmpsrc} || "$cwd/tmp/build";
92 $ENV{working} = $working = $ENV{working} || "$cwd/working";
93 $ENV{rscripts} = $rscripts = $ENV{rscripts} || "$cwd/scripts";
94 $ENV{HOST} = $HOST = $ENV{HOST} || "localhost";
95 $ENV{BASEPORT} = $BASEPORT = $ENV{BASEPORT} || "8101";
96 $ENV{REGRESS_DEBUG} = $debug = $ENV{REGRESS_DEBUG} || 0;
97 $ENV{REMOTE_CLIENT} = $REMOTE_CLIENT = $ENV{REMOTE_CLIENT} || 'remote-fd';
98 $ENV{REMOTE_ADDR} = $REMOTE_ADDR = $ENV{REMOTE_ADDR} || undef;
99 $ENV{REMOTE_FILE} = $REMOTE_FILE = $ENV{REMOTE_FILE} || "/tmp";
100 $ENV{REMOTE_PORT} = $REMOTE_PORT = $ENV{REMOTE_PORT} || 9102;
101 $ENV{REMOTE_PASSWORD} = $REMOTE_PASSWORD = $ENV{REMOTE_PASSWORD} || "xxx";
102 $ENV{REMOTE_STORE_ADDR}=$REMOTE_STORE_ADDR=$ENV{REMOTE_STORE_ADDR} || undef;
103 $ENV{REMOTE_USER} = $REMOTE_USER = $ENV{REMOTE_USER} || undef;
104 $ENV{CLIENT} = $CLIENT = $ENV{CLIENT} || "$HOST-fd";
106 $out = ($debug) ? '@tee' : '@out';
108 $TestName = basename($0);
110 $dstat = $estat = $rstat = $bstat = $zstat = 0;
113 # execute bconsole session
116 my $script = shift || "$tmp/bconcmds";
117 return docmd("cat $script | $bin/bconsole -c $conf/bconsole.conf");
120 # create a file-list for many tests using
121 # <$cwd/tmp/file-list as fileset
122 sub add_to_backup_list
124 open(FP, ">$tmp/file-list") or die "ERROR: Unable to open $tmp/file-list $@";
137 system("$rscripts/cleanup");
143 $start_time = time();
144 my $d = strftime('%R:%S', localtime($start_time));
145 print "\n\n === Starting $TestName at $d ===\n";
151 my $t = strftime('%R:%S', localtime($end_time));
152 my $d = strftime('%H:%M:%S', gmtime($end_time - $start_time));
154 if ( -f "$tmp/err.log") {
155 system("cat $tmp/err.log");
158 if ($estat != 0 || $zstat != 0 || $dstat != 0 || $bstat != 0 ) {
160 !!!!! $TestName failed!!! $t $d !!!!!
161 Status: estat=$estat zombie=$zstat backup=$bstat restore=$rstat diff=$dstat\n";
163 if ($bstat != 0 || $rstat != 0) {
164 print " !!! Bad termination status !!!\n";
166 print " !!! Restored files differ !!!\n";
168 print " Status: backup=$bstat restore=$rstat diff=$dstat\n";
169 print " Test owner of $ENV{SITE_NAME} is $ENV{EMAIL}\n";
171 print "\n\n === Ending $TestName at $t ($d) ===\n\n";
175 # create a console command file, can handle a list
178 open(FP, ">$tmp/bconcmds");
179 map { print FP "$_\n"; } @_;
187 system("sh -c '$cmd " . (($debug)?"":" >/dev/null") . "'");
194 $ret = docmd("$bin/bacula start");
197 create_bconcmds('@out /dev/null',
199 'truncate client_group;',
200 'truncate client_group_member;',
201 'update Media set LocationId=0;',
202 'truncate location;',
210 return docmd("$bin/bacula stop");
215 my $ret = `$bin/bdirjson -c $conf/bacula-dir.conf -l Name -r Director`;
216 if ($ret =~ /"Name": "(.+?)"/) {
223 my ($file, $type, $name) = @_;
225 open(FP, $file) or die "Can't open $file";
226 my $content = join("", <FP>);
228 if ($content =~ m/(^$type \{[^}]+?Name\s*=\s*"?$name"?[^}]+?^\})/ms) {
238 my $ret = get_resource(@_);
246 my ($file, $field) = @_;
249 my $pattern=$field."\\s*([\\d,]+)";
250 open(FP, $file) or die "ERROR: Can't open $file";
267 my ($file, $field) = @_;
271 my $pattern=$field."\\s*[\\d.]+%\\s+([\\d]+)\.[\\d]*:1"; # stop at the '.'
272 my $pattern2=$field."\\s*None";
273 open(FP, $file) or die "ERROR: Can't open $file";
293 sub check_max_backup_size
295 my ($file, $size) = @_;
299 open(FP, $file) or die "ERROR: Can't open $file";
303 if (/FD Bytes Written: +([\d,]+)/) {
313 print "ERROR: backup too big ($s > $size)\n";
321 sub check_min_volume_size
323 my ($size, @vol) = @_;
326 foreach my $v (@vol) {
327 if (! -f "$tmp/$v") {
328 print "ERR: $tmp/$v not accessible\n";
332 if (-s "$tmp/$v" < $size) {
333 print "ERR: $tmp/$v too small\n";
341 # check_volumes("tmp/log1.out", "tmp/log2.out", ...)
346 unlink("$tmp/check_volumes.out");
348 foreach my $f (@files) {
349 open(FP, $f) or next;
352 if ($f =~ /Wrote label to prelabeled Volume "(.+?)" on file device "(.+?)" \((.+?)\)/) {
356 system("$bin/bls -c $conf/bacula-sd.conf -j -E -V \"$1\" \"$2\" &>> $tmp/check_volumes.out");
358 debug("Found problems for $1, traces are in $tmp/check_volumes.out");
370 # check if a volume is too big
371 # check_max_backup_size(10000, "vol1", "vol3");
372 sub check_max_volume_size
374 my ($size, @vol) = @_;
377 foreach my $v (@vol) {
378 if (! -f "$tmp/$v") {
379 print "ERR: $tmp/$v not accessible\n";
383 if (-s "$tmp/$v" > $size) {
384 print "ERR: $tmp/$v too big\n";
392 # update client definition for the current test
393 # it permits to test remote client
396 my ($new_passwd, $new_address, $new_port) = @_;
399 open(FP, "$conf/bacula-dir.conf") or die "can't open source $!";
400 open(NEW, ">$tmp/bacula-dir.conf.$$") or die "can't open dest $!";
401 while (my $l = <FP>) {
402 if (!$in_client && $l =~ /^Client \{/) {
406 if ($in_client && $l =~ /Address/i) {
407 $l = "Address = $new_address\n";
410 if ($in_client && $l =~ /FDPort/i) {
411 $l = "FDPort = $new_port\n";
414 if ($in_client && $l =~ /Password/i) {
415 $l = "Password = \"$new_passwd\"\n";
418 if ($in_client && $l =~ /^\}/) {
425 my $ret = copy("$tmp/bacula-dir.conf.$$", "$conf/bacula-dir.conf");
426 unlink("$tmp/bacula-dir.conf.$$");
430 # if you want to run this function more than 100 times, please, update this number
431 my $last_update = 100;
433 # open a directory and update all files
434 sub update_some_files_rep
436 my ($dest, $nbupdate)=@_;
444 $last_update = $nbupdate;
445 unlink("$tmp/last_update");
447 } elsif (-f "$tmp/last_update") {
448 $last_update = `cat $tmp/last_update`;
451 if ($last_update == 0) {
455 my $base = chr($last_update % 26 + 65); # We use a base directory A-Z
457 system("sh -c 'echo $last_update > $tmp/last_update'");
458 print "Update files in $dest\n";
459 opendir(DIR, "$dest/$base") || die "$!";
461 $f = "$dest/$base/$_";
462 if (($total++ % $last_update) == 0) {
464 # We delete some of them, and we replace them later
465 if ((($nb + $nbdel) % 11) == 0) {
469 open(FP, ">$dest/$base/$last_update-$nbdel.txt") or die "$f $!";
470 seek(FP, $last_update * 4000, 0);
471 print FP "$t update $f\n";
475 open(FP, ">>$f") or die "$f $!";
476 print FP "$t update $f\n";
484 print "$nb files updated, $nbdel deleted/created\n";
487 # open a directory and update all files
488 sub update_some_files
494 print "Update files in $dest\n";
495 opendir(DIR, $dest) || die "$!";
499 open(FP, ">$f") or die "$f $!";
500 print FP "$t update $f\n";
506 print "$nb files updated\n";
509 # create big number of files in a given directory
510 # Inputs: dest destination directory
511 # nb number of file to create
513 # perl -Mscripts::functions -e 'create_many_files("$cwd/files", 100000)'
514 # perl -Mscripts::functions -e 'create_many_files("$cwd/files", 100000, 32000)'
515 sub create_many_files
517 my ($dest, $nb, $sparse_size) = @_;
520 $nb = $nb / 2; # We create 2 files per loop
522 $sparse_size = $sparse_size | 0;
524 $base = chr($nb % 26 + 65); # We use a base directory A-Z
527 if (-f "$dest/$base/a${base}a${nb}aaa${base}") {
528 debug("Files already created\n");
532 # auto flush stdout for dots
534 print "Create ", $nb * 2, " files into $dest\n";
535 for(my $i=0; $i < 26; $i++) {
536 $base = chr($i + 65);
537 mkdir("$dest/$base") if (! -d "$dest/$base");
539 for(my $i=0; $i<=$nb; $i++) {
540 $base = chr($i % 26 + 65);
541 open(FP, ">$dest/$base/a${base}a${i}aaa$base") or die "$dest/$base $!";
543 seek(FP, $sparse_size + $i, 0);
548 open(FP, ">>$dir/b${base}a${i}csq$base") or die "$dir $!";
549 print FP "$base $i\n";
553 $dir = "$dest/$base/$base$i$base";
556 print "." if (!($i % 10000));
562 # create big number of files in a given directory
563 # Inputs: dest destination directory
564 # nb number of file to create
566 # perl -Mscripts::functions -e 'create_many_files_size("$cwd/files", 100000)'
567 sub create_many_files_size
569 my ($dest, $nb) = @_;
574 $base = chr($nb % 26 + 65); # We use a base directory A-Z
577 if (-f "$dest/$base/a${base}a${nb}aaa${base}") {
578 debug("Files already created\n");
582 # auto flush stdout for dots
584 print "Create $nb files into $dest\n";
585 for(my $i=0; $i < 26; $i++) {
586 $base = chr($i + 65);
587 mkdir("$dest/$base") if (! -d "$dest/$base");
589 for(my $i=0; $i<=$nb; $i++) {
590 $base = chr($i % 26 + 65);
591 open(FP, ">$dest/$base/a${base}a${i}aaa$base") or die "$dest/$base $!";
592 print FP "$base" x $i;
595 print "." if (!($i % 10000));
600 # create big number of dirs in a given directory
601 # Inputs: dest destination directory
602 # nb number of dirs to create
604 # perl -Mscripts::functions -e 'create_many_dirs("$cwd/files", 100000)'
607 my ($dest, $nb) = @_;
612 $base = chr($nb % 26 + 65); # We use a base directory A-Z
613 $base2 = chr(($nb+10) % 26 + 65);
615 if (-d "$dest/$base/$base2/$base/a${base}a${nb}aaa${base}") {
616 debug("Files already created\n");
620 # auto flush stdout for dots
622 print "Create $nb dirs into $dest\n";
623 for(my $i=0; $i < 26; $i++) {
624 $base = chr($i + 65);
625 $base2 = chr(($i+10) % 26 + 65);
626 mkdir("$dest/$base");
627 mkdir("$dest/$base/$base2");
628 mkdir("$dest/$base/$base2/$base$base2");
629 mkdir("$dest/$base/$base2/$base$base2/$base$base2");
630 mkdir("$dest/$base/$base2/$base$base2/$base$base2/$base2$base");
632 for(my $i=0; $i<=$nb; $i++) {
633 $base = chr($i % 26 + 65);
634 $base2 = chr(($i+10) % 26 + 65);
635 mkdir("$dest/$base/$base2/$base$base2/$base$base2/$base2$base/a${base}a${i}aaa$base");
636 print "." if (!($i % 10000));
643 if (grep {/Wanted SQL_ASCII, got UTF8/}
644 `${bin}/bacula-dir -d50 -t -c ${conf}/bacula-dir.conf 2>&1`)
646 print "Found database encoding problem, please modify the ",
647 "database encoding (SQL_ASCII)\n";
652 sub set_global_maximum_concurrent_jobs
655 add_attribute("$conf/bacula-dir.conf", "MaximumConcurrentJobs", $nb, "Job");
656 add_attribute("$conf/bacula-dir.conf", "MaximumConcurrentJobs", $nb, "Client");
657 add_attribute("$conf/bacula-dir.conf", "MaximumConcurrentJobs", $nb, "Director");
658 add_attribute("$conf/bacula-dir.conf", "MaximumConcurrentJobs", $nb, "Storage");
659 add_attribute("$conf/bacula-sd.conf", "MaximumConcurrentJobs", $nb, "Storage");
660 add_attribute("$conf/bacula-sd.conf", "MaximumConcurrentJobs", $nb, "Device");
661 add_attribute("$conf/bacula-fd.conf", "MaximumConcurrentJobs", $nb, "FileDaemon");
664 # You can change the maximum concurrent jobs for any config file
665 # If specified, you can change only one Resource or one type of
666 # resource at the time (optional)
667 # set_maximum_concurrent_jobs('$conf/bacula-dir.conf', 100);
668 # set_maximum_concurrent_jobs('$conf/bacula-dir.conf', 100, 'Director');
669 # set_maximum_concurrent_jobs('$conf/bacula-dir.conf', 100, 'Device', 'Drive-0');
670 sub set_maximum_concurrent_jobs
672 my ($file, $nb, $obj, $name) = @_;
674 die "Can't get new maximumconcurrentjobs"
677 add_attribute($file, "Maximum Concurrent Jobs", $nb, $obj, $name);
680 # You can comment out a directive
681 # comment_out('$conf/bacula-dir.conf', 'FDTimeout', 'Job', 'test');
682 # comment_out('$conf/bacula-dir.conf', 'FDTimeout');
685 my ($file, $attr, $obj, $name) = @_;
686 my ($cur_obj, $cur_name, $done);
688 open(FP, ">$tmp/1.$$") or die "Can't write to $tmp/1.$$";
689 open(SRC, $file) or die "Can't open $file";
690 while (my $l = <SRC>)
697 if ($l =~ /^(\w+) \{/) {
702 if ($l =~ /^\s*\Q$attr\E/i) {
703 if (!$obj || $cur_obj eq $obj) {
704 if (!$name || $cur_name eq $name) {
711 if ($l =~ /^\s*Name\s*=\s*"?([\w\d\.-]+)"?/i) {
718 copy("$tmp/1.$$", $file) or die "Can't copy $tmp/1.$$ to $file";
721 # You can add option to a resource
722 # add_attribute('$conf/bacula-dir.conf', 'FDTimeout', 1600, 'Director');
723 # add_attribute('$conf/bacula-dir.conf', 'FDTimeout', 1600, 'Storage', 'FileStorage');
726 my ($file, $attr, $value, $obj, $name) = @_;
727 my ($cur_obj, $cur_name, $done);
729 my $is_options = $obj && $obj eq 'Options';
730 if ($value =~ /\s/ && $value !~ m:[/"]:) { # exclude speed from the escape
731 $value = "\"$value\"";
733 open(FP, ">$tmp/1.$$") or die "Can't write to $tmp/1.$$";
734 open(SRC, $file) or die "Can't open $file";
735 while (my $l = <SRC>)
742 if ($l =~ /^(\w+) \{/ || ($is_options && $l =~ /\s+(Options)\s*\{/)) {
747 if ($l =~ /^\s*\Q$attr\E/i) {
748 if (!$obj || $cur_obj eq $obj) {
749 if (!$name || $cur_name eq $name) {
750 $l =~ s/\Q$attr\E\s*=\s*.+/$attr = $value/ig;
756 if ($l =~ /^\s*Name\s*=\s*"?([\w\d\.-]+)"?/i) {
765 } elsif ($l =~ /^\}/) {
771 if ($cur_obj && $cur_obj eq $obj) {
772 if (!$name || $cur_name eq $name) {
773 $l =~ s/\}/\n $attr = $value\n\}/;
777 $cur_name = $cur_obj = undef;
783 copy("$tmp/1.$$", $file) or die "Can't copy $tmp/1.$$ to $file";
786 # This test the list jobs output to check differences
787 # Input: read file argument
788 # check if all jobids in argument are present in the first
789 # 'list jobs' and not present in the second
790 # Output: exit(1) if something goes wrong and print error
794 my %to_check = map { $_ => 1} @_;
799 open(FP, $f) or die "Can't open $f $!";
800 while (my $l = <FP>) # read all files to check
802 if ($l =~ /list jobs/) {
806 if ($nb_list_job == 2) {
807 foreach my $jobid (keys %to_check) {
808 if (!$seen{$jobid}) {
809 print "ERROR: in $f, can't find JobId=$jobid in first 'list jobs'\n";
816 if ($nb_list_job == 0) {
819 if ($l =~ /Pruned (\d+) Job for client/) {
821 print "ERROR: in $f, Prune command returns $1 jobs, want $nb\n";
826 if ($l =~ /No Jobs found to prune/) {
828 print "ERROR: in $f, Prune command returns 0 job, want $nb\n";
834 # | 1 | NightlySave | 2010-06-16 22:43:05 | B | F | 27 | 4173577 | T |
835 if ($l =~ /^\|\s+(\d+)/) {
836 if ($nb_list_job == 1) {
844 foreach my $jobid (keys %to_check) {
845 if (!$seen{$jobid}) {
846 print "******** listing of $f *********\n";
848 print "******** end listing of $f *********\n";
849 print "ERROR: in $f, JobId=$jobid should not be, but is still present in the 2nd 'list jobs'\n";
853 if ($nb_list_job != 2) {
854 print "ERROR: in $f, not enough 'list jobs'\n";
860 # This test ensure that 'list copies' displays only each copy one time
862 # Input: read stream from stdin or with file list argument
863 # check the number of copies with the ARGV[1]
864 # Output: exit(1) if something goes wrong and print error
865 sub check_multiple_copies
867 my ($nb_to_found) = @_;
869 my $in_list_copies=0; # are we or not in a list copies block
870 my $nb_found=0; # count the number of copies found
874 while (my $l = <>) # read all files to check
876 if ($l =~ /list copies/) {
882 # not in a list copies anymore
883 if ($in_list_copies && $l =~ /^ /) {
889 # | 3 | Backup.2009-09-28 | 9 | DiskChangerMedia |
890 if ($in_list_copies && $l =~ /^\|\s+\d+/) {
891 my (undef, $jobid, undef, $copyid, undef) = split(/\s*\|\s*/, $l);
892 if (exists $seen{$jobid}) {
893 print "ERROR: $jobid/$copyid already known as $seen{$jobid}\n";
896 $seen{$jobid}=$copyid;
902 # test the number of copies against the given arg
903 if ($nb_to_found && ($nb_to_found != $nb_found)) {
904 print "ERROR: Found wrong number of copies ",
905 "($nb_to_found != $nb_found)\n";
912 use POSIX qw/strftime/;
916 print strftime('%F %T', localtime(time+$sec)), "\n";
922 print join("\n", @_), "\n";
928 debug("\n################################################################",
930 "################################################################\n");
933 # check if binaries are OK
937 my $path = "/opt/bacula/bin";
938 print "INFO: check binaries\n";
939 foreach my $b (qw/bacula-fd bacula-dir bconsole bdirjson bsdjson
940 bfdjson bbconsjson bacula-sd/)
943 my $out = `$path/$b -? 2>&1`;
944 if ($out !~ /Version:/g) {
945 print "ERROR: with $b -?\n";
946 system("$path/$b -?");
951 foreach my $b (qw/bacula-sd/)
954 my $libs = `ldd $path/$b`;
955 if ($libs !~ /tokyocabinet/g) {
956 print "ERROR: unable to find tokyocabinet for $b\n";
968 open(FP, ">$REMOTE_FILE/bacula-fd.conf") or
969 die "ERROR: Can't open $REMOTE_FILE/bacula-fd.conf $!";
971 my $plugins = '/opt/bacula/bin';
972 if (-d '/opt/bacula/plugins') {
973 $plugins = '/opt/bacula/plugins';
979 Password = \"$REMOTE_PASSWORD\"
983 FDport = $REMOTE_PORT
984 WorkingDirectory = $REMOTE_FILE/working
985 Pid Directory = $REMOTE_FILE/working
986 Plugin Directory = $plugins
987 Maximum Concurrent Jobs = 20
991 director = $HOST-dir = all, !skipped, !restored
995 system("mkdir -p '$REMOTE_FILE/working' '$REMOTE_FILE/save'");
996 system("rm -rf '$REMOTE_FILE/restore'");
999 close(STDIN); open(STDIN, "/dev/null");
1000 close(STDOUT); open(STDOUT, ">/dev/null");
1001 close(STDERR); open(STDERR, ">/dev/null");
1002 exec("/opt/bacula/bin/bacula-fd -c $REMOTE_FILE/bacula-fd.conf");
1006 $pid = `cat $REMOTE_FILE/working/bacula-fd.$REMOTE_PORT.pid`;
1009 # create files and tweak rights
1010 create_many_files("$REMOTE_FILE/save", 5000);
1011 chdir("$REMOTE_FILE/save");
1014 for my $g ( split(' ', $( )) {
1019 # create a sparse file of 2MB
1020 init_delta("$REMOTE_FILE/save", 2000000);
1022 # create a simple script to execute
1023 open(FP, ">test.sh") or die "Can't open test.sh $!";
1024 print FP "#!/bin/sh\n";
1025 print FP "echo this is a script";
1027 chmod 0755, "test.sh";
1030 link("test.sh", "link-test.sh");
1032 # create long filename
1033 mkdir("b" x 255) or print "can't create long dir $!\n";
1034 copy("test.sh", ("b" x 255) . '/' . ("a" x 255)) or print "can't create long dir $!\n";
1036 # play with some symlinks
1037 symlink("test.sh", "sym-test.sh");
1038 symlink("$REMOTE_FILE/save/test.sh", "sym-abs-test.sh");
1050 debug("Doing diff between save and restore");
1051 system("ssh $REMOTE_USER$REMOTE_ADDR " .
1052 "$REMOTE_FILE/scripts/diff.pl -s $REMOTE_FILE/save -d $REMOTE_FILE/restore/$REMOTE_FILE/save");
1058 debug("Kill remote bacula-fd $REMOTE_ADDR");
1059 system("ssh $REMOTE_USER$REMOTE_ADDR " .
1060 "'test -f $REMOTE_FILE/working/bacula-fd.$REMOTE_PORT.pid && " .
1061 "kill `cat $REMOTE_FILE/working/bacula-fd.$REMOTE_PORT.pid`'");
1066 system("ssh $REMOTE_USER$REMOTE_ADDR mkdir -p '$REMOTE_FILE/scripts/'");
1067 system("scp -q scripts/functions.pm scripts/diff.pl $REMOTE_USER$REMOTE_ADDR:$REMOTE_FILE/scripts/");
1068 system("scp -q config $REMOTE_USER$REMOTE_ADDR:$REMOTE_FILE/");
1069 debug("INFO: Configuring remote client");
1070 system("ssh $REMOTE_USER$REMOTE_ADDR 'cd $REMOTE_FILE && perl -Mscripts::functions -e remote_config'");
1071 system("ssh $REMOTE_USER$REMOTE_ADDR 'cd $REMOTE_FILE && perl -Mscripts::functions -e remote_check'");
1076 my ($file, $nb) = @_;
1079 if (!open(FP, ">$file")) {
1080 print "ERR\nCan't create txt $file $@\n";
1083 for (my $i = 0; $i < $nb ; $i++) {
1084 foreach my $c ('a'..'z') {
1085 my $l = ($c x 1024);
1096 my ($source, $sparse_size) = @_;
1098 $sparse_size = $sparse_size || 100000000;
1100 # Create $source if needed
1101 system("mkdir -p '$source'");
1103 if (!chdir($source)) {
1104 print "ERR\nCan't access to $source $!\n";
1108 open(FP, ">text.txt") or return "ERR\nCan't create txt file $@\n";
1109 my $l = ($c x 80) . "\n";
1110 print FP $l x 40000;
1117 open(FP, ">sparse.dat") or return "ERR\nCan't create sparse $@\n";
1118 seek(FP, $sparse_size, 0);
1125 my ($source) = shift;
1127 if (!chdir($source)) {
1128 return "ERR\nCan't access to $source $!\n";
1134 open(FP, "+<sparse.dat") or return "ERR\nCan't update the sparse file $@\n";
1135 seek(FP, int(rand(-s "sparse.dat")), 0);
1142 open(FP, ">>text.txt") or return "ERR\nCan't update txt file $@\n";
1144 my $l = ($c x 80) . "\n";
1145 print FP $l x 40000;