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 open(FP, ">$tmp/1.$$") or die "Can't write to $tmp/1.$$";
731 open(SRC, $file) or die "Can't open $file";
732 while (my $l = <SRC>)
739 if ($l =~ /^(\w+) \{/ || ($is_options && $l =~ /\s+(Options)\s*\{/)) {
744 if ($l =~ /^\s*\Q$attr\E/i) {
745 if (!$obj || $cur_obj eq $obj) {
746 if (!$name || $cur_name eq $name) {
747 $l =~ s/\Q$attr\E\s*=\s*.+/$attr = $value/ig;
753 if ($l =~ /^\s*Name\s*=\s*"?([\w\d\.-]+)"?/i) {
762 } elsif ($l =~ /^\}/) {
768 if ($cur_obj && $cur_obj eq $obj) {
769 if (!$name || $cur_name eq $name) {
770 $l =~ s/\}/\n $attr = $value\n\}/;
774 $cur_name = $cur_obj = undef;
780 copy("$tmp/1.$$", $file) or die "Can't copy $tmp/1.$$ to $file";
783 # This test the list jobs output to check differences
784 # Input: read file argument
785 # check if all jobids in argument are present in the first
786 # 'list jobs' and not present in the second
787 # Output: exit(1) if something goes wrong and print error
791 my %to_check = map { $_ => 1} @_;
796 open(FP, $f) or die "Can't open $f $!";
797 while (my $l = <FP>) # read all files to check
799 if ($l =~ /list jobs/) {
803 if ($nb_list_job == 2) {
804 foreach my $jobid (keys %to_check) {
805 if (!$seen{$jobid}) {
806 print "ERROR: in $f, can't find JobId=$jobid in first 'list jobs'\n";
813 if ($nb_list_job == 0) {
816 if ($l =~ /Pruned (\d+) Job for client/) {
818 print "ERROR: in $f, Prune command returns $1 jobs, want $nb\n";
823 if ($l =~ /No Jobs found to prune/) {
825 print "ERROR: in $f, Prune command returns 0 job, want $nb\n";
831 # | 1 | NightlySave | 2010-06-16 22:43:05 | B | F | 27 | 4173577 | T |
832 if ($l =~ /^\|\s+(\d+)/) {
833 if ($nb_list_job == 1) {
841 foreach my $jobid (keys %to_check) {
842 if (!$seen{$jobid}) {
843 print "******** listing of $f *********\n";
845 print "******** end listing of $f *********\n";
846 print "ERROR: in $f, JobId=$jobid should not be, but is still present in the 2nd 'list jobs'\n";
850 if ($nb_list_job != 2) {
851 print "ERROR: in $f, not enough 'list jobs'\n";
857 # This test ensure that 'list copies' displays only each copy one time
859 # Input: read stream from stdin or with file list argument
860 # check the number of copies with the ARGV[1]
861 # Output: exit(1) if something goes wrong and print error
862 sub check_multiple_copies
864 my ($nb_to_found) = @_;
866 my $in_list_copies=0; # are we or not in a list copies block
867 my $nb_found=0; # count the number of copies found
871 while (my $l = <>) # read all files to check
873 if ($l =~ /list copies/) {
879 # not in a list copies anymore
880 if ($in_list_copies && $l =~ /^ /) {
886 # | 3 | Backup.2009-09-28 | 9 | DiskChangerMedia |
887 if ($in_list_copies && $l =~ /^\|\s+\d+/) {
888 my (undef, $jobid, undef, $copyid, undef) = split(/\s*\|\s*/, $l);
889 if (exists $seen{$jobid}) {
890 print "ERROR: $jobid/$copyid already known as $seen{$jobid}\n";
893 $seen{$jobid}=$copyid;
899 # test the number of copies against the given arg
900 if ($nb_to_found && ($nb_to_found != $nb_found)) {
901 print "ERROR: Found wrong number of copies ",
902 "($nb_to_found != $nb_found)\n";
909 use POSIX qw/strftime/;
913 print strftime('%F %T', localtime(time+$sec)), "\n";
919 print join("\n", @_), "\n";
925 debug("\n################################################################",
927 "################################################################\n");
930 # check if binaries are OK
934 my $path = "/opt/bacula/bin";
935 print "INFO: check binaries\n";
936 foreach my $b (qw/bacula-fd bacula-dir bconsole bdirjson bsdjson
937 bfdjson bbconsjson bacula-sd/)
940 my $out = `$path/$b -? 2>&1`;
941 if ($out !~ /Version:/g) {
942 print "ERROR: with $b -?\n";
943 system("$path/$b -?");
948 foreach my $b (qw/bacula-sd/)
951 my $libs = `ldd $path/$b`;
952 if ($libs !~ /tokyocabinet/g) {
953 print "ERROR: unable to find tokyocabinet for $b\n";
965 open(FP, ">$REMOTE_FILE/bacula-fd.conf") or
966 die "ERROR: Can't open $REMOTE_FILE/bacula-fd.conf $!";
968 my $plugins = '/opt/bacula/bin';
969 if (-d '/opt/bacula/plugins') {
970 $plugins = '/opt/bacula/plugins';
976 Password = \"$REMOTE_PASSWORD\"
980 FDport = $REMOTE_PORT
981 WorkingDirectory = $REMOTE_FILE/working
982 Pid Directory = $REMOTE_FILE/working
983 Plugin Directory = $plugins
984 Maximum Concurrent Jobs = 20
988 director = $HOST-dir = all, !skipped, !restored
992 system("mkdir -p '$REMOTE_FILE/working' '$REMOTE_FILE/save'");
993 system("rm -rf '$REMOTE_FILE/restore'");
996 close(STDIN); open(STDIN, "/dev/null");
997 close(STDOUT); open(STDOUT, ">/dev/null");
998 close(STDERR); open(STDERR, ">/dev/null");
999 exec("/opt/bacula/bin/bacula-fd -c $REMOTE_FILE/bacula-fd.conf");
1003 $pid = `cat $REMOTE_FILE/working/bacula-fd.$REMOTE_PORT.pid`;
1006 # create files and tweak rights
1007 create_many_files("$REMOTE_FILE/save", 5000);
1008 chdir("$REMOTE_FILE/save");
1011 for my $g ( split(' ', $( )) {
1016 # create a sparse file of 2MB
1017 init_delta("$REMOTE_FILE/save", 2000000);
1019 # create a simple script to execute
1020 open(FP, ">test.sh") or die "Can't open test.sh $!";
1021 print FP "#!/bin/sh\n";
1022 print FP "echo this is a script";
1024 chmod 0755, "test.sh";
1027 link("test.sh", "link-test.sh");
1029 # create long filename
1030 mkdir("b" x 255) or print "can't create long dir $!\n";
1031 copy("test.sh", ("b" x 255) . '/' . ("a" x 255)) or print "can't create long dir $!\n";
1033 # play with some symlinks
1034 symlink("test.sh", "sym-test.sh");
1035 symlink("$REMOTE_FILE/save/test.sh", "sym-abs-test.sh");
1047 debug("Doing diff between save and restore");
1048 system("ssh $REMOTE_USER$REMOTE_ADDR " .
1049 "$REMOTE_FILE/scripts/diff.pl -s $REMOTE_FILE/save -d $REMOTE_FILE/restore/$REMOTE_FILE/save");
1055 debug("Kill remote bacula-fd $REMOTE_ADDR");
1056 system("ssh $REMOTE_USER$REMOTE_ADDR " .
1057 "'test -f $REMOTE_FILE/working/bacula-fd.$REMOTE_PORT.pid && " .
1058 "kill `cat $REMOTE_FILE/working/bacula-fd.$REMOTE_PORT.pid`'");
1063 system("ssh $REMOTE_USER$REMOTE_ADDR mkdir -p '$REMOTE_FILE/scripts/'");
1064 system("scp -q scripts/functions.pm scripts/diff.pl $REMOTE_USER$REMOTE_ADDR:$REMOTE_FILE/scripts/");
1065 system("scp -q config $REMOTE_USER$REMOTE_ADDR:$REMOTE_FILE/");
1066 debug("INFO: Configuring remote client");
1067 system("ssh $REMOTE_USER$REMOTE_ADDR 'cd $REMOTE_FILE && perl -Mscripts::functions -e remote_config'");
1068 system("ssh $REMOTE_USER$REMOTE_ADDR 'cd $REMOTE_FILE && perl -Mscripts::functions -e remote_check'");
1073 my ($file, $nb) = @_;
1076 if (!open(FP, ">$file")) {
1077 print "ERR\nCan't create txt $file $@\n";
1080 for (my $i = 0; $i < $nb ; $i++) {
1081 foreach my $c ('a'..'z') {
1082 my $l = ($c x 1024);
1093 my ($source, $sparse_size) = @_;
1095 $sparse_size = $sparse_size || 100000000;
1097 # Create $source if needed
1098 system("mkdir -p '$source'");
1100 if (!chdir($source)) {
1101 print "ERR\nCan't access to $source $!\n";
1105 open(FP, ">text.txt") or return "ERR\nCan't create txt file $@\n";
1106 my $l = ($c x 80) . "\n";
1107 print FP $l x 40000;
1114 open(FP, ">sparse.dat") or return "ERR\nCan't create sparse $@\n";
1115 seek(FP, $sparse_size, 0);
1122 my ($source) = shift;
1124 if (!chdir($source)) {
1125 return "ERR\nCan't access to $source $!\n";
1131 open(FP, "+<sparse.dat") or return "ERR\nCan't update the sparse file $@\n";
1132 seek(FP, int(rand(-s "sparse.dat")), 0);
1139 open(FP, ">>text.txt") or return "ERR\nCan't update txt file $@\n";
1141 my $l = ($c x 80) . "\n";
1142 print FP $l x 40000;