diff --git a/mxmirror/mxmirror b/mxmirror/mxmirror index 712d39e..79a7750 100755 --- a/mxmirror/mxmirror +++ b/mxmirror/mxmirror @@ -1,43 +1,26 @@ #!/usr/bin/perl -# -# original is in /src/mariux/mariux/mxmirror/mxmirror -# - use Socket; use Sys::Hostname; -use Data::Dumper; use Getopt::Long; - use Date::Calc; use strict; use warnings; -$Data::Dumper::Sortkeys = "macheteinfach"; - - -#print Dumper $t1, $t2, $t3, $t4, $dt12, $dt21, $dt23, $dt34; - - - my $JBODMAP='/etc/amd/amd.jbod'; my $MIRRORMAP='/etc/mxmirrors'; my %CONFIG = ( CMD => 'STRING', - START => '21:00', - END => '07:00', - STEP => '00:15' ); - + my %opt = ( from => undef, to => undef, check => undef, verbose => 0, debug => 0, - ); my $fullhostname = hostname; @@ -46,275 +29,6 @@ my $hostip = inet_ntoa(scalar gethostbyname($fullhostname)); my $jbodmap = read_jbodmap($JBODMAP); my $mirrors = read_mirrormap($MIRRORMAP); -#my $timeslots = CalcTimeslots($mirrors); -my $timeslots; - -#print Dumper GroupMirrors($mirrors); - -#exit; - -sub GroupMirrors { - my $list = shift; - - my $nrofslots = 100; - - my @slots = (); - - my $nlist = {}; - - my @hosts = sort keys %{$list}; - - my $grpptr = {}; - - my $groups = []; - - my $ngrps=0; - - - foreach my $host (@hosts) { - my @dest = @{$list->{$host}}; - foreach my $dest (@dest) { - my $dhost = $dest->{destination}->{host}; - my ($grp, $dgrp); - - if(not exists $grpptr->{$host}) { - if(not exists $grpptr->{$dhost}) { - $grp = [ ]; - $grpptr->{$dhost} = $grp; - push @{$groups}, $grp; - } else { - $grp = $grpptr->{$dhost}; - } - $grpptr->{$host} = $grp; - } else { - $grp = $grpptr->{$host}; - - if(exists $grpptr->{$dhost}) { - $dgrp = $grpptr->{$dhost}; - - # merge groups if different - if($grp ne $dgrp) { - push @{$grp}, @{$dgrp}; - @{$groups} = grep { $_ ne $dgrp } @{$groups}; - } - } - $grpptr->{$dhost} = $grp; - } - - push @{$grp}, $dest; - - } - } - - print Dumper $grpptr; -# exit; - - for(my $i=0; $i < @{$groups}; $i++) { - print "group $i\n"; - - my $grp = $groups->[$i]; - - my %dummy = (); - - foreach my $m (@{$grp}) { - my $host = $m->{source}{host}; - my $dhost = $m->{destination}{host}; - push @{$dummy{"$host,$dhost"}}, $m; - print " $host -> $dhost\n"; - } - - - print Dumper \%dummy; - - @{$grp} = sort { $a->[0]{source}{host} cmp $b->[0]{source}{host} } values %dummy; - # @{$grp} = map { $dummy{$_} } sort keys %dummy; - } - - print Dumper $groups; - - exit; - return $groups; - -} - -sub GroupMirrors3 { - my $list = shift; - - my $nrofslots = 100; - - my @slots = (); - - my $nlist = {}; - - my @hosts = sort keys %{$list}; - - foreach my $host (@hosts) { - my @dest = @{$list->{$host}}; - foreach my $dest (@dest) { - my $dhost = $dest->{destination}->{host}; - - if(not exists $nlist->{$host}{$dhost} and $host ne $dhost) { - $nlist->{$host}{__cnt}++; - $nlist->{$dhost}{__cnt}++; - push @{$nlist->{$dhost}{__hosts}}, $host; - - - } - - $nlist->{$host}{$dhost} = 1; - - # push @{$nlist->{$host}{$dhost}{to}}, $dest; - } - } - - - foreach my $host (sort {$nlist->{$b}{__cnt} <=> $nlist->{$a}{__cnt} || $a cmp $b} keys %{$nlist}) { - - - my $cnt = $nlist->{$host}{__cnt}; - print "$host $cnt\n"; - my $ds = $cnt?$nrofslots/$cnt:1; - - my $s = 0; - - print "XXXX $host $nlist->{$host}{__cnt} $ds\n"; - - for($s=0; defined $slots[$s] and $s < $nrofslots; $s++) { - - } - - print " => first free slot: $s\n"; - - for(my $i=0; $i < $cnt; $i++) { - $slots[$s] = $host; - print " -> $s : $host\n"; - $s += $ds; - } - } - - print "RETURN.."; - return $nlist; - - -} -sub GroupMirrors2 { - my $list = shift; - - my $a = {}; - - my @hosts = sort keys %{$list}; - foreach my $h (@hosts) { - - unless(exists $a->{$h}) { - $a->{$h} = { - name => $h, - destinations => [], - sources => [] - } - } - my $this = $a->{$h}; - - foreach(@{$list->{$h}}) { - - my $d = $_->{destination}->{host}; - - unless(exists $a->{$d}) { - $a->{$d} = { - name => $d, - destinations => [], - sources => [] - } - } - - my $that = $a->{$d}; - - push @{$this->{destinations}}, $that; - push @{$that->{sources}}, $this; - - } - } - - foreach(keys %$a) { - unless(@{$a->{$_}->{destinations}}) { - printf "ENDPOINT: $_\n"; - delete $a->{$_} - } - } - - my $grps = {}; - - foreach(keys %$a) { - next unless defined $a->{$_}; - - my @g = check_a($a->{$_}); - - my @group = (); - - map { push @group, $a->{$_}; delete $a->{$_} } @g; - -# print "@g\n"; -# print Dumper \@group; - - $grps->{"@g"}->{group} = [ @group ]; - - } - - foreach my $g (keys %$grps) { - my $dest = {}; - foreach my $host (split / /, $g) { - next unless exists $list->{$host}; - printf "$g :: $host\n"; - foreach my $m (@{$list->{$host}}) { - $dest->{"$host $m->{destination}->{host}"} = [ $host, $m->{destination}->{host} ]; - - if($host eq $m->{destination}->{host}) { - $dest->{$host}->{"self-$m->{destination}->{host}"}->{self} = $host; - } else { - $dest->{$host}->{"to-$m->{destination}->{host}"}->{to} = $m->{destination}->{host}; - $dest->{$m->{destination}->{host}}->{"from-$host"}->{from} = $host; - } - } - } - - - - print Dumper $dest; - - } - - - - return $grps; - -} - - -sub check_a { - my $a = shift; - my $href = shift || {}; - - return if(exists $href->{$a->{name}}); - -# printf "checking $a->{name} .. \n"; - - $href->{$a->{name}} = 1; - - foreach(@{$a->{destinations}}, @{$a->{sources}}) { - next if(exists $href->{$_->{name}}); - check_a($_, $href); - } - - - - return sort keys %$href; - -} - -#print Dumper $timeslots; -#exit; - - -#print Dumper $mirrors; my $result = GetOptions( "from:s" => \$opt{from}, @@ -336,35 +50,32 @@ if($opt{help}) { print <<"EOF"; $0 [options] [action] - + actions: - + print mirror-cmds to mirror local filesystems - + --sourcehosts list all hosts to mirror --destinationhosts list all mirror hosts - + --all list all defined mirrors - + --check check mirrorstatus of localhost - + options: - + --format= define output format --execute execute if is not specified - + --command= execute for every host listed --config= read mirror-definitions from --jbodmap= read amd-map for jbods from - - + EOF exit 0; } - - if(defined $opt{destinationhosts}) { exit print_and_exec_hostlist(mirrors_reverse($mirrors)); } @@ -374,11 +85,9 @@ if(defined $opt{sourcehosts}) { } if(defined $opt{all}) { - exit print_and_exec_all($mirrors, $timeslots); + exit print_and_exec_all($mirrors); } - - if(defined $opt{check}) { my $host = $opt{check} || $hostname; @@ -430,20 +139,17 @@ foreach(@{$mirrors->{$hostname}}) { } } - exit($err); - ################################################################### sub print_and_exec_all { my $list = shift; - my $ts = shift; my $default_fmt = "SRCHOST:SRCPATH DSTHOST:DSTPATH ARGS"; my $fmt = (defined $opt{format})?$opt{format}:$default_fmt; my $cmd = $opt{command}; - + if(not defined $cmd and $opt{execute}) { $cmd = $fmt; } @@ -465,10 +171,8 @@ sub print_and_exec_all { my @hosts = sort keys %{$list}; - foreach my $h (@hosts) { my %vars = ( -# TIME => $ts->{hosts}->{$h}->{time_str} ); foreach(@{$list->{$h}}) { @@ -484,8 +188,6 @@ sub print_and_exec_all { return 0; } - - sub print_and_exec_hostlist { my $list = shift; @@ -518,7 +220,6 @@ sub print_and_exec_hostlist { return 0; } - sub mirrors_reverse { my $mirrors = shift; @@ -533,7 +234,6 @@ sub mirrors_reverse { return $r; } - sub get_mirror_status { my $mirror = shift; @@ -551,22 +251,17 @@ sub get_mirror_status { if($status eq 'OK') { my ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = Date::Calc::Gmtime($days); - $days = Date::Calc::Delta_Days($year,$month,$day, Date::Calc::Today()); return $days; } - return $line; - } return 'UNKNOWN'; } -#print Dumper \%opt; - sub do_format { my $fmt = shift; my $data = shift; @@ -595,8 +290,6 @@ sub do_format { return $fmt; } - - sub to_jbod_path { my $host = shift; my $jbod = shift; @@ -631,8 +324,6 @@ sub to_amd_path { # isempty(): : # - - # from := # /jbod/ @@ -648,8 +339,8 @@ sub convert_to_sourcepath { if(($jbod, $path) = $string =~ /^([XCMD][\da-f]\d\d\d)(.*?)$/) { unless(defined $jbodmap->{$jbod}) { - printf STDERR "**ERROR: unknown jbod: $string"; - next; + printf STDERR "**ERROR: unknown jbod: $string\n"; + return undef } $host = $jbodmap->{$jbod}; @@ -677,8 +368,6 @@ sub convert_to_sourcepath { path => $path, hostpath => $path }); - - } return; } @@ -714,8 +403,8 @@ sub convert_to_destinationpath { if(($jbod, $path) = $string =~ /^([XCMD][\da-f]\d\d\d)(.*?)$/) { unless(defined $jbodmap->{$jbod}) { - printf STDERR "**ERROR: unknown jbod: $string"; - next; + printf STDERR "**ERROR: unknown jbod: $string\n"; + return undef; } $host = $jbodmap->{$jbod}; @@ -748,7 +437,6 @@ sub convert_to_destinationpath { if(($host,$partition,$path) = $string =~ /^(.*?):(\d+)(.*?)$/) { - unless($path) { if(defined $source->{jbod}) { $path = "/mirror/$source->{jbod}$source->{path}"; @@ -773,50 +461,9 @@ sub convert_to_destinationpath { } - - return; } - - - -#sub convert_to_path { -# my $string = shift; -# my $mirror = shift; -# -# my ($jbod, $path, $host, $hostpath, $partition); -# -# if(($jbod, $path) = $string =~ /^(X\d+)(.*?)$/) { -# unless(defined $jbodmap->{$jbod}) { -# printf STDERR "**ERROR: unknown jbod: $string"; -# next; -# } -# #sauerkraut:/amd/sauerkraut/X/X0053/mirror/balmer/1 -# -# $host = $jbodmap->{$jbod}; -# -# $hostpath = to_jbod_path($host, $jbod, ${path}, ${mirror}); -# -## printf " - jbod=${jbod} path=${path} => ${hostpath}\n"; -# -# return wantarray?($host, $hostpath):"${host}:${hostpath}"; -# } -# -# if(($host,$partition,$path) = $string =~ /^(.*?):(\d+)(.*?)$/) { -# $hostpath = to_amd_path($host, $partition, $path, $mirror); -# -## printf " - partition=${partition} path=${path} => ${hostpath}\n"; -# -# return wantarray?($host, $hostpath):"${host}:${hostpath}"; -# } -# -# -# -# -# return; -#} - sub read_mirrormap { my $file = shift; @@ -830,8 +477,6 @@ sub read_mirrormap { open(F, '<', $file) or die "can't open $file: $?"; - - foreach() { s/^\s+//; s/\s+$//; @@ -852,13 +497,11 @@ sub read_mirrormap { $source = convert_to_sourcepath($from); $destination = convert_to_destinationpath($to, $source); - unless($source and $destination) { print STDERR "**ERROR: CAN'T PARSE FROM/TO: $_\n"; next; } - push @{$map->{$source->{host}}}, {string => $string, source => $source, destination => $destination, args => $args}; } else { @@ -872,8 +515,6 @@ sub read_mirrormap { return $map; } - - sub read_jbodmap { my $file = shift; @@ -890,203 +531,3 @@ sub read_jbodmap { return $map; } - - -sub DeltaTime { - my $t1 = shift; - my $t2 = shift; - - my $dm = TimeToSeconds($t2) - TimeToSeconds($t1); - - $dm = ($dm < 0) ? ($dm + 24*60*60) : $dm; - - my $dt = SecondsToTime($dm); - -# print Dumper ["delta", $t1, $t2, $dt, $dm]; - - return $dt; -} - -sub AddDeltaTime { - my $t1 = shift; - my $dt = shift; - - my $m = TimeToSeconds($t1) + TimeToSeconds($dt); - - my $t2 = SecondsToTime($m); - -# print Dumper ["add", $t1, $dt, $t2, $m]; - - return $t2; -} - -sub SubDeltaTime { - my $t1 = shift; - my $dt = shift; - - my $m = TimeToSeconds($t1) - TimeToSeconds($dt); - - my $t2 = SecondsToTime($m); - -# print Dumper ["add", $t1, $dt, $t2, $m]; - - return $t2; -} - - -sub TimeToMinutes { - my $t = shift; - my $m; - - $m = ($t->[0]*60 + $t->[1]) % (24*60); - -# print Dumper ["t2min", $t, $m]; - - return $m; - -} - -sub TimeToSeconds { - my $t = shift; - my $m; - - $m = ($t->[0]*60*60 + $t->[1]*60 + $t->[2]) % (24*60*60); - -# print Dumper ["t2min", $t, $m]; - - return $m; - -} - -sub SecondsToTime { - my $s = shift; - my $t = [0,0,0]; - - $t->[0] = int($s/(60*60)); - - $s -= ($t->[0] * 60*60); - - $t->[1] = int($s/60); - - $s -= ($t->[1] * 60); - - $t->[2] = $s; - - # this is my very first use of the %= statement EVER! - # YEAH! mx. - - $t->[0] %= 24; - -# print Dumper ["min2t", $m, $t]; - - return $t; - -} - - -sub MinutesToTime { - my $m = shift; - my $t = [0,0,0]; - - $t->[0] = int($m/60); - $t->[1] = $m - ($t->[0] * 60); - - # this is my very first use of the %= statement EVER! - # YEAH! mx. - - $t->[0] %= 24; - - -# print Dumper ["min2t", $m, $t]; - - return $t; - -} - -sub FormatTime { - my $t = shift; - - return sprintf("%02d:%02d:%02d", @{$t}); -} - - -sub ParseTime { - my $s = shift; - - my @t; - - if(@t = $s =~ /^(\d+):([0-5][0-9])$/) { - return [ @t, 0 ]; - } - - if(@t = $s =~ /^(\d+):([0-5][0-9]):([0-5][0-9])$/) { - return @t; - } - - warn "ParseTime invalid time '$s'"; - return [0,0]; -} - - - -sub CalcTimeslots { - my $list = shift; - - my @hosts = sort keys %{$list}; - - my $ts = {}; - my $t1 = ParseTime($CONFIG{START}); - my $t2 = ParseTime($CONFIG{END}); - my $step = ParseTime($CONFIG{STEP}); - - my $dt = DeltaTime($t1, $t2); - - my $s = TimeToSeconds($step); - my $dspan = SecondsToTime($s/2); - - $ts->{nslots} = int(TimeToSeconds($dt) / $s)+1; - $ts->{start} = $t1; - $ts->{end} = $t2; - $ts->{step} = $step; - $ts->{slots} = []; - $ts->{hosts} = {}; - - my $this = $ts->{start}; - - my $i = 0; - while($i++ < $ts->{nslots}) { - my $slot = {}; - - $slot->{time} = $this; - $slot->{timespan}->[0] = SubDeltaTime($this, $dspan); - $slot->{timespan}->[1] = AddDeltaTime($this, $dspan); - $slot->{time_str} = FormatTime($this); - - push @{$ts->{slots}}, $slot; - - $this = AddDeltaTime($this, $step); - } - - - $i = 0; - - foreach my $host (@hosts) { - my $slot = $ts->{slots}->[$i++ % $ts->{nslots}]; - - foreach(@{$list->{$host}}) { - $_->{timeslot} = $slot; - } - } - - return $ts; -} - - - -# read jbod map - -#eval $(cat /etc/amd/amd.jbod | sed -ne 's,^.*/amd/\(.*\)/X/\(X....\).*$,\2=\1,p') - - - -